diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 741 |
1 files changed, 353 insertions, 388 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 3defe5d4f7d..1bf23e41f58 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -44,7 +44,6 @@ | |||
44 | * aggregated as a single large packet | 44 | * aggregated as a single large packet |
45 | ************************************************************************/ | 45 | ************************************************************************/ |
46 | 46 | ||
47 | #include <linux/config.h> | ||
48 | #include <linux/module.h> | 47 | #include <linux/module.h> |
49 | #include <linux/types.h> | 48 | #include <linux/types.h> |
50 | #include <linux/errno.h> | 49 | #include <linux/errno.h> |
@@ -72,12 +71,13 @@ | |||
72 | #include <asm/uaccess.h> | 71 | #include <asm/uaccess.h> |
73 | #include <asm/io.h> | 72 | #include <asm/io.h> |
74 | #include <asm/div64.h> | 73 | #include <asm/div64.h> |
74 | #include <asm/irq.h> | ||
75 | 75 | ||
76 | /* local include */ | 76 | /* local include */ |
77 | #include "s2io.h" | 77 | #include "s2io.h" |
78 | #include "s2io-regs.h" | 78 | #include "s2io-regs.h" |
79 | 79 | ||
80 | #define DRV_VERSION "2.0.14.2" | 80 | #define DRV_VERSION "2.0.15.2" |
81 | 81 | ||
82 | /* S2io Driver name & version. */ | 82 | /* S2io Driver name & version. */ |
83 | static char s2io_driver_name[] = "Neterion"; | 83 | static char s2io_driver_name[] = "Neterion"; |
@@ -371,38 +371,50 @@ static const u64 fix_mac[] = { | |||
371 | END_SIGN | 371 | END_SIGN |
372 | }; | 372 | }; |
373 | 373 | ||
374 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | ||
375 | MODULE_LICENSE("GPL"); | ||
376 | MODULE_VERSION(DRV_VERSION); | ||
377 | |||
378 | |||
374 | /* Module Loadable parameters. */ | 379 | /* Module Loadable parameters. */ |
375 | static unsigned int tx_fifo_num = 1; | 380 | S2IO_PARM_INT(tx_fifo_num, 1); |
376 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | 381 | S2IO_PARM_INT(rx_ring_num, 1); |
377 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; | 382 | |
378 | static unsigned int rx_ring_num = 1; | 383 | |
379 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 384 | S2IO_PARM_INT(rx_ring_mode, 1); |
380 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; | 385 | S2IO_PARM_INT(use_continuous_tx_intrs, 1); |
381 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | 386 | S2IO_PARM_INT(rmac_pause_time, 0x100); |
382 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 387 | S2IO_PARM_INT(mc_pause_threshold_q0q3, 187); |
383 | static unsigned int rx_ring_mode = 1; | 388 | S2IO_PARM_INT(mc_pause_threshold_q4q7, 187); |
384 | static unsigned int use_continuous_tx_intrs = 1; | 389 | S2IO_PARM_INT(shared_splits, 0); |
385 | static unsigned int rmac_pause_time = 0x100; | 390 | S2IO_PARM_INT(tmac_util_period, 5); |
386 | static unsigned int mc_pause_threshold_q0q3 = 187; | 391 | S2IO_PARM_INT(rmac_util_period, 5); |
387 | static unsigned int mc_pause_threshold_q4q7 = 187; | 392 | S2IO_PARM_INT(bimodal, 0); |
388 | static unsigned int shared_splits; | 393 | S2IO_PARM_INT(l3l4hdr_size, 128); |
389 | static unsigned int tmac_util_period = 5; | ||
390 | static unsigned int rmac_util_period = 5; | ||
391 | static unsigned int bimodal = 0; | ||
392 | static unsigned int l3l4hdr_size = 128; | ||
393 | #ifndef CONFIG_S2IO_NAPI | ||
394 | static unsigned int indicate_max_pkts; | ||
395 | #endif | ||
396 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 394 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
397 | static unsigned int rxsync_frequency = 3; | 395 | S2IO_PARM_INT(rxsync_frequency, 3); |
398 | /* 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) */ |
399 | static unsigned int intr_type = 0; | 397 | S2IO_PARM_INT(intr_type, 0); |
400 | /* Large receive offload feature */ | 398 | /* Large receive offload feature */ |
401 | static unsigned int lro = 0; | 399 | S2IO_PARM_INT(lro, 0); |
402 | /* 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, |
403 | * aggregation happens until we hit max IP pkt size(64K) | 401 | * aggregation happens until we hit max IP pkt size(64K) |
404 | */ | 402 | */ |
405 | 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); | ||
406 | 418 | ||
407 | /* | 419 | /* |
408 | * S2IO device table. | 420 | * S2IO device table. |
@@ -465,10 +477,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
465 | size += config->tx_cfg[i].fifo_len; | 477 | size += config->tx_cfg[i].fifo_len; |
466 | } | 478 | } |
467 | if (size > MAX_AVAILABLE_TXDS) { | 479 | if (size > MAX_AVAILABLE_TXDS) { |
468 | DBG_PRINT(ERR_DBG, "%s: Requested TxDs too high, ", | 480 | DBG_PRINT(ERR_DBG, "s2io: Requested TxDs too high, "); |
469 | __FUNCTION__); | ||
470 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); | 481 | DBG_PRINT(ERR_DBG, "Requested: %d, max supported: 8192\n", size); |
471 | return FAILURE; | 482 | return -EINVAL; |
472 | } | 483 | } |
473 | 484 | ||
474 | lst_size = (sizeof(TxD_t) * config->max_txds); | 485 | lst_size = (sizeof(TxD_t) * config->max_txds); |
@@ -519,9 +530,9 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
519 | */ | 530 | */ |
520 | if (!tmp_p) { | 531 | if (!tmp_p) { |
521 | mac_control->zerodma_virt_addr = tmp_v; | 532 | mac_control->zerodma_virt_addr = tmp_v; |
522 | DBG_PRINT(INIT_DBG, | 533 | DBG_PRINT(INIT_DBG, |
523 | "%s: Zero DMA address for TxDL. ", dev->name); | 534 | "%s: Zero DMA address for TxDL. ", dev->name); |
524 | DBG_PRINT(INIT_DBG, | 535 | DBG_PRINT(INIT_DBG, |
525 | "Virtual address %p\n", tmp_v); | 536 | "Virtual address %p\n", tmp_v); |
526 | tmp_v = pci_alloc_consistent(nic->pdev, | 537 | tmp_v = pci_alloc_consistent(nic->pdev, |
527 | PAGE_SIZE, &tmp_p); | 538 | PAGE_SIZE, &tmp_p); |
@@ -548,6 +559,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
548 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); | 559 | nic->ufo_in_band_v = kmalloc((sizeof(u64) * size), GFP_KERNEL); |
549 | if (!nic->ufo_in_band_v) | 560 | if (!nic->ufo_in_band_v) |
550 | return -ENOMEM; | 561 | return -ENOMEM; |
562 | memset(nic->ufo_in_band_v, 0, size); | ||
551 | 563 | ||
552 | /* Allocation and initialization of RXDs in Rings */ | 564 | /* Allocation and initialization of RXDs in Rings */ |
553 | size = 0; | 565 | size = 0; |
@@ -744,7 +756,7 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
744 | for (j = 0; j < page_num; j++) { | 756 | for (j = 0; j < page_num; j++) { |
745 | int mem_blks = (j * lst_per_page); | 757 | int mem_blks = (j * lst_per_page); |
746 | if (!mac_control->fifos[i].list_info) | 758 | if (!mac_control->fifos[i].list_info) |
747 | return; | 759 | return; |
748 | if (!mac_control->fifos[i].list_info[mem_blks]. | 760 | if (!mac_control->fifos[i].list_info[mem_blks]. |
749 | list_virt_addr) | 761 | list_virt_addr) |
750 | break; | 762 | break; |
@@ -763,7 +775,7 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
763 | pci_free_consistent(nic->pdev, PAGE_SIZE, | 775 | pci_free_consistent(nic->pdev, PAGE_SIZE, |
764 | mac_control->zerodma_virt_addr, | 776 | mac_control->zerodma_virt_addr, |
765 | (dma_addr_t)0); | 777 | (dma_addr_t)0); |
766 | DBG_PRINT(INIT_DBG, | 778 | DBG_PRINT(INIT_DBG, |
767 | "%s: Freeing TxDL with zero DMA addr. ", | 779 | "%s: Freeing TxDL with zero DMA addr. ", |
768 | dev->name); | 780 | dev->name); |
769 | DBG_PRINT(INIT_DBG, "Virtual address %p\n", | 781 | DBG_PRINT(INIT_DBG, "Virtual address %p\n", |
@@ -843,9 +855,10 @@ static int s2io_verify_pci_mode(nic_t *nic) | |||
843 | static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) | 855 | static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) |
844 | { | 856 | { |
845 | struct pci_dev *tdev = NULL; | 857 | struct pci_dev *tdev = NULL; |
846 | while ((tdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { | 858 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { |
847 | if ((tdev->vendor == NEC_VENID) && (tdev->device == NEC_DEVID)){ | 859 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { |
848 | if (tdev->bus == s2io_pdev->bus->parent) | 860 | if (tdev->bus == s2io_pdev->bus->parent) |
861 | pci_dev_put(tdev); | ||
849 | return 1; | 862 | return 1; |
850 | } | 863 | } |
851 | } | 864 | } |
@@ -1214,7 +1227,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1214 | break; | 1227 | break; |
1215 | } | 1228 | } |
1216 | 1229 | ||
1217 | /* Enable Tx FIFO partition 0. */ | 1230 | /* Enable all configured Tx FIFO partitions */ |
1218 | val64 = readq(&bar0->tx_fifo_partition_0); | 1231 | val64 = readq(&bar0->tx_fifo_partition_0); |
1219 | val64 |= (TX_FIFO_PARTITION_EN); | 1232 | val64 |= (TX_FIFO_PARTITION_EN); |
1220 | writeq(val64, &bar0->tx_fifo_partition_0); | 1233 | writeq(val64, &bar0->tx_fifo_partition_0); |
@@ -1264,7 +1277,7 @@ static int init_nic(struct s2io_nic *nic) | |||
1264 | writeq(val64, &bar0->rx_w_round_robin_1); | 1277 | writeq(val64, &bar0->rx_w_round_robin_1); |
1265 | val64 = 0x0200010000010203ULL; | 1278 | val64 = 0x0200010000010203ULL; |
1266 | writeq(val64, &bar0->rx_w_round_robin_2); | 1279 | writeq(val64, &bar0->rx_w_round_robin_2); |
1267 | val64 = 0x0001020001000001ULL; | 1280 | val64 = 0x0001020001000001ULL; |
1268 | writeq(val64, &bar0->rx_w_round_robin_3); | 1281 | writeq(val64, &bar0->rx_w_round_robin_3); |
1269 | val64 = 0x0203000100000000ULL; | 1282 | val64 = 0x0203000100000000ULL; |
1270 | writeq(val64, &bar0->rx_w_round_robin_4); | 1283 | writeq(val64, &bar0->rx_w_round_robin_4); |
@@ -1651,7 +1664,7 @@ static void en_dis_able_nic_intrs(struct s2io_nic *nic, u16 mask, int flag) | |||
1651 | writeq(temp64, &bar0->general_int_mask); | 1664 | writeq(temp64, &bar0->general_int_mask); |
1652 | /* | 1665 | /* |
1653 | * If Hercules adapter enable GPIO otherwise | 1666 | * If Hercules adapter enable GPIO otherwise |
1654 | * disabled all PCIX, Flash, MDIO, IIC and GPIO | 1667 | * disable all PCIX, Flash, MDIO, IIC and GPIO |
1655 | * interrupts for now. | 1668 | * interrupts for now. |
1656 | * TODO | 1669 | * TODO |
1657 | */ | 1670 | */ |
@@ -1977,7 +1990,6 @@ static int start_nic(struct s2io_nic *nic) | |||
1977 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 1990 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
1978 | struct net_device *dev = nic->dev; | 1991 | struct net_device *dev = nic->dev; |
1979 | register u64 val64 = 0; | 1992 | register u64 val64 = 0; |
1980 | u16 interruptible; | ||
1981 | u16 subid, i; | 1993 | u16 subid, i; |
1982 | mac_info_t *mac_control; | 1994 | mac_info_t *mac_control; |
1983 | struct config_param *config; | 1995 | struct config_param *config; |
@@ -2048,16 +2060,6 @@ static int start_nic(struct s2io_nic *nic) | |||
2048 | return FAILURE; | 2060 | return FAILURE; |
2049 | } | 2061 | } |
2050 | 2062 | ||
2051 | /* Enable select interrupts */ | ||
2052 | if (nic->intr_type != INTA) | ||
2053 | en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS); | ||
2054 | else { | ||
2055 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | ||
2056 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; | ||
2057 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
2058 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | ||
2059 | } | ||
2060 | |||
2061 | /* | 2063 | /* |
2062 | * With some switches, link might be already up at this point. | 2064 | * With some switches, link might be already up at this point. |
2063 | * Because of this weird behavior, when we enable laser, | 2065 | * Because of this weird behavior, when we enable laser, |
@@ -2126,12 +2128,12 @@ static struct sk_buff *s2io_txdl_getskb(fifo_info_t *fifo_data, TxD_t *txdlp, in | |||
2126 | skb_frag_t *frag = &skb_shinfo(skb)->frags[j]; | 2128 | skb_frag_t *frag = &skb_shinfo(skb)->frags[j]; |
2127 | if (!txds->Buffer_Pointer) | 2129 | if (!txds->Buffer_Pointer) |
2128 | break; | 2130 | break; |
2129 | pci_unmap_page(nic->pdev, (dma_addr_t) | 2131 | pci_unmap_page(nic->pdev, (dma_addr_t) |
2130 | txds->Buffer_Pointer, | 2132 | txds->Buffer_Pointer, |
2131 | frag->size, PCI_DMA_TODEVICE); | 2133 | frag->size, PCI_DMA_TODEVICE); |
2132 | } | 2134 | } |
2133 | } | 2135 | } |
2134 | txdlp->Host_Control = 0; | 2136 | memset(txdlp,0, (sizeof(TxD_t) * fifo_data->max_txds)); |
2135 | return(skb); | 2137 | return(skb); |
2136 | } | 2138 | } |
2137 | 2139 | ||
@@ -2383,25 +2385,33 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2383 | skb->data = (void *) (unsigned long)tmp; | 2385 | skb->data = (void *) (unsigned long)tmp; |
2384 | skb->tail = (void *) (unsigned long)tmp; | 2386 | skb->tail = (void *) (unsigned long)tmp; |
2385 | 2387 | ||
2386 | ((RxD3_t*)rxdp)->Buffer0_ptr = | 2388 | if (!(((RxD3_t*)rxdp)->Buffer0_ptr)) |
2387 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | 2389 | ((RxD3_t*)rxdp)->Buffer0_ptr = |
2390 | pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN, | ||
2388 | PCI_DMA_FROMDEVICE); | 2391 | PCI_DMA_FROMDEVICE); |
2392 | else | ||
2393 | pci_dma_sync_single_for_device(nic->pdev, | ||
2394 | (dma_addr_t) ((RxD3_t*)rxdp)->Buffer0_ptr, | ||
2395 | BUF0_LEN, PCI_DMA_FROMDEVICE); | ||
2389 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2396 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
2390 | if (nic->rxd_mode == RXD_MODE_3B) { | 2397 | if (nic->rxd_mode == RXD_MODE_3B) { |
2391 | /* Two buffer mode */ | 2398 | /* Two buffer mode */ |
2392 | 2399 | ||
2393 | /* | 2400 | /* |
2394 | * Buffer2 will have L3/L4 header plus | 2401 | * Buffer2 will have L3/L4 header plus |
2395 | * L4 payload | 2402 | * L4 payload |
2396 | */ | 2403 | */ |
2397 | ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single | 2404 | ((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single |
2398 | (nic->pdev, skb->data, dev->mtu + 4, | 2405 | (nic->pdev, skb->data, dev->mtu + 4, |
2399 | PCI_DMA_FROMDEVICE); | 2406 | PCI_DMA_FROMDEVICE); |
2400 | 2407 | ||
2401 | /* Buffer-1 will be dummy buffer not used */ | 2408 | /* Buffer-1 will be dummy buffer. Not used */ |
2402 | ((RxD3_t*)rxdp)->Buffer1_ptr = | 2409 | if (!(((RxD3_t*)rxdp)->Buffer1_ptr)) { |
2403 | pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN, | 2410 | ((RxD3_t*)rxdp)->Buffer1_ptr = |
2404 | PCI_DMA_FROMDEVICE); | 2411 | pci_map_single(nic->pdev, |
2412 | ba->ba_1, BUF1_LEN, | ||
2413 | PCI_DMA_FROMDEVICE); | ||
2414 | } | ||
2405 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); | 2415 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); |
2406 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 | 2416 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3 |
2407 | (dev->mtu + 4); | 2417 | (dev->mtu + 4); |
@@ -2500,7 +2510,7 @@ static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk) | |||
2500 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, | 2510 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, |
2501 | PCI_DMA_FROMDEVICE); | 2511 | PCI_DMA_FROMDEVICE); |
2502 | pci_unmap_single(sp->pdev, (dma_addr_t) | 2512 | pci_unmap_single(sp->pdev, (dma_addr_t) |
2503 | ((RxD3_t*)rxdp)->Buffer1_ptr, | 2513 | ((RxD3_t*)rxdp)->Buffer1_ptr, |
2504 | l3l4hdr_size + 4, | 2514 | l3l4hdr_size + 4, |
2505 | PCI_DMA_FROMDEVICE); | 2515 | PCI_DMA_FROMDEVICE); |
2506 | pci_unmap_single(sp->pdev, (dma_addr_t) | 2516 | pci_unmap_single(sp->pdev, (dma_addr_t) |
@@ -2626,23 +2636,23 @@ no_rx: | |||
2626 | } | 2636 | } |
2627 | #endif | 2637 | #endif |
2628 | 2638 | ||
2639 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2629 | /** | 2640 | /** |
2630 | * s2io_netpoll - Rx interrupt service handler for netpoll support | 2641 | * s2io_netpoll - netpoll event handler entry point |
2631 | * @dev : pointer to the device structure. | 2642 | * @dev : pointer to the device structure. |
2632 | * Description: | 2643 | * Description: |
2633 | * Polling 'interrupt' - used by things like netconsole to send skbs | 2644 | * This function will be called by upper layer to check for events on the |
2634 | * without having to re-enable interrupts. It's not called while | 2645 | * interface in situations where interrupts are disabled. It is used for |
2635 | * the interrupt routine is executing. | 2646 | * specific in-kernel networking tasks, such as remote consoles and kernel |
2647 | * debugging over the network (example netdump in RedHat). | ||
2636 | */ | 2648 | */ |
2637 | |||
2638 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
2639 | static void s2io_netpoll(struct net_device *dev) | 2649 | static void s2io_netpoll(struct net_device *dev) |
2640 | { | 2650 | { |
2641 | nic_t *nic = dev->priv; | 2651 | nic_t *nic = dev->priv; |
2642 | mac_info_t *mac_control; | 2652 | mac_info_t *mac_control; |
2643 | struct config_param *config; | 2653 | struct config_param *config; |
2644 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2654 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
2645 | u64 val64; | 2655 | u64 val64 = 0xFFFFFFFFFFFFFFFFULL; |
2646 | int i; | 2656 | int i; |
2647 | 2657 | ||
2648 | disable_irq(dev->irq); | 2658 | disable_irq(dev->irq); |
@@ -2651,9 +2661,17 @@ static void s2io_netpoll(struct net_device *dev) | |||
2651 | mac_control = &nic->mac_control; | 2661 | mac_control = &nic->mac_control; |
2652 | config = &nic->config; | 2662 | config = &nic->config; |
2653 | 2663 | ||
2654 | val64 = readq(&bar0->rx_traffic_int); | ||
2655 | writeq(val64, &bar0->rx_traffic_int); | 2664 | writeq(val64, &bar0->rx_traffic_int); |
2665 | writeq(val64, &bar0->tx_traffic_int); | ||
2656 | 2666 | ||
2667 | /* we need to free up the transmitted skbufs or else netpoll will | ||
2668 | * run out of skbs and will fail and eventually netpoll application such | ||
2669 | * as netdump will fail. | ||
2670 | */ | ||
2671 | for (i = 0; i < config->tx_fifo_num; i++) | ||
2672 | tx_intr_handler(&mac_control->fifos[i]); | ||
2673 | |||
2674 | /* check for received packet and indicate up to network */ | ||
2657 | for (i = 0; i < config->rx_ring_num; i++) | 2675 | for (i = 0; i < config->rx_ring_num; i++) |
2658 | rx_intr_handler(&mac_control->rings[i]); | 2676 | rx_intr_handler(&mac_control->rings[i]); |
2659 | 2677 | ||
@@ -2720,7 +2738,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2720 | /* If your are next to put index then it's FIFO full condition */ | 2738 | /* If your are next to put index then it's FIFO full condition */ |
2721 | if ((get_block == put_block) && | 2739 | if ((get_block == put_block) && |
2722 | (get_info.offset + 1) == put_info.offset) { | 2740 | (get_info.offset + 1) == put_info.offset) { |
2723 | DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name); | 2741 | DBG_PRINT(INTR_DBG, "%s: Ring Full\n",dev->name); |
2724 | break; | 2742 | break; |
2725 | } | 2743 | } |
2726 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); | 2744 | skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control); |
@@ -2740,18 +2758,15 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
2740 | HEADER_SNAP_SIZE, | 2758 | HEADER_SNAP_SIZE, |
2741 | PCI_DMA_FROMDEVICE); | 2759 | PCI_DMA_FROMDEVICE); |
2742 | } else if (nic->rxd_mode == RXD_MODE_3B) { | 2760 | } else if (nic->rxd_mode == RXD_MODE_3B) { |
2743 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2761 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2744 | ((RxD3_t*)rxdp)->Buffer0_ptr, | 2762 | ((RxD3_t*)rxdp)->Buffer0_ptr, |
2745 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2763 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2746 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2764 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2747 | ((RxD3_t*)rxdp)->Buffer1_ptr, | ||
2748 | BUF1_LEN, PCI_DMA_FROMDEVICE); | ||
2749 | pci_unmap_single(nic->pdev, (dma_addr_t) | ||
2750 | ((RxD3_t*)rxdp)->Buffer2_ptr, | 2765 | ((RxD3_t*)rxdp)->Buffer2_ptr, |
2751 | dev->mtu + 4, | 2766 | dev->mtu + 4, |
2752 | PCI_DMA_FROMDEVICE); | 2767 | PCI_DMA_FROMDEVICE); |
2753 | } else { | 2768 | } else { |
2754 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2769 | pci_dma_sync_single_for_cpu(nic->pdev, (dma_addr_t) |
2755 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, | 2770 | ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN, |
2756 | PCI_DMA_FROMDEVICE); | 2771 | PCI_DMA_FROMDEVICE); |
2757 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2772 | pci_unmap_single(nic->pdev, (dma_addr_t) |
@@ -2889,7 +2904,7 @@ static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device | |||
2889 | { | 2904 | { |
2890 | u64 val64 = 0x0; | 2905 | u64 val64 = 0x0; |
2891 | nic_t *sp = dev->priv; | 2906 | nic_t *sp = dev->priv; |
2892 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | 2907 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2893 | 2908 | ||
2894 | //address transaction | 2909 | //address transaction |
2895 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | 2910 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) |
@@ -2938,7 +2953,7 @@ static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) | |||
2938 | u64 val64 = 0x0; | 2953 | u64 val64 = 0x0; |
2939 | u64 rval64 = 0x0; | 2954 | u64 rval64 = 0x0; |
2940 | nic_t *sp = dev->priv; | 2955 | nic_t *sp = dev->priv; |
2941 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | 2956 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
2942 | 2957 | ||
2943 | /* address transaction */ | 2958 | /* address transaction */ |
2944 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | 2959 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) |
@@ -3195,7 +3210,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
3195 | if (val64 & SERR_SOURCE_ANY) { | 3210 | if (val64 & SERR_SOURCE_ANY) { |
3196 | nic->mac_control.stats_info->sw_stat.serious_err_cnt++; | 3211 | nic->mac_control.stats_info->sw_stat.serious_err_cnt++; |
3197 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); | 3212 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); |
3198 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", | 3213 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", |
3199 | (unsigned long long)val64); | 3214 | (unsigned long long)val64); |
3200 | netif_stop_queue(dev); | 3215 | netif_stop_queue(dev); |
3201 | schedule_work(&nic->rst_timer_task); | 3216 | schedule_work(&nic->rst_timer_task); |
@@ -3261,7 +3276,7 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
3261 | * SUCCESS on success and FAILURE on failure. | 3276 | * SUCCESS on success and FAILURE on failure. |
3262 | */ | 3277 | */ |
3263 | 3278 | ||
3264 | static int wait_for_cmd_complete(void *addr, u64 busy_bit) | 3279 | static int wait_for_cmd_complete(void __iomem *addr, u64 busy_bit) |
3265 | { | 3280 | { |
3266 | int ret = FAILURE, cnt = 0; | 3281 | int ret = FAILURE, cnt = 0; |
3267 | u64 val64; | 3282 | u64 val64; |
@@ -3339,7 +3354,7 @@ static void s2io_reset(nic_t * sp) | |||
3339 | 3354 | ||
3340 | /* Clear certain PCI/PCI-X fields after reset */ | 3355 | /* Clear certain PCI/PCI-X fields after reset */ |
3341 | if (sp->device_type == XFRAME_II_DEVICE) { | 3356 | if (sp->device_type == XFRAME_II_DEVICE) { |
3342 | /* Clear parity err detect bit */ | 3357 | /* Clear "detected parity error" bit */ |
3343 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); | 3358 | pci_write_config_word(sp->pdev, PCI_STATUS, 0x8000); |
3344 | 3359 | ||
3345 | /* Clearing PCIX Ecc status register */ | 3360 | /* Clearing PCIX Ecc status register */ |
@@ -3540,7 +3555,7 @@ static void restore_xmsi_data(nic_t *nic) | |||
3540 | u64 val64; | 3555 | u64 val64; |
3541 | int i; | 3556 | int i; |
3542 | 3557 | ||
3543 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3558 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3544 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3559 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3545 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3560 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3546 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); | 3561 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); |
@@ -3559,7 +3574,7 @@ static void store_xmsi_data(nic_t *nic) | |||
3559 | int i; | 3574 | int i; |
3560 | 3575 | ||
3561 | /* Store and display */ | 3576 | /* Store and display */ |
3562 | for (i=0; i< nic->avail_msix_vectors; i++) { | 3577 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3563 | val64 = (BIT(15) | vBIT(i, 26, 6)); | 3578 | val64 = (BIT(15) | vBIT(i, 26, 6)); |
3564 | writeq(val64, &bar0->xmsi_access); | 3579 | writeq(val64, &bar0->xmsi_access); |
3565 | if (wait_for_msix_trans(nic, i)) { | 3580 | if (wait_for_msix_trans(nic, i)) { |
@@ -3750,101 +3765,19 @@ static int s2io_open(struct net_device *dev) | |||
3750 | if (err) { | 3765 | if (err) { |
3751 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 3766 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
3752 | dev->name); | 3767 | dev->name); |
3753 | if (err == -ENODEV) | 3768 | goto hw_init_failed; |
3754 | goto hw_init_failed; | ||
3755 | else | ||
3756 | goto hw_enable_failed; | ||
3757 | } | ||
3758 | |||
3759 | /* Store the values of the MSIX table in the nic_t structure */ | ||
3760 | store_xmsi_data(sp); | ||
3761 | |||
3762 | /* After proper initialization of H/W, register ISR */ | ||
3763 | if (sp->intr_type == MSI) { | ||
3764 | err = request_irq((int) sp->pdev->irq, s2io_msi_handle, | ||
3765 | SA_SHIRQ, sp->name, dev); | ||
3766 | if (err) { | ||
3767 | DBG_PRINT(ERR_DBG, "%s: MSI registration \ | ||
3768 | failed\n", dev->name); | ||
3769 | goto isr_registration_failed; | ||
3770 | } | ||
3771 | } | ||
3772 | if (sp->intr_type == MSI_X) { | ||
3773 | int i; | ||
3774 | |||
3775 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | ||
3776 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | ||
3777 | sprintf(sp->desc1, "%s:MSI-X-%d-TX", | ||
3778 | dev->name, i); | ||
3779 | err = request_irq(sp->entries[i].vector, | ||
3780 | s2io_msix_fifo_handle, 0, sp->desc1, | ||
3781 | sp->s2io_entries[i].arg); | ||
3782 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, | ||
3783 | (unsigned long long)sp->msix_info[i].addr); | ||
3784 | } else { | ||
3785 | sprintf(sp->desc2, "%s:MSI-X-%d-RX", | ||
3786 | dev->name, i); | ||
3787 | err = request_irq(sp->entries[i].vector, | ||
3788 | s2io_msix_ring_handle, 0, sp->desc2, | ||
3789 | sp->s2io_entries[i].arg); | ||
3790 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, | ||
3791 | (unsigned long long)sp->msix_info[i].addr); | ||
3792 | } | ||
3793 | if (err) { | ||
3794 | DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \ | ||
3795 | failed\n", dev->name, i); | ||
3796 | DBG_PRINT(ERR_DBG, "Returned: %d\n", err); | ||
3797 | goto isr_registration_failed; | ||
3798 | } | ||
3799 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
3800 | } | ||
3801 | } | ||
3802 | if (sp->intr_type == INTA) { | ||
3803 | err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, | ||
3804 | sp->name, dev); | ||
3805 | if (err) { | ||
3806 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | ||
3807 | dev->name); | ||
3808 | goto isr_registration_failed; | ||
3809 | } | ||
3810 | } | 3769 | } |
3811 | 3770 | ||
3812 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { | 3771 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { |
3813 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); | 3772 | DBG_PRINT(ERR_DBG, "Set Mac Address Failed\n"); |
3773 | s2io_card_down(sp); | ||
3814 | err = -ENODEV; | 3774 | err = -ENODEV; |
3815 | goto setting_mac_address_failed; | 3775 | goto hw_init_failed; |
3816 | } | 3776 | } |
3817 | 3777 | ||
3818 | netif_start_queue(dev); | 3778 | netif_start_queue(dev); |
3819 | return 0; | 3779 | return 0; |
3820 | 3780 | ||
3821 | setting_mac_address_failed: | ||
3822 | if (sp->intr_type != MSI_X) | ||
3823 | free_irq(sp->pdev->irq, dev); | ||
3824 | isr_registration_failed: | ||
3825 | del_timer_sync(&sp->alarm_timer); | ||
3826 | if (sp->intr_type == MSI_X) { | ||
3827 | int i; | ||
3828 | u16 msi_control; /* Temp variable */ | ||
3829 | |||
3830 | for (i=1; (sp->s2io_entries[i].in_use == | ||
3831 | MSIX_REGISTERED_SUCCESS); i++) { | ||
3832 | int vector = sp->entries[i].vector; | ||
3833 | void *arg = sp->s2io_entries[i].arg; | ||
3834 | |||
3835 | free_irq(vector, arg); | ||
3836 | } | ||
3837 | pci_disable_msix(sp->pdev); | ||
3838 | |||
3839 | /* Temp */ | ||
3840 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
3841 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
3842 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
3843 | } | ||
3844 | else if (sp->intr_type == MSI) | ||
3845 | pci_disable_msi(sp->pdev); | ||
3846 | hw_enable_failed: | ||
3847 | s2io_reset(sp); | ||
3848 | hw_init_failed: | 3781 | hw_init_failed: |
3849 | if (sp->intr_type == MSI_X) { | 3782 | if (sp->intr_type == MSI_X) { |
3850 | if (sp->entries) | 3783 | if (sp->entries) |
@@ -3875,7 +3808,7 @@ static int s2io_close(struct net_device *dev) | |||
3875 | flush_scheduled_work(); | 3808 | flush_scheduled_work(); |
3876 | netif_stop_queue(dev); | 3809 | netif_stop_queue(dev); |
3877 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3810 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
3878 | s2io_card_down(sp, 1); | 3811 | s2io_card_down(sp); |
3879 | 3812 | ||
3880 | sp->device_close_flag = TRUE; /* Device is shut down. */ | 3813 | sp->device_close_flag = TRUE; /* Device is shut down. */ |
3881 | return 0; | 3814 | return 0; |
@@ -3902,13 +3835,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3902 | TxD_t *txdp; | 3835 | TxD_t *txdp; |
3903 | TxFIFO_element_t __iomem *tx_fifo; | 3836 | TxFIFO_element_t __iomem *tx_fifo; |
3904 | unsigned long flags; | 3837 | unsigned long flags; |
3905 | #ifdef NETIF_F_TSO | ||
3906 | int mss; | ||
3907 | #endif | ||
3908 | u16 vlan_tag = 0; | 3838 | u16 vlan_tag = 0; |
3909 | int vlan_priority = 0; | 3839 | int vlan_priority = 0; |
3910 | mac_info_t *mac_control; | 3840 | mac_info_t *mac_control; |
3911 | struct config_param *config; | 3841 | struct config_param *config; |
3842 | int offload_type; | ||
3912 | 3843 | ||
3913 | mac_control = &sp->mac_control; | 3844 | mac_control = &sp->mac_control; |
3914 | config = &sp->config; | 3845 | config = &sp->config; |
@@ -3956,16 +3887,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3956 | return 0; | 3887 | return 0; |
3957 | } | 3888 | } |
3958 | 3889 | ||
3959 | txdp->Control_1 = 0; | 3890 | offload_type = s2io_offload_type(skb); |
3960 | txdp->Control_2 = 0; | ||
3961 | #ifdef NETIF_F_TSO | 3891 | #ifdef NETIF_F_TSO |
3962 | mss = skb_shinfo(skb)->gso_size; | 3892 | if (offload_type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6)) { |
3963 | if (skb_shinfo(skb)->gso_type == SKB_GSO_TCPV4) { | ||
3964 | txdp->Control_1 |= TXD_TCP_LSO_EN; | 3893 | txdp->Control_1 |= TXD_TCP_LSO_EN; |
3965 | txdp->Control_1 |= TXD_TCP_LSO_MSS(mss); | 3894 | txdp->Control_1 |= TXD_TCP_LSO_MSS(s2io_tcp_mss(skb)); |
3966 | } | 3895 | } |
3967 | #endif | 3896 | #endif |
3968 | if (skb->ip_summed == CHECKSUM_HW) { | 3897 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
3969 | txdp->Control_2 |= | 3898 | txdp->Control_2 |= |
3970 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | | 3899 | (TXD_TX_CKO_IPV4_EN | TXD_TX_CKO_TCP_EN | |
3971 | TXD_TX_CKO_UDP_EN); | 3900 | TXD_TX_CKO_UDP_EN); |
@@ -3980,10 +3909,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3980 | } | 3909 | } |
3981 | 3910 | ||
3982 | frg_len = skb->len - skb->data_len; | 3911 | frg_len = skb->len - skb->data_len; |
3983 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) { | 3912 | if (offload_type == SKB_GSO_UDP) { |
3984 | int ufo_size; | 3913 | int ufo_size; |
3985 | 3914 | ||
3986 | ufo_size = skb_shinfo(skb)->gso_size; | 3915 | ufo_size = s2io_udp_mss(skb); |
3987 | ufo_size &= ~7; | 3916 | ufo_size &= ~7; |
3988 | txdp->Control_1 |= TXD_UFO_EN; | 3917 | txdp->Control_1 |= TXD_UFO_EN; |
3989 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); | 3918 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); |
@@ -4000,16 +3929,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4000 | sp->ufo_in_band_v, | 3929 | sp->ufo_in_band_v, |
4001 | sizeof(u64), PCI_DMA_TODEVICE); | 3930 | sizeof(u64), PCI_DMA_TODEVICE); |
4002 | txdp++; | 3931 | txdp++; |
4003 | txdp->Control_1 = 0; | ||
4004 | txdp->Control_2 = 0; | ||
4005 | } | 3932 | } |
4006 | 3933 | ||
4007 | txdp->Buffer_Pointer = pci_map_single | 3934 | txdp->Buffer_Pointer = pci_map_single |
4008 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 3935 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
4009 | txdp->Host_Control = (unsigned long) skb; | 3936 | txdp->Host_Control = (unsigned long) skb; |
4010 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); | 3937 | txdp->Control_1 |= TXD_BUFFER0_SIZE(frg_len); |
4011 | 3938 | if (offload_type == SKB_GSO_UDP) | |
4012 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) | ||
4013 | txdp->Control_1 |= TXD_UFO_EN; | 3939 | txdp->Control_1 |= TXD_UFO_EN; |
4014 | 3940 | ||
4015 | frg_cnt = skb_shinfo(skb)->nr_frags; | 3941 | frg_cnt = skb_shinfo(skb)->nr_frags; |
@@ -4024,12 +3950,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4024 | (sp->pdev, frag->page, frag->page_offset, | 3950 | (sp->pdev, frag->page, frag->page_offset, |
4025 | frag->size, PCI_DMA_TODEVICE); | 3951 | frag->size, PCI_DMA_TODEVICE); |
4026 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); | 3952 | txdp->Control_1 = TXD_BUFFER0_SIZE(frag->size); |
4027 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) | 3953 | if (offload_type == SKB_GSO_UDP) |
4028 | txdp->Control_1 |= TXD_UFO_EN; | 3954 | txdp->Control_1 |= TXD_UFO_EN; |
4029 | } | 3955 | } |
4030 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; | 3956 | txdp->Control_1 |= TXD_GATHER_CODE_LAST; |
4031 | 3957 | ||
4032 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) | 3958 | if (offload_type == SKB_GSO_UDP) |
4033 | frg_cnt++; /* as Txd0 was used for inband header */ | 3959 | frg_cnt++; /* as Txd0 was used for inband header */ |
4034 | 3960 | ||
4035 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 3961 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
@@ -4038,13 +3964,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4038 | 3964 | ||
4039 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 3965 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
4040 | TX_FIFO_LAST_LIST); | 3966 | TX_FIFO_LAST_LIST); |
4041 | 3967 | if (offload_type) | |
4042 | #ifdef NETIF_F_TSO | ||
4043 | if (mss) | ||
4044 | val64 |= TX_FIFO_SPECIAL_FUNC; | ||
4045 | #endif | ||
4046 | if (skb_shinfo(skb)->gso_type == SKB_GSO_UDPV4) | ||
4047 | val64 |= TX_FIFO_SPECIAL_FUNC; | 3968 | val64 |= TX_FIFO_SPECIAL_FUNC; |
3969 | |||
4048 | writeq(val64, &tx_fifo->List_Control); | 3970 | writeq(val64, &tx_fifo->List_Control); |
4049 | 3971 | ||
4050 | mmiowb(); | 3972 | mmiowb(); |
@@ -4078,13 +4000,41 @@ s2io_alarm_handle(unsigned long data) | |||
4078 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4000 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
4079 | } | 4001 | } |
4080 | 4002 | ||
4003 | static int s2io_chk_rx_buffers(nic_t *sp, int rng_n) | ||
4004 | { | ||
4005 | int rxb_size, level; | ||
4006 | |||
4007 | if (!sp->lro) { | ||
4008 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4009 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4010 | |||
4011 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4012 | int ret; | ||
4013 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4014 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4015 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4016 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4017 | __FUNCTION__); | ||
4018 | clear_bit(0, (&sp->tasklet_status)); | ||
4019 | return -1; | ||
4020 | } | ||
4021 | clear_bit(0, (&sp->tasklet_status)); | ||
4022 | } else if (level == LOW) | ||
4023 | tasklet_schedule(&sp->task); | ||
4024 | |||
4025 | } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4026 | DBG_PRINT(ERR_DBG, "%s:Out of memory", sp->dev->name); | ||
4027 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4028 | } | ||
4029 | return 0; | ||
4030 | } | ||
4031 | |||
4081 | static irqreturn_t | 4032 | static irqreturn_t |
4082 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | 4033 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) |
4083 | { | 4034 | { |
4084 | struct net_device *dev = (struct net_device *) dev_id; | 4035 | struct net_device *dev = (struct net_device *) dev_id; |
4085 | nic_t *sp = dev->priv; | 4036 | nic_t *sp = dev->priv; |
4086 | int i; | 4037 | int i; |
4087 | int ret; | ||
4088 | mac_info_t *mac_control; | 4038 | mac_info_t *mac_control; |
4089 | struct config_param *config; | 4039 | struct config_param *config; |
4090 | 4040 | ||
@@ -4106,35 +4056,8 @@ s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4106 | * reallocate the buffers from the interrupt handler itself, | 4056 | * reallocate the buffers from the interrupt handler itself, |
4107 | * else schedule a tasklet to reallocate the buffers. | 4057 | * else schedule a tasklet to reallocate the buffers. |
4108 | */ | 4058 | */ |
4109 | for (i = 0; i < config->rx_ring_num; i++) { | 4059 | for (i = 0; i < config->rx_ring_num; i++) |
4110 | if (!sp->lro) { | 4060 | s2io_chk_rx_buffers(sp, i); |
4111 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4112 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4113 | |||
4114 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4115 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4116 | dev->name); | ||
4117 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4118 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4119 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4120 | dev->name); | ||
4121 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4122 | clear_bit(0, (&sp->tasklet_status)); | ||
4123 | atomic_dec(&sp->isr_cnt); | ||
4124 | return IRQ_HANDLED; | ||
4125 | } | ||
4126 | clear_bit(0, (&sp->tasklet_status)); | ||
4127 | } else if (level == LOW) { | ||
4128 | tasklet_schedule(&sp->task); | ||
4129 | } | ||
4130 | } | ||
4131 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4132 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4133 | dev->name); | ||
4134 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4135 | break; | ||
4136 | } | ||
4137 | } | ||
4138 | 4061 | ||
4139 | atomic_dec(&sp->isr_cnt); | 4062 | atomic_dec(&sp->isr_cnt); |
4140 | return IRQ_HANDLED; | 4063 | return IRQ_HANDLED; |
@@ -4145,39 +4068,13 @@ s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
4145 | { | 4068 | { |
4146 | ring_info_t *ring = (ring_info_t *)dev_id; | 4069 | ring_info_t *ring = (ring_info_t *)dev_id; |
4147 | nic_t *sp = ring->nic; | 4070 | nic_t *sp = ring->nic; |
4148 | struct net_device *dev = (struct net_device *) dev_id; | ||
4149 | int rxb_size, level, rng_n; | ||
4150 | 4071 | ||
4151 | atomic_inc(&sp->isr_cnt); | 4072 | atomic_inc(&sp->isr_cnt); |
4152 | rx_intr_handler(ring); | ||
4153 | 4073 | ||
4154 | rng_n = ring->ring_no; | 4074 | rx_intr_handler(ring); |
4155 | if (!sp->lro) { | 4075 | s2io_chk_rx_buffers(sp, ring->ring_no); |
4156 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4157 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4158 | |||
4159 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4160 | int ret; | ||
4161 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4162 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4163 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4164 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
4165 | __FUNCTION__); | ||
4166 | clear_bit(0, (&sp->tasklet_status)); | ||
4167 | return IRQ_HANDLED; | ||
4168 | } | ||
4169 | clear_bit(0, (&sp->tasklet_status)); | ||
4170 | } else if (level == LOW) { | ||
4171 | tasklet_schedule(&sp->task); | ||
4172 | } | ||
4173 | } | ||
4174 | else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4175 | DBG_PRINT(ERR_DBG, "%s:Out of memory", dev->name); | ||
4176 | DBG_PRINT(ERR_DBG, " in Rx Intr!!\n"); | ||
4177 | } | ||
4178 | 4076 | ||
4179 | atomic_dec(&sp->isr_cnt); | 4077 | atomic_dec(&sp->isr_cnt); |
4180 | |||
4181 | return IRQ_HANDLED; | 4078 | return IRQ_HANDLED; |
4182 | } | 4079 | } |
4183 | 4080 | ||
@@ -4342,37 +4239,8 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
4342 | * else schedule a tasklet to reallocate the buffers. | 4239 | * else schedule a tasklet to reallocate the buffers. |
4343 | */ | 4240 | */ |
4344 | #ifndef CONFIG_S2IO_NAPI | 4241 | #ifndef CONFIG_S2IO_NAPI |
4345 | for (i = 0; i < config->rx_ring_num; i++) { | 4242 | for (i = 0; i < config->rx_ring_num; i++) |
4346 | if (!sp->lro) { | 4243 | s2io_chk_rx_buffers(sp, i); |
4347 | int ret; | ||
4348 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
4349 | int level = rx_buffer_level(sp, rxb_size, i); | ||
4350 | |||
4351 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4352 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", | ||
4353 | dev->name); | ||
4354 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4355 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
4356 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4357 | dev->name); | ||
4358 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
4359 | clear_bit(0, (&sp->tasklet_status)); | ||
4360 | atomic_dec(&sp->isr_cnt); | ||
4361 | writeq(org_mask, &bar0->general_int_mask); | ||
4362 | return IRQ_HANDLED; | ||
4363 | } | ||
4364 | clear_bit(0, (&sp->tasklet_status)); | ||
4365 | } else if (level == LOW) { | ||
4366 | tasklet_schedule(&sp->task); | ||
4367 | } | ||
4368 | } | ||
4369 | else if (fill_rx_buffers(sp, i) == -ENOMEM) { | ||
4370 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
4371 | dev->name); | ||
4372 | DBG_PRINT(ERR_DBG, " in Rx intr!!\n"); | ||
4373 | break; | ||
4374 | } | ||
4375 | } | ||
4376 | #endif | 4244 | #endif |
4377 | writeq(org_mask, &bar0->general_int_mask); | 4245 | writeq(org_mask, &bar0->general_int_mask); |
4378 | atomic_dec(&sp->isr_cnt); | 4246 | atomic_dec(&sp->isr_cnt); |
@@ -4402,6 +4270,8 @@ static void s2io_updt_stats(nic_t *sp) | |||
4402 | if (cnt == 5) | 4270 | if (cnt == 5) |
4403 | break; /* Updt failed */ | 4271 | break; /* Updt failed */ |
4404 | } while(1); | 4272 | } while(1); |
4273 | } else { | ||
4274 | memset(sp->mac_control.stats_info, 0, sizeof(StatInfo_t)); | ||
4405 | } | 4275 | } |
4406 | } | 4276 | } |
4407 | 4277 | ||
@@ -4433,11 +4303,11 @@ static struct net_device_stats *s2io_get_stats(struct net_device *dev) | |||
4433 | sp->stats.tx_errors = | 4303 | sp->stats.tx_errors = |
4434 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); | 4304 | le32_to_cpu(mac_control->stats_info->tmac_any_err_frms); |
4435 | sp->stats.rx_errors = | 4305 | sp->stats.rx_errors = |
4436 | le32_to_cpu(mac_control->stats_info->rmac_drop_frms); | 4306 | le64_to_cpu(mac_control->stats_info->rmac_drop_frms); |
4437 | sp->stats.multicast = | 4307 | sp->stats.multicast = |
4438 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); | 4308 | le32_to_cpu(mac_control->stats_info->rmac_vld_mcst_frms); |
4439 | sp->stats.rx_length_errors = | 4309 | sp->stats.rx_length_errors = |
4440 | le32_to_cpu(mac_control->stats_info->rmac_long_frms); | 4310 | le64_to_cpu(mac_control->stats_info->rmac_long_frms); |
4441 | 4311 | ||
4442 | return (&sp->stats); | 4312 | return (&sp->stats); |
4443 | } | 4313 | } |
@@ -4947,7 +4817,7 @@ static int read_eeprom(nic_t * sp, int off, u64 * data) | |||
4947 | 4817 | ||
4948 | if (sp->device_type == XFRAME_II_DEVICE) { | 4818 | if (sp->device_type == XFRAME_II_DEVICE) { |
4949 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | | 4819 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | |
4950 | SPI_CONTROL_BYTECNT(0x3) | | 4820 | SPI_CONTROL_BYTECNT(0x3) | |
4951 | SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off); | 4821 | SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off); |
4952 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | 4822 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); |
4953 | val64 |= SPI_CONTROL_REQ; | 4823 | val64 |= SPI_CONTROL_REQ; |
@@ -5014,7 +4884,7 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) | |||
5014 | writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data); | 4884 | writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data); |
5015 | 4885 | ||
5016 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | | 4886 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | |
5017 | SPI_CONTROL_BYTECNT(write_cnt) | | 4887 | SPI_CONTROL_BYTECNT(write_cnt) | |
5018 | SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off); | 4888 | SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off); |
5019 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | 4889 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); |
5020 | val64 |= SPI_CONTROL_REQ; | 4890 | val64 |= SPI_CONTROL_REQ; |
@@ -5036,7 +4906,8 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) | |||
5036 | } | 4906 | } |
5037 | static void s2io_vpd_read(nic_t *nic) | 4907 | static void s2io_vpd_read(nic_t *nic) |
5038 | { | 4908 | { |
5039 | u8 vpd_data[256],data; | 4909 | u8 *vpd_data; |
4910 | u8 data; | ||
5040 | int i=0, cnt, fail = 0; | 4911 | int i=0, cnt, fail = 0; |
5041 | int vpd_addr = 0x80; | 4912 | int vpd_addr = 0x80; |
5042 | 4913 | ||
@@ -5049,6 +4920,10 @@ static void s2io_vpd_read(nic_t *nic) | |||
5049 | vpd_addr = 0x50; | 4920 | vpd_addr = 0x50; |
5050 | } | 4921 | } |
5051 | 4922 | ||
4923 | vpd_data = kmalloc(256, GFP_KERNEL); | ||
4924 | if (!vpd_data) | ||
4925 | return; | ||
4926 | |||
5052 | for (i = 0; i < 256; i +=4 ) { | 4927 | for (i = 0; i < 256; i +=4 ) { |
5053 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); | 4928 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); |
5054 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); | 4929 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); |
@@ -5071,6 +4946,7 @@ static void s2io_vpd_read(nic_t *nic) | |||
5071 | memset(nic->product_name, 0, vpd_data[1]); | 4946 | memset(nic->product_name, 0, vpd_data[1]); |
5072 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); | 4947 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); |
5073 | } | 4948 | } |
4949 | kfree(vpd_data); | ||
5074 | } | 4950 | } |
5075 | 4951 | ||
5076 | /** | 4952 | /** |
@@ -5389,7 +5265,7 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
5389 | else | 5265 | else |
5390 | *data = 0; | 5266 | *data = 0; |
5391 | 5267 | ||
5392 | return 0; | 5268 | return *data; |
5393 | } | 5269 | } |
5394 | 5270 | ||
5395 | /** | 5271 | /** |
@@ -5771,7 +5647,7 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
5771 | if (stat_info->sw_stat.num_aggregations) { | 5647 | if (stat_info->sw_stat.num_aggregations) { |
5772 | u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; | 5648 | u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; |
5773 | int count = 0; | 5649 | int count = 0; |
5774 | /* | 5650 | /* |
5775 | * Since 64-bit divide does not work on all platforms, | 5651 | * Since 64-bit divide does not work on all platforms, |
5776 | * do repeated subtraction. | 5652 | * do repeated subtraction. |
5777 | */ | 5653 | */ |
@@ -5847,8 +5723,21 @@ static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data) | |||
5847 | return 0; | 5723 | return 0; |
5848 | } | 5724 | } |
5849 | 5725 | ||
5726 | static u32 s2io_ethtool_op_get_tso(struct net_device *dev) | ||
5727 | { | ||
5728 | return (dev->features & NETIF_F_TSO) != 0; | ||
5729 | } | ||
5730 | static int s2io_ethtool_op_set_tso(struct net_device *dev, u32 data) | ||
5731 | { | ||
5732 | if (data) | ||
5733 | dev->features |= (NETIF_F_TSO | NETIF_F_TSO6); | ||
5734 | else | ||
5735 | dev->features &= ~(NETIF_F_TSO | NETIF_F_TSO6); | ||
5736 | |||
5737 | return 0; | ||
5738 | } | ||
5850 | 5739 | ||
5851 | static struct ethtool_ops netdev_ethtool_ops = { | 5740 | static const struct ethtool_ops netdev_ethtool_ops = { |
5852 | .get_settings = s2io_ethtool_gset, | 5741 | .get_settings = s2io_ethtool_gset, |
5853 | .set_settings = s2io_ethtool_sset, | 5742 | .set_settings = s2io_ethtool_sset, |
5854 | .get_drvinfo = s2io_ethtool_gdrvinfo, | 5743 | .get_drvinfo = s2io_ethtool_gdrvinfo, |
@@ -5867,8 +5756,8 @@ static struct ethtool_ops netdev_ethtool_ops = { | |||
5867 | .get_sg = ethtool_op_get_sg, | 5756 | .get_sg = ethtool_op_get_sg, |
5868 | .set_sg = ethtool_op_set_sg, | 5757 | .set_sg = ethtool_op_set_sg, |
5869 | #ifdef NETIF_F_TSO | 5758 | #ifdef NETIF_F_TSO |
5870 | .get_tso = ethtool_op_get_tso, | 5759 | .get_tso = s2io_ethtool_op_get_tso, |
5871 | .set_tso = ethtool_op_set_tso, | 5760 | .set_tso = s2io_ethtool_op_set_tso, |
5872 | #endif | 5761 | #endif |
5873 | .get_ufo = ethtool_op_get_ufo, | 5762 | .get_ufo = ethtool_op_get_ufo, |
5874 | .set_ufo = ethtool_op_set_ufo, | 5763 | .set_ufo = ethtool_op_set_ufo, |
@@ -5920,7 +5809,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
5920 | 5809 | ||
5921 | dev->mtu = new_mtu; | 5810 | dev->mtu = new_mtu; |
5922 | if (netif_running(dev)) { | 5811 | if (netif_running(dev)) { |
5923 | s2io_card_down(sp, 0); | 5812 | s2io_card_down(sp); |
5924 | netif_stop_queue(dev); | 5813 | netif_stop_queue(dev); |
5925 | if (s2io_card_up(sp)) { | 5814 | if (s2io_card_up(sp)) { |
5926 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 5815 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
@@ -6217,43 +6106,106 @@ static int rxd_owner_bit_reset(nic_t *sp) | |||
6217 | 6106 | ||
6218 | } | 6107 | } |
6219 | 6108 | ||
6220 | static void s2io_card_down(nic_t * sp, int flag) | 6109 | static int s2io_add_isr(nic_t * sp) |
6221 | { | 6110 | { |
6222 | int cnt = 0; | 6111 | int ret = 0; |
6223 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
6224 | unsigned long flags; | ||
6225 | register u64 val64 = 0; | ||
6226 | struct net_device *dev = sp->dev; | 6112 | struct net_device *dev = sp->dev; |
6113 | int err = 0; | ||
6227 | 6114 | ||
6228 | del_timer_sync(&sp->alarm_timer); | 6115 | if (sp->intr_type == MSI) |
6229 | /* If s2io_set_link task is executing, wait till it completes. */ | 6116 | ret = s2io_enable_msi(sp); |
6230 | while (test_and_set_bit(0, &(sp->link_state))) { | 6117 | else if (sp->intr_type == MSI_X) |
6231 | msleep(50); | 6118 | ret = s2io_enable_msi_x(sp); |
6119 | if (ret) { | ||
6120 | DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); | ||
6121 | sp->intr_type = INTA; | ||
6232 | } | 6122 | } |
6233 | atomic_set(&sp->card_state, CARD_DOWN); | ||
6234 | 6123 | ||
6235 | /* disable Tx and Rx traffic on the NIC */ | 6124 | /* Store the values of the MSIX table in the nic_t structure */ |
6236 | stop_nic(sp); | 6125 | store_xmsi_data(sp); |
6237 | if (flag) { | ||
6238 | if (sp->intr_type == MSI_X) { | ||
6239 | int i; | ||
6240 | u16 msi_control; | ||
6241 | 6126 | ||
6242 | for (i=1; (sp->s2io_entries[i].in_use == | 6127 | /* After proper initialization of H/W, register ISR */ |
6243 | MSIX_REGISTERED_SUCCESS); i++) { | 6128 | if (sp->intr_type == MSI) { |
6244 | int vector = sp->entries[i].vector; | 6129 | err = request_irq((int) sp->pdev->irq, s2io_msi_handle, |
6245 | void *arg = sp->s2io_entries[i].arg; | 6130 | IRQF_SHARED, sp->name, dev); |
6131 | if (err) { | ||
6132 | pci_disable_msi(sp->pdev); | ||
6133 | DBG_PRINT(ERR_DBG, "%s: MSI registration failed\n", | ||
6134 | dev->name); | ||
6135 | return -1; | ||
6136 | } | ||
6137 | } | ||
6138 | if (sp->intr_type == MSI_X) { | ||
6139 | int i; | ||
6246 | 6140 | ||
6247 | free_irq(vector, arg); | 6141 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { |
6142 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | ||
6143 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | ||
6144 | dev->name, i); | ||
6145 | err = request_irq(sp->entries[i].vector, | ||
6146 | s2io_msix_fifo_handle, 0, sp->desc[i], | ||
6147 | sp->s2io_entries[i].arg); | ||
6148 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc[i], | ||
6149 | (unsigned long long)sp->msix_info[i].addr); | ||
6150 | } else { | ||
6151 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | ||
6152 | dev->name, i); | ||
6153 | err = request_irq(sp->entries[i].vector, | ||
6154 | s2io_msix_ring_handle, 0, sp->desc[i], | ||
6155 | sp->s2io_entries[i].arg); | ||
6156 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc[i], | ||
6157 | (unsigned long long)sp->msix_info[i].addr); | ||
6248 | } | 6158 | } |
6249 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | 6159 | if (err) { |
6250 | msi_control &= 0xFFFE; /* Disable MSI */ | 6160 | DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " |
6251 | pci_write_config_word(sp->pdev, 0x42, msi_control); | 6161 | "failed\n", dev->name, i); |
6252 | pci_disable_msix(sp->pdev); | 6162 | DBG_PRINT(ERR_DBG, "Returned: %d\n", err); |
6253 | } else { | 6163 | return -1; |
6254 | free_irq(sp->pdev->irq, dev); | 6164 | } |
6255 | if (sp->intr_type == MSI) | 6165 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; |
6256 | pci_disable_msi(sp->pdev); | 6166 | } |
6167 | } | ||
6168 | if (sp->intr_type == INTA) { | ||
6169 | err = request_irq((int) sp->pdev->irq, s2io_isr, IRQF_SHARED, | ||
6170 | sp->name, dev); | ||
6171 | if (err) { | ||
6172 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | ||
6173 | dev->name); | ||
6174 | return -1; | ||
6175 | } | ||
6176 | } | ||
6177 | return 0; | ||
6178 | } | ||
6179 | static void s2io_rem_isr(nic_t * sp) | ||
6180 | { | ||
6181 | int cnt = 0; | ||
6182 | struct net_device *dev = sp->dev; | ||
6183 | |||
6184 | if (sp->intr_type == MSI_X) { | ||
6185 | int i; | ||
6186 | u16 msi_control; | ||
6187 | |||
6188 | for (i=1; (sp->s2io_entries[i].in_use == | ||
6189 | MSIX_REGISTERED_SUCCESS); i++) { | ||
6190 | int vector = sp->entries[i].vector; | ||
6191 | void *arg = sp->s2io_entries[i].arg; | ||
6192 | |||
6193 | free_irq(vector, arg); | ||
6194 | } | ||
6195 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
6196 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
6197 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
6198 | |||
6199 | pci_disable_msix(sp->pdev); | ||
6200 | } else { | ||
6201 | free_irq(sp->pdev->irq, dev); | ||
6202 | if (sp->intr_type == MSI) { | ||
6203 | u16 val; | ||
6204 | |||
6205 | pci_disable_msi(sp->pdev); | ||
6206 | pci_read_config_word(sp->pdev, 0x4c, &val); | ||
6207 | val ^= 0x1; | ||
6208 | pci_write_config_word(sp->pdev, 0x4c, val); | ||
6257 | } | 6209 | } |
6258 | } | 6210 | } |
6259 | /* Waiting till all Interrupt handlers are complete */ | 6211 | /* Waiting till all Interrupt handlers are complete */ |
@@ -6264,6 +6216,26 @@ static void s2io_card_down(nic_t * sp, int flag) | |||
6264 | break; | 6216 | break; |
6265 | cnt++; | 6217 | cnt++; |
6266 | } while(cnt < 5); | 6218 | } while(cnt < 5); |
6219 | } | ||
6220 | |||
6221 | static void s2io_card_down(nic_t * sp) | ||
6222 | { | ||
6223 | int cnt = 0; | ||
6224 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
6225 | unsigned long flags; | ||
6226 | register u64 val64 = 0; | ||
6227 | |||
6228 | del_timer_sync(&sp->alarm_timer); | ||
6229 | /* If s2io_set_link task is executing, wait till it completes. */ | ||
6230 | while (test_and_set_bit(0, &(sp->link_state))) { | ||
6231 | msleep(50); | ||
6232 | } | ||
6233 | atomic_set(&sp->card_state, CARD_DOWN); | ||
6234 | |||
6235 | /* disable Tx and Rx traffic on the NIC */ | ||
6236 | stop_nic(sp); | ||
6237 | |||
6238 | s2io_rem_isr(sp); | ||
6267 | 6239 | ||
6268 | /* Kill tasklet. */ | 6240 | /* Kill tasklet. */ |
6269 | tasklet_kill(&sp->task); | 6241 | tasklet_kill(&sp->task); |
@@ -6315,23 +6287,16 @@ static int s2io_card_up(nic_t * sp) | |||
6315 | mac_info_t *mac_control; | 6287 | mac_info_t *mac_control; |
6316 | struct config_param *config; | 6288 | struct config_param *config; |
6317 | struct net_device *dev = (struct net_device *) sp->dev; | 6289 | struct net_device *dev = (struct net_device *) sp->dev; |
6290 | u16 interruptible; | ||
6318 | 6291 | ||
6319 | /* Initialize the H/W I/O registers */ | 6292 | /* Initialize the H/W I/O registers */ |
6320 | if (init_nic(sp) != 0) { | 6293 | if (init_nic(sp) != 0) { |
6321 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 6294 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
6322 | dev->name); | 6295 | dev->name); |
6296 | s2io_reset(sp); | ||
6323 | return -ENODEV; | 6297 | return -ENODEV; |
6324 | } | 6298 | } |
6325 | 6299 | ||
6326 | if (sp->intr_type == MSI) | ||
6327 | ret = s2io_enable_msi(sp); | ||
6328 | else if (sp->intr_type == MSI_X) | ||
6329 | ret = s2io_enable_msi_x(sp); | ||
6330 | if (ret) { | ||
6331 | DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); | ||
6332 | sp->intr_type = INTA; | ||
6333 | } | ||
6334 | |||
6335 | /* | 6300 | /* |
6336 | * Initializing the Rx buffers. For now we are considering only 1 | 6301 | * Initializing the Rx buffers. For now we are considering only 1 |
6337 | * Rx ring and initializing buffers into 30 Rx blocks | 6302 | * Rx ring and initializing buffers into 30 Rx blocks |
@@ -6355,28 +6320,46 @@ static int s2io_card_up(nic_t * sp) | |||
6355 | s2io_set_multicast(dev); | 6320 | s2io_set_multicast(dev); |
6356 | 6321 | ||
6357 | if (sp->lro) { | 6322 | if (sp->lro) { |
6358 | /* Initialize max aggregatable pkts based on MTU */ | 6323 | /* Initialize max aggregatable pkts per session based on MTU */ |
6359 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; | 6324 | sp->lro_max_aggr_per_sess = ((1<<16) - 1) / dev->mtu; |
6360 | /* Check if we can use(if specified) user provided value */ | 6325 | /* Check if we can use(if specified) user provided value */ |
6361 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) | 6326 | if (lro_max_pkts < sp->lro_max_aggr_per_sess) |
6362 | sp->lro_max_aggr_per_sess = lro_max_pkts; | 6327 | sp->lro_max_aggr_per_sess = lro_max_pkts; |
6363 | } | 6328 | } |
6364 | 6329 | ||
6365 | /* Enable tasklet for the device */ | ||
6366 | tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); | ||
6367 | |||
6368 | /* Enable Rx Traffic and interrupts on the NIC */ | 6330 | /* Enable Rx Traffic and interrupts on the NIC */ |
6369 | if (start_nic(sp)) { | 6331 | if (start_nic(sp)) { |
6370 | DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name); | 6332 | DBG_PRINT(ERR_DBG, "%s: Starting NIC failed\n", dev->name); |
6371 | tasklet_kill(&sp->task); | ||
6372 | s2io_reset(sp); | 6333 | s2io_reset(sp); |
6373 | free_irq(dev->irq, dev); | 6334 | free_rx_buffers(sp); |
6335 | return -ENODEV; | ||
6336 | } | ||
6337 | |||
6338 | /* Add interrupt service routine */ | ||
6339 | if (s2io_add_isr(sp) != 0) { | ||
6340 | if (sp->intr_type == MSI_X) | ||
6341 | s2io_rem_isr(sp); | ||
6342 | s2io_reset(sp); | ||
6374 | free_rx_buffers(sp); | 6343 | free_rx_buffers(sp); |
6375 | return -ENODEV; | 6344 | return -ENODEV; |
6376 | } | 6345 | } |
6377 | 6346 | ||
6378 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); | 6347 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); |
6379 | 6348 | ||
6349 | /* Enable tasklet for the device */ | ||
6350 | tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); | ||
6351 | |||
6352 | /* Enable select interrupts */ | ||
6353 | if (sp->intr_type != INTA) | ||
6354 | en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); | ||
6355 | else { | ||
6356 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | ||
6357 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; | ||
6358 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
6359 | en_dis_able_nic_intrs(sp, interruptible, ENABLE_INTRS); | ||
6360 | } | ||
6361 | |||
6362 | |||
6380 | atomic_set(&sp->card_state, CARD_UP); | 6363 | atomic_set(&sp->card_state, CARD_UP); |
6381 | return 0; | 6364 | return 0; |
6382 | } | 6365 | } |
@@ -6396,7 +6379,7 @@ static void s2io_restart_nic(unsigned long data) | |||
6396 | struct net_device *dev = (struct net_device *) data; | 6379 | struct net_device *dev = (struct net_device *) data; |
6397 | nic_t *sp = dev->priv; | 6380 | nic_t *sp = dev->priv; |
6398 | 6381 | ||
6399 | s2io_card_down(sp, 0); | 6382 | s2io_card_down(sp); |
6400 | if (s2io_card_up(sp)) { | 6383 | if (s2io_card_up(sp)) { |
6401 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 6384 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
6402 | dev->name); | 6385 | dev->name); |
@@ -6438,7 +6421,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
6438 | * @cksum : FCS checksum of the frame. | 6421 | * @cksum : FCS checksum of the frame. |
6439 | * @ring_no : the ring from which this RxD was extracted. | 6422 | * @ring_no : the ring from which this RxD was extracted. |
6440 | * Description: | 6423 | * Description: |
6441 | * This function is called by the Tx interrupt serivce routine to perform | 6424 | * 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 | 6425 | * 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 | 6426 | * 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 | 6427 | * SKBs cksum variable, increments the Rx packet count and passes the SKB |
@@ -6615,7 +6598,7 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) | |||
6615 | } else { | 6598 | } else { |
6616 | send_up: | 6599 | send_up: |
6617 | queue_rx_frame(skb); | 6600 | queue_rx_frame(skb); |
6618 | } | 6601 | } |
6619 | dev->last_rx = jiffies; | 6602 | dev->last_rx = jiffies; |
6620 | aggregate: | 6603 | aggregate: |
6621 | atomic_dec(&sp->rx_bufs_left[ring_no]); | 6604 | atomic_dec(&sp->rx_bufs_left[ring_no]); |
@@ -6698,33 +6681,6 @@ static void s2io_init_pci(nic_t * sp) | |||
6698 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 6681 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
6699 | } | 6682 | } |
6700 | 6683 | ||
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) | 6684 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) |
6729 | { | 6685 | { |
6730 | if ( tx_fifo_num > 8) { | 6686 | if ( tx_fifo_num > 8) { |
@@ -6762,7 +6718,7 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | |||
6762 | if ((*dev_intr_type == MSI_X) && | 6718 | if ((*dev_intr_type == MSI_X) && |
6763 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && | 6719 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && |
6764 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { | 6720 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { |
6765 | DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " | 6721 | DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " |
6766 | "Defaulting to INTA\n"); | 6722 | "Defaulting to INTA\n"); |
6767 | *dev_intr_type = INTA; | 6723 | *dev_intr_type = INTA; |
6768 | } | 6724 | } |
@@ -6832,8 +6788,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6832 | } | 6788 | } |
6833 | if (dev_intr_type != MSI_X) { | 6789 | if (dev_intr_type != MSI_X) { |
6834 | if (pci_request_regions(pdev, s2io_driver_name)) { | 6790 | if (pci_request_regions(pdev, s2io_driver_name)) { |
6835 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | 6791 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"); |
6836 | pci_disable_device(pdev); | 6792 | pci_disable_device(pdev); |
6837 | return -ENODEV; | 6793 | return -ENODEV; |
6838 | } | 6794 | } |
6839 | } | 6795 | } |
@@ -6890,7 +6846,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
6890 | sp->device_type = XFRAME_I_DEVICE; | 6846 | sp->device_type = XFRAME_I_DEVICE; |
6891 | 6847 | ||
6892 | sp->lro = lro; | 6848 | sp->lro = lro; |
6893 | 6849 | ||
6894 | /* Initialize some PCI/PCI-X fields of the NIC. */ | 6850 | /* Initialize some PCI/PCI-X fields of the NIC. */ |
6895 | s2io_init_pci(sp); | 6851 | s2io_init_pci(sp); |
6896 | 6852 | ||
@@ -6957,7 +6913,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 */ | 6913 | /* initialize the shared memory used by the NIC and the host */ |
6958 | if (init_shared_mem(sp)) { | 6914 | if (init_shared_mem(sp)) { |
6959 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", | 6915 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", |
6960 | __FUNCTION__); | 6916 | dev->name); |
6961 | ret = -ENOMEM; | 6917 | ret = -ENOMEM; |
6962 | goto mem_alloc_failed; | 6918 | goto mem_alloc_failed; |
6963 | } | 6919 | } |
@@ -7021,6 +6977,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7021 | #ifdef NETIF_F_TSO | 6977 | #ifdef NETIF_F_TSO |
7022 | dev->features |= NETIF_F_TSO; | 6978 | dev->features |= NETIF_F_TSO; |
7023 | #endif | 6979 | #endif |
6980 | #ifdef NETIF_F_TSO6 | ||
6981 | dev->features |= NETIF_F_TSO6; | ||
6982 | #endif | ||
7024 | if (sp->device_type & XFRAME_II_DEVICE) { | 6983 | if (sp->device_type & XFRAME_II_DEVICE) { |
7025 | dev->features |= NETIF_F_UFO; | 6984 | dev->features |= NETIF_F_UFO; |
7026 | dev->features |= NETIF_F_HW_CSUM; | 6985 | dev->features |= NETIF_F_HW_CSUM; |
@@ -7091,6 +7050,9 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7091 | dev->addr_len = ETH_ALEN; | 7050 | dev->addr_len = ETH_ALEN; |
7092 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); | 7051 | memcpy(dev->dev_addr, sp->def_mac_addr, ETH_ALEN); |
7093 | 7052 | ||
7053 | /* reset Nic and bring it to known state */ | ||
7054 | s2io_reset(sp); | ||
7055 | |||
7094 | /* | 7056 | /* |
7095 | * Initialize the tasklet status and link state flags | 7057 | * Initialize the tasklet status and link state flags |
7096 | * and the card state parameter | 7058 | * and the card state parameter |
@@ -7128,11 +7090,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7128 | goto register_failed; | 7090 | goto register_failed; |
7129 | } | 7091 | } |
7130 | s2io_vpd_read(sp); | 7092 | s2io_vpd_read(sp); |
7131 | DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); | ||
7132 | DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", | ||
7133 | get_xena_rev_id(sp->pdev), | ||
7134 | s2io_driver_version); | ||
7135 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); | 7093 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); |
7094 | DBG_PRINT(ERR_DBG, "%s: Neterion %s (rev %d)\n",dev->name, | ||
7095 | sp->product_name, get_xena_rev_id(sp->pdev)); | ||
7096 | DBG_PRINT(ERR_DBG, "%s: Driver version %s\n", dev->name, | ||
7097 | s2io_driver_version); | ||
7136 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " | 7098 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " |
7137 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, | 7099 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, |
7138 | sp->def_mac_addr[0].mac_addr[0], | 7100 | sp->def_mac_addr[0].mac_addr[0], |
@@ -7272,7 +7234,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) | |||
7272 | 7234 | ||
7273 | int __init s2io_starter(void) | 7235 | int __init s2io_starter(void) |
7274 | { | 7236 | { |
7275 | return pci_module_init(&s2io_driver); | 7237 | return pci_register_driver(&s2io_driver); |
7276 | } | 7238 | } |
7277 | 7239 | ||
7278 | /** | 7240 | /** |
@@ -7289,7 +7251,7 @@ static void s2io_closer(void) | |||
7289 | module_init(s2io_starter); | 7251 | module_init(s2io_starter); |
7290 | module_exit(s2io_closer); | 7252 | module_exit(s2io_closer); |
7291 | 7253 | ||
7292 | static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, | 7254 | static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, |
7293 | struct tcphdr **tcp, RxD_t *rxdp) | 7255 | struct tcphdr **tcp, RxD_t *rxdp) |
7294 | { | 7256 | { |
7295 | int ip_off; | 7257 | int ip_off; |
@@ -7351,7 +7313,7 @@ static void initiate_new_session(lro_t *lro, u8 *l2h, | |||
7351 | lro->sg_num = 1; | 7313 | lro->sg_num = 1; |
7352 | lro->total_len = ntohs(ip->tot_len); | 7314 | lro->total_len = ntohs(ip->tot_len); |
7353 | lro->frags_len = 0; | 7315 | lro->frags_len = 0; |
7354 | /* | 7316 | /* |
7355 | * check if we saw TCP timestamp. Other consistency checks have | 7317 | * check if we saw TCP timestamp. Other consistency checks have |
7356 | * already been done. | 7318 | * already been done. |
7357 | */ | 7319 | */ |
@@ -7408,12 +7370,12 @@ static void aggregate_new_rx(lro_t *lro, struct iphdr *ip, | |||
7408 | /* Update ack seq no. and window ad(from this pkt) in LRO object */ | 7370 | /* Update ack seq no. and window ad(from this pkt) in LRO object */ |
7409 | lro->tcp_ack = tcp->ack_seq; | 7371 | lro->tcp_ack = tcp->ack_seq; |
7410 | lro->window = tcp->window; | 7372 | lro->window = tcp->window; |
7411 | 7373 | ||
7412 | if (lro->saw_ts) { | 7374 | if (lro->saw_ts) { |
7413 | u32 *ptr; | 7375 | u32 *ptr; |
7414 | /* Update tsecr and tsval from this packet */ | 7376 | /* Update tsecr and tsval from this packet */ |
7415 | ptr = (u32 *) (tcp + 1); | 7377 | ptr = (u32 *) (tcp + 1); |
7416 | lro->cur_tsval = *(ptr + 1); | 7378 | lro->cur_tsval = *(ptr + 1); |
7417 | lro->cur_tsecr = *(ptr + 2); | 7379 | lro->cur_tsecr = *(ptr + 2); |
7418 | } | 7380 | } |
7419 | } | 7381 | } |
@@ -7433,8 +7395,13 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7433 | if (ip->ihl != 5) /* IP has options */ | 7395 | if (ip->ihl != 5) /* IP has options */ |
7434 | return -1; | 7396 | return -1; |
7435 | 7397 | ||
7398 | /* If we see CE codepoint in IP header, packet is not mergeable */ | ||
7399 | if (INET_ECN_is_ce(ipv4_get_dsfield(ip))) | ||
7400 | return -1; | ||
7401 | |||
7402 | /* If we see ECE or CWR flags in TCP header, packet is not mergeable */ | ||
7436 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || | 7403 | if (tcp->urg || tcp->psh || tcp->rst || tcp->syn || tcp->fin || |
7437 | !tcp->ack) { | 7404 | tcp->ece || tcp->cwr || !tcp->ack) { |
7438 | /* | 7405 | /* |
7439 | * Currently recognize only the ack control word and | 7406 | * Currently recognize only the ack control word and |
7440 | * any other control field being set would result in | 7407 | * any other control field being set would result in |
@@ -7443,7 +7410,7 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7443 | return -1; | 7410 | return -1; |
7444 | } | 7411 | } |
7445 | 7412 | ||
7446 | /* | 7413 | /* |
7447 | * Allow only one TCP timestamp option. Don't aggregate if | 7414 | * Allow only one TCP timestamp option. Don't aggregate if |
7448 | * any other options are detected. | 7415 | * any other options are detected. |
7449 | */ | 7416 | */ |
@@ -7451,7 +7418,7 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7451 | return -1; | 7418 | return -1; |
7452 | 7419 | ||
7453 | if (tcp->doff == 8) { | 7420 | if (tcp->doff == 8) { |
7454 | ptr = (u8 *)(tcp + 1); | 7421 | ptr = (u8 *)(tcp + 1); |
7455 | while (*ptr == TCPOPT_NOP) | 7422 | while (*ptr == TCPOPT_NOP) |
7456 | ptr++; | 7423 | ptr++; |
7457 | if (*ptr != TCPOPT_TIMESTAMP || *(ptr+1) != TCPOLEN_TIMESTAMP) | 7424 | if (*ptr != TCPOPT_TIMESTAMP || *(ptr+1) != TCPOLEN_TIMESTAMP) |
@@ -7463,7 +7430,7 @@ static int verify_l3_l4_lro_capable(lro_t *l_lro, struct iphdr *ip, | |||
7463 | return -1; | 7430 | return -1; |
7464 | 7431 | ||
7465 | /* timestamp echo reply should be non-zero */ | 7432 | /* timestamp echo reply should be non-zero */ |
7466 | if (*((u32 *)(ptr+6)) == 0) | 7433 | if (*((u32 *)(ptr+6)) == 0) |
7467 | return -1; | 7434 | return -1; |
7468 | } | 7435 | } |
7469 | 7436 | ||
@@ -7588,18 +7555,16 @@ static void queue_rx_frame(struct sk_buff *skb) | |||
7588 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, | 7555 | static void lro_append_pkt(nic_t *sp, lro_t *lro, struct sk_buff *skb, |
7589 | u32 tcp_len) | 7556 | u32 tcp_len) |
7590 | { | 7557 | { |
7591 | struct sk_buff *tmp, *first = lro->parent; | 7558 | struct sk_buff *first = lro->parent; |
7592 | 7559 | ||
7593 | first->len += tcp_len; | 7560 | first->len += tcp_len; |
7594 | first->data_len = lro->frags_len; | 7561 | first->data_len = lro->frags_len; |
7595 | skb_pull(skb, (skb->len - tcp_len)); | 7562 | skb_pull(skb, (skb->len - tcp_len)); |
7596 | if ((tmp = skb_shinfo(first)->frag_list)) { | 7563 | if (skb_shinfo(first)->frag_list) |
7597 | while (tmp->next) | 7564 | lro->last_frag->next = skb; |
7598 | tmp = tmp->next; | ||
7599 | tmp->next = skb; | ||
7600 | } | ||
7601 | else | 7565 | else |
7602 | skb_shinfo(first)->frag_list = skb; | 7566 | skb_shinfo(first)->frag_list = skb; |
7567 | lro->last_frag = skb; | ||
7603 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; | 7568 | sp->mac_control.stats_info->sw_stat.clubbed_frms_cnt++; |
7604 | return; | 7569 | return; |
7605 | } | 7570 | } |