#include "s2io.h"
#include "s2io-regs.h"
-#define DRV_VERSION "2.0.26.5"
+#define DRV_VERSION "2.0.26.17"
/* S2io Driver name & version. */
static char s2io_driver_name[] = "Neterion";
/* to set the swapper controle on the card */
if(s2io_set_swapper(nic)) {
DBG_PRINT(ERR_DBG,"ERROR: Setting Swapper failed\n");
- return -1;
+ return -EIO;
}
/*
msleep(500);
val64 = readq(&bar0->sw_reset);
+ /* Ensure that it's safe to access registers by checking
+ * RIC_RUNNING bit is reset. Check is valid only for XframeII.
+ */
+ if (nic->device_type == XFRAME_II_DEVICE) {
+ for (i = 0; i < 50; i++) {
+ val64 = readq(&bar0->adapter_status);
+ if (!(val64 & ADAPTER_STATUS_RIC_RUNNING))
+ break;
+ msleep(10);
+ }
+ if (i == 50)
+ return -ENODEV;
+ }
+
/* Enable Receiving broadcasts */
add = &bar0->mac_cfg;
val64 = readq(&bar0->mac_cfg);
DBG_PRINT(ERR_DBG, "%s: failed rts ds steering",
dev->name);
DBG_PRINT(ERR_DBG, "set on codepoint %d\n", i);
- return FAILURE;
+ return -ENODEV;
}
}
if (time > 10) {
DBG_PRINT(ERR_DBG, "%s: TTI init Failed\n",
dev->name);
- return -1;
+ return -ENODEV;
}
msleep(50);
time++;
if (time > 10) {
DBG_PRINT(ERR_DBG, "%s: RTI init Failed\n",
dev->name);
- return -1;
+ return -ENODEV;
}
time++;
msleep(50);
MISC_LINK_STABILITY_PRD(3);
writeq(val64, &bar0->misc_control);
val64 = readq(&bar0->pic_control2);
- val64 &= ~(BIT(13)|BIT(14)|BIT(15));
+ val64 &= ~(s2BIT(13)|s2BIT(14)|s2BIT(15));
writeq(val64, &bar0->pic_control2);
}
if (strstr(nic->product_name, "CX4")) {
}
if ((rxdp->Control_1 & RXD_OWN_XENA) &&
((nic->rxd_mode == RXD_MODE_3B) &&
- (rxdp->Control_2 & BIT(0)))) {
+ (rxdp->Control_2 & s2BIT(0)))) {
mac_control->rings[ring_no].rx_curr_put_info.
offset = off;
goto end;
rxdp->Control_2 |= SET_BUFFER2_SIZE_3
(dev->mtu + 4);
}
- rxdp->Control_2 |= BIT(0);
+ rxdp->Control_2 |= s2BIT(0);
}
rxdp->Host_Control = (unsigned long) (skb);
if (alloc_tab & ((1 << rxsync_frequency) - 1))
struct XENA_dev_config __iomem *bar0 = nic->bar0;
int i;
- if (!is_s2io_card_up(nic))
- return 0;
-
mac_control = &nic->mac_control;
config = &nic->config;
pci_write_config_dword(sp->pdev, 0x68, 0x7C);
/* Clearing PCI_STATUS error reflected here */
- writeq(BIT(62), &bar0->txpic_int_reg);
+ writeq(s2BIT(62), &bar0->txpic_int_reg);
}
/* Reset device statistics maintained by OS */
do {
val64 = readq(&bar0->xmsi_access);
- if (!(val64 & BIT(15)))
+ if (!(val64 & s2BIT(15)))
break;
mdelay(1);
cnt++;
for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
writeq(nic->msix_info[i].data, &bar0->xmsi_data);
- val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+ val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, i)) {
DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
/* Store and display */
for (i=0; i < MAX_REQUESTED_MSI_X; i++) {
- val64 = (BIT(15) | vBIT(i, 26, 6));
+ val64 = (s2BIT(15) | vBIT(i, 26, 6));
writeq(val64, &bar0->xmsi_access);
if (wait_for_msix_trans(nic, i)) {
DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
}
/* Handle software interrupt used during MSI(X) test */
-static irqreturn_t __devinit s2io_test_intr(int irq, void *dev_id)
+static irqreturn_t s2io_test_intr(int irq, void *dev_id)
{
struct s2io_nic *sp = dev_id;
}
/* Test interrupt path by forcing a a software IRQ */
-static int __devinit s2io_test_msi(struct s2io_nic *sp)
+static int s2io_test_msi(struct s2io_nic *sp)
{
struct pci_dev *pdev = sp->pdev;
struct XENA_dev_config __iomem *bar0 = sp->bar0;
return err;
}
+
+static void remove_msix_isr(struct s2io_nic *sp)
+{
+ int i;
+ u16 msi_control;
+
+ for (i = 0; i < MAX_REQUESTED_MSI_X; i++) {
+ if (sp->s2io_entries[i].in_use ==
+ MSIX_REGISTERED_SUCCESS) {
+ int vector = sp->entries[i].vector;
+ void *arg = sp->s2io_entries[i].arg;
+ free_irq(vector, arg);
+ }
+ }
+
+ kfree(sp->entries);
+ kfree(sp->s2io_entries);
+ sp->entries = NULL;
+ sp->s2io_entries = NULL;
+
+ pci_read_config_word(sp->pdev, 0x42, &msi_control);
+ msi_control &= 0xFFFE; /* Disable MSI */
+ pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+ pci_disable_msix(sp->pdev);
+}
+
+static void remove_inta_isr(struct s2io_nic *sp)
+{
+ struct net_device *dev = sp->dev;
+
+ free_irq(sp->pdev->irq, dev);
+}
+
/* ********************************************************* *
* Functions defined below concern the OS part of the driver *
* ********************************************************* */
netif_carrier_off(dev);
sp->last_link_state = 0;
- napi_enable(&sp->napi);
-
if (sp->config.intr_type == MSI_X) {
int ret = s2io_enable_msi_x(sp);
if (!ret) {
- u16 msi_control;
-
ret = s2io_test_msi(sp);
-
/* rollback MSI-X, will re-enable during add_isr() */
- kfree(sp->entries);
- sp->mac_control.stats_info->sw_stat.mem_freed +=
- (MAX_REQUESTED_MSI_X *
- sizeof(struct msix_entry));
- kfree(sp->s2io_entries);
- sp->mac_control.stats_info->sw_stat.mem_freed +=
- (MAX_REQUESTED_MSI_X *
- sizeof(struct s2io_msix_entry));
- sp->entries = NULL;
- sp->s2io_entries = NULL;
-
- pci_read_config_word(sp->pdev, 0x42, &msi_control);
- msi_control &= 0xFFFE; /* Disable MSI */
- pci_write_config_word(sp->pdev, 0x42, msi_control);
-
- pci_disable_msix(sp->pdev);
-
+ remove_msix_isr(sp);
}
if (ret) {
return 0;
hw_init_failed:
- napi_disable(&sp->napi);
if (sp->config.intr_type == MSI_X) {
if (sp->entries) {
kfree(sp->entries);
{
struct s2io_nic *sp = dev->priv;
+ /* Return if the device is already closed *
+ * Can happen when s2io_card_up failed in change_mtu *
+ */
+ if (!is_s2io_card_up(sp))
+ return 0;
+
netif_stop_queue(dev);
- napi_disable(&sp->napi);
/* Reset card, kill tasklet and free Tx and Rx buffers. */
s2io_card_down(sp);
do {
udelay(100);
val64 = readq(&bar0->stat_cfg);
- if (!(val64 & BIT(0)))
+ if (!(val64 & s2BIT(0)))
break;
cnt++;
if (cnt == 5)
static int s2io_change_mtu(struct net_device *dev, int new_mtu)
{
struct s2io_nic *sp = dev->priv;
+ int ret = 0;
if ((new_mtu < MIN_MTU) || (new_mtu > S2IO_JUMBO_SIZE)) {
DBG_PRINT(ERR_DBG, "%s: MTU size is invalid.\n",
if (netif_running(dev)) {
s2io_card_down(sp);
netif_stop_queue(dev);
- if (s2io_card_up(sp)) {
+ ret = s2io_card_up(sp);
+ if (ret) {
DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n",
__FUNCTION__);
+ return ret;
}
if (netif_queue_stopped(dev))
netif_wake_queue(dev);
writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len);
}
- return 0;
+ return ret;
}
/**
}
}
if (err) {
+ remove_msix_isr(sp);
DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration "
"failed\n", dev->name, i);
- DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
- return -1;
+ DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n",
+ dev->name);
+ sp->config.intr_type = INTA;
+ break;
}
sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
}
- printk("MSI-X-TX %d entries enabled\n",msix_tx_cnt);
- printk("MSI-X-RX %d entries enabled\n",msix_rx_cnt);
+ if (!err) {
+ printk(KERN_INFO "MSI-X-TX %d entries enabled\n",
+ msix_tx_cnt);
+ printk(KERN_INFO "MSI-X-RX %d entries enabled\n",
+ msix_rx_cnt);
+ }
}
if (sp->config.intr_type == INTA) {
err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED,
}
static void s2io_rem_isr(struct s2io_nic * sp)
{
- struct net_device *dev = sp->dev;
- struct swStat *stats = &sp->mac_control.stats_info->sw_stat;
-
- if (sp->config.intr_type == MSI_X) {
- int i;
- u16 msi_control;
-
- for (i=1; (sp->s2io_entries[i].in_use ==
- MSIX_REGISTERED_SUCCESS); i++) {
- int vector = sp->entries[i].vector;
- void *arg = sp->s2io_entries[i].arg;
-
- synchronize_irq(vector);
- free_irq(vector, arg);
- }
-
- kfree(sp->entries);
- stats->mem_freed +=
- (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
- kfree(sp->s2io_entries);
- stats->mem_freed +=
- (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
- sp->entries = NULL;
- sp->s2io_entries = NULL;
-
- pci_read_config_word(sp->pdev, 0x42, &msi_control);
- msi_control &= 0xFFFE; /* Disable MSI */
- pci_write_config_word(sp->pdev, 0x42, msi_control);
-
- pci_disable_msix(sp->pdev);
- } else {
- synchronize_irq(sp->pdev->irq);
- free_irq(sp->pdev->irq, dev);
- }
+ if (sp->config.intr_type == MSI_X)
+ remove_msix_isr(sp);
+ else
+ remove_inta_isr(sp);
}
static void do_s2io_card_down(struct s2io_nic * sp, int do_io)
struct XENA_dev_config __iomem *bar0 = sp->bar0;
unsigned long flags;
register u64 val64 = 0;
+ struct config_param *config;
+ config = &sp->config;
+
+ if (!is_s2io_card_up(sp))
+ return;
del_timer_sync(&sp->alarm_timer);
/* If s2io_set_link task is executing, wait till it completes. */
}
clear_bit(__S2IO_STATE_CARD_UP, &sp->state);
+ /* Disable napi */
+ if (config->napi)
+ napi_disable(&sp->napi);
+
/* disable Tx and Rx traffic on the NIC */
if (do_io)
stop_nic(sp);
u16 interruptible;
/* Initialize the H/W I/O registers */
- if (init_nic(sp) != 0) {
+ ret = init_nic(sp);
+ if (ret != 0) {
DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n",
dev->name);
- s2io_reset(sp);
- return -ENODEV;
+ if (ret != -EIO)
+ s2io_reset(sp);
+ return ret;
}
/*
DBG_PRINT(INFO_DBG, "Buf in ring:%d is %d:\n", i,
atomic_read(&sp->rx_bufs_left[i]));
}
+
+ /* Initialise napi */
+ if (config->napi)
+ napi_enable(&sp->napi);
+
/* Maintain the state prior to the open */
if (sp->promisc_flg)
sp->promisc_flg = 0;