diff options
| author | Sreenivasa Honnur <Sreenivasa.Honnur@neterion.com> | 2008-05-12 13:42:17 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@redhat.com> | 2008-05-22 06:26:21 -0400 |
| commit | f61e0a3544be2f615a0af4aec71eb85a96bdbd62 (patch) | |
| tree | cc4bf4924c62327bb95f16968fb20286011667d8 | |
| parent | ac731ab66960547c33a4e2c504419389ae747067 (diff) | |
S2io: Added napi support when MSIX is enabled.
- Added napi support when MSIX is enabled.
- Moved test_msi function from s2io_open to probe function.
Signed-off-by: Sreenivasa Honnur <sreenivasa.honnur@neterion.com>
Signed-off-by: Ramkrishna Vepa <ram.vepa@neterion.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
| -rw-r--r-- | drivers/net/s2io-regs.h | 2 | ||||
| -rw-r--r-- | drivers/net/s2io.c | 327 | ||||
| -rw-r--r-- | drivers/net/s2io.h | 17 |
3 files changed, 205 insertions, 141 deletions
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h index 2109508c047a..f8274f8941ea 100644 --- a/drivers/net/s2io-regs.h +++ b/drivers/net/s2io-regs.h | |||
| @@ -250,7 +250,7 @@ struct XENA_dev_config { | |||
| 250 | u64 tx_mat0_n[0x8]; | 250 | u64 tx_mat0_n[0x8]; |
| 251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) | 251 | #define TX_MAT_SET(fifo, msi) vBIT(msi, (8 * fifo), 8) |
| 252 | 252 | ||
| 253 | u8 unused_1[0x8]; | 253 | u64 xmsi_mask_reg; |
| 254 | u64 stat_byte_cnt; | 254 | u64 stat_byte_cnt; |
| 255 | #define STAT_BC(n) vBIT(n,4,12) | 255 | #define STAT_BC(n) vBIT(n,4,12) |
| 256 | 256 | ||
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index e161a847c536..807fb8db8c4b 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -2832,6 +2832,15 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
| 2832 | } | 2832 | } |
| 2833 | } | 2833 | } |
| 2834 | 2834 | ||
| 2835 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
| 2836 | { | ||
| 2837 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
| 2838 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
| 2839 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
| 2840 | } | ||
| 2841 | return 0; | ||
| 2842 | } | ||
| 2843 | |||
| 2835 | /** | 2844 | /** |
| 2836 | * s2io_poll - Rx interrupt handler for NAPI support | 2845 | * s2io_poll - Rx interrupt handler for NAPI support |
| 2837 | * @napi : pointer to the napi structure. | 2846 | * @napi : pointer to the napi structure. |
| @@ -2845,57 +2854,72 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
| 2845 | * 0 on success and 1 if there are No Rx packets to be processed. | 2854 | * 0 on success and 1 if there are No Rx packets to be processed. |
| 2846 | */ | 2855 | */ |
| 2847 | 2856 | ||
| 2848 | static int s2io_poll(struct napi_struct *napi, int budget) | 2857 | static int s2io_poll_msix(struct napi_struct *napi, int budget) |
| 2849 | { | 2858 | { |
| 2850 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | 2859 | struct ring_info *ring = container_of(napi, struct ring_info, napi); |
| 2851 | struct net_device *dev = nic->dev; | 2860 | struct net_device *dev = ring->dev; |
| 2852 | int pkt_cnt = 0, org_pkts_to_process; | ||
| 2853 | struct mac_info *mac_control; | ||
| 2854 | struct config_param *config; | 2861 | struct config_param *config; |
| 2862 | struct mac_info *mac_control; | ||
| 2863 | int pkts_processed = 0; | ||
| 2864 | u8 *addr = NULL, val8 = 0; | ||
| 2865 | struct s2io_nic *nic = dev->priv; | ||
| 2855 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2866 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
| 2856 | int i; | 2867 | int budget_org = budget; |
| 2857 | 2868 | ||
| 2858 | mac_control = &nic->mac_control; | ||
| 2859 | config = &nic->config; | 2869 | config = &nic->config; |
| 2870 | mac_control = &nic->mac_control; | ||
| 2860 | 2871 | ||
| 2861 | nic->pkts_to_process = budget; | 2872 | if (unlikely(!is_s2io_card_up(nic))) |
| 2862 | org_pkts_to_process = nic->pkts_to_process; | 2873 | return 0; |
| 2863 | 2874 | ||
| 2864 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 2875 | pkts_processed = rx_intr_handler(ring, budget); |
| 2865 | readl(&bar0->rx_traffic_int); | 2876 | s2io_chk_rx_buffers(ring); |
| 2866 | 2877 | ||
| 2867 | for (i = 0; i < config->rx_ring_num; i++) { | 2878 | if (pkts_processed < budget_org) { |
| 2868 | rx_intr_handler(&mac_control->rings[i]); | 2879 | netif_rx_complete(dev, napi); |
| 2869 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; | 2880 | /*Re Enable MSI-Rx Vector*/ |
| 2870 | if (!nic->pkts_to_process) { | 2881 | addr = (u8 *)&bar0->xmsi_mask_reg; |
| 2871 | /* Quota for the current iteration has been met */ | 2882 | addr += 7 - ring->ring_no; |
| 2872 | goto no_rx; | 2883 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; |
| 2873 | } | 2884 | writeb(val8, addr); |
| 2885 | val8 = readb(addr); | ||
| 2874 | } | 2886 | } |
| 2887 | return pkts_processed; | ||
| 2888 | } | ||
| 2889 | static int s2io_poll_inta(struct napi_struct *napi, int budget) | ||
| 2890 | { | ||
| 2891 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | ||
| 2892 | struct ring_info *ring; | ||
| 2893 | struct net_device *dev = nic->dev; | ||
| 2894 | struct config_param *config; | ||
| 2895 | struct mac_info *mac_control; | ||
| 2896 | int pkts_processed = 0; | ||
| 2897 | int ring_pkts_processed, i; | ||
| 2898 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
| 2899 | int budget_org = budget; | ||
| 2875 | 2900 | ||
| 2876 | netif_rx_complete(dev, napi); | 2901 | config = &nic->config; |
| 2902 | mac_control = &nic->mac_control; | ||
| 2877 | 2903 | ||
| 2878 | for (i = 0; i < config->rx_ring_num; i++) { | 2904 | if (unlikely(!is_s2io_card_up(nic))) |
| 2879 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2905 | return 0; |
| 2880 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | ||
| 2881 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | ||
| 2882 | break; | ||
| 2883 | } | ||
| 2884 | } | ||
| 2885 | /* Re enable the Rx interrupts. */ | ||
| 2886 | writeq(0x0, &bar0->rx_traffic_mask); | ||
| 2887 | readl(&bar0->rx_traffic_mask); | ||
| 2888 | return pkt_cnt; | ||
| 2889 | 2906 | ||
| 2890 | no_rx: | ||
| 2891 | for (i = 0; i < config->rx_ring_num; i++) { | 2907 | for (i = 0; i < config->rx_ring_num; i++) { |
| 2892 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2908 | ring = &mac_control->rings[i]; |
| 2893 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | 2909 | ring_pkts_processed = rx_intr_handler(ring, budget); |
| 2894 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | 2910 | s2io_chk_rx_buffers(ring); |
| 2911 | pkts_processed += ring_pkts_processed; | ||
| 2912 | budget -= ring_pkts_processed; | ||
| 2913 | if (budget <= 0) | ||
| 2895 | break; | 2914 | break; |
| 2896 | } | ||
| 2897 | } | 2915 | } |
| 2898 | return pkt_cnt; | 2916 | if (pkts_processed < budget_org) { |
| 2917 | netif_rx_complete(dev, napi); | ||
| 2918 | /* Re enable the Rx interrupts for the ring */ | ||
| 2919 | writeq(0, &bar0->rx_traffic_mask); | ||
| 2920 | readl(&bar0->rx_traffic_mask); | ||
| 2921 | } | ||
| 2922 | return pkts_processed; | ||
| 2899 | } | 2923 | } |
| 2900 | 2924 | ||
| 2901 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2925 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| @@ -2937,7 +2961,7 @@ static void s2io_netpoll(struct net_device *dev) | |||
| 2937 | 2961 | ||
| 2938 | /* check for received packet and indicate up to network */ | 2962 | /* check for received packet and indicate up to network */ |
| 2939 | for (i = 0; i < config->rx_ring_num; i++) | 2963 | for (i = 0; i < config->rx_ring_num; i++) |
| 2940 | rx_intr_handler(&mac_control->rings[i]); | 2964 | rx_intr_handler(&mac_control->rings[i], 0); |
| 2941 | 2965 | ||
| 2942 | for (i = 0; i < config->rx_ring_num; i++) { | 2966 | for (i = 0; i < config->rx_ring_num; i++) { |
| 2943 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2967 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { |
| @@ -2953,7 +2977,8 @@ static void s2io_netpoll(struct net_device *dev) | |||
| 2953 | 2977 | ||
| 2954 | /** | 2978 | /** |
| 2955 | * rx_intr_handler - Rx interrupt handler | 2979 | * rx_intr_handler - Rx interrupt handler |
| 2956 | * @nic: device private variable. | 2980 | * @ring_info: per ring structure. |
| 2981 | * @budget: budget for napi processing. | ||
| 2957 | * Description: | 2982 | * Description: |
| 2958 | * If the interrupt is because of a received frame or if the | 2983 | * If the interrupt is because of a received frame or if the |
| 2959 | * receive ring contains fresh as yet un-processed frames,this function is | 2984 | * receive ring contains fresh as yet un-processed frames,this function is |
| @@ -2961,15 +2986,15 @@ static void s2io_netpoll(struct net_device *dev) | |||
| 2961 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2986 | * stopped and sends the skb to the OSM's Rx handler and then increments |
| 2962 | * the offset. | 2987 | * the offset. |
| 2963 | * Return Value: | 2988 | * Return Value: |
| 2964 | * NONE. | 2989 | * No. of napi packets processed. |
| 2965 | */ | 2990 | */ |
| 2966 | static void rx_intr_handler(struct ring_info *ring_data) | 2991 | static int rx_intr_handler(struct ring_info *ring_data, int budget) |
| 2967 | { | 2992 | { |
| 2968 | int get_block, put_block; | 2993 | int get_block, put_block; |
| 2969 | struct rx_curr_get_info get_info, put_info; | 2994 | struct rx_curr_get_info get_info, put_info; |
| 2970 | struct RxD_t *rxdp; | 2995 | struct RxD_t *rxdp; |
| 2971 | struct sk_buff *skb; | 2996 | struct sk_buff *skb; |
| 2972 | int pkt_cnt = 0; | 2997 | int pkt_cnt = 0, napi_pkts = 0; |
| 2973 | int i; | 2998 | int i; |
| 2974 | struct RxD1* rxdp1; | 2999 | struct RxD1* rxdp1; |
| 2975 | struct RxD3* rxdp3; | 3000 | struct RxD3* rxdp3; |
| @@ -2996,7 +3021,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
| 2996 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 3021 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
| 2997 | ring_data->dev->name); | 3022 | ring_data->dev->name); |
| 2998 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 3023 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
| 2999 | return; | 3024 | return 0; |
| 3000 | } | 3025 | } |
| 3001 | if (ring_data->rxd_mode == RXD_MODE_1) { | 3026 | if (ring_data->rxd_mode == RXD_MODE_1) { |
| 3002 | rxdp1 = (struct RxD1*)rxdp; | 3027 | rxdp1 = (struct RxD1*)rxdp; |
| @@ -3033,9 +3058,10 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
| 3033 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; | 3058 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
| 3034 | } | 3059 | } |
| 3035 | 3060 | ||
| 3036 | if(ring_data->nic->config.napi){ | 3061 | if (ring_data->nic->config.napi) { |
| 3037 | ring_data->nic->pkts_to_process -= 1; | 3062 | budget--; |
| 3038 | if (!ring_data->nic->pkts_to_process) | 3063 | napi_pkts++; |
| 3064 | if (!budget) | ||
| 3039 | break; | 3065 | break; |
| 3040 | } | 3066 | } |
| 3041 | pkt_cnt++; | 3067 | pkt_cnt++; |
| @@ -3053,6 +3079,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
| 3053 | } | 3079 | } |
| 3054 | } | 3080 | } |
| 3055 | } | 3081 | } |
| 3082 | return(napi_pkts); | ||
| 3056 | } | 3083 | } |
| 3057 | 3084 | ||
| 3058 | /** | 3085 | /** |
| @@ -3749,14 +3776,19 @@ static void restore_xmsi_data(struct s2io_nic *nic) | |||
| 3749 | { | 3776 | { |
| 3750 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3777 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
| 3751 | u64 val64; | 3778 | u64 val64; |
| 3752 | int i; | 3779 | int i, msix_index; |
| 3780 | |||
| 3781 | |||
| 3782 | if (nic->device_type == XFRAME_I_DEVICE) | ||
| 3783 | return; | ||
| 3753 | 3784 | ||
| 3754 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3785 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
| 3786 | msix_index = (i) ? ((i-1) * 8 + 1): 0; | ||
| 3755 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3787 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
| 3756 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3788 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
| 3757 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); | 3789 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); |
| 3758 | writeq(val64, &bar0->xmsi_access); | 3790 | writeq(val64, &bar0->xmsi_access); |
| 3759 | if (wait_for_msix_trans(nic, i)) { | 3791 | if (wait_for_msix_trans(nic, msix_index)) { |
| 3760 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3792 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
| 3761 | continue; | 3793 | continue; |
| 3762 | } | 3794 | } |
| @@ -3767,13 +3799,17 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
| 3767 | { | 3799 | { |
| 3768 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3800 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
| 3769 | u64 val64, addr, data; | 3801 | u64 val64, addr, data; |
| 3770 | int i; | 3802 | int i, msix_index; |
| 3803 | |||
| 3804 | if (nic->device_type == XFRAME_I_DEVICE) | ||
| 3805 | return; | ||
| 3771 | 3806 | ||
| 3772 | /* Store and display */ | 3807 | /* Store and display */ |
| 3773 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3808 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
| 3774 | val64 = (s2BIT(15) | vBIT(i, 26, 6)); | 3809 | msix_index = (i) ? ((i-1) * 8 + 1): 0; |
| 3810 | val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); | ||
| 3775 | writeq(val64, &bar0->xmsi_access); | 3811 | writeq(val64, &bar0->xmsi_access); |
| 3776 | if (wait_for_msix_trans(nic, i)) { | 3812 | if (wait_for_msix_trans(nic, msix_index)) { |
| 3777 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3813 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
| 3778 | continue; | 3814 | continue; |
| 3779 | } | 3815 | } |
| @@ -3793,7 +3829,7 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
| 3793 | u16 msi_control; /* Temp variable */ | 3829 | u16 msi_control; /* Temp variable */ |
| 3794 | int ret, i, j, msix_indx = 1; | 3830 | int ret, i, j, msix_indx = 1; |
| 3795 | 3831 | ||
| 3796 | nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry), | 3832 | nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry), |
| 3797 | GFP_KERNEL); | 3833 | GFP_KERNEL); |
| 3798 | if (!nic->entries) { | 3834 | if (!nic->entries) { |
| 3799 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ | 3835 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ |
| @@ -3802,10 +3838,12 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
| 3802 | return -ENOMEM; | 3838 | return -ENOMEM; |
| 3803 | } | 3839 | } |
| 3804 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3840 | nic->mac_control.stats_info->sw_stat.mem_allocated |
| 3805 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3841 | += (nic->num_entries * sizeof(struct msix_entry)); |
| 3842 | |||
| 3843 | memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry)); | ||
| 3806 | 3844 | ||
| 3807 | nic->s2io_entries = | 3845 | nic->s2io_entries = |
| 3808 | kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry), | 3846 | kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry), |
| 3809 | GFP_KERNEL); | 3847 | GFP_KERNEL); |
| 3810 | if (!nic->s2io_entries) { | 3848 | if (!nic->s2io_entries) { |
| 3811 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", | 3849 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", |
| @@ -3813,11 +3851,13 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
| 3813 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; | 3851 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; |
| 3814 | kfree(nic->entries); | 3852 | kfree(nic->entries); |
| 3815 | nic->mac_control.stats_info->sw_stat.mem_freed | 3853 | nic->mac_control.stats_info->sw_stat.mem_freed |
| 3816 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3854 | += (nic->num_entries * sizeof(struct msix_entry)); |
| 3817 | return -ENOMEM; | 3855 | return -ENOMEM; |
| 3818 | } | 3856 | } |
| 3819 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3857 | nic->mac_control.stats_info->sw_stat.mem_allocated |
| 3820 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3858 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
| 3859 | memset(nic->s2io_entries, 0, | ||
| 3860 | nic->num_entries * sizeof(struct s2io_msix_entry)); | ||
| 3821 | 3861 | ||
| 3822 | nic->entries[0].entry = 0; | 3862 | nic->entries[0].entry = 0; |
| 3823 | nic->s2io_entries[0].entry = 0; | 3863 | nic->s2io_entries[0].entry = 0; |
| @@ -3825,45 +3865,38 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
| 3825 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; | 3865 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; |
| 3826 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; | 3866 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; |
| 3827 | 3867 | ||
| 3828 | for (i = 1; i < MAX_REQUESTED_MSI_X; i++) { | 3868 | for (i = 1; i < nic->num_entries; i++) { |
| 3829 | nic->entries[i].entry = i; | 3869 | nic->entries[i].entry = ((i - 1) * 8) + 1; |
| 3830 | nic->s2io_entries[i].entry = i; | 3870 | nic->s2io_entries[i].entry = ((i - 1) * 8) + 1; |
| 3831 | nic->s2io_entries[i].arg = NULL; | 3871 | nic->s2io_entries[i].arg = NULL; |
| 3832 | nic->s2io_entries[i].in_use = 0; | 3872 | nic->s2io_entries[i].in_use = 0; |
| 3833 | } | 3873 | } |
| 3834 | 3874 | ||
| 3835 | rx_mat = readq(&bar0->rx_mat); | 3875 | rx_mat = readq(&bar0->rx_mat); |
| 3836 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { | 3876 | for (j = 0; j < nic->config.rx_ring_num; j++) { |
| 3837 | rx_mat |= RX_MAT_SET(j, msix_indx); | 3877 | rx_mat |= RX_MAT_SET(j, msix_indx); |
| 3838 | nic->s2io_entries[msix_indx].arg | 3878 | nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j]; |
| 3839 | = &nic->mac_control.rings[j]; | 3879 | nic->s2io_entries[j+1].type = MSIX_RING_TYPE; |
| 3840 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | 3880 | nic->s2io_entries[j+1].in_use = MSIX_FLG; |
| 3841 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | 3881 | msix_indx += 8; |
| 3842 | } | 3882 | } |
| 3843 | writeq(rx_mat, &bar0->rx_mat); | 3883 | writeq(rx_mat, &bar0->rx_mat); |
| 3884 | readq(&bar0->rx_mat); | ||
| 3844 | 3885 | ||
| 3845 | nic->avail_msix_vectors = 0; | 3886 | ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries); |
| 3846 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | ||
| 3847 | /* We fail init if error or we get less vectors than min required */ | 3887 | /* We fail init if error or we get less vectors than min required */ |
| 3848 | if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { | ||
| 3849 | nic->avail_msix_vectors = ret; | ||
| 3850 | ret = pci_enable_msix(nic->pdev, nic->entries, ret); | ||
| 3851 | } | ||
| 3852 | if (ret) { | 3888 | if (ret) { |
| 3853 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | 3889 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); |
| 3854 | kfree(nic->entries); | 3890 | kfree(nic->entries); |
| 3855 | nic->mac_control.stats_info->sw_stat.mem_freed | 3891 | nic->mac_control.stats_info->sw_stat.mem_freed |
| 3856 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3892 | += (nic->num_entries * sizeof(struct msix_entry)); |
| 3857 | kfree(nic->s2io_entries); | 3893 | kfree(nic->s2io_entries); |
| 3858 | nic->mac_control.stats_info->sw_stat.mem_freed | 3894 | nic->mac_control.stats_info->sw_stat.mem_freed |
| 3859 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3895 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
| 3860 | nic->entries = NULL; | 3896 | nic->entries = NULL; |
| 3861 | nic->s2io_entries = NULL; | 3897 | nic->s2io_entries = NULL; |
| 3862 | nic->avail_msix_vectors = 0; | ||
| 3863 | return -ENOMEM; | 3898 | return -ENOMEM; |
| 3864 | } | 3899 | } |
| 3865 | if (!nic->avail_msix_vectors) | ||
| 3866 | nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; | ||
| 3867 | 3900 | ||
| 3868 | /* | 3901 | /* |
| 3869 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | 3902 | * To enable MSI-X, MSI also needs to be enabled, due to a bug |
| @@ -3935,7 +3968,7 @@ static void remove_msix_isr(struct s2io_nic *sp) | |||
| 3935 | int i; | 3968 | int i; |
| 3936 | u16 msi_control; | 3969 | u16 msi_control; |
| 3937 | 3970 | ||
| 3938 | for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { | 3971 | for (i = 0; i < sp->num_entries; i++) { |
| 3939 | if (sp->s2io_entries[i].in_use == | 3972 | if (sp->s2io_entries[i].in_use == |
| 3940 | MSIX_REGISTERED_SUCCESS) { | 3973 | MSIX_REGISTERED_SUCCESS) { |
| 3941 | int vector = sp->entries[i].vector; | 3974 | int vector = sp->entries[i].vector; |
| @@ -3991,29 +4024,6 @@ static int s2io_open(struct net_device *dev) | |||
| 3991 | netif_carrier_off(dev); | 4024 | netif_carrier_off(dev); |
| 3992 | sp->last_link_state = 0; | 4025 | sp->last_link_state = 0; |
| 3993 | 4026 | ||
| 3994 | if (sp->config.intr_type == MSI_X) { | ||
| 3995 | int ret = s2io_enable_msi_x(sp); | ||
| 3996 | |||
| 3997 | if (!ret) { | ||
| 3998 | ret = s2io_test_msi(sp); | ||
| 3999 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
| 4000 | remove_msix_isr(sp); | ||
| 4001 | } | ||
| 4002 | if (ret) { | ||
| 4003 | |||
| 4004 | DBG_PRINT(ERR_DBG, | ||
| 4005 | "%s: MSI-X requested but failed to enable\n", | ||
| 4006 | dev->name); | ||
| 4007 | sp->config.intr_type = INTA; | ||
| 4008 | } | ||
| 4009 | } | ||
| 4010 | |||
| 4011 | /* NAPI doesn't work well with MSI(X) */ | ||
| 4012 | if (sp->config.intr_type != INTA) { | ||
| 4013 | if(sp->config.napi) | ||
| 4014 | sp->config.napi = 0; | ||
| 4015 | } | ||
| 4016 | |||
| 4017 | /* Initialize H/W and enable interrupts */ | 4027 | /* Initialize H/W and enable interrupts */ |
| 4018 | err = s2io_card_up(sp); | 4028 | err = s2io_card_up(sp); |
| 4019 | if (err) { | 4029 | if (err) { |
| @@ -4036,12 +4046,12 @@ hw_init_failed: | |||
| 4036 | if (sp->entries) { | 4046 | if (sp->entries) { |
| 4037 | kfree(sp->entries); | 4047 | kfree(sp->entries); |
| 4038 | sp->mac_control.stats_info->sw_stat.mem_freed | 4048 | sp->mac_control.stats_info->sw_stat.mem_freed |
| 4039 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 4049 | += (sp->num_entries * sizeof(struct msix_entry)); |
| 4040 | } | 4050 | } |
| 4041 | if (sp->s2io_entries) { | 4051 | if (sp->s2io_entries) { |
| 4042 | kfree(sp->s2io_entries); | 4052 | kfree(sp->s2io_entries); |
| 4043 | sp->mac_control.stats_info->sw_stat.mem_freed | 4053 | sp->mac_control.stats_info->sw_stat.mem_freed |
| 4044 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 4054 | += (sp->num_entries * sizeof(struct s2io_msix_entry)); |
| 4045 | } | 4055 | } |
| 4046 | } | 4056 | } |
| 4047 | return err; | 4057 | return err; |
| @@ -4343,25 +4353,29 @@ s2io_alarm_handle(unsigned long data) | |||
| 4343 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4353 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
| 4344 | } | 4354 | } |
| 4345 | 4355 | ||
| 4346 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
| 4347 | { | ||
| 4348 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
| 4349 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
| 4350 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
| 4351 | } | ||
| 4352 | return 0; | ||
| 4353 | } | ||
| 4354 | |||
| 4355 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | 4356 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) |
| 4356 | { | 4357 | { |
| 4357 | struct ring_info *ring = (struct ring_info *)dev_id; | 4358 | struct ring_info *ring = (struct ring_info *)dev_id; |
| 4358 | struct s2io_nic *sp = ring->nic; | 4359 | struct s2io_nic *sp = ring->nic; |
| 4360 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
| 4361 | struct net_device *dev = sp->dev; | ||
| 4359 | 4362 | ||
| 4360 | if (!is_s2io_card_up(sp)) | 4363 | if (unlikely(!is_s2io_card_up(sp))) |
| 4361 | return IRQ_HANDLED; | 4364 | return IRQ_HANDLED; |
| 4362 | 4365 | ||
| 4363 | rx_intr_handler(ring); | 4366 | if (sp->config.napi) { |
| 4364 | s2io_chk_rx_buffers(ring); | 4367 | u8 *addr = NULL, val8 = 0; |
| 4368 | |||
| 4369 | addr = (u8 *)&bar0->xmsi_mask_reg; | ||
| 4370 | addr += (7 - ring->ring_no); | ||
| 4371 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; | ||
| 4372 | writeb(val8, addr); | ||
| 4373 | val8 = readb(addr); | ||
| 4374 | netif_rx_schedule(dev, &ring->napi); | ||
| 4375 | } else { | ||
| 4376 | rx_intr_handler(ring, 0); | ||
| 4377 | s2io_chk_rx_buffers(ring); | ||
| 4378 | } | ||
| 4365 | 4379 | ||
| 4366 | return IRQ_HANDLED; | 4380 | return IRQ_HANDLED; |
| 4367 | } | 4381 | } |
| @@ -4798,14 +4812,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
| 4798 | 4812 | ||
| 4799 | if (config->napi) { | 4813 | if (config->napi) { |
| 4800 | if (reason & GEN_INTR_RXTRAFFIC) { | 4814 | if (reason & GEN_INTR_RXTRAFFIC) { |
| 4801 | if (likely(netif_rx_schedule_prep(dev, | 4815 | netif_rx_schedule(dev, &sp->napi); |
| 4802 | &sp->napi))) { | 4816 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); |
| 4803 | __netif_rx_schedule(dev, &sp->napi); | 4817 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
| 4804 | writeq(S2IO_MINUS_ONE, | 4818 | readl(&bar0->rx_traffic_int); |
| 4805 | &bar0->rx_traffic_mask); | ||
| 4806 | } else | ||
| 4807 | writeq(S2IO_MINUS_ONE, | ||
| 4808 | &bar0->rx_traffic_int); | ||
| 4809 | } | 4819 | } |
| 4810 | } else { | 4820 | } else { |
| 4811 | /* | 4821 | /* |
| @@ -4817,7 +4827,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
| 4817 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4827 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
| 4818 | 4828 | ||
| 4819 | for (i = 0; i < config->rx_ring_num; i++) | 4829 | for (i = 0; i < config->rx_ring_num; i++) |
| 4820 | rx_intr_handler(&mac_control->rings[i]); | 4830 | rx_intr_handler(&mac_control->rings[i], 0); |
| 4821 | } | 4831 | } |
| 4822 | 4832 | ||
| 4823 | /* | 4833 | /* |
| @@ -7022,8 +7032,9 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
| 7022 | if (sp->config.intr_type == MSI_X) { | 7032 | if (sp->config.intr_type == MSI_X) { |
| 7023 | int i, msix_rx_cnt = 0; | 7033 | int i, msix_rx_cnt = 0; |
| 7024 | 7034 | ||
| 7025 | for (i = 0; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 7035 | for (i = 0; i < sp->num_entries; i++) { |
| 7026 | if (sp->s2io_entries[i].type == | 7036 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { |
| 7037 | if (sp->s2io_entries[i].type == | ||
| 7027 | MSIX_RING_TYPE) { | 7038 | MSIX_RING_TYPE) { |
| 7028 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 7039 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", |
| 7029 | dev->name, i); | 7040 | dev->name, i); |
| @@ -7068,7 +7079,7 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
| 7068 | } | 7079 | } |
| 7069 | sp->s2io_entries[i].in_use = | 7080 | sp->s2io_entries[i].in_use = |
| 7070 | MSIX_REGISTERED_SUCCESS; | 7081 | MSIX_REGISTERED_SUCCESS; |
| 7071 | 7082 | } | |
| 7072 | } | 7083 | } |
| 7073 | if (!err) { | 7084 | if (!err) { |
| 7074 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", | 7085 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", |
| @@ -7115,8 +7126,15 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
| 7115 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); | 7126 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); |
| 7116 | 7127 | ||
| 7117 | /* Disable napi */ | 7128 | /* Disable napi */ |
| 7118 | if (config->napi) | 7129 | if (sp->config.napi) { |
| 7119 | napi_disable(&sp->napi); | 7130 | int off = 0; |
| 7131 | if (config->intr_type == MSI_X) { | ||
| 7132 | for (; off < sp->config.rx_ring_num; off++) | ||
| 7133 | napi_disable(&sp->mac_control.rings[off].napi); | ||
| 7134 | } | ||
| 7135 | else | ||
| 7136 | napi_disable(&sp->napi); | ||
| 7137 | } | ||
| 7120 | 7138 | ||
| 7121 | /* disable Tx and Rx traffic on the NIC */ | 7139 | /* disable Tx and Rx traffic on the NIC */ |
| 7122 | if (do_io) | 7140 | if (do_io) |
| @@ -7208,8 +7226,15 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
| 7208 | } | 7226 | } |
| 7209 | 7227 | ||
| 7210 | /* Initialise napi */ | 7228 | /* Initialise napi */ |
| 7211 | if (config->napi) | 7229 | if (config->napi) { |
| 7212 | napi_enable(&sp->napi); | 7230 | int i; |
| 7231 | if (config->intr_type == MSI_X) { | ||
| 7232 | for (i = 0; i < sp->config.rx_ring_num; i++) | ||
| 7233 | napi_enable(&sp->mac_control.rings[i].napi); | ||
| 7234 | } else { | ||
| 7235 | napi_enable(&sp->napi); | ||
| 7236 | } | ||
| 7237 | } | ||
| 7213 | 7238 | ||
| 7214 | /* Maintain the state prior to the open */ | 7239 | /* Maintain the state prior to the open */ |
| 7215 | if (sp->promisc_flg) | 7240 | if (sp->promisc_flg) |
| @@ -7650,9 +7675,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, | |||
| 7650 | rx_ring_num = MAX_RX_RINGS; | 7675 | rx_ring_num = MAX_RX_RINGS; |
| 7651 | } | 7676 | } |
| 7652 | 7677 | ||
| 7653 | if (*dev_intr_type != INTA) | ||
| 7654 | napi = 0; | ||
| 7655 | |||
| 7656 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { | 7678 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
| 7657 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 7679 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
| 7658 | "Defaulting to INTA\n"); | 7680 | "Defaulting to INTA\n"); |
| @@ -7953,8 +7975,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 7953 | * will use eth_mac_addr() for dev->set_mac_address | 7975 | * will use eth_mac_addr() for dev->set_mac_address |
| 7954 | * mac address will be set every time dev->open() is called | 7976 | * mac address will be set every time dev->open() is called |
| 7955 | */ | 7977 | */ |
| 7956 | netif_napi_add(dev, &sp->napi, s2io_poll, 32); | ||
| 7957 | |||
| 7958 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7978 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 7959 | dev->poll_controller = s2io_netpoll; | 7979 | dev->poll_controller = s2io_netpoll; |
| 7960 | #endif | 7980 | #endif |
| @@ -7998,6 +8018,32 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 7998 | } | 8018 | } |
| 7999 | } | 8019 | } |
| 8000 | 8020 | ||
| 8021 | if (sp->config.intr_type == MSI_X) { | ||
| 8022 | sp->num_entries = config->rx_ring_num + 1; | ||
| 8023 | ret = s2io_enable_msi_x(sp); | ||
| 8024 | |||
| 8025 | if (!ret) { | ||
| 8026 | ret = s2io_test_msi(sp); | ||
| 8027 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
| 8028 | remove_msix_isr(sp); | ||
| 8029 | } | ||
| 8030 | if (ret) { | ||
| 8031 | |||
| 8032 | DBG_PRINT(ERR_DBG, | ||
| 8033 | "%s: MSI-X requested but failed to enable\n", | ||
| 8034 | dev->name); | ||
| 8035 | sp->config.intr_type = INTA; | ||
| 8036 | } | ||
| 8037 | } | ||
| 8038 | |||
| 8039 | if (config->intr_type == MSI_X) { | ||
| 8040 | for (i = 0; i < config->rx_ring_num ; i++) | ||
| 8041 | netif_napi_add(dev, &mac_control->rings[i].napi, | ||
| 8042 | s2io_poll_msix, 64); | ||
| 8043 | } else { | ||
| 8044 | netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64); | ||
| 8045 | } | ||
| 8046 | |||
| 8001 | /* Not needed for Herc */ | 8047 | /* Not needed for Herc */ |
| 8002 | if (sp->device_type & XFRAME_I_DEVICE) { | 8048 | if (sp->device_type & XFRAME_I_DEVICE) { |
| 8003 | /* | 8049 | /* |
| @@ -8048,6 +8094,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 8048 | /* store mac addresses from CAM to s2io_nic structure */ | 8094 | /* store mac addresses from CAM to s2io_nic structure */ |
| 8049 | do_s2io_store_unicast_mc(sp); | 8095 | do_s2io_store_unicast_mc(sp); |
| 8050 | 8096 | ||
| 8097 | /* Configure MSIX vector for number of rings configured plus one */ | ||
| 8098 | if ((sp->device_type == XFRAME_II_DEVICE) && | ||
| 8099 | (config->intr_type == MSI_X)) | ||
| 8100 | sp->num_entries = config->rx_ring_num + 1; | ||
| 8101 | |||
| 8051 | /* Store the values of the MSIX table in the s2io_nic structure */ | 8102 | /* Store the values of the MSIX table in the s2io_nic structure */ |
| 8052 | store_xmsi_data(sp); | 8103 | store_xmsi_data(sp); |
| 8053 | /* reset Nic and bring it to known state */ | 8104 | /* reset Nic and bring it to known state */ |
| @@ -8113,8 +8164,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 8113 | break; | 8164 | break; |
| 8114 | } | 8165 | } |
| 8115 | 8166 | ||
| 8116 | if (napi) | 8167 | switch (sp->config.napi) { |
| 8168 | case 0: | ||
| 8169 | DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name); | ||
| 8170 | break; | ||
| 8171 | case 1: | ||
| 8117 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | 8172 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); |
| 8173 | break; | ||
| 8174 | } | ||
| 8118 | 8175 | ||
| 8119 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, | 8176 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, |
| 8120 | sp->config.tx_fifo_num); | 8177 | sp->config.tx_fifo_num); |
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h index 9a4b772f7411..4706f7f9acb6 100644 --- a/drivers/net/s2io.h +++ b/drivers/net/s2io.h | |||
| @@ -706,7 +706,7 @@ struct ring_info { | |||
| 706 | /* per-ring buffer counter */ | 706 | /* per-ring buffer counter */ |
| 707 | u32 rx_bufs_left; | 707 | u32 rx_bufs_left; |
| 708 | 708 | ||
| 709 | #define MAX_LRO_SESSIONS 32 | 709 | #define MAX_LRO_SESSIONS 32 |
| 710 | struct lro lro0_n[MAX_LRO_SESSIONS]; | 710 | struct lro lro0_n[MAX_LRO_SESSIONS]; |
| 711 | u8 lro; | 711 | u8 lro; |
| 712 | 712 | ||
| @@ -725,6 +725,11 @@ struct ring_info { | |||
| 725 | /* copy of sp->pdev pointer */ | 725 | /* copy of sp->pdev pointer */ |
| 726 | struct pci_dev *pdev; | 726 | struct pci_dev *pdev; |
| 727 | 727 | ||
| 728 | /* Per ring napi struct */ | ||
| 729 | struct napi_struct napi; | ||
| 730 | |||
| 731 | unsigned long interrupt_count; | ||
| 732 | |||
| 728 | /* | 733 | /* |
| 729 | * Place holders for the virtual and physical addresses of | 734 | * Place holders for the virtual and physical addresses of |
| 730 | * all the Rx Blocks | 735 | * all the Rx Blocks |
| @@ -841,7 +846,7 @@ struct usr_addr { | |||
| 841 | * Structure to keep track of the MSI-X vectors and the corresponding | 846 | * Structure to keep track of the MSI-X vectors and the corresponding |
| 842 | * argument registered against each vector | 847 | * argument registered against each vector |
| 843 | */ | 848 | */ |
| 844 | #define MAX_REQUESTED_MSI_X 17 | 849 | #define MAX_REQUESTED_MSI_X 9 |
| 845 | struct s2io_msix_entry | 850 | struct s2io_msix_entry |
| 846 | { | 851 | { |
| 847 | u16 vector; | 852 | u16 vector; |
| @@ -877,7 +882,6 @@ struct s2io_nic { | |||
| 877 | */ | 882 | */ |
| 878 | int pkts_to_process; | 883 | int pkts_to_process; |
| 879 | struct net_device *dev; | 884 | struct net_device *dev; |
| 880 | struct napi_struct napi; | ||
| 881 | struct mac_info mac_control; | 885 | struct mac_info mac_control; |
| 882 | struct config_param config; | 886 | struct config_param config; |
| 883 | struct pci_dev *pdev; | 887 | struct pci_dev *pdev; |
| @@ -948,6 +952,7 @@ struct s2io_nic { | |||
| 948 | */ | 952 | */ |
| 949 | u8 other_fifo_idx; | 953 | u8 other_fifo_idx; |
| 950 | 954 | ||
| 955 | struct napi_struct napi; | ||
| 951 | /* after blink, the adapter must be restored with original | 956 | /* after blink, the adapter must be restored with original |
| 952 | * values. | 957 | * values. |
| 953 | */ | 958 | */ |
| @@ -962,6 +967,7 @@ struct s2io_nic { | |||
| 962 | unsigned long long start_time; | 967 | unsigned long long start_time; |
| 963 | struct vlan_group *vlgrp; | 968 | struct vlan_group *vlgrp; |
| 964 | #define MSIX_FLG 0xA5 | 969 | #define MSIX_FLG 0xA5 |
| 970 | int num_entries; | ||
| 965 | struct msix_entry *entries; | 971 | struct msix_entry *entries; |
| 966 | int msi_detected; | 972 | int msi_detected; |
| 967 | wait_queue_head_t msi_wait; | 973 | wait_queue_head_t msi_wait; |
| @@ -1104,7 +1110,7 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev); | |||
| 1104 | static int init_shared_mem(struct s2io_nic *sp); | 1110 | static int init_shared_mem(struct s2io_nic *sp); |
| 1105 | static void free_shared_mem(struct s2io_nic *sp); | 1111 | static void free_shared_mem(struct s2io_nic *sp); |
| 1106 | static int init_nic(struct s2io_nic *nic); | 1112 | static int init_nic(struct s2io_nic *nic); |
| 1107 | static void rx_intr_handler(struct ring_info *ring_data); | 1113 | static int rx_intr_handler(struct ring_info *ring_data, int budget); |
| 1108 | static void tx_intr_handler(struct fifo_info *fifo_data); | 1114 | static void tx_intr_handler(struct fifo_info *fifo_data); |
| 1109 | static void s2io_handle_errors(void * dev_id); | 1115 | static void s2io_handle_errors(void * dev_id); |
| 1110 | 1116 | ||
| @@ -1115,7 +1121,8 @@ static void s2io_set_multicast(struct net_device *dev); | |||
| 1115 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); | 1121 | static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); |
| 1116 | static void s2io_link(struct s2io_nic * sp, int link); | 1122 | static void s2io_link(struct s2io_nic * sp, int link); |
| 1117 | static void s2io_reset(struct s2io_nic * sp); | 1123 | static void s2io_reset(struct s2io_nic * sp); |
| 1118 | static int s2io_poll(struct napi_struct *napi, int budget); | 1124 | static int s2io_poll_msix(struct napi_struct *napi, int budget); |
| 1125 | static int s2io_poll_inta(struct napi_struct *napi, int budget); | ||
| 1119 | static void s2io_init_pci(struct s2io_nic * sp); | 1126 | static void s2io_init_pci(struct s2io_nic * sp); |
| 1120 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); | 1127 | static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); |
| 1121 | static void s2io_alarm_handle(unsigned long data); | 1128 | static void s2io_alarm_handle(unsigned long data); |
