diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 128 |
1 files changed, 8 insertions, 120 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index dcbe01b0ca0d..157fd932e951 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -86,7 +86,7 @@ | |||
86 | #include "s2io.h" | 86 | #include "s2io.h" |
87 | #include "s2io-regs.h" | 87 | #include "s2io-regs.h" |
88 | 88 | ||
89 | #define DRV_VERSION "2.0.26.20" | 89 | #define DRV_VERSION "2.0.26.22" |
90 | 90 | ||
91 | /* S2io Driver name & version. */ | 91 | /* S2io Driver name & version. */ |
92 | static char s2io_driver_name[] = "Neterion"; | 92 | static char s2io_driver_name[] = "Neterion"; |
@@ -117,20 +117,6 @@ static inline int RXD_IS_UP2DT(struct RxD_t *rxdp) | |||
117 | 117 | ||
118 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ | 118 | #define LINK_IS_UP(val64) (!(val64 & (ADAPTER_STATUS_RMAC_REMOTE_FAULT | \ |
119 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) | 119 | ADAPTER_STATUS_RMAC_LOCAL_FAULT))) |
120 | #define TASKLET_IN_USE test_and_set_bit(0, (&sp->tasklet_status)) | ||
121 | #define PANIC 1 | ||
122 | #define LOW 2 | ||
123 | static inline int rx_buffer_level(struct s2io_nic * sp, int rxb_size, int ring) | ||
124 | { | ||
125 | struct mac_info *mac_control; | ||
126 | |||
127 | mac_control = &sp->mac_control; | ||
128 | if (rxb_size <= rxd_count[sp->rxd_mode]) | ||
129 | return PANIC; | ||
130 | else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) | ||
131 | return LOW; | ||
132 | return 0; | ||
133 | } | ||
134 | 120 | ||
135 | static inline int is_s2io_card_up(const struct s2io_nic * sp) | 121 | static inline int is_s2io_card_up(const struct s2io_nic * sp) |
136 | { | 122 | { |
@@ -2458,7 +2444,7 @@ static void free_tx_buffers(struct s2io_nic *nic) | |||
2458 | for (i = 0; i < config->tx_fifo_num; i++) { | 2444 | for (i = 0; i < config->tx_fifo_num; i++) { |
2459 | unsigned long flags; | 2445 | unsigned long flags; |
2460 | spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags); | 2446 | spin_lock_irqsave(&mac_control->fifos[i].tx_lock, flags); |
2461 | for (j = 0; j < config->tx_cfg[i].fifo_len - 1; j++) { | 2447 | for (j = 0; j < config->tx_cfg[i].fifo_len; j++) { |
2462 | txdp = (struct TxD *) \ | 2448 | txdp = (struct TxD *) \ |
2463 | mac_control->fifos[i].list_info[j].list_virt_addr; | 2449 | mac_control->fifos[i].list_info[j].list_virt_addr; |
2464 | skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); | 2450 | skb = s2io_txdl_getskb(&mac_control->fifos[i], txdp, j); |
@@ -2544,7 +2530,6 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2544 | struct config_param *config; | 2530 | struct config_param *config; |
2545 | u64 tmp; | 2531 | u64 tmp; |
2546 | struct buffAdd *ba; | 2532 | struct buffAdd *ba; |
2547 | unsigned long flags; | ||
2548 | struct RxD_t *first_rxdp = NULL; | 2533 | struct RxD_t *first_rxdp = NULL; |
2549 | u64 Buffer0_ptr = 0, Buffer1_ptr = 0; | 2534 | u64 Buffer0_ptr = 0, Buffer1_ptr = 0; |
2550 | struct RxD1 *rxdp1; | 2535 | struct RxD1 *rxdp1; |
@@ -2592,15 +2577,7 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
2592 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", | 2577 | DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n", |
2593 | dev->name, rxdp); | 2578 | dev->name, rxdp); |
2594 | } | 2579 | } |
2595 | if(!napi) { | 2580 | |
2596 | spin_lock_irqsave(&nic->put_lock, flags); | ||
2597 | mac_control->rings[ring_no].put_pos = | ||
2598 | (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; | ||
2599 | spin_unlock_irqrestore(&nic->put_lock, flags); | ||
2600 | } else { | ||
2601 | mac_control->rings[ring_no].put_pos = | ||
2602 | (block_no * (rxd_count[nic->rxd_mode] + 1)) + off; | ||
2603 | } | ||
2604 | if ((rxdp->Control_1 & RXD_OWN_XENA) && | 2581 | if ((rxdp->Control_1 & RXD_OWN_XENA) && |
2605 | ((nic->rxd_mode == RXD_MODE_3B) && | 2582 | ((nic->rxd_mode == RXD_MODE_3B) && |
2606 | (rxdp->Control_2 & s2BIT(0)))) { | 2583 | (rxdp->Control_2 & s2BIT(0)))) { |
@@ -2978,7 +2955,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2978 | { | 2955 | { |
2979 | struct s2io_nic *nic = ring_data->nic; | 2956 | struct s2io_nic *nic = ring_data->nic; |
2980 | struct net_device *dev = (struct net_device *) nic->dev; | 2957 | struct net_device *dev = (struct net_device *) nic->dev; |
2981 | int get_block, put_block, put_offset; | 2958 | int get_block, put_block; |
2982 | struct rx_curr_get_info get_info, put_info; | 2959 | struct rx_curr_get_info get_info, put_info; |
2983 | struct RxD_t *rxdp; | 2960 | struct RxD_t *rxdp; |
2984 | struct sk_buff *skb; | 2961 | struct sk_buff *skb; |
@@ -2987,19 +2964,11 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2987 | struct RxD1* rxdp1; | 2964 | struct RxD1* rxdp1; |
2988 | struct RxD3* rxdp3; | 2965 | struct RxD3* rxdp3; |
2989 | 2966 | ||
2990 | spin_lock(&nic->rx_lock); | ||
2991 | |||
2992 | get_info = ring_data->rx_curr_get_info; | 2967 | get_info = ring_data->rx_curr_get_info; |
2993 | get_block = get_info.block_index; | 2968 | get_block = get_info.block_index; |
2994 | memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); | 2969 | memcpy(&put_info, &ring_data->rx_curr_put_info, sizeof(put_info)); |
2995 | put_block = put_info.block_index; | 2970 | put_block = put_info.block_index; |
2996 | rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr; | 2971 | rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr; |
2997 | if (!napi) { | ||
2998 | spin_lock(&nic->put_lock); | ||
2999 | put_offset = ring_data->put_pos; | ||
3000 | spin_unlock(&nic->put_lock); | ||
3001 | } else | ||
3002 | put_offset = ring_data->put_pos; | ||
3003 | 2972 | ||
3004 | while (RXD_IS_UP2DT(rxdp)) { | 2973 | while (RXD_IS_UP2DT(rxdp)) { |
3005 | /* | 2974 | /* |
@@ -3016,7 +2985,6 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3016 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 2985 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
3017 | dev->name); | 2986 | dev->name); |
3018 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 2987 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
3019 | spin_unlock(&nic->rx_lock); | ||
3020 | return; | 2988 | return; |
3021 | } | 2989 | } |
3022 | if (nic->rxd_mode == RXD_MODE_1) { | 2990 | if (nic->rxd_mode == RXD_MODE_1) { |
@@ -3072,8 +3040,6 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3072 | } | 3040 | } |
3073 | } | 3041 | } |
3074 | } | 3042 | } |
3075 | |||
3076 | spin_unlock(&nic->rx_lock); | ||
3077 | } | 3043 | } |
3078 | 3044 | ||
3079 | /** | 3045 | /** |
@@ -4105,7 +4071,6 @@ static int s2io_close(struct net_device *dev) | |||
4105 | do_s2io_delete_unicast_mc(sp, tmp64); | 4071 | do_s2io_delete_unicast_mc(sp, tmp64); |
4106 | } | 4072 | } |
4107 | 4073 | ||
4108 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | ||
4109 | s2io_card_down(sp); | 4074 | s2io_card_down(sp); |
4110 | 4075 | ||
4111 | return 0; | 4076 | return 0; |
@@ -4370,29 +4335,9 @@ s2io_alarm_handle(unsigned long data) | |||
4370 | 4335 | ||
4371 | static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) | 4336 | static int s2io_chk_rx_buffers(struct s2io_nic *sp, int rng_n) |
4372 | { | 4337 | { |
4373 | int rxb_size, level; | 4338 | if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { |
4374 | 4339 | DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); | |
4375 | if (!sp->lro) { | 4340 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); |
4376 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
4377 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
4378 | |||
4379 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
4380 | int ret; | ||
4381 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
4382 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
4383 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
4384 | DBG_PRINT(INFO_DBG, "Out of memory in %s", | ||
4385 | __FUNCTION__); | ||
4386 | clear_bit(0, (&sp->tasklet_status)); | ||
4387 | return -1; | ||
4388 | } | ||
4389 | clear_bit(0, (&sp->tasklet_status)); | ||
4390 | } else if (level == LOW) | ||
4391 | tasklet_schedule(&sp->task); | ||
4392 | |||
4393 | } else if (fill_rx_buffers(sp, rng_n) == -ENOMEM) { | ||
4394 | DBG_PRINT(INFO_DBG, "%s:Out of memory", sp->dev->name); | ||
4395 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
4396 | } | 4341 | } |
4397 | return 0; | 4342 | return 0; |
4398 | } | 4343 | } |
@@ -6770,49 +6715,6 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
6770 | } | 6715 | } |
6771 | 6716 | ||
6772 | /** | 6717 | /** |
6773 | * s2io_tasklet - Bottom half of the ISR. | ||
6774 | * @dev_adr : address of the device structure in dma_addr_t format. | ||
6775 | * Description: | ||
6776 | * This is the tasklet or the bottom half of the ISR. This is | ||
6777 | * an extension of the ISR which is scheduled by the scheduler to be run | ||
6778 | * when the load on the CPU is low. All low priority tasks of the ISR can | ||
6779 | * be pushed into the tasklet. For now the tasklet is used only to | ||
6780 | * replenish the Rx buffers in the Rx buffer descriptors. | ||
6781 | * Return value: | ||
6782 | * void. | ||
6783 | */ | ||
6784 | |||
6785 | static void s2io_tasklet(unsigned long dev_addr) | ||
6786 | { | ||
6787 | struct net_device *dev = (struct net_device *) dev_addr; | ||
6788 | struct s2io_nic *sp = dev->priv; | ||
6789 | int i, ret; | ||
6790 | struct mac_info *mac_control; | ||
6791 | struct config_param *config; | ||
6792 | |||
6793 | mac_control = &sp->mac_control; | ||
6794 | config = &sp->config; | ||
6795 | |||
6796 | if (!TASKLET_IN_USE) { | ||
6797 | for (i = 0; i < config->rx_ring_num; i++) { | ||
6798 | ret = fill_rx_buffers(sp, i); | ||
6799 | if (ret == -ENOMEM) { | ||
6800 | DBG_PRINT(INFO_DBG, "%s: Out of ", | ||
6801 | dev->name); | ||
6802 | DBG_PRINT(INFO_DBG, "memory in tasklet\n"); | ||
6803 | break; | ||
6804 | } else if (ret == -EFILL) { | ||
6805 | DBG_PRINT(INFO_DBG, | ||
6806 | "%s: Rx Ring %d is full\n", | ||
6807 | dev->name, i); | ||
6808 | break; | ||
6809 | } | ||
6810 | } | ||
6811 | clear_bit(0, (&sp->tasklet_status)); | ||
6812 | } | ||
6813 | } | ||
6814 | |||
6815 | /** | ||
6816 | * s2io_set_link - Set the LInk status | 6718 | * s2io_set_link - Set the LInk status |
6817 | * @data: long pointer to device private structue | 6719 | * @data: long pointer to device private structue |
6818 | * Description: Sets the link status for the adapter | 6720 | * Description: Sets the link status for the adapter |
@@ -7161,7 +7063,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7161 | { | 7063 | { |
7162 | int cnt = 0; | 7064 | int cnt = 0; |
7163 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 7065 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
7164 | unsigned long flags; | ||
7165 | register u64 val64 = 0; | 7066 | register u64 val64 = 0; |
7166 | struct config_param *config; | 7067 | struct config_param *config; |
7167 | config = &sp->config; | 7068 | config = &sp->config; |
@@ -7186,9 +7087,6 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7186 | 7087 | ||
7187 | s2io_rem_isr(sp); | 7088 | s2io_rem_isr(sp); |
7188 | 7089 | ||
7189 | /* Kill tasklet. */ | ||
7190 | tasklet_kill(&sp->task); | ||
7191 | |||
7192 | /* Check if the device is Quiescent and then Reset the NIC */ | 7090 | /* Check if the device is Quiescent and then Reset the NIC */ |
7193 | while(do_io) { | 7091 | while(do_io) { |
7194 | /* As per the HW requirement we need to replenish the | 7092 | /* As per the HW requirement we need to replenish the |
@@ -7223,9 +7121,7 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7223 | free_tx_buffers(sp); | 7121 | free_tx_buffers(sp); |
7224 | 7122 | ||
7225 | /* Free all Rx buffers */ | 7123 | /* Free all Rx buffers */ |
7226 | spin_lock_irqsave(&sp->rx_lock, flags); | ||
7227 | free_rx_buffers(sp); | 7124 | free_rx_buffers(sp); |
7228 | spin_unlock_irqrestore(&sp->rx_lock, flags); | ||
7229 | 7125 | ||
7230 | clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state)); | 7126 | clear_bit(__S2IO_STATE_LINK_TASK, &(sp->state)); |
7231 | } | 7127 | } |
@@ -7314,9 +7210,6 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7314 | 7210 | ||
7315 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); | 7211 | S2IO_TIMER_CONF(sp->alarm_timer, s2io_alarm_handle, sp, (HZ/2)); |
7316 | 7212 | ||
7317 | /* Enable tasklet for the device */ | ||
7318 | tasklet_init(&sp->task, s2io_tasklet, (unsigned long) dev); | ||
7319 | |||
7320 | /* Enable select interrupts */ | 7213 | /* Enable select interrupts */ |
7321 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7214 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7322 | if (sp->config.intr_type != INTA) | 7215 | if (sp->config.intr_type != INTA) |
@@ -8119,20 +8012,15 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8119 | s2io_reset(sp); | 8012 | s2io_reset(sp); |
8120 | 8013 | ||
8121 | /* | 8014 | /* |
8122 | * Initialize the tasklet status and link state flags | 8015 | * Initialize link state flags |
8123 | * and the card state parameter | 8016 | * and the card state parameter |
8124 | */ | 8017 | */ |
8125 | sp->tasklet_status = 0; | ||
8126 | sp->state = 0; | 8018 | sp->state = 0; |
8127 | 8019 | ||
8128 | /* Initialize spinlocks */ | 8020 | /* Initialize spinlocks */ |
8129 | for (i = 0; i < sp->config.tx_fifo_num; i++) | 8021 | for (i = 0; i < sp->config.tx_fifo_num; i++) |
8130 | spin_lock_init(&mac_control->fifos[i].tx_lock); | 8022 | spin_lock_init(&mac_control->fifos[i].tx_lock); |
8131 | 8023 | ||
8132 | if (!napi) | ||
8133 | spin_lock_init(&sp->put_lock); | ||
8134 | spin_lock_init(&sp->rx_lock); | ||
8135 | |||
8136 | /* | 8024 | /* |
8137 | * SXE-002: Configure link and activity LED to init state | 8025 | * SXE-002: Configure link and activity LED to init state |
8138 | * on driver load. | 8026 | * on driver load. |