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. |
