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