diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 531 |
1 files changed, 307 insertions, 224 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 523478ebfd69..ae7b697456b4 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.23" | 89 | #define DRV_VERSION "2.0.26.24" |
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"; |
@@ -1113,9 +1113,10 @@ static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) | |||
1113 | struct pci_dev *tdev = NULL; | 1113 | struct pci_dev *tdev = NULL; |
1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { | 1114 | while ((tdev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { |
1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { | 1115 | if (tdev->vendor == NEC_VENID && tdev->device == NEC_DEVID) { |
1116 | if (tdev->bus == s2io_pdev->bus->parent) | 1116 | if (tdev->bus == s2io_pdev->bus->parent) { |
1117 | pci_dev_put(tdev); | 1117 | pci_dev_put(tdev); |
1118 | return 1; | 1118 | return 1; |
1119 | } | ||
1119 | } | 1120 | } |
1120 | } | 1121 | } |
1121 | return 0; | 1122 | return 0; |
@@ -1219,15 +1220,33 @@ static int init_tti(struct s2io_nic *nic, int link) | |||
1219 | TTI_DATA1_MEM_TX_URNG_B(0x10) | | 1220 | TTI_DATA1_MEM_TX_URNG_B(0x10) | |
1220 | TTI_DATA1_MEM_TX_URNG_C(0x30) | | 1221 | TTI_DATA1_MEM_TX_URNG_C(0x30) | |
1221 | TTI_DATA1_MEM_TX_TIMER_AC_EN; | 1222 | TTI_DATA1_MEM_TX_TIMER_AC_EN; |
1222 | 1223 | if (i == 0) | |
1223 | if (use_continuous_tx_intrs && (link == LINK_UP)) | 1224 | if (use_continuous_tx_intrs && (link == LINK_UP)) |
1224 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; | 1225 | val64 |= TTI_DATA1_MEM_TX_TIMER_CI_EN; |
1225 | writeq(val64, &bar0->tti_data1_mem); | 1226 | writeq(val64, &bar0->tti_data1_mem); |
1226 | 1227 | ||
1227 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | 1228 | if (nic->config.intr_type == MSI_X) { |
1228 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | 1229 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | |
1229 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | 1230 | TTI_DATA2_MEM_TX_UFC_B(0x100) | |
1230 | TTI_DATA2_MEM_TX_UFC_D(0x80); | 1231 | TTI_DATA2_MEM_TX_UFC_C(0x200) | |
1232 | TTI_DATA2_MEM_TX_UFC_D(0x300); | ||
1233 | } else { | ||
1234 | if ((nic->config.tx_steering_type == | ||
1235 | TX_DEFAULT_STEERING) && | ||
1236 | (config->tx_fifo_num > 1) && | ||
1237 | (i >= nic->udp_fifo_idx) && | ||
1238 | (i < (nic->udp_fifo_idx + | ||
1239 | nic->total_udp_fifos))) | ||
1240 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x50) | | ||
1241 | TTI_DATA2_MEM_TX_UFC_B(0x80) | | ||
1242 | TTI_DATA2_MEM_TX_UFC_C(0x100) | | ||
1243 | TTI_DATA2_MEM_TX_UFC_D(0x120); | ||
1244 | else | ||
1245 | val64 = TTI_DATA2_MEM_TX_UFC_A(0x10) | | ||
1246 | TTI_DATA2_MEM_TX_UFC_B(0x20) | | ||
1247 | TTI_DATA2_MEM_TX_UFC_C(0x40) | | ||
1248 | TTI_DATA2_MEM_TX_UFC_D(0x80); | ||
1249 | } | ||
1231 | 1250 | ||
1232 | writeq(val64, &bar0->tti_data2_mem); | 1251 | writeq(val64, &bar0->tti_data2_mem); |
1233 | 1252 | ||
@@ -2606,9 +2625,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2606 | rxdp1->Buffer0_ptr = pci_map_single | 2625 | rxdp1->Buffer0_ptr = pci_map_single |
2607 | (ring->pdev, skb->data, size - NET_IP_ALIGN, | 2626 | (ring->pdev, skb->data, size - NET_IP_ALIGN, |
2608 | PCI_DMA_FROMDEVICE); | 2627 | PCI_DMA_FROMDEVICE); |
2609 | if( (rxdp1->Buffer0_ptr == 0) || | 2628 | if(pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
2610 | (rxdp1->Buffer0_ptr == | ||
2611 | DMA_ERROR_CODE)) | ||
2612 | goto pci_map_failed; | 2629 | goto pci_map_failed; |
2613 | 2630 | ||
2614 | rxdp->Control_2 = | 2631 | rxdp->Control_2 = |
@@ -2638,6 +2655,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2638 | skb->data = (void *) (unsigned long)tmp; | 2655 | skb->data = (void *) (unsigned long)tmp; |
2639 | skb_reset_tail_pointer(skb); | 2656 | skb_reset_tail_pointer(skb); |
2640 | 2657 | ||
2658 | /* AK: check is wrong. 0 can be valid dma address */ | ||
2641 | if (!(rxdp3->Buffer0_ptr)) | 2659 | if (!(rxdp3->Buffer0_ptr)) |
2642 | rxdp3->Buffer0_ptr = | 2660 | rxdp3->Buffer0_ptr = |
2643 | pci_map_single(ring->pdev, ba->ba_0, | 2661 | pci_map_single(ring->pdev, ba->ba_0, |
@@ -2646,8 +2664,7 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2646 | pci_dma_sync_single_for_device(ring->pdev, | 2664 | pci_dma_sync_single_for_device(ring->pdev, |
2647 | (dma_addr_t) rxdp3->Buffer0_ptr, | 2665 | (dma_addr_t) rxdp3->Buffer0_ptr, |
2648 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 2666 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
2649 | if( (rxdp3->Buffer0_ptr == 0) || | 2667 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) |
2650 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) | ||
2651 | goto pci_map_failed; | 2668 | goto pci_map_failed; |
2652 | 2669 | ||
2653 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | 2670 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); |
@@ -2662,18 +2679,17 @@ static int fill_rx_buffers(struct ring_info *ring) | |||
2662 | (ring->pdev, skb->data, ring->mtu + 4, | 2679 | (ring->pdev, skb->data, ring->mtu + 4, |
2663 | PCI_DMA_FROMDEVICE); | 2680 | PCI_DMA_FROMDEVICE); |
2664 | 2681 | ||
2665 | if( (rxdp3->Buffer2_ptr == 0) || | 2682 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
2666 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) | ||
2667 | goto pci_map_failed; | 2683 | goto pci_map_failed; |
2668 | 2684 | ||
2685 | /* AK: check is wrong */ | ||
2669 | if (!rxdp3->Buffer1_ptr) | 2686 | if (!rxdp3->Buffer1_ptr) |
2670 | rxdp3->Buffer1_ptr = | 2687 | rxdp3->Buffer1_ptr = |
2671 | pci_map_single(ring->pdev, | 2688 | pci_map_single(ring->pdev, |
2672 | ba->ba_1, BUF1_LEN, | 2689 | ba->ba_1, BUF1_LEN, |
2673 | PCI_DMA_FROMDEVICE); | 2690 | PCI_DMA_FROMDEVICE); |
2674 | 2691 | ||
2675 | if( (rxdp3->Buffer1_ptr == 0) || | 2692 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
2676 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
2677 | pci_unmap_single | 2693 | pci_unmap_single |
2678 | (ring->pdev, | 2694 | (ring->pdev, |
2679 | (dma_addr_t)(unsigned long) | 2695 | (dma_addr_t)(unsigned long) |
@@ -2813,6 +2829,15 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2813 | } | 2829 | } |
2814 | } | 2830 | } |
2815 | 2831 | ||
2832 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
2833 | { | ||
2834 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
2835 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
2836 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
2837 | } | ||
2838 | return 0; | ||
2839 | } | ||
2840 | |||
2816 | /** | 2841 | /** |
2817 | * s2io_poll - Rx interrupt handler for NAPI support | 2842 | * s2io_poll - Rx interrupt handler for NAPI support |
2818 | * @napi : pointer to the napi structure. | 2843 | * @napi : pointer to the napi structure. |
@@ -2826,57 +2851,73 @@ static void free_rx_buffers(struct s2io_nic *sp) | |||
2826 | * 0 on success and 1 if there are No Rx packets to be processed. | 2851 | * 0 on success and 1 if there are No Rx packets to be processed. |
2827 | */ | 2852 | */ |
2828 | 2853 | ||
2829 | static int s2io_poll(struct napi_struct *napi, int budget) | 2854 | static int s2io_poll_msix(struct napi_struct *napi, int budget) |
2830 | { | 2855 | { |
2831 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | 2856 | struct ring_info *ring = container_of(napi, struct ring_info, napi); |
2832 | struct net_device *dev = nic->dev; | 2857 | struct net_device *dev = ring->dev; |
2833 | int pkt_cnt = 0, org_pkts_to_process; | ||
2834 | struct mac_info *mac_control; | ||
2835 | struct config_param *config; | 2858 | struct config_param *config; |
2859 | struct mac_info *mac_control; | ||
2860 | int pkts_processed = 0; | ||
2861 | u8 __iomem *addr = NULL; | ||
2862 | u8 val8 = 0; | ||
2863 | struct s2io_nic *nic = dev->priv; | ||
2836 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 2864 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
2837 | int i; | 2865 | int budget_org = budget; |
2838 | 2866 | ||
2839 | mac_control = &nic->mac_control; | ||
2840 | config = &nic->config; | 2867 | config = &nic->config; |
2868 | mac_control = &nic->mac_control; | ||
2841 | 2869 | ||
2842 | nic->pkts_to_process = budget; | 2870 | if (unlikely(!is_s2io_card_up(nic))) |
2843 | org_pkts_to_process = nic->pkts_to_process; | 2871 | return 0; |
2844 | 2872 | ||
2845 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 2873 | pkts_processed = rx_intr_handler(ring, budget); |
2846 | readl(&bar0->rx_traffic_int); | 2874 | s2io_chk_rx_buffers(ring); |
2847 | 2875 | ||
2848 | for (i = 0; i < config->rx_ring_num; i++) { | 2876 | if (pkts_processed < budget_org) { |
2849 | rx_intr_handler(&mac_control->rings[i]); | 2877 | netif_rx_complete(dev, napi); |
2850 | pkt_cnt = org_pkts_to_process - nic->pkts_to_process; | 2878 | /*Re Enable MSI-Rx Vector*/ |
2851 | if (!nic->pkts_to_process) { | 2879 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; |
2852 | /* Quota for the current iteration has been met */ | 2880 | addr += 7 - ring->ring_no; |
2853 | goto no_rx; | 2881 | val8 = (ring->ring_no == 0) ? 0x3f : 0xbf; |
2854 | } | 2882 | writeb(val8, addr); |
2883 | val8 = readb(addr); | ||
2855 | } | 2884 | } |
2885 | return pkts_processed; | ||
2886 | } | ||
2887 | static int s2io_poll_inta(struct napi_struct *napi, int budget) | ||
2888 | { | ||
2889 | struct s2io_nic *nic = container_of(napi, struct s2io_nic, napi); | ||
2890 | struct ring_info *ring; | ||
2891 | struct net_device *dev = nic->dev; | ||
2892 | struct config_param *config; | ||
2893 | struct mac_info *mac_control; | ||
2894 | int pkts_processed = 0; | ||
2895 | int ring_pkts_processed, i; | ||
2896 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | ||
2897 | int budget_org = budget; | ||
2856 | 2898 | ||
2857 | netif_rx_complete(dev, napi); | 2899 | config = &nic->config; |
2900 | mac_control = &nic->mac_control; | ||
2858 | 2901 | ||
2859 | for (i = 0; i < config->rx_ring_num; i++) { | 2902 | if (unlikely(!is_s2io_card_up(nic))) |
2860 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2903 | return 0; |
2861 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | ||
2862 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | ||
2863 | break; | ||
2864 | } | ||
2865 | } | ||
2866 | /* Re enable the Rx interrupts. */ | ||
2867 | writeq(0x0, &bar0->rx_traffic_mask); | ||
2868 | readl(&bar0->rx_traffic_mask); | ||
2869 | return pkt_cnt; | ||
2870 | 2904 | ||
2871 | no_rx: | ||
2872 | for (i = 0; i < config->rx_ring_num; i++) { | 2905 | for (i = 0; i < config->rx_ring_num; i++) { |
2873 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2906 | ring = &mac_control->rings[i]; |
2874 | DBG_PRINT(INFO_DBG, "%s:Out of memory", dev->name); | 2907 | ring_pkts_processed = rx_intr_handler(ring, budget); |
2875 | DBG_PRINT(INFO_DBG, " in Rx Poll!!\n"); | 2908 | s2io_chk_rx_buffers(ring); |
2909 | pkts_processed += ring_pkts_processed; | ||
2910 | budget -= ring_pkts_processed; | ||
2911 | if (budget <= 0) | ||
2876 | break; | 2912 | break; |
2877 | } | ||
2878 | } | 2913 | } |
2879 | return pkt_cnt; | 2914 | if (pkts_processed < budget_org) { |
2915 | netif_rx_complete(dev, napi); | ||
2916 | /* Re enable the Rx interrupts for the ring */ | ||
2917 | writeq(0, &bar0->rx_traffic_mask); | ||
2918 | readl(&bar0->rx_traffic_mask); | ||
2919 | } | ||
2920 | return pkts_processed; | ||
2880 | } | 2921 | } |
2881 | 2922 | ||
2882 | #ifdef CONFIG_NET_POLL_CONTROLLER | 2923 | #ifdef CONFIG_NET_POLL_CONTROLLER |
@@ -2918,7 +2959,7 @@ static void s2io_netpoll(struct net_device *dev) | |||
2918 | 2959 | ||
2919 | /* check for received packet and indicate up to network */ | 2960 | /* check for received packet and indicate up to network */ |
2920 | for (i = 0; i < config->rx_ring_num; i++) | 2961 | for (i = 0; i < config->rx_ring_num; i++) |
2921 | rx_intr_handler(&mac_control->rings[i]); | 2962 | rx_intr_handler(&mac_control->rings[i], 0); |
2922 | 2963 | ||
2923 | for (i = 0; i < config->rx_ring_num; i++) { | 2964 | for (i = 0; i < config->rx_ring_num; i++) { |
2924 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { | 2965 | if (fill_rx_buffers(&mac_control->rings[i]) == -ENOMEM) { |
@@ -2934,7 +2975,8 @@ static void s2io_netpoll(struct net_device *dev) | |||
2934 | 2975 | ||
2935 | /** | 2976 | /** |
2936 | * rx_intr_handler - Rx interrupt handler | 2977 | * rx_intr_handler - Rx interrupt handler |
2937 | * @nic: device private variable. | 2978 | * @ring_info: per ring structure. |
2979 | * @budget: budget for napi processing. | ||
2938 | * Description: | 2980 | * Description: |
2939 | * If the interrupt is because of a received frame or if the | 2981 | * If the interrupt is because of a received frame or if the |
2940 | * receive ring contains fresh as yet un-processed frames,this function is | 2982 | * receive ring contains fresh as yet un-processed frames,this function is |
@@ -2942,15 +2984,15 @@ static void s2io_netpoll(struct net_device *dev) | |||
2942 | * stopped and sends the skb to the OSM's Rx handler and then increments | 2984 | * stopped and sends the skb to the OSM's Rx handler and then increments |
2943 | * the offset. | 2985 | * the offset. |
2944 | * Return Value: | 2986 | * Return Value: |
2945 | * NONE. | 2987 | * No. of napi packets processed. |
2946 | */ | 2988 | */ |
2947 | static void rx_intr_handler(struct ring_info *ring_data) | 2989 | static int rx_intr_handler(struct ring_info *ring_data, int budget) |
2948 | { | 2990 | { |
2949 | int get_block, put_block; | 2991 | int get_block, put_block; |
2950 | struct rx_curr_get_info get_info, put_info; | 2992 | struct rx_curr_get_info get_info, put_info; |
2951 | struct RxD_t *rxdp; | 2993 | struct RxD_t *rxdp; |
2952 | struct sk_buff *skb; | 2994 | struct sk_buff *skb; |
2953 | int pkt_cnt = 0; | 2995 | int pkt_cnt = 0, napi_pkts = 0; |
2954 | int i; | 2996 | int i; |
2955 | struct RxD1* rxdp1; | 2997 | struct RxD1* rxdp1; |
2956 | struct RxD3* rxdp3; | 2998 | struct RxD3* rxdp3; |
@@ -2977,7 +3019,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
2977 | DBG_PRINT(ERR_DBG, "%s: The skb is ", | 3019 | DBG_PRINT(ERR_DBG, "%s: The skb is ", |
2978 | ring_data->dev->name); | 3020 | ring_data->dev->name); |
2979 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); | 3021 | DBG_PRINT(ERR_DBG, "Null in Rx Intr\n"); |
2980 | return; | 3022 | return 0; |
2981 | } | 3023 | } |
2982 | if (ring_data->rxd_mode == RXD_MODE_1) { | 3024 | if (ring_data->rxd_mode == RXD_MODE_1) { |
2983 | rxdp1 = (struct RxD1*)rxdp; | 3025 | rxdp1 = (struct RxD1*)rxdp; |
@@ -3014,9 +3056,10 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3014 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; | 3056 | rxdp = ring_data->rx_blocks[get_block].block_virt_addr; |
3015 | } | 3057 | } |
3016 | 3058 | ||
3017 | if(ring_data->nic->config.napi){ | 3059 | if (ring_data->nic->config.napi) { |
3018 | ring_data->nic->pkts_to_process -= 1; | 3060 | budget--; |
3019 | if (!ring_data->nic->pkts_to_process) | 3061 | napi_pkts++; |
3062 | if (!budget) | ||
3020 | break; | 3063 | break; |
3021 | } | 3064 | } |
3022 | pkt_cnt++; | 3065 | pkt_cnt++; |
@@ -3034,6 +3077,7 @@ static void rx_intr_handler(struct ring_info *ring_data) | |||
3034 | } | 3077 | } |
3035 | } | 3078 | } |
3036 | } | 3079 | } |
3080 | return(napi_pkts); | ||
3037 | } | 3081 | } |
3038 | 3082 | ||
3039 | /** | 3083 | /** |
@@ -3730,14 +3774,19 @@ static void restore_xmsi_data(struct s2io_nic *nic) | |||
3730 | { | 3774 | { |
3731 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3775 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3732 | u64 val64; | 3776 | u64 val64; |
3733 | int i; | 3777 | int i, msix_index; |
3778 | |||
3779 | |||
3780 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3781 | return; | ||
3734 | 3782 | ||
3735 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3783 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3784 | msix_index = (i) ? ((i-1) * 8 + 1): 0; | ||
3736 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3785 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
3737 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3786 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
3738 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(i, 26, 6)); | 3787 | val64 = (s2BIT(7) | s2BIT(15) | vBIT(msix_index, 26, 6)); |
3739 | writeq(val64, &bar0->xmsi_access); | 3788 | writeq(val64, &bar0->xmsi_access); |
3740 | if (wait_for_msix_trans(nic, i)) { | 3789 | if (wait_for_msix_trans(nic, msix_index)) { |
3741 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3790 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3742 | continue; | 3791 | continue; |
3743 | } | 3792 | } |
@@ -3748,13 +3797,17 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3748 | { | 3797 | { |
3749 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3798 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3750 | u64 val64, addr, data; | 3799 | u64 val64, addr, data; |
3751 | int i; | 3800 | int i, msix_index; |
3801 | |||
3802 | if (nic->device_type == XFRAME_I_DEVICE) | ||
3803 | return; | ||
3752 | 3804 | ||
3753 | /* Store and display */ | 3805 | /* Store and display */ |
3754 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { | 3806 | for (i=0; i < MAX_REQUESTED_MSI_X; i++) { |
3755 | val64 = (s2BIT(15) | vBIT(i, 26, 6)); | 3807 | msix_index = (i) ? ((i-1) * 8 + 1): 0; |
3808 | val64 = (s2BIT(15) | vBIT(msix_index, 26, 6)); | ||
3756 | writeq(val64, &bar0->xmsi_access); | 3809 | writeq(val64, &bar0->xmsi_access); |
3757 | if (wait_for_msix_trans(nic, i)) { | 3810 | if (wait_for_msix_trans(nic, msix_index)) { |
3758 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | 3811 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); |
3759 | continue; | 3812 | continue; |
3760 | } | 3813 | } |
@@ -3770,11 +3823,11 @@ static void store_xmsi_data(struct s2io_nic *nic) | |||
3770 | static int s2io_enable_msi_x(struct s2io_nic *nic) | 3823 | static int s2io_enable_msi_x(struct s2io_nic *nic) |
3771 | { | 3824 | { |
3772 | struct XENA_dev_config __iomem *bar0 = nic->bar0; | 3825 | struct XENA_dev_config __iomem *bar0 = nic->bar0; |
3773 | u64 tx_mat, rx_mat; | 3826 | u64 rx_mat; |
3774 | u16 msi_control; /* Temp variable */ | 3827 | u16 msi_control; /* Temp variable */ |
3775 | int ret, i, j, msix_indx = 1; | 3828 | int ret, i, j, msix_indx = 1; |
3776 | 3829 | ||
3777 | nic->entries = kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct msix_entry), | 3830 | nic->entries = kmalloc(nic->num_entries * sizeof(struct msix_entry), |
3778 | GFP_KERNEL); | 3831 | GFP_KERNEL); |
3779 | if (!nic->entries) { | 3832 | if (!nic->entries) { |
3780 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ | 3833 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", \ |
@@ -3783,10 +3836,12 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3783 | return -ENOMEM; | 3836 | return -ENOMEM; |
3784 | } | 3837 | } |
3785 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3838 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3786 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3839 | += (nic->num_entries * sizeof(struct msix_entry)); |
3840 | |||
3841 | memset(nic->entries, 0, nic->num_entries * sizeof(struct msix_entry)); | ||
3787 | 3842 | ||
3788 | nic->s2io_entries = | 3843 | nic->s2io_entries = |
3789 | kcalloc(MAX_REQUESTED_MSI_X, sizeof(struct s2io_msix_entry), | 3844 | kmalloc(nic->num_entries * sizeof(struct s2io_msix_entry), |
3790 | GFP_KERNEL); | 3845 | GFP_KERNEL); |
3791 | if (!nic->s2io_entries) { | 3846 | if (!nic->s2io_entries) { |
3792 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", | 3847 | DBG_PRINT(INFO_DBG, "%s: Memory allocation failed\n", |
@@ -3794,60 +3849,52 @@ static int s2io_enable_msi_x(struct s2io_nic *nic) | |||
3794 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; | 3849 | nic->mac_control.stats_info->sw_stat.mem_alloc_fail_cnt++; |
3795 | kfree(nic->entries); | 3850 | kfree(nic->entries); |
3796 | nic->mac_control.stats_info->sw_stat.mem_freed | 3851 | nic->mac_control.stats_info->sw_stat.mem_freed |
3797 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3852 | += (nic->num_entries * sizeof(struct msix_entry)); |
3798 | return -ENOMEM; | 3853 | return -ENOMEM; |
3799 | } | 3854 | } |
3800 | nic->mac_control.stats_info->sw_stat.mem_allocated | 3855 | nic->mac_control.stats_info->sw_stat.mem_allocated |
3801 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3856 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3802 | 3857 | memset(nic->s2io_entries, 0, | |
3803 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3858 | nic->num_entries * sizeof(struct s2io_msix_entry)); |
3804 | nic->entries[i].entry = i; | 3859 | |
3805 | nic->s2io_entries[i].entry = i; | 3860 | nic->entries[0].entry = 0; |
3861 | nic->s2io_entries[0].entry = 0; | ||
3862 | nic->s2io_entries[0].in_use = MSIX_FLG; | ||
3863 | nic->s2io_entries[0].type = MSIX_ALARM_TYPE; | ||
3864 | nic->s2io_entries[0].arg = &nic->mac_control.fifos; | ||
3865 | |||
3866 | for (i = 1; i < nic->num_entries; i++) { | ||
3867 | nic->entries[i].entry = ((i - 1) * 8) + 1; | ||
3868 | nic->s2io_entries[i].entry = ((i - 1) * 8) + 1; | ||
3806 | nic->s2io_entries[i].arg = NULL; | 3869 | nic->s2io_entries[i].arg = NULL; |
3807 | nic->s2io_entries[i].in_use = 0; | 3870 | nic->s2io_entries[i].in_use = 0; |
3808 | } | 3871 | } |
3809 | 3872 | ||
3810 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3811 | for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { | ||
3812 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3813 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; | ||
3814 | nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; | ||
3815 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3816 | } | ||
3817 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3818 | |||
3819 | rx_mat = readq(&bar0->rx_mat); | 3873 | rx_mat = readq(&bar0->rx_mat); |
3820 | for (j = 0; j < nic->config.rx_ring_num; j++, msix_indx++) { | 3874 | for (j = 0; j < nic->config.rx_ring_num; j++) { |
3821 | rx_mat |= RX_MAT_SET(j, msix_indx); | 3875 | rx_mat |= RX_MAT_SET(j, msix_indx); |
3822 | nic->s2io_entries[msix_indx].arg | 3876 | nic->s2io_entries[j+1].arg = &nic->mac_control.rings[j]; |
3823 | = &nic->mac_control.rings[j]; | 3877 | nic->s2io_entries[j+1].type = MSIX_RING_TYPE; |
3824 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | 3878 | nic->s2io_entries[j+1].in_use = MSIX_FLG; |
3825 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | 3879 | msix_indx += 8; |
3826 | } | 3880 | } |
3827 | writeq(rx_mat, &bar0->rx_mat); | 3881 | writeq(rx_mat, &bar0->rx_mat); |
3882 | readq(&bar0->rx_mat); | ||
3828 | 3883 | ||
3829 | nic->avail_msix_vectors = 0; | 3884 | ret = pci_enable_msix(nic->pdev, nic->entries, nic->num_entries); |
3830 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | ||
3831 | /* We fail init if error or we get less vectors than min required */ | 3885 | /* We fail init if error or we get less vectors than min required */ |
3832 | if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { | ||
3833 | nic->avail_msix_vectors = ret; | ||
3834 | ret = pci_enable_msix(nic->pdev, nic->entries, ret); | ||
3835 | } | ||
3836 | if (ret) { | 3886 | if (ret) { |
3837 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | 3887 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); |
3838 | kfree(nic->entries); | 3888 | kfree(nic->entries); |
3839 | nic->mac_control.stats_info->sw_stat.mem_freed | 3889 | nic->mac_control.stats_info->sw_stat.mem_freed |
3840 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 3890 | += (nic->num_entries * sizeof(struct msix_entry)); |
3841 | kfree(nic->s2io_entries); | 3891 | kfree(nic->s2io_entries); |
3842 | nic->mac_control.stats_info->sw_stat.mem_freed | 3892 | nic->mac_control.stats_info->sw_stat.mem_freed |
3843 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 3893 | += (nic->num_entries * sizeof(struct s2io_msix_entry)); |
3844 | nic->entries = NULL; | 3894 | nic->entries = NULL; |
3845 | nic->s2io_entries = NULL; | 3895 | nic->s2io_entries = NULL; |
3846 | nic->avail_msix_vectors = 0; | ||
3847 | return -ENOMEM; | 3896 | return -ENOMEM; |
3848 | } | 3897 | } |
3849 | if (!nic->avail_msix_vectors) | ||
3850 | nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; | ||
3851 | 3898 | ||
3852 | /* | 3899 | /* |
3853 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | 3900 | * To enable MSI-X, MSI also needs to be enabled, due to a bug |
@@ -3919,7 +3966,7 @@ static void remove_msix_isr(struct s2io_nic *sp) | |||
3919 | int i; | 3966 | int i; |
3920 | u16 msi_control; | 3967 | u16 msi_control; |
3921 | 3968 | ||
3922 | for (i = 0; i < MAX_REQUESTED_MSI_X; i++) { | 3969 | for (i = 0; i < sp->num_entries; i++) { |
3923 | if (sp->s2io_entries[i].in_use == | 3970 | if (sp->s2io_entries[i].in_use == |
3924 | MSIX_REGISTERED_SUCCESS) { | 3971 | MSIX_REGISTERED_SUCCESS) { |
3925 | int vector = sp->entries[i].vector; | 3972 | int vector = sp->entries[i].vector; |
@@ -3975,29 +4022,6 @@ static int s2io_open(struct net_device *dev) | |||
3975 | netif_carrier_off(dev); | 4022 | netif_carrier_off(dev); |
3976 | sp->last_link_state = 0; | 4023 | sp->last_link_state = 0; |
3977 | 4024 | ||
3978 | if (sp->config.intr_type == MSI_X) { | ||
3979 | int ret = s2io_enable_msi_x(sp); | ||
3980 | |||
3981 | if (!ret) { | ||
3982 | ret = s2io_test_msi(sp); | ||
3983 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
3984 | remove_msix_isr(sp); | ||
3985 | } | ||
3986 | if (ret) { | ||
3987 | |||
3988 | DBG_PRINT(ERR_DBG, | ||
3989 | "%s: MSI-X requested but failed to enable\n", | ||
3990 | dev->name); | ||
3991 | sp->config.intr_type = INTA; | ||
3992 | } | ||
3993 | } | ||
3994 | |||
3995 | /* NAPI doesn't work well with MSI(X) */ | ||
3996 | if (sp->config.intr_type != INTA) { | ||
3997 | if(sp->config.napi) | ||
3998 | sp->config.napi = 0; | ||
3999 | } | ||
4000 | |||
4001 | /* Initialize H/W and enable interrupts */ | 4025 | /* Initialize H/W and enable interrupts */ |
4002 | err = s2io_card_up(sp); | 4026 | err = s2io_card_up(sp); |
4003 | if (err) { | 4027 | if (err) { |
@@ -4020,12 +4044,12 @@ hw_init_failed: | |||
4020 | if (sp->entries) { | 4044 | if (sp->entries) { |
4021 | kfree(sp->entries); | 4045 | kfree(sp->entries); |
4022 | sp->mac_control.stats_info->sw_stat.mem_freed | 4046 | sp->mac_control.stats_info->sw_stat.mem_freed |
4023 | += (MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | 4047 | += (sp->num_entries * sizeof(struct msix_entry)); |
4024 | } | 4048 | } |
4025 | if (sp->s2io_entries) { | 4049 | if (sp->s2io_entries) { |
4026 | kfree(sp->s2io_entries); | 4050 | kfree(sp->s2io_entries); |
4027 | sp->mac_control.stats_info->sw_stat.mem_freed | 4051 | sp->mac_control.stats_info->sw_stat.mem_freed |
4028 | += (MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | 4052 | += (sp->num_entries * sizeof(struct s2io_msix_entry)); |
4029 | } | 4053 | } |
4030 | } | 4054 | } |
4031 | return err; | 4055 | return err; |
@@ -4237,16 +4261,14 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
4237 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, | 4261 | txdp->Buffer_Pointer = pci_map_single(sp->pdev, |
4238 | fifo->ufo_in_band_v, | 4262 | fifo->ufo_in_band_v, |
4239 | sizeof(u64), PCI_DMA_TODEVICE); | 4263 | sizeof(u64), PCI_DMA_TODEVICE); |
4240 | if((txdp->Buffer_Pointer == 0) || | 4264 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4241 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4242 | goto pci_map_failed; | 4265 | goto pci_map_failed; |
4243 | txdp++; | 4266 | txdp++; |
4244 | } | 4267 | } |
4245 | 4268 | ||
4246 | txdp->Buffer_Pointer = pci_map_single | 4269 | txdp->Buffer_Pointer = pci_map_single |
4247 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); | 4270 | (sp->pdev, skb->data, frg_len, PCI_DMA_TODEVICE); |
4248 | if((txdp->Buffer_Pointer == 0) || | 4271 | if (pci_dma_mapping_error(txdp->Buffer_Pointer)) |
4249 | (txdp->Buffer_Pointer == DMA_ERROR_CODE)) | ||
4250 | goto pci_map_failed; | 4272 | goto pci_map_failed; |
4251 | 4273 | ||
4252 | txdp->Host_Control = (unsigned long) skb; | 4274 | txdp->Host_Control = (unsigned long) skb; |
@@ -4327,40 +4349,65 @@ s2io_alarm_handle(unsigned long data) | |||
4327 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 4349 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
4328 | } | 4350 | } |
4329 | 4351 | ||
4330 | static int s2io_chk_rx_buffers(struct ring_info *ring) | ||
4331 | { | ||
4332 | if (fill_rx_buffers(ring) == -ENOMEM) { | ||
4333 | DBG_PRINT(INFO_DBG, "%s:Out of memory", ring->dev->name); | ||
4334 | DBG_PRINT(INFO_DBG, " in Rx Intr!!\n"); | ||
4335 | } | ||
4336 | return 0; | ||
4337 | } | ||
4338 | |||
4339 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) | 4352 | static irqreturn_t s2io_msix_ring_handle(int irq, void *dev_id) |
4340 | { | 4353 | { |
4341 | struct ring_info *ring = (struct ring_info *)dev_id; | 4354 | struct ring_info *ring = (struct ring_info *)dev_id; |
4342 | struct s2io_nic *sp = ring->nic; | 4355 | struct s2io_nic *sp = ring->nic; |
4356 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4357 | struct net_device *dev = sp->dev; | ||
4343 | 4358 | ||
4344 | if (!is_s2io_card_up(sp)) | 4359 | if (unlikely(!is_s2io_card_up(sp))) |
4345 | return IRQ_HANDLED; | 4360 | return IRQ_HANDLED; |
4346 | 4361 | ||
4347 | rx_intr_handler(ring); | 4362 | if (sp->config.napi) { |
4348 | s2io_chk_rx_buffers(ring); | 4363 | u8 __iomem *addr = NULL; |
4364 | u8 val8 = 0; | ||
4365 | |||
4366 | addr = (u8 __iomem *)&bar0->xmsi_mask_reg; | ||
4367 | addr += (7 - ring->ring_no); | ||
4368 | val8 = (ring->ring_no == 0) ? 0x7f : 0xff; | ||
4369 | writeb(val8, addr); | ||
4370 | val8 = readb(addr); | ||
4371 | netif_rx_schedule(dev, &ring->napi); | ||
4372 | } else { | ||
4373 | rx_intr_handler(ring, 0); | ||
4374 | s2io_chk_rx_buffers(ring); | ||
4375 | } | ||
4349 | 4376 | ||
4350 | return IRQ_HANDLED; | 4377 | return IRQ_HANDLED; |
4351 | } | 4378 | } |
4352 | 4379 | ||
4353 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) | 4380 | static irqreturn_t s2io_msix_fifo_handle(int irq, void *dev_id) |
4354 | { | 4381 | { |
4355 | struct fifo_info *fifo = (struct fifo_info *)dev_id; | 4382 | int i; |
4356 | struct s2io_nic *sp = fifo->nic; | 4383 | struct fifo_info *fifos = (struct fifo_info *)dev_id; |
4384 | struct s2io_nic *sp = fifos->nic; | ||
4385 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | ||
4386 | struct config_param *config = &sp->config; | ||
4387 | u64 reason; | ||
4357 | 4388 | ||
4358 | if (!is_s2io_card_up(sp)) | 4389 | if (unlikely(!is_s2io_card_up(sp))) |
4390 | return IRQ_NONE; | ||
4391 | |||
4392 | reason = readq(&bar0->general_int_status); | ||
4393 | if (unlikely(reason == S2IO_MINUS_ONE)) | ||
4394 | /* Nothing much can be done. Get out */ | ||
4359 | return IRQ_HANDLED; | 4395 | return IRQ_HANDLED; |
4360 | 4396 | ||
4361 | tx_intr_handler(fifo); | 4397 | writeq(S2IO_MINUS_ONE, &bar0->general_int_mask); |
4398 | |||
4399 | if (reason & GEN_INTR_TXTRAFFIC) | ||
4400 | writeq(S2IO_MINUS_ONE, &bar0->tx_traffic_int); | ||
4401 | |||
4402 | for (i = 0; i < config->tx_fifo_num; i++) | ||
4403 | tx_intr_handler(&fifos[i]); | ||
4404 | |||
4405 | writeq(sp->general_int_mask, &bar0->general_int_mask); | ||
4406 | readl(&bar0->general_int_status); | ||
4407 | |||
4362 | return IRQ_HANDLED; | 4408 | return IRQ_HANDLED; |
4363 | } | 4409 | } |
4410 | |||
4364 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) | 4411 | static void s2io_txpic_intr_handle(struct s2io_nic *sp) |
4365 | { | 4412 | { |
4366 | struct XENA_dev_config __iomem *bar0 = sp->bar0; | 4413 | struct XENA_dev_config __iomem *bar0 = sp->bar0; |
@@ -4762,14 +4809,10 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4762 | 4809 | ||
4763 | if (config->napi) { | 4810 | if (config->napi) { |
4764 | if (reason & GEN_INTR_RXTRAFFIC) { | 4811 | if (reason & GEN_INTR_RXTRAFFIC) { |
4765 | if (likely(netif_rx_schedule_prep(dev, | 4812 | netif_rx_schedule(dev, &sp->napi); |
4766 | &sp->napi))) { | 4813 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_mask); |
4767 | __netif_rx_schedule(dev, &sp->napi); | 4814 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4768 | writeq(S2IO_MINUS_ONE, | 4815 | readl(&bar0->rx_traffic_int); |
4769 | &bar0->rx_traffic_mask); | ||
4770 | } else | ||
4771 | writeq(S2IO_MINUS_ONE, | ||
4772 | &bar0->rx_traffic_int); | ||
4773 | } | 4816 | } |
4774 | } else { | 4817 | } else { |
4775 | /* | 4818 | /* |
@@ -4781,7 +4824,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id) | |||
4781 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); | 4824 | writeq(S2IO_MINUS_ONE, &bar0->rx_traffic_int); |
4782 | 4825 | ||
4783 | for (i = 0; i < config->rx_ring_num; i++) | 4826 | for (i = 0; i < config->rx_ring_num; i++) |
4784 | rx_intr_handler(&mac_control->rings[i]); | 4827 | rx_intr_handler(&mac_control->rings[i], 0); |
4785 | } | 4828 | } |
4786 | 4829 | ||
4787 | /* | 4830 | /* |
@@ -6836,10 +6879,8 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6836 | pci_map_single( sp->pdev, (*skb)->data, | 6879 | pci_map_single( sp->pdev, (*skb)->data, |
6837 | size - NET_IP_ALIGN, | 6880 | size - NET_IP_ALIGN, |
6838 | PCI_DMA_FROMDEVICE); | 6881 | PCI_DMA_FROMDEVICE); |
6839 | if( (rxdp1->Buffer0_ptr == 0) || | 6882 | if (pci_dma_mapping_error(rxdp1->Buffer0_ptr)) |
6840 | (rxdp1->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6841 | goto memalloc_failed; | 6883 | goto memalloc_failed; |
6842 | } | ||
6843 | rxdp->Host_Control = (unsigned long) (*skb); | 6884 | rxdp->Host_Control = (unsigned long) (*skb); |
6844 | } | 6885 | } |
6845 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { | 6886 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { |
@@ -6865,15 +6906,12 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6865 | pci_map_single(sp->pdev, (*skb)->data, | 6906 | pci_map_single(sp->pdev, (*skb)->data, |
6866 | dev->mtu + 4, | 6907 | dev->mtu + 4, |
6867 | PCI_DMA_FROMDEVICE); | 6908 | PCI_DMA_FROMDEVICE); |
6868 | if( (rxdp3->Buffer2_ptr == 0) || | 6909 | if (pci_dma_mapping_error(rxdp3->Buffer2_ptr)) |
6869 | (rxdp3->Buffer2_ptr == DMA_ERROR_CODE)) { | ||
6870 | goto memalloc_failed; | 6910 | goto memalloc_failed; |
6871 | } | ||
6872 | rxdp3->Buffer0_ptr = *temp0 = | 6911 | rxdp3->Buffer0_ptr = *temp0 = |
6873 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, | 6912 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, |
6874 | PCI_DMA_FROMDEVICE); | 6913 | PCI_DMA_FROMDEVICE); |
6875 | if( (rxdp3->Buffer0_ptr == 0) || | 6914 | if (pci_dma_mapping_error(rxdp3->Buffer0_ptr)) { |
6876 | (rxdp3->Buffer0_ptr == DMA_ERROR_CODE)) { | ||
6877 | pci_unmap_single (sp->pdev, | 6915 | pci_unmap_single (sp->pdev, |
6878 | (dma_addr_t)rxdp3->Buffer2_ptr, | 6916 | (dma_addr_t)rxdp3->Buffer2_ptr, |
6879 | dev->mtu + 4, PCI_DMA_FROMDEVICE); | 6917 | dev->mtu + 4, PCI_DMA_FROMDEVICE); |
@@ -6885,8 +6923,7 @@ static int set_rxd_buffer_pointer(struct s2io_nic *sp, struct RxD_t *rxdp, | |||
6885 | rxdp3->Buffer1_ptr = *temp1 = | 6923 | rxdp3->Buffer1_ptr = *temp1 = |
6886 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, | 6924 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, |
6887 | PCI_DMA_FROMDEVICE); | 6925 | PCI_DMA_FROMDEVICE); |
6888 | if( (rxdp3->Buffer1_ptr == 0) || | 6926 | if (pci_dma_mapping_error(rxdp3->Buffer1_ptr)) { |
6889 | (rxdp3->Buffer1_ptr == DMA_ERROR_CODE)) { | ||
6890 | pci_unmap_single (sp->pdev, | 6927 | pci_unmap_single (sp->pdev, |
6891 | (dma_addr_t)rxdp3->Buffer0_ptr, | 6928 | (dma_addr_t)rxdp3->Buffer0_ptr, |
6892 | BUF0_LEN, PCI_DMA_FROMDEVICE); | 6929 | BUF0_LEN, PCI_DMA_FROMDEVICE); |
@@ -6984,62 +7021,62 @@ static int s2io_add_isr(struct s2io_nic * sp) | |||
6984 | 7021 | ||
6985 | /* After proper initialization of H/W, register ISR */ | 7022 | /* After proper initialization of H/W, register ISR */ |
6986 | if (sp->config.intr_type == MSI_X) { | 7023 | if (sp->config.intr_type == MSI_X) { |
6987 | int i, msix_tx_cnt=0,msix_rx_cnt=0; | 7024 | int i, msix_rx_cnt = 0; |
6988 | 7025 | ||
6989 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 7026 | for (i = 0; i < sp->num_entries; i++) { |
6990 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | 7027 | if (sp->s2io_entries[i].in_use == MSIX_FLG) { |
6991 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | 7028 | if (sp->s2io_entries[i].type == |
7029 | MSIX_RING_TYPE) { | ||
7030 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | ||
7031 | dev->name, i); | ||
7032 | err = request_irq(sp->entries[i].vector, | ||
7033 | s2io_msix_ring_handle, 0, | ||
7034 | sp->desc[i], | ||
7035 | sp->s2io_entries[i].arg); | ||
7036 | } else if (sp->s2io_entries[i].type == | ||
7037 | MSIX_ALARM_TYPE) { | ||
7038 | sprintf(sp->desc[i], "%s:MSI-X-%d-TX", | ||
6992 | dev->name, i); | 7039 | dev->name, i); |
6993 | err = request_irq(sp->entries[i].vector, | 7040 | err = request_irq(sp->entries[i].vector, |
6994 | s2io_msix_fifo_handle, 0, sp->desc[i], | 7041 | s2io_msix_fifo_handle, 0, |
6995 | sp->s2io_entries[i].arg); | 7042 | sp->desc[i], |
6996 | /* If either data or addr is zero print it */ | 7043 | sp->s2io_entries[i].arg); |
6997 | if(!(sp->msix_info[i].addr && | 7044 | |
6998 | sp->msix_info[i].data)) { | ||
6999 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | ||
7000 | "Data:0x%llx\n",sp->desc[i], | ||
7001 | (unsigned long long) | ||
7002 | sp->msix_info[i].addr, | ||
7003 | (unsigned long long) | ||
7004 | sp->msix_info[i].data); | ||
7005 | } else { | ||
7006 | msix_tx_cnt++; | ||
7007 | } | 7045 | } |
7008 | } else { | 7046 | /* if either data or addr is zero print it. */ |
7009 | sprintf(sp->desc[i], "%s:MSI-X-%d-RX", | 7047 | if (!(sp->msix_info[i].addr && |
7010 | dev->name, i); | ||
7011 | err = request_irq(sp->entries[i].vector, | ||
7012 | s2io_msix_ring_handle, 0, sp->desc[i], | ||
7013 | sp->s2io_entries[i].arg); | ||
7014 | /* If either data or addr is zero print it */ | ||
7015 | if(!(sp->msix_info[i].addr && | ||
7016 | sp->msix_info[i].data)) { | 7048 | sp->msix_info[i].data)) { |
7017 | DBG_PRINT(ERR_DBG, "%s @ Addr:0x%llx " | 7049 | DBG_PRINT(ERR_DBG, |
7018 | "Data:0x%llx\n",sp->desc[i], | 7050 | "%s @Addr:0x%llx Data:0x%llx\n", |
7051 | sp->desc[i], | ||
7019 | (unsigned long long) | 7052 | (unsigned long long) |
7020 | sp->msix_info[i].addr, | 7053 | sp->msix_info[i].addr, |
7021 | (unsigned long long) | 7054 | (unsigned long long) |
7022 | sp->msix_info[i].data); | 7055 | ntohl(sp->msix_info[i].data)); |
7023 | } else { | 7056 | } else |
7024 | msix_rx_cnt++; | 7057 | msix_rx_cnt++; |
7058 | if (err) { | ||
7059 | remove_msix_isr(sp); | ||
7060 | |||
7061 | DBG_PRINT(ERR_DBG, | ||
7062 | "%s:MSI-X-%d registration " | ||
7063 | "failed\n", dev->name, i); | ||
7064 | |||
7065 | DBG_PRINT(ERR_DBG, | ||
7066 | "%s: Defaulting to INTA\n", | ||
7067 | dev->name); | ||
7068 | sp->config.intr_type = INTA; | ||
7069 | break; | ||
7025 | } | 7070 | } |
7071 | sp->s2io_entries[i].in_use = | ||
7072 | MSIX_REGISTERED_SUCCESS; | ||
7026 | } | 7073 | } |
7027 | if (err) { | ||
7028 | remove_msix_isr(sp); | ||
7029 | DBG_PRINT(ERR_DBG,"%s:MSI-X-%d registration " | ||
7030 | "failed\n", dev->name, i); | ||
7031 | DBG_PRINT(ERR_DBG, "%s: defaulting to INTA\n", | ||
7032 | dev->name); | ||
7033 | sp->config.intr_type = INTA; | ||
7034 | break; | ||
7035 | } | ||
7036 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
7037 | } | 7074 | } |
7038 | if (!err) { | 7075 | if (!err) { |
7039 | printk(KERN_INFO "MSI-X-TX %d entries enabled\n", | ||
7040 | msix_tx_cnt); | ||
7041 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", | 7076 | printk(KERN_INFO "MSI-X-RX %d entries enabled\n", |
7042 | msix_rx_cnt); | 7077 | --msix_rx_cnt); |
7078 | DBG_PRINT(INFO_DBG, "MSI-X-TX entries enabled" | ||
7079 | " through alarm vector\n"); | ||
7043 | } | 7080 | } |
7044 | } | 7081 | } |
7045 | if (sp->config.intr_type == INTA) { | 7082 | if (sp->config.intr_type == INTA) { |
@@ -7080,8 +7117,15 @@ static void do_s2io_card_down(struct s2io_nic * sp, int do_io) | |||
7080 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); | 7117 | clear_bit(__S2IO_STATE_CARD_UP, &sp->state); |
7081 | 7118 | ||
7082 | /* Disable napi */ | 7119 | /* Disable napi */ |
7083 | if (config->napi) | 7120 | if (sp->config.napi) { |
7084 | napi_disable(&sp->napi); | 7121 | int off = 0; |
7122 | if (config->intr_type == MSI_X) { | ||
7123 | for (; off < sp->config.rx_ring_num; off++) | ||
7124 | napi_disable(&sp->mac_control.rings[off].napi); | ||
7125 | } | ||
7126 | else | ||
7127 | napi_disable(&sp->napi); | ||
7128 | } | ||
7085 | 7129 | ||
7086 | /* disable Tx and Rx traffic on the NIC */ | 7130 | /* disable Tx and Rx traffic on the NIC */ |
7087 | if (do_io) | 7131 | if (do_io) |
@@ -7173,8 +7217,15 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7173 | } | 7217 | } |
7174 | 7218 | ||
7175 | /* Initialise napi */ | 7219 | /* Initialise napi */ |
7176 | if (config->napi) | 7220 | if (config->napi) { |
7177 | napi_enable(&sp->napi); | 7221 | int i; |
7222 | if (config->intr_type == MSI_X) { | ||
7223 | for (i = 0; i < sp->config.rx_ring_num; i++) | ||
7224 | napi_enable(&sp->mac_control.rings[i].napi); | ||
7225 | } else { | ||
7226 | napi_enable(&sp->napi); | ||
7227 | } | ||
7228 | } | ||
7178 | 7229 | ||
7179 | /* Maintain the state prior to the open */ | 7230 | /* Maintain the state prior to the open */ |
7180 | if (sp->promisc_flg) | 7231 | if (sp->promisc_flg) |
@@ -7217,7 +7268,7 @@ static int s2io_card_up(struct s2io_nic * sp) | |||
7217 | /* Enable select interrupts */ | 7268 | /* Enable select interrupts */ |
7218 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); | 7269 | en_dis_err_alarms(sp, ENA_ALL_INTRS, ENABLE_INTRS); |
7219 | if (sp->config.intr_type != INTA) | 7270 | if (sp->config.intr_type != INTA) |
7220 | en_dis_able_nic_intrs(sp, ENA_ALL_INTRS, DISABLE_INTRS); | 7271 | en_dis_able_nic_intrs(sp, TX_TRAFFIC_INTR, ENABLE_INTRS); |
7221 | else { | 7272 | else { |
7222 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 7273 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; |
7223 | interruptible |= TX_PIC_INTR; | 7274 | interruptible |= TX_PIC_INTR; |
@@ -7615,9 +7666,6 @@ static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type, | |||
7615 | rx_ring_num = MAX_RX_RINGS; | 7666 | rx_ring_num = MAX_RX_RINGS; |
7616 | } | 7667 | } |
7617 | 7668 | ||
7618 | if (*dev_intr_type != INTA) | ||
7619 | napi = 0; | ||
7620 | |||
7621 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { | 7669 | if ((*dev_intr_type != INTA) && (*dev_intr_type != MSI_X)) { |
7622 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | 7670 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " |
7623 | "Defaulting to INTA\n"); | 7671 | "Defaulting to INTA\n"); |
@@ -7918,8 +7966,6 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7918 | * will use eth_mac_addr() for dev->set_mac_address | 7966 | * will use eth_mac_addr() for dev->set_mac_address |
7919 | * mac address will be set every time dev->open() is called | 7967 | * mac address will be set every time dev->open() is called |
7920 | */ | 7968 | */ |
7921 | netif_napi_add(dev, &sp->napi, s2io_poll, 32); | ||
7922 | |||
7923 | #ifdef CONFIG_NET_POLL_CONTROLLER | 7969 | #ifdef CONFIG_NET_POLL_CONTROLLER |
7924 | dev->poll_controller = s2io_netpoll; | 7970 | dev->poll_controller = s2io_netpoll; |
7925 | #endif | 7971 | #endif |
@@ -7963,6 +8009,32 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
7963 | } | 8009 | } |
7964 | } | 8010 | } |
7965 | 8011 | ||
8012 | if (sp->config.intr_type == MSI_X) { | ||
8013 | sp->num_entries = config->rx_ring_num + 1; | ||
8014 | ret = s2io_enable_msi_x(sp); | ||
8015 | |||
8016 | if (!ret) { | ||
8017 | ret = s2io_test_msi(sp); | ||
8018 | /* rollback MSI-X, will re-enable during add_isr() */ | ||
8019 | remove_msix_isr(sp); | ||
8020 | } | ||
8021 | if (ret) { | ||
8022 | |||
8023 | DBG_PRINT(ERR_DBG, | ||
8024 | "%s: MSI-X requested but failed to enable\n", | ||
8025 | dev->name); | ||
8026 | sp->config.intr_type = INTA; | ||
8027 | } | ||
8028 | } | ||
8029 | |||
8030 | if (config->intr_type == MSI_X) { | ||
8031 | for (i = 0; i < config->rx_ring_num ; i++) | ||
8032 | netif_napi_add(dev, &mac_control->rings[i].napi, | ||
8033 | s2io_poll_msix, 64); | ||
8034 | } else { | ||
8035 | netif_napi_add(dev, &sp->napi, s2io_poll_inta, 64); | ||
8036 | } | ||
8037 | |||
7966 | /* Not needed for Herc */ | 8038 | /* Not needed for Herc */ |
7967 | if (sp->device_type & XFRAME_I_DEVICE) { | 8039 | if (sp->device_type & XFRAME_I_DEVICE) { |
7968 | /* | 8040 | /* |
@@ -8013,6 +8085,11 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8013 | /* store mac addresses from CAM to s2io_nic structure */ | 8085 | /* store mac addresses from CAM to s2io_nic structure */ |
8014 | do_s2io_store_unicast_mc(sp); | 8086 | do_s2io_store_unicast_mc(sp); |
8015 | 8087 | ||
8088 | /* Configure MSIX vector for number of rings configured plus one */ | ||
8089 | if ((sp->device_type == XFRAME_II_DEVICE) && | ||
8090 | (config->intr_type == MSI_X)) | ||
8091 | sp->num_entries = config->rx_ring_num + 1; | ||
8092 | |||
8016 | /* Store the values of the MSIX table in the s2io_nic structure */ | 8093 | /* Store the values of the MSIX table in the s2io_nic structure */ |
8017 | store_xmsi_data(sp); | 8094 | store_xmsi_data(sp); |
8018 | /* reset Nic and bring it to known state */ | 8095 | /* reset Nic and bring it to known state */ |
@@ -8078,8 +8155,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
8078 | break; | 8155 | break; |
8079 | } | 8156 | } |
8080 | 8157 | ||
8081 | if (napi) | 8158 | switch (sp->config.napi) { |
8159 | case 0: | ||
8160 | DBG_PRINT(ERR_DBG, "%s: NAPI disabled\n", dev->name); | ||
8161 | break; | ||
8162 | case 1: | ||
8082 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | 8163 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); |
8164 | break; | ||
8165 | } | ||
8083 | 8166 | ||
8084 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, | 8167 | DBG_PRINT(ERR_DBG, "%s: Using %d Tx fifo(s)\n", dev->name, |
8085 | sp->config.tx_fifo_num); | 8168 | sp->config.tx_fifo_num); |