diff options
author | Surjit Reang <surjit.reang@neterion.com> | 2008-01-24 05:08:59 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 18:07:23 -0500 |
commit | 2fda096d188ddae51a0fe8cd5b13cf9c84b03c1e (patch) | |
tree | 6655b7f5292345109156930d54489e0d94b2f168 /drivers | |
parent | bc4b6b52691bae42b1eec3eb86ab4c718387d9f0 (diff) |
S2io: Fixes to enable multiple transmit fifo support
Fixes to enable multiple transmit fifos (upto a maximum of eight).
- Moved single tx_lock from struct s2io_nic to struct fifo_info.
- Moved single ufo_in_band_v structure from struct s2io_nic to struct
fifo_info.
- Assign the respective interrupt number for the transmitting fifo in the
transmit descriptor (TXD).
- Added boundary checks for number of FIFOs enabled and FIFO length.
Signed-off-by: Surjit Reang <surjit.reang@neterion.com>
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/s2io.c | 136 | ||||
-rw-r--r-- | drivers/net/s2io.h | 12 |
2 files changed, 97 insertions, 51 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 5defb0b17258..e2c206c7391b 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -84,7 +84,7 @@ | |||
84 | #include "s2io.h" | 84 | #include "s2io.h" |
85 | #include "s2io-regs.h" | 85 | #include "s2io-regs.h" |
86 | 86 | ||
87 | #define DRV_VERSION "2.0.26.17" | 87 | #define DRV_VERSION "2.0.26.15-1" |
88 | 88 | ||
89 | /* S2io Driver name & version. */ | 89 | /* S2io Driver name & version. */ |
90 | static char s2io_driver_name[] = "Neterion"; | 90 | static char s2io_driver_name[] = "Neterion"; |
@@ -368,12 +368,19 @@ static void do_s2io_copy_mac_addr(struct s2io_nic *sp, int offset, u64 mac_addr) | |||
368 | static void s2io_vlan_rx_register(struct net_device *dev, | 368 | static void s2io_vlan_rx_register(struct net_device *dev, |
369 | struct vlan_group *grp) | 369 | struct vlan_group *grp) |
370 | { | 370 | { |
371 | int i; | ||
371 | struct s2io_nic *nic = dev->priv; | 372 | struct s2io_nic *nic = dev->priv; |
372 | unsigned long flags; | 373 | unsigned long flags[MAX_TX_FIFOS]; |
374 | struct mac_info *mac_control = &nic->mac_control; | ||
375 | struct config_param *config = &nic->config; | ||
376 | |||
377 | for (i = 0; i < config->tx_fifo_num; i++) | ||
378 | spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags[i]); | ||
373 | 379 | ||
374 | spin_lock_irqsave(&nic->tx_lock, flags); | ||
375 | nic->vlgrp = grp; | 380 | nic->vlgrp = grp; |
376 | spin_unlock_irqrestore(&nic->tx_lock, flags); | 381 | for (i = config->tx_fifo_num - 1; i >= 0; i--) |
382 | spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock, | ||
383 | flags[i]); | ||
377 | } | 384 | } |
378 | 385 | ||
379 | /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ | 386 | /* A flag indicating whether 'RX_PA_CFG_STRIP_VLAN_TAG' bit is set or not */ |
@@ -565,6 +572,21 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
565 | return -EINVAL; | 572 | return -EINVAL; |
566 | } | 573 | } |
567 | 574 | ||
575 | size = 0; | ||
576 | for (i = 0; i < config->tx_fifo_num; i++) { | ||
577 | size = config->tx_cfg[i].fifo_len; | ||
578 | /* | ||
579 | * Legal values are from 2 to 8192 | ||
580 | */ | ||
581 | if (size < 2) { | ||
582 | DBG_PRINT(ERR_DBG, "s2io: Invalid fifo len (%d)", size); | ||
583 | DBG_PRINT(ERR_DBG, "for fifo %d\n", i); | ||
584 | DBG_PRINT(ERR_DBG, "s2io: Legal values for fifo len" | ||
585 | "are 2 to 8192\n"); | ||
586 | return -EINVAL; | ||
587 | } | ||
588 | } | ||
589 | |||
568 | lst_size = (sizeof(struct TxD) * config->max_txds); | 590 | lst_size = (sizeof(struct TxD) * config->max_txds); |
569 | lst_per_page = PAGE_SIZE / lst_size; | 591 | lst_per_page = PAGE_SIZE / lst_size; |
570 | 592 | ||
@@ -639,10 +661,14 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
639 | } | 661 | } |
640 | } | 662 | } |
641 | 663 | ||
642 | nic->ufo_in_band_v = kcalloc(size, sizeof(u64), GFP_KERNEL); | 664 | for (i = 0; i < config->tx_fifo_num; i++) { |
643 | if (!nic->ufo_in_band_v) | 665 | size = config->tx_cfg[i].fifo_len; |
644 | return -ENOMEM; | 666 | mac_control->fifos[i].ufo_in_band_v |
645 | mem_allocated += (size * sizeof(u64)); | 667 | = kcalloc(size, sizeof(u64), GFP_KERNEL); |
668 | if (!mac_control->fifos[i].ufo_in_band_v) | ||
669 | return -ENOMEM; | ||
670 | mem_allocated += (size * sizeof(u64)); | ||
671 | } | ||
646 | 672 | ||
647 | /* Allocation and initialization of RXDs in Rings */ | 673 | /* Allocation and initialization of RXDs in Rings */ |
648 | size = 0; | 674 | size = 0; |
@@ -829,7 +855,6 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
829 | static void free_shared_mem(struct s2io_nic *nic) | 855 | static void free_shared_mem(struct s2io_nic *nic) |
830 | { | 856 | { |
831 | int i, j, blk_cnt, size; | 857 | int i, j, blk_cnt, size; |
832 | u32 ufo_size = 0; | ||
833 | void *tmp_v_addr; | 858 | void *tmp_v_addr; |
834 | dma_addr_t tmp_p_addr; | 859 | dma_addr_t tmp_p_addr; |
835 | struct mac_info *mac_control; | 860 | struct mac_info *mac_control; |
@@ -850,7 +875,6 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
850 | lst_per_page = PAGE_SIZE / lst_size; | 875 | lst_per_page = PAGE_SIZE / lst_size; |
851 | 876 | ||
852 | for (i = 0; i < config->tx_fifo_num; i++) { | 877 | for (i = 0; i < config->tx_fifo_num; i++) { |
853 | ufo_size += config->tx_cfg[i].fifo_len; | ||
854 | page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, | 878 | page_num = TXD_MEM_PAGE_CNT(config->tx_cfg[i].fifo_len, |
855 | lst_per_page); | 879 | lst_per_page); |
856 | for (j = 0; j < page_num; j++) { | 880 | for (j = 0; j < page_num; j++) { |
@@ -940,18 +964,21 @@ static void free_shared_mem(struct s2io_nic *nic) | |||
940 | } | 964 | } |
941 | } | 965 | } |
942 | 966 | ||
967 | for (i = 0; i < nic->config.tx_fifo_num; i++) { | ||
968 | if (mac_control->fifos[i].ufo_in_band_v) { | ||
969 | nic->mac_control.stats_info->sw_stat.mem_freed | ||
970 | += (config->tx_cfg[i].fifo_len * sizeof(u64)); | ||
971 | kfree(mac_control->fifos[i].ufo_in_band_v); | ||
972 | } | ||
973 | } | ||
974 | |||
943 | if (mac_control->stats_mem) { | 975 | if (mac_control->stats_mem) { |
976 | nic->mac_control.stats_info->sw_stat.mem_freed += | ||
977 | mac_control->stats_mem_sz; | ||
944 | pci_free_consistent(nic->pdev, | 978 | pci_free_consistent(nic->pdev, |
945 | mac_control->stats_mem_sz, | 979 | mac_control->stats_mem_sz, |
946 | mac_control->stats_mem, | 980 | mac_control->stats_mem, |
947 | mac_control->stats_mem_phy); | 981 | mac_control->stats_mem_phy); |
948 | nic->mac_control.stats_info->sw_stat.mem_freed += | ||
949 | mac_control->stats_mem_sz; | ||
950 | } | ||
951 | if (nic->ufo_in_band_v) { | ||
952 | kfree(nic->ufo_in_band_v); | ||
953 | nic->mac_control.stats_info->sw_stat.mem_freed | ||
954 | += (ufo_size * sizeof(u64)); | ||
955 | } | 982 | } |
956 | } | 983 | } |
957 | 984 | ||
@@ -2241,7 +2268,7 @@ static struct sk_buff *s2io_txdl_getskb(struct fifo_info *fifo_data, struct \ | |||
2241 | u16 j, frg_cnt; | 2268 | u16 j, frg_cnt; |
2242 | 2269 | ||
2243 | txds = txdlp; | 2270 | txds = txdlp; |
2244 | if (txds->Host_Control == (u64)(long)nic->ufo_in_band_v) { | 2271 | if (txds->Host_Control == (u64)(long)fifo_data->ufo_in_band_v) { |
2245 | pci_unmap_single(nic->pdev, (dma_addr_t) | 2272 | pci_unmap_single(nic->pdev, (dma_addr_t) |
2246 | txds->Buffer_Pointer, sizeof(u64), | 2273 | txds->Buffer_Pointer, sizeof(u64), |
2247 | PCI_DMA_TODEVICE); | 2274 | PCI_DMA_TODEVICE); |
@@ -2296,6 +2323,8 @@ static void free_tx_buffers(struct s2io_nic *nic) | |||
2296 | config = &nic->config; | 2323 | config = &nic->config; |
2297 | 2324 | ||
2298 | for (i = 0; i < config->tx_fifo_num; i++) { | 2325 | for (i = 0; i < config->tx_fifo_num; i++) { |
2326 | unsigned long flags; | ||
2327 | spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags); | ||
2299 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { | 2328 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { |
2300 | txdp = (struct TxD *) \ | 2329 | txdp = (struct TxD *) \ |
2301 | mac_control->fifos[i].list_info[j].list_virt_addr; | 2330 | mac_control->fifos[i].list_info[j].list_virt_addr; |
@@ -2312,6 +2341,7 @@ static void free_tx_buffers(struct s2io_nic *nic) | |||
2312 | dev->name, cnt, i); | 2341 | dev->name, cnt, i); |
2313 | mac_control->fifos[i].tx_curr_get_info.offset = 0; | 2342 | mac_control->fifos[i].tx_curr_get_info.offset = 0; |
2314 | mac_control->fifos[i].tx_curr_put_info.offset = 0; | 2343 | mac_control->fifos[i].tx_curr_put_info.offset = 0; |
2344 | spin_unlock_irqrestore(&mac_control->fifos[i].tx_lock, flags); | ||
2315 | } | 2345 | } |
2316 | } | 2346 | } |
2317 | 2347 | ||
@@ -2932,8 +2962,12 @@ static void tx_intr_handler(struct fifo_info *fifo_data) | |||
2932 | struct tx_curr_get_info get_info, put_info; | 2962 | struct tx_curr_get_info get_info, put_info; |
2933 | struct sk_buff *skb; | 2963 | struct sk_buff *skb; |
2934 | struct TxD *txdlp; | 2964 | struct TxD *txdlp; |
2965 | unsigned long flags = 0; | ||
2935 | u8 err_mask; | 2966 | u8 err_mask; |
2936 | 2967 | ||
2968 | if (!spin_trylock_irqsave(&fifo_data->tx_lock, flags)) | ||
2969 | return; | ||
2970 | |||
2937 | get_info = fifo_data->tx_curr_get_info; | 2971 | get_info = fifo_data->tx_curr_get_info; |
2938 | memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info)); | 2972 | memcpy(&put_info, &fifo_data->tx_curr_put_info, sizeof(put_info)); |
2939 | txdlp = (struct TxD *) fifo_data->list_info[get_info.offset]. | 2973 | txdlp = (struct TxD *) fifo_data->list_info[get_info.offset]. |
@@ -2982,6 +3016,7 @@ static void tx_intr_handler(struct fifo_info *fifo_data) | |||
2982 | 3016 | ||
2983 | skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset); | 3017 | skb = s2io_txdl_getskb(fifo_data, txdlp, get_info.offset); |
2984 | if (skb == NULL) { | 3018 | if (skb == NULL) { |
3019 | spin_unlock_irqrestore(&fifo_data->tx_lock, flags); | ||
2985 | DBG_PRINT(ERR_DBG, "%s: Null skb ", | 3020 | DBG_PRINT(ERR_DBG, "%s: Null skb ", |
2986 | __FUNCTION__); | 3021 | __FUNCTION__); |
2987 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); | 3022 | DBG_PRINT(ERR_DBG, "in Tx Free Intr\n"); |
@@ -3002,10 +3037,10 @@ static void tx_intr_handler(struct fifo_info *fifo_data) | |||
3002 | get_info.offset; | 3037 | get_info.offset; |
3003 | } | 3038 | } |
3004 | 3039 | ||
3005 | spin_lock(&nic->tx_lock); | ||
3006 | if (netif_queue_stopped(dev)) | 3040 | if (netif_queue_stopped(dev)) |
3007 | netif_wake_queue(dev); | 3041 | netif_wake_queue(dev); |
3008 | spin_unlock(&nic->tx_lock); | 3042 | |
3043 | spin_unlock_irqrestore(&fifo_data->tx_lock, flags); | ||
3009 | } | 3044 | } |
3010 | 3045 | ||
3011 | /** | 3046 | /** |
@@ -3965,9 +4000,10 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3965 | register u64 val64; | 4000 | register u64 val64; |
3966 | struct TxD *txdp; | 4001 | struct TxD *txdp; |
3967 | struct TxFIFO_element __iomem *tx_fifo; | 4002 | struct TxFIFO_element __iomem *tx_fifo; |
3968 | unsigned long flags; | 4003 | unsigned long flags = 0; |
3969 | u16 vlan_tag = 0; | 4004 | u16 vlan_tag = 0; |
3970 | int vlan_priority = 0; | 4005 | int vlan_priority = 0; |
4006 | struct fifo_info *fifo = NULL; | ||
3971 | struct mac_info *mac_control; | 4007 | struct mac_info *mac_control; |
3972 | struct config_param *config; | 4008 | struct config_param *config; |
3973 | int offload_type; | 4009 | int offload_type; |
@@ -3982,13 +4018,11 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3982 | DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); | 4018 | DBG_PRINT(TX_DBG, "%s:Buffer has no data..\n", dev->name); |
3983 | dev_kfree_skb_any(skb); | 4019 | dev_kfree_skb_any(skb); |
3984 | return 0; | 4020 | return 0; |
3985 | } | 4021 | } |
3986 | 4022 | ||
3987 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
3988 | if (!is_s2io_card_up(sp)) { | 4023 | if (!is_s2io_card_up(sp)) { |
3989 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", | 4024 | DBG_PRINT(TX_DBG, "%s: Card going down for reset\n", |
3990 | dev->name); | 4025 | dev->name); |
3991 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
3992 | dev_kfree_skb(skb); | 4026 | dev_kfree_skb(skb); |
3993 | return 0; | 4027 | return 0; |
3994 | } | 4028 | } |
@@ -4001,19 +4035,20 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4001 | queue = config->fifo_mapping[vlan_priority]; | 4035 | queue = config->fifo_mapping[vlan_priority]; |
4002 | } | 4036 | } |
4003 | 4037 | ||
4004 | put_off = (u16) mac_control->fifos[queue].tx_curr_put_info.offset; | 4038 | fifo = &mac_control->fifos[queue]; |
4005 | get_off = (u16) mac_control->fifos[queue].tx_curr_get_info.offset; | 4039 | spin_lock_irqsave(&fifo->tx_lock, flags); |
4006 | txdp = (struct TxD *) mac_control->fifos[queue].list_info[put_off]. | 4040 | put_off = (u16) fifo->tx_curr_put_info.offset; |
4007 | list_virt_addr; | 4041 | get_off = (u16) fifo->tx_curr_get_info.offset; |
4042 | txdp = (struct TxD *) fifo->list_info[put_off].list_virt_addr; | ||
4008 | 4043 | ||
4009 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | 4044 | queue_len = fifo->tx_curr_put_info.fifo_len + 1; |
4010 | /* Avoid "put" pointer going beyond "get" pointer */ | 4045 | /* Avoid "put" pointer going beyond "get" pointer */ |
4011 | if (txdp->Host_Control || | 4046 | if (txdp->Host_Control || |
4012 | ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { | 4047 | ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { |
4013 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); | 4048 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); |
4014 | netif_stop_queue(dev); | 4049 | netif_stop_queue(dev); |
4015 | dev_kfree_skb(skb); | 4050 | dev_kfree_skb(skb); |
4016 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 4051 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
4017 | return 0; | 4052 | return 0; |
4018 | } | 4053 | } |
4019 | 4054 | ||
@@ -4029,7 +4064,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4029 | } | 4064 | } |
4030 | txdp->Control_1 |= TXD_GATHER_CODE_FIRST; | 4065 | txdp->Control_1 |= TXD_GATHER_CODE_FIRST; |
4031 | txdp->Control_1 |= TXD_LIST_OWN_XENA; | 4066 | txdp->Control_1 |= TXD_LIST_OWN_XENA; |
4032 | txdp->Control_2 |= config->tx_intr_type; | 4067 | txdp->Control_2 |= TXD_INT_NUMBER(fifo->fifo_no); |
4033 | 4068 | ||
4034 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { | 4069 | if (sp->vlgrp && vlan_tx_tag_present(skb)) { |
4035 | txdp->Control_2 |= TXD_VLAN_ENABLE; | 4070 | txdp->Control_2 |= TXD_VLAN_ENABLE; |
@@ -4046,15 +4081,15 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4046 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); | 4081 | txdp->Control_1 |= TXD_UFO_MSS(ufo_size); |
4047 | txdp->Control_1 |= TXD_BUFFER0_SIZE(8); | 4082 | txdp->Control_1 |= TXD_BUFFER0_SIZE(8); |
4048 | #ifdef __BIG_ENDIAN | 4083 | #ifdef __BIG_ENDIAN |
4049 | sp->ufo_in_band_v[put_off] = | 4084 | fifo->ufo_in_band_v[put_off] = |
4050 | (u64)skb_shinfo(skb)->ip6_frag_id; | 4085 | (u64)skb_shinfo(skb)->ip6_frag_id; |
4051 | #else | 4086 | #else |
4052 | sp->ufo_in_band_v[put_off] = | 4087 | fifo->ufo_in_band_v[put_off] = |
4053 | (u64)skb_shinfo(skb)->ip6_frag_id << 32; | 4088 | (u64)skb_shinfo(skb)->ip6_frag_id << 32; |
4054 | #endif | 4089 | #endif |
4055 | txdp->Host_Control = (unsigned long)sp->ufo_in_band_v; | 4090 | txdp->Host_Control = (unsigned long)fifo->ufo_in_band_v; |
4056 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4091 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
4057 | sp->ufo_in_band_v, | 4092 | fifo->ufo_in_band_v, |
4058 | sizeof(u64), PCI_DMA_TODEVICE); | 4093 | sizeof(u64), PCI_DMA_TODEVICE); |
4059 | if((txdp->Buffer_Pointer == 0) || | 4094 | if((txdp->Buffer_Pointer == 0) || |
4060 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | 4095 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) |
@@ -4094,7 +4129,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4094 | frg_cnt++; /* as Txd0 was used for inband header */ | 4129 | frg_cnt++; /* as Txd0 was used for inband header */ |
4095 | 4130 | ||
4096 | tx_fifo = mac_control->tx_FIFO_start[queue]; | 4131 | tx_fifo = mac_control->tx_FIFO_start[queue]; |
4097 | val64 = mac_control->fifos[queue].list_info[put_off].list_phy_addr; | 4132 | val64 = fifo->list_info[put_off].list_phy_addr; |
4098 | writeq(val64, &tx_fifo->TxDL_Pointer); | 4133 | writeq(val64, &tx_fifo->TxDL_Pointer); |
4099 | 4134 | ||
4100 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | | 4135 | val64 = (TX_FIFO_LAST_TXD_NUM(frg_cnt) | TX_FIFO_FIRST_LIST | |
@@ -4107,9 +4142,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4107 | mmiowb(); | 4142 | mmiowb(); |
4108 | 4143 | ||
4109 | put_off++; | 4144 | put_off++; |
4110 | if (put_off == mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1) | 4145 | if (put_off == fifo->tx_curr_put_info.fifo_len + 1) |
4111 | put_off = 0; | 4146 | put_off = 0; |
4112 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; | 4147 | fifo->tx_curr_put_info.offset = put_off; |
4113 | 4148 | ||
4114 | /* Avoid "put" pointer going beyond "get" pointer */ | 4149 | /* Avoid "put" pointer going beyond "get" pointer */ |
4115 | if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { | 4150 | if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { |
@@ -4121,7 +4156,7 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4121 | } | 4156 | } |
4122 | mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; | 4157 | mac_control->stats_info->sw_stat.mem_allocated += skb->truesize; |
4123 | dev->trans_start = jiffies; | 4158 | dev->trans_start = jiffies; |
4124 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 4159 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
4125 | 4160 | ||
4126 | return 0; | 4161 | return 0; |
4127 | pci_map_failed: | 4162 | pci_map_failed: |
@@ -4129,7 +4164,7 @@ pci_map_failed: | |||
4129 | netif_stop_queue(dev); | 4164 | netif_stop_queue(dev); |
4130 | stats->mem_freed += skb->truesize; | 4165 | stats->mem_freed += skb->truesize; |
4131 | dev_kfree_skb(skb); | 4166 | dev_kfree_skb(skb); |
4132 | spin_unlock_irqrestore(&sp->tx_lock, flags); | 4167 | spin_unlock_irqrestore(&fifo->tx_lock, flags); |
4133 | return 0; | 4168 | return 0; |
4134 | } | 4169 | } |
4135 | 4170 | ||
@@ -6995,10 +7030,8 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
6995 | if (do_io) | 7030 | if (do_io) |
6996 | s2io_reset(sp); | 7031 | s2io_reset(sp); |
6997 | 7032 | ||
6998 | spin_lock_irqsave(&sp->tx_lock, flags); | ||
6999 | /* Free all Tx buffers */ | 7033 | /* Free all Tx buffers */ |
7000 | free_tx_buffers(sp); | 7034 | free_tx_buffers(sp); |
7001 | spin_unlock_irqrestore(&sp->tx_lock, flags); | ||
7002 | 7035 | ||
7003 | /* Free all Rx buffers */ | 7036 | /* Free all Rx buffers */ |
7004 | spin_lock_irqsave(&sp->rx_lock, flags); | 7037 | spin_lock_irqsave(&sp->rx_lock, flags); |
@@ -7462,12 +7495,18 @@ static void s2io_init_pci(struct s2io_nic * sp) | |||
7462 | 7495 | ||
7463 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | 7496 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) |
7464 | { | 7497 | { |
7465 | if ( tx_fifo_num > 8) { | 7498 | if ((tx_fifo_num > MAX_TX_FIFOS) || |
7466 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Tx fifos not " | 7499 | (tx_fifo_num < FIFO_DEFAULT_NUM)) { |
7467 | "supported\n"); | 7500 | DBG_PRINT(ERR_DBG, "s2io: Requested number of tx fifos " |
7468 | DBG_PRINT(ERR_DBG, "s2io: Default to 8 Tx fifos\n"); | 7501 | "(%d) not supported\n", tx_fifo_num); |
7469 | tx_fifo_num = 8; | 7502 | tx_fifo_num = |
7503 | ((tx_fifo_num > MAX_TX_FIFOS)? MAX_TX_FIFOS : | ||
7504 | ((tx_fifo_num < FIFO_DEFAULT_NUM) ? FIFO_DEFAULT_NUM : | ||
7505 | tx_fifo_num)); | ||
7506 | DBG_PRINT(ERR_DBG, "s2io: Default to %d ", tx_fifo_num); | ||
7507 | DBG_PRINT(ERR_DBG, "tx fifos\n"); | ||
7470 | } | 7508 | } |
7509 | |||
7471 | if ( rx_ring_num > 8) { | 7510 | if ( rx_ring_num > 8) { |
7472 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " | 7511 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " |
7473 | "supported\n"); | 7512 | "supported\n"); |
@@ -7846,7 +7885,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7846 | sp->state = 0; | 7885 | sp->state = 0; |
7847 | 7886 | ||
7848 | /* Initialize spinlocks */ | 7887 | /* Initialize spinlocks */ |
7849 | spin_lock_init(&sp->tx_lock); | 7888 | for (i = 0; i < sp->config.tx_fifo_num; i++) |
7889 | spin_lock_init(&mac_control->fifos[i].tx_lock); | ||
7850 | 7890 | ||
7851 | if (!napi) | 7891 | if (!napi) |
7852 | spin_lock_init(&sp->put_lock); | 7892 | spin_lock_init(&sp->put_lock); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index b944a948f19d..9f6016c6f135 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
@@ -360,6 +360,8 @@ struct stat_block { | |||
360 | #define MAX_TX_FIFOS 8 | 360 | #define MAX_TX_FIFOS 8 |
361 | #define MAX_RX_RINGS 8 | 361 | #define MAX_RX_RINGS 8 |
362 | 362 | ||
363 | #define FIFO_DEFAULT_NUM 1 | ||
364 | |||
363 | #define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) | 365 | #define MAX_RX_DESC_1 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 127 ) |
364 | #define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) | 366 | #define MAX_RX_DESC_2 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) |
365 | #define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) | 367 | #define MAX_RX_DESC_3 (MAX_RX_RINGS * MAX_RX_BLOCKS_PER_RING * 85 ) |
@@ -719,8 +721,14 @@ struct fifo_info { | |||
719 | */ | 721 | */ |
720 | struct tx_curr_get_info tx_curr_get_info; | 722 | struct tx_curr_get_info tx_curr_get_info; |
721 | 723 | ||
724 | /* Per fifo lock */ | ||
725 | spinlock_t tx_lock; | ||
726 | |||
727 | /* Per fifo UFO in band structure */ | ||
728 | u64 *ufo_in_band_v; | ||
729 | |||
722 | struct s2io_nic *nic; | 730 | struct s2io_nic *nic; |
723 | }; | 731 | } ____cacheline_aligned; |
724 | 732 | ||
725 | /* Information related to the Tx and Rx FIFOs and Rings of Xena | 733 | /* Information related to the Tx and Rx FIFOs and Rings of Xena |
726 | * is maintained in this structure. | 734 | * is maintained in this structure. |
@@ -848,7 +856,6 @@ struct s2io_nic { | |||
848 | 856 | ||
849 | atomic_t rx_bufs_left[MAX_RX_RINGS]; | 857 | atomic_t rx_bufs_left[MAX_RX_RINGS]; |
850 | 858 | ||
851 | spinlock_t tx_lock; | ||
852 | spinlock_t put_lock; | 859 | spinlock_t put_lock; |
853 | 860 | ||
854 | #define PROMISC 1 | 861 | #define PROMISC 1 |
@@ -915,7 +922,6 @@ struct s2io_nic { | |||
915 | volatile unsigned long state; | 922 | volatile unsigned long state; |
916 | spinlock_t rx_lock; | 923 | spinlock_t rx_lock; |
917 | u64 general_int_mask; | 924 | u64 general_int_mask; |
918 | u64 *ufo_in_band_v; | ||
919 | #define VPD_STRING_LEN 80 | 925 | #define VPD_STRING_LEN 80 |
920 | u8 product_name[VPD_STRING_LEN]; | 926 | u8 product_name[VPD_STRING_LEN]; |
921 | u8 serial_num[VPD_STRING_LEN]; | 927 | u8 serial_num[VPD_STRING_LEN]; |