17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19 #include <linux/kernel.h>
20 #include <linux/errno.h>
21 #include <linux/pci.h>
22 #include <linux/netdevice.h>
24 #include <linux/ethtool.h>
33 #define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
34 #define ETH_MIN_PACKET_SIZE 60
35 #define ETH_MAX_PACKET_SIZE 1500
36 #define ETH_MAX_JUMBO_PACKET_SIZE 9600
37 #define MDIO_ACCESS_TIMEOUT 1000
39 #define I2C_SWITCH_WIDTH 2
42 #define I2C_WA_RETRY_CNT 3
43 #define I2C_WA_PWR_ITER (I2C_WA_RETRY_CNT - 1)
44 #define MCPR_IMC_COMMAND_READ_OP 1
45 #define MCPR_IMC_COMMAND_WRITE_OP 2
48 #define LED_BLINK_RATE_VAL_E3 354
49 #define LED_BLINK_RATE_VAL_E1X_E2 480
54 #define NIG_LATCH_BC_ENABLE_MI_INT 0
56 #define NIG_STATUS_EMAC0_MI_INT \
57 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
58 #define NIG_STATUS_XGXS0_LINK10G \
59 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
60 #define NIG_STATUS_XGXS0_LINK_STATUS \
61 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
62 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
63 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
64 #define NIG_STATUS_SERDES0_LINK_STATUS \
65 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
66 #define NIG_MASK_MI_INT \
67 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
68 #define NIG_MASK_XGXS0_LINK10G \
69 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
70 #define NIG_MASK_XGXS0_LINK_STATUS \
71 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
72 #define NIG_MASK_SERDES0_LINK_STATUS \
73 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
75 #define MDIO_AN_CL73_OR_37_COMPLETE \
76 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
77 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
79 #define XGXS_RESET_BITS \
80 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
81 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
82 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
83 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
84 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
86 #define SERDES_RESET_BITS \
87 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
88 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
89 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
90 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
92 #define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
93 #define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
94 #define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
95 #define AUTONEG_PARALLEL \
96 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
97 #define AUTONEG_SGMII_FIBER_AUTODET \
98 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
99 #define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
101 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
103 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
105 #define GP_STATUS_SPEED_MASK \
106 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
107 #define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
108 #define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
109 #define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
110 #define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
111 #define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
112 #define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
113 #define GP_STATUS_10G_HIG \
114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
115 #define GP_STATUS_10G_CX4 \
116 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
117 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
118 #define GP_STATUS_10G_KX4 \
119 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
120 #define GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
121 #define GP_STATUS_10G_XFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
122 #define GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
123 #define GP_STATUS_10G_SFI MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
124 #define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
125 #define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
126 #define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
127 #define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
128 #define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
129 #define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
130 #define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
131 #define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
132 #define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
133 #define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
134 #define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
135 #define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
136 #define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
137 #define LINK_20GTFD LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
138 #define LINK_20GXFD LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
140 #define LINK_UPDATE_MASK \
141 (LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
142 LINK_STATUS_LINK_UP | \
143 LINK_STATUS_PHYSICAL_LINK_FLAG | \
144 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
145 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
146 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
147 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
148 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
149 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
151 #define SFP_EEPROM_CON_TYPE_ADDR 0x2
152 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
153 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
156 #define SFP_EEPROM_COMP_CODE_ADDR 0x3
157 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
158 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
159 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
161 #define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
162 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
163 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
165 #define SFP_EEPROM_OPTIONS_ADDR 0x40
166 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
167 #define SFP_EEPROM_OPTIONS_SIZE 2
169 #define EDC_MODE_LINEAR 0x0022
170 #define EDC_MODE_LIMITING 0x0044
171 #define EDC_MODE_PASSIVE_DAC 0x0055
174 #define DCBX_INVALID_COS (0xFF)
176 #define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
177 #define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
178 #define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS (1360)
179 #define ETS_E3B0_NIG_MIN_W_VAL_20GBPS (2720)
180 #define ETS_E3B0_PBF_MIN_W_VAL (10000)
182 #define MAX_PACKET_SIZE (9700)
183 #define MAX_KR_LINK_RETRY 4
189 #define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
190 bnx2x_cl45_write(_bp, _phy, \
191 (_phy)->def_md_devad, \
192 (_bank + (_addr & 0xf)), \
195 #define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
196 bnx2x_cl45_read(_bp, _phy, \
197 (_phy)->def_md_devad, \
198 (_bank + (_addr & 0xf)), \
230 u32 cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
231 u32 saved_val, req_val, eee_status;
245 additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
252 port_mb[params->
port].link_status));
266 lfa_mask = 0xffffffff;
276 if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
278 (saved_val & lfa_mask), (req_val & lfa_mask));
285 if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
287 (saved_val & lfa_mask), (req_val & lfa_mask));
294 if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
296 (saved_val & lfa_mask), (req_val & lfa_mask));
300 for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
303 speed_cap_mask[cfg_idx]));
313 cur_req_fc_auto_adv =
326 eee_status[params->
port]));
343 static void bnx2x_get_epio(
struct bnx2x *bp,
u32 epio_pin,
u32 *en)
345 u32 epio_mask, gp_oenable;
353 epio_mask = 1 << epio_pin;
360 static void bnx2x_set_epio(
struct bnx2x *bp,
u32 epio_pin,
u32 en)
362 u32 epio_mask, gp_output, gp_oenable;
370 epio_mask = 1 << epio_pin;
374 gp_output |= epio_mask;
376 gp_output &= ~epio_mask;
385 static void bnx2x_set_cfg_pin(
struct bnx2x *bp,
u32 pin_cfg,
u32 val)
398 static u32 bnx2x_get_cfg_pin(
struct bnx2x *bp,
u32 pin_cfg,
u32 *val)
415 static void bnx2x_ets_e2e3a0_disabled(
struct link_params *params)
473 static u32 bnx2x_ets_get_min_w_val_nig(
const struct link_vars *vars)
494 static u32 bnx2x_ets_get_credit_upper_bound(
const u32 min_w_val)
496 const u32 credit_upper_bound = (
u32)
MAXVAL((150 * min_w_val),
498 return credit_upper_bound;
505 static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
511 const u32 credit_upper_bound =
512 bnx2x_ets_get_credit_upper_bound(min_w_val);
544 static void bnx2x_ets_e3b0_nig_disabled(
const struct link_params *params,
548 const u8 port = params->
port;
549 const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
620 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
627 static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
632 const u32 credit_upper_bound =
633 bnx2x_ets_get_credit_upper_bound(min_w_val);
634 const u8 port = params->
port;
635 u32 base_upper_bound = 0;
650 REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
661 static void bnx2x_ets_e3b0_pbf_disabled(
const struct link_params *params)
664 const u8 port = params->
port;
710 REG_WR(bp, base_weight + (0x4 * i), 0);
712 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
719 static int bnx2x_ets_e3b0_disabled(
const struct link_params *params,
726 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
730 bnx2x_ets_e3b0_nig_disabled(params, vars);
732 bnx2x_ets_e3b0_pbf_disabled(params);
746 int bnx2x_status = 0;
749 bnx2x_ets_e2e3a0_disabled(params);
751 bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
765 static int bnx2x_ets_e3b0_cli_map(
const struct link_params *params,
767 const u8 cos_sp_bitmap,
768 const u8 cos_bw_bitmap)
771 const u8 port = params->
port;
772 const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
773 const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
774 const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
775 const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
785 nig_cli_subject2wfq_bitmap);
789 pbf_cli_subject2wfq_bitmap);
799 static int bnx2x_ets_e3b0_set_cos_bw(
struct bnx2x *bp,
801 const u32 min_w_val_nig,
802 const u32 min_w_val_pbf,
807 u32 nig_reg_adress_crd_weight = 0;
808 u32 pbf_reg_adress_crd_weight = 0;
810 const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
811 const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
815 nig_reg_adress_crd_weight =
818 pbf_reg_adress_crd_weight = (
port) ?
822 nig_reg_adress_crd_weight = (
port) ?
825 pbf_reg_adress_crd_weight = (
port) ?
829 nig_reg_adress_crd_weight = (
port) ?
833 pbf_reg_adress_crd_weight = (
port) ?
839 nig_reg_adress_crd_weight =
841 pbf_reg_adress_crd_weight =
847 nig_reg_adress_crd_weight =
854 nig_reg_adress_crd_weight =
860 REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
862 REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
871 static int bnx2x_ets_e3b0_get_total_bw(
878 u8 is_bw_cos_exist = 0;
882 for (cos_idx = 0; cos_idx < ets_params->
num_of_cos; cos_idx++) {
885 if (!ets_params->
cos[cos_idx].params.bw_params.bw) {
891 ets_params->
cos[cos_idx].params.bw_params.bw
895 ets_params->
cos[cos_idx].params.bw_params.bw;
900 if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
901 if (*total_bw == 0) {
903 "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
907 "bnx2x_ets_E3B0_config total BW should be 100\n");
920 static void bnx2x_ets_e3b0_sp_pri_to_cos_init(
u8 *sp_pri_to_cos)
932 static int bnx2x_ets_e3b0_sp_pri_to_cos_set(
const struct link_params *params,
933 u8 *sp_pri_to_cos,
const u8 pri,
937 const u8 port = params->
port;
941 if (pri >= max_num_of_cos) {
943 "parameter Illegal strict priority\n");
949 "parameter There can't be two COS's with "
950 "the same strict pri\n");
954 sp_pri_to_cos[
pri] = cos_entry;
965 static u64 bnx2x_e3b0_sp_get_pri_cli_reg(
const u8 cos,
const u8 cos_offset,
971 pri_cli_nig = ((
u64)(cos + cos_offset)) << (entry_size *
972 (pri_set + pri_offset));
982 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(
const u8 cos,
const u8 pri_set)
985 const u8 nig_cos_offset = 3;
986 const u8 nig_pri_offset = 3;
988 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
998 static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
const u8 cos,
const u8 pri_set)
1000 const u8 pbf_cos_offset = 0;
1001 const u8 pbf_pri_offset = 0;
1003 return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1014 static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(
const struct link_params *params,
1017 struct bnx2x *bp = params->
bp;
1019 const u8 port = params->
port;
1021 u64 pri_cli_nig = 0x210;
1022 u32 pri_cli_pbf = 0x0;
1028 u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
1031 for (i = 0; i < max_num_of_cos; i++) {
1035 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1036 "invalid cos entry\n");
1040 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1041 sp_pri_to_cos[i], pri_set);
1043 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1044 sp_pri_to_cos[i], pri_set);
1045 pri_bitmask = 1 << sp_pri_to_cos[
i];
1047 if (!(pri_bitmask & cos_bit_to_set)) {
1049 "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1050 "invalid There can't be two COS's with"
1051 " the same strict pri\n");
1054 cos_bit_to_set &= ~pri_bitmask;
1060 for (i = 0; i < max_num_of_cos; i++) {
1061 pri_bitmask = 1 <<
i;
1063 if (pri_bitmask & cos_bit_to_set) {
1065 pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1068 pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1071 cos_bit_to_set &= ~pri_bitmask;
1076 if (pri_set != max_num_of_cos) {
1078 "entries were set\n");
1090 const u32 pri_cli_nig_lsb = (
u32) (pri_cli_nig);
1091 const u32 pri_cli_nig_msb = (
u32) ((pri_cli_nig >> 32) & 0xF);
1111 struct bnx2x *bp = params->
bp;
1112 int bnx2x_status = 0;
1113 const u8 port = params->
port;
1115 const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1117 u8 cos_bw_bitmap = 0;
1118 u8 cos_sp_bitmap = 0;
1126 "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1130 if ((ets_params->
num_of_cos > max_num_of_cos)) {
1132 "isn't supported\n");
1137 bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1140 bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1144 "bnx2x_ets_E3B0_config get_total_bw failed\n");
1151 bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1152 bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1155 for (cos_entry = 0; cos_entry < ets_params->
num_of_cos; cos_entry++) {
1157 cos_bw_bitmap |= (1 << cos_entry);
1161 bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1162 bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1164 ets_params->
cos[cos_entry].params.bw_params.bw,
1167 ets_params->
cos[cos_entry].state){
1168 cos_sp_bitmap |= (1 << cos_entry);
1170 bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1173 ets_params->
cos[cos_entry].params.sp_params.pri,
1178 "bnx2x_ets_e3b0_config cos state not valid\n");
1183 "bnx2x_ets_e3b0_config set cos bw failed\n");
1184 return bnx2x_status;
1189 bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1194 "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1195 return bnx2x_status;
1199 bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1205 return bnx2x_status;
1209 static void bnx2x_ets_bw_limit_common(
const struct link_params *params)
1212 struct bnx2x *bp = params->
bp;
1257 struct bnx2x *bp = params->
bp;
1258 const u32 total_bw = cos0_bw + cos1_bw;
1259 u32 cos0_credit_weight = 0;
1260 u32 cos1_credit_weight = 0;
1276 bnx2x_ets_bw_limit_common(params);
1288 struct bnx2x *bp = params->
bp;
1319 val = (!strict_cos) ? 0x2318 : 0x22E0;
1328 static void bnx2x_update_pfc_xmac(
struct link_params *params,
1332 struct bnx2x *bp = params->
bp;
1334 u32 pause_val, pfc0_val, pfc1_val;
1340 pause_val = 0x18000;
1341 pfc0_val = 0xFFFF8000;
1390 static void bnx2x_emac_get_pfc_stat(
struct link_params *params,
1391 u32 pfc_frames_sent[2],
1392 u32 pfc_frames_received[2])
1395 struct bnx2x *bp = params->
bp;
1403 val_xoff =
REG_RD(bp, emac_base +
1409 pfc_frames_received[0] = val_xon + val_xoff;
1412 val_xoff =
REG_RD(bp, emac_base +
1418 pfc_frames_sent[0] = val_xon + val_xoff;
1423 u32 pfc_frames_sent[2],
1424 u32 pfc_frames_received[2])
1427 struct bnx2x *bp = params->
bp;
1436 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1437 pfc_frames_received);
1467 static u8 bnx2x_is_4_port_mode(
struct bnx2x *bp)
1469 u32 port4mode_ovwr_val;
1472 if (port4mode_ovwr_val & (1<<0)) {
1474 return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1480 static void bnx2x_emac_init(
struct link_params *params,
1484 struct bnx2x *bp = params->
bp;
1511 bnx2x_set_mdio_clk(bp, params->
chip_id, port);
1513 val = ((params->
mac_addr[0] << 8) |
1517 val = ((params->
mac_addr[2] << 24) |
1524 static void bnx2x_set_xumac_nig(
struct link_params *params,
1528 struct bnx2x *bp = params->
bp;
1538 static void bnx2x_set_umac_rxtx(
struct link_params *params,
u8 en)
1542 struct bnx2x *bp = params->
bp;
1557 static void bnx2x_umac_enable(
struct link_params *params,
1562 struct bnx2x *bp = params->
bp;
1649 bnx2x_set_xumac_nig(params,
1656 static void bnx2x_xmac_init(
struct link_params *params,
u32 max_speed)
1658 struct bnx2x *bp = params->
bp;
1659 u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1671 "XMAC already out of reset in 4-port mode\n");
1677 MISC_REGISTERS_RESET_REG_2_XMAC);
1681 MISC_REGISTERS_RESET_REG_2_XMAC);
1695 "Init XMAC to 10G x 1 port per path\n");
1700 "Init XMAC to 20G x 2 ports per path\n");
1715 static void bnx2x_set_xmac_rxtx(
struct link_params *params,
u8 en)
1718 struct bnx2x *bp = params->
bp;
1730 (pfc_ctrl & ~(1<<1)));
1732 (pfc_ctrl | (1<<1)));
1743 static int bnx2x_xmac_enable(
struct link_params *params,
1747 struct bnx2x *bp = params->
bp;
1770 bnx2x_update_pfc_xmac(params, vars, 0);
1787 bnx2x_set_xumac_nig(params,
1795 static int bnx2x_emac_enable(
struct link_params *params,
1798 struct bnx2x *bp = params->
bp;
1845 bnx2x_bits_en(bp, emac_base +
1850 bnx2x_bits_en(bp, emac_base +
1928 static void bnx2x_update_pfc_bmac1(
struct link_params *params,
1932 struct bnx2x *bp = params->
bp;
1957 static void bnx2x_update_pfc_bmac2(
struct link_params *params,
1965 struct bnx2x *bp = params->
bp;
1994 wb_data[0] |= (1<<0);
1995 wb_data[0] |= (1<<1);
1996 wb_data[0] |= (1<<2);
1997 wb_data[0] |= (1<<3);
1998 wb_data[0] |= (1<<5);
2003 wb_data[0] &= ~(1<<2);
2035 val |= ((1<<6)|(1<<5));
2047 static int bnx2x_pfc_nig_rx_priority_mask(
struct bnx2x *bp,
2049 u32 priority_mask,
u8 port)
2051 u32 nig_reg_rx_priority_mask_add = 0;
2053 switch (cos_entry) {
2055 nig_reg_rx_priority_mask_add = (
port) ?
2060 nig_reg_rx_priority_mask_add = (
port) ?
2065 nig_reg_rx_priority_mask_add = (
port) ?
2086 REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2090 static void bnx2x_update_mng(
struct link_params *params,
u32 link_status)
2092 struct bnx2x *bp = params->
bp;
2096 port_mb[params->
port].link_status), link_status);
2099 static void bnx2x_update_pfc_nig(
struct link_params *params,
2103 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2104 u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2105 u32 pkt_priority_to_cos = 0;
2106 struct bnx2x *bp = params->
bp;
2179 bnx2x_pfc_nig_rx_priority_mask(bp, i,
2192 pkt_priority_to_cos);
2204 struct bnx2x *bp = params->
bp;
2205 int bnx2x_status = 0;
2216 bnx2x_update_pfc_nig(params, vars, pfc_params);
2219 return bnx2x_status;
2225 bnx2x_update_pfc_xmac(params, vars, 0);
2232 bnx2x_emac_enable(params, vars, 0);
2233 return bnx2x_status;
2236 bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2238 bnx2x_update_pfc_bmac1(params, vars);
2247 return bnx2x_status;
2251 static int bnx2x_bmac1_enable(
struct link_params *params,
2255 struct bnx2x *bp = params->
bp;
2271 wb_data[0] = ((params->
mac_addr[2] << 24) |
2275 wb_data[1] = ((params->
mac_addr[0] << 8) |
2294 bnx2x_update_pfc_bmac1(params, vars);
2307 wb_data[0] = 0x1000200;
2315 static int bnx2x_bmac2_enable(
struct link_params *params,
2319 struct bnx2x *bp = params->
bp;
2341 wb_data[0] = ((params->
mac_addr[2] << 24) |
2345 wb_data[1] = ((params->
mac_addr[0] << 8) |
2353 wb_data[0] = 0x1000200;
2375 bnx2x_update_pfc_bmac2(params, vars, is_lb);
2380 static int bnx2x_bmac_enable(
struct link_params *params,
2382 u8 is_lb,
u8 reset_bmac)
2386 struct bnx2x *bp = params->
bp;
2403 rc = bnx2x_bmac2_enable(params, vars, is_lb);
2405 rc = bnx2x_bmac1_enable(params, vars, is_lb);
2425 static void bnx2x_set_bmac_rx(
struct bnx2x *bp,
u32 chip_id,
u8 port,
u8 en)
2454 struct bnx2x *bp = params->
bp;
2467 while ((init_crd != crd) && count) {
2473 if (init_crd != crd) {
2497 switch (line_speed) {
2499 init_crd = thresh + 553 - 22;
2509 line_speed, init_crd);
2536 static u32 bnx2x_get_emac_base(
struct bnx2x *bp,
2537 u32 mdc_mdio_access,
u8 port)
2540 switch (mdc_mdio_access) {
2571 static int bnx2x_cl22_write(
struct bnx2x *bp,
2584 tmp = ((phy->
addr << 21) | (reg << 16) | val |
2589 for (i = 0; i < 50; i++) {
2606 static int bnx2x_cl22_read(
struct bnx2x *bp,
2620 val = ((phy->
addr << 21) | (reg << 16) |
2625 for (i = 0; i < 50; i++) {
2635 if (val & EMAC_MDIO_COMM_START_BUSY) {
2648 static int bnx2x_cl45_read(
struct bnx2x *bp,
struct bnx2x_phy *phy,
2658 val = ((phy->
addr << 21) | (devad << 16) | reg |
2663 for (i = 0; i < 50; i++) {
2667 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2672 if (val & EMAC_MDIO_COMM_START_BUSY) {
2674 netdev_err(bp->
dev,
"MDC/MDIO access timeout\n");
2679 val = ((phy->
addr << 21) | (devad << 16) |
2684 for (i = 0; i < 50; i++) {
2689 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2694 if (val & EMAC_MDIO_COMM_START_BUSY) {
2696 netdev_err(bp->
dev,
"MDC/MDIO access timeout\n");
2706 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2716 static int bnx2x_cl45_write(
struct bnx2x *bp,
struct bnx2x_phy *phy,
2727 tmp = ((phy->
addr << 21) | (devad << 16) | reg |
2732 for (i = 0; i < 50; i++) {
2736 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2741 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2743 netdev_err(bp->
dev,
"MDC/MDIO access timeout\n");
2747 tmp = ((phy->
addr << 21) | (devad << 16) | val |
2752 for (i = 0; i < 50; i++) {
2757 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2762 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2764 netdev_err(bp->
dev,
"MDC/MDIO access timeout\n");
2773 bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
2787 struct bnx2x *bp = params->
bp;
2796 static int bnx2x_eee_nvram_to_time(
u32 nvram_mode,
u32 *idle_timer)
2798 switch (nvram_mode) {
2816 static int bnx2x_eee_time_to_nvram(
u32 idle_timer,
u32 *nvram_mode)
2818 switch (idle_timer) {
2838 u32 eee_mode, eee_idle;
2839 struct bnx2x *bp = params->
bp;
2847 if (bnx2x_eee_nvram_to_time(params->
eee_mode &
2856 port_feature_config[params->
port].
2861 if (bnx2x_eee_nvram_to_time(eee_mode, &eee_idle))
2868 static int bnx2x_eee_set_timers(
struct link_params *params,
2871 u32 eee_idle = 0, eee_mode;
2872 struct bnx2x *bp = params->
bp;
2874 eee_idle = bnx2x_eee_calc_timer(params);
2893 if (bnx2x_eee_time_to_nvram(eee_idle, &eee_mode))
2901 static int bnx2x_eee_initial_config(
struct link_params *params,
2910 vars->
eee_status &= ~SHMEM_EEE_LPI_REQUESTED_BIT;
2917 return bnx2x_eee_set_timers(params, vars);
2920 static int bnx2x_eee_disable(
struct bnx2x_phy *phy,
2924 struct bnx2x *bp = params->
bp;
2936 static int bnx2x_eee_advertise(
struct bnx2x_phy *phy,
2940 struct bnx2x *bp = params->
bp;
2963 static void bnx2x_update_mng_eee(
struct link_params *params,
u32 eee_status)
2965 struct bnx2x *bp = params->
bp;
2967 if (bnx2x_eee_has_cap(params))
2970 eee_status[params->
port]), eee_status);
2973 static void bnx2x_eee_an_resolve(
struct bnx2x_phy *phy,
2977 struct bnx2x *bp = params->
bp;
2978 u16 adv = 0,
lp = 0;
3023 static void bnx2x_bsc_module_sel(
struct link_params *params)
3026 u32 board_cfg, sfp_ctrl;
3028 struct bnx2x *bp = params->
bp;
3041 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3046 bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3049 static int bnx2x_bsc_read(
struct link_params *params,
3059 struct bnx2x *bp = params->
bp;
3061 if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3066 if (xfer_cnt > 16) {
3071 bnx2x_bsc_module_sel(params);
3073 xfer_cnt = 16 - lc_addr;
3081 val = (sl_devid << 16) | sl_addr;
3130 for (i = (lc_addr >> 2); i < 4; i++) {
3133 data_array[
i] = ((data_array[
i] & 0x000000ff) << 24) |
3134 ((data_array[
i] & 0x0000ff00) << 8) |
3135 ((data_array[
i] & 0x00ff0000) >> 8) |
3136 ((data_array[
i] & 0xff000000) >> 24);
3142 static void bnx2x_cl45_read_or_write(
struct bnx2x *bp,
struct bnx2x_phy *phy,
3146 bnx2x_cl45_read(bp, phy, devad, reg, &val);
3147 bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3157 for (phy_index = 0; phy_index < params->
num_phys; phy_index++) {
3158 if (params->
phy[phy_index].addr == phy_addr) {
3159 return bnx2x_cl45_read(params->
bp,
3160 ¶ms->
phy[phy_index], devad,
3174 for (phy_index = 0; phy_index < params->
num_phys; phy_index++) {
3175 if (params->
phy[phy_index].addr == phy_addr) {
3176 return bnx2x_cl45_write(params->
bp,
3177 ¶ms->
phy[phy_index], devad,
3183 static u8 bnx2x_get_warpcore_lane(
struct bnx2x_phy *phy,
3187 struct bnx2x *bp = params->
bp;
3188 u32 path_swap, path_swap_ovr;
3192 port = params->
port;
3194 if (bnx2x_is_4_port_mode(bp)) {
3195 u32 port_swap, port_swap_ovr;
3199 if (path_swap_ovr & 0x1)
3200 path_swap = (path_swap_ovr & 0x2);
3209 if (port_swap_ovr & 0x1)
3210 port_swap = (port_swap_ovr & 0x2);
3217 lane = (port<<1) + path;
3223 if (path_swap_ovr & 0x1) {
3224 path_swap = (path_swap_ovr & 0x2);
3237 static void bnx2x_set_aer_mmd(
struct link_params *params,
3242 struct bnx2x *bp = params->
bp;
3248 (phy->
addr + ser_lane) : 0;
3251 aer_val = bnx2x_get_warpcore_lane(phy, params);
3259 aer_val = (aer_val >> 1) | 0x200;
3261 aer_val = 0x3800 + offset - 1;
3263 aer_val = 0x3800 +
offset;
3274 static void bnx2x_set_serdes_access(
struct bnx2x *bp,
u8 port)
3288 static void bnx2x_serdes_deassert(
struct bnx2x *bp,
u8 port)
3301 bnx2x_set_serdes_access(bp, port);
3307 static void bnx2x_xgxs_specific_func(
struct bnx2x_phy *phy,
3311 struct bnx2x *bp = params->
bp;
3322 static void bnx2x_xgxs_deassert(
struct link_params *params)
3324 struct bnx2x *bp = params->
bp;
3328 port = params->
port;
3336 bnx2x_xgxs_specific_func(¶ms->
phy[
INT_PHY], params,
3340 static void bnx2x_calc_ieee_aneg_adv(
struct bnx2x_phy *phy,
3343 struct bnx2x *bp = params->
bp;
3375 static void set_phy_vars(
struct link_params *params,
3378 struct bnx2x *bp = params->
bp;
3379 u8 actual_phy_idx, phy_index, link_cfg_idx;
3385 actual_phy_idx = phy_index;
3386 if (phy_config_swapped) {
3392 params->
phy[actual_phy_idx].req_flow_ctrl =
3395 params->
phy[actual_phy_idx].req_line_speed =
3398 params->
phy[actual_phy_idx].speed_cap_mask =
3401 params->
phy[actual_phy_idx].req_duplex =
3409 " speed_cap_mask %x\n",
3410 params->
phy[actual_phy_idx].req_flow_ctrl,
3411 params->
phy[actual_phy_idx].req_line_speed,
3412 params->
phy[actual_phy_idx].speed_cap_mask);
3416 static void bnx2x_ext_phy_set_pause(
struct link_params *params,
3421 struct bnx2x *bp = params->
bp;
3428 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->
ieee_fc);
3443 static void bnx2x_pause_resolve(
struct link_vars *vars,
u32 pause_result)
3445 switch (pause_result) {
3464 if (pause_result & (1<<0))
3466 if (pause_result & (1<<1))
3471 static void bnx2x_ext_phy_update_adv_fc(
struct bnx2x_phy *phy,
3478 struct bnx2x *bp = params->
bp;
3480 bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
3481 bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3484 u8 lane = bnx2x_get_warpcore_lane(phy, params);
3485 u16 gp_status, gp_mask;
3486 bnx2x_cl45_read(bp, phy,
3492 if ((gp_status & gp_mask) == gp_mask) {
3502 ld_pause = ((ld_pause &
3505 lp_pause = ((lp_pause &
3510 bnx2x_cl45_read(bp, phy,
3513 bnx2x_cl45_read(bp, phy,
3517 pause_result = (ld_pause &
3519 pause_result |= (lp_pause &
3522 bnx2x_pause_resolve(vars, pause_result);
3526 static u8 bnx2x_ext_phy_resolve_fc(
struct bnx2x_phy *phy,
3535 bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3542 bnx2x_ext_phy_update_adv_fc(phy, params, vars);
3555 static void bnx2x_warpcore_set_lpi_passthrough(
struct bnx2x_phy *phy,
3558 struct bnx2x *bp = params->
bp;
3567 static void bnx2x_warpcore_enable_AN_KR(
struct bnx2x_phy *phy,
3570 u16 lane,
i, cl72_ctrl, an_adv = 0;
3572 struct bnx2x *bp = params->
bp;
3584 bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3589 cl72_ctrl &= 0xf8ff;
3590 cl72_ctrl |= 0x3800;
3602 bnx2x_cl45_read_or_write(bp, phy,
MDIO_WC_DEVAD, addr, 0x1);
3616 bnx2x_set_aer_mmd(params, phy);
3621 lane = bnx2x_get_warpcore_lane(phy, params);
3647 port_hw_config[params->
port].default_cfg)) &
3656 bnx2x_ext_phy_set_pause(params, phy, vars);
3661 if (ucode_ver < 0xd108) {
3679 static void bnx2x_warpcore_set_10G_KR(
struct bnx2x_phy *phy,
3683 struct bnx2x *bp = params->
bp;
3701 bnx2x_cl45_write(bp, phy, reg_set[i].devad, reg_set[i].reg,
3704 lane = bnx2x_get_warpcore_lane(phy, params);
3711 val16 &= ~(0x0011 << lane);
3717 val16 |= (0x0303 << (lane << 1));
3721 bnx2x_set_aer_mmd(params, phy);
3749 static void bnx2x_warpcore_set_10G_XFI(
struct bnx2x_phy *phy,
3753 struct bnx2x *bp = params->
bp;
3754 u16 misc1_val, tap_val, tx_driver_val, lane,
val;
3794 ((val | 0x0006) & 0xFFFE));
3800 misc1_val &= ~(0x1f);
3826 lane = bnx2x_get_warpcore_lane(phy, params);
3842 bnx2x_warpcore_set_lpi_passthrough(phy, params);
3861 static void bnx2x_warpcore_set_20G_KR2(
struct bnx2x *bp,
3867 static void bnx2x_warpcore_set_20G_DXGXS(
struct bnx2x *bp,
3925 static void bnx2x_warpcore_set_sgmii_speed(
struct bnx2x_phy *phy,
3930 struct bnx2x *bp = params->
bp;
3931 u16 val16, digctrl_kx1, digctrl_kx2;
3939 bnx2x_warpcore_set_lpi_passthrough(phy, params);
3987 digctrl_kx1 &= 0xff4a;
3998 (digctrl_kx2 & ~(1<<2)));
4003 (digctrl_kx2 | (1<<2)));
4008 (digctrl_kx1 | 0x10));
4011 static void bnx2x_warpcore_reset_lane(
struct bnx2x *bp,
4029 static void bnx2x_warpcore_clear_regs(
struct bnx2x_phy *phy,
4033 struct bnx2x *bp = params->
bp;
4055 for (i = 0; i <
sizeof(wc_regs)/
sizeof(
struct bnx2x_reg_set); i++)
4056 bnx2x_cl45_write(bp, phy, wc_regs[i].devad, wc_regs[i].reg,
4059 lane = bnx2x_get_warpcore_lane(phy, params);
4065 static int bnx2x_get_mod_abs_int_cfg(
struct bnx2x *bp,
4067 u32 shmem_base,
u8 port,
4068 u8 *gpio_num,
u8 *gpio_port)
4074 cfg_pin = (
REG_RD(bp, shmem_base +
4076 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4089 "ERROR: Invalid cfg pin %x for module detect indication\n",
4104 static int bnx2x_is_sfp_module_plugged(
struct bnx2x_phy *phy,
4107 struct bnx2x *bp = params->
bp;
4108 u8 gpio_num, gpio_port;
4110 if (bnx2x_get_mod_abs_int_cfg(bp, params->
chip_id,
4112 &gpio_num, &gpio_port) != 0)
4122 static int bnx2x_warpcore_get_sigdet(
struct bnx2x_phy *phy,
4125 u16 gp2_status_reg0, lane;
4126 struct bnx2x *bp = params->
bp;
4128 lane = bnx2x_get_warpcore_lane(phy, params);
4133 return (gp2_status_reg0 >> (8+lane)) & 0x1;
4136 static void bnx2x_warpcore_config_runtime(
struct bnx2x_phy *phy,
4140 struct bnx2x *bp = params->
bp;
4142 u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4143 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4151 if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4159 port_hw_config[params->
port].default_cfg)) &
4162 switch (serdes_net_if) {
4167 lnkup = (gp_status1 >> (8+lane)) & 0x1;
4169 lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4172 "gp_status1 0x%x\n", gp_status1);
4174 if (lnkup_kr || lnkup) {
4177 "link up, rx_tx_asic_rst 0x%x\n",
4181 bnx2x_warpcore_reset_lane(bp, phy, 1);
4182 bnx2x_warpcore_reset_lane(bp, phy, 0);
4201 static void bnx2x_warpcore_config_sfi(
struct bnx2x_phy *phy,
4204 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4205 struct bnx2x *bp = params->
bp;
4206 bnx2x_warpcore_clear_regs(phy, params, lane);
4211 bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4214 bnx2x_warpcore_set_sgmii_speed(phy, params, 1, 0);
4218 static void bnx2x_warpcore_config_init(
struct bnx2x_phy *phy,
4222 struct bnx2x *bp = params->
bp;
4225 u16 lane = bnx2x_get_warpcore_lane(phy, params);
4228 port_hw_config[params->
port].default_cfg)) &
4231 "serdes_net_if = 0x%x\n",
4233 bnx2x_set_aer_mmd(params, phy);
4234 bnx2x_warpcore_reset_lane(bp, phy, 1);
4242 bnx2x_warpcore_clear_regs(phy, params, lane);
4243 bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
4245 switch (serdes_net_if) {
4249 bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4252 bnx2x_warpcore_set_10G_KR(phy, params, vars);
4257 bnx2x_warpcore_clear_regs(phy, params, lane);
4260 bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4269 bnx2x_warpcore_set_sgmii_speed(phy,
4279 if (bnx2x_is_sfp_module_plugged(phy, params))
4282 bnx2x_warpcore_config_sfi(phy, params);
4291 bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4303 bnx2x_warpcore_set_20G_KR2(bp, phy);
4308 "Unsupported Serdes Net Interface 0x%x\n",
4315 bnx2x_warpcore_reset_lane(bp, phy, 0);
4319 static void bnx2x_sfp_e3_set_transmitter(
struct link_params *params,
4323 struct bnx2x *bp = params->
bp;
4329 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4335 bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4337 bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4340 static void bnx2x_warpcore_link_reset(
struct bnx2x_phy *phy,
4343 struct bnx2x *bp = params->
bp;
4345 bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4346 bnx2x_set_mdio_clk(bp, params->
chip_id, params->
port);
4347 bnx2x_set_aer_mmd(params, phy);
4349 bnx2x_warpcore_reset_lane(bp, phy, 1);
4381 lane = bnx2x_get_warpcore_lane(phy, params);
4385 val16 |= (0x11 << lane);
4387 val16 |= (0x22 << lane);
4393 val16 &= ~(0x0303 << (lane << 1));
4394 val16 |= (0x0101 << (lane << 1));
4396 val16 &= ~(0x0c0c << (lane << 1));
4397 val16 |= (0x0404 << (lane << 1));
4403 bnx2x_set_aer_mmd(params, phy);
4407 static void bnx2x_set_warpcore_loopback(
struct bnx2x_phy *phy,
4410 struct bnx2x *bp = params->
bp;
4427 lane = bnx2x_get_warpcore_lane(phy, params);
4435 bnx2x_set_aer_mmd(params, phy);
4449 static void bnx2x_sync_link(
struct link_params *params,
4452 struct bnx2x *bp = params->
bp;
4526 if (link_10g_plus) {
4558 struct bnx2x *bp = params->
bp;
4562 set_phy_vars(params, vars);
4566 port_mb[port].link_status));
4567 if (bnx2x_eee_has_cap(params))
4570 eee_status[params->
port]));
4573 bnx2x_sync_link(params, vars);
4577 dev_info.port_hw_config[port].media_type);
4578 media_types =
REG_RD(bp, sync_offset);
4594 dev_info.port_hw_config[port].aeu_int_mask);
4612 static void bnx2x_set_master_ln(
struct link_params *params,
4615 struct bnx2x *bp = params->
bp;
4616 u16 new_master_ln, ser_lane;
4630 (new_master_ln | ser_lane));
4633 static int bnx2x_reset_unicore(
struct link_params *params,
4637 struct bnx2x *bp = params->
bp;
4651 bnx2x_set_serdes_access(bp, params->
port);
4669 netdev_err(bp->
dev,
"Warning: PHY was not initialized,"
4677 static void bnx2x_set_swap_lanes(
struct link_params *params,
4680 struct bnx2x *bp = params->
bp;
4684 u16 rx_lane_swap, tx_lane_swap;
4693 if (rx_lane_swap != 0x1b) {
4706 if (tx_lane_swap != 0x1b) {
4719 static void bnx2x_set_parallel_detection(
struct bnx2x_phy *phy,
4722 struct bnx2x *bp = params->
bp;
4772 static void bnx2x_set_autoneg(
struct bnx2x_phy *phy,
4777 struct bnx2x *bp = params->
bp;
4876 static void bnx2x_program_serdes(
struct bnx2x_phy *phy,
4880 struct bnx2x *bp = params->
bp;
4925 static void bnx2x_set_brcm_cl37_advertisement(
struct bnx2x_phy *phy,
4928 struct bnx2x *bp = params->
bp;
4945 static void bnx2x_set_ieee_aneg_advertisement(
struct bnx2x_phy *phy,
4949 struct bnx2x *bp = params->
bp;
4966 static void bnx2x_restart_autoneg(
struct bnx2x_phy *phy,
4970 struct bnx2x *bp = params->
bp;
4995 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
5006 static void bnx2x_initialize_sgmii_process(
struct bnx2x_phy *phy,
5010 struct bnx2x *bp = params->
bp;
5072 bnx2x_restart_autoneg(phy, params, 0);
5078 static int bnx2x_direct_parallel_detect_used(
struct bnx2x_phy *phy,
5081 struct bnx2x *bp = params->
bp;
5082 u16 pd_10g, status2_1000x;
5112 static void bnx2x_update_adv_fc(
struct bnx2x_phy *phy,
5120 struct bnx2x *bp = params->
bp;
5135 pause_result = (ld_pause &
5137 pause_result |= (lp_pause &
5149 pause_result = (ld_pause &
5151 pause_result |= (lp_pause &
5155 bnx2x_pause_resolve(vars, pause_result);
5159 static void bnx2x_flow_ctrl_resolve(
struct bnx2x_phy *phy,
5164 struct bnx2x *bp = params->
bp;
5171 bnx2x_update_adv_fc(phy, params, vars, gp_status);
5178 if (bnx2x_direct_parallel_detect_used(phy, params)) {
5182 bnx2x_update_adv_fc(phy, params, vars, gp_status);
5187 static void bnx2x_check_fallback_to_cl37(
struct bnx2x_phy *phy,
5190 struct bnx2x *bp = params->
bp;
5199 (MDIO_RX0_RX_STATUS_SIGDET)) {
5201 "rx_status(0x80b0) = 0x%x\n", rx_status);
5219 "ustat_val(0x8371) = 0x%x\n", ustat_val);
5228 &cl37_fsm_received);
5229 if ((cl37_fsm_received &
5235 "misc_rx_status(0x8330) = 0x%x\n",
5251 bnx2x_restart_autoneg(phy, params, 0);
5255 static void bnx2x_xgxs_an_resolve(
struct bnx2x_phy *phy,
5260 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5264 if (bnx2x_direct_parallel_detect_used(phy, params))
5268 static int bnx2x_get_link_speed_duplex(
struct bnx2x_phy *phy,
5275 struct bnx2x *bp = params->
bp;
5284 switch (speed_mask) {
5321 "link speed unsupported gp_status 0x%x\n",
5340 "link speed unsupported gp_status 0x%x\n",
5358 static int bnx2x_link_settings_status(
struct bnx2x_phy *phy,
5362 struct bnx2x *bp = params->
bp;
5378 gp_status, link_up, speed_mask);
5379 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5384 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5387 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5389 bnx2x_xgxs_an_resolve(phy, params, vars,
5396 bnx2x_check_fallback_to_cl37(phy, params);
5432 static int bnx2x_warpcore_read_status(
struct bnx2x_phy *phy,
5436 struct bnx2x *bp = params->
bp;
5440 lane = bnx2x_get_warpcore_lane(phy, params);
5449 temp_link_up, link_up);
5452 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5458 gp_status1 = ((gp_status1 >> 8) & 0xf) |
5459 ((gp_status1 >> 12) & 0xf);
5460 link_up = gp_status1 & (1 << lane);
5468 if (gp_status4 & ((1<<12)<<lane))
5480 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5492 if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
5503 if (val & MDIO_OVER_1G_UP1_2_5G)
5522 if ((lane & 1) == 0)
5527 rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5534 static void bnx2x_set_gmii_tx_driver(
struct link_params *params)
5536 struct bnx2x *bp = params->
bp;
5564 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5565 tx_driver |= lp_up2;
5573 static int bnx2x_emac_program(
struct link_params *params,
5576 struct bnx2x *bp = params->
bp;
5620 static void bnx2x_set_preemphasis(
struct bnx2x_phy *phy,
5625 struct bnx2x *bp = params->
bp;
5644 static void bnx2x_xgxs_config_init(
struct bnx2x_phy *phy,
5648 struct bnx2x *bp = params->
bp;
5655 bnx2x_set_preemphasis(phy, params);
5664 bnx2x_set_autoneg(phy, params, vars, 0);
5667 bnx2x_program_serdes(phy, params, vars);
5673 bnx2x_set_brcm_cl37_advertisement(phy, params);
5676 bnx2x_set_ieee_aneg_advertisement(phy, params,
5680 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5683 bnx2x_restart_autoneg(phy, params, enable_cl73);
5689 bnx2x_initialize_sgmii_process(phy, params, vars);
5693 static int bnx2x_prepare_xgxs(
struct bnx2x_phy *phy,
5712 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->
ieee_fc);
5713 bnx2x_set_aer_mmd(params, phy);
5715 bnx2x_set_master_ln(params, phy);
5717 rc = bnx2x_reset_unicore(params, phy, 0);
5722 bnx2x_set_aer_mmd(params, phy);
5725 bnx2x_set_master_ln(params, phy);
5726 bnx2x_set_swap_lanes(params, phy);
5732 static u16 bnx2x_wait_reset_complete(
struct bnx2x *bp,
5738 for (cnt = 0; cnt < 1000; cnt++) {
5740 bnx2x_cl22_read(bp, phy,
5743 bnx2x_cl45_read(bp, phy,
5746 if (!(ctrl & (1<<15)))
5752 netdev_err(bp->
dev,
"Warning: PHY was not initialized,"
5759 static void bnx2x_link_int_enable(
struct link_params *params)
5763 struct bnx2x *bp = params->
bp;
5807 static void bnx2x_rearm_latch_signal(
struct bnx2x *bp,
u8 port,
5810 u32 latch_status = 0;
5817 latch_status =
REG_RD(bp,
5832 if (latch_status & 1) {
5836 (latch_status & 0xfffe) | (latch_status & 1));
5841 static void bnx2x_link_int_ack(
struct link_params *params,
5844 struct bnx2x *bp = params->
bp;
5868 mask = ((1 << ser_lane) <<
5881 static int bnx2x_format_ver(
u32 num,
u8 *
str,
u16 *len)
5884 u32 mask = 0xf0000000;
5887 u8 remove_leading_zeros = 1;
5897 digit = ((num &
mask) >> shift);
5898 if (digit == 0 && remove_leading_zeros) {
5901 }
else if (digit < 0xa)
5902 *str_ptr = digit +
'0';
5904 *str_ptr = digit - 0xa +
'a';
5905 remove_leading_zeros = 0;
5913 remove_leading_zeros = 1;
5920 static int bnx2x_null_format_ver(
u32 spirom_ver,
u8 *str,
u16 *len)
5934 u16 remain_len = len;
5935 if (version ==
NULL || params ==
NULL)
5944 status |= params->
phy[
EXT_PHY1].format_fw_ver(spirom_ver,
5947 ver_p += (len - remain_len);
5960 ver_p = version + (len - remain_len);
5967 static void bnx2x_set_xgxs_loopback(
struct bnx2x_phy *phy,
5971 struct bnx2x *bp = params->
bp;
5987 bnx2x_cl45_write(bp, phy,
5993 bnx2x_cl45_write(bp, phy,
6000 bnx2x_set_aer_mmd(params, phy);
6010 bnx2x_cl45_read(bp, phy, 5,
6014 bnx2x_cl45_write(bp, phy, 5,
6031 struct bnx2x *bp = params->
bp;
6034 speed, hw_led_mode);
6037 if (params->
phy[phy_idx].set_link_led) {
6038 params->
phy[phy_idx].set_link_led(
6039 ¶ms->
phy[phy_idx], params, mode);
6167 struct bnx2x *bp = params->
bp;
6168 u16 gp_status = 0, phy_index = 0;
6169 u8 ext_phy_link_up = 0, serdes_phy_type;
6185 u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
6189 gp_status = ((gp_status >> 8) & 0xf) |
6190 ((gp_status >> 12) & 0xf);
6191 link_up = gp_status & (1 << lane);
6201 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6213 ext_phy_link_up = params->
phy[
EXT_PHY1].read_status(
6215 params, &temp_vars);
6220 serdes_phy_type = ((params->
phy[phy_index].media_type ==
6222 (params->
phy[phy_index].media_type ==
6224 (params->
phy[phy_index].media_type ==
6226 (params->
phy[phy_index].media_type ==
6229 if (is_serdes != serdes_phy_type)
6231 if (params->
phy[phy_index].read_status) {
6233 params->
phy[phy_index].read_status(
6234 ¶ms->
phy[phy_index],
6235 params, &temp_vars);
6240 if (ext_phy_link_up)
6245 static int bnx2x_link_initialize(
struct link_params *params,
6249 u8 phy_index, non_ext_phy;
6250 struct bnx2x *bp = params->
bp;
6263 bnx2x_prepare_xgxs(¶ms->
phy[
INT_PHY], params, vars);
6275 bnx2x_set_parallel_detection(phy, params);
6295 if (params->
phy[phy_index].supported &
6303 "Not initializing second phy\n");
6306 params->
phy[phy_index].config_init(
6307 ¶ms->
phy[phy_index],
6321 static void bnx2x_int_link_reset(
struct bnx2x_phy *phy,
6326 (0x1ff << (params->
port*16)));
6329 static void bnx2x_common_ext_link_reset(
struct bnx2x_phy *phy,
6332 struct bnx2x *bp = params->
bp;
6338 gpio_port = params->
port;
6348 static int bnx2x_update_link_down(
struct link_params *params,
6351 struct bnx2x *bp = params->
bp;
6376 bnx2x_set_bmac_rx(bp, params->
chip_id, params->
port, 0);
6387 bnx2x_update_mng_eee(params, vars->
eee_status);
6388 bnx2x_set_xmac_rxtx(params, 0);
6389 bnx2x_set_umac_rxtx(params, 0);
6395 static int bnx2x_update_link_up(
struct link_params *params,
6399 struct bnx2x *bp = params->
bp;
6400 u8 phy_idx, port = params->
port;
6416 if (bnx2x_xmac_enable(params, vars, 0) ==
6424 bnx2x_umac_enable(params, vars, 0);
6429 (vars->
eee_status & SHMEM_EEE_LPI_REQUESTED_BIT)) {
6432 (params->
port << 2), 1);
6435 (params->
port << 2), 0xfc20);
6441 if (bnx2x_bmac_enable(params, vars, 0, 1) ==
6452 rc = bnx2x_emac_program(params, vars);
6453 bnx2x_emac_enable(params, vars, 0);
6460 bnx2x_set_gmii_tx_driver(params);
6466 rc |= bnx2x_pbf_update(params, vars->
flow_ctrl,
6474 bnx2x_update_mng_eee(params, vars->
eee_status);
6499 struct bnx2x *bp = params->
bp;
6502 u8 link_10g_plus, phy_index;
6503 u8 ext_phy_link_up = 0, cur_link_up;
6506 u16 ext_phy_line_speed = 0, prev_line_speed = vars->
line_speed;
6517 phy_vars[phy_index].
link_up = 0;
6524 bnx2x_set_aer_mmd(params, ¶ms->
phy[
INT_PHY]);
6559 &phy_vars[phy_index]);
6569 if (!ext_phy_link_up) {
6570 ext_phy_link_up = 1;
6571 active_external_phy = phy_index;
6598 "mpc=0x%x. DISABLING LINK !!!\n",
6600 ext_phy_link_up = 0;
6623 if (active_external_phy >
INT_PHY) {
6633 if (active_external_phy ==
EXT_PHY1) {
6636 "Disabling TX on EXT_PHY2\n");
6643 ext_phy_line_speed = phy_vars[active_external_phy].
line_speed;
6645 if (params->
phy[active_external_phy].supported &
6654 active_external_phy);
6659 if (params->
phy[phy_index].flags &
6661 bnx2x_rearm_latch_signal(bp, port,
6663 active_external_phy);
6668 " ext_phy_line_speed = %d\n", vars->
flow_ctrl,
6679 " different than the external"
6681 ext_phy_line_speed);
6683 }
else if (prev_line_speed != vars->
line_speed) {
6693 bnx2x_link_int_ack(params, vars, link_10g_plus);
6704 " init_preceding = %d\n", ext_phy_link_up,
6707 FLAGS_INIT_XGXS_FIRST);
6709 FLAGS_INIT_XGXS_FIRST)
6729 (phy_vars[active_external_phy].fault_detected == 0));
6738 rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6740 rc = bnx2x_update_link_down(params, vars);
6761 static void bnx2x_save_spirom_version(
struct bnx2x *bp,
u8 port,
6765 (
u16)(spirom_ver>>16), (
u16)spirom_ver, port);
6768 REG_WR(bp, ver_addr, spirom_ver);
6771 static void bnx2x_save_bcm_spirom_ver(
struct bnx2x *bp,
6775 u16 fw_ver1, fw_ver2;
6781 bnx2x_save_spirom_version(bp, port, (
u32)(fw_ver1<<16 | fw_ver2),
6785 static void bnx2x_ext_phy_10G_an_resolve(
struct bnx2x *bp,
6790 bnx2x_cl45_read(bp, phy,
6793 bnx2x_cl45_read(bp, phy,
6798 if ((val & (1<<0)) == 0)
6805 static void bnx2x_8073_resolve_fc(
struct bnx2x_phy *phy,
6809 struct bnx2x *bp = params->
bp;
6816 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6821 bnx2x_cl45_read(bp, phy,
6825 bnx2x_cl45_read(bp, phy,
6828 pause_result = (ld_pause &
6830 pause_result |= (lp_pause &
6833 bnx2x_pause_resolve(vars, pause_result);
6838 static int bnx2x_8073_8727_external_rom_boot(
struct bnx2x *bp,
6843 u16 fw_ver1, fw_msgout;
6848 bnx2x_cl45_write(bp, phy,
6854 bnx2x_cl45_write(bp, phy,
6859 bnx2x_cl45_write(bp, phy,
6864 bnx2x_cl45_write(bp, phy,
6870 bnx2x_cl45_write(bp, phy,
6883 "bnx2x_8073_8727_external_rom_boot port %x:"
6884 "Download failed. fw version = 0x%x\n",
6890 bnx2x_cl45_read(bp, phy,
6893 bnx2x_cl45_read(bp, phy,
6898 }
while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
6899 ((fw_msgout & 0xff) != 0x03 && (phy->
type ==
6903 bnx2x_cl45_write(bp, phy,
6906 bnx2x_save_bcm_spirom_ver(bp, phy, port);
6909 "bnx2x_8073_8727_external_rom_boot port %x:"
6910 "Download complete. fw version = 0x%x\n",
6919 static int bnx2x_8073_is_snr_needed(
struct bnx2x *bp,
struct bnx2x_phy *phy)
6925 bnx2x_cl45_read(bp, phy,
6934 bnx2x_cl45_read(bp, phy,
6945 static int bnx2x_8073_xaui_wa(
struct bnx2x *bp,
struct bnx2x_phy *phy)
6949 bnx2x_cl45_read(bp, phy,
6963 for (cnt = 0; cnt < 1000; cnt++) {
6964 bnx2x_cl45_read(bp, phy,
6972 if (!(val & (1<<14)) || !(val & (1<<13))) {
6975 }
else if (!(val & (1<<15))) {
6982 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
6983 bnx2x_cl45_read(bp, phy,
6986 if (val & (1<<15)) {
6988 "XAUI workaround has completed\n");
7001 static void bnx2x_807x_force_10G(
struct bnx2x *bp,
struct bnx2x_phy *phy)
7004 bnx2x_cl45_write(bp, phy,
7006 bnx2x_cl45_write(bp, phy,
7008 bnx2x_cl45_write(bp, phy,
7010 bnx2x_cl45_write(bp, phy,
7014 static void bnx2x_8073_set_pause_cl37(
struct link_params *params,
7019 struct bnx2x *bp = params->
bp;
7020 bnx2x_cl45_read(bp, phy,
7025 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->
ieee_fc);
7042 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
7044 bnx2x_cl45_write(bp, phy,
7049 static void bnx2x_8073_specific_func(
struct bnx2x_phy *phy,
7053 struct bnx2x *bp = params->
bp;
7057 bnx2x_cl45_write(bp, phy,
7059 bnx2x_cl45_write(bp, phy,
7065 static int bnx2x_8073_config_init(
struct bnx2x_phy *phy,
7069 struct bnx2x *bp = params->
bp;
7077 gpio_port = params->
port;
7085 bnx2x_8073_specific_func(phy, params,
PHY_INIT);
7086 bnx2x_8073_set_pause_cl37(params, phy, vars);
7088 bnx2x_cl45_read(bp, phy,
7091 bnx2x_cl45_read(bp, phy,
7101 bnx2x_cl45_read(bp, phy,
7104 bnx2x_cl45_write(bp, phy,
7114 port_hw_config[params->
port].default_cfg)) &
7115 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
7117 bnx2x_cl45_read(bp, phy,
7120 bnx2x_cl45_write(bp, phy,
7126 bnx2x_807x_force_10G(bp, phy);
7130 bnx2x_cl45_write(bp, phy,
7165 bnx2x_cl45_read(bp, phy,
7193 if (bnx2x_8073_is_snr_needed(bp, phy))
7194 bnx2x_cl45_write(bp, phy,
7203 bnx2x_ext_phy_set_pause(params, phy, vars);
7209 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
7213 static u8 bnx2x_8073_read_status(
struct bnx2x_phy *phy,
7217 struct bnx2x *bp = params->
bp;
7220 u16 link_status = 0;
7221 u16 an1000_status = 0;
7223 bnx2x_cl45_read(bp, phy,
7229 bnx2x_cl45_read(bp, phy,
7231 bnx2x_cl45_read(bp, phy,
7235 bnx2x_cl45_read(bp, phy,
7239 bnx2x_cl45_read(bp, phy,
7245 bnx2x_cl45_read(bp, phy,
7249 bnx2x_cl45_read(bp, phy,
7251 bnx2x_cl45_read(bp, phy,
7253 link_up = ((val1 & 4) == 4);
7258 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7261 bnx2x_cl45_read(bp, phy,
7263 bnx2x_cl45_read(bp, phy,
7267 bnx2x_cl45_read(bp, phy,
7269 bnx2x_cl45_read(bp, phy,
7272 "an_link_status=0x%x\n", val2, val1, an1000_status);
7274 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7275 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
7280 bnx2x_cl45_write(bp, phy,
7285 bnx2x_cl45_write(bp, phy,
7289 bnx2x_cl45_read(bp, phy,
7294 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7299 }
else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7304 }
else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7320 bnx2x_cl45_read(bp, phy,
7333 bnx2x_cl45_write(bp, phy,
7338 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7339 bnx2x_8073_resolve_fc(phy, params, vars);
7358 static void bnx2x_8073_link_reset(
struct bnx2x_phy *phy,
7361 struct bnx2x *bp = params->
bp;
7366 gpio_port = params->
port;
7377 static int bnx2x_8705_config_init(
struct bnx2x_phy *phy,
7381 struct bnx2x *bp = params->
bp;
7389 bnx2x_wait_reset_complete(bp, phy, params);
7391 bnx2x_cl45_write(bp, phy,
7393 bnx2x_cl45_write(bp, phy,
7395 bnx2x_cl45_write(bp, phy,
7397 bnx2x_cl45_write(bp, phy,
7400 bnx2x_save_spirom_version(bp, params->
port, params->
shmem_base, 0);
7404 static u8 bnx2x_8705_read_status(
struct bnx2x_phy *phy,
7410 struct bnx2x *bp = params->
bp;
7412 bnx2x_cl45_read(bp, phy,
7416 bnx2x_cl45_read(bp, phy,
7420 bnx2x_cl45_read(bp, phy,
7423 bnx2x_cl45_read(bp, phy,
7425 bnx2x_cl45_read(bp, phy,
7429 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7432 bnx2x_ext_phy_resolve_fc(phy, params, vars);
7440 static void bnx2x_set_disable_pmd_transmit(
struct link_params *params,
7444 struct bnx2x *bp = params->
bp;
7458 bnx2x_cl45_write(bp, phy,
7466 u32 swap_val, swap_override;
7467 struct bnx2x *bp = params->
bp;
7471 gpio_port = params->
port;
7474 return gpio_port ^ (swap_val && swap_override);
7477 static void bnx2x_sfp_e1e2_set_transmitter(
struct link_params *params,
7483 struct bnx2x *bp = params->
bp;
7489 dev_info.port_hw_config[port].sfp_ctrl)) &
7492 "mode = %x\n", tx_en, port, tx_en_mode);
7493 switch (tx_en_mode) {
7496 bnx2x_cl45_read(bp, phy,
7506 bnx2x_cl45_write(bp, phy,
7517 u8 gpio_port, gpio_mode;
7524 gpio_port = bnx2x_get_gpio_port(params);
7534 static void bnx2x_sfp_set_transmitter(
struct link_params *params,
7538 struct bnx2x *bp = params->
bp;
7541 bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7543 bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7546 static int bnx2x_8726_read_sfp_module_eeprom(
struct bnx2x_phy *phy,
7550 struct bnx2x *bp = params->
bp;
7555 "Reading from eeprom is limited to 0xf\n");
7559 bnx2x_cl45_write(bp, phy,
7561 (byte_cnt | 0xa000));
7564 bnx2x_cl45_write(bp, phy,
7569 bnx2x_cl45_write(bp, phy,
7574 for (i = 0; i < 100; i++) {
7575 bnx2x_cl45_read(bp, phy,
7587 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7588 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7593 for (i = 0; i < byte_cnt; i++) {
7594 bnx2x_cl45_read(bp, phy,
7600 for (i = 0; i < 100; i++) {
7601 bnx2x_cl45_read(bp, phy,
7604 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7612 static void bnx2x_warpcore_power_module(
struct link_params *params,
7617 struct bnx2x *bp = params->
bp;
7632 bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
7634 static int bnx2x_warpcore_read_sfp_module_eeprom(
struct bnx2x_phy *phy,
7636 u16 addr,
u8 byte_cnt,
7637 u8 *o_buf,
u8 is_init)
7640 u8 i,
j = 0, cnt = 0;
7643 struct bnx2x *bp = params->
bp;
7647 "Reading from eeprom is limited to 16 bytes\n");
7652 addr32 = addr & (~0x3);
7655 bnx2x_warpcore_power_module(params, phy, 0);
7658 bnx2x_warpcore_power_module(params, phy, 1);
7660 rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7665 for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7666 o_buf[
j] = *((
u8 *)data_array + i);
7674 static int bnx2x_8727_read_sfp_module_eeprom(
struct bnx2x_phy *phy,
7676 u16 addr,
u8 byte_cnt,
u8 *o_buf)
7678 struct bnx2x *bp = params->
bp;
7683 "Reading from eeprom is limited to 0xf\n");
7688 bnx2x_cl45_read(bp, phy,
7694 bnx2x_cl45_write(bp, phy,
7697 ((byte_cnt < 2) ? 2 : byte_cnt));
7700 bnx2x_cl45_write(bp, phy,
7705 bnx2x_cl45_write(bp, phy,
7711 bnx2x_cl45_write(bp, phy,
7721 for (i = 0; i < 100; i++) {
7722 bnx2x_cl45_read(bp, phy,
7725 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7731 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7734 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7735 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7740 for (i = 0; i < byte_cnt; i++) {
7741 bnx2x_cl45_read(bp, phy,
7747 for (i = 0; i < 100; i++) {
7748 bnx2x_cl45_read(bp, phy,
7751 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7762 u8 byte_cnt,
u8 *o_buf)
7765 switch (phy->
type) {
7767 rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7772 rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7776 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7777 byte_cnt, o_buf, 0);
7783 static int bnx2x_get_edc_mode(
struct bnx2x_phy *phy,
7787 struct bnx2x *bp = params->
bp;
7789 u8 val[2], check_limiting_mode = 0;
7806 u8 copper_module_type;
7815 &copper_module_type) != 0) {
7817 "Failed to read copper-cable-type"
7818 " from SFP+ EEPROM\n");
7822 if (copper_module_type &
7825 check_limiting_mode = 1;
7826 }
else if (copper_module_type &
7829 "Passive Copper cable detected\n");
7834 "Unknown copper-cable-type 0x%x !!!\n",
7835 copper_module_type);
7841 check_limiting_mode = 1;
7849 int idx, cfg_idx = 0;
7852 if (params->
phy[idx].type == phy->
type) {
7869 media_types =
REG_RD(bp, sync_offset);
7872 if (&(params->
phy[phy_idx]) == phy) {
7881 REG_WR(bp, sync_offset, media_types);
7882 if (check_limiting_mode) {
7890 "Failed to read Option field from module EEPROM\n");
7904 static int bnx2x_verify_sfp_module(
struct bnx2x_phy *phy,
7907 struct bnx2x *bp = params->
bp;
7909 u32 fw_resp, fw_cmd_param;
7915 port_feature_config[params->
port].config));
7931 "FW does not support OPT MDL verification\n");
7938 "FW does not support OPT MDL verification\n");
7955 vendor_name[0] =
'\0';
7963 vendor_pn[0] =
'\0';
7967 netdev_err(bp->
dev,
"Warning: Unqualified SFP+ module detected,"
7968 " Port %d from %s part number %s\n",
7969 params->
port, vendor_name, vendor_pn);
7970 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
7976 static int bnx2x_wait_for_sfp_module_initialized(
struct bnx2x_phy *phy,
7982 struct bnx2x *bp = params->
bp;
7988 for (timeout = 0; timeout < 60; timeout++) {
7990 rc = bnx2x_warpcore_read_sfp_module_eeprom(phy,
7998 "SFP+ module initialization took %d ms\n",
8008 static void bnx2x_8727_power_module(
struct bnx2x *bp,
8034 bnx2x_cl45_write(bp, phy,
8040 static int bnx2x_8726_set_limiting_mode(
struct bnx2x *bp,
8044 u16 cur_limiting_mode;
8046 bnx2x_cl45_read(bp, phy,
8049 &cur_limiting_mode);
8055 bnx2x_cl45_write(bp, phy,
8069 bnx2x_cl45_write(bp, phy,
8073 bnx2x_cl45_write(bp, phy,
8077 bnx2x_cl45_write(bp, phy,
8081 bnx2x_cl45_write(bp, phy,
8089 static int bnx2x_8727_set_limiting_mode(
struct bnx2x *bp,
8095 bnx2x_cl45_read(bp, phy,
8100 bnx2x_cl45_write(bp, phy,
8103 (phy_identifier & ~(1<<9)));
8105 bnx2x_cl45_read(bp, phy,
8110 bnx2x_cl45_write(bp, phy,
8113 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
8115 bnx2x_cl45_write(bp, phy,
8118 (phy_identifier | (1<<9)));
8123 static void bnx2x_8727_specific_func(
struct bnx2x_phy *phy,
8127 struct bnx2x *bp = params->
bp;
8131 bnx2x_sfp_set_transmitter(params, phy, 0);
8135 bnx2x_sfp_set_transmitter(params, phy, 1);
8138 bnx2x_cl45_write(bp, phy,
8141 bnx2x_cl45_write(bp, phy,
8144 bnx2x_cl45_write(bp, phy,
8158 bnx2x_cl45_write(bp, phy,
8166 bnx2x_cl45_write(bp, phy,
8178 static void bnx2x_set_e1e2_module_fault_led(
struct link_params *params,
8181 struct bnx2x *bp = params->
bp;
8187 switch (fault_led_gpio) {
8195 u8 gpio_port = bnx2x_get_gpio_port(params);
8196 u16 gpio_pin = fault_led_gpio -
8199 "pin %x port %x mode %x\n",
8200 gpio_pin, gpio_port, gpio_mode);
8210 static void bnx2x_set_e3_module_fault_led(
struct link_params *params,
8215 struct bnx2x *bp = params->
bp;
8218 dev_info.port_hw_config[port].e3_sfp_ctrl)) &
8222 gpio_mode, pin_cfg);
8223 bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
8226 static void bnx2x_set_sfp_module_fault_led(
struct link_params *params,
8229 struct bnx2x *bp = params->
bp;
8235 bnx2x_set_e3_module_fault_led(params, gpio_mode);
8237 bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
8240 static void bnx2x_warpcore_hw_reset(
struct bnx2x_phy *phy,
8243 struct bnx2x *bp = params->
bp;
8244 bnx2x_warpcore_power_module(params, phy, 0);
8254 static void bnx2x_power_sfp_module(
struct link_params *params,
8258 struct bnx2x *bp = params->
bp;
8261 switch (phy->
type) {
8264 bnx2x_8727_power_module(params->
bp, phy, power);
8267 bnx2x_warpcore_power_module(params, phy, power);
8273 static void bnx2x_warpcore_set_limiting_mode(
struct link_params *params,
8279 struct bnx2x *bp = params->
bp;
8281 u8 lane = bnx2x_get_warpcore_lane(phy, params);
8285 val &= ~(0xf << (lane << 2));
8299 val |= (mode << (lane << 2));
8307 bnx2x_warpcore_reset_lane(bp, phy, 1);
8308 bnx2x_warpcore_reset_lane(bp, phy, 0);
8312 static void bnx2x_set_limiting_mode(
struct link_params *params,
8316 switch (phy->
type) {
8318 bnx2x_8726_set_limiting_mode(params->
bp, phy, edc_mode);
8322 bnx2x_8727_set_limiting_mode(params->
bp, phy, edc_mode);
8325 bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
8333 struct bnx2x *bp = params->
bp;
8339 port_feature_config[params->
port].config));
8344 bnx2x_power_sfp_module(params, phy, 1);
8345 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8348 }
else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8353 bnx2x_set_sfp_module_fault_led(params,
8357 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8360 bnx2x_power_sfp_module(params, phy, 0);
8371 bnx2x_set_limiting_mode(params, phy, edc_mode);
8377 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8379 bnx2x_sfp_set_transmitter(params, phy, 1);
8381 bnx2x_sfp_set_transmitter(params, phy, 0);
8388 struct bnx2x *bp = params->
bp;
8391 u8 gpio_num, gpio_port;
8398 params->
port, &gpio_num, &gpio_port) ==
8411 if (gpio_val == 0) {
8412 bnx2x_set_mdio_clk(bp, params->
chip_id, params->
port);
8413 bnx2x_set_aer_mmd(params, phy);
8415 bnx2x_power_sfp_module(params, phy, 1);
8419 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) {
8427 bnx2x_cl45_read(bp, phy,
8431 if (!rx_tx_in_reset) {
8432 bnx2x_warpcore_reset_lane(bp, phy, 1);
8433 bnx2x_warpcore_config_sfi(phy, params);
8434 bnx2x_warpcore_reset_lane(bp, phy, 0);
8443 port_feature_config[params->
port].
8452 if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8455 bnx2x_sfp_set_transmitter(params, phy, 0);
8462 static void bnx2x_sfp_mask_fault(
struct bnx2x *bp,
8464 u16 alarm_status_offset,
8465 u16 alarm_ctrl_offset)
8468 bnx2x_cl45_read(bp, phy,
8471 bnx2x_cl45_read(bp, phy,
8475 bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8476 if (alarm_status & (1<<0))
8480 bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8485 static u8 bnx2x_8706_8726_read_status(
struct bnx2x_phy *phy,
8490 u16 val1, val2, rx_sd, pcs_status;
8491 struct bnx2x *bp = params->
bp;
8494 bnx2x_cl45_read(bp, phy,
8501 bnx2x_cl45_read(bp, phy,
8503 bnx2x_cl45_read(bp, phy,
8507 bnx2x_cl45_read(bp, phy,
8509 bnx2x_cl45_read(bp, phy,
8511 bnx2x_cl45_read(bp, phy,
8513 bnx2x_cl45_read(bp, phy,
8517 " link_status 0x%x\n", rx_sd, pcs_status, val2);
8521 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8527 bnx2x_ext_phy_resolve_fc(phy, params, vars);
8547 static u8 bnx2x_8706_config_init(
struct bnx2x_phy *phy,
8553 struct bnx2x *bp = params->
bp;
8560 bnx2x_wait_reset_complete(bp, phy, params);
8563 for (cnt = 0; cnt < 100; cnt++) {
8564 bnx2x_cl45_read(bp, phy,
8575 for (i = 0; i < 4; i++) {
8585 " reg 0x%x <-- val 0x%x\n", reg, val);
8593 bnx2x_cl45_write(bp, phy,
8596 bnx2x_cl45_write(bp, phy,
8600 bnx2x_cl45_write(bp, phy,
8607 bnx2x_cl45_write(bp, phy,
8611 bnx2x_cl45_write(bp, phy,
8614 bnx2x_cl45_write(bp, phy,
8617 bnx2x_cl45_write(bp, phy,
8621 bnx2x_cl45_write(bp, phy,
8623 bnx2x_cl45_write(bp, phy,
8626 bnx2x_cl45_write(bp, phy,
8630 bnx2x_save_bcm_spirom_ver(bp, phy, params->
port);
8643 bnx2x_cl45_read(bp, phy,
8646 bnx2x_cl45_write(bp, phy,
8653 static int bnx2x_8706_read_status(
struct bnx2x_phy *phy,
8657 return bnx2x_8706_8726_read_status(phy, params, vars);
8663 static void bnx2x_8726_config_loopback(
struct bnx2x_phy *phy,
8666 struct bnx2x *bp = params->
bp;
8671 static void bnx2x_8726_external_rom_boot(
struct bnx2x_phy *phy,
8674 struct bnx2x *bp = params->
bp;
8679 bnx2x_cl45_write(bp, phy,
8683 bnx2x_cl45_write(bp, phy,
8688 bnx2x_cl45_write(bp, phy,
8692 bnx2x_cl45_write(bp, phy,
8701 bnx2x_cl45_write(bp, phy,
8706 bnx2x_save_bcm_spirom_ver(bp, phy, params->
port);
8709 static u8 bnx2x_8726_read_status(
struct bnx2x_phy *phy,
8713 struct bnx2x *bp = params->
bp;
8715 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8717 bnx2x_cl45_read(bp, phy,
8720 if (val1 & (1<<15)) {
8730 static int bnx2x_8726_config_init(
struct bnx2x_phy *phy,
8734 struct bnx2x *bp = params->
bp;
8738 bnx2x_wait_reset_complete(bp, phy, params);
8740 bnx2x_8726_external_rom_boot(phy, params);
8751 bnx2x_cl45_write(bp, phy,
8753 bnx2x_cl45_write(bp, phy,
8755 bnx2x_cl45_write(bp, phy,
8757 bnx2x_cl45_write(bp, phy,
8768 bnx2x_ext_phy_set_pause(params, phy, vars);
8769 bnx2x_cl45_write(bp, phy,
8771 bnx2x_cl45_write(bp, phy,
8773 bnx2x_cl45_write(bp, phy,
8775 bnx2x_cl45_write(bp, phy,
8777 bnx2x_cl45_write(bp, phy,
8782 bnx2x_cl45_write(bp, phy,
8784 bnx2x_cl45_write(bp, phy,
8789 bnx2x_cl45_write(bp, phy,
8797 "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8800 bnx2x_cl45_write(bp, phy,
8805 bnx2x_cl45_write(bp, phy,
8815 static void bnx2x_8726_link_reset(
struct bnx2x_phy *phy,
8818 struct bnx2x *bp = params->
bp;
8821 bnx2x_cl45_write(bp, phy,
8830 static void bnx2x_8727_set_link_led(
struct bnx2x_phy *phy,
8833 struct bnx2x *bp = params->
bp;
8834 u16 led_mode_bitmask = 0;
8835 u16 gpio_pins_bitmask = 0;
8843 led_mode_bitmask = 0;
8844 gpio_pins_bitmask = 0x03;
8847 led_mode_bitmask = 0;
8848 gpio_pins_bitmask = 0x02;
8851 led_mode_bitmask = 0x60;
8852 gpio_pins_bitmask = 0x11;
8855 bnx2x_cl45_read(bp, phy,
8860 val |= led_mode_bitmask;
8861 bnx2x_cl45_write(bp, phy,
8865 bnx2x_cl45_read(bp, phy,
8870 val |= gpio_pins_bitmask;
8871 bnx2x_cl45_write(bp, phy,
8876 static void bnx2x_8727_hw_reset(
struct bnx2x_phy *phy,
8878 u32 swap_val, swap_override;
8883 struct bnx2x *bp = params->
bp;
8886 port = (swap_val && swap_override) ^ 1;
8891 static void bnx2x_8727_config_speed(
struct bnx2x_phy *phy,
8894 struct bnx2x *bp = params->
bp;
8900 bnx2x_cl45_write(bp, phy,
8902 bnx2x_cl45_write(bp, phy,
8904 bnx2x_cl45_read(bp, phy,
8911 bnx2x_cl45_read(bp, phy,
8915 bnx2x_cl45_write(bp, phy,
8927 bnx2x_cl45_write(bp, phy,
8929 bnx2x_cl45_write(bp, phy,
8935 bnx2x_cl45_write(bp, phy,
8938 bnx2x_cl45_write(bp, phy,
8940 bnx2x_cl45_write(bp, phy,
8942 bnx2x_cl45_write(bp, phy,
8948 static int bnx2x_8727_config_init(
struct bnx2x_phy *phy,
8954 struct bnx2x *bp = params->
bp;
8957 bnx2x_wait_reset_complete(bp, phy, params);
8961 bnx2x_8727_specific_func(phy, params,
PHY_INIT);
8965 bnx2x_cl45_read(bp, phy,
8974 bnx2x_cl45_write(bp, phy,
8978 bnx2x_set_disable_pmd_transmit(params, phy, 0);
8980 bnx2x_8727_power_module(bp, phy, 1);
8982 bnx2x_cl45_read(bp, phy,
8985 bnx2x_cl45_read(bp, phy,
8988 bnx2x_8727_config_speed(phy, params);
8997 bnx2x_cl45_write(bp, phy,
9001 bnx2x_cl45_write(bp, phy,
9017 bnx2x_cl45_read(bp, phy,
9021 bnx2x_cl45_write(bp, phy,
9023 bnx2x_cl45_read(bp, phy,
9026 bnx2x_cl45_write(bp, phy,
9034 static void bnx2x_8727_handle_mod_abs(
struct bnx2x_phy *phy,
9037 struct bnx2x *bp = params->
bp;
9038 u16 mod_abs, rx_alarm_status;
9041 port_feature_config[params->
port].
9043 bnx2x_cl45_read(bp, phy,
9046 if (mod_abs & (1<<8)) {
9050 "MOD_ABS indication show module is absent\n");
9062 bnx2x_cl45_write(bp, phy,
9069 bnx2x_cl45_read(bp, phy,
9076 "MOD_ABS indication show module is present\n");
9087 bnx2x_cl45_write(bp, phy,
9096 bnx2x_cl45_read(bp, phy,
9101 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9103 bnx2x_sfp_set_transmitter(params, phy, 0);
9105 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
9111 bnx2x_8727_config_speed(phy, params);
9119 static u8 bnx2x_8727_read_status(
struct bnx2x_phy *phy,
9124 struct bnx2x *bp = params->
bp;
9125 u8 link_up = 0, oc_port = params->
port;
9126 u16 link_status = 0;
9127 u16 rx_alarm_status, lasi_ctrl, val1;
9130 bnx2x_cl45_read(bp, phy,
9137 bnx2x_cl45_read(bp, phy,
9146 bnx2x_cl45_read(bp, phy,
9152 bnx2x_cl45_read(bp, phy,
9160 bnx2x_cl45_read(bp, phy,
9164 if ((val1 & (1<<8)) == 0) {
9168 "8727 Power fault has been detected on port %d\n",
9170 netdev_err(bp->
dev,
"Error: Power fault on Port %d has "
9171 "been detected and the power to "
9172 "that SFP+ module has been removed "
9173 "to prevent failure of the card. "
9174 "Please remove the SFP+ module and "
9175 "restart the system to clear this "
9179 bnx2x_cl45_write(bp, phy,
9183 bnx2x_cl45_read(bp, phy,
9188 bnx2x_cl45_write(bp, phy,
9192 bnx2x_cl45_read(bp, phy,
9200 if (rx_alarm_status & (1<<5)) {
9201 bnx2x_8727_handle_mod_abs(phy, params);
9203 bnx2x_cl45_write(bp, phy,
9210 bnx2x_sfp_set_transmitter(params, phy, 1);
9216 bnx2x_cl45_read(bp, phy,
9223 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
9228 }
else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
9247 if (val1 & (1<<0)) {
9253 bnx2x_ext_phy_resolve_fc(phy, params, vars);
9260 bnx2x_cl45_read(bp, phy,
9270 bnx2x_cl45_write(bp, phy,
9277 static void bnx2x_8727_link_reset(
struct bnx2x_phy *phy,
9280 struct bnx2x *bp = params->
bp;
9283 bnx2x_set_disable_pmd_transmit(params, phy, 1);
9286 bnx2x_sfp_set_transmitter(params, phy, 0);
9295 static void bnx2x_save_848xx_spirom_version(
struct bnx2x_phy *phy,
9303 bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
9314 for (cnt = 0; cnt < 100; cnt++) {
9322 "phy fw version(1)\n");
9323 bnx2x_save_spirom_version(bp, port, 0,
9333 for (cnt = 0; cnt < 100; cnt++) {
9342 bnx2x_save_spirom_version(bp, port, 0,
9352 bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9357 static void bnx2x_848xx_set_led(
struct bnx2x *bp,
9363 bnx2x_cl45_read(bp, phy,
9369 bnx2x_cl45_write(bp, phy,
9373 bnx2x_cl45_write(bp, phy,
9378 bnx2x_cl45_write(bp, phy,
9384 bnx2x_cl45_write(bp, phy,
9390 bnx2x_cl45_write(bp, phy,
9396 bnx2x_cl45_write(bp, phy,
9406 bnx2x_cl45_read(bp, phy,
9409 bnx2x_cl45_write(bp, phy,
9413 bnx2x_cl45_write(bp, phy,
9418 static void bnx2x_848xx_specific_func(
struct bnx2x_phy *phy,
9422 struct bnx2x *bp = params->
bp;
9427 bnx2x_save_848xx_spirom_version(phy, bp, params->
port);
9436 bnx2x_848xx_set_led(bp, phy);
9441 static int bnx2x_848xx_cmn_config_init(
struct bnx2x_phy *phy,
9445 struct bnx2x *bp = params->
bp;
9446 u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
9448 bnx2x_848xx_specific_func(phy, params,
PHY_INIT);
9449 bnx2x_cl45_write(bp, phy,
9453 bnx2x_cl45_read(bp, phy,
9457 bnx2x_ext_phy_set_pause(params, phy, vars);
9458 bnx2x_cl45_read(bp, phy,
9462 bnx2x_cl45_read(bp, phy,
9466 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9467 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9473 an_1000_val |= (1<<8);
9474 autoneg_val |= (1<<9 | 1<<12);
9476 an_1000_val |= (1<<9);
9479 an_1000_val &= ~((1<<8) | (1<<9));
9481 bnx2x_cl45_write(bp, phy,
9490 an_10_100_val |= (1<<7);
9492 autoneg_val |= (1<<9 | 1<<12);
9495 an_10_100_val |= (1<<8);
9506 an_10_100_val |= (1<<5);
9507 autoneg_val |= (1<<9 | 1<<12);
9509 an_10_100_val |= (1<<6);
9518 autoneg_val |= (1<<13);
9520 bnx2x_cl45_write(bp, phy,
9522 (1<<15 | 1<<9 | 7<<0));
9524 an_10_100_val |= (1<<8) | (1<<7);
9532 bnx2x_cl45_write(bp, phy,
9534 (1<<15 | 1<<9 | 7<<0));
9538 bnx2x_cl45_write(bp, phy,
9543 autoneg_val |= (1<<8);
9549 ((autoneg_val & (1<<12)) == 0))
9550 bnx2x_cl45_write(bp, phy,
9561 bnx2x_cl45_read(bp, phy,
9565 bnx2x_cl45_write(bp, phy,
9568 an_10g_val | 0x1000);
9569 bnx2x_cl45_write(bp, phy,
9573 bnx2x_cl45_write(bp, phy,
9581 static int bnx2x_8481_config_init(
struct bnx2x_phy *phy,
9585 struct bnx2x *bp = params->
bp;
9592 bnx2x_wait_reset_complete(bp, phy, params);
9595 return bnx2x_848xx_cmn_config_init(phy, params, vars);
9598 #define PHY84833_CMDHDLR_WAIT 300
9599 #define PHY84833_CMDHDLR_MAX_ARGS 5
9600 static int bnx2x_84833_cmd_hdlr(
struct bnx2x_phy *phy,
9607 struct bnx2x *bp = params->
bp;
9619 if (idx >= PHY84833_CMDHDLR_WAIT) {
9625 for (idx = 0; idx <
argc; idx++) {
9640 if ((idx >= PHY84833_CMDHDLR_WAIT) ||
9646 for (idx = 0; idx <
argc; idx++) {
9658 static int bnx2x_84833_pair_swap_cfg(
struct bnx2x_phy *phy,
9665 struct bnx2x *bp = params->
bp;
9677 data[1] = (
u16)pair_swap;
9679 status = bnx2x_84833_cmd_hdlr(phy, params,
9687 static u8 bnx2x_84833_get_reset_gpios(
struct bnx2x *bp,
9688 u32 shmem_base_path[],
9696 for (idx = 0; idx < 2; idx++) {
9698 reset_pin[
idx] =
REG_RD(bp, shmem_base_path[idx] +
9700 dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9701 reset_pin[
idx] = (reset_pin[
idx] &
9705 reset_pin[
idx] = (1 << reset_pin[
idx]);
9707 reset_gpios = (
u8)(reset_pin[0] | reset_pin[1]);
9710 for (idx = 0; idx < 2; idx++) {
9711 reset_pin[
idx] =
REG_RD(bp, shmem_base_path[idx] +
9713 dev_info.port_hw_config[0].default_cfg));
9717 reset_pin[
idx] = (1 << reset_pin[
idx]);
9719 reset_gpios = (
u8)(reset_pin[0] | reset_pin[1]);
9725 static int bnx2x_84833_hw_reset_phy(
struct bnx2x_phy *phy,
9728 struct bnx2x *bp = params->
bp;
9732 other_shmem_base_addr));
9734 u32 shmem_base_path[2];
9745 shmem_base_path[1] = other_shmem_base_addr;
9747 reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9758 static int bnx2x_8483x_disable_eee(
struct bnx2x_phy *phy,
9763 struct bnx2x *bp = params->
bp;
9769 rc = bnx2x_84833_cmd_hdlr(phy, params,
9776 return bnx2x_eee_disable(phy, params, vars);
9779 static int bnx2x_8483x_enable_eee(
struct bnx2x_phy *phy,
9784 struct bnx2x *bp = params->
bp;
9787 rc = bnx2x_84833_cmd_hdlr(phy, params,
9794 return bnx2x_eee_advertise(phy, params, vars, SHMEM_EEE_10G_ADV);
9797 #define PHY84833_CONSTANT_LATENCY 1193
9798 static int bnx2x_848x3_config_init(
struct bnx2x_phy *phy,
9802 struct bnx2x *bp = params->
bp;
9805 u32 actual_phy_selection, cms_enable;
9814 port = params->
port;
9822 bnx2x_cl45_write(bp, phy,
9827 bnx2x_wait_reset_complete(bp, phy, params);
9838 bnx2x_set_autoneg(¶ms->
phy[
INT_PHY], params, vars, 0);
9839 bnx2x_program_serdes(¶ms->
phy[
INT_PHY], params, vars);
9861 switch (actual_phy_selection) {
9888 bnx2x_84833_pair_swap_cfg(phy, params, vars);
9895 rc = bnx2x_84833_cmd_hdlr(phy, params,
9902 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9904 bnx2x_save_848xx_spirom_version(phy, bp, params->
port);
9928 bnx2x_eee_has_cap(params)) {
9929 rc = bnx2x_eee_initial_config(params, vars, SHMEM_EEE_10G_ADV);
9932 bnx2x_8483x_disable_eee(phy, params, vars);
9938 (bnx2x_eee_calc_timer(params) ||
9940 rc = bnx2x_8483x_enable_eee(phy, params, vars);
9942 rc = bnx2x_8483x_disable_eee(phy, params, vars);
9953 bnx2x_cl45_read(bp, phy,
9957 bnx2x_cl45_write(bp, phy,
9964 static u8 bnx2x_848xx_read_status(
struct bnx2x_phy *phy,
9968 struct bnx2x *bp = params->
bp;
9975 bnx2x_cl45_read(bp, phy,
9977 bnx2x_cl45_read(bp, phy,
9983 if (val2 & (1<<11)) {
9987 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9989 u16 legacy_status, legacy_speed;
9992 bnx2x_cl45_write(bp, phy,
9997 bnx2x_cl45_read(bp, phy,
10004 link_up = ((legacy_status & (1<<11)) == (1<<11));
10005 legacy_speed = (legacy_status & (3<<9));
10006 if (legacy_speed == (0<<9))
10008 else if (legacy_speed == (1<<9))
10010 else if (legacy_speed == (2<<9))
10018 if (legacy_status & (1<<8))
10024 "Link is up in %dMbps, is_duplex_full= %d\n",
10028 bnx2x_cl45_read(bp, phy,
10035 bnx2x_cl45_read(bp, phy,
10039 if ((val & (1<<0)) == 0)
10047 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10087 bnx2x_eee_an_resolve(phy, params, vars);
10094 static int bnx2x_848xx_format_ver(
u32 raw_ver,
u8 *str,
u16 *len)
10098 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
10099 status = bnx2x_format_ver(spirom_ver, str, len);
10103 static void bnx2x_8481_hw_reset(
struct bnx2x_phy *phy,
10112 static void bnx2x_8481_link_reset(
struct bnx2x_phy *phy,
10115 bnx2x_cl45_write(params->
bp, phy,
10117 bnx2x_cl45_write(params->
bp, phy,
10121 static void bnx2x_848x3_link_reset(
struct bnx2x_phy *phy,
10124 struct bnx2x *bp = params->
bp;
10131 port = params->
port;
10138 bnx2x_cl45_read(bp, phy,
10142 bnx2x_cl45_write(bp, phy,
10148 static void bnx2x_848xx_set_link_led(
struct bnx2x_phy *phy,
10151 struct bnx2x *bp = params->
bp;
10158 port = params->
port;
10169 bnx2x_cl45_write(bp, phy,
10174 bnx2x_cl45_write(bp, phy,
10179 bnx2x_cl45_write(bp, phy,
10184 bnx2x_cl45_write(bp, phy,
10190 bnx2x_cl45_write(bp, phy,
10205 bnx2x_cl45_write(bp, phy,
10210 bnx2x_cl45_write(bp, phy,
10215 bnx2x_cl45_write(bp, phy,
10220 bnx2x_cl45_write(bp, phy,
10226 bnx2x_cl45_write(bp, phy,
10239 bnx2x_cl45_read(bp, phy,
10246 bnx2x_cl45_write(bp, phy,
10252 bnx2x_cl45_write(bp, phy,
10257 bnx2x_cl45_write(bp, phy,
10262 bnx2x_cl45_write(bp, phy,
10267 bnx2x_cl45_write(bp, phy,
10272 bnx2x_cl45_write(bp, phy,
10287 bnx2x_cl45_read(bp, phy,
10296 bnx2x_cl45_write(bp, phy,
10303 bnx2x_cl45_write(bp, phy,
10308 bnx2x_cl45_write(bp, phy,
10313 bnx2x_cl45_write(bp, phy,
10318 bnx2x_cl45_write(bp, phy,
10324 bnx2x_cl45_write(bp, phy,
10330 bnx2x_cl45_read(bp, phy,
10336 bnx2x_cl45_write(bp, phy,
10356 static void bnx2x_54618se_specific_func(
struct bnx2x_phy *phy,
10360 struct bnx2x *bp = params->
bp;
10366 bnx2x_cl22_write(bp, phy,
10369 bnx2x_cl22_read(bp, phy,
10372 temp &= ~(0xf << 4);
10373 temp |= (0x6 << 4);
10374 bnx2x_cl22_write(bp, phy,
10378 bnx2x_cl22_write(bp, phy,
10385 static int bnx2x_54618se_config_init(
struct bnx2x_phy *phy,
10389 struct bnx2x *bp = params->
bp;
10391 u16 autoneg_val, an_1000_val, an_10_100_val, fc_val,
temp;
10400 port = params->
port;
10404 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10409 bnx2x_set_cfg_pin(bp, cfg_pin, 1);
10415 bnx2x_cl22_write(bp, phy,
10417 bnx2x_wait_reset_complete(bp, phy, params);
10423 bnx2x_54618se_specific_func(phy, params,
PHY_INIT);
10425 bnx2x_cl22_write(bp, phy,
10428 bnx2x_cl22_read(bp, phy,
10432 bnx2x_cl22_write(bp, phy,
10438 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->
ieee_fc);
10449 bnx2x_cl22_read(bp, phy,
10453 bnx2x_cl22_read(bp, phy,
10457 bnx2x_cl22_read(bp, phy,
10462 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10463 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10470 an_1000_val |= (1<<8);
10471 autoneg_val |= (1<<9 | 1<<12);
10473 an_1000_val |= (1<<9);
10476 an_1000_val &= ~((1<<8) | (1<<9));
10478 bnx2x_cl22_write(bp, phy,
10481 bnx2x_cl22_read(bp, phy,
10490 an_10_100_val |= (1<<7);
10492 autoneg_val |= (1<<9 | 1<<12);
10495 an_10_100_val |= (1<<8);
10504 an_10_100_val |= (1<<5);
10505 autoneg_val |= (1<<9 | 1<<12);
10507 an_10_100_val |= (1<<6);
10513 autoneg_val |= (1<<13);
10515 bnx2x_cl22_write(bp, phy,
10517 (1<<15 | 1<<9 | 7<<0));
10522 bnx2x_cl22_write(bp, phy,
10524 (1<<15 | 1<<9 | 7<<0));
10541 bnx2x_eee_disable(phy, params, vars);
10544 (bnx2x_eee_calc_timer(params) ||
10551 bnx2x_eee_advertise(phy, params, vars,
10555 bnx2x_eee_disable(phy, params, vars);
10576 bnx2x_cl22_write(bp, phy,
10578 an_10_100_val | fc_val);
10581 autoneg_val |= (1<<8);
10583 bnx2x_cl22_write(bp, phy,
10590 static void bnx2x_5461x_set_link_led(
struct bnx2x_phy *phy,
10593 struct bnx2x *bp = params->
bp;
10596 bnx2x_cl22_write(bp, phy,
10599 bnx2x_cl22_read(bp, phy,
10619 bnx2x_cl22_write(bp, phy,
10626 static void bnx2x_54618se_link_reset(
struct bnx2x_phy *phy,
10629 struct bnx2x *bp = params->
bp;
10640 port = params->
port;
10643 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10648 bnx2x_set_cfg_pin(bp, cfg_pin, 0);
10651 static u8 bnx2x_54618se_read_status(
struct bnx2x_phy *phy,
10655 struct bnx2x *bp = params->
bp;
10658 u16 legacy_status, legacy_speed;
10661 bnx2x_cl22_read(bp, phy,
10667 bnx2x_cl22_read(bp, phy,
10671 link_up = ((legacy_status & (1<<2)) == (1<<2));
10674 legacy_speed = (legacy_status & (7<<8));
10675 if (legacy_speed == (7<<8)) {
10678 }
else if (legacy_speed == (6<<8)) {
10681 }
else if (legacy_speed == (5<<8)) {
10686 else if (legacy_speed == (3<<8)) {
10689 }
else if (legacy_speed == (2<<8)) {
10692 }
else if (legacy_speed == (1<<8)) {
10699 "Link is up in %dMbps, is_duplex_full= %d\n",
10704 bnx2x_cl22_read(bp, phy,
10710 bnx2x_cl22_read(bp, phy,
10713 if ((val & (1<<0)) == 0)
10720 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10724 bnx2x_cl22_read(bp, phy, 0x5, &val);
10742 bnx2x_cl22_read(bp, phy, 0xa, &val);
10751 bnx2x_eee_has_cap(params))
10752 bnx2x_eee_an_resolve(phy, params, vars);
10758 static void bnx2x_54618se_config_loopback(
struct bnx2x_phy *phy,
10761 struct bnx2x *bp = params->
bp;
10769 bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10776 bnx2x_cl22_read(bp, phy, 0x00, &val);
10777 val &= ~((1<<6) | (1<<12) | (1<<13));
10778 val |= (1<<6) | (1<<8);
10779 bnx2x_cl22_write(bp, phy, 0x00, val);
10785 bnx2x_cl22_write(bp, phy, 0x18, 7);
10786 bnx2x_cl22_read(bp, phy, 0x18, &val);
10787 bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10801 static void bnx2x_7101_config_loopback(
struct bnx2x_phy *phy,
10804 struct bnx2x *bp = params->
bp;
10806 bnx2x_cl45_write(bp, phy,
10810 static int bnx2x_7101_config_init(
struct bnx2x_phy *phy,
10814 u16 fw_ver1, fw_ver2,
val;
10815 struct bnx2x *bp = params->
bp;
10823 bnx2x_wait_reset_complete(bp, phy, params);
10825 bnx2x_cl45_write(bp, phy,
10828 bnx2x_cl45_write(bp, phy,
10831 bnx2x_ext_phy_set_pause(params, phy, vars);
10833 bnx2x_cl45_read(bp, phy,
10836 bnx2x_cl45_write(bp, phy,
10840 bnx2x_cl45_read(bp, phy,
10843 bnx2x_cl45_read(bp, phy,
10845 bnx2x_save_spirom_version(bp, params->
port,
10850 static u8 bnx2x_7101_read_status(
struct bnx2x_phy *phy,
10854 struct bnx2x *bp = params->
bp;
10857 bnx2x_cl45_read(bp, phy,
10859 bnx2x_cl45_read(bp, phy,
10863 bnx2x_cl45_read(bp, phy,
10865 bnx2x_cl45_read(bp, phy,
10869 link_up = ((val1 & 4) == 4);
10872 bnx2x_cl45_read(bp, phy,
10878 val2, (val2 & (1<<14)));
10879 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10880 bnx2x_ext_phy_resolve_fc(phy, params, vars);
10883 if (val2 & (1<<11))
10890 static int bnx2x_7101_format_ver(
u32 spirom_ver,
u8 *str,
u16 *len)
10894 str[0] = (spirom_ver & 0xFF);
10895 str[1] = (spirom_ver & 0xFF00) >> 8;
10896 str[2] = (spirom_ver & 0xFF0000) >> 16;
10897 str[3] = (spirom_ver & 0xFF000000) >> 24;
10907 bnx2x_cl45_read(bp, phy,
10911 for (cnt = 0; cnt < 10; cnt++) {
10914 bnx2x_cl45_write(bp, phy,
10919 bnx2x_cl45_read(bp, phy,
10923 if ((val & (1<<15)) == 0)
10928 static void bnx2x_7101_hw_reset(
struct bnx2x_phy *phy,
10938 static void bnx2x_7101_set_link_led(
struct bnx2x_phy *phy,
10942 struct bnx2x *bp = params->
bp;
10955 bnx2x_cl45_write(bp, phy,
10970 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10971 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10976 .req_flow_ctrl = 0,
10977 .req_line_speed = 0,
10978 .speed_cap_mask = 0,
10996 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
10997 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11031 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11032 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11061 static struct bnx2x_phy phy_warpcore = {
11068 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11094 .hw_reset = (
hw_reset_t)bnx2x_warpcore_hw_reset,
11105 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11106 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11125 .hw_reset = (
hw_reset_t)bnx2x_7101_hw_reset,
11134 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11135 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11165 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11166 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11193 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11194 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11223 FLAGS_INIT_XGXS_FIRST |
11226 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11258 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11277 .hw_reset = (
hw_reset_t)bnx2x_8727_hw_reset,
11287 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11288 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11312 .hw_reset = (
hw_reset_t)bnx2x_8481_hw_reset,
11325 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11362 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11384 .hw_reset = (
hw_reset_t)bnx2x_84833_hw_reset_phy,
11389 static struct bnx2x_phy phy_54618se = {
11394 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11395 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
11428 static void bnx2x_populate_preemphasis(
struct bnx2x *bp,
u32 shmem_base,
11434 for (i = 0; i < 2; i++) {
11440 rx =
REG_RD(bp, shmem_base +
11442 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
11446 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11448 rx =
REG_RD(bp, shmem_base +
11450 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11454 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11465 static u32 bnx2x_get_ext_phy_config(
struct bnx2x *bp,
u32 shmem_base,
11466 u8 phy_index,
u8 port)
11468 u32 ext_phy_config = 0;
11469 switch (phy_index) {
11471 ext_phy_config =
REG_RD(bp, shmem_base +
11473 dev_info.port_hw_config[port].external_phy_config));
11476 ext_phy_config =
REG_RD(bp, shmem_base +
11478 dev_info.port_hw_config[port].external_phy_config2));
11485 return ext_phy_config;
11487 static int bnx2x_populate_int_phy(
struct bnx2x *bp,
u32 shmem_base,
u8 port,
11492 u32 switch_cfg = (
REG_RD(bp, shmem_base +
11494 dev_info.port_feature_config[port].link_config)) &
11504 *phy = phy_warpcore;
11510 serdes_net_if = (
REG_RD(bp, shmem_base +
11512 port_hw_config[port].default_cfg)) &
11517 switch (serdes_net_if) {
11586 switch (switch_cfg) {
11604 phy->
addr = (
u8)phy_addr;
11605 phy->
mdio_ctrl = bnx2x_get_emac_base(bp,
11616 bnx2x_populate_preemphasis(bp, shmem_base, phy, port,
INT_PHY);
11620 static int bnx2x_populate_ext_phy(
struct bnx2x *bp,
11627 u32 ext_phy_config, phy_type, config2;
11629 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11633 switch (phy_type) {
11670 *phy = phy_54618se;
11690 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11697 dev_info.shared_hw_config.config2));
11700 port_mb[port].ext_phy_fw_version);
11704 mdc_mdio_access = config2 &
11713 ext_phy_fw_version2[port]);
11717 mdc_mdio_access = (config2 &
11722 phy->
mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11730 if (((raw_ver & 0x7F) <= 39) &&
11731 (((raw_ver & 0xF80) >> 7) <= 1))
11743 phy_type, port, phy_index);
11749 static int bnx2x_populate_phy(
struct bnx2x *bp,
u8 phy_index,
u32 shmem_base,
11755 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11756 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11761 static void bnx2x_phy_def_cfg(
struct link_params *params,
11765 struct bnx2x *bp = params->
bp;
11771 port_feature_config[params->
port].link_config2));
11775 port_hw_config[params->
port].speed_capability_mask2));
11779 port_feature_config[params->
port].link_config));
11783 port_hw_config[params->
port].speed_capability_mask));
11786 "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
11836 u32 phy_config_swapped, prio_cfg;
11845 if (phy_config_swapped) {
11846 switch (prio_cfg) {
11861 return_cfg = prio_cfg;
11869 u8 phy_index, actual_phy_idx;
11871 struct bnx2x *bp = params->
bp;
11880 actual_phy_idx = phy_index;
11881 if (phy_config_swapped) {
11888 " actual_phy_idx %x\n", phy_config_swapped,
11889 phy_index, actual_phy_idx);
11890 phy = ¶ms->
phy[actual_phy_idx];
11891 if (bnx2x_populate_phy(bp, phy_index, params->
shmem_base,
11913 media_types =
REG_RD(bp, sync_offset);
11921 actual_phy_idx))) == 0) {
11927 REG_WR(bp, sync_offset, media_types);
11929 bnx2x_phy_def_cfg(params, phy, phy_index);
11940 struct bnx2x *bp = params->
bp;
11949 bnx2x_xgxs_deassert(params);
11952 bnx2x_bmac_enable(params, vars, 1, 1);
11960 struct bnx2x *bp = params->
bp;
11969 bnx2x_xgxs_deassert(params);
11971 bnx2x_emac_enable(params, vars, 1);
11972 bnx2x_emac_program(params, vars);
11979 struct bnx2x *bp = params->
bp;
11992 bnx2x_set_aer_mmd(params, ¶ms->
phy[0]);
11993 bnx2x_warpcore_reset_lane(bp, ¶ms->
phy[0], 0);
11998 bnx2x_xmac_enable(params, vars, 1);
12005 struct bnx2x *bp = params->
bp;
12012 bnx2x_umac_enable(params, vars, 1);
12020 struct bnx2x *bp = params->
bp;
12030 bnx2x_xgxs_deassert(params);
12031 bnx2x_link_initialize(params, vars);
12035 bnx2x_umac_enable(params, vars, 0);
12037 bnx2x_emac_program(params, vars);
12038 bnx2x_emac_enable(params, vars, 0);
12042 bnx2x_xmac_enable(params, vars, 0);
12044 bnx2x_bmac_enable(params, vars, 0, 1);
12057 phy_index < params->
num_phys; phy_index++) {
12058 if (params->
phy[phy_index].config_loopback)
12059 params->
phy[phy_index].config_loopback(
12060 ¶ms->
phy[phy_index],
12069 static void bnx2x_set_rx_filter(
struct link_params *params,
u8 en)
12071 struct bnx2x *bp = params->
bp;
12072 u8 val = en * 0x1F;
12087 static int bnx2x_avoid_link_flap(
struct link_params *params,
12091 u32 dont_clear_stat, lfa_sts;
12092 struct bnx2x *bp = params->
bp;
12111 bnx2x_verify_sfp_module(phy, params);
12121 if (!dont_clear_stat) {
12132 bnx2x_umac_enable(params, vars, 0);
12134 bnx2x_xmac_enable(params, vars, 0);
12137 bnx2x_emac_enable(params, vars, 0);
12139 bnx2x_bmac_enable(params, vars, 0, !dont_clear_stat);
12157 bnx2x_link_int_enable(params);
12161 static void bnx2x_cannot_avoid_link_flap(
struct link_params *params,
12165 u32 lfa_sts, cfg_idx, tmp_val;
12166 struct bnx2x *bp = params->
bp;
12188 speed_cap_mask[cfg_idx]),
12204 lfa_sts &= ~SHMEM_LFA_DONT_CLEAR_STAT;
12224 struct bnx2x *bp = params->
bp;
12239 bnx2x_set_rx_filter(params, 1);
12241 lfa_status = bnx2x_check_lfa(params);
12243 if (lfa_status == 0) {
12245 return bnx2x_avoid_link_flap(params, vars);
12250 bnx2x_cannot_avoid_link_flap(params, vars, lfa_status);
12259 bnx2x_emac_init(params, vars);
12268 set_phy_vars(params, vars);
12291 bnx2x_xgxs_deassert(params);
12293 bnx2x_serdes_deassert(bp, params->
port);
12295 bnx2x_link_initialize(params, vars);
12297 bnx2x_link_int_enable(params);
12302 bnx2x_update_mng_eee(params, vars->
eee_status);
12309 struct bnx2x *bp = params->
bp;
12310 u8 phy_index, port = params->
port, clear_latch_ind = 0;
12317 bnx2x_update_mng_eee(params, vars->
eee_status);
12334 bnx2x_set_bmac_rx(bp, params->
chip_id, port, 0);
12336 bnx2x_set_xmac_rxtx(params, 0);
12337 bnx2x_set_umac_rxtx(params, 0);
12348 bnx2x_set_mdio_clk(bp, params->
chip_id, port);
12351 if (reset_ext_phy) {
12354 if (params->
phy[phy_index].link_reset) {
12355 bnx2x_set_aer_mmd(params,
12356 ¶ms->
phy[phy_index]);
12357 params->
phy[phy_index].link_reset(
12358 ¶ms->
phy[phy_index],
12361 if (params->
phy[phy_index].flags &
12363 clear_latch_ind = 1;
12367 if (clear_latch_ind) {
12369 bnx2x_rearm_latch_signal(bp, port, 0);
12386 bnx2x_set_xumac_nig(params, 0, 0);
12388 MISC_REGISTERS_RESET_REG_2_XMAC)
12399 struct bnx2x *bp = params->
bp;
12415 bnx2x_set_bmac_rx(bp, params->
chip_id, params->
port, 0);
12418 bnx2x_set_xmac_rxtx(params, 0);
12419 bnx2x_set_umac_rxtx(params, 0);
12427 bnx2x_set_rx_filter(params, 0);
12436 bnx2x_set_bmac_rx(bp, params->
chip_id, params->
port, 1);
12439 bnx2x_set_xmac_rxtx(params, 1);
12440 bnx2x_set_umac_rxtx(params, 1);
12450 static int bnx2x_8073_common_init_phy(
struct bnx2x *bp,
12451 u32 shmem_base_path[],
12452 u32 shmem2_base_path[],
u8 phy_index,
12459 s8 port_of_path = 0;
12460 u32 swap_val, swap_override;
12463 port ^= (swap_val && swap_override);
12467 u32 shmem_base, shmem2_base;
12470 shmem_base = shmem_base_path[0];
12471 shmem2_base = shmem2_base_path[0];
12472 port_of_path =
port;
12474 shmem_base = shmem_base_path[
port];
12475 shmem2_base = shmem2_base_path[
port];
12480 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12481 port_of_path, &phy[port]) !=
12502 bnx2x_cl45_write(bp, &phy[port],
12511 if (phy[
PORT_0].addr & 0x1) {
12522 port_of_path = port;
12527 phy_blk[port]->addr);
12528 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12533 bnx2x_cl45_read(bp, phy_blk[port],
12538 bnx2x_cl45_write(bp, phy_blk[port],
12553 bnx2x_cl45_read(bp, phy_blk[port],
12557 bnx2x_cl45_write(bp, phy_blk[port],
12563 bnx2x_cl45_read(bp, phy_blk[port],
12566 bnx2x_cl45_write(bp, phy_blk[port],
12576 static int bnx2x_8726_common_init_phy(
struct bnx2x *bp,
12577 u32 shmem_base_path[],
12578 u32 shmem2_base_path[],
u8 phy_index,
12593 for (port = 0; port <
PORT_MAX; port++) {
12594 u32 shmem_base, shmem2_base;
12598 shmem_base = shmem_base_path[0];
12599 shmem2_base = shmem2_base_path[0];
12601 shmem_base = shmem_base_path[
port];
12602 shmem2_base = shmem2_base_path[
port];
12605 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12613 bnx2x_cl45_write(bp, &phy,
12625 static void bnx2x_get_ext_phy_reset_gpio(
struct bnx2x *bp,
u32 shmem_base,
12629 u32 phy_gpio_reset =
REG_RD(bp, shmem_base +
12632 switch (phy_gpio_reset) {
12671 static int bnx2x_8727_common_init_phy(
struct bnx2x *bp,
12672 u32 shmem_base_path[],
12673 u32 shmem2_base_path[],
u8 phy_index,
12677 u32 swap_val, swap_override;
12690 bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
12691 (
u8 *)&reset_gpio, (
u8 *)&port);
12694 port ^= (swap_val && swap_override);
12706 for (port = PORT_MAX - 1; port >=
PORT_0; port--) {
12707 u32 shmem_base, shmem2_base;
12711 shmem_base = shmem_base_path[0];
12712 shmem2_base = shmem2_base_path[0];
12713 port_of_path =
port;
12715 shmem_base = shmem_base_path[
port];
12716 shmem2_base = shmem2_base_path[
port];
12721 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12722 port_of_path, &phy[port]) !=
12737 bnx2x_cl45_write(bp, &phy[port],
12743 if (phy[
PORT_0].addr & 0x1) {
12751 for (port = PORT_MAX - 1; port >=
PORT_0; port--) {
12753 port_of_path = port;
12757 phy_blk[port]->addr);
12758 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12762 bnx2x_cl45_write(bp, phy_blk[port],
12770 static int bnx2x_84833_common_init_phy(
struct bnx2x *bp,
12771 u32 shmem_base_path[],
12772 u32 shmem2_base_path[],
12777 reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
12786 static int bnx2x_84833_pre_init_phy(
struct bnx2x *bp,
12791 for (cnt = 0; cnt < 1500; cnt++) {
12792 bnx2x_cl45_read(bp, phy,
12795 if (!(val & (1<<15)))
12805 bnx2x_cl45_read(bp, phy,
12809 bnx2x_cl45_write(bp, phy,
12814 bnx2x_save_848xx_spirom_version(phy, bp,
PORT_0);
12825 bnx2x_set_mdio_clk(bp, chip_id,
PORT_0);
12826 if (bnx2x_populate_phy(bp,
EXT_PHY1, shmem_base, shmem2_base,
12831 switch (phy.
type) {
12833 rc = bnx2x_84833_pre_init_phy(bp, &phy);
12841 static int bnx2x_ext_phy_common_init(
struct bnx2x *bp,
u32 shmem_base_path[],
12842 u32 shmem2_base_path[],
u8 phy_index,
12843 u32 ext_phy_type,
u32 chip_id)
12847 switch (ext_phy_type) {
12849 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12851 phy_index, chip_id);
12856 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12858 phy_index, chip_id);
12865 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12867 phy_index, chip_id);
12873 rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
12875 phy_index, chip_id);
12882 "ext_phy 0x%x common init not required\n",
12888 netdev_err(bp->
dev,
"Warning: PHY was not initialized,"
12895 u32 shmem2_base_path[],
u32 chip_id)
12900 u32 ext_phy_type, ext_phy_config;
12901 bnx2x_set_mdio_clk(bp, chip_id,
PORT_0);
12902 bnx2x_set_mdio_clk(bp, chip_id,
PORT_1);
12910 phy_ver =
REG_RD(bp, shmem_base_path[0] +
12912 port_mb[
PORT_0].ext_phy_fw_version));
12922 ext_phy_config = bnx2x_get_ext_phy_config(bp,
12923 shmem_base_path[0],
12926 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12928 phy_index, ext_phy_type,
12934 static void bnx2x_check_over_curr(
struct link_params *params,
12937 struct bnx2x *bp = params->
bp;
12944 dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
12949 if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
12954 netdev_err(bp->
dev,
"Error: Power fault on Port %d has"
12955 " been detected and the power to "
12956 "that SFP+ module has been removed"
12957 " to prevent failure of the card."
12958 " Please remove the SFP+ module and"
12959 " restart the system to clear this"
12969 static u8 bnx2x_analyze_link_error(
struct link_params *params,
12973 struct bnx2x *bp = params->
bp;
12976 u32 old_status = (vars->
phy_flags & phy_flag) ? 1 : 0;
12978 if ((status ^ old_status) == 0)
12982 switch (phy_flag) {
12993 old_status, status);
13020 bnx2x_sync_link(params, vars);
13048 struct bnx2x *bp = params->
bp;
13049 u32 lss_status = 0;
13058 (MISC_REGISTERS_RESET_REG_2_XMAC))) {
13074 bnx2x_analyze_link_error(params, vars, lss_status,
13080 u32 lss_status_reg;
13090 REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
13091 lss_status = (wb_data[0] > 0);
13093 bnx2x_analyze_link_error(params, vars, lss_status,
13099 static void bnx2x_sfp_tx_fault_detection(
struct bnx2x_phy *phy,
13103 struct bnx2x *bp = params->
bp;
13105 u8 led_change, port = params->
port;
13109 dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
13113 if (bnx2x_get_cfg_pin(bp, cfg_pin, &value)) {
13118 led_change = bnx2x_analyze_link_error(params, vars, value,
13138 bnx2x_set_e3_module_fault_led(params, led_mode);
13145 struct bnx2x *bp = params->
bp;
13148 bnx2x_set_aer_mmd(params, ¶ms->
phy[phy_idx]);
13158 bnx2x_set_aer_mmd(params, phy);
13159 bnx2x_check_over_curr(params, vars);
13161 bnx2x_warpcore_config_runtime(phy, params, vars);
13165 port_hw_config[params->
port].default_cfg))
13168 if (bnx2x_is_sfp_module_plugged(phy, params)) {
13169 bnx2x_sfp_tx_fault_detection(phy, params, vars);
13190 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
13207 u8 phy_index, fan_failure_det_req = 0;
13211 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
13217 fan_failure_det_req |= (phy.
flags &
13220 return fan_failure_det_req;
13226 struct bnx2x *bp = params->
bp;
13227 bnx2x_update_mng(params, 0);
13236 if (params->
phy[phy_index].hw_reset) {
13237 params->
phy[phy_index].hw_reset(
13238 ¶ms->
phy[phy_index],
13240 params->
phy[phy_index] = phy_null;
13246 u32 chip_id,
u32 shmem_base,
u32 shmem2_base,
13249 u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
13253 if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
13263 if (bnx2x_populate_phy(bp, phy_index, shmem_base,
13264 shmem2_base, port, &phy)
13277 if (gpio_num == 0xff)
13285 gpio_port ^= (swap_val && swap_override);
13288 (gpio_num + (gpio_port << 2));
13290 sync_offset = shmem_base +
13292 dev_info.port_hw_config[port].aeu_int_mask);
13304 aeu_mask =
REG_RD(bp, offset);
13306 REG_WR(bp, offset, aeu_mask);
13310 val |= 1 << (gpio_num + (gpio_port << 2));