diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 387 |
1 files changed, 174 insertions, 213 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e1fe3a0a7b0b..e72e0e099060 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -71,12 +71,13 @@ | |||
71 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
72 | #include <asm/io.h> | 72 | #include <asm/io.h> |
73 | #include <asm/div64.h> | 73 | #include <asm/div64.h> |
74 | #include <asm/irq.h> | ||
74 | 75 | ||
75 | /* local include */ | 76 | /* local include */ |
76 | #include "s2io.h" | 77 | #include "s2io.h" |
77 | #include "s2io-regs.h" | 78 | #include "s2io-regs.h" |
78 | 79 | ||
79 | #define DRV_VERSION "2.0.14.2" | 80 | #define DRV_VERSION "2.0.15.2" |
80 | 81 | ||
81 | /* S2io Driver name & version. */ | 82 | /* S2io Driver name & version. */ |
82 | static char s2io_driver_name[] = "Neterion"; | 83 | static char s2io_driver_name[] = "Neterion"; |
@@ -370,38 +371,50 @@ static const u64 fix_mac[] = { | |||
370 | END_SIGN | 371 | END_SIGN |
371 | }; | 372 | }; |
372 | 373 | ||
374 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | ||
375 | MODULE_LICENSE("GPL"); | ||
376 | MODULE_VERSION(DRV_VERSION); | ||
377 | |||
378 | |||
373 | /* Module Loadable parameters. */ | 379 | /* Module Loadable parameters. */ |
374 | static unsigned int tx_fifo_num = 1; | 380 | S2IO_PARM_INT(tx_fifo_num, 1); |
375 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | 381 | S2IO_PARM_INT(rx_ring_num, 1); |
376 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; | 382 | |
377 | static unsigned int rx_ring_num = 1; | 383 | |
378 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 384 | S2IO_PARM_INT(rx_ring_mode, 1); |
379 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; | 385 | S2IO_PARM_INT(use_continuous_tx_intrs, 1); |
380 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | 386 | S2IO_PARM_INT(rmac_pause_time, 0x100); |
381 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 387 | S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); |
382 | static unsigned int rx_ring_mode = 1; | 388 | S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); |
383 | static unsigned int use_continuous_tx_intrs = 1; | 389 | S2IO_PARM_INT(shared_splits, 0); |
384 | static unsigned int rmac_pause_time = 0x100; | 390 | S2IO_PARM_INT(tmac_util_period, 5); |
385 | static unsigned int mc_pause_threshold_q0q3 = 187; | 391 | S2IO_PARM_INT(rmac_util_period, 5); |
386 | static unsigned int mc_pause_threshold_q4q7 = 187; | 392 | S2IO_PARM_INT(bimodal, 0); |
387 | static unsigned int shared_splits; | 393 | S2IO_PARM_INT(l3l4hdr_size, 128); |
388 | static unsigned int tmac_util_period = 5; | ||
389 | static unsigned int rmac_util_period = 5; | ||
390 | static unsigned int bimodal = 0; | ||
391 | static unsigned int l3l4hdr_size = 128; | ||
392 | #ifndef CONFIG_S2IO_NAPI | ||
393 | static unsigned int indicate_max_pkts; | ||
394 | #endif | ||
395 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 394 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
396 | static unsigned int rxsync_frequency = 3; | 395 | S2IO_PARM_INT(rxsync_frequency, 3); |
397 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ | 396 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ |
398 | static unsigned int intr_type = 0; | 397 | S2IO_PARM_INT(intr_type, 0); |
399 | /* Large receive offload feature */ | 398 | /* Large receive offload feature */ |
400 | static unsigned int lro = 0; | 399 | S2IO_PARM_INT(lro, 0); |
401 | /* Max pkts to be aggregated by LRO at one time. If not specified, | 400 | /* Max pkts to be aggregated by LRO at one time. If not specified, |
402 | * aggregation happens until we hit max IP pkt size(64K) | 401 | * aggregation happens until we hit max IP pkt size(64K) |
403 | */ | 402 | */ |
404 | static unsigned int lro_max_pkts = 0xFFFF; | 403 | S2IO_PARM_INT(lro_max_pkts, 0xFFFF); |
404 | #ifndef CONFIG_S2IO_NAPI | ||
405 | S2IO_PARM_INT(indicate_max_pkts, 0); | ||
406 | #endif | ||
407 | |||
408 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | ||
409 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; | ||
410 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | ||
411 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; | ||
412 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | ||
413 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | ||
414 | |||
415 | module_param_array(tx_fifo_len, uint, NULL, 0); | ||
416 | module_param_array(rx_ring_sz, uint, NULL, 0); | ||
417 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
405 | 418 | ||
406 | /* | 419 | /* |
407 | * S2IO device table. | 420 | * S2IO device table. |
@@ -464,10 +477,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
464 | size += config->tx_cfg[i].fifo_len; | 477 | size += config->tx_cfg[i].fifo_len; |
465 | } | 478 | } |
466 | if (size > MAX_AVAILABLE_TXDS) { | 479 | if (size > MAX_AVAILABLE_TXDS) { |
467 | DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", | 480 | DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, "); |
468 | __FUNCTION__); | ||
469 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); | 481 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); |
470 | return FAILURE; | 482 | return -EINVAL; |
471 | } | 483 | } |
472 | 484 | ||
473 | lst_size = (sizeof(TxD_t) * config->max_txds); | 485 | lst_size = (sizeof(TxD_t) * config->max_txds); |
@@ -547,6 +559,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
547 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); | 559 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); |
548 | if (!nic->ufo_in_band_v) | 560 | if (!nic->ufo_in_band_v) |
549 | return -ENOMEM; | 561 | return -ENOMEM; |
562 | memset(nic->ufo_in_band_v, 0, size); | ||
550 | 563 | ||
551 | /* Allocation and initialization of RXDs in Rings */ | 564 | /* Allocation and initialization of RXDs in Rings */ |
552 | size = 0; | 565 | size = 0; |
@@ -1213,7 +1226,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1213 | break; | 1226 | break; |
1214 | } | 1227 | } |
1215 | 1228 | ||
1216 | /* Enable Tx FIFO partition 0. */ | 1229 | /* Enable all configured Tx FIFO partitions */ |
1217 | val64 = readq(&bar0->tx_fifo_partition_0); | 1230 | val64 = readq(&bar0->tx_fifo_partition_0); |
1218 | val64 |= (TX_FIFO_PARTITION_EN); | 1231 | val64 |= (TX_FIFO_PARTITION_EN); |
1219 | writeq(val64, &bar0->tx_fifo_partition_0); | 1232 | writeq(val64, &bar0->tx_fifo_partition_0); |
@@ -1650,7 +1663,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1650 | writeq(temp64, &bar0->general_int_mask); | 1663 | writeq(temp64, &bar0->general_int_mask); |
1651 | /* | 1664 | /* |
1652 | * If Hercules adapter enable GPIO otherwise | 1665 | * If Hercules adapter enable GPIO otherwise |
1653 | * disabled all PCIX, Flash, MDIO, IIC and GPIO | 1666 | * disable all PCIX, Flash, MDIO, IIC and GPIO |
1654 | * interrupts for now. | 1667 | * interrupts for now. |
1655 | * TODO | 1668 | * TODO |
1656 | */ | 1669 | */ |
@@ -2119,7 +2132,7 @@ static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, in | |||
2119 | frag->size, PCI_DMA_TODEVICE); | 2132 | frag->size, PCI_DMA_TODEVICE); |
2120 | } | 2133 | } |
2121 | } | 2134 | } |
2122 | txdlp->Host_Control = 0; | 2135 | memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); |
2123 | return(skb); | 2136 | return(skb); |
2124 | } | 2137 | } |
2125 | 2138 | ||
@@ -2371,9 +2384,14 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2371 | skb->data = (void *) (unsigned long)tmp; | 2384 | skb->data = (void *) (unsigned long)tmp; |
2372 | skb->tail = (void *) (unsigned long)tmp; | 2385 | skb->tail = (void *) (unsigned long)tmp; |
2373 | 2386 | ||
2374 | ((RxD3_t*)rxdp)->Buffer0_ptr = | 2387 | if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) |
2375 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | 2388 | ((RxD3_t*)rxdp)->Buffer0_ptr = |
2389 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | ||
2376 | PCI_DMA_FROMDEVICE); | 2390 | PCI_DMA_FROMDEVICE); |
2391 | else | ||
2392 | pci_dma_sync_single_for_device(nic->pdev, | ||
2393 | (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, | ||
2394 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2377 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2395 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
2378 | if (nic->rxd_mode == RXD_MODE_3B) { | 2396 | if (nic->rxd_mode == RXD_MODE_3B) { |
2379 | /* Two buffer mode */ | 2397 | /* Two buffer mode */ |
@@ -2386,10 +2404,13 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2386 | (nic->pdev, skb->data, dev->mtu + 4, | 2404 | (nic->pdev, skb->data, dev->mtu + 4, |
2387 | PCI_DMA_FROMDEVICE); | 2405 | PCI_DMA_FROMDEVICE); |
2388 | 2406 | ||
2389 | /* Buffer-1 will be dummy buffer not used */ | 2407 | /* Buffer-1 will be dummy buffer. Not used */ |
2390 | ((RxD3_t*)rxdp)->Buffer1_ptr = | 2408 | if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { |
2391 | pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, | 2409 | ((RxD3_t*)rxdp)->Buffer1_ptr = |
2392 | PCI_DMA_FROMDEVICE); | 2410 | pci_map_single(nic->pdev, |
2411 | ba->ba_1, BUF1_LEN, | ||
2412 | PCI_DMA_FROMDEVICE); | ||
2413 | } | ||
2393 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); | 2414 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); |
2394 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 | 2415 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 |
2395 | (dev->mtu + 4); | 2416 | (dev->mtu + 4); |
@@ -2614,23 +2635,23 @@ no_rx: | |||
2614 | } | 2635 | } |
2615 | #endif | 2636 | #endif |
2616 | 2637 | ||
2638 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2617 | /** | 2639 | /** |
2618 | * s2io_netpoll - Rx interrupt service handler for netpoll support | 2640 | * s2io_netpoll - netpoll event handler entry point |
2619 | * @dev : pointer to the device structure. | 2641 | * @dev : pointer to the device structure. |
2620 | * Description: | 2642 | * Description: |
2621 | * Polling 'interrupt' - used by things like netconsole to send skbs | 2643 | * This function will be called by upper layer to check for events on the |
2622 | * without having to re-enable interrupts. It's not called while | 2644 | * interface in situations where interrupts are disabled. It is used for |
2623 | * the interrupt routine is executing. | 2645 | * specific in-kernel networking tasks, such as remote consoles and kernel |
2646 | * debugging over the network (example netdump in RedHat). | ||
2624 | */ | 2647 | */ |
2625 | |||
2626 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2627 | static void s2io_netpoll(struct net_device *dev) | 2648 | static void s2io_netpoll(struct net_device *dev) |
2628 | { | 2649 | { |
2629 | nic_t *nic = dev->priv; | 2650 | nic_t *nic = dev->priv; |
2630 | mac_info_t *mac_control; | 2651 | mac_info_t *mac_control; |
2631 | struct config_param *config; | 2652 | struct config_param *config; |
2632 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2653 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
2633 | u64 val64; | 2654 | u64 val64 = 0xFFFFFFFFFFFFFFFFULL; |
2634 | int i; | 2655 | int i; |
2635 | 2656 | ||
2636 | disable_irq(dev->irq); | 2657 | disable_irq(dev->irq); |
@@ -2639,9 +2660,17 @@ static void s2io_netpoll(struct net_device *dev) | |||
2639 | mac_control = &nic->mac_control; | 2660 | mac_control = &nic->mac_control; |
2640 | config = &nic->config; | 2661 | config = &nic->config; |
2641 | 2662 | ||
2642 | val64 = readq(&bar0->rx_traffic_int); | ||
2643 | writeq(val64, &bar0->rx_traffic_int); | 2663 | writeq(val64, &bar0->rx_traffic_int); |
2664 | writeq(val64, &bar0->tx_traffic_int); | ||
2644 | 2665 | ||
2666 | /* we need to free up the transmitted skbufs or else netpoll will | ||
2667 | * run out of skbs and will fail and eventually netpoll application such | ||
2668 | * as netdump will fail. | ||
2669 | */ | ||
2670 | for (i = 0; i < config->tx_fifo_num; i++) | ||
2671 | tx_intr_handler(&mac_control->fifos[i]); | ||
2672 | |||
2673 | /* check for received packet and indicate up to network */ | ||
2645 | for (i = 0; i < config->rx_ring_num; i++) | 2674 | for (i = 0; i < config->rx_ring_num; i++) |
2646 | rx_intr_handler(&mac_control->rings[i]); | 2675 | rx_intr_handler(&mac_control->rings[i]); |
2647 | 2676 | ||
@@ -2708,7 +2737,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2708 | /* If your are next to put index then it's FIFO full condition */ | 2737 | /* If your are next to put index then it's FIFO full condition */ |
2709 | if ((get_block == put_block) && | 2738 | if ((get_block == put_block) && |
2710 | (get_info.offset + 1) == put_info.offset) { | 2739 | (get_info.offset + 1) == put_info.offset) { |
2711 | DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name); | 2740 | DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); |
2712 | break; | 2741 | break; |
2713 | } | 2742 | } |
2714 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); | 2743 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); |
@@ -2728,18 +2757,15 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2728 | HEADER_SNAP_SIZE, | 2757 | HEADER_SNAP_SIZE, |
2729 | PCI_DMA_FROMDEVICE); | 2758 | PCI_DMA_FROMDEVICE); |
2730 | } else if (nic->rxd_mode == RXD_MODE_3B) { | 2759 | } else if (nic->rxd_mode == RXD_MODE_3B) { |
2731 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2760 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2732 | ((RxD3_t*)rxdp)->Buffer0_ptr, | 2761 | ((RxD3_t*)rxdp)->Buffer0_ptr, |
2733 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2762 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2734 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2763 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2735 | ((RxD3_t*)rxdp)->Buffer1_ptr, | ||
2736 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2737 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2738 | ((RxD3_t*)rxdp)->Buffer2_ptr, | 2764 | ((RxD3_t*)rxdp)->Buffer2_ptr, |
2739 | dev->mtu + 4, | 2765 | dev->mtu + 4, |
2740 | PCI_DMA_FROMDEVICE); | 2766 | PCI_DMA_FROMDEVICE); |
2741 | } else { | 2767 | } else { |
2742 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2768 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2743 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, | 2769 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, |
2744 | PCI_DMA_FROMDEVICE); | 2770 | PCI_DMA_FROMDEVICE); |
2745 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2771 | pci_unmap_single(nic->pdev, (dma_addr_t) |
@@ -3327,7 +3353,7 @@ static void s2io_reset(nic_t * sp) | |||
3327 | 3353 | ||
3328 | /* Clear certain PCI/PCI-X fields after reset */ | 3354 | /* Clear certain PCI/PCI-X fields after reset */ |
3329 | if (sp->device_type == XFRAME_II_DEVICE) { | 3355 | if (sp->device_type == XFRAME_II_DEVICE) { |
3330 | /* Clear parity err detect bit */ | 3356 | /* Clear "detected parity error" bit */ |
3331 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); | 3357 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); |
3332 | 3358 | ||
3333 | /* Clearing PCIX Ecc status register */ | 3359 | /* Clearing PCIX Ecc status register */ |
@@ -3528,7 +3554,7 @@ static void restore_xmsi_data(nic_t *nic) | |||
3528 | u64 val64; | 3554 | u64 val64; |
3529 | int i; | 3555 | int i; |
3530 | 3556 | ||
3531 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3557 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3532 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3558 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3533 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3559 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3534 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); | 3560 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); |
@@ -3547,7 +3573,7 @@ static void store_xmsi_data(nic_t *nic) | |||
3547 | int i; | 3573 | int i; |
3548 | 3574 | ||
3549 | /* Store and display */ | 3575 | /* Store and display */ |
3550 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3576 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3551 | val64 = (BIT(15) | vBIT(i, 26, 6)); | 3577 | val64 = (BIT(15) | vBIT(i, 26, 6)); |
3552 | writeq(val64, &bar0->xmsi_access); | 3578 | writeq(val64, &bar0->xmsi_access); |
3553 | if (wait_for_msix_trans(nic, i)) { | 3579 | if (wait_for_msix_trans(nic, i)) { |
@@ -3808,13 +3834,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3808 | TxD_t *txdp; | 3834 | TxD_t *txdp; |
3809 | TxFIFO_element_t __iomem *tx_fifo; | 3835 | TxFIFO_element_t __iomem *tx_fifo; |
3810 | unsigned long flags; | 3836 | unsigned long flags; |
3811 | #ifdef NETIF_F_TSO | ||
3812 | int mss; | ||
3813 | #endif | ||
3814 | u16 vlan_tag = 0; | 3837 | u16 vlan_tag = 0; |
3815 | int vlan_priority = 0; | 3838 | int vlan_priority = 0; |
3816 | mac_info_t *mac_control; | 3839 | mac_info_t *mac_control; |
3817 | struct config_param *config; | 3840 | struct config_param *config; |
3841 | int offload_type; | ||
3818 | 3842 | ||
3819 | mac_control = &sp->mac_control; | 3843 | mac_control = &sp->mac_control; |
3820 | config = &sp->config; | 3844 | config = &sp->config; |
@@ -3862,13 +3886,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3862 | return 0; | 3886 | return 0; |
3863 | } | 3887 | } |
3864 | 3888 | ||
3865 | txdp->Control_1 = 0; | 3889 | offload_type = s2io_offload_type(skb); |
3866 | txdp->Control_2 = 0; | ||
3867 | #ifdef NETIF_F_TSO | 3890 | #ifdef NETIF_F_TSO |
3868 | mss = skb_shinfo(skb)->gso_size; | 3891 | if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { |
3869 | if (skb_shinfo(skb)->gso_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { | ||
3870 | txdp->Control_1 |= TXD_TCP_LSO_EN; | 3892 | txdp->Control_1 |= TXD_TCP_LSO_EN; |
3871 | txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); | 3893 | txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); |
3872 | } | 3894 | } |
3873 | #endif | 3895 | #endif |
3874 | if (skb->ip_summed == CHECKSUM_HW) { | 3896 | if (skb->ip_summed == CHECKSUM_HW) { |
@@ -3886,10 +3908,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3886 | } | 3908 | } |
3887 | 3909 | ||
3888 | frg_len = skb->len - skb->data_len; | 3910 | frg_len = skb->len - skb->data_len; |
3889 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) { | 3911 | if (offload_type == SKB_GSO_UDP) { |
3890 | int ufo_size; | 3912 | int ufo_size; |
3891 | 3913 | ||
3892 | ufo_size = skb_shinfo(skb)->gso_size; | 3914 | ufo_size = s2io_udp_mss(skb); |
3893 | ufo_size &= ~7; | 3915 | ufo_size &= ~7; |
3894 | txdp->Control_1 |= TXD_UFO_EN; | 3916 | txdp->Control_1 |= TXD_UFO_EN; |
3895 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); | 3917 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); |
@@ -3906,16 +3928,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3906 | sp->ufo_in_band_v, | 3928 | sp->ufo_in_band_v, |
3907 | sizeof(u64), PCI_DMA_TODEVICE); | 3929 | sizeof(u64), PCI_DMA_TODEVICE); |
3908 | txdp++; | 3930 | txdp++; |
3909 | txdp->Control_1 = 0; | ||
3910 | txdp->Control_2 = 0; | ||
3911 | } | 3931 | } |
3912 | 3932 | ||
3913 | txdp->Buffer_Pointer = pci_map_single | 3933 | txdp->Buffer_Pointer = pci_map_single |
3914 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 3934 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
3915 | txdp->Host_Control = (unsigned long) skb; | 3935 | txdp->Host_Control = (unsigned long) skb; |
3916 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); | 3936 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); |
3917 | 3937 | if (offload_type == SKB_GSO_UDP) | |
3918 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | ||
3919 | txdp->Control_1 |= TXD_UFO_EN; | 3938 | txdp->Control_1 |= TXD_UFO_EN; |
3920 | 3939 | ||
3921 | frg_cnt = skb_shinfo(skb)->nr_frags; | 3940 | frg_cnt = skb_shinfo(skb)->nr_frags; |
@@ -3930,12 +3949,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3930 | (sp->pdev, frag->page, frag->page_offset, | 3949 | (sp->pdev, frag->page, frag->page_offset, |
3931 | frag->size, PCI_DMA_TODEVICE); | 3950 | frag->size, PCI_DMA_TODEVICE); |
3932 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); | 3951 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); |
3933 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | 3952 | if (offload_type == SKB_GSO_UDP) |
3934 | txdp->Control_1 |= TXD_UFO_EN; | 3953 | txdp->Control_1 |= TXD_UFO_EN; |
3935 | } | 3954 | } |
3936 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; | 3955 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; |
3937 | 3956 | ||
3938 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | 3957 | if (offload_type == SKB_GSO_UDP) |
3939 | frg_cnt++; /* as Txd0 was used for inband header */ | 3958 | frg_cnt++; /* as Txd0 was used for inband header */ |
3940 | 3959 | ||
3941 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 3960 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
@@ -3944,13 +3963,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3944 | 3963 | ||
3945 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 3964 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
3946 | TX_FIFO_LAST_LIST); | 3965 | TX_FIFO_LAST_LIST); |
3947 | 3966 | if (offload_type) | |
3948 | #ifdef NETIF_F_TSO | ||
3949 | if (mss) | ||
3950 | val64 |= TX_FIFO_SPECIAL_FUNC; | ||
3951 | #endif | ||
3952 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDP) | ||
3953 | val64 |= TX_FIFO_SPECIAL_FUNC; | 3967 | val64 |= TX_FIFO_SPECIAL_FUNC; |
3968 | |||
3954 | writeq(val64, &tx_fifo->List_Control); | 3969 | writeq(val64, &tx_fifo->List_Control); |
3955 | 3970 | ||
3956 | mmiowb(); | 3971 | mmiowb(); |
@@ -3984,13 +3999,41 @@ s2io_alarm_handle(unsigned long data) | |||
3984 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 3999 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
3985 | } | 4000 | } |
3986 | 4001 | ||
4002 | static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) | ||
4003 | { | ||
4004 | int rxb_size, level; | ||
4005 | |||
4006 | if (!sp->lro) { | ||
4007 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4008 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4009 | |||
4010 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4011 | int ret; | ||
4012 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4013 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4014 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4015 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4016 | __FUNCTION__); | ||
4017 | clear_bit(0, (&sp->tasklet_status)); | ||
4018 | return -1; | ||
4019 | } | ||
4020 | clear_bit(0, (&sp->tasklet_status)); | ||
4021 | } else if (level == LOW) | ||
4022 | tasklet_schedule(&sp->task); | ||
4023 | |||
4024 | } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4025 | DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); | ||
4026 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4027 | } | ||
4028 | return 0; | ||
4029 | } | ||
4030 | |||
3987 | static irqreturn_t | 4031 | static irqreturn_t |
3988 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | 4032 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) |
3989 | { | 4033 | { |
3990 | struct net_device *dev = (struct net_device *) dev_id; | 4034 | struct net_device *dev = (struct net_device *) dev_id; |
3991 | nic_t *sp = dev->priv; | 4035 | nic_t *sp = dev->priv; |
3992 | int i; | 4036 | int i; |
3993 | int ret; | ||
3994 | mac_info_t *mac_control; | 4037 | mac_info_t *mac_control; |
3995 | struct config_param *config; | 4038 | struct config_param *config; |
3996 | 4039 | ||
@@ -4012,35 +4055,8 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4012 | * reallocate the buffers from the interrupt handler itself, | 4055 | * reallocate the buffers from the interrupt handler itself, |
4013 | * else schedule a tasklet to reallocate the buffers. | 4056 | * else schedule a tasklet to reallocate the buffers. |
4014 | */ | 4057 | */ |
4015 | for (i = 0; i < config->rx_ring_num; i++) { | 4058 | for (i = 0; i < config->rx_ring_num; i++) |
4016 | if (!sp->lro) { | 4059 | s2io_chk_rx_buffers(sp, i); |
4017 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4018 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4019 | |||
4020 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4021 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4022 | dev->name); | ||
4023 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4024 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4025 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4026 | dev->name); | ||
4027 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4028 | clear_bit(0, (&sp->tasklet_status)); | ||
4029 | atomic_dec(&sp->isr_cnt); | ||
4030 | return IRQ_HANDLED; | ||
4031 | } | ||
4032 | clear_bit(0, (&sp->tasklet_status)); | ||
4033 | } else if (level == LOW) { | ||
4034 | tasklet_schedule(&sp->task); | ||
4035 | } | ||
4036 | } | ||
4037 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4038 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4039 | dev->name); | ||
4040 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4041 | break; | ||
4042 | } | ||
4043 | } | ||
4044 | 4060 | ||
4045 | atomic_dec(&sp->isr_cnt); | 4061 | atomic_dec(&sp->isr_cnt); |
4046 | return IRQ_HANDLED; | 4062 | return IRQ_HANDLED; |
@@ -4051,39 +4067,13 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4051 | { | 4067 | { |
4052 | ring_info_t *ring = (ring_info_t *)dev_id; | 4068 | ring_info_t *ring = (ring_info_t *)dev_id; |
4053 | nic_t *sp = ring->nic; | 4069 | nic_t *sp = ring->nic; |
4054 | struct net_device *dev = (struct net_device *) dev_id; | ||
4055 | int rxb_size, level, rng_n; | ||
4056 | 4070 | ||
4057 | atomic_inc(&sp->isr_cnt); | 4071 | atomic_inc(&sp->isr_cnt); |
4058 | rx_intr_handler(ring); | ||
4059 | |||
4060 | rng_n = ring->ring_no; | ||
4061 | if (!sp->lro) { | ||
4062 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4063 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4064 | 4072 | ||
4065 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | 4073 | rx_intr_handler(ring); |
4066 | int ret; | 4074 | s2io_chk_rx_buffers(sp, ring->ring_no); |
4067 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4068 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4069 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4070 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4071 | __FUNCTION__); | ||
4072 | clear_bit(0, (&sp->tasklet_status)); | ||
4073 | return IRQ_HANDLED; | ||
4074 | } | ||
4075 | clear_bit(0, (&sp->tasklet_status)); | ||
4076 | } else if (level == LOW) { | ||
4077 | tasklet_schedule(&sp->task); | ||
4078 | } | ||
4079 | } | ||
4080 | else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4081 | DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); | ||
4082 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4083 | } | ||
4084 | 4075 | ||
4085 | atomic_dec(&sp->isr_cnt); | 4076 | atomic_dec(&sp->isr_cnt); |
4086 | |||
4087 | return IRQ_HANDLED; | 4077 | return IRQ_HANDLED; |
4088 | } | 4078 | } |
4089 | 4079 | ||
@@ -4248,37 +4238,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
4248 | * else schedule a tasklet to reallocate the buffers. | 4238 | * else schedule a tasklet to reallocate the buffers. |
4249 | */ | 4239 | */ |
4250 | #ifndef CONFIG_S2IO_NAPI | 4240 | #ifndef CONFIG_S2IO_NAPI |
4251 | for (i = 0; i < config->rx_ring_num; i++) { | 4241 | for (i = 0; i < config->rx_ring_num; i++) |
4252 | if (!sp->lro) { | 4242 | s2io_chk_rx_buffers(sp, i); |
4253 | int ret; | ||
4254 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4255 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4256 | |||
4257 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4258 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4259 | dev->name); | ||
4260 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4261 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4262 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4263 | dev->name); | ||
4264 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4265 | clear_bit(0, (&sp->tasklet_status)); | ||
4266 | atomic_dec(&sp->isr_cnt); | ||
4267 | writeq(org_mask, &bar0->general_int_mask); | ||
4268 | return IRQ_HANDLED; | ||
4269 | } | ||
4270 | clear_bit(0, (&sp->tasklet_status)); | ||
4271 | } else if (level == LOW) { | ||
4272 | tasklet_schedule(&sp->task); | ||
4273 | } | ||
4274 | } | ||
4275 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4276 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4277 | dev->name); | ||
4278 | DBG_PRINT(ERR_DBG, " in Rx intr!!\n"); | ||
4279 | break; | ||
4280 | } | ||
4281 | } | ||
4282 | #endif | 4243 | #endif |
4283 | writeq(org_mask, &bar0->general_int_mask); | 4244 | writeq(org_mask, &bar0->general_int_mask); |
4284 | atomic_dec(&sp->isr_cnt); | 4245 | atomic_dec(&sp->isr_cnt); |
@@ -4308,6 +4269,8 @@ static void s2io_updt_stats(nic_t *sp) | |||
4308 | if (cnt == 5) | 4269 | if (cnt == 5) |
4309 | break; /* Updt failed */ | 4270 | break; /* Updt failed */ |
4310 | } while(1); | 4271 | } while(1); |
4272 | } else { | ||
4273 | memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); | ||
4311 | } | 4274 | } |
4312 | } | 4275 | } |
4313 | 4276 | ||
@@ -4942,7 +4905,8 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) | |||
4942 | } | 4905 | } |
4943 | static void s2io_vpd_read(nic_t *nic) | 4906 | static void s2io_vpd_read(nic_t *nic) |
4944 | { | 4907 | { |
4945 | u8 vpd_data[256],data; | 4908 | u8 *vpd_data; |
4909 | u8 data; | ||
4946 | int i=0, cnt, fail = 0; | 4910 | int i=0, cnt, fail = 0; |
4947 | int vpd_addr = 0x80; | 4911 | int vpd_addr = 0x80; |
4948 | 4912 | ||
@@ -4955,6 +4919,10 @@ static void s2io_vpd_read(nic_t *nic) | |||
4955 | vpd_addr = 0x50; | 4919 | vpd_addr = 0x50; |
4956 | } | 4920 | } |
4957 | 4921 | ||
4922 | vpd_data = kmalloc(256, GFP_KERNEL); | ||
4923 | if (!vpd_data) | ||
4924 | return; | ||
4925 | |||
4958 | for (i = 0; i < 256; i +=4 ) { | 4926 | for (i = 0; i < 256; i +=4 ) { |
4959 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); | 4927 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); |
4960 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); | 4928 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); |
@@ -4977,6 +4945,7 @@ static void s2io_vpd_read(nic_t *nic) | |||
4977 | memset(nic->product_name, 0, vpd_data[1]); | 4945 | memset(nic->product_name, 0, vpd_data[1]); |
4978 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); | 4946 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); |
4979 | } | 4947 | } |
4948 | kfree(vpd_data); | ||
4980 | } | 4949 | } |
4981 | 4950 | ||
4982 | /** | 4951 | /** |
@@ -5295,7 +5264,7 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
5295 | else | 5264 | else |
5296 | *data = 0; | 5265 | *data = 0; |
5297 | 5266 | ||
5298 | return 0; | 5267 | return *data; |
5299 | } | 5268 | } |
5300 | 5269 | ||
5301 | /** | 5270 | /** |
@@ -5753,6 +5722,19 @@ static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
5753 | return 0; | 5722 | return 0; |
5754 | } | 5723 | } |
5755 | 5724 | ||
5725 | static u32 s2io_ethtool_op_get_tso(struct net_device *dev) | ||
5726 | { | ||
5727 | return (dev->features & NETIF_F_TSO) != 0; | ||
5728 | } | ||
5729 | static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) | ||
5730 | { | ||
5731 | if (data) | ||
5732 | dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); | ||
5733 | else | ||
5734 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
5735 | |||
5736 | return 0; | ||
5737 | } | ||
5756 | 5738 | ||
5757 | static struct ethtool_ops netdev_ethtool_ops = { | 5739 | static struct ethtool_ops netdev_ethtool_ops = { |
5758 | .get_settings = s2io_ethtool_gset, | 5740 | .get_settings = s2io_ethtool_gset, |
@@ -5773,8 +5755,8 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
5773 | .get_sg = ethtool_op_get_sg, | 5755 | .get_sg = ethtool_op_get_sg, |
5774 | .set_sg = ethtool_op_set_sg, | 5756 | .set_sg = ethtool_op_set_sg, |
5775 | #ifdef NETIF_F_TSO | 5757 | #ifdef NETIF_F_TSO |
5776 | .get_tso = ethtool_op_get_tso, | 5758 | .get_tso = s2io_ethtool_op_get_tso, |
5777 | .set_tso = ethtool_op_set_tso, | 5759 | .set_tso = s2io_ethtool_op_set_tso, |
5778 | #endif | 5760 | #endif |
5779 | .get_ufo = ethtool_op_get_ufo, | 5761 | .get_ufo = ethtool_op_get_ufo, |
5780 | .set_ufo = ethtool_op_set_ufo, | 5762 | .set_ufo = ethtool_op_set_ufo, |
@@ -6337,7 +6319,7 @@ static int s2io_card_up(nic_t * sp) | |||
6337 | s2io_set_multicast(dev); | 6319 | s2io_set_multicast(dev); |
6338 | 6320 | ||
6339 | if (sp->lro) { | 6321 | if (sp->lro) { |
6340 | /* Initialize max aggregatable pkts based on MTU */ | 6322 | /* Initialize max aggregatable pkts per session based on MTU */ |
6341 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; | 6323 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; |
6342 | /* Check if we can use(if specified) user provided value */ | 6324 | /* Check if we can use(if specified) user provided value */ |
6343 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) | 6325 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) |
@@ -6438,7 +6420,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
6438 | * @cksum : FCS checksum of the frame. | 6420 | * @cksum : FCS checksum of the frame. |
6439 | * @ring_no : the ring from which this RxD was extracted. | 6421 | * @ring_no : the ring from which this RxD was extracted. |
6440 | * Description: | 6422 | * Description: |
6441 | * This function is called by the Tx interrupt serivce routine to perform | 6423 | * This function is called by the Rx interrupt serivce routine to perform |
6442 | * some OS related operations on the SKB before passing it to the upper | 6424 | * some OS related operations on the SKB before passing it to the upper |
6443 | * layers. It mainly checks if the checksum is OK, if so adds it to the | 6425 | * layers. It mainly checks if the checksum is OK, if so adds it to the |
6444 | * SKBs cksum variable, increments the Rx packet count and passes the SKB | 6426 | * SKBs cksum variable, increments the Rx packet count and passes the SKB |
@@ -6698,33 +6680,6 @@ static void s2io_init_pci(nic_t * sp) | |||
6698 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 6680 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
6699 | } | 6681 | } |
6700 | 6682 | ||
6701 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | ||
6702 | MODULE_LICENSE("GPL"); | ||
6703 | MODULE_VERSION(DRV_VERSION); | ||
6704 | |||
6705 | module_param(tx_fifo_num, int, 0); | ||
6706 | module_param(rx_ring_num, int, 0); | ||
6707 | module_param(rx_ring_mode, int, 0); | ||
6708 | module_param_array(tx_fifo_len, uint, NULL, 0); | ||
6709 | module_param_array(rx_ring_sz, uint, NULL, 0); | ||
6710 | module_param_array(rts_frm_len, uint, NULL, 0); | ||
6711 | module_param(use_continuous_tx_intrs, int, 1); | ||
6712 | module_param(rmac_pause_time, int, 0); | ||
6713 | module_param(mc_pause_threshold_q0q3, int, 0); | ||
6714 | module_param(mc_pause_threshold_q4q7, int, 0); | ||
6715 | module_param(shared_splits, int, 0); | ||
6716 | module_param(tmac_util_period, int, 0); | ||
6717 | module_param(rmac_util_period, int, 0); | ||
6718 | module_param(bimodal, bool, 0); | ||
6719 | module_param(l3l4hdr_size, int , 0); | ||
6720 | #ifndef CONFIG_S2IO_NAPI | ||
6721 | module_param(indicate_max_pkts, int, 0); | ||
6722 | #endif | ||
6723 | module_param(rxsync_frequency, int, 0); | ||
6724 | module_param(intr_type, int, 0); | ||
6725 | module_param(lro, int, 0); | ||
6726 | module_param(lro_max_pkts, int, 0); | ||
6727 | |||
6728 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | 6683 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) |
6729 | { | 6684 | { |
6730 | if ( tx_fifo_num > 8) { | 6685 | if ( tx_fifo_num > 8) { |
@@ -6832,8 +6787,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6832 | } | 6787 | } |
6833 | if (dev_intr_type != MSI_X) { | 6788 | if (dev_intr_type != MSI_X) { |
6834 | if (pci_request_regions(pdev, s2io_driver_name)) { | 6789 | if (pci_request_regions(pdev, s2io_driver_name)) { |
6835 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | 6790 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"); |
6836 | pci_disable_device(pdev); | 6791 | pci_disable_device(pdev); |
6837 | return -ENODEV; | 6792 | return -ENODEV; |
6838 | } | 6793 | } |
6839 | } | 6794 | } |
@@ -6957,7 +6912,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6957 | /* initialize the shared memory used by the NIC and the host */ | 6912 | /* initialize the shared memory used by the NIC and the host */ |
6958 | if (init_shared_mem(sp)) { | 6913 | if (init_shared_mem(sp)) { |
6959 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 6914 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
6960 | __FUNCTION__); | 6915 | dev->name); |
6961 | ret = -ENOMEM; | 6916 | ret = -ENOMEM; |
6962 | goto mem_alloc_failed; | 6917 | goto mem_alloc_failed; |
6963 | } | 6918 | } |
@@ -7094,6 +7049,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7094 | dev->addr_len = ETH_ALEN; | 7049 | dev->addr_len = ETH_ALEN; |
7095 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 7050 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
7096 | 7051 | ||
7052 | /* reset Nic and bring it to known state */ | ||
7053 | s2io_reset(sp); | ||
7054 | |||
7097 | /* | 7055 | /* |
7098 | * Initialize the tasklet status and link state flags | 7056 | * Initialize the tasklet status and link state flags |
7099 | * and the card state parameter | 7057 | * and the card state parameter |
@@ -7131,11 +7089,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7131 | goto register_failed; | 7089 | goto register_failed; |
7132 | } | 7090 | } |
7133 | s2io_vpd_read(sp); | 7091 | s2io_vpd_read(sp); |
7134 | DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); | ||
7135 | DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", | ||
7136 | get_xena_rev_id(sp->pdev), | ||
7137 | s2io_driver_version); | ||
7138 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); | 7092 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); |
7093 | DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, | ||
7094 | sp->product_name, get_xena_rev_id(sp->pdev)); | ||
7095 | DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, | ||
7096 | s2io_driver_version); | ||
7139 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " | 7097 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " |
7140 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | 7098 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, |
7141 | sp->def_mac_addr[0].mac_addr[0], | 7099 | sp->def_mac_addr[0].mac_addr[0], |
@@ -7436,8 +7394,13 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7436 | if (ip->ihl != 5) /* IP has options */ | 7394 | if (ip->ihl != 5) /* IP has options */ |
7437 | return -1; | 7395 | return -1; |
7438 | 7396 | ||
7397 | /* If we see CE codepoint in IP header, packet is not mergeable */ | ||
7398 | if (INET_ECN_is_ce(ipv4_get_dsfield(ip))) | ||
7399 | return -1; | ||
7400 | |||
7401 | /* If we see ECE or CWR flags in TCP header, packet is not mergeable */ | ||
7439 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || | 7402 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || |
7440 | !tcp->ack) { | 7403 | tcp->ece || tcp->cwr || !tcp->ack) { |
7441 | /* | 7404 | /* |
7442 | * Currently recognize only the ack control word and | 7405 | * Currently recognize only the ack control word and |
7443 | * any other control field being set would result in | 7406 | * any other control field being set would result in |
@@ -7591,18 +7554,16 @@ static void queue_rx_frame(struct sk_buff *skb) | |||
7591 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, | 7554 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, |
7592 | u32 tcp_len) | 7555 | u32 tcp_len) |
7593 | { | 7556 | { |
7594 | struct sk_buff *tmp, *first = lro->parent; | 7557 | struct sk_buff *first = lro->parent; |
7595 | 7558 | ||
7596 | first->len += tcp_len; | 7559 | first->len += tcp_len; |
7597 | first->data_len = lro->frags_len; | 7560 | first->data_len = lro->frags_len; |
7598 | skb_pull(skb, (skb->len - tcp_len)); | 7561 | skb_pull(skb, (skb->len - tcp_len)); |
7599 | if ((tmp = skb_shinfo(first)->frag_list)) { | 7562 | if (skb_shinfo(first)->frag_list) |
7600 | while (tmp->next) | 7563 | lro->last_frag->next = skb; |
7601 | tmp = tmp->next; | ||
7602 | tmp->next = skb; | ||
7603 | } | ||
7604 | else | 7564 | else |
7605 | skb_shinfo(first)->frag_list = skb; | 7565 | skb_shinfo(first)->frag_list = skb; |
7566 | lro->last_frag = skb; | ||
7606 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; | 7567 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; |
7607 | return; | 7568 | return; |
7608 | } | 7569 | } |