diff options
Diffstat (limited to 'drivers/net/s2io.c')
| -rw-r--r-- | drivers/net/s2io.c | 1476 |
1 files changed, 1107 insertions, 369 deletions
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c index 79208f434ac1..cac9fdd2e1d5 100644 --- a/drivers/net/s2io.c +++ b/drivers/net/s2io.c | |||
| @@ -26,15 +26,22 @@ | |||
| 26 | * | 26 | * |
| 27 | * The module loadable parameters that are supported by the driver and a brief | 27 | * The module loadable parameters that are supported by the driver and a brief |
| 28 | * explaination of all the variables. | 28 | * explaination of all the variables. |
| 29 | * | ||
| 29 | * rx_ring_num : This can be used to program the number of receive rings used | 30 | * rx_ring_num : This can be used to program the number of receive rings used |
| 30 | * in the driver. | 31 | * in the driver. |
| 31 | * rx_ring_sz: This defines the number of descriptors each ring can have. This | 32 | * rx_ring_sz: This defines the number of receive blocks each ring can have. |
| 32 | * is also an array of size 8. | 33 | * This is also an array of size 8. |
| 33 | * rx_ring_mode: This defines the operation mode of all 8 rings. The valid | 34 | * rx_ring_mode: This defines the operation mode of all 8 rings. The valid |
| 34 | * values are 1, 2 and 3. | 35 | * values are 1, 2 and 3. |
| 35 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. | 36 | * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver. |
| 36 | * tx_fifo_len: This too is an array of 8. Each element defines the number of | 37 | * tx_fifo_len: This too is an array of 8. Each element defines the number of |
| 37 | * Tx descriptors that can be associated with each corresponding FIFO. | 38 | * Tx descriptors that can be associated with each corresponding FIFO. |
| 39 | * intr_type: This defines the type of interrupt. The values can be 0(INTA), | ||
| 40 | * 1(MSI), 2(MSI_X). Default value is '0(INTA)' | ||
| 41 | * lro: Specifies whether to enable Large Receive Offload (LRO) or not. | ||
| 42 | * Possible values '1' for enable '0' for disable. Default is '0' | ||
| 43 | * lro_max_pkts: This parameter defines maximum number of packets can be | ||
| 44 | * aggregated as a single large packet | ||
| 38 | ************************************************************************/ | 45 | ************************************************************************/ |
| 39 | 46 | ||
| 40 | #include <linux/config.h> | 47 | #include <linux/config.h> |
| @@ -70,7 +77,7 @@ | |||
| 70 | #include "s2io.h" | 77 | #include "s2io.h" |
| 71 | #include "s2io-regs.h" | 78 | #include "s2io-regs.h" |
| 72 | 79 | ||
| 73 | #define DRV_VERSION "2.0.11.2" | 80 | #define DRV_VERSION "2.0.14.2" |
| 74 | 81 | ||
| 75 | /* S2io Driver name & version. */ | 82 | /* S2io Driver name & version. */ |
| 76 | static char s2io_driver_name[] = "Neterion"; | 83 | static char s2io_driver_name[] = "Neterion"; |
| @@ -106,18 +113,14 @@ static inline int RXD_IS_UP2DT(RxD_t *rxdp) | |||
| 106 | #define LOW 2 | 113 | #define LOW 2 |
| 107 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) | 114 | static inline int rx_buffer_level(nic_t * sp, int rxb_size, int ring) |
| 108 | { | 115 | { |
| 109 | int level = 0; | ||
| 110 | mac_info_t *mac_control; | 116 | mac_info_t *mac_control; |
| 111 | 117 | ||
| 112 | mac_control = &sp->mac_control; | 118 | mac_control = &sp->mac_control; |
| 113 | if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) { | 119 | if (rxb_size <= rxd_count[sp->rxd_mode]) |
| 114 | level = LOW; | 120 | return PANIC; |
| 115 | if (rxb_size <= rxd_count[sp->rxd_mode]) { | 121 | else if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) |
| 116 | level = PANIC; | 122 | return LOW; |
| 117 | } | 123 | return 0; |
| 118 | } | ||
| 119 | |||
| 120 | return level; | ||
| 121 | } | 124 | } |
| 122 | 125 | ||
| 123 | /* Ethtool related variables and Macros. */ | 126 | /* Ethtool related variables and Macros. */ |
| @@ -136,7 +139,11 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
| 136 | {"tmac_mcst_frms"}, | 139 | {"tmac_mcst_frms"}, |
| 137 | {"tmac_bcst_frms"}, | 140 | {"tmac_bcst_frms"}, |
| 138 | {"tmac_pause_ctrl_frms"}, | 141 | {"tmac_pause_ctrl_frms"}, |
| 142 | {"tmac_ttl_octets"}, | ||
| 143 | {"tmac_ucst_frms"}, | ||
| 144 | {"tmac_nucst_frms"}, | ||
| 139 | {"tmac_any_err_frms"}, | 145 | {"tmac_any_err_frms"}, |
| 146 | {"tmac_ttl_less_fb_octets"}, | ||
| 140 | {"tmac_vld_ip_octets"}, | 147 | {"tmac_vld_ip_octets"}, |
| 141 | {"tmac_vld_ip"}, | 148 | {"tmac_vld_ip"}, |
| 142 | {"tmac_drop_ip"}, | 149 | {"tmac_drop_ip"}, |
| @@ -151,13 +158,27 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
| 151 | {"rmac_vld_mcst_frms"}, | 158 | {"rmac_vld_mcst_frms"}, |
| 152 | {"rmac_vld_bcst_frms"}, | 159 | {"rmac_vld_bcst_frms"}, |
| 153 | {"rmac_in_rng_len_err_frms"}, | 160 | {"rmac_in_rng_len_err_frms"}, |
| 161 | {"rmac_out_rng_len_err_frms"}, | ||
| 154 | {"rmac_long_frms"}, | 162 | {"rmac_long_frms"}, |
| 155 | {"rmac_pause_ctrl_frms"}, | 163 | {"rmac_pause_ctrl_frms"}, |
| 164 | {"rmac_unsup_ctrl_frms"}, | ||
| 165 | {"rmac_ttl_octets"}, | ||
| 166 | {"rmac_accepted_ucst_frms"}, | ||
| 167 | {"rmac_accepted_nucst_frms"}, | ||
| 156 | {"rmac_discarded_frms"}, | 168 | {"rmac_discarded_frms"}, |
| 169 | {"rmac_drop_events"}, | ||
| 170 | {"rmac_ttl_less_fb_octets"}, | ||
| 171 | {"rmac_ttl_frms"}, | ||
| 157 | {"rmac_usized_frms"}, | 172 | {"rmac_usized_frms"}, |
| 158 | {"rmac_osized_frms"}, | 173 | {"rmac_osized_frms"}, |
| 159 | {"rmac_frag_frms"}, | 174 | {"rmac_frag_frms"}, |
| 160 | {"rmac_jabber_frms"}, | 175 | {"rmac_jabber_frms"}, |
| 176 | {"rmac_ttl_64_frms"}, | ||
| 177 | {"rmac_ttl_65_127_frms"}, | ||
| 178 | {"rmac_ttl_128_255_frms"}, | ||
| 179 | {"rmac_ttl_256_511_frms"}, | ||
| 180 | {"rmac_ttl_512_1023_frms"}, | ||
| 181 | {"rmac_ttl_1024_1518_frms"}, | ||
| 161 | {"rmac_ip"}, | 182 | {"rmac_ip"}, |
| 162 | {"rmac_ip_octets"}, | 183 | {"rmac_ip_octets"}, |
| 163 | {"rmac_hdr_err_ip"}, | 184 | {"rmac_hdr_err_ip"}, |
| @@ -166,12 +187,82 @@ static char ethtool_stats_keys[][ETH_GSTRING_LEN] = { | |||
| 166 | {"rmac_tcp"}, | 187 | {"rmac_tcp"}, |
| 167 | {"rmac_udp"}, | 188 | {"rmac_udp"}, |
| 168 | {"rmac_err_drp_udp"}, | 189 | {"rmac_err_drp_udp"}, |
| 190 | {"rmac_xgmii_err_sym"}, | ||
| 191 | {"rmac_frms_q0"}, | ||
| 192 | {"rmac_frms_q1"}, | ||
| 193 | {"rmac_frms_q2"}, | ||
| 194 | {"rmac_frms_q3"}, | ||
| 195 | {"rmac_frms_q4"}, | ||
| 196 | {"rmac_frms_q5"}, | ||
| 197 | {"rmac_frms_q6"}, | ||
| 198 | {"rmac_frms_q7"}, | ||
| 199 | {"rmac_full_q0"}, | ||
| 200 | {"rmac_full_q1"}, | ||
| 201 | {"rmac_full_q2"}, | ||
| 202 | {"rmac_full_q3"}, | ||
| 203 | {"rmac_full_q4"}, | ||
| 204 | {"rmac_full_q5"}, | ||
| 205 | {"rmac_full_q6"}, | ||
| 206 | {"rmac_full_q7"}, | ||
| 169 | {"rmac_pause_cnt"}, | 207 | {"rmac_pause_cnt"}, |
| 208 | {"rmac_xgmii_data_err_cnt"}, | ||
| 209 | {"rmac_xgmii_ctrl_err_cnt"}, | ||
| 170 | {"rmac_accepted_ip"}, | 210 | {"rmac_accepted_ip"}, |
| 171 | {"rmac_err_tcp"}, | 211 | {"rmac_err_tcp"}, |
| 212 | {"rd_req_cnt"}, | ||
| 213 | {"new_rd_req_cnt"}, | ||
| 214 | {"new_rd_req_rtry_cnt"}, | ||
| 215 | {"rd_rtry_cnt"}, | ||
| 216 | {"wr_rtry_rd_ack_cnt"}, | ||
| 217 | {"wr_req_cnt"}, | ||
| 218 | {"new_wr_req_cnt"}, | ||
| 219 | {"new_wr_req_rtry_cnt"}, | ||
| 220 | {"wr_rtry_cnt"}, | ||
| 221 | {"wr_disc_cnt"}, | ||
| 222 | {"rd_rtry_wr_ack_cnt"}, | ||
| 223 | {"txp_wr_cnt"}, | ||
| 224 | {"txd_rd_cnt"}, | ||
| 225 | {"txd_wr_cnt"}, | ||
| 226 | {"rxd_rd_cnt"}, | ||
| 227 | {"rxd_wr_cnt"}, | ||
| 228 | {"txf_rd_cnt"}, | ||
| 229 | {"rxf_wr_cnt"}, | ||
| 230 | {"rmac_ttl_1519_4095_frms"}, | ||
| 231 | {"rmac_ttl_4096_8191_frms"}, | ||
| 232 | {"rmac_ttl_8192_max_frms"}, | ||
| 233 | {"rmac_ttl_gt_max_frms"}, | ||
| 234 | {"rmac_osized_alt_frms"}, | ||
| 235 | {"rmac_jabber_alt_frms"}, | ||
| 236 | {"rmac_gt_max_alt_frms"}, | ||
| 237 | {"rmac_vlan_frms"}, | ||
| 238 | {"rmac_len_discard"}, | ||
| 239 | {"rmac_fcs_discard"}, | ||
| 240 | {"rmac_pf_discard"}, | ||
| 241 | {"rmac_da_discard"}, | ||
| 242 | {"rmac_red_discard"}, | ||
| 243 | {"rmac_rts_discard"}, | ||
| 244 | {"rmac_ingm_full_discard"}, | ||
| 245 | {"link_fault_cnt"}, | ||
| 172 | {"\n DRIVER STATISTICS"}, | 246 | {"\n DRIVER STATISTICS"}, |
| 173 | {"single_bit_ecc_errs"}, | 247 | {"single_bit_ecc_errs"}, |
| 174 | {"double_bit_ecc_errs"}, | 248 | {"double_bit_ecc_errs"}, |
| 249 | {"parity_err_cnt"}, | ||
| 250 | {"serious_err_cnt"}, | ||
| 251 | {"soft_reset_cnt"}, | ||
| 252 | {"fifo_full_cnt"}, | ||
| 253 | {"ring_full_cnt"}, | ||
| 254 | ("alarm_transceiver_temp_high"), | ||
| 255 | ("alarm_transceiver_temp_low"), | ||
| 256 | ("alarm_laser_bias_current_high"), | ||
| 257 | ("alarm_laser_bias_current_low"), | ||
| 258 | ("alarm_laser_output_power_high"), | ||
| 259 | ("alarm_laser_output_power_low"), | ||
| 260 | ("warn_transceiver_temp_high"), | ||
| 261 | ("warn_transceiver_temp_low"), | ||
| 262 | ("warn_laser_bias_current_high"), | ||
| 263 | ("warn_laser_bias_current_low"), | ||
| 264 | ("warn_laser_output_power_high"), | ||
| 265 | ("warn_laser_output_power_low"), | ||
| 175 | ("lro_aggregated_pkts"), | 266 | ("lro_aggregated_pkts"), |
| 176 | ("lro_flush_both_count"), | 267 | ("lro_flush_both_count"), |
| 177 | ("lro_out_of_sequence_pkts"), | 268 | ("lro_out_of_sequence_pkts"), |
| @@ -220,9 +311,7 @@ static void s2io_vlan_rx_kill_vid(struct net_device *dev, unsigned long vid) | |||
| 220 | * the XAUI. | 311 | * the XAUI. |
| 221 | */ | 312 | */ |
| 222 | 313 | ||
| 223 | #define SWITCH_SIGN 0xA5A5A5A5A5A5A5A5ULL | ||
| 224 | #define END_SIGN 0x0 | 314 | #define END_SIGN 0x0 |
| 225 | |||
| 226 | static const u64 herc_act_dtx_cfg[] = { | 315 | static const u64 herc_act_dtx_cfg[] = { |
| 227 | /* Set address */ | 316 | /* Set address */ |
| 228 | 0x8000051536750000ULL, 0x80000515367500E0ULL, | 317 | 0x8000051536750000ULL, 0x80000515367500E0ULL, |
| @@ -244,37 +333,19 @@ static const u64 herc_act_dtx_cfg[] = { | |||
| 244 | END_SIGN | 333 | END_SIGN |
| 245 | }; | 334 | }; |
| 246 | 335 | ||
| 247 | static const u64 xena_mdio_cfg[] = { | ||
| 248 | /* Reset PMA PLL */ | ||
| 249 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, | ||
| 250 | 0xC0010100008000E4ULL, | ||
| 251 | /* Remove Reset from PMA PLL */ | ||
| 252 | 0xC001010000000000ULL, 0xC0010100000000E0ULL, | ||
| 253 | 0xC0010100000000E4ULL, | ||
| 254 | END_SIGN | ||
| 255 | }; | ||
| 256 | |||
| 257 | static const u64 xena_dtx_cfg[] = { | 336 | static const u64 xena_dtx_cfg[] = { |
| 337 | /* Set address */ | ||
| 258 | 0x8000051500000000ULL, 0x80000515000000E0ULL, | 338 | 0x8000051500000000ULL, 0x80000515000000E0ULL, |
| 259 | 0x80000515D93500E4ULL, 0x8001051500000000ULL, | 339 | /* Write data */ |
| 260 | 0x80010515000000E0ULL, 0x80010515001E00E4ULL, | 340 | 0x80000515D9350004ULL, 0x80000515D93500E4ULL, |
| 261 | 0x8002051500000000ULL, 0x80020515000000E0ULL, | 341 | /* Set address */ |
| 262 | 0x80020515F21000E4ULL, | 342 | 0x8001051500000000ULL, 0x80010515000000E0ULL, |
| 263 | /* Set PADLOOPBACKN */ | 343 | /* Write data */ |
| 264 | 0x8002051500000000ULL, 0x80020515000000E0ULL, | 344 | 0x80010515001E0004ULL, 0x80010515001E00E4ULL, |
| 265 | 0x80020515B20000E4ULL, 0x8003051500000000ULL, | 345 | /* Set address */ |
| 266 | 0x80030515000000E0ULL, 0x80030515B20000E4ULL, | ||
| 267 | 0x8004051500000000ULL, 0x80040515000000E0ULL, | ||
| 268 | 0x80040515B20000E4ULL, 0x8005051500000000ULL, | ||
| 269 | 0x80050515000000E0ULL, 0x80050515B20000E4ULL, | ||
| 270 | SWITCH_SIGN, | ||
| 271 | /* Remove PADLOOPBACKN */ | ||
| 272 | 0x8002051500000000ULL, 0x80020515000000E0ULL, | 346 | 0x8002051500000000ULL, 0x80020515000000E0ULL, |
| 273 | 0x80020515F20000E4ULL, 0x8003051500000000ULL, | 347 | /* Write data */ |
| 274 | 0x80030515000000E0ULL, 0x80030515F20000E4ULL, | 348 | 0x80020515F2100004ULL, 0x80020515F21000E4ULL, |
| 275 | 0x8004051500000000ULL, 0x80040515000000E0ULL, | ||
| 276 | 0x80040515F20000E4ULL, 0x8005051500000000ULL, | ||
| 277 | 0x80050515000000E0ULL, 0x80050515F20000E4ULL, | ||
| 278 | END_SIGN | 349 | END_SIGN |
| 279 | }; | 350 | }; |
| 280 | 351 | ||
| @@ -303,15 +374,15 @@ static const u64 fix_mac[] = { | |||
| 303 | /* Module Loadable parameters. */ | 374 | /* Module Loadable parameters. */ |
| 304 | static unsigned int tx_fifo_num = 1; | 375 | static unsigned int tx_fifo_num = 1; |
| 305 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = | 376 | static unsigned int tx_fifo_len[MAX_TX_FIFOS] = |
| 306 | {[0 ...(MAX_TX_FIFOS - 1)] = 0 }; | 377 | {DEFAULT_FIFO_0_LEN, [1 ...(MAX_TX_FIFOS - 1)] = DEFAULT_FIFO_1_7_LEN}; |
| 307 | static unsigned int rx_ring_num = 1; | 378 | static unsigned int rx_ring_num = 1; |
| 308 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = | 379 | static unsigned int rx_ring_sz[MAX_RX_RINGS] = |
| 309 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 380 | {[0 ...(MAX_RX_RINGS - 1)] = SMALL_BLK_CNT}; |
| 310 | static unsigned int rts_frm_len[MAX_RX_RINGS] = | 381 | static unsigned int rts_frm_len[MAX_RX_RINGS] = |
| 311 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; | 382 | {[0 ...(MAX_RX_RINGS - 1)] = 0 }; |
| 312 | static unsigned int rx_ring_mode = 1; | 383 | static unsigned int rx_ring_mode = 1; |
| 313 | static unsigned int use_continuous_tx_intrs = 1; | 384 | static unsigned int use_continuous_tx_intrs = 1; |
| 314 | static unsigned int rmac_pause_time = 65535; | 385 | static unsigned int rmac_pause_time = 0x100; |
| 315 | static unsigned int mc_pause_threshold_q0q3 = 187; | 386 | static unsigned int mc_pause_threshold_q0q3 = 187; |
| 316 | static unsigned int mc_pause_threshold_q4q7 = 187; | 387 | static unsigned int mc_pause_threshold_q4q7 = 187; |
| 317 | static unsigned int shared_splits; | 388 | static unsigned int shared_splits; |
| @@ -549,11 +620,6 @@ static int init_shared_mem(struct s2io_nic *nic) | |||
| 549 | rx_blocks->block_dma_addr + | 620 | rx_blocks->block_dma_addr + |
| 550 | (rxd_size[nic->rxd_mode] * l); | 621 | (rxd_size[nic->rxd_mode] * l); |
| 551 | } | 622 | } |
| 552 | |||
| 553 | mac_control->rings[i].rx_blocks[j].block_virt_addr = | ||
| 554 | tmp_v_addr; | ||
| 555 | mac_control->rings[i].rx_blocks[j].block_dma_addr = | ||
| 556 | tmp_p_addr; | ||
| 557 | } | 623 | } |
| 558 | /* Interlinking all Rx Blocks */ | 624 | /* Interlinking all Rx Blocks */ |
| 559 | for (j = 0; j < blk_cnt; j++) { | 625 | for (j = 0; j < blk_cnt; j++) { |
| @@ -772,7 +838,21 @@ static int s2io_verify_pci_mode(nic_t *nic) | |||
| 772 | return mode; | 838 | return mode; |
| 773 | } | 839 | } |
| 774 | 840 | ||
| 841 | #define NEC_VENID 0x1033 | ||
| 842 | #define NEC_DEVID 0x0125 | ||
| 843 | static int s2io_on_nec_bridge(struct pci_dev *s2io_pdev) | ||
| 844 | { | ||
| 845 | struct pci_dev *tdev = NULL; | ||
| 846 | while ((tdev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, tdev)) != NULL) { | ||
| 847 | if ((tdev->vendor == NEC_VENID) && (tdev->device == NEC_DEVID)){ | ||
| 848 | if (tdev->bus == s2io_pdev->bus->parent) | ||
| 849 | return 1; | ||
| 850 | } | ||
| 851 | } | ||
| 852 | return 0; | ||
| 853 | } | ||
| 775 | 854 | ||
| 855 | static int bus_speed[8] = {33, 133, 133, 200, 266, 133, 200, 266}; | ||
| 776 | /** | 856 | /** |
| 777 | * s2io_print_pci_mode - | 857 | * s2io_print_pci_mode - |
| 778 | */ | 858 | */ |
| @@ -789,6 +869,14 @@ static int s2io_print_pci_mode(nic_t *nic) | |||
| 789 | if ( val64 & PCI_MODE_UNKNOWN_MODE) | 869 | if ( val64 & PCI_MODE_UNKNOWN_MODE) |
| 790 | return -1; /* Unknown PCI mode */ | 870 | return -1; /* Unknown PCI mode */ |
| 791 | 871 | ||
| 872 | config->bus_speed = bus_speed[mode]; | ||
| 873 | |||
| 874 | if (s2io_on_nec_bridge(nic->pdev)) { | ||
| 875 | DBG_PRINT(ERR_DBG, "%s: Device is on PCI-E bus\n", | ||
| 876 | nic->dev->name); | ||
| 877 | return mode; | ||
| 878 | } | ||
| 879 | |||
| 792 | if (val64 & PCI_MODE_32_BITS) { | 880 | if (val64 & PCI_MODE_32_BITS) { |
| 793 | DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name); | 881 | DBG_PRINT(ERR_DBG, "%s: Device is on 32 bit ", nic->dev->name); |
| 794 | } else { | 882 | } else { |
| @@ -798,35 +886,27 @@ static int s2io_print_pci_mode(nic_t *nic) | |||
| 798 | switch(mode) { | 886 | switch(mode) { |
| 799 | case PCI_MODE_PCI_33: | 887 | case PCI_MODE_PCI_33: |
| 800 | DBG_PRINT(ERR_DBG, "33MHz PCI bus\n"); | 888 | DBG_PRINT(ERR_DBG, "33MHz PCI bus\n"); |
| 801 | config->bus_speed = 33; | ||
| 802 | break; | 889 | break; |
| 803 | case PCI_MODE_PCI_66: | 890 | case PCI_MODE_PCI_66: |
| 804 | DBG_PRINT(ERR_DBG, "66MHz PCI bus\n"); | 891 | DBG_PRINT(ERR_DBG, "66MHz PCI bus\n"); |
| 805 | config->bus_speed = 133; | ||
| 806 | break; | 892 | break; |
| 807 | case PCI_MODE_PCIX_M1_66: | 893 | case PCI_MODE_PCIX_M1_66: |
| 808 | DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n"); | 894 | DBG_PRINT(ERR_DBG, "66MHz PCIX(M1) bus\n"); |
| 809 | config->bus_speed = 133; /* Herc doubles the clock rate */ | ||
| 810 | break; | 895 | break; |
| 811 | case PCI_MODE_PCIX_M1_100: | 896 | case PCI_MODE_PCIX_M1_100: |
| 812 | DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n"); | 897 | DBG_PRINT(ERR_DBG, "100MHz PCIX(M1) bus\n"); |
| 813 | config->bus_speed = 200; | ||
| 814 | break; | 898 | break; |
| 815 | case PCI_MODE_PCIX_M1_133: | 899 | case PCI_MODE_PCIX_M1_133: |
| 816 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n"); | 900 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M1) bus\n"); |
| 817 | config->bus_speed = 266; | ||
| 818 | break; | 901 | break; |
| 819 | case PCI_MODE_PCIX_M2_66: | 902 | case PCI_MODE_PCIX_M2_66: |
| 820 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n"); | 903 | DBG_PRINT(ERR_DBG, "133MHz PCIX(M2) bus\n"); |
| 821 | config->bus_speed = 133; | ||
| 822 | break; | 904 | break; |
| 823 | case PCI_MODE_PCIX_M2_100: | 905 | case PCI_MODE_PCIX_M2_100: |
| 824 | DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n"); | 906 | DBG_PRINT(ERR_DBG, "200MHz PCIX(M2) bus\n"); |
| 825 | config->bus_speed = 200; | ||
| 826 | break; | 907 | break; |
| 827 | case PCI_MODE_PCIX_M2_133: | 908 | case PCI_MODE_PCIX_M2_133: |
| 828 | DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n"); | 909 | DBG_PRINT(ERR_DBG, "266MHz PCIX(M2) bus\n"); |
| 829 | config->bus_speed = 266; | ||
| 830 | break; | 910 | break; |
| 831 | default: | 911 | default: |
| 832 | return -1; /* Unsupported bus speed */ | 912 | return -1; /* Unsupported bus speed */ |
| @@ -854,7 +934,7 @@ static int init_nic(struct s2io_nic *nic) | |||
| 854 | int i, j; | 934 | int i, j; |
| 855 | mac_info_t *mac_control; | 935 | mac_info_t *mac_control; |
| 856 | struct config_param *config; | 936 | struct config_param *config; |
| 857 | int mdio_cnt = 0, dtx_cnt = 0; | 937 | int dtx_cnt = 0; |
| 858 | unsigned long long mem_share; | 938 | unsigned long long mem_share; |
| 859 | int mem_size; | 939 | int mem_size; |
| 860 | 940 | ||
| @@ -901,20 +981,6 @@ static int init_nic(struct s2io_nic *nic) | |||
| 901 | val64 = dev->mtu; | 981 | val64 = dev->mtu; |
| 902 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); | 982 | writeq(vBIT(val64, 2, 14), &bar0->rmac_max_pyld_len); |
| 903 | 983 | ||
| 904 | /* | ||
| 905 | * Configuring the XAUI Interface of Xena. | ||
| 906 | * *************************************** | ||
| 907 | * To Configure the Xena's XAUI, one has to write a series | ||
| 908 | * of 64 bit values into two registers in a particular | ||
| 909 | * sequence. Hence a macro 'SWITCH_SIGN' has been defined | ||
| 910 | * which will be defined in the array of configuration values | ||
| 911 | * (xena_dtx_cfg & xena_mdio_cfg) at appropriate places | ||
| 912 | * to switch writing from one regsiter to another. We continue | ||
| 913 | * writing these values until we encounter the 'END_SIGN' macro. | ||
| 914 | * For example, After making a series of 21 writes into | ||
| 915 | * dtx_control register the 'SWITCH_SIGN' appears and hence we | ||
| 916 | * start writing into mdio_control until we encounter END_SIGN. | ||
| 917 | */ | ||
| 918 | if (nic->device_type & XFRAME_II_DEVICE) { | 984 | if (nic->device_type & XFRAME_II_DEVICE) { |
| 919 | while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) { | 985 | while (herc_act_dtx_cfg[dtx_cnt] != END_SIGN) { |
| 920 | SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt], | 986 | SPECIAL_REG_WRITE(herc_act_dtx_cfg[dtx_cnt], |
| @@ -924,35 +990,11 @@ static int init_nic(struct s2io_nic *nic) | |||
| 924 | dtx_cnt++; | 990 | dtx_cnt++; |
| 925 | } | 991 | } |
| 926 | } else { | 992 | } else { |
| 927 | while (1) { | 993 | while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { |
| 928 | dtx_cfg: | 994 | SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], |
| 929 | while (xena_dtx_cfg[dtx_cnt] != END_SIGN) { | 995 | &bar0->dtx_control, UF); |
| 930 | if (xena_dtx_cfg[dtx_cnt] == SWITCH_SIGN) { | 996 | val64 = readq(&bar0->dtx_control); |
| 931 | dtx_cnt++; | 997 | dtx_cnt++; |
| 932 | goto mdio_cfg; | ||
| 933 | } | ||
| 934 | SPECIAL_REG_WRITE(xena_dtx_cfg[dtx_cnt], | ||
| 935 | &bar0->dtx_control, UF); | ||
| 936 | val64 = readq(&bar0->dtx_control); | ||
| 937 | dtx_cnt++; | ||
| 938 | } | ||
| 939 | mdio_cfg: | ||
| 940 | while (xena_mdio_cfg[mdio_cnt] != END_SIGN) { | ||
| 941 | if (xena_mdio_cfg[mdio_cnt] == SWITCH_SIGN) { | ||
| 942 | mdio_cnt++; | ||
| 943 | goto dtx_cfg; | ||
| 944 | } | ||
| 945 | SPECIAL_REG_WRITE(xena_mdio_cfg[mdio_cnt], | ||
| 946 | &bar0->mdio_control, UF); | ||
| 947 | val64 = readq(&bar0->mdio_control); | ||
| 948 | mdio_cnt++; | ||
| 949 | } | ||
| 950 | if ((xena_dtx_cfg[dtx_cnt] == END_SIGN) && | ||
| 951 | (xena_mdio_cfg[mdio_cnt] == END_SIGN)) { | ||
| 952 | break; | ||
| 953 | } else { | ||
| 954 | goto dtx_cfg; | ||
| 955 | } | ||
| 956 | } | 998 | } |
| 957 | } | 999 | } |
| 958 | 1000 | ||
| @@ -994,11 +1036,6 @@ static int init_nic(struct s2io_nic *nic) | |||
| 994 | } | 1036 | } |
| 995 | } | 1037 | } |
| 996 | 1038 | ||
| 997 | /* Enable Tx FIFO partition 0. */ | ||
| 998 | val64 = readq(&bar0->tx_fifo_partition_0); | ||
| 999 | val64 |= BIT(0); /* To enable the FIFO partition. */ | ||
| 1000 | writeq(val64, &bar0->tx_fifo_partition_0); | ||
| 1001 | |||
| 1002 | /* | 1039 | /* |
| 1003 | * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug | 1040 | * Disable 4 PCCs for Xena1, 2 and 3 as per H/W bug |
| 1004 | * SXE-008 TRANSMIT DMA ARBITRATION ISSUE. | 1041 | * SXE-008 TRANSMIT DMA ARBITRATION ISSUE. |
| @@ -1177,6 +1214,11 @@ static int init_nic(struct s2io_nic *nic) | |||
| 1177 | break; | 1214 | break; |
| 1178 | } | 1215 | } |
| 1179 | 1216 | ||
| 1217 | /* Enable Tx FIFO partition 0. */ | ||
| 1218 | val64 = readq(&bar0->tx_fifo_partition_0); | ||
| 1219 | val64 |= (TX_FIFO_PARTITION_EN); | ||
| 1220 | writeq(val64, &bar0->tx_fifo_partition_0); | ||
| 1221 | |||
| 1180 | /* Filling the Rx round robin registers as per the | 1222 | /* Filling the Rx round robin registers as per the |
| 1181 | * number of Rings and steering based on QoS. | 1223 | * number of Rings and steering based on QoS. |
| 1182 | */ | 1224 | */ |
| @@ -1545,19 +1587,26 @@ static int init_nic(struct s2io_nic *nic) | |||
| 1545 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); | 1587 | val64 |= PIC_CNTL_SHARED_SPLITS(shared_splits); |
| 1546 | writeq(val64, &bar0->pic_control); | 1588 | writeq(val64, &bar0->pic_control); |
| 1547 | 1589 | ||
| 1590 | if (nic->config.bus_speed == 266) { | ||
| 1591 | writeq(TXREQTO_VAL(0x7f) | TXREQTO_EN, &bar0->txreqtimeout); | ||
| 1592 | writeq(0x0, &bar0->read_retry_delay); | ||
| 1593 | writeq(0x0, &bar0->write_retry_delay); | ||
| 1594 | } | ||
| 1595 | |||
| 1548 | /* | 1596 | /* |
| 1549 | * Programming the Herc to split every write transaction | 1597 | * Programming the Herc to split every write transaction |
| 1550 | * that does not start on an ADB to reduce disconnects. | 1598 | * that does not start on an ADB to reduce disconnects. |
| 1551 | */ | 1599 | */ |
| 1552 | if (nic->device_type == XFRAME_II_DEVICE) { | 1600 | if (nic->device_type == XFRAME_II_DEVICE) { |
| 1553 | val64 = WREQ_SPLIT_MASK_SET_MASK(255); | 1601 | val64 = EXT_REQ_EN | MISC_LINK_STABILITY_PRD(3); |
| 1554 | writeq(val64, &bar0->wreq_split_mask); | ||
| 1555 | } | ||
| 1556 | |||
| 1557 | /* Setting Link stability period to 64 ms */ | ||
| 1558 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
| 1559 | val64 = MISC_LINK_STABILITY_PRD(3); | ||
| 1560 | writeq(val64, &bar0->misc_control); | 1602 | writeq(val64, &bar0->misc_control); |
| 1603 | val64 = readq(&bar0->pic_control2); | ||
| 1604 | val64 &= ~(BIT(13)|BIT(14)|BIT(15)); | ||
| 1605 | writeq(val64, &bar0->pic_control2); | ||
| 1606 | } | ||
| 1607 | if (strstr(nic->product_name, "CX4")) { | ||
| 1608 | val64 = TMAC_AVG_IPG(0x17); | ||
| 1609 | writeq(val64, &bar0->tmac_avg_ipg); | ||
| 1561 | } | 1610 | } |
| 1562 | 1611 | ||
| 1563 | return SUCCESS; | 1612 | return SUCCESS; |
| @@ -1948,6 +1997,10 @@ static int start_nic(struct s2io_nic *nic) | |||
| 1948 | val64 |= PRC_CTRL_RC_ENABLED; | 1997 | val64 |= PRC_CTRL_RC_ENABLED; |
| 1949 | else | 1998 | else |
| 1950 | val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3; | 1999 | val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3; |
| 2000 | if (nic->device_type == XFRAME_II_DEVICE) | ||
| 2001 | val64 |= PRC_CTRL_GROUP_READS; | ||
| 2002 | val64 &= ~PRC_CTRL_RXD_BACKOFF_INTERVAL(0xFFFFFF); | ||
| 2003 | val64 |= PRC_CTRL_RXD_BACKOFF_INTERVAL(0x1000); | ||
| 1951 | writeq(val64, &bar0->prc_ctrl_n[i]); | 2004 | writeq(val64, &bar0->prc_ctrl_n[i]); |
| 1952 | } | 2005 | } |
| 1953 | 2006 | ||
| @@ -2018,6 +2071,13 @@ static int start_nic(struct s2io_nic *nic) | |||
| 2018 | val64 |= ADAPTER_EOI_TX_ON; | 2071 | val64 |= ADAPTER_EOI_TX_ON; |
| 2019 | writeq(val64, &bar0->adapter_control); | 2072 | writeq(val64, &bar0->adapter_control); |
| 2020 | 2073 | ||
| 2074 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { | ||
| 2075 | /* | ||
| 2076 | * Dont see link state interrupts initally on some switches, | ||
| 2077 | * so directly scheduling the link state task here. | ||
| 2078 | */ | ||
| 2079 | schedule_work(&nic->set_link_task); | ||
| 2080 | } | ||
| 2021 | /* SXE-002: Initialize link and activity LED */ | 2081 | /* SXE-002: Initialize link and activity LED */ |
| 2022 | subid = nic->pdev->subsystem_device; | 2082 | subid = nic->pdev->subsystem_device; |
| 2023 | if (((subid & 0xFF) >= 0x07) && | 2083 | if (((subid & 0xFF) >= 0x07) && |
| @@ -2029,12 +2089,6 @@ static int start_nic(struct s2io_nic *nic) | |||
| 2029 | writeq(val64, (void __iomem *)bar0 + 0x2700); | 2089 | writeq(val64, (void __iomem *)bar0 + 0x2700); |
| 2030 | } | 2090 | } |
| 2031 | 2091 | ||
| 2032 | /* | ||
| 2033 | * Don't see link state interrupts on certain switches, so | ||
| 2034 | * directly scheduling a link state task from here. | ||
| 2035 | */ | ||
| 2036 | schedule_work(&nic->set_link_task); | ||
| 2037 | |||
| 2038 | return SUCCESS; | 2092 | return SUCCESS; |
| 2039 | } | 2093 | } |
| 2040 | /** | 2094 | /** |
| @@ -2134,7 +2188,7 @@ static void stop_nic(struct s2io_nic *nic) | |||
| 2134 | { | 2188 | { |
| 2135 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2189 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
| 2136 | register u64 val64 = 0; | 2190 | register u64 val64 = 0; |
| 2137 | u16 interruptible, i; | 2191 | u16 interruptible; |
| 2138 | mac_info_t *mac_control; | 2192 | mac_info_t *mac_control; |
| 2139 | struct config_param *config; | 2193 | struct config_param *config; |
| 2140 | 2194 | ||
| @@ -2147,12 +2201,10 @@ static void stop_nic(struct s2io_nic *nic) | |||
| 2147 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; | 2201 | interruptible |= TX_MAC_INTR | RX_MAC_INTR; |
| 2148 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); | 2202 | en_dis_able_nic_intrs(nic, interruptible, DISABLE_INTRS); |
| 2149 | 2203 | ||
| 2150 | /* Disable PRCs */ | 2204 | /* Clearing Adapter_En bit of ADAPTER_CONTROL Register */ |
| 2151 | for (i = 0; i < config->rx_ring_num; i++) { | 2205 | val64 = readq(&bar0->adapter_control); |
| 2152 | val64 = readq(&bar0->prc_ctrl_n[i]); | 2206 | val64 &= ~(ADAPTER_CNTL_EN); |
| 2153 | val64 &= ~((u64) PRC_CTRL_RC_ENABLED); | 2207 | writeq(val64, &bar0->adapter_control); |
| 2154 | writeq(val64, &bar0->prc_ctrl_n[i]); | ||
| 2155 | } | ||
| 2156 | } | 2208 | } |
| 2157 | 2209 | ||
| 2158 | static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) | 2210 | static int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb) |
| @@ -2231,13 +2283,12 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
| 2231 | alloc_cnt = mac_control->rings[ring_no].pkt_cnt - | 2283 | alloc_cnt = mac_control->rings[ring_no].pkt_cnt - |
| 2232 | atomic_read(&nic->rx_bufs_left[ring_no]); | 2284 | atomic_read(&nic->rx_bufs_left[ring_no]); |
| 2233 | 2285 | ||
| 2286 | block_no1 = mac_control->rings[ring_no].rx_curr_get_info.block_index; | ||
| 2287 | off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; | ||
| 2234 | while (alloc_tab < alloc_cnt) { | 2288 | while (alloc_tab < alloc_cnt) { |
| 2235 | block_no = mac_control->rings[ring_no].rx_curr_put_info. | 2289 | block_no = mac_control->rings[ring_no].rx_curr_put_info. |
| 2236 | block_index; | 2290 | block_index; |
| 2237 | block_no1 = mac_control->rings[ring_no].rx_curr_get_info. | ||
| 2238 | block_index; | ||
| 2239 | off = mac_control->rings[ring_no].rx_curr_put_info.offset; | 2291 | off = mac_control->rings[ring_no].rx_curr_put_info.offset; |
| 2240 | off1 = mac_control->rings[ring_no].rx_curr_get_info.offset; | ||
| 2241 | 2292 | ||
| 2242 | rxdp = mac_control->rings[ring_no]. | 2293 | rxdp = mac_control->rings[ring_no]. |
| 2243 | rx_blocks[block_no].rxds[off].virt_addr; | 2294 | rx_blocks[block_no].rxds[off].virt_addr; |
| @@ -2307,9 +2358,9 @@ static int fill_rx_buffers(struct s2io_nic *nic, int ring_no) | |||
| 2307 | memset(rxdp, 0, sizeof(RxD1_t)); | 2358 | memset(rxdp, 0, sizeof(RxD1_t)); |
| 2308 | skb_reserve(skb, NET_IP_ALIGN); | 2359 | skb_reserve(skb, NET_IP_ALIGN); |
| 2309 | ((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single | 2360 | ((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single |
| 2310 | (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE); | 2361 | (nic->pdev, skb->data, size - NET_IP_ALIGN, |
| 2311 | rxdp->Control_2 &= (~MASK_BUFFER0_SIZE_1); | 2362 | PCI_DMA_FROMDEVICE); |
| 2312 | rxdp->Control_2 |= SET_BUFFER0_SIZE_1(size); | 2363 | rxdp->Control_2 = SET_BUFFER0_SIZE_1(size - NET_IP_ALIGN); |
| 2313 | 2364 | ||
| 2314 | } else if (nic->rxd_mode >= RXD_MODE_3A) { | 2365 | } else if (nic->rxd_mode >= RXD_MODE_3A) { |
| 2315 | /* | 2366 | /* |
| @@ -2516,7 +2567,7 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
| 2516 | mac_info_t *mac_control; | 2567 | mac_info_t *mac_control; |
| 2517 | struct config_param *config; | 2568 | struct config_param *config; |
| 2518 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 2569 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
| 2519 | u64 val64; | 2570 | u64 val64 = 0xFFFFFFFFFFFFFFFFULL; |
| 2520 | int i; | 2571 | int i; |
| 2521 | 2572 | ||
| 2522 | atomic_inc(&nic->isr_cnt); | 2573 | atomic_inc(&nic->isr_cnt); |
| @@ -2528,8 +2579,8 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
| 2528 | nic->pkts_to_process = dev->quota; | 2579 | nic->pkts_to_process = dev->quota; |
| 2529 | org_pkts_to_process = nic->pkts_to_process; | 2580 | org_pkts_to_process = nic->pkts_to_process; |
| 2530 | 2581 | ||
| 2531 | val64 = readq(&bar0->rx_traffic_int); | ||
| 2532 | writeq(val64, &bar0->rx_traffic_int); | 2582 | writeq(val64, &bar0->rx_traffic_int); |
| 2583 | val64 = readl(&bar0->rx_traffic_int); | ||
| 2533 | 2584 | ||
| 2534 | for (i = 0; i < config->rx_ring_num; i++) { | 2585 | for (i = 0; i < config->rx_ring_num; i++) { |
| 2535 | rx_intr_handler(&mac_control->rings[i]); | 2586 | rx_intr_handler(&mac_control->rings[i]); |
| @@ -2554,7 +2605,8 @@ static int s2io_poll(struct net_device *dev, int *budget) | |||
| 2554 | } | 2605 | } |
| 2555 | } | 2606 | } |
| 2556 | /* Re enable the Rx interrupts. */ | 2607 | /* Re enable the Rx interrupts. */ |
| 2557 | en_dis_able_nic_intrs(nic, RX_TRAFFIC_INTR, ENABLE_INTRS); | 2608 | writeq(0x0, &bar0->rx_traffic_mask); |
| 2609 | val64 = readl(&bar0->rx_traffic_mask); | ||
| 2558 | atomic_dec(&nic->isr_cnt); | 2610 | atomic_dec(&nic->isr_cnt); |
| 2559 | return 0; | 2611 | return 0; |
| 2560 | 2612 | ||
| @@ -2666,6 +2718,7 @@ static void rx_intr_handler(ring_info_t *ring_data) | |||
| 2666 | ((RxD3_t*)rxdp)->Buffer2_ptr, | 2718 | ((RxD3_t*)rxdp)->Buffer2_ptr, |
| 2667 | dev->mtu, PCI_DMA_FROMDEVICE); | 2719 | dev->mtu, PCI_DMA_FROMDEVICE); |
| 2668 | } | 2720 | } |
| 2721 | prefetch(skb->data); | ||
| 2669 | rx_osm_handler(ring_data, rxdp); | 2722 | rx_osm_handler(ring_data, rxdp); |
| 2670 | get_info.offset++; | 2723 | get_info.offset++; |
| 2671 | ring_data->rx_curr_get_info.offset = get_info.offset; | 2724 | ring_data->rx_curr_get_info.offset = get_info.offset; |
| @@ -2737,6 +2790,10 @@ static void tx_intr_handler(fifo_info_t *fifo_data) | |||
| 2737 | if (txdlp->Control_1 & TXD_T_CODE) { | 2790 | if (txdlp->Control_1 & TXD_T_CODE) { |
| 2738 | unsigned long long err; | 2791 | unsigned long long err; |
| 2739 | err = txdlp->Control_1 & TXD_T_CODE; | 2792 | err = txdlp->Control_1 & TXD_T_CODE; |
| 2793 | if (err & 0x1) { | ||
| 2794 | nic->mac_control.stats_info->sw_stat. | ||
| 2795 | parity_err_cnt++; | ||
| 2796 | } | ||
| 2740 | if ((err >> 48) == 0xA) { | 2797 | if ((err >> 48) == 0xA) { |
| 2741 | DBG_PRINT(TX_DBG, "TxD returned due \ | 2798 | DBG_PRINT(TX_DBG, "TxD returned due \ |
| 2742 | to loss of link\n"); | 2799 | to loss of link\n"); |
| @@ -2760,7 +2817,8 @@ to loss of link\n"); | |||
| 2760 | dev_kfree_skb_irq(skb); | 2817 | dev_kfree_skb_irq(skb); |
| 2761 | 2818 | ||
| 2762 | get_info.offset++; | 2819 | get_info.offset++; |
| 2763 | get_info.offset %= get_info.fifo_len + 1; | 2820 | if (get_info.offset == get_info.fifo_len + 1) |
| 2821 | get_info.offset = 0; | ||
| 2764 | txdlp = (TxD_t *) fifo_data->list_info | 2822 | txdlp = (TxD_t *) fifo_data->list_info |
| 2765 | [get_info.offset].list_virt_addr; | 2823 | [get_info.offset].list_virt_addr; |
| 2766 | fifo_data->tx_curr_get_info.offset = | 2824 | fifo_data->tx_curr_get_info.offset = |
| @@ -2774,6 +2832,256 @@ to loss of link\n"); | |||
| 2774 | } | 2832 | } |
| 2775 | 2833 | ||
| 2776 | /** | 2834 | /** |
| 2835 | * s2io_mdio_write - Function to write in to MDIO registers | ||
| 2836 | * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) | ||
| 2837 | * @addr : address value | ||
| 2838 | * @value : data value | ||
| 2839 | * @dev : pointer to net_device structure | ||
| 2840 | * Description: | ||
| 2841 | * This function is used to write values to the MDIO registers | ||
| 2842 | * NONE | ||
| 2843 | */ | ||
| 2844 | static void s2io_mdio_write(u32 mmd_type, u64 addr, u16 value, struct net_device *dev) | ||
| 2845 | { | ||
| 2846 | u64 val64 = 0x0; | ||
| 2847 | nic_t *sp = dev->priv; | ||
| 2848 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | ||
| 2849 | |||
| 2850 | //address transaction | ||
| 2851 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | ||
| 2852 | | MDIO_MMD_DEV_ADDR(mmd_type) | ||
| 2853 | | MDIO_MMS_PRT_ADDR(0x0); | ||
| 2854 | writeq(val64, &bar0->mdio_control); | ||
| 2855 | val64 = val64 | MDIO_CTRL_START_TRANS(0xE); | ||
| 2856 | writeq(val64, &bar0->mdio_control); | ||
| 2857 | udelay(100); | ||
| 2858 | |||
| 2859 | //Data transaction | ||
| 2860 | val64 = 0x0; | ||
| 2861 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | ||
| 2862 | | MDIO_MMD_DEV_ADDR(mmd_type) | ||
| 2863 | | MDIO_MMS_PRT_ADDR(0x0) | ||
| 2864 | | MDIO_MDIO_DATA(value) | ||
| 2865 | | MDIO_OP(MDIO_OP_WRITE_TRANS); | ||
| 2866 | writeq(val64, &bar0->mdio_control); | ||
| 2867 | val64 = val64 | MDIO_CTRL_START_TRANS(0xE); | ||
| 2868 | writeq(val64, &bar0->mdio_control); | ||
| 2869 | udelay(100); | ||
| 2870 | |||
| 2871 | val64 = 0x0; | ||
| 2872 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | ||
| 2873 | | MDIO_MMD_DEV_ADDR(mmd_type) | ||
| 2874 | | MDIO_MMS_PRT_ADDR(0x0) | ||
| 2875 | | MDIO_OP(MDIO_OP_READ_TRANS); | ||
| 2876 | writeq(val64, &bar0->mdio_control); | ||
| 2877 | val64 = val64 | MDIO_CTRL_START_TRANS(0xE); | ||
| 2878 | writeq(val64, &bar0->mdio_control); | ||
| 2879 | udelay(100); | ||
| 2880 | |||
| 2881 | } | ||
| 2882 | |||
| 2883 | /** | ||
| 2884 | * s2io_mdio_read - Function to write in to MDIO registers | ||
| 2885 | * @mmd_type : MMD type value (PMA/PMD/WIS/PCS/PHYXS) | ||
| 2886 | * @addr : address value | ||
| 2887 | * @dev : pointer to net_device structure | ||
| 2888 | * Description: | ||
| 2889 | * This function is used to read values to the MDIO registers | ||
| 2890 | * NONE | ||
| 2891 | */ | ||
| 2892 | static u64 s2io_mdio_read(u32 mmd_type, u64 addr, struct net_device *dev) | ||
| 2893 | { | ||
| 2894 | u64 val64 = 0x0; | ||
| 2895 | u64 rval64 = 0x0; | ||
| 2896 | nic_t *sp = dev->priv; | ||
| 2897 | XENA_dev_config_t *bar0 = (XENA_dev_config_t *)sp->bar0; | ||
| 2898 | |||
| 2899 | /* address transaction */ | ||
| 2900 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | ||
| 2901 | | MDIO_MMD_DEV_ADDR(mmd_type) | ||
| 2902 | | MDIO_MMS_PRT_ADDR(0x0); | ||
| 2903 | writeq(val64, &bar0->mdio_control); | ||
| 2904 | val64 = val64 | MDIO_CTRL_START_TRANS(0xE); | ||
| 2905 | writeq(val64, &bar0->mdio_control); | ||
| 2906 | udelay(100); | ||
| 2907 | |||
| 2908 | /* Data transaction */ | ||
| 2909 | val64 = 0x0; | ||
| 2910 | val64 = val64 | MDIO_MMD_INDX_ADDR(addr) | ||
| 2911 | | MDIO_MMD_DEV_ADDR(mmd_type) | ||
| 2912 | | MDIO_MMS_PRT_ADDR(0x0) | ||
| 2913 | | MDIO_OP(MDIO_OP_READ_TRANS); | ||
| 2914 | writeq(val64, &bar0->mdio_control); | ||
| 2915 | val64 = val64 | MDIO_CTRL_START_TRANS(0xE); | ||
| 2916 | writeq(val64, &bar0->mdio_control); | ||
| 2917 | udelay(100); | ||
| 2918 | |||
| 2919 | /* Read the value from regs */ | ||
| 2920 | rval64 = readq(&bar0->mdio_control); | ||
| 2921 | rval64 = rval64 & 0xFFFF0000; | ||
| 2922 | rval64 = rval64 >> 16; | ||
| 2923 | return rval64; | ||
| 2924 | } | ||
| 2925 | /** | ||
| 2926 | * s2io_chk_xpak_counter - Function to check the status of the xpak counters | ||
| 2927 | * @counter : couter value to be updated | ||
| 2928 | * @flag : flag to indicate the status | ||
| 2929 | * @type : counter type | ||
| 2930 | * Description: | ||
| 2931 | * This function is to check the status of the xpak counters value | ||
| 2932 | * NONE | ||
| 2933 | */ | ||
| 2934 | |||
| 2935 | static void s2io_chk_xpak_counter(u64 *counter, u64 * regs_stat, u32 index, u16 flag, u16 type) | ||
| 2936 | { | ||
| 2937 | u64 mask = 0x3; | ||
| 2938 | u64 val64; | ||
| 2939 | int i; | ||
| 2940 | for(i = 0; i <index; i++) | ||
| 2941 | mask = mask << 0x2; | ||
| 2942 | |||
| 2943 | if(flag > 0) | ||
| 2944 | { | ||
| 2945 | *counter = *counter + 1; | ||
| 2946 | val64 = *regs_stat & mask; | ||
| 2947 | val64 = val64 >> (index * 0x2); | ||
| 2948 | val64 = val64 + 1; | ||
| 2949 | if(val64 == 3) | ||
| 2950 | { | ||
| 2951 | switch(type) | ||
| 2952 | { | ||
| 2953 | case 1: | ||
| 2954 | DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " | ||
| 2955 | "service. Excessive temperatures may " | ||
| 2956 | "result in premature transceiver " | ||
| 2957 | "failure \n"); | ||
| 2958 | break; | ||
| 2959 | case 2: | ||
| 2960 | DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " | ||
| 2961 | "service Excessive bias currents may " | ||
| 2962 | "indicate imminent laser diode " | ||
| 2963 | "failure \n"); | ||
| 2964 | break; | ||
| 2965 | case 3: | ||
| 2966 | DBG_PRINT(ERR_DBG, "Take Xframe NIC out of " | ||
| 2967 | "service Excessive laser output " | ||
| 2968 | "power may saturate far-end " | ||
| 2969 | "receiver\n"); | ||
| 2970 | break; | ||
| 2971 | default: | ||
| 2972 | DBG_PRINT(ERR_DBG, "Incorrect XPAK Alarm " | ||
| 2973 | "type \n"); | ||
| 2974 | } | ||
| 2975 | val64 = 0x0; | ||
| 2976 | } | ||
| 2977 | val64 = val64 << (index * 0x2); | ||
| 2978 | *regs_stat = (*regs_stat & (~mask)) | (val64); | ||
| 2979 | |||
| 2980 | } else { | ||
| 2981 | *regs_stat = *regs_stat & (~mask); | ||
| 2982 | } | ||
| 2983 | } | ||
| 2984 | |||
| 2985 | /** | ||
| 2986 | * s2io_updt_xpak_counter - Function to update the xpak counters | ||
| 2987 | * @dev : pointer to net_device struct | ||
| 2988 | * Description: | ||
| 2989 | * This function is to upate the status of the xpak counters value | ||
| 2990 | * NONE | ||
| 2991 | */ | ||
| 2992 | static void s2io_updt_xpak_counter(struct net_device *dev) | ||
| 2993 | { | ||
| 2994 | u16 flag = 0x0; | ||
| 2995 | u16 type = 0x0; | ||
| 2996 | u16 val16 = 0x0; | ||
| 2997 | u64 val64 = 0x0; | ||
| 2998 | u64 addr = 0x0; | ||
| 2999 | |||
| 3000 | nic_t *sp = dev->priv; | ||
| 3001 | StatInfo_t *stat_info = sp->mac_control.stats_info; | ||
| 3002 | |||
| 3003 | /* Check the communication with the MDIO slave */ | ||
| 3004 | addr = 0x0000; | ||
| 3005 | val64 = 0x0; | ||
| 3006 | val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); | ||
| 3007 | if((val64 == 0xFFFF) || (val64 == 0x0000)) | ||
| 3008 | { | ||
| 3009 | DBG_PRINT(ERR_DBG, "ERR: MDIO slave access failed - " | ||
| 3010 | "Returned %llx\n", (unsigned long long)val64); | ||
| 3011 | return; | ||
| 3012 | } | ||
| 3013 | |||
| 3014 | /* Check for the expecte value of 2040 at PMA address 0x0000 */ | ||
| 3015 | if(val64 != 0x2040) | ||
| 3016 | { | ||
| 3017 | DBG_PRINT(ERR_DBG, "Incorrect value at PMA address 0x0000 - "); | ||
| 3018 | DBG_PRINT(ERR_DBG, "Returned: %llx- Expected: 0x2040\n", | ||
| 3019 | (unsigned long long)val64); | ||
| 3020 | return; | ||
| 3021 | } | ||
| 3022 | |||
| 3023 | /* Loading the DOM register to MDIO register */ | ||
| 3024 | addr = 0xA100; | ||
| 3025 | s2io_mdio_write(MDIO_MMD_PMA_DEV_ADDR, addr, val16, dev); | ||
| 3026 | val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); | ||
| 3027 | |||
| 3028 | /* Reading the Alarm flags */ | ||
| 3029 | addr = 0xA070; | ||
| 3030 | val64 = 0x0; | ||
| 3031 | val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); | ||
| 3032 | |||
| 3033 | flag = CHECKBIT(val64, 0x7); | ||
| 3034 | type = 1; | ||
| 3035 | s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_transceiver_temp_high, | ||
| 3036 | &stat_info->xpak_stat.xpak_regs_stat, | ||
| 3037 | 0x0, flag, type); | ||
| 3038 | |||
| 3039 | if(CHECKBIT(val64, 0x6)) | ||
| 3040 | stat_info->xpak_stat.alarm_transceiver_temp_low++; | ||
| 3041 | |||
| 3042 | flag = CHECKBIT(val64, 0x3); | ||
| 3043 | type = 2; | ||
| 3044 | s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_bias_current_high, | ||
| 3045 | &stat_info->xpak_stat.xpak_regs_stat, | ||
| 3046 | 0x2, flag, type); | ||
| 3047 | |||
| 3048 | if(CHECKBIT(val64, 0x2)) | ||
| 3049 | stat_info->xpak_stat.alarm_laser_bias_current_low++; | ||
| 3050 | |||
| 3051 | flag = CHECKBIT(val64, 0x1); | ||
| 3052 | type = 3; | ||
| 3053 | s2io_chk_xpak_counter(&stat_info->xpak_stat.alarm_laser_output_power_high, | ||
| 3054 | &stat_info->xpak_stat.xpak_regs_stat, | ||
| 3055 | 0x4, flag, type); | ||
| 3056 | |||
| 3057 | if(CHECKBIT(val64, 0x0)) | ||
| 3058 | stat_info->xpak_stat.alarm_laser_output_power_low++; | ||
| 3059 | |||
| 3060 | /* Reading the Warning flags */ | ||
| 3061 | addr = 0xA074; | ||
| 3062 | val64 = 0x0; | ||
| 3063 | val64 = s2io_mdio_read(MDIO_MMD_PMA_DEV_ADDR, addr, dev); | ||
| 3064 | |||
| 3065 | if(CHECKBIT(val64, 0x7)) | ||
| 3066 | stat_info->xpak_stat.warn_transceiver_temp_high++; | ||
| 3067 | |||
| 3068 | if(CHECKBIT(val64, 0x6)) | ||
| 3069 | stat_info->xpak_stat.warn_transceiver_temp_low++; | ||
| 3070 | |||
| 3071 | if(CHECKBIT(val64, 0x3)) | ||
| 3072 | stat_info->xpak_stat.warn_laser_bias_current_high++; | ||
| 3073 | |||
| 3074 | if(CHECKBIT(val64, 0x2)) | ||
| 3075 | stat_info->xpak_stat.warn_laser_bias_current_low++; | ||
| 3076 | |||
| 3077 | if(CHECKBIT(val64, 0x1)) | ||
| 3078 | stat_info->xpak_stat.warn_laser_output_power_high++; | ||
| 3079 | |||
| 3080 | if(CHECKBIT(val64, 0x0)) | ||
| 3081 | stat_info->xpak_stat.warn_laser_output_power_low++; | ||
| 3082 | } | ||
| 3083 | |||
| 3084 | /** | ||
| 2777 | * alarm_intr_handler - Alarm Interrrupt handler | 3085 | * alarm_intr_handler - Alarm Interrrupt handler |
| 2778 | * @nic: device private variable | 3086 | * @nic: device private variable |
| 2779 | * Description: If the interrupt was neither because of Rx packet or Tx | 3087 | * Description: If the interrupt was neither because of Rx packet or Tx |
| @@ -2790,6 +3098,18 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2790 | struct net_device *dev = (struct net_device *) nic->dev; | 3098 | struct net_device *dev = (struct net_device *) nic->dev; |
| 2791 | XENA_dev_config_t __iomem *bar0 = nic->bar0; | 3099 | XENA_dev_config_t __iomem *bar0 = nic->bar0; |
| 2792 | register u64 val64 = 0, err_reg = 0; | 3100 | register u64 val64 = 0, err_reg = 0; |
| 3101 | u64 cnt; | ||
| 3102 | int i; | ||
| 3103 | nic->mac_control.stats_info->sw_stat.ring_full_cnt = 0; | ||
| 3104 | /* Handling the XPAK counters update */ | ||
| 3105 | if(nic->mac_control.stats_info->xpak_stat.xpak_timer_count < 72000) { | ||
| 3106 | /* waiting for an hour */ | ||
| 3107 | nic->mac_control.stats_info->xpak_stat.xpak_timer_count++; | ||
| 3108 | } else { | ||
| 3109 | s2io_updt_xpak_counter(dev); | ||
| 3110 | /* reset the count to zero */ | ||
| 3111 | nic->mac_control.stats_info->xpak_stat.xpak_timer_count = 0; | ||
| 3112 | } | ||
| 2793 | 3113 | ||
| 2794 | /* Handling link status change error Intr */ | 3114 | /* Handling link status change error Intr */ |
| 2795 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { | 3115 | if (s2io_link_fault_indication(nic) == MAC_RMAC_ERR_TIMER) { |
| @@ -2816,6 +3136,8 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2816 | MC_ERR_REG_MIRI_ECC_DB_ERR_1)) { | 3136 | MC_ERR_REG_MIRI_ECC_DB_ERR_1)) { |
| 2817 | netif_stop_queue(dev); | 3137 | netif_stop_queue(dev); |
| 2818 | schedule_work(&nic->rst_timer_task); | 3138 | schedule_work(&nic->rst_timer_task); |
| 3139 | nic->mac_control.stats_info->sw_stat. | ||
| 3140 | soft_reset_cnt++; | ||
| 2819 | } | 3141 | } |
| 2820 | } | 3142 | } |
| 2821 | } else { | 3143 | } else { |
| @@ -2827,11 +3149,13 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2827 | /* In case of a serious error, the device will be Reset. */ | 3149 | /* In case of a serious error, the device will be Reset. */ |
| 2828 | val64 = readq(&bar0->serr_source); | 3150 | val64 = readq(&bar0->serr_source); |
| 2829 | if (val64 & SERR_SOURCE_ANY) { | 3151 | if (val64 & SERR_SOURCE_ANY) { |
| 3152 | nic->mac_control.stats_info->sw_stat.serious_err_cnt++; | ||
| 2830 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); | 3153 | DBG_PRINT(ERR_DBG, "%s: Device indicates ", dev->name); |
| 2831 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", | 3154 | DBG_PRINT(ERR_DBG, "serious error %llx!!\n", |
| 2832 | (unsigned long long)val64); | 3155 | (unsigned long long)val64); |
| 2833 | netif_stop_queue(dev); | 3156 | netif_stop_queue(dev); |
| 2834 | schedule_work(&nic->rst_timer_task); | 3157 | schedule_work(&nic->rst_timer_task); |
| 3158 | nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; | ||
| 2835 | } | 3159 | } |
| 2836 | 3160 | ||
| 2837 | /* | 3161 | /* |
| @@ -2849,6 +3173,35 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2849 | ac = readq(&bar0->adapter_control); | 3173 | ac = readq(&bar0->adapter_control); |
| 2850 | schedule_work(&nic->set_link_task); | 3174 | schedule_work(&nic->set_link_task); |
| 2851 | } | 3175 | } |
| 3176 | /* Check for data parity error */ | ||
| 3177 | val64 = readq(&bar0->pic_int_status); | ||
| 3178 | if (val64 & PIC_INT_GPIO) { | ||
| 3179 | val64 = readq(&bar0->gpio_int_reg); | ||
| 3180 | if (val64 & GPIO_INT_REG_DP_ERR_INT) { | ||
| 3181 | nic->mac_control.stats_info->sw_stat.parity_err_cnt++; | ||
| 3182 | schedule_work(&nic->rst_timer_task); | ||
| 3183 | nic->mac_control.stats_info->sw_stat.soft_reset_cnt++; | ||
| 3184 | } | ||
| 3185 | } | ||
| 3186 | |||
| 3187 | /* Check for ring full counter */ | ||
| 3188 | if (nic->device_type & XFRAME_II_DEVICE) { | ||
| 3189 | val64 = readq(&bar0->ring_bump_counter1); | ||
| 3190 | for (i=0; i<4; i++) { | ||
| 3191 | cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
| 3192 | cnt >>= 64 - ((i+1)*16); | ||
| 3193 | nic->mac_control.stats_info->sw_stat.ring_full_cnt | ||
| 3194 | += cnt; | ||
| 3195 | } | ||
| 3196 | |||
| 3197 | val64 = readq(&bar0->ring_bump_counter2); | ||
| 3198 | for (i=0; i<4; i++) { | ||
| 3199 | cnt = ( val64 & vBIT(0xFFFF,(i*16),16)); | ||
| 3200 | cnt >>= 64 - ((i+1)*16); | ||
| 3201 | nic->mac_control.stats_info->sw_stat.ring_full_cnt | ||
| 3202 | += cnt; | ||
| 3203 | } | ||
| 3204 | } | ||
| 2852 | 3205 | ||
| 2853 | /* Other type of interrupts are not being handled now, TODO */ | 3206 | /* Other type of interrupts are not being handled now, TODO */ |
| 2854 | } | 3207 | } |
| @@ -2864,23 +3217,26 @@ static void alarm_intr_handler(struct s2io_nic *nic) | |||
| 2864 | * SUCCESS on success and FAILURE on failure. | 3217 | * SUCCESS on success and FAILURE on failure. |
| 2865 | */ | 3218 | */ |
| 2866 | 3219 | ||
| 2867 | static int wait_for_cmd_complete(nic_t * sp) | 3220 | static int wait_for_cmd_complete(void *addr, u64 busy_bit) |
| 2868 | { | 3221 | { |
| 2869 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | ||
| 2870 | int ret = FAILURE, cnt = 0; | 3222 | int ret = FAILURE, cnt = 0; |
| 2871 | u64 val64; | 3223 | u64 val64; |
| 2872 | 3224 | ||
| 2873 | while (TRUE) { | 3225 | while (TRUE) { |
| 2874 | val64 = readq(&bar0->rmac_addr_cmd_mem); | 3226 | val64 = readq(addr); |
| 2875 | if (!(val64 & RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { | 3227 | if (!(val64 & busy_bit)) { |
| 2876 | ret = SUCCESS; | 3228 | ret = SUCCESS; |
| 2877 | break; | 3229 | break; |
| 2878 | } | 3230 | } |
| 2879 | msleep(50); | 3231 | |
| 3232 | if(in_interrupt()) | ||
| 3233 | mdelay(50); | ||
| 3234 | else | ||
| 3235 | msleep(50); | ||
| 3236 | |||
| 2880 | if (cnt++ > 10) | 3237 | if (cnt++ > 10) |
| 2881 | break; | 3238 | break; |
| 2882 | } | 3239 | } |
| 2883 | |||
| 2884 | return ret; | 3240 | return ret; |
| 2885 | } | 3241 | } |
| 2886 | 3242 | ||
| @@ -2919,6 +3275,9 @@ static void s2io_reset(nic_t * sp) | |||
| 2919 | * PCI write to sw_reset register is done by this time. | 3275 | * PCI write to sw_reset register is done by this time. |
| 2920 | */ | 3276 | */ |
| 2921 | msleep(250); | 3277 | msleep(250); |
| 3278 | if (strstr(sp->product_name, "CX4")) { | ||
| 3279 | msleep(750); | ||
| 3280 | } | ||
| 2922 | 3281 | ||
| 2923 | /* Restore the PCI state saved during initialization. */ | 3282 | /* Restore the PCI state saved during initialization. */ |
| 2924 | pci_restore_state(sp->pdev); | 3283 | pci_restore_state(sp->pdev); |
| @@ -3137,7 +3496,7 @@ static void restore_xmsi_data(nic_t *nic) | |||
| 3137 | u64 val64; | 3496 | u64 val64; |
| 3138 | int i; | 3497 | int i; |
| 3139 | 3498 | ||
| 3140 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3499 | for (i=0; i< nic->avail_msix_vectors; i++) { |
| 3141 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); | 3500 | writeq(nic->msix_info[i].addr, &bar0->xmsi_address); |
| 3142 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); | 3501 | writeq(nic->msix_info[i].data, &bar0->xmsi_data); |
| 3143 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); | 3502 | val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6)); |
| @@ -3156,7 +3515,7 @@ static void store_xmsi_data(nic_t *nic) | |||
| 3156 | int i; | 3515 | int i; |
| 3157 | 3516 | ||
| 3158 | /* Store and display */ | 3517 | /* Store and display */ |
| 3159 | for (i=0; i< MAX_REQUESTED_MSI_X; i++) { | 3518 | for (i=0; i< nic->avail_msix_vectors; i++) { |
| 3160 | val64 = (BIT(15) | vBIT(i, 26, 6)); | 3519 | val64 = (BIT(15) | vBIT(i, 26, 6)); |
| 3161 | writeq(val64, &bar0->xmsi_access); | 3520 | writeq(val64, &bar0->xmsi_access); |
| 3162 | if (wait_for_msix_trans(nic, i)) { | 3521 | if (wait_for_msix_trans(nic, i)) { |
| @@ -3284,15 +3643,24 @@ static int s2io_enable_msi_x(nic_t *nic) | |||
| 3284 | writeq(tx_mat, &bar0->tx_mat0_n[7]); | 3643 | writeq(tx_mat, &bar0->tx_mat0_n[7]); |
| 3285 | } | 3644 | } |
| 3286 | 3645 | ||
| 3646 | nic->avail_msix_vectors = 0; | ||
| 3287 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); | 3647 | ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X); |
| 3648 | /* We fail init if error or we get less vectors than min required */ | ||
| 3649 | if (ret >= (nic->config.tx_fifo_num + nic->config.rx_ring_num + 1)) { | ||
| 3650 | nic->avail_msix_vectors = ret; | ||
| 3651 | ret = pci_enable_msix(nic->pdev, nic->entries, ret); | ||
| 3652 | } | ||
| 3288 | if (ret) { | 3653 | if (ret) { |
| 3289 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); | 3654 | DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name); |
| 3290 | kfree(nic->entries); | 3655 | kfree(nic->entries); |
| 3291 | kfree(nic->s2io_entries); | 3656 | kfree(nic->s2io_entries); |
| 3292 | nic->entries = NULL; | 3657 | nic->entries = NULL; |
| 3293 | nic->s2io_entries = NULL; | 3658 | nic->s2io_entries = NULL; |
| 3659 | nic->avail_msix_vectors = 0; | ||
| 3294 | return -ENOMEM; | 3660 | return -ENOMEM; |
| 3295 | } | 3661 | } |
| 3662 | if (!nic->avail_msix_vectors) | ||
| 3663 | nic->avail_msix_vectors = MAX_REQUESTED_MSI_X; | ||
| 3296 | 3664 | ||
| 3297 | /* | 3665 | /* |
| 3298 | * To enable MSI-X, MSI also needs to be enabled, due to a bug | 3666 | * To enable MSI-X, MSI also needs to be enabled, due to a bug |
| @@ -3325,8 +3693,6 @@ static int s2io_open(struct net_device *dev) | |||
| 3325 | { | 3693 | { |
| 3326 | nic_t *sp = dev->priv; | 3694 | nic_t *sp = dev->priv; |
| 3327 | int err = 0; | 3695 | int err = 0; |
| 3328 | int i; | ||
| 3329 | u16 msi_control; /* Temp variable */ | ||
| 3330 | 3696 | ||
| 3331 | /* | 3697 | /* |
| 3332 | * Make sure you have link off by default every time | 3698 | * Make sure you have link off by default every time |
| @@ -3336,11 +3702,14 @@ static int s2io_open(struct net_device *dev) | |||
| 3336 | sp->last_link_state = 0; | 3702 | sp->last_link_state = 0; |
| 3337 | 3703 | ||
| 3338 | /* Initialize H/W and enable interrupts */ | 3704 | /* Initialize H/W and enable interrupts */ |
| 3339 | if (s2io_card_up(sp)) { | 3705 | err = s2io_card_up(sp); |
| 3706 | if (err) { | ||
| 3340 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", | 3707 | DBG_PRINT(ERR_DBG, "%s: H/W initialization failed\n", |
| 3341 | dev->name); | 3708 | dev->name); |
| 3342 | err = -ENODEV; | 3709 | if (err == -ENODEV) |
| 3343 | goto hw_init_failed; | 3710 | goto hw_init_failed; |
| 3711 | else | ||
| 3712 | goto hw_enable_failed; | ||
| 3344 | } | 3713 | } |
| 3345 | 3714 | ||
| 3346 | /* Store the values of the MSIX table in the nic_t structure */ | 3715 | /* Store the values of the MSIX table in the nic_t structure */ |
| @@ -3357,6 +3726,8 @@ failed\n", dev->name); | |||
| 3357 | } | 3726 | } |
| 3358 | } | 3727 | } |
| 3359 | if (sp->intr_type == MSI_X) { | 3728 | if (sp->intr_type == MSI_X) { |
| 3729 | int i; | ||
| 3730 | |||
| 3360 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { | 3731 | for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) { |
| 3361 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { | 3732 | if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) { |
| 3362 | sprintf(sp->desc1, "%s:MSI-X-%d-TX", | 3733 | sprintf(sp->desc1, "%s:MSI-X-%d-TX", |
| @@ -3409,24 +3780,26 @@ setting_mac_address_failed: | |||
| 3409 | isr_registration_failed: | 3780 | isr_registration_failed: |
| 3410 | del_timer_sync(&sp->alarm_timer); | 3781 | del_timer_sync(&sp->alarm_timer); |
| 3411 | if (sp->intr_type == MSI_X) { | 3782 | if (sp->intr_type == MSI_X) { |
| 3412 | if (sp->device_type == XFRAME_II_DEVICE) { | 3783 | int i; |
| 3413 | for (i=1; (sp->s2io_entries[i].in_use == | 3784 | u16 msi_control; /* Temp variable */ |
| 3414 | MSIX_REGISTERED_SUCCESS); i++) { | ||
| 3415 | int vector = sp->entries[i].vector; | ||
| 3416 | void *arg = sp->s2io_entries[i].arg; | ||
| 3417 | 3785 | ||
| 3418 | free_irq(vector, arg); | 3786 | for (i=1; (sp->s2io_entries[i].in_use == |
| 3419 | } | 3787 | MSIX_REGISTERED_SUCCESS); i++) { |
| 3420 | pci_disable_msix(sp->pdev); | 3788 | int vector = sp->entries[i].vector; |
| 3789 | void *arg = sp->s2io_entries[i].arg; | ||
| 3421 | 3790 | ||
| 3422 | /* Temp */ | 3791 | free_irq(vector, arg); |
| 3423 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
| 3424 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
| 3425 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
| 3426 | } | 3792 | } |
| 3793 | pci_disable_msix(sp->pdev); | ||
| 3794 | |||
| 3795 | /* Temp */ | ||
| 3796 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
| 3797 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
| 3798 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
| 3427 | } | 3799 | } |
| 3428 | else if (sp->intr_type == MSI) | 3800 | else if (sp->intr_type == MSI) |
| 3429 | pci_disable_msi(sp->pdev); | 3801 | pci_disable_msi(sp->pdev); |
| 3802 | hw_enable_failed: | ||
| 3430 | s2io_reset(sp); | 3803 | s2io_reset(sp); |
| 3431 | hw_init_failed: | 3804 | hw_init_failed: |
| 3432 | if (sp->intr_type == MSI_X) { | 3805 | if (sp->intr_type == MSI_X) { |
| @@ -3454,35 +3827,12 @@ hw_init_failed: | |||
| 3454 | static int s2io_close(struct net_device *dev) | 3827 | static int s2io_close(struct net_device *dev) |
| 3455 | { | 3828 | { |
| 3456 | nic_t *sp = dev->priv; | 3829 | nic_t *sp = dev->priv; |
| 3457 | int i; | ||
| 3458 | u16 msi_control; | ||
| 3459 | 3830 | ||
| 3460 | flush_scheduled_work(); | 3831 | flush_scheduled_work(); |
| 3461 | netif_stop_queue(dev); | 3832 | netif_stop_queue(dev); |
| 3462 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ | 3833 | /* Reset card, kill tasklet and free Tx and Rx buffers. */ |
| 3463 | s2io_card_down(sp); | 3834 | s2io_card_down(sp, 1); |
| 3464 | |||
| 3465 | if (sp->intr_type == MSI_X) { | ||
| 3466 | if (sp->device_type == XFRAME_II_DEVICE) { | ||
| 3467 | for (i=1; (sp->s2io_entries[i].in_use == | ||
| 3468 | MSIX_REGISTERED_SUCCESS); i++) { | ||
| 3469 | int vector = sp->entries[i].vector; | ||
| 3470 | void *arg = sp->s2io_entries[i].arg; | ||
| 3471 | 3835 | ||
| 3472 | free_irq(vector, arg); | ||
| 3473 | } | ||
| 3474 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
| 3475 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
| 3476 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
| 3477 | |||
| 3478 | pci_disable_msix(sp->pdev); | ||
| 3479 | } | ||
| 3480 | } | ||
| 3481 | else { | ||
| 3482 | free_irq(sp->pdev->irq, dev); | ||
| 3483 | if (sp->intr_type == MSI) | ||
| 3484 | pci_disable_msi(sp->pdev); | ||
| 3485 | } | ||
| 3486 | sp->device_close_flag = TRUE; /* Device is shut down. */ | 3836 | sp->device_close_flag = TRUE; /* Device is shut down. */ |
| 3487 | return 0; | 3837 | return 0; |
| 3488 | } | 3838 | } |
| @@ -3545,7 +3895,8 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3545 | 3895 | ||
| 3546 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | 3896 | queue_len = mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; |
| 3547 | /* Avoid "put" pointer going beyond "get" pointer */ | 3897 | /* Avoid "put" pointer going beyond "get" pointer */ |
| 3548 | if (txdp->Host_Control || (((put_off + 1) % queue_len) == get_off)) { | 3898 | if (txdp->Host_Control || |
| 3899 | ((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { | ||
| 3549 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); | 3900 | DBG_PRINT(TX_DBG, "Error in xmit, No free TXDs.\n"); |
| 3550 | netif_stop_queue(dev); | 3901 | netif_stop_queue(dev); |
| 3551 | dev_kfree_skb(skb); | 3902 | dev_kfree_skb(skb); |
| @@ -3655,11 +4006,13 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev) | |||
| 3655 | mmiowb(); | 4006 | mmiowb(); |
| 3656 | 4007 | ||
| 3657 | put_off++; | 4008 | put_off++; |
| 3658 | put_off %= mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1; | 4009 | if (put_off == mac_control->fifos[queue].tx_curr_put_info.fifo_len + 1) |
| 4010 | put_off = 0; | ||
| 3659 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; | 4011 | mac_control->fifos[queue].tx_curr_put_info.offset = put_off; |
| 3660 | 4012 | ||
| 3661 | /* Avoid "put" pointer going beyond "get" pointer */ | 4013 | /* Avoid "put" pointer going beyond "get" pointer */ |
| 3662 | if (((put_off + 1) % queue_len) == get_off) { | 4014 | if (((put_off+1) == queue_len ? 0 : (put_off+1)) == get_off) { |
| 4015 | sp->mac_control.stats_info->sw_stat.fifo_full_cnt++; | ||
| 3663 | DBG_PRINT(TX_DBG, | 4016 | DBG_PRINT(TX_DBG, |
| 3664 | "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", | 4017 | "No free TxDs for xmit, Put: 0x%x Get:0x%x\n", |
| 3665 | put_off, get_off); | 4018 | put_off, get_off); |
| @@ -3795,7 +4148,6 @@ s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs) | |||
| 3795 | atomic_dec(&sp->isr_cnt); | 4148 | atomic_dec(&sp->isr_cnt); |
| 3796 | return IRQ_HANDLED; | 4149 | return IRQ_HANDLED; |
| 3797 | } | 4150 | } |
| 3798 | |||
| 3799 | static void s2io_txpic_intr_handle(nic_t *sp) | 4151 | static void s2io_txpic_intr_handle(nic_t *sp) |
| 3800 | { | 4152 | { |
| 3801 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4153 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
| @@ -3806,41 +4158,56 @@ static void s2io_txpic_intr_handle(nic_t *sp) | |||
| 3806 | val64 = readq(&bar0->gpio_int_reg); | 4158 | val64 = readq(&bar0->gpio_int_reg); |
| 3807 | if ((val64 & GPIO_INT_REG_LINK_DOWN) && | 4159 | if ((val64 & GPIO_INT_REG_LINK_DOWN) && |
| 3808 | (val64 & GPIO_INT_REG_LINK_UP)) { | 4160 | (val64 & GPIO_INT_REG_LINK_UP)) { |
| 4161 | /* | ||
| 4162 | * This is unstable state so clear both up/down | ||
| 4163 | * interrupt and adapter to re-evaluate the link state. | ||
| 4164 | */ | ||
| 3809 | val64 |= GPIO_INT_REG_LINK_DOWN; | 4165 | val64 |= GPIO_INT_REG_LINK_DOWN; |
| 3810 | val64 |= GPIO_INT_REG_LINK_UP; | 4166 | val64 |= GPIO_INT_REG_LINK_UP; |
| 3811 | writeq(val64, &bar0->gpio_int_reg); | 4167 | writeq(val64, &bar0->gpio_int_reg); |
| 3812 | goto masking; | ||
| 3813 | } | ||
| 3814 | |||
| 3815 | if (((sp->last_link_state == LINK_UP) && | ||
| 3816 | (val64 & GPIO_INT_REG_LINK_DOWN)) || | ||
| 3817 | ((sp->last_link_state == LINK_DOWN) && | ||
| 3818 | (val64 & GPIO_INT_REG_LINK_UP))) { | ||
| 3819 | val64 = readq(&bar0->gpio_int_mask); | 4168 | val64 = readq(&bar0->gpio_int_mask); |
| 3820 | val64 |= GPIO_INT_MASK_LINK_DOWN; | 4169 | val64 &= ~(GPIO_INT_MASK_LINK_UP | |
| 3821 | val64 |= GPIO_INT_MASK_LINK_UP; | 4170 | GPIO_INT_MASK_LINK_DOWN); |
| 3822 | writeq(val64, &bar0->gpio_int_mask); | 4171 | writeq(val64, &bar0->gpio_int_mask); |
| 3823 | s2io_set_link((unsigned long)sp); | ||
| 3824 | } | 4172 | } |
| 3825 | masking: | 4173 | else if (val64 & GPIO_INT_REG_LINK_UP) { |
| 3826 | if (sp->last_link_state == LINK_UP) { | 4174 | val64 = readq(&bar0->adapter_status); |
| 3827 | /*enable down interrupt */ | 4175 | if (verify_xena_quiescence(sp, val64, |
| 3828 | val64 = readq(&bar0->gpio_int_mask); | 4176 | sp->device_enabled_once)) { |
| 3829 | /* unmasks link down intr */ | 4177 | /* Enable Adapter */ |
| 3830 | val64 &= ~GPIO_INT_MASK_LINK_DOWN; | 4178 | val64 = readq(&bar0->adapter_control); |
| 3831 | /* masks link up intr */ | 4179 | val64 |= ADAPTER_CNTL_EN; |
| 3832 | val64 |= GPIO_INT_MASK_LINK_UP; | 4180 | writeq(val64, &bar0->adapter_control); |
| 3833 | writeq(val64, &bar0->gpio_int_mask); | 4181 | val64 |= ADAPTER_LED_ON; |
| 3834 | } else { | 4182 | writeq(val64, &bar0->adapter_control); |
| 3835 | /*enable UP Interrupt */ | 4183 | if (!sp->device_enabled_once) |
| 3836 | val64 = readq(&bar0->gpio_int_mask); | 4184 | sp->device_enabled_once = 1; |
| 3837 | /* unmasks link up interrupt */ | 4185 | |
| 3838 | val64 &= ~GPIO_INT_MASK_LINK_UP; | 4186 | s2io_link(sp, LINK_UP); |
| 3839 | /* masks link down interrupt */ | 4187 | /* |
| 3840 | val64 |= GPIO_INT_MASK_LINK_DOWN; | 4188 | * unmask link down interrupt and mask link-up |
| 3841 | writeq(val64, &bar0->gpio_int_mask); | 4189 | * intr |
| 4190 | */ | ||
| 4191 | val64 = readq(&bar0->gpio_int_mask); | ||
| 4192 | val64 &= ~GPIO_INT_MASK_LINK_DOWN; | ||
| 4193 | val64 |= GPIO_INT_MASK_LINK_UP; | ||
| 4194 | writeq(val64, &bar0->gpio_int_mask); | ||
| 4195 | |||
| 4196 | } | ||
| 4197 | }else if (val64 & GPIO_INT_REG_LINK_DOWN) { | ||
| 4198 | val64 = readq(&bar0->adapter_status); | ||
| 4199 | if (verify_xena_quiescence(sp, val64, | ||
| 4200 | sp->device_enabled_once)) { | ||
| 4201 | s2io_link(sp, LINK_DOWN); | ||
| 4202 | /* Link is down so unmaks link up interrupt */ | ||
| 4203 | val64 = readq(&bar0->gpio_int_mask); | ||
| 4204 | val64 &= ~GPIO_INT_MASK_LINK_UP; | ||
| 4205 | val64 |= GPIO_INT_MASK_LINK_DOWN; | ||
| 4206 | writeq(val64, &bar0->gpio_int_mask); | ||
| 4207 | } | ||
| 3842 | } | 4208 | } |
| 3843 | } | 4209 | } |
| 4210 | val64 = readq(&bar0->gpio_int_mask); | ||
| 3844 | } | 4211 | } |
| 3845 | 4212 | ||
| 3846 | /** | 4213 | /** |
| @@ -3863,7 +4230,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 3863 | nic_t *sp = dev->priv; | 4230 | nic_t *sp = dev->priv; |
| 3864 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 4231 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
| 3865 | int i; | 4232 | int i; |
| 3866 | u64 reason = 0, val64; | 4233 | u64 reason = 0, val64, org_mask; |
| 3867 | mac_info_t *mac_control; | 4234 | mac_info_t *mac_control; |
| 3868 | struct config_param *config; | 4235 | struct config_param *config; |
| 3869 | 4236 | ||
| @@ -3887,43 +4254,41 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 3887 | return IRQ_NONE; | 4254 | return IRQ_NONE; |
| 3888 | } | 4255 | } |
| 3889 | 4256 | ||
| 4257 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
| 4258 | /* Store current mask before masking all interrupts */ | ||
| 4259 | org_mask = readq(&bar0->general_int_mask); | ||
| 4260 | writeq(val64, &bar0->general_int_mask); | ||
| 4261 | |||
| 3890 | #ifdef CONFIG_S2IO_NAPI | 4262 | #ifdef CONFIG_S2IO_NAPI |
| 3891 | if (reason & GEN_INTR_RXTRAFFIC) { | 4263 | if (reason & GEN_INTR_RXTRAFFIC) { |
| 3892 | if (netif_rx_schedule_prep(dev)) { | 4264 | if (netif_rx_schedule_prep(dev)) { |
| 3893 | en_dis_able_nic_intrs(sp, RX_TRAFFIC_INTR, | 4265 | writeq(val64, &bar0->rx_traffic_mask); |
| 3894 | DISABLE_INTRS); | ||
| 3895 | __netif_rx_schedule(dev); | 4266 | __netif_rx_schedule(dev); |
| 3896 | } | 4267 | } |
| 3897 | } | 4268 | } |
| 3898 | #else | 4269 | #else |
| 3899 | /* If Intr is because of Rx Traffic */ | 4270 | /* |
| 3900 | if (reason & GEN_INTR_RXTRAFFIC) { | 4271 | * Rx handler is called by default, without checking for the |
| 3901 | /* | 4272 | * cause of interrupt. |
| 3902 | * rx_traffic_int reg is an R1 register, writing all 1's | 4273 | * rx_traffic_int reg is an R1 register, writing all 1's |
| 3903 | * will ensure that the actual interrupt causing bit get's | 4274 | * will ensure that the actual interrupt causing bit get's |
| 3904 | * cleared and hence a read can be avoided. | 4275 | * cleared and hence a read can be avoided. |
| 3905 | */ | 4276 | */ |
| 3906 | val64 = 0xFFFFFFFFFFFFFFFFULL; | 4277 | writeq(val64, &bar0->rx_traffic_int); |
| 3907 | writeq(val64, &bar0->rx_traffic_int); | 4278 | for (i = 0; i < config->rx_ring_num; i++) { |
| 3908 | for (i = 0; i < config->rx_ring_num; i++) { | 4279 | rx_intr_handler(&mac_control->rings[i]); |
| 3909 | rx_intr_handler(&mac_control->rings[i]); | ||
| 3910 | } | ||
| 3911 | } | 4280 | } |
| 3912 | #endif | 4281 | #endif |
| 3913 | 4282 | ||
| 3914 | /* If Intr is because of Tx Traffic */ | 4283 | /* |
| 3915 | if (reason & GEN_INTR_TXTRAFFIC) { | 4284 | * tx_traffic_int reg is an R1 register, writing all 1's |
| 3916 | /* | 4285 | * will ensure that the actual interrupt causing bit get's |
| 3917 | * tx_traffic_int reg is an R1 register, writing all 1's | 4286 | * cleared and hence a read can be avoided. |
| 3918 | * will ensure that the actual interrupt causing bit get's | 4287 | */ |
| 3919 | * cleared and hence a read can be avoided. | 4288 | writeq(val64, &bar0->tx_traffic_int); |
| 3920 | */ | ||
| 3921 | val64 = 0xFFFFFFFFFFFFFFFFULL; | ||
| 3922 | writeq(val64, &bar0->tx_traffic_int); | ||
| 3923 | 4289 | ||
| 3924 | for (i = 0; i < config->tx_fifo_num; i++) | 4290 | for (i = 0; i < config->tx_fifo_num; i++) |
| 3925 | tx_intr_handler(&mac_control->fifos[i]); | 4291 | tx_intr_handler(&mac_control->fifos[i]); |
| 3926 | } | ||
| 3927 | 4292 | ||
| 3928 | if (reason & GEN_INTR_TXPIC) | 4293 | if (reason & GEN_INTR_TXPIC) |
| 3929 | s2io_txpic_intr_handle(sp); | 4294 | s2io_txpic_intr_handle(sp); |
| @@ -3949,6 +4314,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 3949 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); | 4314 | DBG_PRINT(ERR_DBG, " in ISR!!\n"); |
| 3950 | clear_bit(0, (&sp->tasklet_status)); | 4315 | clear_bit(0, (&sp->tasklet_status)); |
| 3951 | atomic_dec(&sp->isr_cnt); | 4316 | atomic_dec(&sp->isr_cnt); |
| 4317 | writeq(org_mask, &bar0->general_int_mask); | ||
| 3952 | return IRQ_HANDLED; | 4318 | return IRQ_HANDLED; |
| 3953 | } | 4319 | } |
| 3954 | clear_bit(0, (&sp->tasklet_status)); | 4320 | clear_bit(0, (&sp->tasklet_status)); |
| @@ -3964,7 +4330,7 @@ static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs) | |||
| 3964 | } | 4330 | } |
| 3965 | } | 4331 | } |
| 3966 | #endif | 4332 | #endif |
| 3967 | 4333 | writeq(org_mask, &bar0->general_int_mask); | |
| 3968 | atomic_dec(&sp->isr_cnt); | 4334 | atomic_dec(&sp->isr_cnt); |
| 3969 | return IRQ_HANDLED; | 4335 | return IRQ_HANDLED; |
| 3970 | } | 4336 | } |
| @@ -4067,7 +4433,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 4067 | RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); | 4433 | RMAC_ADDR_CMD_MEM_OFFSET(MAC_MC_ALL_MC_ADDR_OFFSET); |
| 4068 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4434 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 4069 | /* Wait till command completes */ | 4435 | /* Wait till command completes */ |
| 4070 | wait_for_cmd_complete(sp); | 4436 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 4437 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); | ||
| 4071 | 4438 | ||
| 4072 | sp->m_cast_flg = 1; | 4439 | sp->m_cast_flg = 1; |
| 4073 | sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; | 4440 | sp->all_multi_pos = MAC_MC_ALL_MC_ADDR_OFFSET; |
| @@ -4082,7 +4449,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 4082 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); | 4449 | RMAC_ADDR_CMD_MEM_OFFSET(sp->all_multi_pos); |
| 4083 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4450 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 4084 | /* Wait till command completes */ | 4451 | /* Wait till command completes */ |
| 4085 | wait_for_cmd_complete(sp); | 4452 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 4453 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); | ||
| 4086 | 4454 | ||
| 4087 | sp->m_cast_flg = 0; | 4455 | sp->m_cast_flg = 0; |
| 4088 | sp->all_multi_pos = 0; | 4456 | sp->all_multi_pos = 0; |
| @@ -4147,7 +4515,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 4147 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4515 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 4148 | 4516 | ||
| 4149 | /* Wait for command completes */ | 4517 | /* Wait for command completes */ |
| 4150 | if (wait_for_cmd_complete(sp)) { | 4518 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 4519 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { | ||
| 4151 | DBG_PRINT(ERR_DBG, "%s: Adding ", | 4520 | DBG_PRINT(ERR_DBG, "%s: Adding ", |
| 4152 | dev->name); | 4521 | dev->name); |
| 4153 | DBG_PRINT(ERR_DBG, "Multicasts failed\n"); | 4522 | DBG_PRINT(ERR_DBG, "Multicasts failed\n"); |
| @@ -4177,7 +4546,8 @@ static void s2io_set_multicast(struct net_device *dev) | |||
| 4177 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4546 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 4178 | 4547 | ||
| 4179 | /* Wait for command completes */ | 4548 | /* Wait for command completes */ |
| 4180 | if (wait_for_cmd_complete(sp)) { | 4549 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 4550 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { | ||
| 4181 | DBG_PRINT(ERR_DBG, "%s: Adding ", | 4551 | DBG_PRINT(ERR_DBG, "%s: Adding ", |
| 4182 | dev->name); | 4552 | dev->name); |
| 4183 | DBG_PRINT(ERR_DBG, "Multicasts failed\n"); | 4553 | DBG_PRINT(ERR_DBG, "Multicasts failed\n"); |
| @@ -4222,7 +4592,8 @@ static int s2io_set_mac_addr(struct net_device *dev, u8 * addr) | |||
| 4222 | RMAC_ADDR_CMD_MEM_OFFSET(0); | 4592 | RMAC_ADDR_CMD_MEM_OFFSET(0); |
| 4223 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 4593 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 4224 | /* Wait till command completes */ | 4594 | /* Wait till command completes */ |
| 4225 | if (wait_for_cmd_complete(sp)) { | 4595 | if (wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 4596 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING)) { | ||
| 4226 | DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name); | 4597 | DBG_PRINT(ERR_DBG, "%s: set_mac_addr failed\n", dev->name); |
| 4227 | return FAILURE; | 4598 | return FAILURE; |
| 4228 | } | 4599 | } |
| @@ -4619,6 +4990,44 @@ static int write_eeprom(nic_t * sp, int off, u64 data, int cnt) | |||
| 4619 | } | 4990 | } |
| 4620 | return ret; | 4991 | return ret; |
| 4621 | } | 4992 | } |
| 4993 | static void s2io_vpd_read(nic_t *nic) | ||
| 4994 | { | ||
| 4995 | u8 vpd_data[256],data; | ||
| 4996 | int i=0, cnt, fail = 0; | ||
| 4997 | int vpd_addr = 0x80; | ||
| 4998 | |||
| 4999 | if (nic->device_type == XFRAME_II_DEVICE) { | ||
| 5000 | strcpy(nic->product_name, "Xframe II 10GbE network adapter"); | ||
| 5001 | vpd_addr = 0x80; | ||
| 5002 | } | ||
| 5003 | else { | ||
| 5004 | strcpy(nic->product_name, "Xframe I 10GbE network adapter"); | ||
| 5005 | vpd_addr = 0x50; | ||
| 5006 | } | ||
| 5007 | |||
| 5008 | for (i = 0; i < 256; i +=4 ) { | ||
| 5009 | pci_write_config_byte(nic->pdev, (vpd_addr + 2), i); | ||
| 5010 | pci_read_config_byte(nic->pdev, (vpd_addr + 2), &data); | ||
| 5011 | pci_write_config_byte(nic->pdev, (vpd_addr + 3), 0); | ||
| 5012 | for (cnt = 0; cnt <5; cnt++) { | ||
| 5013 | msleep(2); | ||
| 5014 | pci_read_config_byte(nic->pdev, (vpd_addr + 3), &data); | ||
| 5015 | if (data == 0x80) | ||
| 5016 | break; | ||
| 5017 | } | ||
| 5018 | if (cnt >= 5) { | ||
| 5019 | DBG_PRINT(ERR_DBG, "Read of VPD data failed\n"); | ||
| 5020 | fail = 1; | ||
| 5021 | break; | ||
| 5022 | } | ||
| 5023 | pci_read_config_dword(nic->pdev, (vpd_addr + 4), | ||
| 5024 | (u32 *)&vpd_data[i]); | ||
| 5025 | } | ||
| 5026 | if ((!fail) && (vpd_data[1] < VPD_PRODUCT_NAME_LEN)) { | ||
| 5027 | memset(nic->product_name, 0, vpd_data[1]); | ||
| 5028 | memcpy(nic->product_name, &vpd_data[3], vpd_data[1]); | ||
| 5029 | } | ||
| 5030 | } | ||
| 4622 | 5031 | ||
| 4623 | /** | 5032 | /** |
| 4624 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. | 5033 | * s2io_ethtool_geeprom - reads the value stored in the Eeprom. |
| @@ -4931,8 +5340,10 @@ static int s2io_link_test(nic_t * sp, uint64_t * data) | |||
| 4931 | u64 val64; | 5340 | u64 val64; |
| 4932 | 5341 | ||
| 4933 | val64 = readq(&bar0->adapter_status); | 5342 | val64 = readq(&bar0->adapter_status); |
| 4934 | if (val64 & ADAPTER_STATUS_RMAC_LOCAL_FAULT) | 5343 | if(!(LINK_IS_UP(val64))) |
| 4935 | *data = 1; | 5344 | *data = 1; |
| 5345 | else | ||
| 5346 | *data = 0; | ||
| 4936 | 5347 | ||
| 4937 | return 0; | 5348 | return 0; |
| 4938 | } | 5349 | } |
| @@ -5112,7 +5523,6 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
| 5112 | int i = 0; | 5523 | int i = 0; |
| 5113 | nic_t *sp = dev->priv; | 5524 | nic_t *sp = dev->priv; |
| 5114 | StatInfo_t *stat_info = sp->mac_control.stats_info; | 5525 | StatInfo_t *stat_info = sp->mac_control.stats_info; |
| 5115 | u64 tmp; | ||
| 5116 | 5526 | ||
| 5117 | s2io_updt_stats(sp); | 5527 | s2io_updt_stats(sp); |
| 5118 | tmp_stats[i++] = | 5528 | tmp_stats[i++] = |
| @@ -5129,9 +5539,19 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
| 5129 | (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 | | 5539 | (u64)le32_to_cpu(stat_info->tmac_bcst_frms_oflow) << 32 | |
| 5130 | le32_to_cpu(stat_info->tmac_bcst_frms); | 5540 | le32_to_cpu(stat_info->tmac_bcst_frms); |
| 5131 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); | 5541 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_pause_ctrl_frms); |
| 5542 | tmp_stats[i++] = | ||
| 5543 | (u64)le32_to_cpu(stat_info->tmac_ttl_octets_oflow) << 32 | | ||
| 5544 | le32_to_cpu(stat_info->tmac_ttl_octets); | ||
| 5545 | tmp_stats[i++] = | ||
| 5546 | (u64)le32_to_cpu(stat_info->tmac_ucst_frms_oflow) << 32 | | ||
| 5547 | le32_to_cpu(stat_info->tmac_ucst_frms); | ||
| 5548 | tmp_stats[i++] = | ||
| 5549 | (u64)le32_to_cpu(stat_info->tmac_nucst_frms_oflow) << 32 | | ||
| 5550 | le32_to_cpu(stat_info->tmac_nucst_frms); | ||
| 5132 | tmp_stats[i++] = | 5551 | tmp_stats[i++] = |
| 5133 | (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 | | 5552 | (u64)le32_to_cpu(stat_info->tmac_any_err_frms_oflow) << 32 | |
| 5134 | le32_to_cpu(stat_info->tmac_any_err_frms); | 5553 | le32_to_cpu(stat_info->tmac_any_err_frms); |
| 5554 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_ttl_less_fb_octets); | ||
| 5135 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); | 5555 | tmp_stats[i++] = le64_to_cpu(stat_info->tmac_vld_ip_octets); |
| 5136 | tmp_stats[i++] = | 5556 | tmp_stats[i++] = |
| 5137 | (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 | | 5557 | (u64)le32_to_cpu(stat_info->tmac_vld_ip_oflow) << 32 | |
| @@ -5163,11 +5583,27 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
| 5163 | (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 | | 5583 | (u64)le32_to_cpu(stat_info->rmac_vld_bcst_frms_oflow) << 32 | |
| 5164 | le32_to_cpu(stat_info->rmac_vld_bcst_frms); | 5584 | le32_to_cpu(stat_info->rmac_vld_bcst_frms); |
| 5165 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); | 5585 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_in_rng_len_err_frms); |
| 5586 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_out_rng_len_err_frms); | ||
| 5166 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); | 5587 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_long_frms); |
| 5167 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); | 5588 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_pause_ctrl_frms); |
| 5589 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_unsup_ctrl_frms); | ||
| 5590 | tmp_stats[i++] = | ||
| 5591 | (u64)le32_to_cpu(stat_info->rmac_ttl_octets_oflow) << 32 | | ||
| 5592 | le32_to_cpu(stat_info->rmac_ttl_octets); | ||
| 5593 | tmp_stats[i++] = | ||
| 5594 | (u64)le32_to_cpu(stat_info->rmac_accepted_ucst_frms_oflow) | ||
| 5595 | << 32 | le32_to_cpu(stat_info->rmac_accepted_ucst_frms); | ||
| 5596 | tmp_stats[i++] = | ||
| 5597 | (u64)le32_to_cpu(stat_info->rmac_accepted_nucst_frms_oflow) | ||
| 5598 | << 32 | le32_to_cpu(stat_info->rmac_accepted_nucst_frms); | ||
| 5168 | tmp_stats[i++] = | 5599 | tmp_stats[i++] = |
| 5169 | (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 | | 5600 | (u64)le32_to_cpu(stat_info->rmac_discarded_frms_oflow) << 32 | |
| 5170 | le32_to_cpu(stat_info->rmac_discarded_frms); | 5601 | le32_to_cpu(stat_info->rmac_discarded_frms); |
| 5602 | tmp_stats[i++] = | ||
| 5603 | (u64)le32_to_cpu(stat_info->rmac_drop_events_oflow) | ||
| 5604 | << 32 | le32_to_cpu(stat_info->rmac_drop_events); | ||
| 5605 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_less_fb_octets); | ||
| 5606 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_frms); | ||
| 5171 | tmp_stats[i++] = | 5607 | tmp_stats[i++] = |
| 5172 | (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 | | 5608 | (u64)le32_to_cpu(stat_info->rmac_usized_frms_oflow) << 32 | |
| 5173 | le32_to_cpu(stat_info->rmac_usized_frms); | 5609 | le32_to_cpu(stat_info->rmac_usized_frms); |
| @@ -5180,40 +5616,129 @@ static void s2io_get_ethtool_stats(struct net_device *dev, | |||
| 5180 | tmp_stats[i++] = | 5616 | tmp_stats[i++] = |
| 5181 | (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 | | 5617 | (u64)le32_to_cpu(stat_info->rmac_jabber_frms_oflow) << 32 | |
| 5182 | le32_to_cpu(stat_info->rmac_jabber_frms); | 5618 | le32_to_cpu(stat_info->rmac_jabber_frms); |
| 5183 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | | 5619 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_64_frms); |
| 5620 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_65_127_frms); | ||
| 5621 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_128_255_frms); | ||
| 5622 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_256_511_frms); | ||
| 5623 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_512_1023_frms); | ||
| 5624 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1024_1518_frms); | ||
| 5625 | tmp_stats[i++] = | ||
| 5626 | (u64)le32_to_cpu(stat_info->rmac_ip_oflow) << 32 | | ||
| 5184 | le32_to_cpu(stat_info->rmac_ip); | 5627 | le32_to_cpu(stat_info->rmac_ip); |
| 5185 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); | 5628 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ip_octets); |
| 5186 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); | 5629 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_hdr_err_ip); |
| 5187 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | | 5630 | tmp_stats[i++] = |
| 5631 | (u64)le32_to_cpu(stat_info->rmac_drop_ip_oflow) << 32 | | ||
| 5188 | le32_to_cpu(stat_info->rmac_drop_ip); | 5632 | le32_to_cpu(stat_info->rmac_drop_ip); |
| 5189 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | | 5633 | tmp_stats[i++] = |
| 5634 | (u64)le32_to_cpu(stat_info->rmac_icmp_oflow) << 32 | | ||
| 5190 | le32_to_cpu(stat_info->rmac_icmp); | 5635 | le32_to_cpu(stat_info->rmac_icmp); |
| 5191 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); | 5636 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_tcp); |
| 5192 | tmp_stats[i++] = (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | | 5637 | tmp_stats[i++] = |
| 5638 | (u64)le32_to_cpu(stat_info->rmac_udp_oflow) << 32 | | ||
| 5193 | le32_to_cpu(stat_info->rmac_udp); | 5639 | le32_to_cpu(stat_info->rmac_udp); |
| 5194 | tmp_stats[i++] = | 5640 | tmp_stats[i++] = |
| 5195 | (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 | | 5641 | (u64)le32_to_cpu(stat_info->rmac_err_drp_udp_oflow) << 32 | |
| 5196 | le32_to_cpu(stat_info->rmac_err_drp_udp); | 5642 | le32_to_cpu(stat_info->rmac_err_drp_udp); |
| 5643 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_err_sym); | ||
| 5644 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q0); | ||
| 5645 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q1); | ||
| 5646 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q2); | ||
| 5647 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q3); | ||
| 5648 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q4); | ||
| 5649 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q5); | ||
| 5650 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q6); | ||
| 5651 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_frms_q7); | ||
| 5652 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q0); | ||
| 5653 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q1); | ||
| 5654 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q2); | ||
| 5655 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q3); | ||
| 5656 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q4); | ||
| 5657 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q5); | ||
| 5658 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q6); | ||
| 5659 | tmp_stats[i++] = le16_to_cpu(stat_info->rmac_full_q7); | ||
| 5197 | tmp_stats[i++] = | 5660 | tmp_stats[i++] = |
| 5198 | (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 | | 5661 | (u64)le32_to_cpu(stat_info->rmac_pause_cnt_oflow) << 32 | |
| 5199 | le32_to_cpu(stat_info->rmac_pause_cnt); | 5662 | le32_to_cpu(stat_info->rmac_pause_cnt); |
| 5663 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_data_err_cnt); | ||
| 5664 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_xgmii_ctrl_err_cnt); | ||
| 5200 | tmp_stats[i++] = | 5665 | tmp_stats[i++] = |
| 5201 | (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 | | 5666 | (u64)le32_to_cpu(stat_info->rmac_accepted_ip_oflow) << 32 | |
| 5202 | le32_to_cpu(stat_info->rmac_accepted_ip); | 5667 | le32_to_cpu(stat_info->rmac_accepted_ip); |
| 5203 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); | 5668 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_err_tcp); |
| 5669 | tmp_stats[i++] = le32_to_cpu(stat_info->rd_req_cnt); | ||
| 5670 | tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_cnt); | ||
| 5671 | tmp_stats[i++] = le32_to_cpu(stat_info->new_rd_req_rtry_cnt); | ||
| 5672 | tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_cnt); | ||
| 5673 | tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_rd_ack_cnt); | ||
| 5674 | tmp_stats[i++] = le32_to_cpu(stat_info->wr_req_cnt); | ||
| 5675 | tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_cnt); | ||
| 5676 | tmp_stats[i++] = le32_to_cpu(stat_info->new_wr_req_rtry_cnt); | ||
| 5677 | tmp_stats[i++] = le32_to_cpu(stat_info->wr_rtry_cnt); | ||
| 5678 | tmp_stats[i++] = le32_to_cpu(stat_info->wr_disc_cnt); | ||
| 5679 | tmp_stats[i++] = le32_to_cpu(stat_info->rd_rtry_wr_ack_cnt); | ||
| 5680 | tmp_stats[i++] = le32_to_cpu(stat_info->txp_wr_cnt); | ||
| 5681 | tmp_stats[i++] = le32_to_cpu(stat_info->txd_rd_cnt); | ||
| 5682 | tmp_stats[i++] = le32_to_cpu(stat_info->txd_wr_cnt); | ||
| 5683 | tmp_stats[i++] = le32_to_cpu(stat_info->rxd_rd_cnt); | ||
| 5684 | tmp_stats[i++] = le32_to_cpu(stat_info->rxd_wr_cnt); | ||
| 5685 | tmp_stats[i++] = le32_to_cpu(stat_info->txf_rd_cnt); | ||
| 5686 | tmp_stats[i++] = le32_to_cpu(stat_info->rxf_wr_cnt); | ||
| 5687 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_1519_4095_frms); | ||
| 5688 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_4096_8191_frms); | ||
| 5689 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_8192_max_frms); | ||
| 5690 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_ttl_gt_max_frms); | ||
| 5691 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_osized_alt_frms); | ||
| 5692 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_jabber_alt_frms); | ||
| 5693 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_gt_max_alt_frms); | ||
| 5694 | tmp_stats[i++] = le64_to_cpu(stat_info->rmac_vlan_frms); | ||
| 5695 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_len_discard); | ||
| 5696 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_fcs_discard); | ||
| 5697 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_pf_discard); | ||
| 5698 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_da_discard); | ||
| 5699 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_red_discard); | ||
| 5700 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_rts_discard); | ||
| 5701 | tmp_stats[i++] = le32_to_cpu(stat_info->rmac_ingm_full_discard); | ||
| 5702 | tmp_stats[i++] = le32_to_cpu(stat_info->link_fault_cnt); | ||
| 5204 | tmp_stats[i++] = 0; | 5703 | tmp_stats[i++] = 0; |
| 5205 | tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; | 5704 | tmp_stats[i++] = stat_info->sw_stat.single_ecc_errs; |
| 5206 | tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; | 5705 | tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs; |
| 5706 | tmp_stats[i++] = stat_info->sw_stat.parity_err_cnt; | ||
| 5707 | tmp_stats[i++] = stat_info->sw_stat.serious_err_cnt; | ||
| 5708 | tmp_stats[i++] = stat_info->sw_stat.soft_reset_cnt; | ||
| 5709 | tmp_stats[i++] = stat_info->sw_stat.fifo_full_cnt; | ||
| 5710 | tmp_stats[i++] = stat_info->sw_stat.ring_full_cnt; | ||
| 5711 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_high; | ||
| 5712 | tmp_stats[i++] = stat_info->xpak_stat.alarm_transceiver_temp_low; | ||
| 5713 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_high; | ||
| 5714 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_bias_current_low; | ||
| 5715 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_high; | ||
| 5716 | tmp_stats[i++] = stat_info->xpak_stat.alarm_laser_output_power_low; | ||
| 5717 | tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_high; | ||
| 5718 | tmp_stats[i++] = stat_info->xpak_stat.warn_transceiver_temp_low; | ||
| 5719 | tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_high; | ||
| 5720 | tmp_stats[i++] = stat_info->xpak_stat.warn_laser_bias_current_low; | ||
| 5721 | tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_high; | ||
| 5722 | tmp_stats[i++] = stat_info->xpak_stat.warn_laser_output_power_low; | ||
| 5207 | tmp_stats[i++] = stat_info->sw_stat.clubbed_frms_cnt; | 5723 | tmp_stats[i++] = stat_info->sw_stat.clubbed_frms_cnt; |
| 5208 | tmp_stats[i++] = stat_info->sw_stat.sending_both; | 5724 | tmp_stats[i++] = stat_info->sw_stat.sending_both; |
| 5209 | tmp_stats[i++] = stat_info->sw_stat.outof_sequence_pkts; | 5725 | tmp_stats[i++] = stat_info->sw_stat.outof_sequence_pkts; |
| 5210 | tmp_stats[i++] = stat_info->sw_stat.flush_max_pkts; | 5726 | tmp_stats[i++] = stat_info->sw_stat.flush_max_pkts; |
| 5211 | tmp = 0; | ||
| 5212 | if (stat_info->sw_stat.num_aggregations) { | 5727 | if (stat_info->sw_stat.num_aggregations) { |
| 5213 | tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; | 5728 | u64 tmp = stat_info->sw_stat.sum_avg_pkts_aggregated; |
| 5214 | do_div(tmp, stat_info->sw_stat.num_aggregations); | 5729 | int count = 0; |
| 5730 | /* | ||
| 5731 | * Since 64-bit divide does not work on all platforms, | ||
| 5732 | * do repeated subtraction. | ||
| 5733 | */ | ||
| 5734 | while (tmp >= stat_info->sw_stat.num_aggregations) { | ||
| 5735 | tmp -= stat_info->sw_stat.num_aggregations; | ||
| 5736 | count++; | ||
| 5737 | } | ||
| 5738 | tmp_stats[i++] = count; | ||
| 5215 | } | 5739 | } |
| 5216 | tmp_stats[i++] = tmp; | 5740 | else |
| 5741 | tmp_stats[i++] = 0; | ||
| 5217 | } | 5742 | } |
| 5218 | 5743 | ||
| 5219 | static int s2io_ethtool_get_regs_len(struct net_device *dev) | 5744 | static int s2io_ethtool_get_regs_len(struct net_device *dev) |
| @@ -5351,7 +5876,7 @@ static int s2io_change_mtu(struct net_device *dev, int new_mtu) | |||
| 5351 | 5876 | ||
| 5352 | dev->mtu = new_mtu; | 5877 | dev->mtu = new_mtu; |
| 5353 | if (netif_running(dev)) { | 5878 | if (netif_running(dev)) { |
| 5354 | s2io_card_down(sp); | 5879 | s2io_card_down(sp, 0); |
| 5355 | netif_stop_queue(dev); | 5880 | netif_stop_queue(dev); |
| 5356 | if (s2io_card_up(sp)) { | 5881 | if (s2io_card_up(sp)) { |
| 5357 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 5882 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
| @@ -5489,12 +6014,172 @@ static void s2io_set_link(unsigned long data) | |||
| 5489 | clear_bit(0, &(nic->link_state)); | 6014 | clear_bit(0, &(nic->link_state)); |
| 5490 | } | 6015 | } |
| 5491 | 6016 | ||
| 5492 | static void s2io_card_down(nic_t * sp) | 6017 | static int set_rxd_buffer_pointer(nic_t *sp, RxD_t *rxdp, buffAdd_t *ba, |
| 6018 | struct sk_buff **skb, u64 *temp0, u64 *temp1, | ||
| 6019 | u64 *temp2, int size) | ||
| 6020 | { | ||
| 6021 | struct net_device *dev = sp->dev; | ||
| 6022 | struct sk_buff *frag_list; | ||
| 6023 | |||
| 6024 | if ((sp->rxd_mode == RXD_MODE_1) && (rxdp->Host_Control == 0)) { | ||
| 6025 | /* allocate skb */ | ||
| 6026 | if (*skb) { | ||
| 6027 | DBG_PRINT(INFO_DBG, "SKB is not NULL\n"); | ||
| 6028 | /* | ||
| 6029 | * As Rx frame are not going to be processed, | ||
| 6030 | * using same mapped address for the Rxd | ||
| 6031 | * buffer pointer | ||
| 6032 | */ | ||
| 6033 | ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0; | ||
| 6034 | } else { | ||
| 6035 | *skb = dev_alloc_skb(size); | ||
| 6036 | if (!(*skb)) { | ||
| 6037 | DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name); | ||
| 6038 | DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n"); | ||
| 6039 | return -ENOMEM ; | ||
| 6040 | } | ||
| 6041 | /* storing the mapped addr in a temp variable | ||
| 6042 | * such it will be used for next rxd whose | ||
| 6043 | * Host Control is NULL | ||
| 6044 | */ | ||
| 6045 | ((RxD1_t*)rxdp)->Buffer0_ptr = *temp0 = | ||
| 6046 | pci_map_single( sp->pdev, (*skb)->data, | ||
| 6047 | size - NET_IP_ALIGN, | ||
| 6048 | PCI_DMA_FROMDEVICE); | ||
| 6049 | rxdp->Host_Control = (unsigned long) (*skb); | ||
| 6050 | } | ||
| 6051 | } else if ((sp->rxd_mode == RXD_MODE_3B) && (rxdp->Host_Control == 0)) { | ||
| 6052 | /* Two buffer Mode */ | ||
| 6053 | if (*skb) { | ||
| 6054 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; | ||
| 6055 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; | ||
| 6056 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; | ||
| 6057 | } else { | ||
| 6058 | *skb = dev_alloc_skb(size); | ||
| 6059 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = | ||
| 6060 | pci_map_single(sp->pdev, (*skb)->data, | ||
| 6061 | dev->mtu + 4, | ||
| 6062 | PCI_DMA_FROMDEVICE); | ||
| 6063 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = | ||
| 6064 | pci_map_single( sp->pdev, ba->ba_0, BUF0_LEN, | ||
| 6065 | PCI_DMA_FROMDEVICE); | ||
| 6066 | rxdp->Host_Control = (unsigned long) (*skb); | ||
| 6067 | |||
| 6068 | /* Buffer-1 will be dummy buffer not used */ | ||
| 6069 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = | ||
| 6070 | pci_map_single(sp->pdev, ba->ba_1, BUF1_LEN, | ||
| 6071 | PCI_DMA_FROMDEVICE); | ||
| 6072 | } | ||
| 6073 | } else if ((rxdp->Host_Control == 0)) { | ||
| 6074 | /* Three buffer mode */ | ||
| 6075 | if (*skb) { | ||
| 6076 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0; | ||
| 6077 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1; | ||
| 6078 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2; | ||
| 6079 | } else { | ||
| 6080 | *skb = dev_alloc_skb(size); | ||
| 6081 | |||
| 6082 | ((RxD3_t*)rxdp)->Buffer0_ptr = *temp0 = | ||
| 6083 | pci_map_single(sp->pdev, ba->ba_0, BUF0_LEN, | ||
| 6084 | PCI_DMA_FROMDEVICE); | ||
| 6085 | /* Buffer-1 receives L3/L4 headers */ | ||
| 6086 | ((RxD3_t*)rxdp)->Buffer1_ptr = *temp1 = | ||
| 6087 | pci_map_single( sp->pdev, (*skb)->data, | ||
| 6088 | l3l4hdr_size + 4, | ||
| 6089 | PCI_DMA_FROMDEVICE); | ||
| 6090 | /* | ||
| 6091 | * skb_shinfo(skb)->frag_list will have L4 | ||
| 6092 | * data payload | ||
| 6093 | */ | ||
| 6094 | skb_shinfo(*skb)->frag_list = dev_alloc_skb(dev->mtu + | ||
| 6095 | ALIGN_SIZE); | ||
| 6096 | if (skb_shinfo(*skb)->frag_list == NULL) { | ||
| 6097 | DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb \ | ||
| 6098 | failed\n ", dev->name); | ||
| 6099 | return -ENOMEM ; | ||
| 6100 | } | ||
| 6101 | frag_list = skb_shinfo(*skb)->frag_list; | ||
| 6102 | frag_list->next = NULL; | ||
| 6103 | /* | ||
| 6104 | * Buffer-2 receives L4 data payload | ||
| 6105 | */ | ||
| 6106 | ((RxD3_t*)rxdp)->Buffer2_ptr = *temp2 = | ||
| 6107 | pci_map_single( sp->pdev, frag_list->data, | ||
| 6108 | dev->mtu, PCI_DMA_FROMDEVICE); | ||
| 6109 | } | ||
| 6110 | } | ||
| 6111 | return 0; | ||
| 6112 | } | ||
| 6113 | static void set_rxd_buffer_size(nic_t *sp, RxD_t *rxdp, int size) | ||
| 6114 | { | ||
| 6115 | struct net_device *dev = sp->dev; | ||
| 6116 | if (sp->rxd_mode == RXD_MODE_1) { | ||
| 6117 | rxdp->Control_2 = SET_BUFFER0_SIZE_1( size - NET_IP_ALIGN); | ||
| 6118 | } else if (sp->rxd_mode == RXD_MODE_3B) { | ||
| 6119 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | ||
| 6120 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1); | ||
| 6121 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3( dev->mtu + 4); | ||
| 6122 | } else { | ||
| 6123 | rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN); | ||
| 6124 | rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4); | ||
| 6125 | rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu); | ||
| 6126 | } | ||
| 6127 | } | ||
| 6128 | |||
| 6129 | static int rxd_owner_bit_reset(nic_t *sp) | ||
| 6130 | { | ||
| 6131 | int i, j, k, blk_cnt = 0, size; | ||
| 6132 | mac_info_t * mac_control = &sp->mac_control; | ||
| 6133 | struct config_param *config = &sp->config; | ||
| 6134 | struct net_device *dev = sp->dev; | ||
| 6135 | RxD_t *rxdp = NULL; | ||
| 6136 | struct sk_buff *skb = NULL; | ||
| 6137 | buffAdd_t *ba = NULL; | ||
| 6138 | u64 temp0_64 = 0, temp1_64 = 0, temp2_64 = 0; | ||
| 6139 | |||
| 6140 | /* Calculate the size based on ring mode */ | ||
| 6141 | size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE + | ||
| 6142 | HEADER_802_2_SIZE + HEADER_SNAP_SIZE; | ||
| 6143 | if (sp->rxd_mode == RXD_MODE_1) | ||
| 6144 | size += NET_IP_ALIGN; | ||
| 6145 | else if (sp->rxd_mode == RXD_MODE_3B) | ||
| 6146 | size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4; | ||
| 6147 | else | ||
| 6148 | size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4; | ||
| 6149 | |||
| 6150 | for (i = 0; i < config->rx_ring_num; i++) { | ||
| 6151 | blk_cnt = config->rx_cfg[i].num_rxd / | ||
| 6152 | (rxd_count[sp->rxd_mode] +1); | ||
| 6153 | |||
| 6154 | for (j = 0; j < blk_cnt; j++) { | ||
| 6155 | for (k = 0; k < rxd_count[sp->rxd_mode]; k++) { | ||
| 6156 | rxdp = mac_control->rings[i]. | ||
| 6157 | rx_blocks[j].rxds[k].virt_addr; | ||
| 6158 | if(sp->rxd_mode >= RXD_MODE_3A) | ||
| 6159 | ba = &mac_control->rings[i].ba[j][k]; | ||
| 6160 | set_rxd_buffer_pointer(sp, rxdp, ba, | ||
| 6161 | &skb,(u64 *)&temp0_64, | ||
| 6162 | (u64 *)&temp1_64, | ||
| 6163 | (u64 *)&temp2_64, size); | ||
| 6164 | |||
| 6165 | set_rxd_buffer_size(sp, rxdp, size); | ||
| 6166 | wmb(); | ||
| 6167 | /* flip the Ownership bit to Hardware */ | ||
| 6168 | rxdp->Control_1 |= RXD_OWN_XENA; | ||
| 6169 | } | ||
| 6170 | } | ||
| 6171 | } | ||
| 6172 | return 0; | ||
| 6173 | |||
| 6174 | } | ||
| 6175 | |||
| 6176 | static void s2io_card_down(nic_t * sp, int flag) | ||
| 5493 | { | 6177 | { |
| 5494 | int cnt = 0; | 6178 | int cnt = 0; |
| 5495 | XENA_dev_config_t __iomem *bar0 = sp->bar0; | 6179 | XENA_dev_config_t __iomem *bar0 = sp->bar0; |
| 5496 | unsigned long flags; | 6180 | unsigned long flags; |
| 5497 | register u64 val64 = 0; | 6181 | register u64 val64 = 0; |
| 6182 | struct net_device *dev = sp->dev; | ||
| 5498 | 6183 | ||
| 5499 | del_timer_sync(&sp->alarm_timer); | 6184 | del_timer_sync(&sp->alarm_timer); |
| 5500 | /* If s2io_set_link task is executing, wait till it completes. */ | 6185 | /* If s2io_set_link task is executing, wait till it completes. */ |
| @@ -5505,12 +6190,51 @@ static void s2io_card_down(nic_t * sp) | |||
| 5505 | 6190 | ||
| 5506 | /* disable Tx and Rx traffic on the NIC */ | 6191 | /* disable Tx and Rx traffic on the NIC */ |
| 5507 | stop_nic(sp); | 6192 | stop_nic(sp); |
| 6193 | if (flag) { | ||
| 6194 | if (sp->intr_type == MSI_X) { | ||
| 6195 | int i; | ||
| 6196 | u16 msi_control; | ||
| 6197 | |||
| 6198 | for (i=1; (sp->s2io_entries[i].in_use == | ||
| 6199 | MSIX_REGISTERED_SUCCESS); i++) { | ||
| 6200 | int vector = sp->entries[i].vector; | ||
| 6201 | void *arg = sp->s2io_entries[i].arg; | ||
| 6202 | |||
| 6203 | free_irq(vector, arg); | ||
| 6204 | } | ||
| 6205 | pci_read_config_word(sp->pdev, 0x42, &msi_control); | ||
| 6206 | msi_control &= 0xFFFE; /* Disable MSI */ | ||
| 6207 | pci_write_config_word(sp->pdev, 0x42, msi_control); | ||
| 6208 | pci_disable_msix(sp->pdev); | ||
| 6209 | } else { | ||
| 6210 | free_irq(sp->pdev->irq, dev); | ||
| 6211 | if (sp->intr_type == MSI) | ||
| 6212 | pci_disable_msi(sp->pdev); | ||
| 6213 | } | ||
| 6214 | } | ||
| 6215 | /* Waiting till all Interrupt handlers are complete */ | ||
| 6216 | cnt = 0; | ||
| 6217 | do { | ||
| 6218 | msleep(10); | ||
| 6219 | if (!atomic_read(&sp->isr_cnt)) | ||
| 6220 | break; | ||
| 6221 | cnt++; | ||
| 6222 | } while(cnt < 5); | ||
| 5508 | 6223 | ||
| 5509 | /* Kill tasklet. */ | 6224 | /* Kill tasklet. */ |
| 5510 | tasklet_kill(&sp->task); | 6225 | tasklet_kill(&sp->task); |
| 5511 | 6226 | ||
| 5512 | /* Check if the device is Quiescent and then Reset the NIC */ | 6227 | /* Check if the device is Quiescent and then Reset the NIC */ |
| 5513 | do { | 6228 | do { |
| 6229 | /* As per the HW requirement we need to replenish the | ||
| 6230 | * receive buffer to avoid the ring bump. Since there is | ||
| 6231 | * no intention of processing the Rx frame at this pointwe are | ||
| 6232 | * just settting the ownership bit of rxd in Each Rx | ||
| 6233 | * ring to HW and set the appropriate buffer size | ||
| 6234 | * based on the ring mode | ||
| 6235 | */ | ||
| 6236 | rxd_owner_bit_reset(sp); | ||
| 6237 | |||
| 5514 | val64 = readq(&bar0->adapter_status); | 6238 | val64 = readq(&bar0->adapter_status); |
| 5515 | if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { | 6239 | if (verify_xena_quiescence(sp, val64, sp->device_enabled_once)) { |
| 5516 | break; | 6240 | break; |
| @@ -5528,15 +6252,6 @@ static void s2io_card_down(nic_t * sp) | |||
| 5528 | } while (1); | 6252 | } while (1); |
| 5529 | s2io_reset(sp); | 6253 | s2io_reset(sp); |
| 5530 | 6254 | ||
| 5531 | /* Waiting till all Interrupt handlers are complete */ | ||
| 5532 | cnt = 0; | ||
| 5533 | do { | ||
| 5534 | msleep(10); | ||
| 5535 | if (!atomic_read(&sp->isr_cnt)) | ||
| 5536 | break; | ||
| 5537 | cnt++; | ||
| 5538 | } while(cnt < 5); | ||
| 5539 | |||
| 5540 | spin_lock_irqsave(&sp->tx_lock, flags); | 6255 | spin_lock_irqsave(&sp->tx_lock, flags); |
| 5541 | /* Free all Tx buffers */ | 6256 | /* Free all Tx buffers */ |
| 5542 | free_tx_buffers(sp); | 6257 | free_tx_buffers(sp); |
| @@ -5637,7 +6352,7 @@ static void s2io_restart_nic(unsigned long data) | |||
| 5637 | struct net_device *dev = (struct net_device *) data; | 6352 | struct net_device *dev = (struct net_device *) data; |
| 5638 | nic_t *sp = dev->priv; | 6353 | nic_t *sp = dev->priv; |
| 5639 | 6354 | ||
| 5640 | s2io_card_down(sp); | 6355 | s2io_card_down(sp, 0); |
| 5641 | if (s2io_card_up(sp)) { | 6356 | if (s2io_card_up(sp)) { |
| 5642 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", | 6357 | DBG_PRINT(ERR_DBG, "%s: Device bring up failed\n", |
| 5643 | dev->name); | 6358 | dev->name); |
| @@ -5667,6 +6382,7 @@ static void s2io_tx_watchdog(struct net_device *dev) | |||
| 5667 | 6382 | ||
| 5668 | if (netif_carrier_ok(dev)) { | 6383 | if (netif_carrier_ok(dev)) { |
| 5669 | schedule_work(&sp->rst_timer_task); | 6384 | schedule_work(&sp->rst_timer_task); |
| 6385 | sp->mac_control.stats_info->sw_stat.soft_reset_cnt++; | ||
| 5670 | } | 6386 | } |
| 5671 | } | 6387 | } |
| 5672 | 6388 | ||
| @@ -5695,18 +6411,33 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) | |||
| 5695 | ((unsigned long) rxdp->Host_Control); | 6411 | ((unsigned long) rxdp->Host_Control); |
| 5696 | int ring_no = ring_data->ring_no; | 6412 | int ring_no = ring_data->ring_no; |
| 5697 | u16 l3_csum, l4_csum; | 6413 | u16 l3_csum, l4_csum; |
| 6414 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | ||
| 5698 | lro_t *lro; | 6415 | lro_t *lro; |
| 5699 | 6416 | ||
| 5700 | skb->dev = dev; | 6417 | skb->dev = dev; |
| 5701 | if (rxdp->Control_1 & RXD_T_CODE) { | 6418 | |
| 5702 | unsigned long long err = rxdp->Control_1 & RXD_T_CODE; | 6419 | if (err) { |
| 5703 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | 6420 | /* Check for parity error */ |
| 5704 | dev->name, err); | 6421 | if (err & 0x1) { |
| 5705 | dev_kfree_skb(skb); | 6422 | sp->mac_control.stats_info->sw_stat.parity_err_cnt++; |
| 5706 | sp->stats.rx_crc_errors++; | 6423 | } |
| 5707 | atomic_dec(&sp->rx_bufs_left[ring_no]); | 6424 | |
| 5708 | rxdp->Host_Control = 0; | 6425 | /* |
| 5709 | return 0; | 6426 | * Drop the packet if bad transfer code. Exception being |
| 6427 | * 0x5, which could be due to unsupported IPv6 extension header. | ||
| 6428 | * In this case, we let stack handle the packet. | ||
| 6429 | * Note that in this case, since checksum will be incorrect, | ||
| 6430 | * stack will validate the same. | ||
| 6431 | */ | ||
| 6432 | if (err && ((err >> 48) != 0x5)) { | ||
| 6433 | DBG_PRINT(ERR_DBG, "%s: Rx error Value: 0x%llx\n", | ||
| 6434 | dev->name, err); | ||
| 6435 | sp->stats.rx_crc_errors++; | ||
| 6436 | dev_kfree_skb(skb); | ||
| 6437 | atomic_dec(&sp->rx_bufs_left[ring_no]); | ||
| 6438 | rxdp->Host_Control = 0; | ||
| 6439 | return 0; | ||
| 6440 | } | ||
| 5710 | } | 6441 | } |
| 5711 | 6442 | ||
| 5712 | /* Updating statistics */ | 6443 | /* Updating statistics */ |
| @@ -5792,6 +6523,9 @@ static int rx_osm_handler(ring_info_t *ring_data, RxD_t * rxdp) | |||
| 5792 | clear_lro_session(lro); | 6523 | clear_lro_session(lro); |
| 5793 | goto send_up; | 6524 | goto send_up; |
| 5794 | case 0: /* sessions exceeded */ | 6525 | case 0: /* sessions exceeded */ |
| 6526 | case -1: /* non-TCP or not | ||
| 6527 | * L2 aggregatable | ||
| 6528 | */ | ||
| 5795 | case 5: /* | 6529 | case 5: /* |
| 5796 | * First pkt in session not | 6530 | * First pkt in session not |
| 5797 | * L3/L4 aggregatable | 6531 | * L3/L4 aggregatable |
| @@ -5918,13 +6652,6 @@ static void s2io_init_pci(nic_t * sp) | |||
| 5918 | pci_write_config_word(sp->pdev, PCI_COMMAND, | 6652 | pci_write_config_word(sp->pdev, PCI_COMMAND, |
| 5919 | (pci_cmd | PCI_COMMAND_PARITY)); | 6653 | (pci_cmd | PCI_COMMAND_PARITY)); |
| 5920 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); | 6654 | pci_read_config_word(sp->pdev, PCI_COMMAND, &pci_cmd); |
| 5921 | |||
| 5922 | /* Forcibly disabling relaxed ordering capability of the card. */ | ||
| 5923 | pcix_cmd &= 0xfffd; | ||
| 5924 | pci_write_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
| 5925 | pcix_cmd); | ||
| 5926 | pci_read_config_word(sp->pdev, PCIX_COMMAND_REGISTER, | ||
| 5927 | &(pcix_cmd)); | ||
| 5928 | } | 6655 | } |
| 5929 | 6656 | ||
| 5930 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); | 6657 | MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik@neterion.com>"); |
| @@ -5954,6 +6681,55 @@ module_param(intr_type, int, 0); | |||
| 5954 | module_param(lro, int, 0); | 6681 | module_param(lro, int, 0); |
| 5955 | module_param(lro_max_pkts, int, 0); | 6682 | module_param(lro_max_pkts, int, 0); |
| 5956 | 6683 | ||
| 6684 | static int s2io_verify_parm(struct pci_dev *pdev, u8 *dev_intr_type) | ||
| 6685 | { | ||
| 6686 | if ( tx_fifo_num > 8) { | ||
| 6687 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Tx fifos not " | ||
| 6688 | "supported\n"); | ||
| 6689 | DBG_PRINT(ERR_DBG, "s2io: Default to 8 Tx fifos\n"); | ||
| 6690 | tx_fifo_num = 8; | ||
| 6691 | } | ||
| 6692 | if ( rx_ring_num > 8) { | ||
| 6693 | DBG_PRINT(ERR_DBG, "s2io: Requested number of Rx rings not " | ||
| 6694 | "supported\n"); | ||
| 6695 | DBG_PRINT(ERR_DBG, "s2io: Default to 8 Rx rings\n"); | ||
| 6696 | rx_ring_num = 8; | ||
| 6697 | } | ||
| 6698 | #ifdef CONFIG_S2IO_NAPI | ||
| 6699 | if (*dev_intr_type != INTA) { | ||
| 6700 | DBG_PRINT(ERR_DBG, "s2io: NAPI cannot be enabled when " | ||
| 6701 | "MSI/MSI-X is enabled. Defaulting to INTA\n"); | ||
| 6702 | *dev_intr_type = INTA; | ||
| 6703 | } | ||
| 6704 | #endif | ||
| 6705 | #ifndef CONFIG_PCI_MSI | ||
| 6706 | if (*dev_intr_type != INTA) { | ||
| 6707 | DBG_PRINT(ERR_DBG, "s2io: This kernel does not support" | ||
| 6708 | "MSI/MSI-X. Defaulting to INTA\n"); | ||
| 6709 | *dev_intr_type = INTA; | ||
| 6710 | } | ||
| 6711 | #else | ||
| 6712 | if (*dev_intr_type > MSI_X) { | ||
| 6713 | DBG_PRINT(ERR_DBG, "s2io: Wrong intr_type requested. " | ||
| 6714 | "Defaulting to INTA\n"); | ||
| 6715 | *dev_intr_type = INTA; | ||
| 6716 | } | ||
| 6717 | #endif | ||
| 6718 | if ((*dev_intr_type == MSI_X) && | ||
| 6719 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && | ||
| 6720 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { | ||
| 6721 | DBG_PRINT(ERR_DBG, "s2io: Xframe I does not support MSI_X. " | ||
| 6722 | "Defaulting to INTA\n"); | ||
| 6723 | *dev_intr_type = INTA; | ||
| 6724 | } | ||
| 6725 | if (rx_ring_mode > 3) { | ||
| 6726 | DBG_PRINT(ERR_DBG, "s2io: Requested ring mode not supported\n"); | ||
| 6727 | DBG_PRINT(ERR_DBG, "s2io: Defaulting to 3-buffer mode\n"); | ||
| 6728 | rx_ring_mode = 3; | ||
| 6729 | } | ||
| 6730 | return SUCCESS; | ||
| 6731 | } | ||
| 6732 | |||
| 5957 | /** | 6733 | /** |
| 5958 | * s2io_init_nic - Initialization of the adapter . | 6734 | * s2io_init_nic - Initialization of the adapter . |
| 5959 | * @pdev : structure containing the PCI related information of the device. | 6735 | * @pdev : structure containing the PCI related information of the device. |
| @@ -5984,15 +6760,8 @@ s2io_init_nic(struct pci_dev *pdev, const struct pci_device_id *pre) | |||
| 5984 | int mode; | 6760 | int mode; |
| 5985 | u8 dev_intr_type = intr_type; | 6761 | u8 dev_intr_type = intr_type; |
| 5986 | 6762 | ||
| 5987 | #ifdef CONFIG_S2IO_NAPI | 6763 | if ((ret = s2io_verify_parm(pdev, &dev_intr_type))) |
| 5988 | if (dev_intr_type != INTA) { | 6764 | return ret; |
| 5989 | DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \ | ||
| 5990 | is enabled. Defaulting to INTA\n"); | ||
| 5991 | dev_intr_type = INTA; | ||
| 5992 | } | ||
| 5993 | else | ||
| 5994 | DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n"); | ||
| 5995 | #endif | ||
| 5996 | 6765 | ||
| 5997 | if ((ret = pci_enable_device(pdev))) { | 6766 | if ((ret = pci_enable_device(pdev))) { |
| 5998 | DBG_PRINT(ERR_DBG, | 6767 | DBG_PRINT(ERR_DBG, |
| @@ -6017,14 +6786,6 @@ is enabled. Defaulting to INTA\n"); | |||
| 6017 | pci_disable_device(pdev); | 6786 | pci_disable_device(pdev); |
| 6018 | return -ENOMEM; | 6787 | return -ENOMEM; |
| 6019 | } | 6788 | } |
| 6020 | |||
| 6021 | if ((dev_intr_type == MSI_X) && | ||
| 6022 | ((pdev->device != PCI_DEVICE_ID_HERC_WIN) && | ||
| 6023 | (pdev->device != PCI_DEVICE_ID_HERC_UNI))) { | ||
| 6024 | DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \ | ||
| 6025 | Defaulting to INTA\n"); | ||
| 6026 | dev_intr_type = INTA; | ||
| 6027 | } | ||
| 6028 | if (dev_intr_type != MSI_X) { | 6789 | if (dev_intr_type != MSI_X) { |
| 6029 | if (pci_request_regions(pdev, s2io_driver_name)) { | 6790 | if (pci_request_regions(pdev, s2io_driver_name)) { |
| 6030 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), | 6791 | DBG_PRINT(ERR_DBG, "Request Regions failed\n"), |
| @@ -6100,8 +6861,6 @@ Defaulting to INTA\n"); | |||
| 6100 | config = &sp->config; | 6861 | config = &sp->config; |
| 6101 | 6862 | ||
| 6102 | /* Tx side parameters. */ | 6863 | /* Tx side parameters. */ |
| 6103 | if (tx_fifo_len[0] == 0) | ||
| 6104 | tx_fifo_len[0] = DEFAULT_FIFO_LEN; /* Default value. */ | ||
| 6105 | config->tx_fifo_num = tx_fifo_num; | 6864 | config->tx_fifo_num = tx_fifo_num; |
| 6106 | for (i = 0; i < MAX_TX_FIFOS; i++) { | 6865 | for (i = 0; i < MAX_TX_FIFOS; i++) { |
| 6107 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; | 6866 | config->tx_cfg[i].fifo_len = tx_fifo_len[i]; |
| @@ -6125,8 +6884,6 @@ Defaulting to INTA\n"); | |||
| 6125 | config->max_txds = MAX_SKB_FRAGS + 2; | 6884 | config->max_txds = MAX_SKB_FRAGS + 2; |
| 6126 | 6885 | ||
| 6127 | /* Rx side parameters. */ | 6886 | /* Rx side parameters. */ |
| 6128 | if (rx_ring_sz[0] == 0) | ||
| 6129 | rx_ring_sz[0] = SMALL_BLK_CNT; /* Default value. */ | ||
| 6130 | config->rx_ring_num = rx_ring_num; | 6887 | config->rx_ring_num = rx_ring_num; |
| 6131 | for (i = 0; i < MAX_RX_RINGS; i++) { | 6888 | for (i = 0; i < MAX_RX_RINGS; i++) { |
| 6132 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * | 6889 | config->rx_cfg[i].num_rxd = rx_ring_sz[i] * |
| @@ -6267,8 +7024,8 @@ Defaulting to INTA\n"); | |||
| 6267 | val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | | 7024 | val64 = RMAC_ADDR_CMD_MEM_RD | RMAC_ADDR_CMD_MEM_STROBE_NEW_CMD | |
| 6268 | RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); | 7025 | RMAC_ADDR_CMD_MEM_OFFSET(0 + MAC_MAC_ADDR_START_OFFSET); |
| 6269 | writeq(val64, &bar0->rmac_addr_cmd_mem); | 7026 | writeq(val64, &bar0->rmac_addr_cmd_mem); |
| 6270 | wait_for_cmd_complete(sp); | 7027 | wait_for_cmd_complete(&bar0->rmac_addr_cmd_mem, |
| 6271 | 7028 | RMAC_ADDR_CMD_MEM_STROBE_CMD_EXECUTING); | |
| 6272 | tmp64 = readq(&bar0->rmac_addr_data0_mem); | 7029 | tmp64 = readq(&bar0->rmac_addr_data0_mem); |
| 6273 | mac_down = (u32) tmp64; | 7030 | mac_down = (u32) tmp64; |
| 6274 | mac_up = (u32) (tmp64 >> 32); | 7031 | mac_up = (u32) (tmp64 >> 32); |
| @@ -6322,82 +7079,63 @@ Defaulting to INTA\n"); | |||
| 6322 | ret = -ENODEV; | 7079 | ret = -ENODEV; |
| 6323 | goto register_failed; | 7080 | goto register_failed; |
| 6324 | } | 7081 | } |
| 6325 | 7082 | s2io_vpd_read(sp); | |
| 6326 | if (sp->device_type & XFRAME_II_DEVICE) { | 7083 | DBG_PRINT(ERR_DBG, "%s: Neterion %s",dev->name, sp->product_name); |
| 6327 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ", | 7084 | DBG_PRINT(ERR_DBG, "(rev %d), Driver version %s\n", |
| 6328 | dev->name); | ||
| 6329 | DBG_PRINT(ERR_DBG, "(rev %d), Version %s", | ||
| 6330 | get_xena_rev_id(sp->pdev), | 7085 | get_xena_rev_id(sp->pdev), |
| 6331 | s2io_driver_version); | 7086 | s2io_driver_version); |
| 6332 | switch(sp->intr_type) { | 7087 | DBG_PRINT(ERR_DBG, "Copyright(c) 2002-2005 Neterion Inc.\n"); |
| 6333 | case INTA: | 7088 | DBG_PRINT(ERR_DBG, "%s: MAC ADDR: " |
| 6334 | DBG_PRINT(ERR_DBG, ", Intr type INTA"); | 7089 | "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, |
| 6335 | break; | ||
| 6336 | case MSI: | ||
| 6337 | DBG_PRINT(ERR_DBG, ", Intr type MSI"); | ||
| 6338 | break; | ||
| 6339 | case MSI_X: | ||
| 6340 | DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); | ||
| 6341 | break; | ||
| 6342 | } | ||
| 6343 | |||
| 6344 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | ||
| 6345 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 6346 | sp->def_mac_addr[0].mac_addr[0], | 7090 | sp->def_mac_addr[0].mac_addr[0], |
| 6347 | sp->def_mac_addr[0].mac_addr[1], | 7091 | sp->def_mac_addr[0].mac_addr[1], |
| 6348 | sp->def_mac_addr[0].mac_addr[2], | 7092 | sp->def_mac_addr[0].mac_addr[2], |
| 6349 | sp->def_mac_addr[0].mac_addr[3], | 7093 | sp->def_mac_addr[0].mac_addr[3], |
| 6350 | sp->def_mac_addr[0].mac_addr[4], | 7094 | sp->def_mac_addr[0].mac_addr[4], |
| 6351 | sp->def_mac_addr[0].mac_addr[5]); | 7095 | sp->def_mac_addr[0].mac_addr[5]); |
| 7096 | if (sp->device_type & XFRAME_II_DEVICE) { | ||
| 6352 | mode = s2io_print_pci_mode(sp); | 7097 | mode = s2io_print_pci_mode(sp); |
| 6353 | if (mode < 0) { | 7098 | if (mode < 0) { |
| 6354 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode "); | 7099 | DBG_PRINT(ERR_DBG, " Unsupported PCI bus mode\n"); |
| 6355 | ret = -EBADSLT; | 7100 | ret = -EBADSLT; |
| 7101 | unregister_netdev(dev); | ||
| 6356 | goto set_swap_failed; | 7102 | goto set_swap_failed; |
| 6357 | } | 7103 | } |
| 6358 | } else { | ||
| 6359 | DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ", | ||
| 6360 | dev->name); | ||
| 6361 | DBG_PRINT(ERR_DBG, "(rev %d), Version %s", | ||
| 6362 | get_xena_rev_id(sp->pdev), | ||
| 6363 | s2io_driver_version); | ||
| 6364 | switch(sp->intr_type) { | ||
| 6365 | case INTA: | ||
| 6366 | DBG_PRINT(ERR_DBG, ", Intr type INTA"); | ||
| 6367 | break; | ||
| 6368 | case MSI: | ||
| 6369 | DBG_PRINT(ERR_DBG, ", Intr type MSI"); | ||
| 6370 | break; | ||
| 6371 | case MSI_X: | ||
| 6372 | DBG_PRINT(ERR_DBG, ", Intr type MSI-X"); | ||
| 6373 | break; | ||
| 6374 | } | ||
| 6375 | DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n"); | ||
| 6376 | DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n", | ||
| 6377 | sp->def_mac_addr[0].mac_addr[0], | ||
| 6378 | sp->def_mac_addr[0].mac_addr[1], | ||
| 6379 | sp->def_mac_addr[0].mac_addr[2], | ||
| 6380 | sp->def_mac_addr[0].mac_addr[3], | ||
| 6381 | sp->def_mac_addr[0].mac_addr[4], | ||
| 6382 | sp->def_mac_addr[0].mac_addr[5]); | ||
| 6383 | } | 7104 | } |
| 6384 | if (sp->rxd_mode == RXD_MODE_3B) | 7105 | switch(sp->rxd_mode) { |
| 6385 | DBG_PRINT(ERR_DBG, "%s: 2-Buffer mode support has been " | 7106 | case RXD_MODE_1: |
| 6386 | "enabled\n",dev->name); | 7107 | DBG_PRINT(ERR_DBG, "%s: 1-Buffer receive mode enabled\n", |
| 6387 | if (sp->rxd_mode == RXD_MODE_3A) | 7108 | dev->name); |
| 6388 | DBG_PRINT(ERR_DBG, "%s: 3-Buffer mode support has been " | 7109 | break; |
| 6389 | "enabled\n",dev->name); | 7110 | case RXD_MODE_3B: |
| 6390 | 7111 | DBG_PRINT(ERR_DBG, "%s: 2-Buffer receive mode enabled\n", | |
| 7112 | dev->name); | ||
| 7113 | break; | ||
| 7114 | case RXD_MODE_3A: | ||
| 7115 | DBG_PRINT(ERR_DBG, "%s: 3-Buffer receive mode enabled\n", | ||
| 7116 | dev->name); | ||
| 7117 | break; | ||
| 7118 | } | ||
| 7119 | #ifdef CONFIG_S2IO_NAPI | ||
| 7120 | DBG_PRINT(ERR_DBG, "%s: NAPI enabled\n", dev->name); | ||
| 7121 | #endif | ||
| 7122 | switch(sp->intr_type) { | ||
| 7123 | case INTA: | ||
| 7124 | DBG_PRINT(ERR_DBG, "%s: Interrupt type INTA\n", dev->name); | ||
| 7125 | break; | ||
| 7126 | case MSI: | ||
| 7127 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI\n", dev->name); | ||
| 7128 | break; | ||
| 7129 | case MSI_X: | ||
| 7130 | DBG_PRINT(ERR_DBG, "%s: Interrupt type MSI-X\n", dev->name); | ||
| 7131 | break; | ||
| 7132 | } | ||
| 6391 | if (sp->lro) | 7133 | if (sp->lro) |
| 6392 | DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", | 7134 | DBG_PRINT(ERR_DBG, "%s: Large receive offload enabled\n", |
| 6393 | dev->name); | 7135 | dev->name); |
| 6394 | 7136 | ||
| 6395 | /* Initialize device name */ | 7137 | /* Initialize device name */ |
| 6396 | strcpy(sp->name, dev->name); | 7138 | sprintf(sp->name, "%s Neterion %s", dev->name, sp->product_name); |
| 6397 | if (sp->device_type & XFRAME_II_DEVICE) | ||
| 6398 | strcat(sp->name, ": Neterion Xframe II 10GbE adapter"); | ||
| 6399 | else | ||
| 6400 | strcat(sp->name, ": Neterion Xframe I 10GbE adapter"); | ||
| 6401 | 7139 | ||
| 6402 | /* Initialize bimodal Interrupts */ | 7140 | /* Initialize bimodal Interrupts */ |
| 6403 | sp->config.bimodal = bimodal; | 7141 | sp->config.bimodal = bimodal; |
