aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorSreenivasa Honnur <Sreenivasa.Honnur@neterion.com>2008-05-12 13:42:17 -0400
committerJeff Garzik <jgarzik@redhat.com>2008-05-22 06:26:21 -0400
commitf61e0a3544be2f615a0af4aec71eb85a96bdbd62 (patch)
treecc4bf4924c62327bb95f16968fb20286011667d8 /drivers
parentac731ab66960547c33a4e2c504419389ae747067 (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>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/s2io-regs.h2
-rw-r--r--drivers/net/s2io.c327
-rw-r--r--drivers/net/s2io.h17
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
2835static 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
2848static int s2io_poll(struct napi_struct *napi, int budget) 2857static 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}
2889static 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
2890no_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 */
2966static void rx_intr_handler(struct ring_info *ring_data) 2991static 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
4346static 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
4355static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) 4356static 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
845struct s2io_msix_entry 850struct 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);
1104static int init_shared_mem(struct s2io_nic *sp); 1110static int init_shared_mem(struct s2io_nic *sp);
1105static void free_shared_mem(struct s2io_nic *sp); 1111static void free_shared_mem(struct s2io_nic *sp);
1106static int init_nic(struct s2io_nic *nic); 1112static int init_nic(struct s2io_nic *nic);
1107static void rx_intr_handler(struct ring_info *ring_data); 1113static int rx_intr_handler(struct ring_info *ring_data, int budget);
1108static void tx_intr_handler(struct fifo_info *fifo_data); 1114static void tx_intr_handler(struct fifo_info *fifo_data);
1109static void s2io_handle_errors(void * dev_id); 1115static void s2io_handle_errors(void * dev_id);
1110 1116
@@ -1115,7 +1121,8 @@ static void s2io_set_multicast(struct net_device *dev);
1115static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp); 1121static int rx_osm_handler(struct ring_info *ring_data, struct RxD_t * rxdp);
1116static void s2io_link(struct s2io_nic * sp, int link); 1122static void s2io_link(struct s2io_nic * sp, int link);
1117static void s2io_reset(struct s2io_nic * sp); 1123static void s2io_reset(struct s2io_nic * sp);
1118static int s2io_poll(struct napi_struct *napi, int budget); 1124static int s2io_poll_msix(struct napi_struct *napi, int budget);
1125static int s2io_poll_inta(struct napi_struct *napi, int budget);
1119static void s2io_init_pci(struct s2io_nic * sp); 1126static void s2io_init_pci(struct s2io_nic * sp);
1120static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr); 1127static int do_s2io_prog_unicast(struct net_device *dev, u8 *addr);
1121static void s2io_alarm_handle(unsigned long data); 1128static void s2io_alarm_handle(unsigned long data);