diff options
Diffstat (limited to 'drivers/net/s2io.c')
-rw-r--r-- | drivers/net/s2io.c | 791 |
1 files changed, 672 insertions, 119 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index dd451e099a4c..d303d162974f 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
@@ -65,9 +65,11 @@ | |||
65 | #include "s2io.h" | 65 | #include "s2io.h" |
66 | #include "s2io-regs.h" | 66 | #include "s2io-regs.h" |
67 | 67 | ||
68 | #define DRV_VERSION "Version 2.0.9.1" | ||
69 | |||
68 | /* S2io Driver name & version. */ | 70 | /* S2io Driver name & version. */ |
69 | static char s2io_driver_name[] = "Neterion"; | 71 | static char s2io_driver_name[] = "Neterion"; |
70 | static char s2io_driver_version[] = "Version 2.0.8.1"; | 72 | static char s2io_driver_version[] = DRV_VERSION; |
71 | 73 | ||
72 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) | 74 | static inline int RXD_IS_UP2DT(RxD_t *rxdp) |
73 | { | 75 | { |
@@ -307,6 +309,8 @@ static unsigned int indicate_max_pkts; | |||
307 | #endif | 309 | #endif |
308 | /* Frequency of Rx desc syncs expressed as power of 2 */ | 310 | /* Frequency of Rx desc syncs expressed as power of 2 */ |
309 | static unsigned int rxsync_frequency = 3; | 311 | static unsigned int rxsync_frequency = 3; |
312 | /* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */ | ||
313 | static unsigned int intr_type = 0; | ||
310 | 314 | ||
311 | /* | 315 | /* |
312 | * S2IO device table. | 316 | * S2IO device table. |
@@ -1396,8 +1400,13 @@ static int init_nic(struct s2io_nic *nic) | |||
1396 | writeq(val64, &bar0->rti_data1_mem); | 1400 | writeq(val64, &bar0->rti_data1_mem); |
1397 | 1401 | ||
1398 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | | 1402 | val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) | |
1399 | RTI_DATA2_MEM_RX_UFC_B(0x2) | | 1403 | RTI_DATA2_MEM_RX_UFC_B(0x2) ; |
1400 | RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80); | 1404 | if (nic->intr_type == MSI_X) |
1405 | val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \ | ||
1406 | RTI_DATA2_MEM_RX_UFC_D(0x40)); | ||
1407 | else | ||
1408 | val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \ | ||
1409 | RTI_DATA2_MEM_RX_UFC_D(0x80)); | ||
1401 | writeq(val64, &bar0->rti_data2_mem); | 1410 | writeq(val64, &bar0->rti_data2_mem); |
1402 | 1411 | ||
1403 | for (i = 0; i < config->rx_ring_num; i++) { | 1412 | for (i = 0; i < config->rx_ring_num; i++) { |
@@ -1507,17 +1516,15 @@ static int init_nic(struct s2io_nic *nic) | |||
1507 | #define LINK_UP_DOWN_INTERRUPT 1 | 1516 | #define LINK_UP_DOWN_INTERRUPT 1 |
1508 | #define MAC_RMAC_ERR_TIMER 2 | 1517 | #define MAC_RMAC_ERR_TIMER 2 |
1509 | 1518 | ||
1510 | #if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE) | ||
1511 | #define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER | ||
1512 | #else | ||
1513 | int s2io_link_fault_indication(nic_t *nic) | 1519 | int s2io_link_fault_indication(nic_t *nic) |
1514 | { | 1520 | { |
1521 | if (nic->intr_type != INTA) | ||
1522 | return MAC_RMAC_ERR_TIMER; | ||
1515 | if (nic->device_type == XFRAME_II_DEVICE) | 1523 | if (nic->device_type == XFRAME_II_DEVICE) |
1516 | return LINK_UP_DOWN_INTERRUPT; | 1524 | return LINK_UP_DOWN_INTERRUPT; |
1517 | else | 1525 | else |
1518 | return MAC_RMAC_ERR_TIMER; | 1526 | return MAC_RMAC_ERR_TIMER; |
1519 | } | 1527 | } |
1520 | #endif | ||
1521 | 1528 | ||
1522 | /** | 1529 | /** |
1523 | * en_dis_able_nic_intrs - Enable or Disable the interrupts | 1530 | * en_dis_able_nic_intrs - Enable or Disable the interrupts |
@@ -1941,11 +1948,14 @@ static int start_nic(struct s2io_nic *nic) | |||
1941 | } | 1948 | } |
1942 | 1949 | ||
1943 | /* Enable select interrupts */ | 1950 | /* Enable select interrupts */ |
1944 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | 1951 | if (nic->intr_type != INTA) |
1945 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; | 1952 | en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS); |
1946 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | 1953 | else { |
1947 | 1954 | interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR; | |
1948 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | 1955 | interruptible |= TX_PIC_INTR | RX_PIC_INTR; |
1956 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | ||
1957 | en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS); | ||
1958 | } | ||
1949 | 1959 | ||
1950 | /* | 1960 | /* |
1951 | * With some switches, link might be already up at this point. | 1961 | * With some switches, link might be already up at this point. |
@@ -2633,11 +2643,11 @@ static void tx_intr_handler(fifo_info_t *fifo_data) | |||
2633 | err = txdlp->Control_1 & TXD_T_CODE; | 2643 | err = txdlp->Control_1 & TXD_T_CODE; |
2634 | if ((err >> 48) == 0xA) { | 2644 | if ((err >> 48) == 0xA) { |
2635 | DBG_PRINT(TX_DBG, "TxD returned due \ | 2645 | DBG_PRINT(TX_DBG, "TxD returned due \ |
2636 | to loss of link\n"); | 2646 | to loss of link\n"); |
2637 | } | 2647 | } |
2638 | else { | 2648 | else { |
2639 | DBG_PRINT(ERR_DBG, "***TxD error \ | 2649 | DBG_PRINT(ERR_DBG, "***TxD error \ |
2640 | %llx\n", err); | 2650 | %llx\n", err); |
2641 | } | 2651 | } |
2642 | } | 2652 | } |
2643 | 2653 | ||
@@ -2854,6 +2864,9 @@ void s2io_reset(nic_t * sp) | |||
2854 | /* Set swapper to enable I/O register access */ | 2864 | /* Set swapper to enable I/O register access */ |
2855 | s2io_set_swapper(sp); | 2865 | s2io_set_swapper(sp); |
2856 | 2866 | ||
2867 | /* Restore the MSIX table entries from local variables */ | ||
2868 | restore_xmsi_data(sp); | ||
2869 | |||
2857 | /* Clear certain PCI/PCI-X fields after reset */ | 2870 | /* Clear certain PCI/PCI-X fields after reset */ |
2858 | if (sp->device_type == XFRAME_II_DEVICE) { | 2871 | if (sp->device_type == XFRAME_II_DEVICE) { |
2859 | /* Clear parity err detect bit */ | 2872 | /* Clear parity err detect bit */ |
@@ -2983,8 +2996,9 @@ int s2io_set_swapper(nic_t * sp) | |||
2983 | SWAPPER_CTRL_RXD_W_FE | | 2996 | SWAPPER_CTRL_RXD_W_FE | |
2984 | SWAPPER_CTRL_RXF_W_FE | | 2997 | SWAPPER_CTRL_RXF_W_FE | |
2985 | SWAPPER_CTRL_XMSI_FE | | 2998 | SWAPPER_CTRL_XMSI_FE | |
2986 | SWAPPER_CTRL_XMSI_SE | | ||
2987 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); | 2999 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); |
3000 | if (sp->intr_type == INTA) | ||
3001 | val64 |= SWAPPER_CTRL_XMSI_SE; | ||
2988 | writeq(val64, &bar0->swapper_ctrl); | 3002 | writeq(val64, &bar0->swapper_ctrl); |
2989 | #else | 3003 | #else |
2990 | /* | 3004 | /* |
@@ -3005,8 +3019,9 @@ int s2io_set_swapper(nic_t * sp) | |||
3005 | SWAPPER_CTRL_RXD_W_SE | | 3019 | SWAPPER_CTRL_RXD_W_SE | |
3006 | SWAPPER_CTRL_RXF_W_FE | | 3020 | SWAPPER_CTRL_RXF_W_FE | |
3007 | SWAPPER_CTRL_XMSI_FE | | 3021 | SWAPPER_CTRL_XMSI_FE | |
3008 | SWAPPER_CTRL_XMSI_SE | | ||
3009 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); | 3022 | SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE); |
3023 | if (sp->intr_type == INTA) | ||
3024 | val64 |= SWAPPER_CTRL_XMSI_SE; | ||
3010 | writeq(val64, &bar0->swapper_ctrl); | 3025 | writeq(val64, &bar0->swapper_ctrl); |
3011 | #endif | 3026 | #endif |
3012 | val64 = readq(&bar0->swapper_ctrl); | 3027 | val64 = readq(&bar0->swapper_ctrl); |
@@ -3028,6 +3043,201 @@ int s2io_set_swapper(nic_t * sp) | |||
3028 | return SUCCESS; | 3043 | return SUCCESS; |
3029 | } | 3044 | } |
3030 | 3045 | ||
3046 | int wait_for_msix_trans(nic_t *nic, int i) | ||
3047 | { | ||
3048 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
3049 | u64 val64; | ||
3050 | int ret = 0, cnt = 0; | ||
3051 | |||
3052 | do { | ||
3053 | val64 = readq(&bar0->xmsi_access); | ||
3054 | if (!(val64 & BIT(15))) | ||
3055 | break; | ||
3056 | mdelay(1); | ||
3057 | cnt++; | ||
3058 | } while(cnt < 5); | ||
3059 | if (cnt == 5) { | ||
3060 | DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i); | ||
3061 | ret = 1; | ||
3062 | } | ||
3063 | |||
3064 | return ret; | ||
3065 | } | ||
3066 | |||
3067 | void restore_xmsi_data(nic_t *nic) | ||
3068 | { | ||
3069 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
3070 | u64 val64; | ||
3071 | int i; | ||
3072 | |||
3073 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | ||
3074 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | ||
3075 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | ||
3076 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); | ||
3077 | writeq(val64, &bar0->xmsi_access); | ||
3078 | if (wait_for_msix_trans(nic, i)) { | ||
3079 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | ||
3080 | continue; | ||
3081 | } | ||
3082 | } | ||
3083 | } | ||
3084 | |||
3085 | void store_xmsi_data(nic_t *nic) | ||
3086 | { | ||
3087 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
3088 | u64 val64, addr, data; | ||
3089 | int i; | ||
3090 | |||
3091 | /* Store and display */ | ||
3092 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | ||
3093 | val64 = (BIT(15) | vBIT(i, 26, 6)); | ||
3094 | writeq(val64, &bar0->xmsi_access); | ||
3095 | if (wait_for_msix_trans(nic, i)) { | ||
3096 | DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__); | ||
3097 | continue; | ||
3098 | } | ||
3099 | addr = readq(&bar0->xmsi_address); | ||
3100 | data = readq(&bar0->xmsi_data); | ||
3101 | if (addr && data) { | ||
3102 | nic->msix_info[i].addr = addr; | ||
3103 | nic->msix_info[i].data = data; | ||
3104 | } | ||
3105 | } | ||
3106 | } | ||
3107 | |||
3108 | int s2io_enable_msi(nic_t *nic) | ||
3109 | { | ||
3110 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
3111 | u16 msi_ctrl, msg_val; | ||
3112 | struct config_param *config = &nic->config; | ||
3113 | struct net_device *dev = nic->dev; | ||
3114 | u64 val64, tx_mat, rx_mat; | ||
3115 | int i, err; | ||
3116 | |||
3117 | val64 = readq(&bar0->pic_control); | ||
3118 | val64 &= ~BIT(1); | ||
3119 | writeq(val64, &bar0->pic_control); | ||
3120 | |||
3121 | err = pci_enable_msi(nic->pdev); | ||
3122 | if (err) { | ||
3123 | DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n", | ||
3124 | nic->dev->name); | ||
3125 | return err; | ||
3126 | } | ||
3127 | |||
3128 | /* | ||
3129 | * Enable MSI and use MSI-1 in stead of the standard MSI-0 | ||
3130 | * for interrupt handling. | ||
3131 | */ | ||
3132 | pci_read_config_word(nic->pdev, 0x4c, &msg_val); | ||
3133 | msg_val ^= 0x1; | ||
3134 | pci_write_config_word(nic->pdev, 0x4c, msg_val); | ||
3135 | pci_read_config_word(nic->pdev, 0x4c, &msg_val); | ||
3136 | |||
3137 | pci_read_config_word(nic->pdev, 0x42, &msi_ctrl); | ||
3138 | msi_ctrl |= 0x10; | ||
3139 | pci_write_config_word(nic->pdev, 0x42, msi_ctrl); | ||
3140 | |||
3141 | /* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */ | ||
3142 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3143 | for (i=0; i<config->tx_fifo_num; i++) { | ||
3144 | tx_mat |= TX_MAT_SET(i, 1); | ||
3145 | } | ||
3146 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3147 | |||
3148 | rx_mat = readq(&bar0->rx_mat); | ||
3149 | for (i=0; i<config->rx_ring_num; i++) { | ||
3150 | rx_mat |= RX_MAT_SET(i, 1); | ||
3151 | } | ||
3152 | writeq(rx_mat, &bar0->rx_mat); | ||
3153 | |||
3154 | dev->irq = nic->pdev->irq; | ||
3155 | return 0; | ||
3156 | } | ||
3157 | |||
3158 | int s2io_enable_msi_x(nic_t *nic) | ||
3159 | { | ||
3160 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0; | ||
3161 | u64 tx_mat, rx_mat; | ||
3162 | u16 msi_control; /* Temp variable */ | ||
3163 | int ret, i, j, msix_indx = 1; | ||
3164 | |||
3165 | nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry), | ||
3166 | GFP_KERNEL); | ||
3167 | if (nic->entries == NULL) { | ||
3168 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); | ||
3169 | return -ENOMEM; | ||
3170 | } | ||
3171 | memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry)); | ||
3172 | |||
3173 | nic->s2io_entries = | ||
3174 | kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry), | ||
3175 | GFP_KERNEL); | ||
3176 | if (nic->s2io_entries == NULL) { | ||
3177 | DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__); | ||
3178 | kfree(nic->entries); | ||
3179 | return -ENOMEM; | ||
3180 | } | ||
3181 | memset(nic->s2io_entries, 0, | ||
3182 | MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry)); | ||
3183 | |||
3184 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | ||
3185 | nic->entries[i].entry = i; | ||
3186 | nic->s2io_entries[i].entry = i; | ||
3187 | nic->s2io_entries[i].arg = NULL; | ||
3188 | nic->s2io_entries[i].in_use = 0; | ||
3189 | } | ||
3190 | |||
3191 | tx_mat = readq(&bar0->tx_mat0_n[0]); | ||
3192 | for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) { | ||
3193 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3194 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i]; | ||
3195 | nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE; | ||
3196 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3197 | } | ||
3198 | writeq(tx_mat, &bar0->tx_mat0_n[0]); | ||
3199 | |||
3200 | if (!nic->config.bimodal) { | ||
3201 | rx_mat = readq(&bar0->rx_mat); | ||
3202 | for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) { | ||
3203 | rx_mat |= RX_MAT_SET(j, msix_indx); | ||
3204 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; | ||
3205 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | ||
3206 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3207 | } | ||
3208 | writeq(rx_mat, &bar0->rx_mat); | ||
3209 | } else { | ||
3210 | tx_mat = readq(&bar0->tx_mat0_n[7]); | ||
3211 | for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) { | ||
3212 | tx_mat |= TX_MAT_SET(i, msix_indx); | ||
3213 | nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j]; | ||
3214 | nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE; | ||
3215 | nic->s2io_entries[msix_indx].in_use = MSIX_FLG; | ||
3216 | } | ||
3217 | writeq(tx_mat, &bar0->tx_mat0_n[7]); | ||
3218 | } | ||
3219 | |||
3220 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | ||
3221 | if (ret) { | ||
3222 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | ||
3223 | kfree(nic->entries); | ||
3224 | kfree(nic->s2io_entries); | ||
3225 | nic->entries = NULL; | ||
3226 | nic->s2io_entries = NULL; | ||
3227 | return -ENOMEM; | ||
3228 | } | ||
3229 | |||
3230 | /* | ||
3231 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | ||
3232 | * in the herc NIC. (Temp change, needs to be removed later) | ||
3233 | */ | ||
3234 | pci_read_config_word(nic->pdev, 0x42, &msi_control); | ||
3235 | msi_control |= 0x1; /* Enable MSI */ | ||
3236 | pci_write_config_word(nic->pdev, 0x42, msi_control); | ||
3237 | |||
3238 | return 0; | ||
3239 | } | ||
3240 | |||
3031 | /* ********************************************************* * | 3241 | /* ********************************************************* * |
3032 | * Functions defined below concern the OS part of the driver * | 3242 | * Functions defined below concern the OS part of the driver * |
3033 | * ********************************************************* */ | 3243 | * ********************************************************* */ |
@@ -3048,6 +3258,8 @@ int s2io_open(struct net_device *dev) | |||
3048 | { | 3258 | { |
3049 | nic_t *sp = dev->priv; | 3259 | nic_t *sp = dev->priv; |
3050 | int err = 0; | 3260 | int err = 0; |
3261 | int i; | ||
3262 | u16 msi_control; /* Temp variable */ | ||
3051 | 3263 | ||
3052 | /* | 3264 | /* |
3053 | * Make sure you have link off by default every time | 3265 | * Make sure you have link off by default every time |
@@ -3064,13 +3276,55 @@ int s2io_open(struct net_device *dev) | |||
3064 | goto hw_init_failed; | 3276 | goto hw_init_failed; |
3065 | } | 3277 | } |
3066 | 3278 | ||
3279 | /* Store the values of the MSIX table in the nic_t structure */ | ||
3280 | store_xmsi_data(sp); | ||
3281 | |||
3067 | /* After proper initialization of H/W, register ISR */ | 3282 | /* After proper initialization of H/W, register ISR */ |
3068 | err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, | 3283 | if (sp->intr_type == MSI) { |
3069 | sp->name, dev); | 3284 | err = request_irq((int) sp->pdev->irq, s2io_msi_handle, |
3070 | if (err) { | 3285 | SA_SHIRQ, sp->name, dev); |
3071 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | 3286 | if (err) { |
3072 | dev->name); | 3287 | DBG_PRINT(ERR_DBG, "%s: MSI registration \ |
3073 | goto isr_registration_failed; | 3288 | failed\n", dev->name); |
3289 | goto isr_registration_failed; | ||
3290 | } | ||
3291 | } | ||
3292 | if (sp->intr_type == MSI_X) { | ||
3293 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | ||
3294 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | ||
3295 | sprintf(sp->desc1, "%s:MSI-X-%d-TX", | ||
3296 | dev->name, i); | ||
3297 | err = request_irq(sp->entries[i].vector, | ||
3298 | s2io_msix_fifo_handle, 0, sp->desc1, | ||
3299 | sp->s2io_entries[i].arg); | ||
3300 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, | ||
3301 | sp->msix_info[i].addr); | ||
3302 | } else { | ||
3303 | sprintf(sp->desc2, "%s:MSI-X-%d-RX", | ||
3304 | dev->name, i); | ||
3305 | err = request_irq(sp->entries[i].vector, | ||
3306 | s2io_msix_ring_handle, 0, sp->desc2, | ||
3307 | sp->s2io_entries[i].arg); | ||
3308 | DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, | ||
3309 | sp->msix_info[i].addr); | ||
3310 | } | ||
3311 | if (err) { | ||
3312 | DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \ | ||
3313 | failed\n", dev->name, i); | ||
3314 | DBG_PRINT(ERR_DBG, "Returned: %d\n", err); | ||
3315 | goto isr_registration_failed; | ||
3316 | } | ||
3317 | sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS; | ||
3318 | } | ||
3319 | } | ||
3320 | if (sp->intr_type == INTA) { | ||
3321 | err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ, | ||
3322 | sp->name, dev); | ||
3323 | if (err) { | ||
3324 | DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n", | ||
3325 | dev->name); | ||
3326 | goto isr_registration_failed; | ||
3327 | } | ||
3074 | } | 3328 | } |
3075 | 3329 | ||
3076 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { | 3330 | if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) { |
@@ -3083,11 +3337,37 @@ int s2io_open(struct net_device *dev) | |||
3083 | return 0; | 3337 | return 0; |
3084 | 3338 | ||
3085 | setting_mac_address_failed: | 3339 | setting_mac_address_failed: |
3086 | free_irq(sp->pdev->irq, dev); | 3340 | if (sp->intr_type != MSI_X) |
3341 | free_irq(sp->pdev->irq, dev); | ||
3087 | isr_registration_failed: | 3342 | isr_registration_failed: |
3088 | del_timer_sync(&sp->alarm_timer); | 3343 | del_timer_sync(&sp->alarm_timer); |
3344 | if (sp->intr_type == MSI_X) { | ||
3345 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
3346 | for (i=1; (sp->s2io_entries[i].in_use == | ||
3347 | MSIX_REGISTERED_SUCCESS); i++) { | ||
3348 | int vector = sp->entries[i].vector; | ||
3349 | void *arg = sp->s2io_entries[i].arg; | ||
3350 | |||
3351 | free_irq(vector, arg); | ||
3352 | } | ||
3353 | pci_disable_msix(sp->pdev); | ||
3354 | |||
3355 | /* Temp */ | ||
3356 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
3357 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
3358 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
3359 | } | ||
3360 | } | ||
3361 | else if (sp->intr_type == MSI) | ||
3362 | pci_disable_msi(sp->pdev); | ||
3089 | s2io_reset(sp); | 3363 | s2io_reset(sp); |
3090 | hw_init_failed: | 3364 | hw_init_failed: |
3365 | if (sp->intr_type == MSI_X) { | ||
3366 | if (sp->entries) | ||
3367 | kfree(sp->entries); | ||
3368 | if (sp->s2io_entries) | ||
3369 | kfree(sp->s2io_entries); | ||
3370 | } | ||
3091 | return err; | 3371 | return err; |
3092 | } | 3372 | } |
3093 | 3373 | ||
@@ -3107,12 +3387,35 @@ hw_init_failed: | |||
3107 | int s2io_close(struct net_device *dev) | 3387 | int s2io_close(struct net_device *dev) |
3108 | { | 3388 | { |
3109 | nic_t *sp = dev->priv; | 3389 | nic_t *sp = dev->priv; |
3390 | int i; | ||
3391 | u16 msi_control; | ||
3392 | |||
3110 | flush_scheduled_work(); | 3393 | flush_scheduled_work(); |
3111 | netif_stop_queue(dev); | 3394 | netif_stop_queue(dev); |
3112 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3395 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
3113 | s2io_card_down(sp); | 3396 | s2io_card_down(sp); |
3114 | 3397 | ||
3115 | free_irq(sp->pdev->irq, dev); | 3398 | if (sp->intr_type == MSI_X) { |
3399 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
3400 | for (i=1; (sp->s2io_entries[i].in_use == | ||
3401 | MSIX_REGISTERED_SUCCESS); i++) { | ||
3402 | int vector = sp->entries[i].vector; | ||
3403 | void *arg = sp->s2io_entries[i].arg; | ||
3404 | |||
3405 | free_irq(vector, arg); | ||
3406 | } | ||
3407 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
3408 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
3409 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
3410 | |||
3411 | pci_disable_msix(sp->pdev); | ||
3412 | } | ||
3413 | } | ||
3414 | else { | ||
3415 | free_irq(sp->pdev->irq, dev); | ||
3416 | if (sp->intr_type == MSI) | ||
3417 | pci_disable_msi(sp->pdev); | ||
3418 | } | ||
3116 | sp->device_close_flag = TRUE; /* Device is shut down. */ | 3419 | sp->device_close_flag = TRUE; /* Device is shut down. */ |
3117 | return 0; | 3420 | return 0; |
3118 | } | 3421 | } |
@@ -3278,6 +3581,104 @@ s2io_alarm_handle(unsigned long data) | |||
3278 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); | 3581 | mod_timer(&sp->alarm_timer, jiffies + HZ / 2); |
3279 | } | 3582 | } |
3280 | 3583 | ||
3584 | static irqreturn_t | ||
3585 | s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs) | ||
3586 | { | ||
3587 | struct net_device *dev = (struct net_device *) dev_id; | ||
3588 | nic_t *sp = dev->priv; | ||
3589 | int i; | ||
3590 | int ret; | ||
3591 | mac_info_t *mac_control; | ||
3592 | struct config_param *config; | ||
3593 | |||
3594 | atomic_inc(&sp->isr_cnt); | ||
3595 | mac_control = &sp->mac_control; | ||
3596 | config = &sp->config; | ||
3597 | DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__); | ||
3598 | |||
3599 | /* If Intr is because of Rx Traffic */ | ||
3600 | for (i = 0; i < config->rx_ring_num; i++) | ||
3601 | rx_intr_handler(&mac_control->rings[i]); | ||
3602 | |||
3603 | /* If Intr is because of Tx Traffic */ | ||
3604 | for (i = 0; i < config->tx_fifo_num; i++) | ||
3605 | tx_intr_handler(&mac_control->fifos[i]); | ||
3606 | |||
3607 | /* | ||
3608 | * If the Rx buffer count is below the panic threshold then | ||
3609 | * reallocate the buffers from the interrupt handler itself, | ||
3610 | * else schedule a tasklet to reallocate the buffers. | ||
3611 | */ | ||
3612 | for (i = 0; i < config->rx_ring_num; i++) { | ||
3613 | int rxb_size = atomic_read(&sp->rx_bufs_left[i]); | ||
3614 | int level = rx_buffer_level(sp, rxb_size, i); | ||
3615 | |||
3616 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
3617 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name); | ||
3618 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
3619 | if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) { | ||
3620 | DBG_PRINT(ERR_DBG, "%s:Out of memory", | ||
3621 | dev->name); | ||
3622 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | ||
3623 | clear_bit(0, (&sp->tasklet_status)); | ||
3624 | atomic_dec(&sp->isr_cnt); | ||
3625 | return IRQ_HANDLED; | ||
3626 | } | ||
3627 | clear_bit(0, (&sp->tasklet_status)); | ||
3628 | } else if (level == LOW) { | ||
3629 | tasklet_schedule(&sp->task); | ||
3630 | } | ||
3631 | } | ||
3632 | |||
3633 | atomic_dec(&sp->isr_cnt); | ||
3634 | return IRQ_HANDLED; | ||
3635 | } | ||
3636 | |||
3637 | static irqreturn_t | ||
3638 | s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs) | ||
3639 | { | ||
3640 | ring_info_t *ring = (ring_info_t *)dev_id; | ||
3641 | nic_t *sp = ring->nic; | ||
3642 | int rxb_size, level, rng_n; | ||
3643 | |||
3644 | atomic_inc(&sp->isr_cnt); | ||
3645 | rx_intr_handler(ring); | ||
3646 | |||
3647 | rng_n = ring->ring_no; | ||
3648 | rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]); | ||
3649 | level = rx_buffer_level(sp, rxb_size, rng_n); | ||
3650 | |||
3651 | if ((level == PANIC) && (!TASKLET_IN_USE)) { | ||
3652 | int ret; | ||
3653 | DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__); | ||
3654 | DBG_PRINT(INTR_DBG, "PANIC levels\n"); | ||
3655 | if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) { | ||
3656 | DBG_PRINT(ERR_DBG, "Out of memory in %s", | ||
3657 | __FUNCTION__); | ||
3658 | clear_bit(0, (&sp->tasklet_status)); | ||
3659 | return IRQ_HANDLED; | ||
3660 | } | ||
3661 | clear_bit(0, (&sp->tasklet_status)); | ||
3662 | } else if (level == LOW) { | ||
3663 | tasklet_schedule(&sp->task); | ||
3664 | } | ||
3665 | atomic_dec(&sp->isr_cnt); | ||
3666 | |||
3667 | return IRQ_HANDLED; | ||
3668 | } | ||
3669 | |||
3670 | static irqreturn_t | ||
3671 | s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs) | ||
3672 | { | ||
3673 | fifo_info_t *fifo = (fifo_info_t *)dev_id; | ||
3674 | nic_t *sp = fifo->nic; | ||
3675 | |||
3676 | atomic_inc(&sp->isr_cnt); | ||
3677 | tx_intr_handler(fifo); | ||
3678 | atomic_dec(&sp->isr_cnt); | ||
3679 | return IRQ_HANDLED; | ||
3680 | } | ||
3681 | |||
3281 | static void s2io_txpic_intr_handle(nic_t *sp) | 3682 | static void s2io_txpic_intr_handle(nic_t *sp) |
3282 | { | 3683 | { |
3283 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 3684 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
@@ -3778,11 +4179,10 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev, | |||
3778 | { | 4179 | { |
3779 | nic_t *sp = dev->priv; | 4180 | nic_t *sp = dev->priv; |
3780 | 4181 | ||
3781 | strncpy(info->driver, s2io_driver_name, sizeof(s2io_driver_name)); | 4182 | strncpy(info->driver, s2io_driver_name, sizeof(info->driver)); |
3782 | strncpy(info->version, s2io_driver_version, | 4183 | strncpy(info->version, s2io_driver_version, sizeof(info->version)); |
3783 | sizeof(s2io_driver_version)); | 4184 | strncpy(info->fw_version, "", sizeof(info->fw_version)); |
3784 | strncpy(info->fw_version, "", 32); | 4185 | strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info)); |
3785 | strncpy(info->bus_info, pci_name(sp->pdev), 32); | ||
3786 | info->regdump_len = XENA_REG_SPACE; | 4186 | info->regdump_len = XENA_REG_SPACE; |
3787 | info->eedump_len = XENA_EEPROM_SPACE; | 4187 | info->eedump_len = XENA_EEPROM_SPACE; |
3788 | info->testinfo_len = S2IO_TEST_LEN; | 4188 | info->testinfo_len = S2IO_TEST_LEN; |
@@ -3978,29 +4378,53 @@ static int s2io_ethtool_setpause_data(struct net_device *dev, | |||
3978 | */ | 4378 | */ |
3979 | 4379 | ||
3980 | #define S2IO_DEV_ID 5 | 4380 | #define S2IO_DEV_ID 5 |
3981 | static int read_eeprom(nic_t * sp, int off, u32 * data) | 4381 | static int read_eeprom(nic_t * sp, int off, u64 * data) |
3982 | { | 4382 | { |
3983 | int ret = -1; | 4383 | int ret = -1; |
3984 | u32 exit_cnt = 0; | 4384 | u32 exit_cnt = 0; |
3985 | u64 val64; | 4385 | u64 val64; |
3986 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4386 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
3987 | 4387 | ||
3988 | val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | | 4388 | if (sp->device_type == XFRAME_I_DEVICE) { |
3989 | I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ | | 4389 | val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | |
3990 | I2C_CONTROL_CNTL_START; | 4390 | I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ | |
3991 | SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); | 4391 | I2C_CONTROL_CNTL_START; |
4392 | SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); | ||
3992 | 4393 | ||
3993 | while (exit_cnt < 5) { | 4394 | while (exit_cnt < 5) { |
3994 | val64 = readq(&bar0->i2c_control); | 4395 | val64 = readq(&bar0->i2c_control); |
3995 | if (I2C_CONTROL_CNTL_END(val64)) { | 4396 | if (I2C_CONTROL_CNTL_END(val64)) { |
3996 | *data = I2C_CONTROL_GET_DATA(val64); | 4397 | *data = I2C_CONTROL_GET_DATA(val64); |
3997 | ret = 0; | 4398 | ret = 0; |
3998 | break; | 4399 | break; |
4400 | } | ||
4401 | msleep(50); | ||
4402 | exit_cnt++; | ||
3999 | } | 4403 | } |
4000 | msleep(50); | ||
4001 | exit_cnt++; | ||
4002 | } | 4404 | } |
4003 | 4405 | ||
4406 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
4407 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | | ||
4408 | SPI_CONTROL_BYTECNT(0x3) | | ||
4409 | SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off); | ||
4410 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | ||
4411 | val64 |= SPI_CONTROL_REQ; | ||
4412 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | ||
4413 | while (exit_cnt < 5) { | ||
4414 | val64 = readq(&bar0->spi_control); | ||
4415 | if (val64 & SPI_CONTROL_NACK) { | ||
4416 | ret = 1; | ||
4417 | break; | ||
4418 | } else if (val64 & SPI_CONTROL_DONE) { | ||
4419 | *data = readq(&bar0->spi_data); | ||
4420 | *data &= 0xffffff; | ||
4421 | ret = 0; | ||
4422 | break; | ||
4423 | } | ||
4424 | msleep(50); | ||
4425 | exit_cnt++; | ||
4426 | } | ||
4427 | } | ||
4004 | return ret; | 4428 | return ret; |
4005 | } | 4429 | } |
4006 | 4430 | ||
@@ -4019,28 +4443,53 @@ static int read_eeprom(nic_t * sp, int off, u32 * data) | |||
4019 | * 0 on success, -1 on failure. | 4443 | * 0 on success, -1 on failure. |
4020 | */ | 4444 | */ |
4021 | 4445 | ||
4022 | static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | 4446 | static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) |
4023 | { | 4447 | { |
4024 | int exit_cnt = 0, ret = -1; | 4448 | int exit_cnt = 0, ret = -1; |
4025 | u64 val64; | 4449 | u64 val64; |
4026 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4450 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
4027 | 4451 | ||
4028 | val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | | 4452 | if (sp->device_type == XFRAME_I_DEVICE) { |
4029 | I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) | | 4453 | val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) | |
4030 | I2C_CONTROL_CNTL_START; | 4454 | I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) | |
4031 | SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); | 4455 | I2C_CONTROL_CNTL_START; |
4456 | SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF); | ||
4457 | |||
4458 | while (exit_cnt < 5) { | ||
4459 | val64 = readq(&bar0->i2c_control); | ||
4460 | if (I2C_CONTROL_CNTL_END(val64)) { | ||
4461 | if (!(val64 & I2C_CONTROL_NACK)) | ||
4462 | ret = 0; | ||
4463 | break; | ||
4464 | } | ||
4465 | msleep(50); | ||
4466 | exit_cnt++; | ||
4467 | } | ||
4468 | } | ||
4032 | 4469 | ||
4033 | while (exit_cnt < 5) { | 4470 | if (sp->device_type == XFRAME_II_DEVICE) { |
4034 | val64 = readq(&bar0->i2c_control); | 4471 | int write_cnt = (cnt == 8) ? 0 : cnt; |
4035 | if (I2C_CONTROL_CNTL_END(val64)) { | 4472 | writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data); |
4036 | if (!(val64 & I2C_CONTROL_NACK)) | 4473 | |
4474 | val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 | | ||
4475 | SPI_CONTROL_BYTECNT(write_cnt) | | ||
4476 | SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off); | ||
4477 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | ||
4478 | val64 |= SPI_CONTROL_REQ; | ||
4479 | SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF); | ||
4480 | while (exit_cnt < 5) { | ||
4481 | val64 = readq(&bar0->spi_control); | ||
4482 | if (val64 & SPI_CONTROL_NACK) { | ||
4483 | ret = 1; | ||
4484 | break; | ||
4485 | } else if (val64 & SPI_CONTROL_DONE) { | ||
4037 | ret = 0; | 4486 | ret = 0; |
4038 | break; | 4487 | break; |
4488 | } | ||
4489 | msleep(50); | ||
4490 | exit_cnt++; | ||
4039 | } | 4491 | } |
4040 | msleep(50); | ||
4041 | exit_cnt++; | ||
4042 | } | 4492 | } |
4043 | |||
4044 | return ret; | 4493 | return ret; |
4045 | } | 4494 | } |
4046 | 4495 | ||
@@ -4060,7 +4509,8 @@ static int write_eeprom(nic_t * sp, int off, u32 data, int cnt) | |||
4060 | static int s2io_ethtool_geeprom(struct net_device *dev, | 4509 | static int s2io_ethtool_geeprom(struct net_device *dev, |
4061 | struct ethtool_eeprom *eeprom, u8 * data_buf) | 4510 | struct ethtool_eeprom *eeprom, u8 * data_buf) |
4062 | { | 4511 | { |
4063 | u32 data, i, valid; | 4512 | u32 i, valid; |
4513 | u64 data; | ||
4064 | nic_t *sp = dev->priv; | 4514 | nic_t *sp = dev->priv; |
4065 | 4515 | ||
4066 | eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16); | 4516 | eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16); |
@@ -4098,7 +4548,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev, | |||
4098 | u8 * data_buf) | 4548 | u8 * data_buf) |
4099 | { | 4549 | { |
4100 | int len = eeprom->len, cnt = 0; | 4550 | int len = eeprom->len, cnt = 0; |
4101 | u32 valid = 0, data; | 4551 | u64 valid = 0, data; |
4102 | nic_t *sp = dev->priv; | 4552 | nic_t *sp = dev->priv; |
4103 | 4553 | ||
4104 | if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) { | 4554 | if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) { |
@@ -4146,7 +4596,7 @@ static int s2io_ethtool_seeprom(struct net_device *dev, | |||
4146 | static int s2io_register_test(nic_t * sp, uint64_t * data) | 4596 | static int s2io_register_test(nic_t * sp, uint64_t * data) |
4147 | { | 4597 | { |
4148 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4598 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
4149 | u64 val64 = 0; | 4599 | u64 val64 = 0, exp_val; |
4150 | int fail = 0; | 4600 | int fail = 0; |
4151 | 4601 | ||
4152 | val64 = readq(&bar0->pif_rd_swapper_fb); | 4602 | val64 = readq(&bar0->pif_rd_swapper_fb); |
@@ -4162,7 +4612,11 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
4162 | } | 4612 | } |
4163 | 4613 | ||
4164 | val64 = readq(&bar0->rx_queue_cfg); | 4614 | val64 = readq(&bar0->rx_queue_cfg); |
4165 | if (val64 != 0x0808080808080808ULL) { | 4615 | if (sp->device_type == XFRAME_II_DEVICE) |
4616 | exp_val = 0x0404040404040404ULL; | ||
4617 | else | ||
4618 | exp_val = 0x0808080808080808ULL; | ||
4619 | if (val64 != exp_val) { | ||
4166 | fail = 1; | 4620 | fail = 1; |
4167 | DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n"); | 4621 | DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n"); |
4168 | } | 4622 | } |
@@ -4190,7 +4644,7 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
4190 | } | 4644 | } |
4191 | 4645 | ||
4192 | *data = fail; | 4646 | *data = fail; |
4193 | return 0; | 4647 | return fail; |
4194 | } | 4648 | } |
4195 | 4649 | ||
4196 | /** | 4650 | /** |
@@ -4209,58 +4663,83 @@ static int s2io_register_test(nic_t * sp, uint64_t * data) | |||
4209 | static int s2io_eeprom_test(nic_t * sp, uint64_t * data) | 4663 | static int s2io_eeprom_test(nic_t * sp, uint64_t * data) |
4210 | { | 4664 | { |
4211 | int fail = 0; | 4665 | int fail = 0; |
4212 | u32 ret_data; | 4666 | u64 ret_data, org_4F0, org_7F0; |
4667 | u8 saved_4F0 = 0, saved_7F0 = 0; | ||
4668 | struct net_device *dev = sp->dev; | ||
4213 | 4669 | ||
4214 | /* Test Write Error at offset 0 */ | 4670 | /* Test Write Error at offset 0 */ |
4215 | if (!write_eeprom(sp, 0, 0, 3)) | 4671 | /* Note that SPI interface allows write access to all areas |
4216 | fail = 1; | 4672 | * of EEPROM. Hence doing all negative testing only for Xframe I. |
4673 | */ | ||
4674 | if (sp->device_type == XFRAME_I_DEVICE) | ||
4675 | if (!write_eeprom(sp, 0, 0, 3)) | ||
4676 | fail = 1; | ||
4677 | |||
4678 | /* Save current values at offsets 0x4F0 and 0x7F0 */ | ||
4679 | if (!read_eeprom(sp, 0x4F0, &org_4F0)) | ||
4680 | saved_4F0 = 1; | ||
4681 | if (!read_eeprom(sp, 0x7F0, &org_7F0)) | ||
4682 | saved_7F0 = 1; | ||
4217 | 4683 | ||
4218 | /* Test Write at offset 4f0 */ | 4684 | /* Test Write at offset 4f0 */ |
4219 | if (write_eeprom(sp, 0x4F0, 0x01234567, 3)) | 4685 | if (write_eeprom(sp, 0x4F0, 0x012345, 3)) |
4220 | fail = 1; | 4686 | fail = 1; |
4221 | if (read_eeprom(sp, 0x4F0, &ret_data)) | 4687 | if (read_eeprom(sp, 0x4F0, &ret_data)) |
4222 | fail = 1; | 4688 | fail = 1; |
4223 | 4689 | ||
4224 | if (ret_data != 0x01234567) | 4690 | if (ret_data != 0x012345) { |
4691 | DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); | ||
4225 | fail = 1; | 4692 | fail = 1; |
4693 | } | ||
4226 | 4694 | ||
4227 | /* Reset the EEPROM data go FFFF */ | 4695 | /* Reset the EEPROM data go FFFF */ |
4228 | write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3); | 4696 | write_eeprom(sp, 0x4F0, 0xFFFFFF, 3); |
4229 | 4697 | ||
4230 | /* Test Write Request Error at offset 0x7c */ | 4698 | /* Test Write Request Error at offset 0x7c */ |
4231 | if (!write_eeprom(sp, 0x07C, 0, 3)) | 4699 | if (sp->device_type == XFRAME_I_DEVICE) |
4232 | fail = 1; | 4700 | if (!write_eeprom(sp, 0x07C, 0, 3)) |
4701 | fail = 1; | ||
4233 | 4702 | ||
4234 | /* Test Write Request at offset 0x7fc */ | 4703 | /* Test Write Request at offset 0x7f0 */ |
4235 | if (write_eeprom(sp, 0x7FC, 0x01234567, 3)) | 4704 | if (write_eeprom(sp, 0x7F0, 0x012345, 3)) |
4236 | fail = 1; | 4705 | fail = 1; |
4237 | if (read_eeprom(sp, 0x7FC, &ret_data)) | 4706 | if (read_eeprom(sp, 0x7F0, &ret_data)) |
4238 | fail = 1; | 4707 | fail = 1; |
4239 | 4708 | ||
4240 | if (ret_data != 0x01234567) | 4709 | if (ret_data != 0x012345) { |
4710 | DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); | ||
4241 | fail = 1; | 4711 | fail = 1; |
4712 | } | ||
4242 | 4713 | ||
4243 | /* Reset the EEPROM data go FFFF */ | 4714 | /* Reset the EEPROM data go FFFF */ |
4244 | write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3); | 4715 | write_eeprom(sp, 0x7F0, 0xFFFFFF, 3); |
4245 | 4716 | ||
4246 | /* Test Write Error at offset 0x80 */ | 4717 | if (sp->device_type == XFRAME_I_DEVICE) { |
4247 | if (!write_eeprom(sp, 0x080, 0, 3)) | 4718 | /* Test Write Error at offset 0x80 */ |
4248 | fail = 1; | 4719 | if (!write_eeprom(sp, 0x080, 0, 3)) |
4720 | fail = 1; | ||
4249 | 4721 | ||
4250 | /* Test Write Error at offset 0xfc */ | 4722 | /* Test Write Error at offset 0xfc */ |
4251 | if (!write_eeprom(sp, 0x0FC, 0, 3)) | 4723 | if (!write_eeprom(sp, 0x0FC, 0, 3)) |
4252 | fail = 1; | 4724 | fail = 1; |
4253 | 4725 | ||
4254 | /* Test Write Error at offset 0x100 */ | 4726 | /* Test Write Error at offset 0x100 */ |
4255 | if (!write_eeprom(sp, 0x100, 0, 3)) | 4727 | if (!write_eeprom(sp, 0x100, 0, 3)) |
4256 | fail = 1; | 4728 | fail = 1; |
4257 | 4729 | ||
4258 | /* Test Write Error at offset 4ec */ | 4730 | /* Test Write Error at offset 4ec */ |
4259 | if (!write_eeprom(sp, 0x4EC, 0, 3)) | 4731 | if (!write_eeprom(sp, 0x4EC, 0, 3)) |
4260 | fail = 1; | 4732 | fail = 1; |
4733 | } | ||
4734 | |||
4735 | /* Restore values at offsets 0x4F0 and 0x7F0 */ | ||
4736 | if (saved_4F0) | ||
4737 | write_eeprom(sp, 0x4F0, org_4F0, 3); | ||
4738 | if (saved_7F0) | ||
4739 | write_eeprom(sp, 0x7F0, org_7F0, 3); | ||
4261 | 4740 | ||
4262 | *data = fail; | 4741 | *data = fail; |
4263 | return 0; | 4742 | return fail; |
4264 | } | 4743 | } |
4265 | 4744 | ||
4266 | /** | 4745 | /** |
@@ -4342,7 +4821,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
4342 | { | 4821 | { |
4343 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4822 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
4344 | u64 val64; | 4823 | u64 val64; |
4345 | int cnt, iteration = 0, test_pass = 0; | 4824 | int cnt, iteration = 0, test_fail = 0; |
4346 | 4825 | ||
4347 | val64 = readq(&bar0->adapter_control); | 4826 | val64 = readq(&bar0->adapter_control); |
4348 | val64 &= ~ADAPTER_ECC_EN; | 4827 | val64 &= ~ADAPTER_ECC_EN; |
@@ -4350,7 +4829,7 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
4350 | 4829 | ||
4351 | val64 = readq(&bar0->mc_rldram_test_ctrl); | 4830 | val64 = readq(&bar0->mc_rldram_test_ctrl); |
4352 | val64 |= MC_RLDRAM_TEST_MODE; | 4831 | val64 |= MC_RLDRAM_TEST_MODE; |
4353 | writeq(val64, &bar0->mc_rldram_test_ctrl); | 4832 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); |
4354 | 4833 | ||
4355 | val64 = readq(&bar0->mc_rldram_mrs); | 4834 | val64 = readq(&bar0->mc_rldram_mrs); |
4356 | val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE; | 4835 | val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE; |
@@ -4378,17 +4857,12 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
4378 | } | 4857 | } |
4379 | writeq(val64, &bar0->mc_rldram_test_d2); | 4858 | writeq(val64, &bar0->mc_rldram_test_d2); |
4380 | 4859 | ||
4381 | val64 = (u64) (0x0000003fffff0000ULL); | 4860 | val64 = (u64) (0x0000003ffffe0100ULL); |
4382 | writeq(val64, &bar0->mc_rldram_test_add); | 4861 | writeq(val64, &bar0->mc_rldram_test_add); |
4383 | 4862 | ||
4384 | 4863 | val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE | | |
4385 | val64 = MC_RLDRAM_TEST_MODE; | 4864 | MC_RLDRAM_TEST_GO; |
4386 | writeq(val64, &bar0->mc_rldram_test_ctrl); | 4865 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); |
4387 | |||
4388 | val64 |= | ||
4389 | MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE | | ||
4390 | MC_RLDRAM_TEST_GO; | ||
4391 | writeq(val64, &bar0->mc_rldram_test_ctrl); | ||
4392 | 4866 | ||
4393 | for (cnt = 0; cnt < 5; cnt++) { | 4867 | for (cnt = 0; cnt < 5; cnt++) { |
4394 | val64 = readq(&bar0->mc_rldram_test_ctrl); | 4868 | val64 = readq(&bar0->mc_rldram_test_ctrl); |
@@ -4400,11 +4874,8 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
4400 | if (cnt == 5) | 4874 | if (cnt == 5) |
4401 | break; | 4875 | break; |
4402 | 4876 | ||
4403 | val64 = MC_RLDRAM_TEST_MODE; | 4877 | val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO; |
4404 | writeq(val64, &bar0->mc_rldram_test_ctrl); | 4878 | SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF); |
4405 | |||
4406 | val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO; | ||
4407 | writeq(val64, &bar0->mc_rldram_test_ctrl); | ||
4408 | 4879 | ||
4409 | for (cnt = 0; cnt < 5; cnt++) { | 4880 | for (cnt = 0; cnt < 5; cnt++) { |
4410 | val64 = readq(&bar0->mc_rldram_test_ctrl); | 4881 | val64 = readq(&bar0->mc_rldram_test_ctrl); |
@@ -4417,18 +4888,18 @@ static int s2io_rldram_test(nic_t * sp, uint64_t * data) | |||
4417 | break; | 4888 | break; |
4418 | 4889 | ||
4419 | val64 = readq(&bar0->mc_rldram_test_ctrl); | 4890 | val64 = readq(&bar0->mc_rldram_test_ctrl); |
4420 | if (val64 & MC_RLDRAM_TEST_PASS) | 4891 | if (!(val64 & MC_RLDRAM_TEST_PASS)) |
4421 | test_pass = 1; | 4892 | test_fail = 1; |
4422 | 4893 | ||
4423 | iteration++; | 4894 | iteration++; |
4424 | } | 4895 | } |
4425 | 4896 | ||
4426 | if (!test_pass) | 4897 | *data = test_fail; |
4427 | *data = 1; | ||
4428 | else | ||
4429 | *data = 0; | ||
4430 | 4898 | ||
4431 | return 0; | 4899 | /* Bring the adapter out of test mode */ |
4900 | SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF); | ||
4901 | |||
4902 | return test_fail; | ||
4432 | } | 4903 | } |
4433 | 4904 | ||
4434 | /** | 4905 | /** |
@@ -4932,7 +5403,7 @@ static void s2io_card_down(nic_t * sp) | |||
4932 | 5403 | ||
4933 | static int s2io_card_up(nic_t * sp) | 5404 | static int s2io_card_up(nic_t * sp) |
4934 | { | 5405 | { |
4935 | int i, ret; | 5406 | int i, ret = 0; |
4936 | mac_info_t *mac_control; | 5407 | mac_info_t *mac_control; |
4937 | struct config_param *config; | 5408 | struct config_param *config; |
4938 | struct net_device *dev = (struct net_device *) sp->dev; | 5409 | struct net_device *dev = (struct net_device *) sp->dev; |
@@ -4944,6 +5415,15 @@ static int s2io_card_up(nic_t * sp) | |||
4944 | return -ENODEV; | 5415 | return -ENODEV; |
4945 | } | 5416 | } |
4946 | 5417 | ||
5418 | if (sp->intr_type == MSI) | ||
5419 | ret = s2io_enable_msi(sp); | ||
5420 | else if (sp->intr_type == MSI_X) | ||
5421 | ret = s2io_enable_msi_x(sp); | ||
5422 | if (ret) { | ||
5423 | DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name); | ||
5424 | sp->intr_type = INTA; | ||
5425 | } | ||
5426 | |||
4947 | /* | 5427 | /* |
4948 | * Initializing the Rx buffers. For now we are considering only 1 | 5428 | * Initializing the Rx buffers. For now we are considering only 1 |
4949 | * Rx ring and initializing buffers into 30 Rx blocks | 5429 | * Rx ring and initializing buffers into 30 Rx blocks |
@@ -5228,6 +5708,8 @@ static void s2io_init_pci(nic_t * sp) | |||
5228 | 5708 | ||
5229 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | 5709 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); |
5230 | MODULE_LICENSE("GPL"); | 5710 | MODULE_LICENSE("GPL"); |
5711 | MODULE_VERSION(DRV_VERSION); | ||
5712 | |||
5231 | module_param(tx_fifo_num, int, 0); | 5713 | module_param(tx_fifo_num, int, 0); |
5232 | module_param(rx_ring_num, int, 0); | 5714 | module_param(rx_ring_num, int, 0); |
5233 | module_param_array(tx_fifo_len, uint, NULL, 0); | 5715 | module_param_array(tx_fifo_len, uint, NULL, 0); |
@@ -5245,6 +5727,7 @@ module_param(bimodal, bool, 0); | |||
5245 | module_param(indicate_max_pkts, int, 0); | 5727 | module_param(indicate_max_pkts, int, 0); |
5246 | #endif | 5728 | #endif |
5247 | module_param(rxsync_frequency, int, 0); | 5729 | module_param(rxsync_frequency, int, 0); |
5730 | module_param(intr_type, int, 0); | ||
5248 | 5731 | ||
5249 | /** | 5732 | /** |
5250 | * s2io_init_nic - Initialization of the adapter . | 5733 | * s2io_init_nic - Initialization of the adapter . |
@@ -5274,9 +5757,16 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5274 | mac_info_t *mac_control; | 5757 | mac_info_t *mac_control; |
5275 | struct config_param *config; | 5758 | struct config_param *config; |
5276 | int mode; | 5759 | int mode; |
5760 | u8 dev_intr_type = intr_type; | ||
5277 | 5761 | ||
5278 | #ifdef CONFIG_S2IO_NAPI | 5762 | #ifdef CONFIG_S2IO_NAPI |
5279 | DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); | 5763 | if (dev_intr_type != INTA) { |
5764 | DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \ | ||
5765 | is enabled. Defaulting to INTA\n"); | ||
5766 | dev_intr_type = INTA; | ||
5767 | } | ||
5768 | else | ||
5769 | DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); | ||
5280 | #endif | 5770 | #endif |
5281 | 5771 | ||
5282 | if ((ret = pci_enable_device(pdev))) { | 5772 | if ((ret = pci_enable_device(pdev))) { |
@@ -5303,10 +5793,35 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5303 | return -ENOMEM; | 5793 | return -ENOMEM; |
5304 | } | 5794 | } |
5305 | 5795 | ||
5306 | if (pci_request_regions(pdev, s2io_driver_name)) { | 5796 | if ((dev_intr_type == MSI_X) && |
5307 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | 5797 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && |
5308 | pci_disable_device(pdev); | 5798 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { |
5309 | return -ENODEV; | 5799 | DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \ |
5800 | Defaulting to INTA\n"); | ||
5801 | dev_intr_type = INTA; | ||
5802 | } | ||
5803 | if (dev_intr_type != MSI_X) { | ||
5804 | if (pci_request_regions(pdev, s2io_driver_name)) { | ||
5805 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | ||
5806 | pci_disable_device(pdev); | ||
5807 | return -ENODEV; | ||
5808 | } | ||
5809 | } | ||
5810 | else { | ||
5811 | if (!(request_mem_region(pci_resource_start(pdev, 0), | ||
5812 | pci_resource_len(pdev, 0), s2io_driver_name))) { | ||
5813 | DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n"); | ||
5814 | pci_disable_device(pdev); | ||
5815 | return -ENODEV; | ||
5816 | } | ||
5817 | if (!(request_mem_region(pci_resource_start(pdev, 2), | ||
5818 | pci_resource_len(pdev, 2), s2io_driver_name))) { | ||
5819 | DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n"); | ||
5820 | release_mem_region(pci_resource_start(pdev, 0), | ||
5821 | pci_resource_len(pdev, 0)); | ||
5822 | pci_disable_device(pdev); | ||
5823 | return -ENODEV; | ||
5824 | } | ||
5310 | } | 5825 | } |
5311 | 5826 | ||
5312 | dev = alloc_etherdev(sizeof(nic_t)); | 5827 | dev = alloc_etherdev(sizeof(nic_t)); |
@@ -5329,6 +5844,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5329 | sp->pdev = pdev; | 5844 | sp->pdev = pdev; |
5330 | sp->high_dma_flag = dma_flag; | 5845 | sp->high_dma_flag = dma_flag; |
5331 | sp->device_enabled_once = FALSE; | 5846 | sp->device_enabled_once = FALSE; |
5847 | sp->intr_type = dev_intr_type; | ||
5332 | 5848 | ||
5333 | if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) || | 5849 | if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) || |
5334 | (pdev->device == PCI_DEVICE_ID_HERC_UNI)) | 5850 | (pdev->device == PCI_DEVICE_ID_HERC_UNI)) |
@@ -5336,6 +5852,7 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5336 | else | 5852 | else |
5337 | sp->device_type = XFRAME_I_DEVICE; | 5853 | sp->device_type = XFRAME_I_DEVICE; |
5338 | 5854 | ||
5855 | |||
5339 | /* Initialize some PCI/PCI-X fields of the NIC. */ | 5856 | /* Initialize some PCI/PCI-X fields of the NIC. */ |
5340 | s2io_init_pci(sp); | 5857 | s2io_init_pci(sp); |
5341 | 5858 | ||
@@ -5571,12 +6088,23 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5571 | if (sp->device_type & XFRAME_II_DEVICE) { | 6088 | if (sp->device_type & XFRAME_II_DEVICE) { |
5572 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", | 6089 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", |
5573 | dev->name); | 6090 | dev->name); |
5574 | DBG_PRINT(ERR_DBG, "(rev %d), %s", | 6091 | DBG_PRINT(ERR_DBG, "(rev %d), Version %s", |
5575 | get_xena_rev_id(sp->pdev), | 6092 | get_xena_rev_id(sp->pdev), |
5576 | s2io_driver_version); | 6093 | s2io_driver_version); |
5577 | #ifdef CONFIG_2BUFF_MODE | 6094 | #ifdef CONFIG_2BUFF_MODE |
5578 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); | 6095 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); |
5579 | #endif | 6096 | #endif |
6097 | switch(sp->intr_type) { | ||
6098 | case INTA: | ||
6099 | DBG_PRINT(ERR_DBG, ", Intr type INTA"); | ||
6100 | break; | ||
6101 | case MSI: | ||
6102 | DBG_PRINT(ERR_DBG, ", Intr type MSI"); | ||
6103 | break; | ||
6104 | case MSI_X: | ||
6105 | DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); | ||
6106 | break; | ||
6107 | } | ||
5580 | 6108 | ||
5581 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | 6109 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); |
5582 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | 6110 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", |
@@ -5595,12 +6123,23 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5595 | } else { | 6123 | } else { |
5596 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", | 6124 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", |
5597 | dev->name); | 6125 | dev->name); |
5598 | DBG_PRINT(ERR_DBG, "(rev %d), %s", | 6126 | DBG_PRINT(ERR_DBG, "(rev %d), Version %s", |
5599 | get_xena_rev_id(sp->pdev), | 6127 | get_xena_rev_id(sp->pdev), |
5600 | s2io_driver_version); | 6128 | s2io_driver_version); |
5601 | #ifdef CONFIG_2BUFF_MODE | 6129 | #ifdef CONFIG_2BUFF_MODE |
5602 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); | 6130 | DBG_PRINT(ERR_DBG, ", Buffer mode %d",2); |
5603 | #endif | 6131 | #endif |
6132 | switch(sp->intr_type) { | ||
6133 | case INTA: | ||
6134 | DBG_PRINT(ERR_DBG, ", Intr type INTA"); | ||
6135 | break; | ||
6136 | case MSI: | ||
6137 | DBG_PRINT(ERR_DBG, ", Intr type MSI"); | ||
6138 | break; | ||
6139 | case MSI_X: | ||
6140 | DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); | ||
6141 | break; | ||
6142 | } | ||
5604 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | 6143 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); |
5605 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | 6144 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", |
5606 | sp->def_mac_addr[0].mac_addr[0], | 6145 | sp->def_mac_addr[0].mac_addr[0], |
@@ -5644,7 +6183,14 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
5644 | mem_alloc_failed: | 6183 | mem_alloc_failed: |
5645 | free_shared_mem(sp); | 6184 | free_shared_mem(sp); |
5646 | pci_disable_device(pdev); | 6185 | pci_disable_device(pdev); |
5647 | pci_release_regions(pdev); | 6186 | if (dev_intr_type != MSI_X) |
6187 | pci_release_regions(pdev); | ||
6188 | else { | ||
6189 | release_mem_region(pci_resource_start(pdev, 0), | ||
6190 | pci_resource_len(pdev, 0)); | ||
6191 | release_mem_region(pci_resource_start(pdev, 2), | ||
6192 | pci_resource_len(pdev, 2)); | ||
6193 | } | ||
5648 | pci_set_drvdata(pdev, NULL); | 6194 | pci_set_drvdata(pdev, NULL); |
5649 | free_netdev(dev); | 6195 | free_netdev(dev); |
5650 | 6196 | ||
@@ -5678,7 +6224,14 @@ static void __devexit s2io_rem_nic(struct pci_dev *pdev) | |||
5678 | iounmap(sp->bar0); | 6224 | iounmap(sp->bar0); |
5679 | iounmap(sp->bar1); | 6225 | iounmap(sp->bar1); |
5680 | pci_disable_device(pdev); | 6226 | pci_disable_device(pdev); |
5681 | pci_release_regions(pdev); | 6227 | if (sp->intr_type != MSI_X) |
6228 | pci_release_regions(pdev); | ||
6229 | else { | ||
6230 | release_mem_region(pci_resource_start(pdev, 0), | ||
6231 | pci_resource_len(pdev, 0)); | ||
6232 | release_mem_region(pci_resource_start(pdev, 2), | ||
6233 | pci_resource_len(pdev, 2)); | ||
6234 | } | ||
5682 | pci_set_drvdata(pdev, NULL); | 6235 | pci_set_drvdata(pdev, NULL); |
5683 | free_netdev(dev); | 6236 | free_netdev(dev); |
5684 | } | 6237 | } |