diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 459 |
1 files changed, 362 insertions, 97 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index c082cf0b1ac6..dcbe01b0ca0d 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -50,6 +50,8 @@ | |||
50 | * Possible values '1' for enable , '0' for disable. | 50 | * Possible values '1' for enable , '0' for disable. |
51 | * Default is '2' - which means disable in promisc mode | 51 | * Default is '2' - which means disable in promisc mode |
52 | * and enable in non-promiscuous mode. | 52 | * and enable in non-promiscuous mode. |
53 | * multiq: This parameter used to enable/disable MULTIQUEUE support. | ||
54 | * Possible values '1' for enable and '0' for disable. Default is '0' | ||
53 | ************************************************************************/ | 55 | ************************************************************************/ |
54 | 56 | ||
55 | #include <linux/module.h> | 57 | #include <linux/module.h> |
@@ -386,6 +388,26 @@ static void s2io_vlan_rx_register(struct net_device *dev, | |||
386 | /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ | 388 | /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ |
387 | static int vlan_strip_flag; | 389 | static int vlan_strip_flag; |
388 | 390 | ||
391 | /* Unregister the vlan */ | ||
392 | static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) | ||
393 | { | ||
394 | int i; | ||
395 | struct s2io_nic *nic = dev->priv; | ||
396 | unsigned long flags[MAX_TX_FIFOS]; | ||
397 | struct mac_info *mac_control = &nic->mac_control; | ||
398 | struct config_param *config = &nic->config; | ||
399 | |||
400 | for (i = 0; i < config->tx_fifo_num; i++) | ||
401 | spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]); | ||
402 | |||
403 | if (nic->vlgrp) | ||
404 | vlan_group_set_device(nic->vlgrp, vid, NULL); | ||
405 | |||
406 | for (i = config->tx_fifo_num - 1; i >= 0; i--) | ||
407 | spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock, | ||
408 | flags[i]); | ||
409 | } | ||
410 | |||
389 | /* | 411 | /* |
390 | * Constants to be programmed into the Xena's registers, to configure | 412 | * Constants to be programmed into the Xena's registers, to configure |
391 | * the XAUI. | 413 | * the XAUI. |
@@ -456,10 +478,9 @@ MODULE_VERSION(DRV_VERSION); | |||
456 | 478 | ||
457 | 479 | ||
458 | /* Module Loadable parameters. */ | 480 | /* Module Loadable parameters. */ |
459 | S2IO_PARM_INT(tx_fifo_num, 1); | 481 | S2IO_PARM_INT(tx_fifo_num, FIFO_DEFAULT_NUM); |
460 | S2IO_PARM_INT(rx_ring_num, 1); | 482 | S2IO_PARM_INT(rx_ring_num, 1); |
461 | 483 | S2IO_PARM_INT(multiq, 0); | |
462 | |||
463 | S2IO_PARM_INT(rx_ring_mode, 1); | 484 | S2IO_PARM_INT(rx_ring_mode, 1); |
464 | S2IO_PARM_INT(use_continuous_tx_intrs, 1); | 485 | S2IO_PARM_INT(use_continuous_tx_intrs, 1); |
465 | S2IO_PARM_INT(rmac_pause_time, 0x100); | 486 | S2IO_PARM_INT(rmac_pause_time, 0x100); |
@@ -469,6 +490,8 @@ S2IO_PARM_INT(shared_splits, 0); | |||
469 | S2IO_PARM_INT(tmac_util_period, 5); | 490 | S2IO_PARM_INT(tmac_util_period, 5); |
470 | S2IO_PARM_INT(rmac_util_period, 5); | 491 | S2IO_PARM_INT(rmac_util_period, 5); |
471 | S2IO_PARM_INT(l3l4hdr_size, 128); | 492 | S2IO_PARM_INT(l3l4hdr_size, 128); |
493 | /* 0 is no steering, 1 is Priority steering, 2 is Default steering */ | ||
494 | S2IO_PARM_INT(tx_steering_type, TX_DEFAULT_STEERING); | ||
472 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 495 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
473 | S2IO_PARM_INT(rxsync_frequency, 3); | 496 | S2IO_PARM_INT(rxsync_frequency, 3); |
474 | /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ | 497 | /* Interrupt type. Values can be 0(INTA), 2(MSI_X) */ |
@@ -533,6 +556,101 @@ static struct pci_driver s2io_driver = { | |||
533 | /* A simplifier macro used both by init and free shared_mem Fns(). */ | 556 | /* A simplifier macro used both by init and free shared_mem Fns(). */ |
534 | #define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each) | 557 | #define TXD_MEM_PAGE_CNT(len, per_each) ((len+per_each - 1) / per_each) |
535 | 558 | ||
559 | /* netqueue manipulation helper functions */ | ||
560 | static inline void s2io_stop_all_tx_queue(struct s2io_nic *sp) | ||
561 | { | ||
562 | int i; | ||
563 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
564 | if (sp->config.multiq) { | ||
565 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
566 | netif_stop_subqueue(sp->dev, i); | ||
567 | } else | ||
568 | #endif | ||
569 | { | ||
570 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
571 | sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_STOP; | ||
572 | netif_stop_queue(sp->dev); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | static inline void s2io_stop_tx_queue(struct s2io_nic *sp, int fifo_no) | ||
577 | { | ||
578 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
579 | if (sp->config.multiq) | ||
580 | netif_stop_subqueue(sp->dev, fifo_no); | ||
581 | else | ||
582 | #endif | ||
583 | { | ||
584 | sp->mac_control.fifos[fifo_no].queue_state = | ||
585 | FIFO_QUEUE_STOP; | ||
586 | netif_stop_queue(sp->dev); | ||
587 | } | ||
588 | } | ||
589 | |||
590 | static inline void s2io_start_all_tx_queue(struct s2io_nic *sp) | ||
591 | { | ||
592 | int i; | ||
593 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
594 | if (sp->config.multiq) { | ||
595 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
596 | netif_start_subqueue(sp->dev, i); | ||
597 | } else | ||
598 | #endif | ||
599 | { | ||
600 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
601 | sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; | ||
602 | netif_start_queue(sp->dev); | ||
603 | } | ||
604 | } | ||
605 | |||
606 | static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no) | ||
607 | { | ||
608 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
609 | if (sp->config.multiq) | ||
610 | netif_start_subqueue(sp->dev, fifo_no); | ||
611 | else | ||
612 | #endif | ||
613 | { | ||
614 | sp->mac_control.fifos[fifo_no].queue_state = | ||
615 | FIFO_QUEUE_START; | ||
616 | netif_start_queue(sp->dev); | ||
617 | } | ||
618 | } | ||
619 | |||
620 | static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp) | ||
621 | { | ||
622 | int i; | ||
623 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
624 | if (sp->config.multiq) { | ||
625 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
626 | netif_wake_subqueue(sp->dev, i); | ||
627 | } else | ||
628 | #endif | ||
629 | { | ||
630 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
631 | sp->mac_control.fifos[i].queue_state = FIFO_QUEUE_START; | ||
632 | netif_wake_queue(sp->dev); | ||
633 | } | ||
634 | } | ||
635 | |||
636 | static inline void s2io_wake_tx_queue( | ||
637 | struct fifo_info *fifo, int cnt, u8 multiq) | ||
638 | { | ||
639 | |||
640 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
641 | if (multiq) { | ||
642 | if (cnt && __netif_subqueue_stopped(fifo->dev, fifo->fifo_no)) | ||
643 | netif_wake_subqueue(fifo->dev, fifo->fifo_no); | ||
644 | } else | ||
645 | #endif | ||
646 | if (cnt && (fifo->queue_state == FIFO_QUEUE_STOP)) { | ||
647 | if (netif_queue_stopped(fifo->dev)) { | ||
648 | fifo->queue_state = FIFO_QUEUE_START; | ||
649 | netif_wake_queue(fifo->dev); | ||
650 | } | ||
651 | } | ||
652 | } | ||
653 | |||
536 | /** | 654 | /** |
537 | * init_shared_mem - Allocation and Initialization of Memory | 655 | * init_shared_mem - Allocation and Initialization of Memory |
538 | * @nic: Device private variable. | 656 | * @nic: Device private variable. |
@@ -614,6 +732,7 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
614 | mac_control->fifos[i].fifo_no = i; | 732 | mac_control->fifos[i].fifo_no = i; |
615 | mac_control->fifos[i].nic = nic; | 733 | mac_control->fifos[i].nic = nic; |
616 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2; | 734 | mac_control->fifos[i].max_txds = MAX_SKB_FRAGS + 2; |
735 | mac_control->fifos[i].dev = dev; | ||
617 | 736 | ||
618 | for (j = 0; j < page_num; j++) { | 737 | for (j = 0; j < page_num; j++) { |
619 | int k = 0; | 738 | int k = 0; |
@@ -2948,7 +3067,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2948 | struct lro *lro = &nic->lro0_n[i]; | 3067 | struct lro *lro = &nic->lro0_n[i]; |
2949 | if (lro->in_use) { | 3068 | if (lro->in_use) { |
2950 | update_L3L4_header(nic, lro); | 3069 | update_L3L4_header(nic, lro); |
2951 | queue_rx_frame(lro->parent); | 3070 | queue_rx_frame(lro->parent, lro->vlan_tag); |
2952 | clear_lro_session(lro); | 3071 | clear_lro_session(lro); |
2953 | } | 3072 | } |
2954 | } | 3073 | } |
@@ -2972,10 +3091,10 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2972 | static void tx_intr_handler(struct fifo_info *fifo_data) | 3091 | static void tx_intr_handler(struct fifo_info *fifo_data) |
2973 | { | 3092 | { |
2974 | struct s2io_nic *nic = fifo_data->nic; | 3093 | struct s2io_nic *nic = fifo_data->nic; |
2975 | struct net_device *dev = (struct net_device *) nic->dev; | ||
2976 | struct tx_curr_get_info get_info, put_info; | 3094 | struct tx_curr_get_info get_info, put_info; |
2977 | struct sk_buff *skb; | 3095 | struct sk_buff *skb = NULL; |
2978 | struct TxD *txdlp; | 3096 | struct TxD *txdlp; |
3097 | int pkt_cnt = 0; | ||
2979 | unsigned long flags = 0; | 3098 | unsigned long flags = 0; |
2980 | u8 err_mask; | 3099 | u8 err_mask; |
2981 | 3100 | ||
@@ -3036,6 +3155,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) | |||
3036 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); | 3155 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); |
3037 | return; | 3156 | return; |
3038 | } | 3157 | } |
3158 | pkt_cnt++; | ||
3039 | 3159 | ||
3040 | /* Updating the statistics block */ | 3160 | /* Updating the statistics block */ |
3041 | nic->stats.tx_bytes += skb->len; | 3161 | nic->stats.tx_bytes += skb->len; |
@@ -3051,8 +3171,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) | |||
3051 | get_info.offset; | 3171 | get_info.offset; |
3052 | } | 3172 | } |
3053 | 3173 | ||
3054 | if (netif_queue_stopped(dev)) | 3174 | s2io_wake_tx_queue(fifo_data, pkt_cnt, nic->config.multiq); |
3055 | netif_wake_queue(dev); | ||
3056 | 3175 | ||
3057 | spin_unlock_irqrestore(&fifo_data->tx_lock, flags); | 3176 | spin_unlock_irqrestore(&fifo_data->tx_lock, flags); |
3058 | } | 3177 | } |
@@ -3933,8 +4052,7 @@ static int s2io_open(struct net_device *dev) | |||
3933 | err = -ENODEV; | 4052 | err = -ENODEV; |
3934 | goto hw_init_failed; | 4053 | goto hw_init_failed; |
3935 | } | 4054 | } |
3936 | 4055 | s2io_start_all_tx_queue(sp); | |
3937 | netif_start_queue(dev); | ||
3938 | return 0; | 4056 | return 0; |
3939 | 4057 | ||
3940 | hw_init_failed: | 4058 | hw_init_failed: |
@@ -3979,8 +4097,7 @@ static int s2io_close(struct net_device *dev) | |||
3979 | if (!is_s2io_card_up(sp)) | 4097 | if (!is_s2io_card_up(sp)) |
3980 | return 0; | 4098 | return 0; |
3981 | 4099 | ||
3982 | netif_stop_queue(dev); | 4100 | s2io_stop_all_tx_queue(sp); |
3983 | |||
3984 | /* delete all populated mac entries */ | 4101 | /* delete all populated mac entries */ |
3985 | for (offset = 1; offset < config->max_mc_addr; offset++) { | 4102 | for (offset = 1; offset < config->max_mc_addr; offset++) { |
3986 | tmp64 = do_s2io_read_unicast_mc(sp, offset); | 4103 | tmp64 = do_s2io_read_unicast_mc(sp, offset); |
@@ -4016,11 +4133,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4016 | struct TxFIFO_element __iomem *tx_fifo; | 4133 | struct TxFIFO_element __iomem *tx_fifo; |
4017 | unsigned long flags = 0; | 4134 | unsigned long flags = 0; |
4018 | u16 vlan_tag = 0; | 4135 | u16 vlan_tag = 0; |
4019 | int vlan_priority = 0; | ||
4020 | struct fifo_info *fifo = NULL; | 4136 | struct fifo_info *fifo = NULL; |
4021 | struct mac_info *mac_control; | 4137 | struct mac_info *mac_control; |
4022 | struct config_param *config; | 4138 | struct config_param *config; |
4139 | int do_spin_lock = 1; | ||
4023 | int offload_type; | 4140 | int offload_type; |
4141 | int enable_per_list_interrupt = 0; | ||
4024 | struct swStat *stats = &sp->mac_control.stats_info->sw_stat; | 4142 | struct swStat *stats = &sp->mac_control.stats_info->sw_stat; |
4025 | 4143 | ||
4026 | mac_control = &sp->mac_control; | 4144 | mac_control = &sp->mac_control; |
@@ -4042,15 +4160,67 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4042 | } | 4160 | } |
4043 | 4161 | ||
4044 | queue = 0; | 4162 | queue = 0; |
4045 | /* Get Fifo number to Transmit based on vlan priority */ | 4163 | if (sp->vlgrp && vlan_tx_tag_present(skb)) |
4046 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | ||
4047 | vlan_tag = vlan_tx_tag_get(skb); | 4164 | vlan_tag = vlan_tx_tag_get(skb); |
4048 | vlan_priority = vlan_tag >> 13; | 4165 | if (sp->config.tx_steering_type == TX_DEFAULT_STEERING) { |
4049 | queue = config->fifo_mapping[vlan_priority]; | 4166 | if (skb->protocol == htons(ETH_P_IP)) { |
4167 | struct iphdr *ip; | ||
4168 | struct tcphdr *th; | ||
4169 | ip = ip_hdr(skb); | ||
4170 | |||
4171 | if ((ip->frag_off & htons(IP_OFFSET|IP_MF)) == 0) { | ||
4172 | th = (struct tcphdr *)(((unsigned char *)ip) + | ||
4173 | ip->ihl*4); | ||
4174 | |||
4175 | if (ip->protocol == IPPROTO_TCP) { | ||
4176 | queue_len = sp->total_tcp_fifos; | ||
4177 | queue = (ntohs(th->source) + | ||
4178 | ntohs(th->dest)) & | ||
4179 | sp->fifo_selector[queue_len - 1]; | ||
4180 | if (queue >= queue_len) | ||
4181 | queue = queue_len - 1; | ||
4182 | } else if (ip->protocol == IPPROTO_UDP) { | ||
4183 | queue_len = sp->total_udp_fifos; | ||
4184 | queue = (ntohs(th->source) + | ||
4185 | ntohs(th->dest)) & | ||
4186 | sp->fifo_selector[queue_len - 1]; | ||
4187 | if (queue >= queue_len) | ||
4188 | queue = queue_len - 1; | ||
4189 | queue += sp->udp_fifo_idx; | ||
4190 | if (skb->len > 1024) | ||
4191 | enable_per_list_interrupt = 1; | ||
4192 | do_spin_lock = 0; | ||
4193 | } | ||
4194 | } | ||
4195 | } | ||
4196 | } else if (sp->config.tx_steering_type == TX_PRIORITY_STEERING) | ||
4197 | /* get fifo number based on skb->priority value */ | ||
4198 | queue = config->fifo_mapping | ||
4199 | [skb->priority & (MAX_TX_FIFOS - 1)]; | ||
4200 | fifo = &mac_control->fifos[queue]; | ||
4201 | |||
4202 | if (do_spin_lock) | ||
4203 | spin_lock_irqsave(&fifo->tx_lock, flags); | ||
4204 | else { | ||
4205 | if (unlikely(!spin_trylock_irqsave(&fifo->tx_lock, flags))) | ||
4206 | return NETDEV_TX_LOCKED; | ||
4207 | } | ||
4208 | |||
4209 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | ||
4210 | if (sp->config.multiq) { | ||
4211 | if (__netif_subqueue_stopped(dev, fifo->fifo_no)) { | ||
4212 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | ||
4213 | return NETDEV_TX_BUSY; | ||
4214 | } | ||
4215 | } else | ||
4216 | #endif | ||
4217 | if (unlikely(fifo->queue_state == FIFO_QUEUE_STOP)) { | ||
4218 | if (netif_queue_stopped(dev)) { | ||
4219 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | ||
4220 | return NETDEV_TX_BUSY; | ||
4221 | } | ||
4050 | } | 4222 | } |
4051 | 4223 | ||
4052 | fifo = &mac_control->fifos[queue]; | ||
4053 | spin_lock_irqsave(&fifo->tx_lock, flags); | ||
4054 | put_off = (u16) fifo->tx_curr_put_info.offset; | 4224 | put_off = (u16) fifo->tx_curr_put_info.offset; |
4055 | get_off = (u16) fifo->tx_curr_get_info.offset; | 4225 | get_off = (u16) fifo->tx_curr_get_info.offset; |
4056 | txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr; | 4226 | txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr; |
@@ -4060,7 +4230,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4060 | if (txdp->Host_Control || | 4230 | if (txdp->Host_Control || |
4061 | ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { | 4231 | ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { |
4062 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); | 4232 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); |
4063 | netif_stop_queue(dev); | 4233 | s2io_stop_tx_queue(sp, fifo->fifo_no); |
4064 | dev_kfree_skb(skb); | 4234 | dev_kfree_skb(skb); |
4065 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | 4235 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
4066 | return 0; | 4236 | return 0; |
@@ -4079,8 +4249,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4079 | txdp->Control_1 |= TXD_GATHER_CODE_FIRST; | 4249 | txdp->Control_1 |= TXD_GATHER_CODE_FIRST; |
4080 | txdp->Control_1 |= TXD_LIST_OWN_XENA; | 4250 | txdp->Control_1 |= TXD_LIST_OWN_XENA; |
4081 | txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no); | 4251 | txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no); |
4082 | 4252 | if (enable_per_list_interrupt) | |
4083 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | 4253 | if (put_off & (queue_len >> 5)) |
4254 | txdp->Control_2 |= TXD_INT_TYPE_PER_LIST; | ||
4255 | if (vlan_tag) { | ||
4084 | txdp->Control_2 |= TXD_VLAN_ENABLE; | 4256 | txdp->Control_2 |= TXD_VLAN_ENABLE; |
4085 | txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag); | 4257 | txdp->Control_2 |= TXD_VLAN_TAG(vlan_tag); |
4086 | } | 4258 | } |
@@ -4095,11 +4267,12 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4095 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); | 4267 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); |
4096 | txdp->Control_1 |= TXD_BUFFER0_SIZE(8); | 4268 | txdp->Control_1 |= TXD_BUFFER0_SIZE(8); |
4097 | #ifdef __BIG_ENDIAN | 4269 | #ifdef __BIG_ENDIAN |
4270 | /* both variants do cpu_to_be64(be32_to_cpu(...)) */ | ||
4098 | fifo->ufo_in_band_v[put_off] = | 4271 | fifo->ufo_in_band_v[put_off] = |
4099 | (u64)skb_shinfo(skb)->ip6_frag_id; | 4272 | (__force u64)skb_shinfo(skb)->ip6_frag_id; |
4100 | #else | 4273 | #else |
4101 | fifo->ufo_in_band_v[put_off] = | 4274 | fifo->ufo_in_band_v[put_off] = |
4102 | (u64)skb_shinfo(skb)->ip6_frag_id << 32; | 4275 | (__force u64)skb_shinfo(skb)->ip6_frag_id << 32; |
4103 | #endif | 4276 | #endif |
4104 | txdp->Host_Control = (unsigned long)fifo->ufo_in_band_v; | 4277 | txdp->Host_Control = (unsigned long)fifo->ufo_in_band_v; |
4105 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4278 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
@@ -4166,7 +4339,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4166 | DBG_PRINT(TX_DBG, | 4339 | DBG_PRINT(TX_DBG, |
4167 | "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", | 4340 | "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", |
4168 | put_off, get_off); | 4341 | put_off, get_off); |
4169 | netif_stop_queue(dev); | 4342 | s2io_stop_tx_queue(sp, fifo->fifo_no); |
4170 | } | 4343 | } |
4171 | mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; | 4344 | mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; |
4172 | dev->trans_start = jiffies; | 4345 | dev->trans_start = jiffies; |
@@ -4178,7 +4351,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4178 | return 0; | 4351 | return 0; |
4179 | pci_map_failed: | 4352 | pci_map_failed: |
4180 | stats->pci_map_fail_cnt++; | 4353 | stats->pci_map_fail_cnt++; |
4181 | netif_stop_queue(dev); | 4354 | s2io_stop_tx_queue(sp, fifo->fifo_no); |
4182 | stats->mem_freed += skb->truesize; | 4355 | stats->mem_freed += skb->truesize; |
4183 | dev_kfree_skb(skb); | 4356 | dev_kfree_skb(skb); |
4184 | spin_unlock_irqrestore(&fifo->tx_lock, flags); | 4357 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
@@ -4590,7 +4763,7 @@ static void s2io_handle_errors(void * dev_id) | |||
4590 | return; | 4763 | return; |
4591 | 4764 | ||
4592 | reset: | 4765 | reset: |
4593 | netif_stop_queue(dev); | 4766 | s2io_stop_all_tx_queue(sp); |
4594 | schedule_work(&sp->rst_timer_task); | 4767 | schedule_work(&sp->rst_timer_task); |
4595 | sw_stat->soft_reset_cnt++; | 4768 | sw_stat->soft_reset_cnt++; |
4596 | return; | 4769 | return; |
@@ -6577,16 +6750,15 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
6577 | 6750 | ||
6578 | dev->mtu = new_mtu; | 6751 | dev->mtu = new_mtu; |
6579 | if (netif_running(dev)) { | 6752 | if (netif_running(dev)) { |
6753 | s2io_stop_all_tx_queue(sp); | ||
6580 | s2io_card_down(sp); | 6754 | s2io_card_down(sp); |
6581 | netif_stop_queue(dev); | ||
6582 | ret = s2io_card_up(sp); | 6755 | ret = s2io_card_up(sp); |
6583 | if (ret) { | 6756 | if (ret) { |
6584 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 6757 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
6585 | __FUNCTION__); | 6758 | __FUNCTION__); |
6586 | return ret; | 6759 | return ret; |
6587 | } | 6760 | } |
6588 | if (netif_queue_stopped(dev)) | 6761 | s2io_wake_all_tx_queue(sp); |
6589 | netif_wake_queue(dev); | ||
6590 | } else { /* Device is down */ | 6762 | } else { /* Device is down */ |
6591 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 6763 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
6592 | u64 val64 = new_mtu; | 6764 | u64 val64 = new_mtu; |
@@ -6694,7 +6866,7 @@ static void s2io_set_link(struct work_struct *work) | |||
6694 | } else { | 6866 | } else { |
6695 | DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); | 6867 | DBG_PRINT(ERR_DBG, "%s: Error: ", dev->name); |
6696 | DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); | 6868 | DBG_PRINT(ERR_DBG, "device is not Quiescent\n"); |
6697 | netif_stop_queue(dev); | 6869 | s2io_stop_all_tx_queue(nic); |
6698 | } | 6870 | } |
6699 | } | 6871 | } |
6700 | val64 = readq(&bar0->adapter_control); | 6872 | val64 = readq(&bar0->adapter_control); |
@@ -6921,11 +7093,11 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6921 | if(!(sp->msix_info[i].addr && | 7093 | if(!(sp->msix_info[i].addr && |
6922 | sp->msix_info[i].data)) { | 7094 | sp->msix_info[i].data)) { |
6923 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7095 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " |
6924 | "Data:0x%lx\n",sp->desc[i], | 7096 | "Data:0x%llx\n",sp->desc[i], |
6925 | (unsigned long long) | 7097 | (unsigned long long) |
6926 | sp->msix_info[i].addr, | 7098 | sp->msix_info[i].addr, |
6927 | (unsigned long) | 7099 | (unsigned long long) |
6928 | ntohl(sp->msix_info[i].data)); | 7100 | sp->msix_info[i].data); |
6929 | } else { | 7101 | } else { |
6930 | msix_tx_cnt++; | 7102 | msix_tx_cnt++; |
6931 | } | 7103 | } |
@@ -6939,11 +7111,11 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6939 | if(!(sp->msix_info[i].addr && | 7111 | if(!(sp->msix_info[i].addr && |
6940 | sp->msix_info[i].data)) { | 7112 | sp->msix_info[i].data)) { |
6941 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7113 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " |
6942 | "Data:0x%lx\n",sp->desc[i], | 7114 | "Data:0x%llx\n",sp->desc[i], |
6943 | (unsigned long long) | 7115 | (unsigned long long) |
6944 | sp->msix_info[i].addr, | 7116 | sp->msix_info[i].addr, |
6945 | (unsigned long) | 7117 | (unsigned long long) |
6946 | ntohl(sp->msix_info[i].data)); | 7118 | sp->msix_info[i].data); |
6947 | } else { | 7119 | } else { |
6948 | msix_rx_cnt++; | 7120 | msix_rx_cnt++; |
6949 | } | 7121 | } |
@@ -7184,7 +7356,7 @@ static void s2io_restart_nic(struct work_struct *work) | |||
7184 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 7356 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
7185 | dev->name); | 7357 | dev->name); |
7186 | } | 7358 | } |
7187 | netif_wake_queue(dev); | 7359 | s2io_wake_all_tx_queue(sp); |
7188 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", | 7360 | DBG_PRINT(ERR_DBG, "%s: was reset by Tx watchdog timer\n", |
7189 | dev->name); | 7361 | dev->name); |
7190 | out_unlock: | 7362 | out_unlock: |
@@ -7374,7 +7546,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) | |||
7374 | { | 7546 | { |
7375 | lro_append_pkt(sp, lro, | 7547 | lro_append_pkt(sp, lro, |
7376 | skb, tcp_len); | 7548 | skb, tcp_len); |
7377 | queue_rx_frame(lro->parent); | 7549 | queue_rx_frame(lro->parent, |
7550 | lro->vlan_tag); | ||
7378 | clear_lro_session(lro); | 7551 | clear_lro_session(lro); |
7379 | sp->mac_control.stats_info-> | 7552 | sp->mac_control.stats_info-> |
7380 | sw_stat.flush_max_pkts++; | 7553 | sw_stat.flush_max_pkts++; |
@@ -7385,7 +7558,8 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) | |||
7385 | lro->frags_len; | 7558 | lro->frags_len; |
7386 | sp->mac_control.stats_info-> | 7559 | sp->mac_control.stats_info-> |
7387 | sw_stat.sending_both++; | 7560 | sw_stat.sending_both++; |
7388 | queue_rx_frame(lro->parent); | 7561 | queue_rx_frame(lro->parent, |
7562 | lro->vlan_tag); | ||
7389 | clear_lro_session(lro); | 7563 | clear_lro_session(lro); |
7390 | goto send_up; | 7564 | goto send_up; |
7391 | case 0: /* sessions exceeded */ | 7565 | case 0: /* sessions exceeded */ |
@@ -7411,31 +7585,12 @@ static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp) | |||
7411 | */ | 7585 | */ |
7412 | skb->ip_summed = CHECKSUM_NONE; | 7586 | skb->ip_summed = CHECKSUM_NONE; |
7413 | } | 7587 | } |
7414 | } else { | 7588 | } else |
7415 | skb->ip_summed = CHECKSUM_NONE; | 7589 | skb->ip_summed = CHECKSUM_NONE; |
7416 | } | 7590 | |
7417 | sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; | 7591 | sp->mac_control.stats_info->sw_stat.mem_freed += skb->truesize; |
7418 | if (!sp->lro) { | ||
7419 | skb->protocol = eth_type_trans(skb, dev); | ||
7420 | if ((sp->vlgrp && RXD_GET_VLAN_TAG(rxdp->Control_2) && | ||
7421 | vlan_strip_flag)) { | ||
7422 | /* Queueing the vlan frame to the upper layer */ | ||
7423 | if (napi) | ||
7424 | vlan_hwaccel_receive_skb(skb, sp->vlgrp, | ||
7425 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
7426 | else | ||
7427 | vlan_hwaccel_rx(skb, sp->vlgrp, | ||
7428 | RXD_GET_VLAN_TAG(rxdp->Control_2)); | ||
7429 | } else { | ||
7430 | if (napi) | ||
7431 | netif_receive_skb(skb); | ||
7432 | else | ||
7433 | netif_rx(skb); | ||
7434 | } | ||
7435 | } else { | ||
7436 | send_up: | 7592 | send_up: |
7437 | queue_rx_frame(skb); | 7593 | queue_rx_frame(skb, RXD_GET_VLAN_TAG(rxdp->Control_2)); |
7438 | } | ||
7439 | dev->last_rx = jiffies; | 7594 | dev->last_rx = jiffies; |
7440 | aggregate: | 7595 | aggregate: |
7441 | atomic_dec(&sp->rx_bufs_left[ring_no]); | 7596 | atomic_dec(&sp->rx_bufs_left[ring_no]); |
@@ -7463,6 +7618,7 @@ static void s2io_link(struct s2io_nic * sp, int link) | |||
7463 | init_tti(sp, link); | 7618 | init_tti(sp, link); |
7464 | if (link == LINK_DOWN) { | 7619 | if (link == LINK_DOWN) { |
7465 | DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); | 7620 | DBG_PRINT(ERR_DBG, "%s: Link down\n", dev->name); |
7621 | s2io_stop_all_tx_queue(sp); | ||
7466 | netif_carrier_off(dev); | 7622 | netif_carrier_off(dev); |
7467 | if(sp->mac_control.stats_info->sw_stat.link_up_cnt) | 7623 | if(sp->mac_control.stats_info->sw_stat.link_up_cnt) |
7468 | sp->mac_control.stats_info->sw_stat.link_up_time = | 7624 | sp->mac_control.stats_info->sw_stat.link_up_time = |
@@ -7475,6 +7631,7 @@ static void s2io_link(struct s2io_nic * sp, int link) | |||
7475 | jiffies - sp->start_time; | 7631 | jiffies - sp->start_time; |
7476 | sp->mac_control.stats_info->sw_stat.link_up_cnt++; | 7632 | sp->mac_control.stats_info->sw_stat.link_up_cnt++; |
7477 | netif_carrier_on(dev); | 7633 | netif_carrier_on(dev); |
7634 | s2io_wake_all_tx_queue(sp); | ||
7478 | } | 7635 | } |
7479 | } | 7636 | } |
7480 | sp->last_link_state = link; | 7637 | sp->last_link_state = link; |
@@ -7511,20 +7668,48 @@ static void s2io_init_pci(struct s2io_nic * sp) | |||
7511 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 7668 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
7512 | } | 7669 | } |
7513 | 7670 | ||
7514 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | 7671 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, |
7672 | u8 *dev_multiq) | ||
7515 | { | 7673 | { |
7516 | if ((tx_fifo_num > MAX_TX_FIFOS) || | 7674 | if ((tx_fifo_num > MAX_TX_FIFOS) || |
7517 | (tx_fifo_num < FIFO_DEFAULT_NUM)) { | 7675 | (tx_fifo_num < 1)) { |
7518 | DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos " | 7676 | DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos " |
7519 | "(%d) not supported\n", tx_fifo_num); | 7677 | "(%d) not supported\n", tx_fifo_num); |
7520 | tx_fifo_num = | 7678 | |
7521 | ((tx_fifo_num > MAX_TX_FIFOS)? MAX_TX_FIFOS : | 7679 | if (tx_fifo_num < 1) |
7522 | ((tx_fifo_num < FIFO_DEFAULT_NUM) ? FIFO_DEFAULT_NUM : | 7680 | tx_fifo_num = 1; |
7523 | tx_fifo_num)); | 7681 | else |
7682 | tx_fifo_num = MAX_TX_FIFOS; | ||
7683 | |||
7524 | DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num); | 7684 | DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num); |
7525 | DBG_PRINT(ERR_DBG, "tx fifos\n"); | 7685 | DBG_PRINT(ERR_DBG, "tx fifos\n"); |
7526 | } | 7686 | } |
7527 | 7687 | ||
7688 | #ifndef CONFIG_NETDEVICES_MULTIQUEUE | ||
7689 | if (multiq) { | ||
7690 | DBG_PRINT(ERR_DBG, "s2io: Multiqueue support not enabled\n"); | ||
7691 | multiq = 0; | ||
7692 | } | ||
7693 | #endif | ||
7694 | if (multiq) | ||
7695 | *dev_multiq = multiq; | ||
7696 | |||
7697 | if (tx_steering_type && (1 == tx_fifo_num)) { | ||
7698 | if (tx_steering_type != TX_DEFAULT_STEERING) | ||
7699 | DBG_PRINT(ERR_DBG, | ||
7700 | "s2io: Tx steering is not supported with " | ||
7701 | "one fifo. Disabling Tx steering.\n"); | ||
7702 | tx_steering_type = NO_STEERING; | ||
7703 | } | ||
7704 | |||
7705 | if ((tx_steering_type < NO_STEERING) || | ||
7706 | (tx_steering_type > TX_DEFAULT_STEERING)) { | ||
7707 | DBG_PRINT(ERR_DBG, "s2io: Requested transmit steering not " | ||
7708 | "supported\n"); | ||
7709 | DBG_PRINT(ERR_DBG, "s2io: Disabling transmit steering\n"); | ||
7710 | tx_steering_type = NO_STEERING; | ||
7711 | } | ||
7712 | |||
7528 | if ( rx_ring_num > 8) { | 7713 | if ( rx_ring_num > 8) { |
7529 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " | 7714 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " |
7530 | "supported\n"); | 7715 | "supported\n"); |
@@ -7616,9 +7801,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7616 | struct config_param *config; | 7801 | struct config_param *config; |
7617 | int mode; | 7802 | int mode; |
7618 | u8 dev_intr_type = intr_type; | 7803 | u8 dev_intr_type = intr_type; |
7804 | u8 dev_multiq = 0; | ||
7619 | DECLARE_MAC_BUF(mac); | 7805 | DECLARE_MAC_BUF(mac); |
7620 | 7806 | ||
7621 | if ((ret = s2io_verify_parm(pdev, &dev_intr_type))) | 7807 | ret = s2io_verify_parm(pdev, &dev_intr_type, &dev_multiq); |
7808 | if (ret) | ||
7622 | return ret; | 7809 | return ret; |
7623 | 7810 | ||
7624 | if ((ret = pci_enable_device(pdev))) { | 7811 | if ((ret = pci_enable_device(pdev))) { |
@@ -7649,7 +7836,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7649 | pci_disable_device(pdev); | 7836 | pci_disable_device(pdev); |
7650 | return -ENODEV; | 7837 | return -ENODEV; |
7651 | } | 7838 | } |
7652 | 7839 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | |
7840 | if (dev_multiq) | ||
7841 | dev = alloc_etherdev_mq(sizeof(struct s2io_nic), tx_fifo_num); | ||
7842 | else | ||
7843 | #endif | ||
7653 | dev = alloc_etherdev(sizeof(struct s2io_nic)); | 7844 | dev = alloc_etherdev(sizeof(struct s2io_nic)); |
7654 | if (dev == NULL) { | 7845 | if (dev == NULL) { |
7655 | DBG_PRINT(ERR_DBG, "Device allocation failed\n"); | 7846 | DBG_PRINT(ERR_DBG, "Device allocation failed\n"); |
@@ -7698,17 +7889,45 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7698 | config = &sp->config; | 7889 | config = &sp->config; |
7699 | 7890 | ||
7700 | config->napi = napi; | 7891 | config->napi = napi; |
7892 | config->tx_steering_type = tx_steering_type; | ||
7701 | 7893 | ||
7702 | /* Tx side parameters. */ | 7894 | /* Tx side parameters. */ |
7703 | config->tx_fifo_num = tx_fifo_num; | 7895 | if (config->tx_steering_type == TX_PRIORITY_STEERING) |
7704 | for (i = 0; i < MAX_TX_FIFOS; i++) { | 7896 | config->tx_fifo_num = MAX_TX_FIFOS; |
7897 | else | ||
7898 | config->tx_fifo_num = tx_fifo_num; | ||
7899 | |||
7900 | /* Initialize the fifos used for tx steering */ | ||
7901 | if (config->tx_fifo_num < 5) { | ||
7902 | if (config->tx_fifo_num == 1) | ||
7903 | sp->total_tcp_fifos = 1; | ||
7904 | else | ||
7905 | sp->total_tcp_fifos = config->tx_fifo_num - 1; | ||
7906 | sp->udp_fifo_idx = config->tx_fifo_num - 1; | ||
7907 | sp->total_udp_fifos = 1; | ||
7908 | sp->other_fifo_idx = sp->total_tcp_fifos - 1; | ||
7909 | } else { | ||
7910 | sp->total_tcp_fifos = (tx_fifo_num - FIFO_UDP_MAX_NUM - | ||
7911 | FIFO_OTHER_MAX_NUM); | ||
7912 | sp->udp_fifo_idx = sp->total_tcp_fifos; | ||
7913 | sp->total_udp_fifos = FIFO_UDP_MAX_NUM; | ||
7914 | sp->other_fifo_idx = sp->udp_fifo_idx + FIFO_UDP_MAX_NUM; | ||
7915 | } | ||
7916 | |||
7917 | config->multiq = dev_multiq; | ||
7918 | for (i = 0; i < config->tx_fifo_num; i++) { | ||
7705 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; | 7919 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; |
7706 | config->tx_cfg[i].fifo_priority = i; | 7920 | config->tx_cfg[i].fifo_priority = i; |
7707 | } | 7921 | } |
7708 | 7922 | ||
7709 | /* mapping the QoS priority to the configured fifos */ | 7923 | /* mapping the QoS priority to the configured fifos */ |
7710 | for (i = 0; i < MAX_TX_FIFOS; i++) | 7924 | for (i = 0; i < MAX_TX_FIFOS; i++) |
7711 | config->fifo_mapping[i] = fifo_map[config->tx_fifo_num][i]; | 7925 | config->fifo_mapping[i] = fifo_map[config->tx_fifo_num - 1][i]; |
7926 | |||
7927 | /* map the hashing selector table to the configured fifos */ | ||
7928 | for (i = 0; i < config->tx_fifo_num; i++) | ||
7929 | sp->fifo_selector[i] = fifo_selector[i]; | ||
7930 | |||
7712 | 7931 | ||
7713 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; | 7932 | config->tx_intr_type = TXD_INT_TYPE_UTILZ; |
7714 | for (i = 0; i < config->tx_fifo_num; i++) { | 7933 | for (i = 0; i < config->tx_fifo_num; i++) { |
@@ -7793,6 +8012,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7793 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 8012 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
7794 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; | 8013 | dev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX; |
7795 | dev->vlan_rx_register = s2io_vlan_rx_register; | 8014 | dev->vlan_rx_register = s2io_vlan_rx_register; |
8015 | dev->vlan_rx_kill_vid = (void *)s2io_vlan_rx_kill_vid; | ||
7796 | 8016 | ||
7797 | /* | 8017 | /* |
7798 | * will use eth_mac_addr() for dev->set_mac_address | 8018 | * will use eth_mac_addr() for dev->set_mac_address |
@@ -7813,7 +8033,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7813 | dev->features |= NETIF_F_UFO; | 8033 | dev->features |= NETIF_F_UFO; |
7814 | dev->features |= NETIF_F_HW_CSUM; | 8034 | dev->features |= NETIF_F_HW_CSUM; |
7815 | } | 8035 | } |
7816 | 8036 | #ifdef CONFIG_NETDEVICES_MULTIQUEUE | |
8037 | if (config->multiq) | ||
8038 | dev->features |= NETIF_F_MULTI_QUEUE; | ||
8039 | #endif | ||
7817 | dev->tx_timeout = &s2io_tx_watchdog; | 8040 | dev->tx_timeout = &s2io_tx_watchdog; |
7818 | dev->watchdog_timeo = WATCH_DOG_TIMEOUT; | 8041 | dev->watchdog_timeo = WATCH_DOG_TIMEOUT; |
7819 | INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); | 8042 | INIT_WORK(&sp->rst_timer_task, s2io_restart_nic); |
@@ -7962,6 +8185,10 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7962 | 8185 | ||
7963 | if (napi) | 8186 | if (napi) |
7964 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | 8187 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); |
8188 | |||
8189 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, | ||
8190 | sp->config.tx_fifo_num); | ||
8191 | |||
7965 | switch(sp->config.intr_type) { | 8192 | switch(sp->config.intr_type) { |
7966 | case INTA: | 8193 | case INTA: |
7967 | DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); | 8194 | DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); |
@@ -7970,6 +8197,29 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7970 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); | 8197 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); |
7971 | break; | 8198 | break; |
7972 | } | 8199 | } |
8200 | if (sp->config.multiq) { | ||
8201 | for (i = 0; i < sp->config.tx_fifo_num; i++) | ||
8202 | mac_control->fifos[i].multiq = config->multiq; | ||
8203 | DBG_PRINT(ERR_DBG, "%s: Multiqueue support enabled\n", | ||
8204 | dev->name); | ||
8205 | } else | ||
8206 | DBG_PRINT(ERR_DBG, "%s: Multiqueue support disabled\n", | ||
8207 | dev->name); | ||
8208 | |||
8209 | switch (sp->config.tx_steering_type) { | ||
8210 | case NO_STEERING: | ||
8211 | DBG_PRINT(ERR_DBG, "%s: No steering enabled for" | ||
8212 | " transmit\n", dev->name); | ||
8213 | break; | ||
8214 | case TX_PRIORITY_STEERING: | ||
8215 | DBG_PRINT(ERR_DBG, "%s: Priority steering enabled for" | ||
8216 | " transmit\n", dev->name); | ||
8217 | break; | ||
8218 | case TX_DEFAULT_STEERING: | ||
8219 | DBG_PRINT(ERR_DBG, "%s: Default steering enabled for" | ||
8220 | " transmit\n", dev->name); | ||
8221 | } | ||
8222 | |||
7973 | if (sp->lro) | 8223 | if (sp->lro) |
7974 | DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", | 8224 | DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", |
7975 | dev->name); | 8225 | dev->name); |
@@ -8064,7 +8314,8 @@ module_init(s2io_starter); | |||
8064 | module_exit(s2io_closer); | 8314 | module_exit(s2io_closer); |
8065 | 8315 | ||
8066 | static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, | 8316 | static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, |
8067 | struct tcphdr **tcp, struct RxD_t *rxdp) | 8317 | struct tcphdr **tcp, struct RxD_t *rxdp, |
8318 | struct s2io_nic *sp) | ||
8068 | { | 8319 | { |
8069 | int ip_off; | 8320 | int ip_off; |
8070 | u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; | 8321 | u8 l2_type = (u8)((rxdp->Control_1 >> 37) & 0x7), ip_len; |
@@ -8075,19 +8326,20 @@ static int check_L2_lro_capable(u8 *buffer, struct iphdr **ip, | |||
8075 | return -1; | 8326 | return -1; |
8076 | } | 8327 | } |
8077 | 8328 | ||
8078 | /* TODO: | 8329 | /* Checking for DIX type or DIX type with VLAN */ |
8079 | * By default the VLAN field in the MAC is stripped by the card, if this | 8330 | if ((l2_type == 0) |
8080 | * feature is turned off in rx_pa_cfg register, then the ip_off field | 8331 | || (l2_type == 4)) { |
8081 | * has to be shifted by a further 2 bytes | 8332 | ip_off = HEADER_ETHERNET_II_802_3_SIZE; |
8082 | */ | 8333 | /* |
8083 | switch (l2_type) { | 8334 | * If vlan stripping is disabled and the frame is VLAN tagged, |
8084 | case 0: /* DIX type */ | 8335 | * shift the offset by the VLAN header size bytes. |
8085 | case 4: /* DIX type with VLAN */ | 8336 | */ |
8086 | ip_off = HEADER_ETHERNET_II_802_3_SIZE; | 8337 | if ((!vlan_strip_flag) && |
8087 | break; | 8338 | (rxdp->Control_1 & RXD_FRAME_VLAN_TAG)) |
8339 | ip_off += HEADER_VLAN_SIZE; | ||
8340 | } else { | ||
8088 | /* LLC, SNAP etc are considered non-mergeable */ | 8341 | /* LLC, SNAP etc are considered non-mergeable */ |
8089 | default: | 8342 | return -1; |
8090 | return -1; | ||
8091 | } | 8343 | } |
8092 | 8344 | ||
8093 | *ip = (struct iphdr *)((u8 *)buffer + ip_off); | 8345 | *ip = (struct iphdr *)((u8 *)buffer + ip_off); |
@@ -8114,7 +8366,7 @@ static inline int get_l4_pyld_length(struct iphdr *ip, struct tcphdr *tcp) | |||
8114 | } | 8366 | } |
8115 | 8367 | ||
8116 | static void initiate_new_session(struct lro *lro, u8 *l2h, | 8368 | static void initiate_new_session(struct lro *lro, u8 *l2h, |
8117 | struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len) | 8369 | struct iphdr *ip, struct tcphdr *tcp, u32 tcp_pyld_len, u16 vlan_tag) |
8118 | { | 8370 | { |
8119 | DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); | 8371 | DBG_PRINT(INFO_DBG,"%s: Been here...\n", __FUNCTION__); |
8120 | lro->l2h = l2h; | 8372 | lro->l2h = l2h; |
@@ -8125,6 +8377,7 @@ static void initiate_new_session(struct lro *lro, u8 *l2h, | |||
8125 | lro->sg_num = 1; | 8377 | lro->sg_num = 1; |
8126 | lro->total_len = ntohs(ip->tot_len); | 8378 | lro->total_len = ntohs(ip->tot_len); |
8127 | lro->frags_len = 0; | 8379 | lro->frags_len = 0; |
8380 | lro->vlan_tag = vlan_tag; | ||
8128 | /* | 8381 | /* |
8129 | * check if we saw TCP timestamp. Other consistency checks have | 8382 | * check if we saw TCP timestamp. Other consistency checks have |
8130 | * already been done. | 8383 | * already been done. |
@@ -8256,15 +8509,16 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, | |||
8256 | struct iphdr *ip; | 8509 | struct iphdr *ip; |
8257 | struct tcphdr *tcph; | 8510 | struct tcphdr *tcph; |
8258 | int ret = 0, i; | 8511 | int ret = 0, i; |
8512 | u16 vlan_tag = 0; | ||
8259 | 8513 | ||
8260 | if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp, | 8514 | if (!(ret = check_L2_lro_capable(buffer, &ip, (struct tcphdr **)tcp, |
8261 | rxdp))) { | 8515 | rxdp, sp))) { |
8262 | DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n", | 8516 | DBG_PRINT(INFO_DBG,"IP Saddr: %x Daddr: %x\n", |
8263 | ip->saddr, ip->daddr); | 8517 | ip->saddr, ip->daddr); |
8264 | } else { | 8518 | } else |
8265 | return ret; | 8519 | return ret; |
8266 | } | ||
8267 | 8520 | ||
8521 | vlan_tag = RXD_GET_VLAN_TAG(rxdp->Control_2); | ||
8268 | tcph = (struct tcphdr *)*tcp; | 8522 | tcph = (struct tcphdr *)*tcp; |
8269 | *tcp_len = get_l4_pyld_length(ip, tcph); | 8523 | *tcp_len = get_l4_pyld_length(ip, tcph); |
8270 | for (i=0; i<MAX_LRO_SESSIONS; i++) { | 8524 | for (i=0; i<MAX_LRO_SESSIONS; i++) { |
@@ -8324,7 +8578,8 @@ s2io_club_tcp_session(u8 *buffer, u8 **tcp, u32 *tcp_len, struct lro **lro, | |||
8324 | 8578 | ||
8325 | switch (ret) { | 8579 | switch (ret) { |
8326 | case 3: | 8580 | case 3: |
8327 | initiate_new_session(*lro, buffer, ip, tcph, *tcp_len); | 8581 | initiate_new_session(*lro, buffer, ip, tcph, *tcp_len, |
8582 | vlan_tag); | ||
8328 | break; | 8583 | break; |
8329 | case 2: | 8584 | case 2: |
8330 | update_L3L4_header(sp, *lro); | 8585 | update_L3L4_header(sp, *lro); |
@@ -8352,15 +8607,25 @@ static void clear_lro_session(struct lro *lro) | |||
8352 | memset(lro, 0, lro_struct_size); | 8607 | memset(lro, 0, lro_struct_size); |
8353 | } | 8608 | } |
8354 | 8609 | ||
8355 | static void queue_rx_frame(struct sk_buff *skb) | 8610 | static void queue_rx_frame(struct sk_buff *skb, u16 vlan_tag) |
8356 | { | 8611 | { |
8357 | struct net_device *dev = skb->dev; | 8612 | struct net_device *dev = skb->dev; |
8613 | struct s2io_nic *sp = dev->priv; | ||
8358 | 8614 | ||
8359 | skb->protocol = eth_type_trans(skb, dev); | 8615 | skb->protocol = eth_type_trans(skb, dev); |
8360 | if (napi) | 8616 | if (sp->vlgrp && vlan_tag |
8361 | netif_receive_skb(skb); | 8617 | && (vlan_strip_flag)) { |
8362 | else | 8618 | /* Queueing the vlan frame to the upper layer */ |
8363 | netif_rx(skb); | 8619 | if (sp->config.napi) |
8620 | vlan_hwaccel_receive_skb(skb, sp->vlgrp, vlan_tag); | ||
8621 | else | ||
8622 | vlan_hwaccel_rx(skb, sp->vlgrp, vlan_tag); | ||
8623 | } else { | ||
8624 | if (sp->config.napi) | ||
8625 | netif_receive_skb(skb); | ||
8626 | else | ||
8627 | netif_rx(skb); | ||
8628 | } | ||
8364 | } | 8629 | } |
8365 | 8630 | ||
8366 | static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, | 8631 | static void lro_append_pkt(struct s2io_nic *sp, struct lro *lro, |