diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 686 |
1 files changed, 371 insertions, 315 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 523478ebfd6..9dae40ccf04 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c @@ -86,7 +86,7 @@ #include "s2io.h" #include "s2io-regs.h" -#define DRV_VERSION "2.0.26.23" +#define DRV_VERSION "2.0.26.25" /* S2io Driver name & version. */ static char s2io_driver_name[] = "Neterion"; @@ -545,91 +545,63 @@ static struct pci_driver s2io_driver = { /* netqueue manipulation helper functions */ static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp) { - int i; -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (sp->config.multiq) { - for (i = 0; i < sp->config.tx_fifo_num; i++) - netif_stop_subqueue(sp->dev, i); - } else -#endif - { + if (!sp->config.multiq) { + int i; + for (i = 0; i < sp->config.tx_fifo_num; i++) sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP; - netif_stop_queue(sp->dev); } + netif_tx_stop_all_queues(sp->dev); } static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no) { -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (sp->config.multiq) - netif_stop_subqueue(sp->dev, fifo_no); - else -#endif - { + if (!sp->config.multiq) sp->mac_control.fifos[fifo_no].queue_state = FIFO_QUEUE_STOP; - netif_stop_queue(sp->dev); - } + + netif_tx_stop_all_queues(sp->dev); } static inline void s2io_start_all_tx_queue(struct s2io_nic *sp) { - int i; -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (sp->config.multiq) { - for (i = 0; i < sp->config.tx_fifo_num; i++) - netif_start_subqueue(sp->dev, i); - } else -#endif - { + if (!sp->config.multiq) { + int i; + for (i = 0; i < sp->config.tx_fifo_num; i++) sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; - netif_start_queue(sp->dev); } + netif_tx_start_all_queues(sp->dev); } static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no) { -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (sp->config.multiq) - netif_start_subqueue(sp->dev, fifo_no); - else -#endif - { + if (!sp->config.multiq) sp->mac_control.fifos[fifo_no].queue_state = FIFO_QUEUE_START; - netif_start_queue(sp->dev); - } + + netif_tx_start_all_queues(sp->dev); } static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp) { - int i; -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (sp->config.multiq) { - for (i = 0; i < sp->config.tx_fifo_num; i++) - netif_wake_subqueue(sp->dev, i); - } else -#endif - { + if (!sp->config.multiq) { + int i; + for (i = 0; i < sp->config.tx_fifo_num; i++) sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; - netif_wake_queue(sp->dev); } + netif_tx_wake_all_queues(sp->dev); } static inline void s2io_wake_tx_queue( struct fifo_info *fifo, int cnt, u8 multiq) { -#ifdef CONFIG_NETDEVICES_MULTIQUEUE if (multiq) { if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no)) netif_wake_subqueue(fifo->dev, fifo->fifo_no); - } else -#endif - if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) { + } else if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) { if (netif_queue_stopped(fifo->dev)) { fifo->queue_state = FIFO_QUEUE_START; netif_wake_queue(fifo->dev); @@ -1113,9 +1085,10 @@ static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) struct pci_dev *tdev = NULL; while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { - if (tdev->bus == s2io_pdev->bus->parent) + if (tdev->bus == s2io_pdev->bus->parent) { pci_dev_put(tdev); return 1; + } } } return 0; @@ -1219,15 +1192,33 @@ static int init_tti(struct s2io_nic *nic, int link) TTI_DATA1_MEM_TX_URNG_B(0x10) | TTI_DATA1_MEM_TX_URNG_C(0x30) | TTI_DATA1_MEM_TX_TIMER_AC_EN; - - if (use_continuous_tx_intrs && (link == LINK_UP)) - val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; + if (i == 0) + if (use_continuous_tx_intrs && (link == LINK_UP)) + val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; writeq(val64, &bar0->tti_data1_mem); - val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | - TTI_DATA2_MEM_TX_UFC_B(0x20) | - TTI_DATA2_MEM_TX_UFC_C(0x40) | - TTI_DATA2_MEM_TX_UFC_D(0x80); + if (nic->config.intr_type == MSI_X) { + val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | + TTI_DATA2_MEM_TX_UFC_B(0x100) | + TTI_DATA2_MEM_TX_UFC_C(0x200) | + TTI_DATA2_MEM_TX_UFC_D(0x300); + } else { + if ((nic->config.tx_steering_type == + TX_DEFAULT_STEERING) && + (config->tx_fifo_num > 1) && + (i >= nic->udp_fifo_idx) && + (i < (nic->udp_fifo_idx + + nic->total_udp_fifos))) + val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) | + TTI_DATA2_MEM_TX_UFC_B(0x80) | + TTI_DATA2_MEM_TX_UFC_C(0x100) | + TTI_DATA2_MEM_TX_UFC_D(0x120); + else + val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | + TTI_DATA2_MEM_TX_UFC_B(0x20) | + TTI_DATA2_MEM_TX_UFC_C(0x40) | + TTI_DATA2_MEM_TX_UFC_D(0x80); + } writeq(val64, &bar0->tti_data2_mem); @@ -1890,8 +1881,6 @@ static int init_nic(struct s2io_nic *nic) static int s2io_link_fault_indication(struct s2io_nic *nic) { - if (nic->config.intr_type != INTA) - return MAC_RMAC_ERR_TIMER; if (nic->device_type == XFRAME_II_DEVICE) return LINK_UP_DOWN_INTERRUPT; else @@ -1924,7 +1913,9 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) { struct XENA_dev_config __iomem *bar0 = nic->bar0; register u64 gen_int_mask = 0; + u64 interruptible; + writeq(DISABLE_ALL_INTRS, &bar0->general_int_mask); if (mask & TX_DMA_INTR) { gen_int_mask |= TXDMA_INT_M; @@ -2014,10 +2005,12 @@ static void en_dis_err_alarms(struct s2io_nic *nic, u16 mask, int flag) gen_int_mask |= RXMAC_INT_M; do_s2io_write_bits(MAC_INT_STATUS_RMAC_INT, flag, &bar0->mac_int_mask); - do_s2io_write_bits(RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | + interruptible = RMAC_RX_BUFF_OVRN | RMAC_RX_SM_ERR | RMAC_UNUSED_INT | RMAC_SINGLE_ECC_ERR | - RMAC_DOUBLE_ECC_ERR | - RMAC_LINK_STATE_CHANGE_INT, + RMAC_DOUBLE_ECC_ERR; + if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) + interruptible |= RMAC_LINK_STATE_CHANGE_INT; + do_s2io_write_bits(interruptible, flag, &bar0->mac_rmac_err_mask); } @@ -2500,6 +2493,9 @@ static void stop_nic(struct s2io_nic *nic) /** * fill_rx_buffers - Allocates the Rx side skbs * @ring_info: per ring structure + * @from_card_up: If this is true, we will map the buffer to get + * the dma address for buf0 and buf1 to give it to the card. + * Else we will sync the already mapped buffer to give it to the card. * Description: * The function allocates Rx side skbs and puts the physical * address of these buffers into the RxD buffer pointers, so that the NIC @@ -2517,7 +2513,7 @@ static void stop_nic(struct s2io_nic *nic) * SUCCESS on success or an appropriate -ve value on failure. */ -static int fill_rx_buffers(struct ring_info *ring) +static int fill_rx_buffers(struct ring_info *ring, int from_card_up) { struct sk_buff *skb; struct RxD_t *rxdp; @@ -2547,7 +2543,7 @@ static int fill_rx_buffers(struct ring_info *ring) if (block_no) rxd_index += (block_no * ring->rxd_count); - if ((block_no == block_no1) && + if ((block_no == block_no1) && (off == ring->rx_curr_get_info.offset) && (rxdp->Host_Control)) { DBG_PRINT(INTR_DBG, "%s: Get and Put", @@ -2593,7 +2589,7 @@ static int fill_rx_buffers(struct ring_info *ring) first_rxdp->Control_1 |= RXD_OWN_XENA; } stats->mem_alloc_fail_cnt++; - + return -ENOMEM ; } stats->mem_allocated += skb->truesize; @@ -2606,9 +2602,7 @@ static int fill_rx_buffers(struct ring_info *ring) rxdp1->Buffer0_ptr = pci_map_single (ring->pdev, skb->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if( (rxdp1->Buffer0_ptr == 0) || - (rxdp1->Buffer0_ptr == - DMA_ERROR_CODE)) + if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) goto pci_map_failed; rxdp->Control_2 = @@ -2638,17 +2632,16 @@ static int fill_rx_buffers(struct ring_info *ring) skb->data = (void *) (unsigned long)tmp; skb_reset_tail_pointer(skb); - if (!(rxdp3->Buffer0_ptr)) + if (from_card_up) { rxdp3->Buffer0_ptr = pci_map_single(ring->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - else + if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) + goto pci_map_failed; + } else pci_dma_sync_single_for_device(ring->pdev, (dma_addr_t) rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer0_ptr == 0) || - (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) - goto pci_map_failed; rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); if (ring->rxd_mode == RXD_MODE_3B) { @@ -2662,25 +2655,25 @@ static int fill_rx_buffers(struct ring_info *ring) (ring->pdev, skb->data, ring->mtu + 4, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer2_ptr == 0) || - (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) + if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) goto pci_map_failed; - if (!rxdp3->Buffer1_ptr) + if (from_card_up) { rxdp3->Buffer1_ptr = pci_map_single(ring->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer1_ptr == 0) || - (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { - pci_unmap_single - (ring->pdev, - (dma_addr_t)(unsigned long) - skb->data, - ring->mtu + 4, - PCI_DMA_FROMDEVICE); - goto pci_map_failed; + if (pci_dma_mapping_error + (rxdp3->Buffer1_ptr)) { + pci_unmap_single + (ring->pdev, + (dma_addr_t)(unsigned long) + skb->data, + ring->mtu + 4, + PCI_DMA_FROMDEVICE); + goto pci_map_failed; + } } rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); rxdp->Control_2 |= SET_BUFFER2_SIZE_3 @@ -2813,6 +2806,15 @@ static void free_rx_buffers(struct s2io_nic *sp) } } +static int s2io_chk_rx_buffers(struct ring_info *ring) +{ + if (fill_rx_buffers(ring, 0) == -ENOMEM) { + DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); + DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); + } + return 0; +} + /** * s2io_poll - Rx interrupt handler for NAPI support * @napi : pointer to the napi structure. @@ -2826,57 +2828,73 @@ static void free_rx_buffers(struct s2io_nic *sp) * 0 on success and 1 if there are No Rx packets to be processed. */ -static int s2io_poll(struct napi_struct *napi, int budget) +static int s2io_poll_msix(struct napi_struct *napi, int budget) { - struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); - struct net_device *dev = nic->dev; - int pkt_cnt = 0, org_pkts_to_process; - struct mac_info *mac_control; + struct ring_info *ring = container_of(napi, struct ring_info, napi); + struct net_device *dev = ring->dev; struct config_param *config; + struct mac_info *mac_control; + int pkts_processed = 0; + u8 __iomem *addr = NULL; + u8 val8 = 0; + struct s2io_nic *nic = dev->priv; struct XENA_dev_config __iomem *bar0 = nic->bar0; - int i; + int budget_org = budget; - mac_control = &nic->mac_control; config = &nic->config; + mac_control = &nic->mac_control; - nic->pkts_to_process = budget; - org_pkts_to_process = nic->pkts_to_process; + if (unlikely(!is_s2io_card_up(nic))) + return 0; - writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); - readl(&bar0->rx_traffic_int); + pkts_processed = rx_intr_handler(ring, budget); + s2io_chk_rx_buffers(ring); - for (i = 0; i < config->rx_ring_num; i++) { - rx_intr_handler(&mac_control->rings[i]); - pkt_cnt = org_pkts_to_process - nic->pkts_to_process; - if (!nic->pkts_to_process) { - /* Quota for the current iteration has been met */ - goto no_rx; - } + if (pkts_processed < budget_org) { + netif_rx_complete(dev, napi); + /*Re Enable MSI-Rx Vector*/ + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; + addr += 7 - ring->ring_no; + val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; + writeb(val8, addr); + val8 = readb(addr); } + return pkts_processed; +} +static int s2io_poll_inta(struct napi_struct *napi, int budget) +{ + struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); + struct ring_info *ring; + struct net_device *dev = nic->dev; + struct config_param *config; + struct mac_info *mac_control; + int pkts_processed = 0; + int ring_pkts_processed, i; + struct XENA_dev_config __iomem *bar0 = nic->bar0; + int budget_org = budget; - netif_rx_complete(dev, napi); + config = &nic->config; + mac_control = &nic->mac_control; - for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); - break; - } - } - /* Re enable the Rx interrupts. */ - writeq(0x0, &bar0->rx_traffic_mask); - readl(&bar0->rx_traffic_mask); - return pkt_cnt; + if (unlikely(!is_s2io_card_up(nic))) + return 0; -no_rx: for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); - DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); + ring = &mac_control->rings[i]; + ring_pkts_processed = rx_intr_handler(ring, budget); + s2io_chk_rx_buffers(ring); + pkts_processed += ring_pkts_processed; + budget -= ring_pkts_processed; + if (budget <= 0) break; - } } - return pkt_cnt; + if (pkts_processed < budget_org) { + netif_rx_complete(dev, napi); + /* Re enable the Rx interrupts for the ring */ + writeq(0, &bar0->rx_traffic_mask); + readl(&bar0->rx_traffic_mask); + } + return pkts_processed; } #ifdef CONFIG_NET_POLL_CONTROLLER @@ -2918,10 +2936,10 @@ static void s2io_netpoll(struct net_device *dev) /* check for received packet and indicate up to network */ for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); + rx_intr_handler(&mac_control->rings[i], 0); for (i = 0; i < config->rx_ring_num; i++) { - if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { + if (fill_rx_buffers(&mac_control->rings[i], 0) == -ENOMEM) { DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); DBG_PRINT(INFO_DBG, " in Rx Netpoll!!\n"); break; @@ -2934,7 +2952,8 @@ static void s2io_netpoll(struct net_device *dev) /** * rx_intr_handler - Rx interrupt handler - * @nic: device private variable. + * @ring_info: per ring structure. + * @budget: budget for napi processing. * Description: * If the interrupt is because of a received frame or if the * receive ring contains fresh as yet un-processed frames,this function is @@ -2942,15 +2961,15 @@ static void s2io_netpoll(struct net_device *dev) * stopped and sends the skb to the OSM's Rx handler and then increments * the offset. * Return Value: - * NONE. + * No. of napi packets processed. */ -static void rx_intr_handler(struct ring_info *ring_data) +static int rx_intr_handler(struct ring_info *ring_data, int budget) { int get_block, put_block; struct rx_curr_get_info get_info, put_info; struct RxD_t *rxdp; struct sk_buff *skb; - int pkt_cnt = 0; + int pkt_cnt = 0, napi_pkts = 0; int i; struct RxD1* rxdp1; struct RxD3* rxdp3; @@ -2977,7 +2996,7 @@ static void rx_intr_handler(struct ring_info *ring_data) DBG_PRINT(ERR_DBG, "%s: The skb is ", ring_data->dev->name); DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); - return; + return 0; } if (ring_data->rxd_mode == RXD_MODE_1) { rxdp1 = (struct RxD1*)rxdp; @@ -3014,9 +3033,10 @@ static void rx_intr_handler(struct ring_info *ring_data) rxdp = ring_data->rx_blocks[get_block].block_virt_addr; } - if(ring_data->nic->config.napi){ - ring_data->nic->pkts_to_process -= 1; - if (!ring_data->nic->pkts_to_process) + if (ring_data->nic->config.napi) { + budget--; + napi_pkts++; + if (!budget) break; } pkt_cnt++; @@ -3034,6 +3054,7 @@ static void rx_intr_handler(struct ring_info *ring_data) } } } + return(napi_pkts); } /** @@ -3730,14 +3751,19 @@ static void restore_xmsi_data(struct s2io_nic *nic) { struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64; - int i; + int i, msix_index; + + + if (nic->device_type == XFRAME_I_DEVICE) + return; for (i=0; i < MAX_REQUESTED_MSI_X; i++) { + msix_index = (i) ? ((i-1) * 8 + 1): 0; writeq(nic->msix_info[i].addr, &bar0->xmsi_address); writeq(nic->msix_info[i].data, &bar0->xmsi_data); - val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); + val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); writeq(val64, &bar0->xmsi_access); - if (wait_for_msix_trans(nic, i)) { + if (wait_for_msix_trans(nic, msix_index)) { DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); continue; } @@ -3748,13 +3774,17 @@ static void store_xmsi_data(struct s2io_nic *nic) { struct XENA_dev_config __iomem *bar0 = nic->bar0; u64 val64, addr, data; - int i; + int i, msix_index; + + if (nic->device_type == XFRAME_I_DEVICE) + return; /* Store and display */ for (i=0; i < MAX_REQUESTED_MSI_X; i++) { - val64 = (s2BIT(15) | vBIT(i, 26, 6)); + msix_index = (i) ? ((i-1) * 8 + 1): 0; + val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); writeq(val64, &bar0->xmsi_access); - if (wait_for_msix_trans(nic, i)) { + if (wait_for_msix_trans(nic, msix_index)) { DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); continue; } @@ -3770,11 +3800,11 @@ static void store_xmsi_data(struct s2io_nic *nic) static int s2io_enable_msi_x(struct s2io_nic *nic) { struct XENA_dev_config __iomem *bar0 = nic->bar0; - u64 tx_mat, rx_mat; + u64 rx_mat; u16 msi_control; /* Temp variable */ int ret, i, j, msix_indx = 1; - nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry), + nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry), GFP_KERNEL); if (!nic->entries) { DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ @@ -3783,10 +3813,12 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) return -ENOMEM; } nic->mac_control.stats_info->sw_stat.mem_allocated - += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + += (nic->num_entries * sizeof(struct msix_entry)); + + memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry)); nic->s2io_entries = - kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry), + kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry), GFP_KERNEL); if (!nic->s2io_entries) { DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", @@ -3794,60 +3826,52 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; kfree(nic->entries); nic->mac_control.stats_info->sw_stat.mem_freed - += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + += (nic->num_entries * sizeof(struct msix_entry)); return -ENOMEM; } nic->mac_control.stats_info->sw_stat.mem_allocated - += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); - - for (i=0; i< MAX_REQUESTED_MSI_X; i++) { - nic->entries[i].entry = i; - nic->s2io_entries[i].entry = i; + += (nic->num_entries * sizeof(struct s2io_msix_entry)); + memset(nic->s2io_entries, 0, + nic->num_entries * sizeof(struct s2io_msix_entry)); + + nic->entries[0].entry = 0; + nic->s2io_entries[0].entry = 0; + nic->s2io_entries[0].in_use = MSIX_FLG; + nic->s2io_entries[0].type = MSIX_ALARM_TYPE; + nic->s2io_entries[0].arg = &nic->mac_control.fifos; + + for (i = 1; i < nic->num_entries; i++) { + nic->entries[i].entry = ((i - 1) * 8) + 1; + nic->s2io_entries[i].entry = ((i - 1) * 8) + 1; nic->s2io_entries[i].arg = NULL; nic->s2io_entries[i].in_use = 0; } - tx_mat = readq(&bar0->tx_mat0_n[0]); - for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { - tx_mat |= TX_MAT_SET(i, msix_indx); - nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; - nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; - nic->s2io_entries[msix_indx].in_use = MSIX_FLG; - } - writeq(tx_mat, &bar0->tx_mat0_n[0]); - rx_mat = readq(&bar0->rx_mat); - for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { + for (j = 0; j < nic->config.rx_ring_num; j++) { rx_mat |= RX_MAT_SET(j, msix_indx); - nic->s2io_entries[msix_indx].arg - = &nic->mac_control.rings[j]; - nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; - nic->s2io_entries[msix_indx].in_use = MSIX_FLG; + nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j]; + nic->s2io_entries[j+1].type = MSIX_RING_TYPE; + nic->s2io_entries[j+1].in_use = MSIX_FLG; + msix_indx += 8; } writeq(rx_mat, &bar0->rx_mat); + readq(&bar0->rx_mat); - nic->avail_msix_vectors = 0; - ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); + ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries); /* We fail init if error or we get less vectors than min required */ - if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { - nic->avail_msix_vectors = ret; - ret = pci_enable_msix(nic->pdev, nic->entries, ret); - } if (ret) { DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); kfree(nic->entries); nic->mac_control.stats_info->sw_stat.mem_freed - += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + += (nic->num_entries * sizeof(struct msix_entry)); kfree(nic->s2io_entries); nic->mac_control.stats_info->sw_stat.mem_freed - += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); + += (nic->num_entries * sizeof(struct s2io_msix_entry)); nic->entries = NULL; nic->s2io_entries = NULL; - nic->avail_msix_vectors = 0; return -ENOMEM; } - if (!nic->avail_msix_vectors) - nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; /* * To enable MSI-X, MSI also needs to be enabled, due to a bug @@ -3919,7 +3943,7 @@ static void remove_msix_isr(struct s2io_nic *sp) int i; u16 msi_control; - for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { + for (i = 0; i < sp->num_entries; i++) { if (sp->s2io_entries[i].in_use == MSIX_REGISTERED_SUCCESS) { int vector = sp->entries[i].vector; @@ -3975,29 +3999,6 @@ static int s2io_open(struct net_device *dev) netif_carrier_off(dev); sp->last_link_state = 0; - if (sp->config.intr_type == MSI_X) { - int ret = s2io_enable_msi_x(sp); - - if (!ret) { - ret = s2io_test_msi(sp); - /* rollback MSI-X, will re-enable during add_isr() */ - remove_msix_isr(sp); - } - if (ret) { - - DBG_PRINT(ERR_DBG, - "%s: MSI-X requested but failed to enable\n", - dev->name); - sp->config.intr_type = INTA; - } - } - - /* NAPI doesn't work well with MSI(X) */ - if (sp->config.intr_type != INTA) { - if(sp->config.napi) - sp->config.napi = 0; - } - /* Initialize H/W and enable interrupts */ err = s2io_card_up(sp); if (err) { @@ -4020,12 +4021,12 @@ hw_init_failed: if (sp->entries) { kfree(sp->entries); sp->mac_control.stats_info->sw_stat.mem_freed - += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); + += (sp->num_entries * sizeof(struct msix_entry)); } if (sp->s2io_entries) { kfree(sp->s2io_entries); sp->mac_control.stats_info->sw_stat.mem_freed - += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); + += (sp->num_entries * sizeof(struct s2io_msix_entry)); } } return err; @@ -4165,15 +4166,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_LOCKED; } -#ifdef CONFIG_NETDEVICES_MULTIQUEUE if (sp->config.multiq) { if (__netif_subqueue_stopped(dev, fifo->fifo_no)) { spin_unlock_irqrestore(&fifo->tx_lock, flags); return NETDEV_TX_BUSY; } - } else -#endif - if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) { + } else if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) { if (netif_queue_stopped(dev)) { spin_unlock_irqrestore(&fifo->tx_lock, flags); return NETDEV_TX_BUSY; @@ -4237,16 +4235,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) txdp->Buffer_Pointer = pci_map_single(sp->pdev, fifo->ufo_in_band_v, sizeof(u64), PCI_DMA_TODEVICE); - if((txdp->Buffer_Pointer == 0) || - (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + if (pci_dma_mapping_error(txdp->Buffer_Pointer)) goto pci_map_failed; txdp++; } txdp->Buffer_Pointer = pci_map_single (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); - if((txdp->Buffer_Pointer == 0) || - (txdp->Buffer_Pointer == DMA_ERROR_CODE)) + if (pci_dma_mapping_error(txdp->Buffer_Pointer)) goto pci_map_failed; txdp->Host_Control = (unsigned long) skb; @@ -4327,40 +4323,71 @@ s2io_alarm_handle(unsigned long data) mod_timer(&sp->alarm_timer, jiffies + HZ / 2); } -static int s2io_chk_rx_buffers(struct ring_info *ring) -{ - if (fill_rx_buffers(ring) == -ENOMEM) { - DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); - DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); - } - return 0; -} - static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) { struct ring_info *ring = (struct ring_info *)dev_id; struct s2io_nic *sp = ring->nic; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + struct net_device *dev = sp->dev; - if (!is_s2io_card_up(sp)) + if (unlikely(!is_s2io_card_up(sp))) return IRQ_HANDLED; - rx_intr_handler(ring); - s2io_chk_rx_buffers(ring); + if (sp->config.napi) { + u8 __iomem *addr = NULL; + u8 val8 = 0; + + addr = (u8 __iomem *)&bar0->xmsi_mask_reg; + addr += (7 - ring->ring_no); + val8 = (ring->ring_no == 0) ? 0x7f : 0xff; + writeb(val8, addr); + val8 = readb(addr); + netif_rx_schedule(dev, &ring->napi); + } else { + rx_intr_handler(ring, 0); + s2io_chk_rx_buffers(ring); + } return IRQ_HANDLED; } static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) { - struct fifo_info *fifo = (struct fifo_info *)dev_id; - struct s2io_nic *sp = fifo->nic; + int i; + struct fifo_info *fifos = (struct fifo_info *)dev_id; + struct s2io_nic *sp = fifos->nic; + struct XENA_dev_config __iomem *bar0 = sp->bar0; + struct config_param *config = &sp->config; + u64 reason; - if (!is_s2io_card_up(sp)) + if (unlikely(!is_s2io_card_up(sp))) + return IRQ_NONE; + + reason = readq(&bar0->general_int_status); + if (unlikely(reason == S2IO_MINUS_ONE)) + /* Nothing much can be done. Get out */ return IRQ_HANDLED; - tx_intr_handler(fifo); - return IRQ_HANDLED; + if (reason & (GEN_INTR_TXPIC | GEN_INTR_TXTRAFFIC)) { + writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); + + if (reason & GEN_INTR_TXPIC) + s2io_txpic_intr_handle(sp); + + if (reason & GEN_INTR_TXTRAFFIC) + writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); + + for (i = 0; i < config->tx_fifo_num; i++) + tx_intr_handler(&fifos[i]); + + writeq(sp->general_int_mask, &bar0->general_int_mask); + readl(&bar0->general_int_status); + return IRQ_HANDLED; + } + /* The interrupt was not raised by us */ + return IRQ_NONE; } + static void s2io_txpic_intr_handle(struct s2io_nic *sp) { struct XENA_dev_config __iomem *bar0 = sp->bar0; @@ -4762,14 +4789,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) if (config->napi) { if (reason & GEN_INTR_RXTRAFFIC) { - if (likely(netif_rx_schedule_prep(dev, - &sp->napi))) { - __netif_rx_schedule(dev, &sp->napi); - writeq(S2IO_MINUS_ONE, - &bar0->rx_traffic_mask); - } else - writeq(S2IO_MINUS_ONE, - &bar0->rx_traffic_int); + netif_rx_schedule(dev, &sp->napi); + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); + writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); + readl(&bar0->rx_traffic_int); } } else { /* @@ -4781,7 +4804,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); for (i = 0; i < config->rx_ring_num; i++) - rx_intr_handler(&mac_control->rings[i]); + rx_intr_handler(&mac_control->rings[i], 0); } /* @@ -6836,10 +6859,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single( sp->pdev, (*skb)->data, size - NET_IP_ALIGN, PCI_DMA_FROMDEVICE); - if( (rxdp1->Buffer0_ptr == 0) || - (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { + if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) goto memalloc_failed; - } rxdp->Host_Control = (unsigned long) (*skb); } } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { @@ -6865,15 +6886,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, pci_map_single(sp->pdev, (*skb)->data, dev->mtu + 4, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer2_ptr == 0) || - (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { + if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) goto memalloc_failed; - } rxdp3->Buffer0_ptr = *temp0 = pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer0_ptr == 0) || - (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { + if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer2_ptr, dev->mtu + 4, PCI_DMA_FROMDEVICE); @@ -6885,8 +6903,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, rxdp3->Buffer1_ptr = *temp1 = pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, PCI_DMA_FROMDEVICE); - if( (rxdp3->Buffer1_ptr == 0) || - (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { + if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { pci_unmap_single (sp->pdev, (dma_addr_t)rxdp3->Buffer0_ptr, BUF0_LEN, PCI_DMA_FROMDEVICE); @@ -6951,7 +6968,7 @@ static int rxd_owner_bit_reset(struct s2io_nic *sp) &skb,(u64 *)&temp0_64, (u64 *)&temp1_64, (u64 *)&temp2_64, - size) == ENOMEM) { + size) == -ENOMEM) { return 0; } @@ -6984,62 +7001,62 @@ static int s2io_add_isr(struct s2io_nic * sp) /* After proper initialization of H/W, register ISR */ if (sp->config.intr_type == MSI_X) { - int i, msix_tx_cnt=0,msix_rx_cnt=0; - - for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { - if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { - sprintf(sp->desc[i], "%s:MSI-X-%d-TX", + int i, msix_rx_cnt = 0; + + for (i = 0; i < sp->num_entries; i++) { + if (sp->s2io_entries[i].in_use == MSIX_FLG) { + if (sp->s2io_entries[i].type == + MSIX_RING_TYPE) { + sprintf(sp->desc[i], "%s:MSI-X-%d-RX", + dev->name, i); + err = request_irq(sp->entries[i].vector, + s2io_msix_ring_handle, 0, + sp->desc[i], + sp->s2io_entries[i].arg); + } else if (sp->s2io_entries[i].type == + MSIX_ALARM_TYPE) { + sprintf(sp->desc[i], "%s:MSI-X-%d-TX", dev->name, i); - err = request_irq(sp->entries[i].vector, - s2io_msix_fifo_handle, 0, sp->desc[i], - sp->s2io_entries[i].arg); - /* If either data or addr is zero print it */ - if(!(sp->msix_info[i].addr && - sp->msix_info[i].data)) { - DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " - "Data:0x%llx\n",sp->desc[i], - (unsigned long long) - sp->msix_info[i].addr, - (unsigned long long) - sp->msix_info[i].data); - } else { - msix_tx_cnt++; + err = request_irq(sp->entries[i].vector, + s2io_msix_fifo_handle, 0, + sp->desc[i], + sp->s2io_entries[i].arg); + } - } else { - sprintf(sp->desc[i], "%s:MSI-X-%d-RX", - dev->name, i); - err = request_irq(sp->entries[i].vector, - s2io_msix_ring_handle, 0, sp->desc[i], - sp->s2io_entries[i].arg); - /* If either data or addr is zero print it */ - if(!(sp->msix_info[i].addr && + /* if either data or addr is zero print it. */ + if (!(sp->msix_info[i].addr && sp->msix_info[i].data)) { - DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " - "Data:0x%llx\n",sp->desc[i], + DBG_PRINT(ERR_DBG, + "%s @Addr:0x%llx Data:0x%llx\n", + sp->desc[i], (unsigned long long) sp->msix_info[i].addr, (unsigned long long) - sp->msix_info[i].data); - } else { + ntohl(sp->msix_info[i].data)); + } else msix_rx_cnt++; + if (err) { + remove_msix_isr(sp); + + DBG_PRINT(ERR_DBG, + "%s:MSI-X-%d registration " + "failed\n", dev->name, i); + + 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; } - if (err) { - remove_msix_isr(sp); - DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " - "failed\n", dev->name, i); - 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; } 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); + --msix_rx_cnt); + DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled" + " through alarm vector\n"); } } if (sp->config.intr_type == INTA) { @@ -7080,8 +7097,15 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) clear_bit(__S2IO_STATE_CARD_UP, &sp->state); /* Disable napi */ - if (config->napi) - napi_disable(&sp->napi); + if (sp->config.napi) { + int off = 0; + if (config->intr_type == MSI_X) { + for (; off < sp->config.rx_ring_num; off++) + napi_disable(&sp->mac_control.rings[off].napi); + } + else + napi_disable(&sp->napi); + } /* disable Tx and Rx traffic on the NIC */ if (do_io) @@ -7089,6 +7113,9 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) s2io_rem_isr(sp); + /* stop the tx queue, indicate link down */ + s2io_link(sp, LINK_DOWN); + /* Check if the device is Quiescent and then Reset the NIC */ while(do_io) { /* As per the HW requirement we need to replenish the @@ -7160,7 +7187,7 @@ static int s2io_card_up(struct s2io_nic * sp) for (i = 0; i < config->rx_ring_num; i++) { mac_control->rings[i].mtu = dev->mtu; - ret = fill_rx_buffers(&mac_control->rings[i]); + ret = fill_rx_buffers(&mac_control->rings[i], 1); if (ret) { DBG_PRINT(ERR_DBG, "%s: Out of memory in Open\n", dev->name); @@ -7173,8 +7200,15 @@ static int s2io_card_up(struct s2io_nic * sp) } /* Initialise napi */ - if (config->napi) - napi_enable(&sp->napi); + if (config->napi) { + int i; + if (config->intr_type == MSI_X) { + for (i = 0; i < sp->config.rx_ring_num; i++) + napi_enable(&sp->mac_control.rings[i].napi); + } else { + napi_enable(&sp->napi); + } + } /* Maintain the state prior to the open */ if (sp->promisc_flg) @@ -7214,17 +7248,19 @@ static int s2io_card_up(struct s2io_nic * sp) S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); + set_bit(__S2IO_STATE_CARD_UP, &sp->state); + /* Enable select interrupts */ en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); - if (sp->config.intr_type != INTA) - en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); - else { + if (sp->config.intr_type != INTA) { + interruptible = TX_TRAFFIC_INTR | TX_PIC_INTR; + en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); + } else { interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; interruptible |= TX_PIC_INTR; en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); } - set_bit(__S2IO_STATE_CARD_UP, &sp->state); return 0; } @@ -7582,12 +7618,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, DBG_PRINT(ERR_DBG, "tx fifos\n"); } -#ifndef CONFIG_NETDEVICES_MULTIQUEUE - if (multiq) { - DBG_PRINT(ERR_DBG, "s2io: Multiqueue support not enabled\n"); - multiq = 0; - } -#endif if (multiq) *dev_multiq = multiq; @@ -7615,9 +7645,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, rx_ring_num = MAX_RX_RINGS; } - if (*dev_intr_type != INTA) - napi = 0; - if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " "Defaulting to INTA\n"); @@ -7735,12 +7762,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) pci_disable_device(pdev); return -ENODEV; } -#ifdef CONFIG_NETDEVICES_MULTIQUEUE if (dev_multiq) dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num); else -#endif - dev = alloc_etherdev(sizeof(struct s2io_nic)); + dev = alloc_etherdev(sizeof(struct s2io_nic)); if (dev == NULL) { DBG_PRINT(ERR_DBG, "Device allocation failed\n"); pci_disable_device(pdev); @@ -7918,8 +7943,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) * will use eth_mac_addr() for dev->set_mac_address * mac address will be set every time dev->open() is called */ - netif_napi_add(dev, &sp->napi, s2io_poll, 32); - #ifdef CONFIG_NET_POLL_CONTROLLER dev->poll_controller = s2io_netpoll; #endif @@ -7933,10 +7956,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) dev->features |= NETIF_F_UFO; dev->features |= NETIF_F_HW_CSUM; } -#ifdef CONFIG_NETDEVICES_MULTIQUEUE - if (config->multiq) - dev->features |= NETIF_F_MULTI_QUEUE; -#endif dev->tx_timeout = &s2io_tx_watchdog; dev->watchdog_timeo = WATCH_DOG_TIMEOUT; INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); @@ -7963,6 +7982,32 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) } } + if (sp->config.intr_type == MSI_X) { + sp->num_entries = config->rx_ring_num + 1; + ret = s2io_enable_msi_x(sp); + + if (!ret) { + ret = s2io_test_msi(sp); + /* rollback MSI-X, will re-enable during add_isr() */ + remove_msix_isr(sp); + } + if (ret) { + + DBG_PRINT(ERR_DBG, + "%s: MSI-X requested but failed to enable\n", + dev->name); + sp->config.intr_type = INTA; + } + } + + if (config->intr_type == MSI_X) { + for (i = 0; i < config->rx_ring_num ; i++) + netif_napi_add(dev, &mac_control->rings[i].napi, + s2io_poll_msix, 64); + } else { + netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64); + } + /* Not needed for Herc */ if (sp->device_type & XFRAME_I_DEVICE) { /* @@ -8013,6 +8058,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) /* store mac addresses from CAM to s2io_nic structure */ do_s2io_store_unicast_mc(sp); + /* Configure MSIX vector for number of rings configured plus one */ + if ((sp->device_type == XFRAME_II_DEVICE) && + (config->intr_type == MSI_X)) + sp->num_entries = config->rx_ring_num + 1; + /* Store the values of the MSIX table in the s2io_nic structure */ store_xmsi_data(sp); /* reset Nic and bring it to known state */ @@ -8078,8 +8128,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) break; } - if (napi) + switch (sp->config.napi) { + case 0: + DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name); + break; + case 1: DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); + break; + } DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, sp->config.tx_fifo_num); @@ -8625,5 +8681,5 @@ static void s2io_io_resume(struct pci_dev *pdev) } netif_device_attach(netdev); - netif_wake_queue(netdev); + netif_tx_wake_all_queues(netdev); } |