aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/bnx2x/bnx2x_link.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
committerGlenn Elliott <gelliott@cs.unc.edu>2012-03-04 19:47:13 -0500
commitc71c03bda1e86c9d5198c5d83f712e695c4f2a1e (patch)
treeecb166cb3e2b7e2adb3b5e292245fefd23381ac8 /drivers/net/bnx2x/bnx2x_link.c
parentea53c912f8a86a8567697115b6a0d8152beee5c8 (diff)
parent6a00f206debf8a5c8899055726ad127dbeeed098 (diff)
Merge branch 'mpi-master' into wip-k-fmlpwip-k-fmlp
Conflicts: litmus/sched_cedf.c
Diffstat (limited to 'drivers/net/bnx2x/bnx2x_link.c')
-rw-r--r--drivers/net/bnx2x/bnx2x_link.c10888
1 files changed, 6205 insertions, 4683 deletions
diff --git a/drivers/net/bnx2x/bnx2x_link.c b/drivers/net/bnx2x/bnx2x_link.c
index 0383e3066313..076e11f5769f 100644
--- a/drivers/net/bnx2x/bnx2x_link.c
+++ b/drivers/net/bnx2x/bnx2x_link.c
@@ -1,4 +1,4 @@
1/* Copyright 2008-2009 Broadcom Corporation 1/* Copyright 2008-2011 Broadcom Corporation
2 * 2 *
3 * Unless you and Broadcom execute a separate written software license 3 * Unless you and Broadcom execute a separate written software license
4 * agreement governing use of this software, this software is licensed to you 4 * agreement governing use of this software, this software is licensed to you
@@ -28,12 +28,13 @@
28 28
29/********************************************************/ 29/********************************************************/
30#define ETH_HLEN 14 30#define ETH_HLEN 14
31#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/ 31/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
32#define ETH_OVREHEAD (ETH_HLEN + 8 + 8)
32#define ETH_MIN_PACKET_SIZE 60 33#define ETH_MIN_PACKET_SIZE 60
33#define ETH_MAX_PACKET_SIZE 1500 34#define ETH_MAX_PACKET_SIZE 1500
34#define ETH_MAX_JUMBO_PACKET_SIZE 9600 35#define ETH_MAX_JUMBO_PACKET_SIZE 9600
35#define MDIO_ACCESS_TIMEOUT 1000 36#define MDIO_ACCESS_TIMEOUT 1000
36#define BMAC_CONTROL_RX_ENABLE 2 37#define BMAC_CONTROL_RX_ENABLE 2
37 38
38/***********************************************************/ 39/***********************************************************/
39/* Shortcut definitions */ 40/* Shortcut definitions */
@@ -79,7 +80,7 @@
79 80
80#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37 81#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
81#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73 82#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
82#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM 83#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
83#define AUTONEG_PARALLEL \ 84#define AUTONEG_PARALLEL \
84 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION 85 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85#define AUTONEG_SGMII_FIBER_AUTODET \ 86#define AUTONEG_SGMII_FIBER_AUTODET \
@@ -112,10 +113,10 @@
112#define GP_STATUS_10G_KX4 \ 113#define GP_STATUS_10G_KX4 \
113 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4 114 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114 115
115#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD 116#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
116#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD 117#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD 118#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4 119#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
119#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD 120#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD 121#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD 122#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
@@ -123,18 +124,18 @@
123#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD 124#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD 125#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD 126#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD 127#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD 128#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD 129#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD 130#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD 131#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD 132#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD 133#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD 134#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD 135#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD 136#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD 137#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD 138#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138 139
139#define PHY_XGXS_FLAG 0x1 140#define PHY_XGXS_FLAG 0x1
140#define PHY_SGMII_FLAG 0x2 141#define PHY_SGMII_FLAG 0x2
@@ -142,7 +143,7 @@
142 143
143/* */ 144/* */
144#define SFP_EEPROM_CON_TYPE_ADDR 0x2 145#define SFP_EEPROM_CON_TYPE_ADDR 0x2
145 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7 146 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
146 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21 147 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
147 148
148 149
@@ -153,85 +154,318 @@
153 154
154#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8 155#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
155 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4 156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8 157 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
157 158
158#define SFP_EEPROM_OPTIONS_ADDR 0x40 159#define SFP_EEPROM_OPTIONS_ADDR 0x40
159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1 160 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160#define SFP_EEPROM_OPTIONS_SIZE 2 161#define SFP_EEPROM_OPTIONS_SIZE 2
161
162#define EDC_MODE_LINEAR 0x0022
163#define EDC_MODE_LIMITING 0x0044
164#define EDC_MODE_PASSIVE_DAC 0x0055
165 162
163#define EDC_MODE_LINEAR 0x0022
164#define EDC_MODE_LIMITING 0x0044
165#define EDC_MODE_PASSIVE_DAC 0x0055
166 166
167 167
168#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND (0x5000)
169#define ETS_BW_LIMIT_CREDIT_WEIGHT (0x5000)
168/**********************************************************/ 170/**********************************************************/
169/* INTERFACE */ 171/* INTERFACE */
170/**********************************************************/ 172/**********************************************************/
171#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ 173
172 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \ 174#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
173 DEFAULT_PHY_DEV_ADDR, \ 175 bnx2x_cl45_write(_bp, _phy, \
176 (_phy)->def_md_devad, \
174 (_bank + (_addr & 0xf)), \ 177 (_bank + (_addr & 0xf)), \
175 _val) 178 _val)
176 179
177#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \ 180#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
178 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \ 181 bnx2x_cl45_read(_bp, _phy, \
179 DEFAULT_PHY_DEV_ADDR, \ 182 (_phy)->def_md_devad, \
180 (_bank + (_addr & 0xf)), \ 183 (_bank + (_addr & 0xf)), \
181 _val) 184 _val)
182 185
183static void bnx2x_set_serdes_access(struct link_params *params) 186static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
187{
188 u32 val = REG_RD(bp, reg);
189
190 val |= bits;
191 REG_WR(bp, reg, val);
192 return val;
193}
194
195static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
184{ 196{
197 u32 val = REG_RD(bp, reg);
198
199 val &= ~bits;
200 REG_WR(bp, reg, val);
201 return val;
202}
203
204/******************************************************************/
205/* ETS section */
206/******************************************************************/
207void bnx2x_ets_disabled(struct link_params *params)
208{
209 /* ETS disabled configuration*/
185 struct bnx2x *bp = params->bp; 210 struct bnx2x *bp = params->bp;
186 u32 emac_base = (params->port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
187 211
188 /* Set Clause 22 */ 212 DP(NETIF_MSG_LINK, "ETS disabled configuration\n");
189 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 1); 213
190 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000); 214 /*
191 udelay(500); 215 * mapping between entry priority to client number (0,1,2 -debug and
192 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f); 216 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
193 udelay(500); 217 * 3bits client num.
194 /* Set Clause 45 */ 218 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
195 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + params->port*0x10, 0); 219 * cos1-100 cos0-011 dbg1-010 dbg0-001 MCP-000
220 */
221
222 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
223 /*
224 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
225 * as strict. Bits 0,1,2 - debug and management entries, 3 -
226 * COS0 entry, 4 - COS1 entry.
227 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
228 * bit4 bit3 bit2 bit1 bit0
229 * MCP and debug are strict
230 */
231
232 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
233 /* defines which entries (clients) are subjected to WFQ arbitration */
234 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
235 /*
236 * For strict priority entries defines the number of consecutive
237 * slots for the highest priority.
238 */
239 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
240 /*
241 * mapping between the CREDIT_WEIGHT registers and actual client
242 * numbers
243 */
244 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
245 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
246 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
247
248 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
249 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
250 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
251 /* ETS mode disable */
252 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
253 /*
254 * If ETS mode is enabled (there is no strict priority) defines a WFQ
255 * weight for COS0/COS1.
256 */
257 REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
258 REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
259 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
260 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
261 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
262 /* Defines the number of consecutive slots for the strict priority */
263 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
264}
265
266static void bnx2x_ets_bw_limit_common(const struct link_params *params)
267{
268 /* ETS disabled configuration */
269 struct bnx2x *bp = params->bp;
270 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
271 /*
272 * defines which entries (clients) are subjected to WFQ arbitration
273 * COS0 0x8
274 * COS1 0x10
275 */
276 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
277 /*
278 * mapping between the ARB_CREDIT_WEIGHT registers and actual
279 * client numbers (WEIGHT_0 does not actually have to represent
280 * client 0)
281 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
282 * cos1-001 cos0-000 dbg1-100 dbg0-011 MCP-010
283 */
284 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
285
286 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
287 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
288 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
289 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
290
291 /* ETS mode enabled*/
292 REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
293
294 /* Defines the number of consecutive slots for the strict priority */
295 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
296 /*
297 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
298 * as strict. Bits 0,1,2 - debug and management entries, 3 - COS0
299 * entry, 4 - COS1 entry.
300 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
301 * bit4 bit3 bit2 bit1 bit0
302 * MCP and debug are strict
303 */
304 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
305
306 /* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
307 REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
308 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
309 REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
310 ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
196} 311}
197static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags) 312
313void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
314 const u32 cos1_bw)
198{ 315{
316 /* ETS disabled configuration*/
199 struct bnx2x *bp = params->bp; 317 struct bnx2x *bp = params->bp;
318 const u32 total_bw = cos0_bw + cos1_bw;
319 u32 cos0_credit_weight = 0;
320 u32 cos1_credit_weight = 0;
200 321
201 if (phy_flags & PHY_XGXS_FLAG) { 322 DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
202 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
203 params->port*0x18, 0);
204 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
205 DEFAULT_PHY_DEV_ADDR);
206 } else {
207 bnx2x_set_serdes_access(params);
208 323
209 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + 324 if ((0 == total_bw) ||
210 params->port*0x10, 325 (0 == cos0_bw) ||
211 DEFAULT_PHY_DEV_ADDR); 326 (0 == cos1_bw)) {
327 DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
328 return;
212 } 329 }
330
331 cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
332 total_bw;
333 cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
334 total_bw;
335
336 bnx2x_ets_bw_limit_common(params);
337
338 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
339 REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
340
341 REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
342 REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
213} 343}
214 344
215static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits) 345u8 bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
216{ 346{
217 u32 val = REG_RD(bp, reg); 347 /* ETS disabled configuration*/
348 struct bnx2x *bp = params->bp;
349 u32 val = 0;
218 350
219 val |= bits; 351 DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
220 REG_WR(bp, reg, val); 352 /*
221 return val; 353 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
354 * as strict. Bits 0,1,2 - debug and management entries,
355 * 3 - COS0 entry, 4 - COS1 entry.
356 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
357 * bit4 bit3 bit2 bit1 bit0
358 * MCP and debug are strict
359 */
360 REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
361 /*
362 * For strict priority entries defines the number of consecutive slots
363 * for the highest priority.
364 */
365 REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
366 /* ETS mode disable */
367 REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
368 /* Defines the number of consecutive slots for the strict priority */
369 REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
370
371 /* Defines the number of consecutive slots for the strict priority */
372 REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
373
374 /*
375 * mapping between entry priority to client number (0,1,2 -debug and
376 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
377 * 3bits client num.
378 * PRI4 | PRI3 | PRI2 | PRI1 | PRI0
379 * dbg0-010 dbg1-001 cos1-100 cos0-011 MCP-000
380 * dbg0-010 dbg1-001 cos0-011 cos1-100 MCP-000
381 */
382 val = (0 == strict_cos) ? 0x2318 : 0x22E0;
383 REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
384
385 return 0;
222} 386}
387/******************************************************************/
388/* PFC section */
389/******************************************************************/
223 390
224static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits) 391static void bnx2x_bmac2_get_pfc_stat(struct link_params *params,
392 u32 pfc_frames_sent[2],
393 u32 pfc_frames_received[2])
225{ 394{
226 u32 val = REG_RD(bp, reg); 395 /* Read pfc statistic */
396 struct bnx2x *bp = params->bp;
397 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
398 NIG_REG_INGRESS_BMAC0_MEM;
227 399
228 val &= ~bits; 400 DP(NETIF_MSG_LINK, "pfc statistic read from BMAC\n");
229 REG_WR(bp, reg, val); 401
230 return val; 402 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_STAT_GTPP,
403 pfc_frames_sent, 2);
404
405 REG_RD_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_STAT_GRPP,
406 pfc_frames_received, 2);
407
408}
409static void bnx2x_emac_get_pfc_stat(struct link_params *params,
410 u32 pfc_frames_sent[2],
411 u32 pfc_frames_received[2])
412{
413 /* Read pfc statistic */
414 struct bnx2x *bp = params->bp;
415 u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
416 u32 val_xon = 0;
417 u32 val_xoff = 0;
418
419 DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
420
421 /* PFC received frames */
422 val_xoff = REG_RD(bp, emac_base +
423 EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
424 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
425 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
426 val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
427
428 pfc_frames_received[0] = val_xon + val_xoff;
429
430 /* PFC received sent */
431 val_xoff = REG_RD(bp, emac_base +
432 EMAC_REG_RX_PFC_STATS_XOFF_SENT);
433 val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
434 val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
435 val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
436
437 pfc_frames_sent[0] = val_xon + val_xoff;
231} 438}
232 439
440void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
441 u32 pfc_frames_sent[2],
442 u32 pfc_frames_received[2])
443{
444 /* Read pfc statistic */
445 struct bnx2x *bp = params->bp;
446 u32 val = 0;
447 DP(NETIF_MSG_LINK, "pfc statistic\n");
448
449 if (!vars->link_up)
450 return;
451
452 val = REG_RD(bp, MISC_REG_RESET_REG_2);
453 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
454 == 0) {
455 DP(NETIF_MSG_LINK, "About to read stats from EMAC\n");
456 bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
457 pfc_frames_received);
458 } else {
459 DP(NETIF_MSG_LINK, "About to read stats from BMAC\n");
460 bnx2x_bmac2_get_pfc_stat(params, pfc_frames_sent,
461 pfc_frames_received);
462 }
463}
464/******************************************************************/
465/* MAC/PBF section */
466/******************************************************************/
233static void bnx2x_emac_init(struct link_params *params, 467static void bnx2x_emac_init(struct link_params *params,
234 struct link_vars *vars) 468 struct link_vars *vars)
235{ 469{
236 /* reset and unreset the emac core */ 470 /* reset and unreset the emac core */
237 struct bnx2x *bp = params->bp; 471 struct bnx2x *bp = params->bp;
@@ -241,10 +475,10 @@ static void bnx2x_emac_init(struct link_params *params,
241 u16 timeout; 475 u16 timeout;
242 476
243 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 477 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
244 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); 478 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
245 udelay(5); 479 udelay(5);
246 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET, 480 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
247 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port)); 481 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
248 482
249 /* init emac - use read-modify-write */ 483 /* init emac - use read-modify-write */
250 /* self clear reset */ 484 /* self clear reset */
@@ -275,7 +509,7 @@ static void bnx2x_emac_init(struct link_params *params,
275} 509}
276 510
277static u8 bnx2x_emac_enable(struct link_params *params, 511static u8 bnx2x_emac_enable(struct link_params *params,
278 struct link_vars *vars, u8 lb) 512 struct link_vars *vars, u8 lb)
279{ 513{
280 struct bnx2x *bp = params->bp; 514 struct bnx2x *bp = params->bp;
281 u8 port = params->port; 515 u8 port = params->port;
@@ -287,77 +521,86 @@ static u8 bnx2x_emac_enable(struct link_params *params,
287 /* enable emac and not bmac */ 521 /* enable emac and not bmac */
288 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1); 522 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
289 523
290 /* for paladium */
291 if (CHIP_REV_IS_EMUL(bp)) {
292 /* Use lane 1 (of lanes 0-3) */
293 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
294 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
295 port*4, 1);
296 }
297 /* for fpga */
298 else
299
300 if (CHIP_REV_IS_FPGA(bp)) {
301 /* Use lane 1 (of lanes 0-3) */
302 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
303
304 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
305 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
306 0);
307 } else
308 /* ASIC */ 524 /* ASIC */
309 if (vars->phy_flags & PHY_XGXS_FLAG) { 525 if (vars->phy_flags & PHY_XGXS_FLAG) {
310 u32 ser_lane = ((params->lane_config & 526 u32 ser_lane = ((params->lane_config &
311 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 527 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
312 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 528 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
313 529
314 DP(NETIF_MSG_LINK, "XGXS\n"); 530 DP(NETIF_MSG_LINK, "XGXS\n");
315 /* select the master lanes (out of 0-3) */ 531 /* select the master lanes (out of 0-3) */
316 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + 532 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
317 port*4, ser_lane);
318 /* select XGXS */ 533 /* select XGXS */
319 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + 534 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
320 port*4, 1);
321 535
322 } else { /* SerDes */ 536 } else { /* SerDes */
323 DP(NETIF_MSG_LINK, "SerDes\n"); 537 DP(NETIF_MSG_LINK, "SerDes\n");
324 /* select SerDes */ 538 /* select SerDes */
325 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + 539 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
326 port*4, 0);
327 } 540 }
328 541
329 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE, 542 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
330 EMAC_RX_MODE_RESET); 543 EMAC_RX_MODE_RESET);
331 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 544 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
332 EMAC_TX_MODE_RESET); 545 EMAC_TX_MODE_RESET);
333 546
334 if (CHIP_REV_IS_SLOW(bp)) { 547 if (CHIP_REV_IS_SLOW(bp)) {
335 /* config GMII mode */ 548 /* config GMII mode */
336 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE); 549 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
337 EMAC_WR(bp, EMAC_REG_EMAC_MODE, 550 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
338 (val | EMAC_MODE_PORT_GMII));
339 } else { /* ASIC */ 551 } else { /* ASIC */
340 /* pause enable/disable */ 552 /* pause enable/disable */
341 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE, 553 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
342 EMAC_RX_MODE_FLOW_EN); 554 EMAC_RX_MODE_FLOW_EN);
343 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
344 bnx2x_bits_en(bp, emac_base +
345 EMAC_REG_EMAC_RX_MODE,
346 EMAC_RX_MODE_FLOW_EN);
347 555
348 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE, 556 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
349 (EMAC_TX_MODE_EXT_PAUSE_EN | 557 (EMAC_TX_MODE_EXT_PAUSE_EN |
350 EMAC_TX_MODE_FLOW_EN)); 558 EMAC_TX_MODE_FLOW_EN));
351 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 559 if (!(params->feature_config_flags &
352 bnx2x_bits_en(bp, emac_base + 560 FEATURE_CONFIG_PFC_ENABLED)) {
353 EMAC_REG_EMAC_TX_MODE, 561 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
354 (EMAC_TX_MODE_EXT_PAUSE_EN | 562 bnx2x_bits_en(bp, emac_base +
355 EMAC_TX_MODE_FLOW_EN)); 563 EMAC_REG_EMAC_RX_MODE,
564 EMAC_RX_MODE_FLOW_EN);
565
566 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
567 bnx2x_bits_en(bp, emac_base +
568 EMAC_REG_EMAC_TX_MODE,
569 (EMAC_TX_MODE_EXT_PAUSE_EN |
570 EMAC_TX_MODE_FLOW_EN));
571 } else
572 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
573 EMAC_TX_MODE_FLOW_EN);
356 } 574 }
357 575
358 /* KEEP_VLAN_TAG, promiscuous */ 576 /* KEEP_VLAN_TAG, promiscuous */
359 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE); 577 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
360 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS; 578 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
579
580 /*
581 * Setting this bit causes MAC control frames (except for pause
582 * frames) to be passed on for processing. This setting has no
583 * affect on the operation of the pause frames. This bit effects
584 * all packets regardless of RX Parser packet sorting logic.
585 * Turn the PFC off to make sure we are in Xon state before
586 * enabling it.
587 */
588 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
589 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
590 DP(NETIF_MSG_LINK, "PFC is enabled\n");
591 /* Enable PFC again */
592 EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
593 EMAC_REG_RX_PFC_MODE_RX_EN |
594 EMAC_REG_RX_PFC_MODE_TX_EN |
595 EMAC_REG_RX_PFC_MODE_PRIORITIES);
596
597 EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
598 ((0x0101 <<
599 EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
600 (0x00ff <<
601 EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
602 val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
603 }
361 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val); 604 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
362 605
363 /* Set Loopback */ 606 /* Set Loopback */
@@ -387,31 +630,381 @@ static u8 bnx2x_emac_enable(struct link_params *params,
387 /* enable the NIG in/out to the emac */ 630 /* enable the NIG in/out to the emac */
388 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1); 631 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
389 val = 0; 632 val = 0;
390 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) 633 if ((params->feature_config_flags &
634 FEATURE_CONFIG_PFC_ENABLED) ||
635 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
391 val = 1; 636 val = 1;
392 637
393 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val); 638 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
394 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1); 639 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
395 640
396 if (CHIP_REV_IS_EMUL(bp)) { 641 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
397 /* take the BigMac out of reset */
398 REG_WR(bp,
399 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
400 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
401
402 /* enable access for bmac registers */
403 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
404 } else
405 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
406 642
407 vars->mac_type = MAC_TYPE_EMAC; 643 vars->mac_type = MAC_TYPE_EMAC;
408 return 0; 644 return 0;
409} 645}
410 646
647static void bnx2x_update_pfc_bmac1(struct link_params *params,
648 struct link_vars *vars)
649{
650 u32 wb_data[2];
651 struct bnx2x *bp = params->bp;
652 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
653 NIG_REG_INGRESS_BMAC0_MEM;
654
655 u32 val = 0x14;
656 if ((!(params->feature_config_flags &
657 FEATURE_CONFIG_PFC_ENABLED)) &&
658 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
659 /* Enable BigMAC to react on received Pause packets */
660 val |= (1<<5);
661 wb_data[0] = val;
662 wb_data[1] = 0;
663 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
664
665 /* tx control */
666 val = 0xc0;
667 if (!(params->feature_config_flags &
668 FEATURE_CONFIG_PFC_ENABLED) &&
669 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
670 val |= 0x800000;
671 wb_data[0] = val;
672 wb_data[1] = 0;
673 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
674}
675
676static void bnx2x_update_pfc_bmac2(struct link_params *params,
677 struct link_vars *vars,
678 u8 is_lb)
679{
680 /*
681 * Set rx control: Strip CRC and enable BigMAC to relay
682 * control packets to the system as well
683 */
684 u32 wb_data[2];
685 struct bnx2x *bp = params->bp;
686 u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
687 NIG_REG_INGRESS_BMAC0_MEM;
688 u32 val = 0x14;
689
690 if ((!(params->feature_config_flags &
691 FEATURE_CONFIG_PFC_ENABLED)) &&
692 (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
693 /* Enable BigMAC to react on received Pause packets */
694 val |= (1<<5);
695 wb_data[0] = val;
696 wb_data[1] = 0;
697 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
698 udelay(30);
699
700 /* Tx control */
701 val = 0xc0;
702 if (!(params->feature_config_flags &
703 FEATURE_CONFIG_PFC_ENABLED) &&
704 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
705 val |= 0x800000;
706 wb_data[0] = val;
707 wb_data[1] = 0;
708 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
709
710 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
711 DP(NETIF_MSG_LINK, "PFC is enabled\n");
712 /* Enable PFC RX & TX & STATS and set 8 COS */
713 wb_data[0] = 0x0;
714 wb_data[0] |= (1<<0); /* RX */
715 wb_data[0] |= (1<<1); /* TX */
716 wb_data[0] |= (1<<2); /* Force initial Xon */
717 wb_data[0] |= (1<<3); /* 8 cos */
718 wb_data[0] |= (1<<5); /* STATS */
719 wb_data[1] = 0;
720 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
721 wb_data, 2);
722 /* Clear the force Xon */
723 wb_data[0] &= ~(1<<2);
724 } else {
725 DP(NETIF_MSG_LINK, "PFC is disabled\n");
726 /* disable PFC RX & TX & STATS and set 8 COS */
727 wb_data[0] = 0x8;
728 wb_data[1] = 0;
729 }
730
731 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
732
733 /*
734 * Set Time (based unit is 512 bit time) between automatic
735 * re-sending of PP packets amd enable automatic re-send of
736 * Per-Priroity Packet as long as pp_gen is asserted and
737 * pp_disable is low.
738 */
739 val = 0x8000;
740 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
741 val |= (1<<16); /* enable automatic re-send */
742
743 wb_data[0] = val;
744 wb_data[1] = 0;
745 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
746 wb_data, 2);
411 747
748 /* mac control */
749 val = 0x3; /* Enable RX and TX */
750 if (is_lb) {
751 val |= 0x4; /* Local loopback */
752 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
753 }
754 /* When PFC enabled, Pass pause frames towards the NIG. */
755 if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
756 val |= ((1<<6)|(1<<5));
757
758 wb_data[0] = val;
759 wb_data[1] = 0;
760 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
761}
412 762
413static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars, 763static void bnx2x_update_pfc_brb(struct link_params *params,
414 u8 is_lb) 764 struct link_vars *vars,
765 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
766{
767 struct bnx2x *bp = params->bp;
768 int set_pfc = params->feature_config_flags &
769 FEATURE_CONFIG_PFC_ENABLED;
770
771 /* default - pause configuration */
772 u32 pause_xoff_th = PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
773 u32 pause_xon_th = PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
774 u32 full_xoff_th = PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
775 u32 full_xon_th = PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
776
777 if (set_pfc && pfc_params)
778 /* First COS */
779 if (!pfc_params->cos0_pauseable) {
780 pause_xoff_th =
781 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
782 pause_xon_th =
783 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
784 full_xoff_th =
785 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
786 full_xon_th =
787 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
788 }
789 /*
790 * The number of free blocks below which the pause signal to class 0
791 * of MAC #n is asserted. n=0,1
792 */
793 REG_WR(bp, BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 , pause_xoff_th);
794 /*
795 * The number of free blocks above which the pause signal to class 0
796 * of MAC #n is de-asserted. n=0,1
797 */
798 REG_WR(bp, BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , pause_xon_th);
799 /*
800 * The number of free blocks below which the full signal to class 0
801 * of MAC #n is asserted. n=0,1
802 */
803 REG_WR(bp, BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , full_xoff_th);
804 /*
805 * The number of free blocks above which the full signal to class 0
806 * of MAC #n is de-asserted. n=0,1
807 */
808 REG_WR(bp, BRB1_REG_FULL_0_XON_THRESHOLD_0 , full_xon_th);
809
810 if (set_pfc && pfc_params) {
811 /* Second COS */
812 if (pfc_params->cos1_pauseable) {
813 pause_xoff_th =
814 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_PAUSEABLE;
815 pause_xon_th =
816 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_PAUSEABLE;
817 full_xoff_th =
818 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_PAUSEABLE;
819 full_xon_th =
820 PFC_BRB_MAC_FULL_XON_THRESHOLD_PAUSEABLE;
821 } else {
822 pause_xoff_th =
823 PFC_BRB_MAC_PAUSE_XOFF_THRESHOLD_NON_PAUSEABLE;
824 pause_xon_th =
825 PFC_BRB_MAC_PAUSE_XON_THRESHOLD_NON_PAUSEABLE;
826 full_xoff_th =
827 PFC_BRB_MAC_FULL_XOFF_THRESHOLD_NON_PAUSEABLE;
828 full_xon_th =
829 PFC_BRB_MAC_FULL_XON_THRESHOLD_NON_PAUSEABLE;
830 }
831 /*
832 * The number of free blocks below which the pause signal to
833 * class 1 of MAC #n is asserted. n=0,1
834 */
835 REG_WR(bp, BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0, pause_xoff_th);
836 /*
837 * The number of free blocks above which the pause signal to
838 * class 1 of MAC #n is de-asserted. n=0,1
839 */
840 REG_WR(bp, BRB1_REG_PAUSE_1_XON_THRESHOLD_0, pause_xon_th);
841 /*
842 * The number of free blocks below which the full signal to
843 * class 1 of MAC #n is asserted. n=0,1
844 */
845 REG_WR(bp, BRB1_REG_FULL_1_XOFF_THRESHOLD_0, full_xoff_th);
846 /*
847 * The number of free blocks above which the full signal to
848 * class 1 of MAC #n is de-asserted. n=0,1
849 */
850 REG_WR(bp, BRB1_REG_FULL_1_XON_THRESHOLD_0, full_xon_th);
851 }
852}
853
854static void bnx2x_update_pfc_nig(struct link_params *params,
855 struct link_vars *vars,
856 struct bnx2x_nig_brb_pfc_port_params *nig_params)
857{
858 u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
859 u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
860 u32 pkt_priority_to_cos = 0;
861 u32 val;
862 struct bnx2x *bp = params->bp;
863 int port = params->port;
864 int set_pfc = params->feature_config_flags &
865 FEATURE_CONFIG_PFC_ENABLED;
866 DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
867
868 /*
869 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
870 * MAC control frames (that are not pause packets)
871 * will be forwarded to the XCM.
872 */
873 xcm_mask = REG_RD(bp,
874 port ? NIG_REG_LLH1_XCM_MASK :
875 NIG_REG_LLH0_XCM_MASK);
876 /*
877 * nig params will override non PFC params, since it's possible to
878 * do transition from PFC to SAFC
879 */
880 if (set_pfc) {
881 pause_enable = 0;
882 llfc_out_en = 0;
883 llfc_enable = 0;
884 ppp_enable = 1;
885 xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
886 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
887 xcm0_out_en = 0;
888 p0_hwpfc_enable = 1;
889 } else {
890 if (nig_params) {
891 llfc_out_en = nig_params->llfc_out_en;
892 llfc_enable = nig_params->llfc_enable;
893 pause_enable = nig_params->pause_enable;
894 } else /*defaul non PFC mode - PAUSE */
895 pause_enable = 1;
896
897 xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
898 NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
899 xcm0_out_en = 1;
900 }
901
902 REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
903 NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
904 REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
905 NIG_REG_LLFC_ENABLE_0, llfc_enable);
906 REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
907 NIG_REG_PAUSE_ENABLE_0, pause_enable);
908
909 REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
910 NIG_REG_PPP_ENABLE_0, ppp_enable);
911
912 REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
913 NIG_REG_LLH0_XCM_MASK, xcm_mask);
914
915 REG_WR(bp, NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
916
917 /* output enable for RX_XCM # IF */
918 REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
919
920 /* HW PFC TX enable */
921 REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
922
923 /* 0x2 = BMAC, 0x1= EMAC */
924 switch (vars->mac_type) {
925 case MAC_TYPE_EMAC:
926 val = 1;
927 break;
928 case MAC_TYPE_BMAC:
929 val = 0;
930 break;
931 default:
932 val = 0;
933 break;
934 }
935 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT, val);
936
937 if (nig_params) {
938 pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
939
940 REG_WR(bp, port ? NIG_REG_P1_RX_COS0_PRIORITY_MASK :
941 NIG_REG_P0_RX_COS0_PRIORITY_MASK,
942 nig_params->rx_cos0_priority_mask);
943
944 REG_WR(bp, port ? NIG_REG_P1_RX_COS1_PRIORITY_MASK :
945 NIG_REG_P0_RX_COS1_PRIORITY_MASK,
946 nig_params->rx_cos1_priority_mask);
947
948 REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
949 NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
950 nig_params->llfc_high_priority_classes);
951
952 REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
953 NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
954 nig_params->llfc_low_priority_classes);
955 }
956 REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
957 NIG_REG_P0_PKT_PRIORITY_TO_COS,
958 pkt_priority_to_cos);
959}
960
961
962void bnx2x_update_pfc(struct link_params *params,
963 struct link_vars *vars,
964 struct bnx2x_nig_brb_pfc_port_params *pfc_params)
965{
966 /*
967 * The PFC and pause are orthogonal to one another, meaning when
968 * PFC is enabled, the pause are disabled, and when PFC is
969 * disabled, pause are set according to the pause result.
970 */
971 u32 val;
972 struct bnx2x *bp = params->bp;
973
974 /* update NIG params */
975 bnx2x_update_pfc_nig(params, vars, pfc_params);
976
977 /* update BRB params */
978 bnx2x_update_pfc_brb(params, vars, pfc_params);
979
980 if (!vars->link_up)
981 return;
982
983 val = REG_RD(bp, MISC_REG_RESET_REG_2);
984 if ((val & (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
985 == 0) {
986 DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
987 bnx2x_emac_enable(params, vars, 0);
988 return;
989 }
990
991 DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
992 if (CHIP_IS_E2(bp))
993 bnx2x_update_pfc_bmac2(params, vars, 0);
994 else
995 bnx2x_update_pfc_bmac1(params, vars);
996
997 val = 0;
998 if ((params->feature_config_flags &
999 FEATURE_CONFIG_PFC_ENABLED) ||
1000 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1001 val = 1;
1002 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
1003}
1004
1005static u8 bnx2x_bmac1_enable(struct link_params *params,
1006 struct link_vars *vars,
1007 u8 is_lb)
415{ 1008{
416 struct bnx2x *bp = params->bp; 1009 struct bnx2x *bp = params->bp;
417 u8 port = params->port; 1010 u8 port = params->port;
@@ -420,24 +1013,13 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
420 u32 wb_data[2]; 1013 u32 wb_data[2];
421 u32 val; 1014 u32 val;
422 1015
423 DP(NETIF_MSG_LINK, "Enabling BigMAC\n"); 1016 DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
424 /* reset and unreset the BigMac */
425 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
426 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
427 msleep(1);
428
429 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
430 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
431
432 /* enable access for bmac registers */
433 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
434 1017
435 /* XGXS control */ 1018 /* XGXS control */
436 wb_data[0] = 0x3c; 1019 wb_data[0] = 0x3c;
437 wb_data[1] = 0; 1020 wb_data[1] = 0;
438 REG_WR_DMAE(bp, bmac_addr + 1021 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
439 BIGMAC_REGISTER_BMAC_XGXS_CONTROL, 1022 wb_data, 2);
440 wb_data, 2);
441 1023
442 /* tx MAC SA */ 1024 /* tx MAC SA */
443 wb_data[0] = ((params->mac_addr[2] << 24) | 1025 wb_data[0] = ((params->mac_addr[2] << 24) |
@@ -446,17 +1028,7 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
446 params->mac_addr[5]); 1028 params->mac_addr[5]);
447 wb_data[1] = ((params->mac_addr[0] << 8) | 1029 wb_data[1] = ((params->mac_addr[0] << 8) |
448 params->mac_addr[1]); 1030 params->mac_addr[1]);
449 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, 1031 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
450 wb_data, 2);
451
452 /* tx control */
453 val = 0xc0;
454 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
455 val |= 0x800000;
456 wb_data[0] = val;
457 wb_data[1] = 0;
458 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
459 wb_data, 2);
460 1032
461 /* mac control */ 1033 /* mac control */
462 val = 0x3; 1034 val = 0x3;
@@ -466,238 +1038,155 @@ static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
466 } 1038 }
467 wb_data[0] = val; 1039 wb_data[0] = val;
468 wb_data[1] = 0; 1040 wb_data[1] = 0;
469 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, 1041 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
470 wb_data, 2);
471 1042
472 /* set rx mtu */ 1043 /* set rx mtu */
473 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 1044 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
474 wb_data[1] = 0; 1045 wb_data[1] = 0;
475 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, 1046 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
476 wb_data, 2);
477 1047
478 /* rx control set to don't strip crc */ 1048 bnx2x_update_pfc_bmac1(params, vars);
479 val = 0x14;
480 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
481 val |= 0x20;
482 wb_data[0] = val;
483 wb_data[1] = 0;
484 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
485 wb_data, 2);
486 1049
487 /* set tx mtu */ 1050 /* set tx mtu */
488 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 1051 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
489 wb_data[1] = 0; 1052 wb_data[1] = 0;
490 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, 1053 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
491 wb_data, 2);
492 1054
493 /* set cnt max size */ 1055 /* set cnt max size */
494 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD; 1056 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
495 wb_data[1] = 0; 1057 wb_data[1] = 0;
496 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, 1058 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
497 wb_data, 2);
498 1059
499 /* configure safc */ 1060 /* configure safc */
500 wb_data[0] = 0x1000200; 1061 wb_data[0] = 0x1000200;
501 wb_data[1] = 0; 1062 wb_data[1] = 0;
502 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS, 1063 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
503 wb_data, 2); 1064 wb_data, 2);
504 /* fix for emulation */
505 if (CHIP_REV_IS_EMUL(bp)) {
506 wb_data[0] = 0xf000;
507 wb_data[1] = 0;
508 REG_WR_DMAE(bp,
509 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
510 wb_data, 2);
511 }
512
513 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
514 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
515 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
516 val = 0;
517 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
518 val = 1;
519 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
520 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
521 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
522 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
523 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
524 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
525 1065
526 vars->mac_type = MAC_TYPE_BMAC;
527 return 0; 1066 return 0;
528} 1067}
529 1068
530static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags) 1069static u8 bnx2x_bmac2_enable(struct link_params *params,
531{ 1070 struct link_vars *vars,
532 struct bnx2x *bp = params->bp; 1071 u8 is_lb)
533 u32 val;
534
535 if (phy_flags & PHY_XGXS_FLAG) {
536 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
537 val = XGXS_RESET_BITS;
538
539 } else { /* SerDes */
540 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
541 val = SERDES_RESET_BITS;
542 }
543
544 val = val << (params->port*16);
545
546 /* reset and unreset the SerDes/XGXS */
547 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
548 val);
549 udelay(500);
550 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
551 val);
552 bnx2x_set_phy_mdio(params, phy_flags);
553}
554
555void bnx2x_link_status_update(struct link_params *params,
556 struct link_vars *vars)
557{ 1072{
558 struct bnx2x *bp = params->bp; 1073 struct bnx2x *bp = params->bp;
559 u8 link_10g;
560 u8 port = params->port; 1074 u8 port = params->port;
1075 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
1076 NIG_REG_INGRESS_BMAC0_MEM;
1077 u32 wb_data[2];
561 1078
562 if (params->switch_cfg == SWITCH_CFG_1G) 1079 DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
563 vars->phy_flags = PHY_SERDES_FLAG;
564 else
565 vars->phy_flags = PHY_XGXS_FLAG;
566 vars->link_status = REG_RD(bp, params->shmem_base +
567 offsetof(struct shmem_region,
568 port_mb[port].link_status));
569
570 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
571
572 if (vars->link_up) {
573 DP(NETIF_MSG_LINK, "phy link up\n");
574
575 vars->phy_link_up = 1;
576 vars->duplex = DUPLEX_FULL;
577 switch (vars->link_status &
578 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
579 case LINK_10THD:
580 vars->duplex = DUPLEX_HALF;
581 /* fall thru */
582 case LINK_10TFD:
583 vars->line_speed = SPEED_10;
584 break;
585
586 case LINK_100TXHD:
587 vars->duplex = DUPLEX_HALF;
588 /* fall thru */
589 case LINK_100T4:
590 case LINK_100TXFD:
591 vars->line_speed = SPEED_100;
592 break;
593
594 case LINK_1000THD:
595 vars->duplex = DUPLEX_HALF;
596 /* fall thru */
597 case LINK_1000TFD:
598 vars->line_speed = SPEED_1000;
599 break;
600
601 case LINK_2500THD:
602 vars->duplex = DUPLEX_HALF;
603 /* fall thru */
604 case LINK_2500TFD:
605 vars->line_speed = SPEED_2500;
606 break;
607
608 case LINK_10GTFD:
609 vars->line_speed = SPEED_10000;
610 break;
611 1080
612 case LINK_12GTFD: 1081 wb_data[0] = 0;
613 vars->line_speed = SPEED_12000; 1082 wb_data[1] = 0;
614 break; 1083 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
615 1084 udelay(30);
616 case LINK_12_5GTFD:
617 vars->line_speed = SPEED_12500;
618 break;
619 1085
620 case LINK_13GTFD: 1086 /* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
621 vars->line_speed = SPEED_13000; 1087 wb_data[0] = 0x3c;
622 break; 1088 wb_data[1] = 0;
1089 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
1090 wb_data, 2);
623 1091
624 case LINK_15GTFD: 1092 udelay(30);
625 vars->line_speed = SPEED_15000;
626 break;
627 1093
628 case LINK_16GTFD: 1094 /* tx MAC SA */
629 vars->line_speed = SPEED_16000; 1095 wb_data[0] = ((params->mac_addr[2] << 24) |
630 break; 1096 (params->mac_addr[3] << 16) |
1097 (params->mac_addr[4] << 8) |
1098 params->mac_addr[5]);
1099 wb_data[1] = ((params->mac_addr[0] << 8) |
1100 params->mac_addr[1]);
1101 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
1102 wb_data, 2);
631 1103
632 default: 1104 udelay(30);
633 break;
634 }
635 1105
636 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED) 1106 /* Configure SAFC */
637 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX; 1107 wb_data[0] = 0x1000200;
638 else 1108 wb_data[1] = 0;
639 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX; 1109 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
1110 wb_data, 2);
1111 udelay(30);
640 1112
641 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED) 1113 /* set rx mtu */
642 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX; 1114 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
643 else 1115 wb_data[1] = 0;
644 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX; 1116 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
1117 udelay(30);
645 1118
646 if (vars->phy_flags & PHY_XGXS_FLAG) { 1119 /* set tx mtu */
647 if (vars->line_speed && 1120 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
648 ((vars->line_speed == SPEED_10) || 1121 wb_data[1] = 0;
649 (vars->line_speed == SPEED_100))) { 1122 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
650 vars->phy_flags |= PHY_SGMII_FLAG; 1123 udelay(30);
651 } else { 1124 /* set cnt max size */
652 vars->phy_flags &= ~PHY_SGMII_FLAG; 1125 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
653 } 1126 wb_data[1] = 0;
654 } 1127 REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
1128 udelay(30);
1129 bnx2x_update_pfc_bmac2(params, vars, is_lb);
655 1130
656 /* anything 10 and over uses the bmac */ 1131 return 0;
657 link_10g = ((vars->line_speed == SPEED_10000) || 1132}
658 (vars->line_speed == SPEED_12000) ||
659 (vars->line_speed == SPEED_12500) ||
660 (vars->line_speed == SPEED_13000) ||
661 (vars->line_speed == SPEED_15000) ||
662 (vars->line_speed == SPEED_16000));
663 if (link_10g)
664 vars->mac_type = MAC_TYPE_BMAC;
665 else
666 vars->mac_type = MAC_TYPE_EMAC;
667 1133
668 } else { /* link down */ 1134static u8 bnx2x_bmac_enable(struct link_params *params,
669 DP(NETIF_MSG_LINK, "phy link down\n"); 1135 struct link_vars *vars,
1136 u8 is_lb)
1137{
1138 u8 rc, port = params->port;
1139 struct bnx2x *bp = params->bp;
1140 u32 val;
1141 /* reset and unreset the BigMac */
1142 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1143 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1144 msleep(1);
670 1145
671 vars->phy_link_up = 0; 1146 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1147 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
672 1148
673 vars->line_speed = 0; 1149 /* enable access for bmac registers */
674 vars->duplex = DUPLEX_FULL; 1150 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
675 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
676 1151
677 /* indicate no mac active */ 1152 /* Enable BMAC according to BMAC type*/
678 vars->mac_type = MAC_TYPE_NONE; 1153 if (CHIP_IS_E2(bp))
679 } 1154 rc = bnx2x_bmac2_enable(params, vars, is_lb);
1155 else
1156 rc = bnx2x_bmac1_enable(params, vars, is_lb);
1157 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
1158 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
1159 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
1160 val = 0;
1161 if ((params->feature_config_flags &
1162 FEATURE_CONFIG_PFC_ENABLED) ||
1163 (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1164 val = 1;
1165 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
1166 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
1167 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
1168 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
1169 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
1170 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
680 1171
681 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n", 1172 vars->mac_type = MAC_TYPE_BMAC;
682 vars->link_status, vars->phy_link_up); 1173 return rc;
683 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
684 vars->line_speed, vars->duplex, vars->flow_ctrl);
685} 1174}
686 1175
1176
687static void bnx2x_update_mng(struct link_params *params, u32 link_status) 1177static void bnx2x_update_mng(struct link_params *params, u32 link_status)
688{ 1178{
689 struct bnx2x *bp = params->bp; 1179 struct bnx2x *bp = params->bp;
690 1180
691 REG_WR(bp, params->shmem_base + 1181 REG_WR(bp, params->shmem_base +
692 offsetof(struct shmem_region, 1182 offsetof(struct shmem_region,
693 port_mb[params->port].link_status), 1183 port_mb[params->port].link_status), link_status);
694 link_status);
695} 1184}
696 1185
697static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port) 1186static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
698{ 1187{
699 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM : 1188 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
700 NIG_REG_INGRESS_BMAC0_MEM; 1189 NIG_REG_INGRESS_BMAC0_MEM;
701 u32 wb_data[2]; 1190 u32 wb_data[2];
702 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4); 1191 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
703 1192
@@ -706,19 +1195,31 @@ static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
706 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) && 1195 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
707 nig_bmac_enable) { 1196 nig_bmac_enable) {
708 1197
709 /* Clear Rx Enable bit in BMAC_CONTROL register */ 1198 if (CHIP_IS_E2(bp)) {
710 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, 1199 /* Clear Rx Enable bit in BMAC_CONTROL register */
711 wb_data, 2); 1200 REG_RD_DMAE(bp, bmac_addr +
712 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE; 1201 BIGMAC2_REGISTER_BMAC_CONTROL,
713 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, 1202 wb_data, 2);
714 wb_data, 2); 1203 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
715 1204 REG_WR_DMAE(bp, bmac_addr +
1205 BIGMAC2_REGISTER_BMAC_CONTROL,
1206 wb_data, 2);
1207 } else {
1208 /* Clear Rx Enable bit in BMAC_CONTROL register */
1209 REG_RD_DMAE(bp, bmac_addr +
1210 BIGMAC_REGISTER_BMAC_CONTROL,
1211 wb_data, 2);
1212 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
1213 REG_WR_DMAE(bp, bmac_addr +
1214 BIGMAC_REGISTER_BMAC_CONTROL,
1215 wb_data, 2);
1216 }
716 msleep(1); 1217 msleep(1);
717 } 1218 }
718} 1219}
719 1220
720static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl, 1221static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
721 u32 line_speed) 1222 u32 line_speed)
722{ 1223{
723 struct bnx2x *bp = params->bp; 1224 struct bnx2x *bp = params->bp;
724 u8 port = params->port; 1225 u8 port = params->port;
@@ -755,7 +1256,7 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
755 /* update threshold */ 1256 /* update threshold */
756 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0); 1257 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
757 /* update init credit */ 1258 /* update init credit */
758 init_crd = 778; /* (800-18-4) */ 1259 init_crd = 778; /* (800-18-4) */
759 1260
760 } else { 1261 } else {
761 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE + 1262 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
@@ -800,62 +1301,86 @@ static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
800 return 0; 1301 return 0;
801} 1302}
802 1303
803static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port) 1304/**
1305 * bnx2x_get_emac_base - retrive emac base address
1306 *
1307 * @bp: driver handle
1308 * @mdc_mdio_access: access type
1309 * @port: port id
1310 *
1311 * This function selects the MDC/MDIO access (through emac0 or
1312 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
1313 * phy has a default access mode, which could also be overridden
1314 * by nvram configuration. This parameter, whether this is the
1315 * default phy configuration, or the nvram overrun
1316 * configuration, is passed here as mdc_mdio_access and selects
1317 * the emac_base for the CL45 read/writes operations
1318 */
1319static u32 bnx2x_get_emac_base(struct bnx2x *bp,
1320 u32 mdc_mdio_access, u8 port)
804{ 1321{
805 u32 emac_base; 1322 u32 emac_base = 0;
806 1323 switch (mdc_mdio_access) {
807 switch (ext_phy_type) { 1324 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
808 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 1325 break;
809 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 1326 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
810 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 1327 if (REG_RD(bp, NIG_REG_PORT_SWAP))
811 /* All MDC/MDIO is directed through single EMAC */ 1328 emac_base = GRCBASE_EMAC1;
1329 else
1330 emac_base = GRCBASE_EMAC0;
1331 break;
1332 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
812 if (REG_RD(bp, NIG_REG_PORT_SWAP)) 1333 if (REG_RD(bp, NIG_REG_PORT_SWAP))
813 emac_base = GRCBASE_EMAC0; 1334 emac_base = GRCBASE_EMAC0;
814 else 1335 else
815 emac_base = GRCBASE_EMAC1; 1336 emac_base = GRCBASE_EMAC1;
816 break; 1337 break;
817 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 1338 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
1339 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1340 break;
1341 case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
818 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1; 1342 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
819 break; 1343 break;
820 default: 1344 default:
821 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
822 break; 1345 break;
823 } 1346 }
824 return emac_base; 1347 return emac_base;
825 1348
826} 1349}
827 1350
828u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type, 1351/******************************************************************/
829 u8 phy_addr, u8 devad, u16 reg, u16 val) 1352/* CL45 access functions */
1353/******************************************************************/
1354static u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
1355 u8 devad, u16 reg, u16 val)
830{ 1356{
831 u32 tmp, saved_mode; 1357 u32 tmp, saved_mode;
832 u8 i, rc = 0; 1358 u8 i, rc = 0;
833 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); 1359 /*
834 1360 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
835 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
836 * (a value of 49==0x31) and make sure that the AUTO poll is off 1361 * (a value of 49==0x31) and make sure that the AUTO poll is off
837 */ 1362 */
838 1363
839 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 1364 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
840 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL | 1365 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
841 EMAC_MDIO_MODE_CLOCK_CNT); 1366 EMAC_MDIO_MODE_CLOCK_CNT);
842 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 | 1367 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
843 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); 1368 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
844 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp); 1369 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
845 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 1370 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
846 udelay(40); 1371 udelay(40);
847 1372
848 /* address */ 1373 /* address */
849 1374
850 tmp = ((phy_addr << 21) | (devad << 16) | reg | 1375 tmp = ((phy->addr << 21) | (devad << 16) | reg |
851 EMAC_MDIO_COMM_COMMAND_ADDRESS | 1376 EMAC_MDIO_COMM_COMMAND_ADDRESS |
852 EMAC_MDIO_COMM_START_BUSY); 1377 EMAC_MDIO_COMM_START_BUSY);
853 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); 1378 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
854 1379
855 for (i = 0; i < 50; i++) { 1380 for (i = 0; i < 50; i++) {
856 udelay(10); 1381 udelay(10);
857 1382
858 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 1383 tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
859 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { 1384 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
860 udelay(5); 1385 udelay(5);
861 break; 1386 break;
@@ -863,19 +1388,20 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
863 } 1388 }
864 if (tmp & EMAC_MDIO_COMM_START_BUSY) { 1389 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
865 DP(NETIF_MSG_LINK, "write phy register failed\n"); 1390 DP(NETIF_MSG_LINK, "write phy register failed\n");
1391 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
866 rc = -EFAULT; 1392 rc = -EFAULT;
867 } else { 1393 } else {
868 /* data */ 1394 /* data */
869 tmp = ((phy_addr << 21) | (devad << 16) | val | 1395 tmp = ((phy->addr << 21) | (devad << 16) | val |
870 EMAC_MDIO_COMM_COMMAND_WRITE_45 | 1396 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
871 EMAC_MDIO_COMM_START_BUSY); 1397 EMAC_MDIO_COMM_START_BUSY);
872 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp); 1398 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
873 1399
874 for (i = 0; i < 50; i++) { 1400 for (i = 0; i < 50; i++) {
875 udelay(10); 1401 udelay(10);
876 1402
877 tmp = REG_RD(bp, mdio_ctrl + 1403 tmp = REG_RD(bp, phy->mdio_ctrl +
878 EMAC_REG_EMAC_MDIO_COMM); 1404 EMAC_REG_EMAC_MDIO_COMM);
879 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) { 1405 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
880 udelay(5); 1406 udelay(5);
881 break; 1407 break;
@@ -883,47 +1409,47 @@ u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
883 } 1409 }
884 if (tmp & EMAC_MDIO_COMM_START_BUSY) { 1410 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
885 DP(NETIF_MSG_LINK, "write phy register failed\n"); 1411 DP(NETIF_MSG_LINK, "write phy register failed\n");
1412 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
886 rc = -EFAULT; 1413 rc = -EFAULT;
887 } 1414 }
888 } 1415 }
889 1416
890 /* Restore the saved mode */ 1417 /* Restore the saved mode */
891 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); 1418 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
892 1419
893 return rc; 1420 return rc;
894} 1421}
895 1422
896u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type, 1423static u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
897 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val) 1424 u8 devad, u16 reg, u16 *ret_val)
898{ 1425{
899 u32 val, saved_mode; 1426 u32 val, saved_mode;
900 u16 i; 1427 u16 i;
901 u8 rc = 0; 1428 u8 rc = 0;
902 1429 /*
903 u32 mdio_ctrl = bnx2x_get_emac_base(bp, ext_phy_type, port); 1430 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
904 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
905 * (a value of 49==0x31) and make sure that the AUTO poll is off 1431 * (a value of 49==0x31) and make sure that the AUTO poll is off
906 */ 1432 */
907 1433
908 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 1434 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
909 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL | 1435 val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
910 EMAC_MDIO_MODE_CLOCK_CNT)); 1436 EMAC_MDIO_MODE_CLOCK_CNT));
911 val |= (EMAC_MDIO_MODE_CLAUSE_45 | 1437 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
912 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT)); 1438 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
913 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val); 1439 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
914 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE); 1440 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
915 udelay(40); 1441 udelay(40);
916 1442
917 /* address */ 1443 /* address */
918 val = ((phy_addr << 21) | (devad << 16) | reg | 1444 val = ((phy->addr << 21) | (devad << 16) | reg |
919 EMAC_MDIO_COMM_COMMAND_ADDRESS | 1445 EMAC_MDIO_COMM_COMMAND_ADDRESS |
920 EMAC_MDIO_COMM_START_BUSY); 1446 EMAC_MDIO_COMM_START_BUSY);
921 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); 1447 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
922 1448
923 for (i = 0; i < 50; i++) { 1449 for (i = 0; i < 50; i++) {
924 udelay(10); 1450 udelay(10);
925 1451
926 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM); 1452 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
927 if (!(val & EMAC_MDIO_COMM_START_BUSY)) { 1453 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
928 udelay(5); 1454 udelay(5);
929 break; 1455 break;
@@ -931,22 +1457,22 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
931 } 1457 }
932 if (val & EMAC_MDIO_COMM_START_BUSY) { 1458 if (val & EMAC_MDIO_COMM_START_BUSY) {
933 DP(NETIF_MSG_LINK, "read phy register failed\n"); 1459 DP(NETIF_MSG_LINK, "read phy register failed\n");
934 1460 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
935 *ret_val = 0; 1461 *ret_val = 0;
936 rc = -EFAULT; 1462 rc = -EFAULT;
937 1463
938 } else { 1464 } else {
939 /* data */ 1465 /* data */
940 val = ((phy_addr << 21) | (devad << 16) | 1466 val = ((phy->addr << 21) | (devad << 16) |
941 EMAC_MDIO_COMM_COMMAND_READ_45 | 1467 EMAC_MDIO_COMM_COMMAND_READ_45 |
942 EMAC_MDIO_COMM_START_BUSY); 1468 EMAC_MDIO_COMM_START_BUSY);
943 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val); 1469 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
944 1470
945 for (i = 0; i < 50; i++) { 1471 for (i = 0; i < 50; i++) {
946 udelay(10); 1472 udelay(10);
947 1473
948 val = REG_RD(bp, mdio_ctrl + 1474 val = REG_RD(bp, phy->mdio_ctrl +
949 EMAC_REG_EMAC_MDIO_COMM); 1475 EMAC_REG_EMAC_MDIO_COMM);
950 if (!(val & EMAC_MDIO_COMM_START_BUSY)) { 1476 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
951 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA); 1477 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
952 break; 1478 break;
@@ -954,91 +1480,314 @@ u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
954 } 1480 }
955 if (val & EMAC_MDIO_COMM_START_BUSY) { 1481 if (val & EMAC_MDIO_COMM_START_BUSY) {
956 DP(NETIF_MSG_LINK, "read phy register failed\n"); 1482 DP(NETIF_MSG_LINK, "read phy register failed\n");
957 1483 netdev_err(bp->dev, "MDC/MDIO access timeout\n");
958 *ret_val = 0; 1484 *ret_val = 0;
959 rc = -EFAULT; 1485 rc = -EFAULT;
960 } 1486 }
961 } 1487 }
962 1488
963 /* Restore the saved mode */ 1489 /* Restore the saved mode */
964 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode); 1490 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
965 1491
966 return rc; 1492 return rc;
967} 1493}
968 1494
969static void bnx2x_set_aer_mmd(struct link_params *params, 1495u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
970 struct link_vars *vars) 1496 u8 devad, u16 reg, u16 *ret_val)
971{ 1497{
972 struct bnx2x *bp = params->bp; 1498 u8 phy_index;
973 u32 ser_lane; 1499 /*
974 u16 offset; 1500 * Probe for the phy according to the given phy_addr, and execute
1501 * the read request on it
1502 */
1503 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1504 if (params->phy[phy_index].addr == phy_addr) {
1505 return bnx2x_cl45_read(params->bp,
1506 &params->phy[phy_index], devad,
1507 reg, ret_val);
1508 }
1509 }
1510 return -EINVAL;
1511}
1512
1513u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
1514 u8 devad, u16 reg, u16 val)
1515{
1516 u8 phy_index;
1517 /*
1518 * Probe for the phy according to the given phy_addr, and execute
1519 * the write request on it
1520 */
1521 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
1522 if (params->phy[phy_index].addr == phy_addr) {
1523 return bnx2x_cl45_write(params->bp,
1524 &params->phy[phy_index], devad,
1525 reg, val);
1526 }
1527 }
1528 return -EINVAL;
1529}
975 1530
1531static void bnx2x_set_aer_mmd_xgxs(struct link_params *params,
1532 struct bnx2x_phy *phy)
1533{
1534 u32 ser_lane;
1535 u16 offset, aer_val;
1536 struct bnx2x *bp = params->bp;
976 ser_lane = ((params->lane_config & 1537 ser_lane = ((params->lane_config &
977 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 1538 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
978 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 1539 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
979 1540
980 offset = (vars->phy_flags & PHY_XGXS_FLAG) ? 1541 offset = phy->addr + ser_lane;
981 (params->phy_addr + ser_lane) : 0; 1542 if (CHIP_IS_E2(bp))
1543 aer_val = 0x3800 + offset - 1;
1544 else
1545 aer_val = 0x3800 + offset;
1546 CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
1547 MDIO_AER_BLOCK_AER_REG, aer_val);
1548}
1549static void bnx2x_set_aer_mmd_serdes(struct bnx2x *bp,
1550 struct bnx2x_phy *phy)
1551{
1552 CL22_WR_OVER_CL45(bp, phy,
1553 MDIO_REG_BANK_AER_BLOCK,
1554 MDIO_AER_BLOCK_AER_REG, 0x3800);
1555}
1556
1557/******************************************************************/
1558/* Internal phy section */
1559/******************************************************************/
1560
1561static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
1562{
1563 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1564
1565 /* Set Clause 22 */
1566 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
1567 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
1568 udelay(500);
1569 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
1570 udelay(500);
1571 /* Set Clause 45 */
1572 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
1573}
1574
1575static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
1576{
1577 u32 val;
1578
1579 DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
1580
1581 val = SERDES_RESET_BITS << (port*16);
1582
1583 /* reset and unreset the SerDes/XGXS */
1584 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1585 udelay(500);
1586 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1587
1588 bnx2x_set_serdes_access(bp, port);
982 1589
983 CL45_WR_OVER_CL22(bp, params->port, 1590 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
984 params->phy_addr, 1591 DEFAULT_PHY_DEV_ADDR);
985 MDIO_REG_BANK_AER_BLOCK,
986 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
987} 1592}
988 1593
989static void bnx2x_set_master_ln(struct link_params *params) 1594static void bnx2x_xgxs_deassert(struct link_params *params)
1595{
1596 struct bnx2x *bp = params->bp;
1597 u8 port;
1598 u32 val;
1599 DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
1600 port = params->port;
1601
1602 val = XGXS_RESET_BITS << (port*16);
1603
1604 /* reset and unreset the SerDes/XGXS */
1605 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
1606 udelay(500);
1607 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
1608
1609 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
1610 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
1611 params->phy[INT_PHY].def_md_devad);
1612}
1613
1614
1615void bnx2x_link_status_update(struct link_params *params,
1616 struct link_vars *vars)
1617{
1618 struct bnx2x *bp = params->bp;
1619 u8 link_10g;
1620 u8 port = params->port;
1621
1622 vars->link_status = REG_RD(bp, params->shmem_base +
1623 offsetof(struct shmem_region,
1624 port_mb[port].link_status));
1625
1626 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
1627
1628 if (vars->link_up) {
1629 DP(NETIF_MSG_LINK, "phy link up\n");
1630
1631 vars->phy_link_up = 1;
1632 vars->duplex = DUPLEX_FULL;
1633 switch (vars->link_status &
1634 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
1635 case LINK_10THD:
1636 vars->duplex = DUPLEX_HALF;
1637 /* fall thru */
1638 case LINK_10TFD:
1639 vars->line_speed = SPEED_10;
1640 break;
1641
1642 case LINK_100TXHD:
1643 vars->duplex = DUPLEX_HALF;
1644 /* fall thru */
1645 case LINK_100T4:
1646 case LINK_100TXFD:
1647 vars->line_speed = SPEED_100;
1648 break;
1649
1650 case LINK_1000THD:
1651 vars->duplex = DUPLEX_HALF;
1652 /* fall thru */
1653 case LINK_1000TFD:
1654 vars->line_speed = SPEED_1000;
1655 break;
1656
1657 case LINK_2500THD:
1658 vars->duplex = DUPLEX_HALF;
1659 /* fall thru */
1660 case LINK_2500TFD:
1661 vars->line_speed = SPEED_2500;
1662 break;
1663
1664 case LINK_10GTFD:
1665 vars->line_speed = SPEED_10000;
1666 break;
1667
1668 case LINK_12GTFD:
1669 vars->line_speed = SPEED_12000;
1670 break;
1671
1672 case LINK_12_5GTFD:
1673 vars->line_speed = SPEED_12500;
1674 break;
1675
1676 case LINK_13GTFD:
1677 vars->line_speed = SPEED_13000;
1678 break;
1679
1680 case LINK_15GTFD:
1681 vars->line_speed = SPEED_15000;
1682 break;
1683
1684 case LINK_16GTFD:
1685 vars->line_speed = SPEED_16000;
1686 break;
1687
1688 default:
1689 break;
1690 }
1691 vars->flow_ctrl = 0;
1692 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
1693 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
1694
1695 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
1696 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
1697
1698 if (!vars->flow_ctrl)
1699 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1700
1701 if (vars->line_speed &&
1702 ((vars->line_speed == SPEED_10) ||
1703 (vars->line_speed == SPEED_100))) {
1704 vars->phy_flags |= PHY_SGMII_FLAG;
1705 } else {
1706 vars->phy_flags &= ~PHY_SGMII_FLAG;
1707 }
1708
1709 /* anything 10 and over uses the bmac */
1710 link_10g = ((vars->line_speed == SPEED_10000) ||
1711 (vars->line_speed == SPEED_12000) ||
1712 (vars->line_speed == SPEED_12500) ||
1713 (vars->line_speed == SPEED_13000) ||
1714 (vars->line_speed == SPEED_15000) ||
1715 (vars->line_speed == SPEED_16000));
1716 if (link_10g)
1717 vars->mac_type = MAC_TYPE_BMAC;
1718 else
1719 vars->mac_type = MAC_TYPE_EMAC;
1720
1721 } else { /* link down */
1722 DP(NETIF_MSG_LINK, "phy link down\n");
1723
1724 vars->phy_link_up = 0;
1725
1726 vars->line_speed = 0;
1727 vars->duplex = DUPLEX_FULL;
1728 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1729
1730 /* indicate no mac active */
1731 vars->mac_type = MAC_TYPE_NONE;
1732 }
1733
1734 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
1735 vars->link_status, vars->phy_link_up);
1736 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
1737 vars->line_speed, vars->duplex, vars->flow_ctrl);
1738}
1739
1740
1741static void bnx2x_set_master_ln(struct link_params *params,
1742 struct bnx2x_phy *phy)
990{ 1743{
991 struct bnx2x *bp = params->bp; 1744 struct bnx2x *bp = params->bp;
992 u16 new_master_ln, ser_lane; 1745 u16 new_master_ln, ser_lane;
993 ser_lane = ((params->lane_config & 1746 ser_lane = ((params->lane_config &
994 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 1747 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
995 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 1748 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
996 1749
997 /* set the master_ln for AN */ 1750 /* set the master_ln for AN */
998 CL45_RD_OVER_CL22(bp, params->port, 1751 CL22_RD_OVER_CL45(bp, phy,
999 params->phy_addr, 1752 MDIO_REG_BANK_XGXS_BLOCK2,
1000 MDIO_REG_BANK_XGXS_BLOCK2, 1753 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1001 MDIO_XGXS_BLOCK2_TEST_MODE_LANE, 1754 &new_master_ln);
1002 &new_master_ln); 1755
1003 1756 CL22_WR_OVER_CL45(bp, phy,
1004 CL45_WR_OVER_CL22(bp, params->port, 1757 MDIO_REG_BANK_XGXS_BLOCK2 ,
1005 params->phy_addr, 1758 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1006 MDIO_REG_BANK_XGXS_BLOCK2 , 1759 (new_master_ln | ser_lane));
1007 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1008 (new_master_ln | ser_lane));
1009} 1760}
1010 1761
1011static u8 bnx2x_reset_unicore(struct link_params *params) 1762static u8 bnx2x_reset_unicore(struct link_params *params,
1763 struct bnx2x_phy *phy,
1764 u8 set_serdes)
1012{ 1765{
1013 struct bnx2x *bp = params->bp; 1766 struct bnx2x *bp = params->bp;
1014 u16 mii_control; 1767 u16 mii_control;
1015 u16 i; 1768 u16 i;
1016 1769 CL22_RD_OVER_CL45(bp, phy,
1017 CL45_RD_OVER_CL22(bp, params->port, 1770 MDIO_REG_BANK_COMBO_IEEE0,
1018 params->phy_addr, 1771 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1019 MDIO_REG_BANK_COMBO_IEEE0,
1020 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1021 1772
1022 /* reset the unicore */ 1773 /* reset the unicore */
1023 CL45_WR_OVER_CL22(bp, params->port, 1774 CL22_WR_OVER_CL45(bp, phy,
1024 params->phy_addr, 1775 MDIO_REG_BANK_COMBO_IEEE0,
1025 MDIO_REG_BANK_COMBO_IEEE0, 1776 MDIO_COMBO_IEEE0_MII_CONTROL,
1026 MDIO_COMBO_IEEE0_MII_CONTROL, 1777 (mii_control |
1027 (mii_control | 1778 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
1028 MDIO_COMBO_IEEO_MII_CONTROL_RESET)); 1779 if (set_serdes)
1029 if (params->switch_cfg == SWITCH_CFG_1G) 1780 bnx2x_set_serdes_access(bp, params->port);
1030 bnx2x_set_serdes_access(params);
1031 1781
1032 /* wait for the reset to self clear */ 1782 /* wait for the reset to self clear */
1033 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) { 1783 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1034 udelay(5); 1784 udelay(5);
1035 1785
1036 /* the reset erased the previous bank value */ 1786 /* the reset erased the previous bank value */
1037 CL45_RD_OVER_CL22(bp, params->port, 1787 CL22_RD_OVER_CL45(bp, phy,
1038 params->phy_addr, 1788 MDIO_REG_BANK_COMBO_IEEE0,
1039 MDIO_REG_BANK_COMBO_IEEE0, 1789 MDIO_COMBO_IEEE0_MII_CONTROL,
1040 MDIO_COMBO_IEEE0_MII_CONTROL, 1790 &mii_control);
1041 &mii_control);
1042 1791
1043 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) { 1792 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1044 udelay(5); 1793 udelay(5);
@@ -1046,131 +1795,125 @@ static u8 bnx2x_reset_unicore(struct link_params *params)
1046 } 1795 }
1047 } 1796 }
1048 1797
1798 netdev_err(bp->dev, "Warning: PHY was not initialized,"
1799 " Port %d\n",
1800 params->port);
1049 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n"); 1801 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1050 return -EINVAL; 1802 return -EINVAL;
1051 1803
1052} 1804}
1053 1805
1054static void bnx2x_set_swap_lanes(struct link_params *params) 1806static void bnx2x_set_swap_lanes(struct link_params *params,
1807 struct bnx2x_phy *phy)
1055{ 1808{
1056 struct bnx2x *bp = params->bp; 1809 struct bnx2x *bp = params->bp;
1057 /* Each two bits represents a lane number: 1810 /*
1058 No swap is 0123 => 0x1b no need to enable the swap */ 1811 * Each two bits represents a lane number:
1812 * No swap is 0123 => 0x1b no need to enable the swap
1813 */
1059 u16 ser_lane, rx_lane_swap, tx_lane_swap; 1814 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1060 1815
1061 ser_lane = ((params->lane_config & 1816 ser_lane = ((params->lane_config &
1062 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >> 1817 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1063 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT); 1818 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1064 rx_lane_swap = ((params->lane_config & 1819 rx_lane_swap = ((params->lane_config &
1065 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >> 1820 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1066 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT); 1821 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1067 tx_lane_swap = ((params->lane_config & 1822 tx_lane_swap = ((params->lane_config &
1068 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >> 1823 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1069 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT); 1824 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1070 1825
1071 if (rx_lane_swap != 0x1b) { 1826 if (rx_lane_swap != 0x1b) {
1072 CL45_WR_OVER_CL22(bp, params->port, 1827 CL22_WR_OVER_CL45(bp, phy,
1073 params->phy_addr, 1828 MDIO_REG_BANK_XGXS_BLOCK2,
1074 MDIO_REG_BANK_XGXS_BLOCK2, 1829 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1075 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 1830 (rx_lane_swap |
1076 (rx_lane_swap | 1831 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1077 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE | 1832 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1078 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1079 } else { 1833 } else {
1080 CL45_WR_OVER_CL22(bp, params->port, 1834 CL22_WR_OVER_CL45(bp, phy,
1081 params->phy_addr, 1835 MDIO_REG_BANK_XGXS_BLOCK2,
1082 MDIO_REG_BANK_XGXS_BLOCK2, 1836 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1083 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1084 } 1837 }
1085 1838
1086 if (tx_lane_swap != 0x1b) { 1839 if (tx_lane_swap != 0x1b) {
1087 CL45_WR_OVER_CL22(bp, params->port, 1840 CL22_WR_OVER_CL45(bp, phy,
1088 params->phy_addr, 1841 MDIO_REG_BANK_XGXS_BLOCK2,
1089 MDIO_REG_BANK_XGXS_BLOCK2, 1842 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1090 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 1843 (tx_lane_swap |
1091 (tx_lane_swap | 1844 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1092 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1093 } else { 1845 } else {
1094 CL45_WR_OVER_CL22(bp, params->port, 1846 CL22_WR_OVER_CL45(bp, phy,
1095 params->phy_addr, 1847 MDIO_REG_BANK_XGXS_BLOCK2,
1096 MDIO_REG_BANK_XGXS_BLOCK2, 1848 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1097 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1098 } 1849 }
1099} 1850}
1100 1851
1101static void bnx2x_set_parallel_detection(struct link_params *params, 1852static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1102 u8 phy_flags) 1853 struct link_params *params)
1103{ 1854{
1104 struct bnx2x *bp = params->bp; 1855 struct bnx2x *bp = params->bp;
1105 u16 control2; 1856 u16 control2;
1106 1857 CL22_RD_OVER_CL45(bp, phy,
1107 CL45_RD_OVER_CL22(bp, params->port, 1858 MDIO_REG_BANK_SERDES_DIGITAL,
1108 params->phy_addr, 1859 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1109 MDIO_REG_BANK_SERDES_DIGITAL, 1860 &control2);
1110 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, 1861 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1111 &control2);
1112 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1113 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; 1862 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1114 else 1863 else
1115 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN; 1864 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1116 DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n", 1865 DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1117 params->speed_cap_mask, control2); 1866 phy->speed_cap_mask, control2);
1118 CL45_WR_OVER_CL22(bp, params->port, 1867 CL22_WR_OVER_CL45(bp, phy,
1119 params->phy_addr, 1868 MDIO_REG_BANK_SERDES_DIGITAL,
1120 MDIO_REG_BANK_SERDES_DIGITAL, 1869 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1121 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2, 1870 control2);
1122 control2); 1871
1123 1872 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
1124 if ((phy_flags & PHY_XGXS_FLAG) && 1873 (phy->speed_cap_mask &
1125 (params->speed_cap_mask &
1126 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) { 1874 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
1127 DP(NETIF_MSG_LINK, "XGXS\n"); 1875 DP(NETIF_MSG_LINK, "XGXS\n");
1128 1876
1129 CL45_WR_OVER_CL22(bp, params->port, 1877 CL22_WR_OVER_CL45(bp, phy,
1130 params->phy_addr, 1878 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1131 MDIO_REG_BANK_10G_PARALLEL_DETECT, 1879 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1132 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK, 1880 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1133 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1134 1881
1135 CL45_RD_OVER_CL22(bp, params->port, 1882 CL22_RD_OVER_CL45(bp, phy,
1136 params->phy_addr, 1883 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1137 MDIO_REG_BANK_10G_PARALLEL_DETECT, 1884 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1138 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, 1885 &control2);
1139 &control2);
1140 1886
1141 1887
1142 control2 |= 1888 control2 |=
1143 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN; 1889 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1144 1890
1145 CL45_WR_OVER_CL22(bp, params->port, 1891 CL22_WR_OVER_CL45(bp, phy,
1146 params->phy_addr, 1892 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1147 MDIO_REG_BANK_10G_PARALLEL_DETECT, 1893 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1148 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL, 1894 control2);
1149 control2);
1150 1895
1151 /* Disable parallel detection of HiG */ 1896 /* Disable parallel detection of HiG */
1152 CL45_WR_OVER_CL22(bp, params->port, 1897 CL22_WR_OVER_CL45(bp, phy,
1153 params->phy_addr, 1898 MDIO_REG_BANK_XGXS_BLOCK2,
1154 MDIO_REG_BANK_XGXS_BLOCK2, 1899 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1155 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G, 1900 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1156 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS | 1901 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1157 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1158 } 1902 }
1159} 1903}
1160 1904
1161static void bnx2x_set_autoneg(struct link_params *params, 1905static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1162 struct link_vars *vars, 1906 struct link_params *params,
1163 u8 enable_cl73) 1907 struct link_vars *vars,
1908 u8 enable_cl73)
1164{ 1909{
1165 struct bnx2x *bp = params->bp; 1910 struct bnx2x *bp = params->bp;
1166 u16 reg_val; 1911 u16 reg_val;
1167 1912
1168 /* CL37 Autoneg */ 1913 /* CL37 Autoneg */
1169 1914 CL22_RD_OVER_CL45(bp, phy,
1170 CL45_RD_OVER_CL22(bp, params->port, 1915 MDIO_REG_BANK_COMBO_IEEE0,
1171 params->phy_addr, 1916 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1172 MDIO_REG_BANK_COMBO_IEEE0,
1173 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1174 1917
1175 /* CL37 Autoneg Enabled */ 1918 /* CL37 Autoneg Enabled */
1176 if (vars->line_speed == SPEED_AUTO_NEG) 1919 if (vars->line_speed == SPEED_AUTO_NEG)
@@ -1179,17 +1922,15 @@ static void bnx2x_set_autoneg(struct link_params *params,
1179 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 1922 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1180 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN); 1923 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1181 1924
1182 CL45_WR_OVER_CL22(bp, params->port, 1925 CL22_WR_OVER_CL45(bp, phy,
1183 params->phy_addr, 1926 MDIO_REG_BANK_COMBO_IEEE0,
1184 MDIO_REG_BANK_COMBO_IEEE0, 1927 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1185 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1186 1928
1187 /* Enable/Disable Autodetection */ 1929 /* Enable/Disable Autodetection */
1188 1930
1189 CL45_RD_OVER_CL22(bp, params->port, 1931 CL22_RD_OVER_CL45(bp, phy,
1190 params->phy_addr, 1932 MDIO_REG_BANK_SERDES_DIGITAL,
1191 MDIO_REG_BANK_SERDES_DIGITAL, 1933 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1192 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1193 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN | 1934 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1194 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT); 1935 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1195 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE; 1936 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
@@ -1198,16 +1939,14 @@ static void bnx2x_set_autoneg(struct link_params *params,
1198 else 1939 else
1199 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET; 1940 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1200 1941
1201 CL45_WR_OVER_CL22(bp, params->port, 1942 CL22_WR_OVER_CL45(bp, phy,
1202 params->phy_addr, 1943 MDIO_REG_BANK_SERDES_DIGITAL,
1203 MDIO_REG_BANK_SERDES_DIGITAL, 1944 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1204 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1205 1945
1206 /* Enable TetonII and BAM autoneg */ 1946 /* Enable TetonII and BAM autoneg */
1207 CL45_RD_OVER_CL22(bp, params->port, 1947 CL22_RD_OVER_CL45(bp, phy,
1208 params->phy_addr, 1948 MDIO_REG_BANK_BAM_NEXT_PAGE,
1209 MDIO_REG_BANK_BAM_NEXT_PAGE, 1949 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1210 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1211 &reg_val); 1950 &reg_val);
1212 if (vars->line_speed == SPEED_AUTO_NEG) { 1951 if (vars->line_speed == SPEED_AUTO_NEG) {
1213 /* Enable BAM aneg Mode and TetonII aneg Mode */ 1952 /* Enable BAM aneg Mode and TetonII aneg Mode */
@@ -1218,23 +1957,20 @@ static void bnx2x_set_autoneg(struct link_params *params,
1218 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE | 1957 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1219 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN); 1958 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1220 } 1959 }
1221 CL45_WR_OVER_CL22(bp, params->port, 1960 CL22_WR_OVER_CL45(bp, phy,
1222 params->phy_addr, 1961 MDIO_REG_BANK_BAM_NEXT_PAGE,
1223 MDIO_REG_BANK_BAM_NEXT_PAGE, 1962 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1224 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL, 1963 reg_val);
1225 reg_val);
1226 1964
1227 if (enable_cl73) { 1965 if (enable_cl73) {
1228 /* Enable Cl73 FSM status bits */ 1966 /* Enable Cl73 FSM status bits */
1229 CL45_WR_OVER_CL22(bp, params->port, 1967 CL22_WR_OVER_CL45(bp, phy,
1230 params->phy_addr, 1968 MDIO_REG_BANK_CL73_USERB0,
1231 MDIO_REG_BANK_CL73_USERB0, 1969 MDIO_CL73_USERB0_CL73_UCTRL,
1232 MDIO_CL73_USERB0_CL73_UCTRL, 1970 0xe);
1233 0xe);
1234 1971
1235 /* Enable BAM Station Manager*/ 1972 /* Enable BAM Station Manager*/
1236 CL45_WR_OVER_CL22(bp, params->port, 1973 CL22_WR_OVER_CL45(bp, phy,
1237 params->phy_addr,
1238 MDIO_REG_BANK_CL73_USERB0, 1974 MDIO_REG_BANK_CL73_USERB0,
1239 MDIO_CL73_USERB0_CL73_BAM_CTRL1, 1975 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1240 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN | 1976 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
@@ -1242,23 +1978,21 @@ static void bnx2x_set_autoneg(struct link_params *params,
1242 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN); 1978 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1243 1979
1244 /* Advertise CL73 link speeds */ 1980 /* Advertise CL73 link speeds */
1245 CL45_RD_OVER_CL22(bp, params->port, 1981 CL22_RD_OVER_CL45(bp, phy,
1246 params->phy_addr, 1982 MDIO_REG_BANK_CL73_IEEEB1,
1247 MDIO_REG_BANK_CL73_IEEEB1, 1983 MDIO_CL73_IEEEB1_AN_ADV2,
1248 MDIO_CL73_IEEEB1_AN_ADV2, 1984 &reg_val);
1249 &reg_val); 1985 if (phy->speed_cap_mask &
1250 if (params->speed_cap_mask &
1251 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 1986 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1252 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4; 1987 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1253 if (params->speed_cap_mask & 1988 if (phy->speed_cap_mask &
1254 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) 1989 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1255 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX; 1990 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1256 1991
1257 CL45_WR_OVER_CL22(bp, params->port, 1992 CL22_WR_OVER_CL45(bp, phy,
1258 params->phy_addr, 1993 MDIO_REG_BANK_CL73_IEEEB1,
1259 MDIO_REG_BANK_CL73_IEEEB1, 1994 MDIO_CL73_IEEEB1_AN_ADV2,
1260 MDIO_CL73_IEEEB1_AN_ADV2, 1995 reg_val);
1261 reg_val);
1262 1996
1263 /* CL73 Autoneg Enabled */ 1997 /* CL73 Autoneg Enabled */
1264 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN; 1998 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
@@ -1266,40 +2000,39 @@ static void bnx2x_set_autoneg(struct link_params *params,
1266 } else /* CL73 Autoneg Disabled */ 2000 } else /* CL73 Autoneg Disabled */
1267 reg_val = 0; 2001 reg_val = 0;
1268 2002
1269 CL45_WR_OVER_CL22(bp, params->port, 2003 CL22_WR_OVER_CL45(bp, phy,
1270 params->phy_addr, 2004 MDIO_REG_BANK_CL73_IEEEB0,
1271 MDIO_REG_BANK_CL73_IEEEB0, 2005 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1272 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1273} 2006}
1274 2007
1275/* program SerDes, forced speed */ 2008/* program SerDes, forced speed */
1276static void bnx2x_program_serdes(struct link_params *params, 2009static void bnx2x_program_serdes(struct bnx2x_phy *phy,
1277 struct link_vars *vars) 2010 struct link_params *params,
2011 struct link_vars *vars)
1278{ 2012{
1279 struct bnx2x *bp = params->bp; 2013 struct bnx2x *bp = params->bp;
1280 u16 reg_val; 2014 u16 reg_val;
1281 2015
1282 /* program duplex, disable autoneg and sgmii*/ 2016 /* program duplex, disable autoneg and sgmii*/
1283 CL45_RD_OVER_CL22(bp, params->port, 2017 CL22_RD_OVER_CL45(bp, phy,
1284 params->phy_addr, 2018 MDIO_REG_BANK_COMBO_IEEE0,
1285 MDIO_REG_BANK_COMBO_IEEE0, 2019 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1286 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1287 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX | 2020 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1288 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 2021 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1289 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK); 2022 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
1290 if (params->req_duplex == DUPLEX_FULL) 2023 if (phy->req_duplex == DUPLEX_FULL)
1291 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; 2024 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1292 CL45_WR_OVER_CL22(bp, params->port, 2025 CL22_WR_OVER_CL45(bp, phy,
1293 params->phy_addr, 2026 MDIO_REG_BANK_COMBO_IEEE0,
1294 MDIO_REG_BANK_COMBO_IEEE0, 2027 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1295 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val); 2028
1296 2029 /*
1297 /* program speed 2030 * program speed
1298 - needed only if the speed is greater than 1G (2.5G or 10G) */ 2031 * - needed only if the speed is greater than 1G (2.5G or 10G)
1299 CL45_RD_OVER_CL22(bp, params->port, 2032 */
1300 params->phy_addr, 2033 CL22_RD_OVER_CL45(bp, phy,
1301 MDIO_REG_BANK_SERDES_DIGITAL, 2034 MDIO_REG_BANK_SERDES_DIGITAL,
1302 MDIO_SERDES_DIGITAL_MISC1, &reg_val); 2035 MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1303 /* clearing the speed value before setting the right speed */ 2036 /* clearing the speed value before setting the right speed */
1304 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val); 2037 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1305 2038
@@ -1320,14 +2053,14 @@ static void bnx2x_program_serdes(struct link_params *params,
1320 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G; 2053 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1321 } 2054 }
1322 2055
1323 CL45_WR_OVER_CL22(bp, params->port, 2056 CL22_WR_OVER_CL45(bp, phy,
1324 params->phy_addr, 2057 MDIO_REG_BANK_SERDES_DIGITAL,
1325 MDIO_REG_BANK_SERDES_DIGITAL, 2058 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1326 MDIO_SERDES_DIGITAL_MISC1, reg_val);
1327 2059
1328} 2060}
1329 2061
1330static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params) 2062static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
2063 struct link_params *params)
1331{ 2064{
1332 struct bnx2x *bp = params->bp; 2065 struct bnx2x *bp = params->bp;
1333 u16 val = 0; 2066 u16 val = 0;
@@ -1335,41 +2068,39 @@ static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1335 /* configure the 48 bits for BAM AN */ 2068 /* configure the 48 bits for BAM AN */
1336 2069
1337 /* set extended capabilities */ 2070 /* set extended capabilities */
1338 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) 2071 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1339 val |= MDIO_OVER_1G_UP1_2_5G; 2072 val |= MDIO_OVER_1G_UP1_2_5G;
1340 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) 2073 if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1341 val |= MDIO_OVER_1G_UP1_10G; 2074 val |= MDIO_OVER_1G_UP1_10G;
1342 CL45_WR_OVER_CL22(bp, params->port, 2075 CL22_WR_OVER_CL45(bp, phy,
1343 params->phy_addr, 2076 MDIO_REG_BANK_OVER_1G,
1344 MDIO_REG_BANK_OVER_1G, 2077 MDIO_OVER_1G_UP1, val);
1345 MDIO_OVER_1G_UP1, val);
1346 2078
1347 CL45_WR_OVER_CL22(bp, params->port, 2079 CL22_WR_OVER_CL45(bp, phy,
1348 params->phy_addr, 2080 MDIO_REG_BANK_OVER_1G,
1349 MDIO_REG_BANK_OVER_1G, 2081 MDIO_OVER_1G_UP3, 0x400);
1350 MDIO_OVER_1G_UP3, 0x400);
1351} 2082}
1352 2083
1353static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc) 2084static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
2085 struct link_params *params, u16 *ieee_fc)
1354{ 2086{
1355 struct bnx2x *bp = params->bp; 2087 struct bnx2x *bp = params->bp;
1356 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX; 2088 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1357 /* resolve pause mode and advertisement 2089 /*
1358 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */ 2090 * Resolve pause mode and advertisement.
2091 * Please refer to Table 28B-3 of the 802.3ab-1999 spec
2092 */
1359 2093
1360 switch (params->req_flow_ctrl) { 2094 switch (phy->req_flow_ctrl) {
1361 case BNX2X_FLOW_CTRL_AUTO: 2095 case BNX2X_FLOW_CTRL_AUTO:
1362 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) { 2096 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
1363 *ieee_fc |= 2097 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1364 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 2098 else
1365 } else {
1366 *ieee_fc |= 2099 *ieee_fc |=
1367 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 2100 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1368 }
1369 break; 2101 break;
1370 case BNX2X_FLOW_CTRL_TX: 2102 case BNX2X_FLOW_CTRL_TX:
1371 *ieee_fc |= 2103 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1372 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1373 break; 2104 break;
1374 2105
1375 case BNX2X_FLOW_CTRL_RX: 2106 case BNX2X_FLOW_CTRL_RX:
@@ -1385,30 +2116,30 @@ static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u16 *ieee_fc)
1385 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc); 2116 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
1386} 2117}
1387 2118
1388static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params, 2119static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
1389 u16 ieee_fc) 2120 struct link_params *params,
2121 u16 ieee_fc)
1390{ 2122{
1391 struct bnx2x *bp = params->bp; 2123 struct bnx2x *bp = params->bp;
1392 u16 val; 2124 u16 val;
1393 /* for AN, we are always publishing full duplex */ 2125 /* for AN, we are always publishing full duplex */
1394 2126
1395 CL45_WR_OVER_CL22(bp, params->port, 2127 CL22_WR_OVER_CL45(bp, phy,
1396 params->phy_addr, 2128 MDIO_REG_BANK_COMBO_IEEE0,
1397 MDIO_REG_BANK_COMBO_IEEE0, 2129 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
1398 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc); 2130 CL22_RD_OVER_CL45(bp, phy,
1399 CL45_RD_OVER_CL22(bp, params->port, 2131 MDIO_REG_BANK_CL73_IEEEB1,
1400 params->phy_addr, 2132 MDIO_CL73_IEEEB1_AN_ADV1, &val);
1401 MDIO_REG_BANK_CL73_IEEEB1,
1402 MDIO_CL73_IEEEB1_AN_ADV1, &val);
1403 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH; 2133 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
1404 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK); 2134 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
1405 CL45_WR_OVER_CL22(bp, params->port, 2135 CL22_WR_OVER_CL45(bp, phy,
1406 params->phy_addr, 2136 MDIO_REG_BANK_CL73_IEEEB1,
1407 MDIO_REG_BANK_CL73_IEEEB1, 2137 MDIO_CL73_IEEEB1_AN_ADV1, val);
1408 MDIO_CL73_IEEEB1_AN_ADV1, val);
1409} 2138}
1410 2139
1411static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73) 2140static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
2141 struct link_params *params,
2142 u8 enable_cl73)
1412{ 2143{
1413 struct bnx2x *bp = params->bp; 2144 struct bnx2x *bp = params->bp;
1414 u16 mii_control; 2145 u16 mii_control;
@@ -1417,73 +2148,67 @@ static void bnx2x_restart_autoneg(struct link_params *params, u8 enable_cl73)
1417 /* Enable and restart BAM/CL37 aneg */ 2148 /* Enable and restart BAM/CL37 aneg */
1418 2149
1419 if (enable_cl73) { 2150 if (enable_cl73) {
1420 CL45_RD_OVER_CL22(bp, params->port, 2151 CL22_RD_OVER_CL45(bp, phy,
1421 params->phy_addr, 2152 MDIO_REG_BANK_CL73_IEEEB0,
1422 MDIO_REG_BANK_CL73_IEEEB0, 2153 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1423 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 2154 &mii_control);
1424 &mii_control); 2155
1425 2156 CL22_WR_OVER_CL45(bp, phy,
1426 CL45_WR_OVER_CL22(bp, params->port, 2157 MDIO_REG_BANK_CL73_IEEEB0,
1427 params->phy_addr, 2158 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1428 MDIO_REG_BANK_CL73_IEEEB0, 2159 (mii_control |
1429 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 2160 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1430 (mii_control | 2161 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1431 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1432 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1433 } else { 2162 } else {
1434 2163
1435 CL45_RD_OVER_CL22(bp, params->port, 2164 CL22_RD_OVER_CL45(bp, phy,
1436 params->phy_addr, 2165 MDIO_REG_BANK_COMBO_IEEE0,
1437 MDIO_REG_BANK_COMBO_IEEE0, 2166 MDIO_COMBO_IEEE0_MII_CONTROL,
1438 MDIO_COMBO_IEEE0_MII_CONTROL, 2167 &mii_control);
1439 &mii_control);
1440 DP(NETIF_MSG_LINK, 2168 DP(NETIF_MSG_LINK,
1441 "bnx2x_restart_autoneg mii_control before = 0x%x\n", 2169 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1442 mii_control); 2170 mii_control);
1443 CL45_WR_OVER_CL22(bp, params->port, 2171 CL22_WR_OVER_CL45(bp, phy,
1444 params->phy_addr, 2172 MDIO_REG_BANK_COMBO_IEEE0,
1445 MDIO_REG_BANK_COMBO_IEEE0, 2173 MDIO_COMBO_IEEE0_MII_CONTROL,
1446 MDIO_COMBO_IEEE0_MII_CONTROL, 2174 (mii_control |
1447 (mii_control | 2175 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1448 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 2176 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1449 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1450 } 2177 }
1451} 2178}
1452 2179
1453static void bnx2x_initialize_sgmii_process(struct link_params *params, 2180static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
1454 struct link_vars *vars) 2181 struct link_params *params,
2182 struct link_vars *vars)
1455{ 2183{
1456 struct bnx2x *bp = params->bp; 2184 struct bnx2x *bp = params->bp;
1457 u16 control1; 2185 u16 control1;
1458 2186
1459 /* in SGMII mode, the unicore is always slave */ 2187 /* in SGMII mode, the unicore is always slave */
1460 2188
1461 CL45_RD_OVER_CL22(bp, params->port, 2189 CL22_RD_OVER_CL45(bp, phy,
1462 params->phy_addr, 2190 MDIO_REG_BANK_SERDES_DIGITAL,
1463 MDIO_REG_BANK_SERDES_DIGITAL, 2191 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1464 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, 2192 &control1);
1465 &control1);
1466 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT; 2193 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1467 /* set sgmii mode (and not fiber) */ 2194 /* set sgmii mode (and not fiber) */
1468 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE | 2195 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1469 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET | 2196 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1470 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE); 2197 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1471 CL45_WR_OVER_CL22(bp, params->port, 2198 CL22_WR_OVER_CL45(bp, phy,
1472 params->phy_addr, 2199 MDIO_REG_BANK_SERDES_DIGITAL,
1473 MDIO_REG_BANK_SERDES_DIGITAL, 2200 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1474 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, 2201 control1);
1475 control1);
1476 2202
1477 /* if forced speed */ 2203 /* if forced speed */
1478 if (!(vars->line_speed == SPEED_AUTO_NEG)) { 2204 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1479 /* set speed, disable autoneg */ 2205 /* set speed, disable autoneg */
1480 u16 mii_control; 2206 u16 mii_control;
1481 2207
1482 CL45_RD_OVER_CL22(bp, params->port, 2208 CL22_RD_OVER_CL45(bp, phy,
1483 params->phy_addr, 2209 MDIO_REG_BANK_COMBO_IEEE0,
1484 MDIO_REG_BANK_COMBO_IEEE0, 2210 MDIO_COMBO_IEEE0_MII_CONTROL,
1485 MDIO_COMBO_IEEE0_MII_CONTROL, 2211 &mii_control);
1486 &mii_control);
1487 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN | 2212 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1488 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK| 2213 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1489 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX); 2214 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
@@ -1508,18 +2233,17 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
1508 } 2233 }
1509 2234
1510 /* setting the full duplex */ 2235 /* setting the full duplex */
1511 if (params->req_duplex == DUPLEX_FULL) 2236 if (phy->req_duplex == DUPLEX_FULL)
1512 mii_control |= 2237 mii_control |=
1513 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX; 2238 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1514 CL45_WR_OVER_CL22(bp, params->port, 2239 CL22_WR_OVER_CL45(bp, phy,
1515 params->phy_addr, 2240 MDIO_REG_BANK_COMBO_IEEE0,
1516 MDIO_REG_BANK_COMBO_IEEE0, 2241 MDIO_COMBO_IEEE0_MII_CONTROL,
1517 MDIO_COMBO_IEEE0_MII_CONTROL, 2242 mii_control);
1518 mii_control);
1519 2243
1520 } else { /* AN mode */ 2244 } else { /* AN mode */
1521 /* enable and restart AN */ 2245 /* enable and restart AN */
1522 bnx2x_restart_autoneg(params, 0); 2246 bnx2x_restart_autoneg(phy, params, 0);
1523 } 2247 }
1524} 2248}
1525 2249
@@ -1530,124 +2254,56 @@ static void bnx2x_initialize_sgmii_process(struct link_params *params,
1530 2254
1531static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result) 2255static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1532{ /* LD LP */ 2256{ /* LD LP */
1533 switch (pause_result) { /* ASYM P ASYM P */ 2257 switch (pause_result) { /* ASYM P ASYM P */
1534 case 0xb: /* 1 0 1 1 */ 2258 case 0xb: /* 1 0 1 1 */
1535 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX; 2259 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1536 break; 2260 break;
1537 2261
1538 case 0xe: /* 1 1 1 0 */ 2262 case 0xe: /* 1 1 1 0 */
1539 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX; 2263 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1540 break; 2264 break;
1541 2265
1542 case 0x5: /* 0 1 0 1 */ 2266 case 0x5: /* 0 1 0 1 */
1543 case 0x7: /* 0 1 1 1 */ 2267 case 0x7: /* 0 1 1 1 */
1544 case 0xd: /* 1 1 0 1 */ 2268 case 0xd: /* 1 1 0 1 */
1545 case 0xf: /* 1 1 1 1 */ 2269 case 0xf: /* 1 1 1 1 */
1546 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH; 2270 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1547 break; 2271 break;
1548 2272
1549 default: 2273 default:
1550 break; 2274 break;
1551 } 2275 }
2276 if (pause_result & (1<<0))
2277 vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
2278 if (pause_result & (1<<1))
2279 vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
1552} 2280}
1553 2281
1554static u8 bnx2x_ext_phy_resolve_fc(struct link_params *params, 2282static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
1555 struct link_vars *vars) 2283 struct link_params *params)
1556{
1557 struct bnx2x *bp = params->bp;
1558 u8 ext_phy_addr;
1559 u16 ld_pause; /* local */
1560 u16 lp_pause; /* link partner */
1561 u16 an_complete; /* AN complete */
1562 u16 pause_result;
1563 u8 ret = 0;
1564 u32 ext_phy_type;
1565 u8 port = params->port;
1566 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
1567 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1568 /* read twice */
1569
1570 bnx2x_cl45_read(bp, port,
1571 ext_phy_type,
1572 ext_phy_addr,
1573 MDIO_AN_DEVAD,
1574 MDIO_AN_REG_STATUS, &an_complete);
1575 bnx2x_cl45_read(bp, port,
1576 ext_phy_type,
1577 ext_phy_addr,
1578 MDIO_AN_DEVAD,
1579 MDIO_AN_REG_STATUS, &an_complete);
1580
1581 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1582 ret = 1;
1583 bnx2x_cl45_read(bp, port,
1584 ext_phy_type,
1585 ext_phy_addr,
1586 MDIO_AN_DEVAD,
1587 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1588 bnx2x_cl45_read(bp, port,
1589 ext_phy_type,
1590 ext_phy_addr,
1591 MDIO_AN_DEVAD,
1592 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1593 pause_result = (ld_pause &
1594 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1595 pause_result |= (lp_pause &
1596 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1597 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
1598 pause_result);
1599 bnx2x_pause_resolve(vars, pause_result);
1600 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1601 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1602 bnx2x_cl45_read(bp, port,
1603 ext_phy_type,
1604 ext_phy_addr,
1605 MDIO_AN_DEVAD,
1606 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1607
1608 bnx2x_cl45_read(bp, port,
1609 ext_phy_type,
1610 ext_phy_addr,
1611 MDIO_AN_DEVAD,
1612 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1613 pause_result = (ld_pause &
1614 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1615 pause_result |= (lp_pause &
1616 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1617
1618 bnx2x_pause_resolve(vars, pause_result);
1619 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
1620 pause_result);
1621 }
1622 }
1623 return ret;
1624}
1625
1626static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
1627{ 2284{
1628 struct bnx2x *bp = params->bp; 2285 struct bnx2x *bp = params->bp;
1629 u16 pd_10g, status2_1000x; 2286 u16 pd_10g, status2_1000x;
1630 CL45_RD_OVER_CL22(bp, params->port, 2287 if (phy->req_line_speed != SPEED_AUTO_NEG)
1631 params->phy_addr, 2288 return 0;
1632 MDIO_REG_BANK_SERDES_DIGITAL, 2289 CL22_RD_OVER_CL45(bp, phy,
1633 MDIO_SERDES_DIGITAL_A_1000X_STATUS2, 2290 MDIO_REG_BANK_SERDES_DIGITAL,
1634 &status2_1000x); 2291 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1635 CL45_RD_OVER_CL22(bp, params->port, 2292 &status2_1000x);
1636 params->phy_addr, 2293 CL22_RD_OVER_CL45(bp, phy,
1637 MDIO_REG_BANK_SERDES_DIGITAL, 2294 MDIO_REG_BANK_SERDES_DIGITAL,
1638 MDIO_SERDES_DIGITAL_A_1000X_STATUS2, 2295 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1639 &status2_1000x); 2296 &status2_1000x);
1640 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) { 2297 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
1641 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n", 2298 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
1642 params->port); 2299 params->port);
1643 return 1; 2300 return 1;
1644 } 2301 }
1645 2302
1646 CL45_RD_OVER_CL22(bp, params->port, 2303 CL22_RD_OVER_CL45(bp, phy,
1647 params->phy_addr, 2304 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1648 MDIO_REG_BANK_10G_PARALLEL_DETECT, 2305 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
1649 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS, 2306 &pd_10g);
1650 &pd_10g);
1651 2307
1652 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) { 2308 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
1653 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n", 2309 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
@@ -1657,9 +2313,10 @@ static u8 bnx2x_direct_parallel_detect_used(struct link_params *params)
1657 return 0; 2313 return 0;
1658} 2314}
1659 2315
1660static void bnx2x_flow_ctrl_resolve(struct link_params *params, 2316static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
1661 struct link_vars *vars, 2317 struct link_params *params,
1662 u32 gp_status) 2318 struct link_vars *vars,
2319 u32 gp_status)
1663{ 2320{
1664 struct bnx2x *bp = params->bp; 2321 struct bnx2x *bp = params->bp;
1665 u16 ld_pause; /* local driver */ 2322 u16 ld_pause; /* local driver */
@@ -1669,12 +2326,13 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1669 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 2326 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1670 2327
1671 /* resolve from gp_status in case of AN complete and not sgmii */ 2328 /* resolve from gp_status in case of AN complete and not sgmii */
1672 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) && 2329 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
1673 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) && 2330 vars->flow_ctrl = phy->req_flow_ctrl;
1674 (!(vars->phy_flags & PHY_SGMII_FLAG)) && 2331 else if (phy->req_line_speed != SPEED_AUTO_NEG)
1675 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 2332 vars->flow_ctrl = params->req_fc_auto_adv;
1676 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) { 2333 else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1677 if (bnx2x_direct_parallel_detect_used(params)) { 2334 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
2335 if (bnx2x_direct_parallel_detect_used(phy, params)) {
1678 vars->flow_ctrl = params->req_fc_auto_adv; 2336 vars->flow_ctrl = params->req_fc_auto_adv;
1679 return; 2337 return;
1680 } 2338 }
@@ -1684,16 +2342,14 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1684 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | 2342 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1685 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) { 2343 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
1686 2344
1687 CL45_RD_OVER_CL22(bp, params->port, 2345 CL22_RD_OVER_CL45(bp, phy,
1688 params->phy_addr, 2346 MDIO_REG_BANK_CL73_IEEEB1,
1689 MDIO_REG_BANK_CL73_IEEEB1, 2347 MDIO_CL73_IEEEB1_AN_ADV1,
1690 MDIO_CL73_IEEEB1_AN_ADV1, 2348 &ld_pause);
1691 &ld_pause); 2349 CL22_RD_OVER_CL45(bp, phy,
1692 CL45_RD_OVER_CL22(bp, params->port, 2350 MDIO_REG_BANK_CL73_IEEEB1,
1693 params->phy_addr, 2351 MDIO_CL73_IEEEB1_AN_LP_ADV1,
1694 MDIO_REG_BANK_CL73_IEEEB1, 2352 &lp_pause);
1695 MDIO_CL73_IEEEB1_AN_LP_ADV1,
1696 &lp_pause);
1697 pause_result = (ld_pause & 2353 pause_result = (ld_pause &
1698 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) 2354 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
1699 >> 8; 2355 >> 8;
@@ -1703,65 +2359,52 @@ static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1703 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", 2359 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
1704 pause_result); 2360 pause_result);
1705 } else { 2361 } else {
1706 2362 CL22_RD_OVER_CL45(bp, phy,
1707 CL45_RD_OVER_CL22(bp, params->port, 2363 MDIO_REG_BANK_COMBO_IEEE0,
1708 params->phy_addr, 2364 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1709 MDIO_REG_BANK_COMBO_IEEE0, 2365 &ld_pause);
1710 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, 2366 CL22_RD_OVER_CL45(bp, phy,
1711 &ld_pause); 2367 MDIO_REG_BANK_COMBO_IEEE0,
1712 CL45_RD_OVER_CL22(bp, params->port, 2368 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1713 params->phy_addr, 2369 &lp_pause);
1714 MDIO_REG_BANK_COMBO_IEEE0,
1715 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1716 &lp_pause);
1717 pause_result = (ld_pause & 2370 pause_result = (ld_pause &
1718 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5; 2371 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1719 pause_result |= (lp_pause & 2372 pause_result |= (lp_pause &
1720 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7; 2373 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1721 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", 2374 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
1722 pause_result); 2375 pause_result);
1723 } 2376 }
1724 bnx2x_pause_resolve(vars, pause_result); 2377 bnx2x_pause_resolve(vars, pause_result);
1725 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1726 (bnx2x_ext_phy_resolve_fc(params, vars))) {
1727 return;
1728 } else {
1729 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1730 vars->flow_ctrl = params->req_fc_auto_adv;
1731 else
1732 vars->flow_ctrl = params->req_flow_ctrl;
1733 } 2378 }
1734 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl); 2379 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1735} 2380}
1736 2381
1737static void bnx2x_check_fallback_to_cl37(struct link_params *params) 2382static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
2383 struct link_params *params)
1738{ 2384{
1739 struct bnx2x *bp = params->bp; 2385 struct bnx2x *bp = params->bp;
1740 u16 rx_status, ustat_val, cl37_fsm_recieved; 2386 u16 rx_status, ustat_val, cl37_fsm_recieved;
1741 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n"); 2387 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
1742 /* Step 1: Make sure signal is detected */ 2388 /* Step 1: Make sure signal is detected */
1743 CL45_RD_OVER_CL22(bp, params->port, 2389 CL22_RD_OVER_CL45(bp, phy,
1744 params->phy_addr, 2390 MDIO_REG_BANK_RX0,
1745 MDIO_REG_BANK_RX0, 2391 MDIO_RX0_RX_STATUS,
1746 MDIO_RX0_RX_STATUS, 2392 &rx_status);
1747 &rx_status);
1748 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) != 2393 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
1749 (MDIO_RX0_RX_STATUS_SIGDET)) { 2394 (MDIO_RX0_RX_STATUS_SIGDET)) {
1750 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73." 2395 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
1751 "rx_status(0x80b0) = 0x%x\n", rx_status); 2396 "rx_status(0x80b0) = 0x%x\n", rx_status);
1752 CL45_WR_OVER_CL22(bp, params->port, 2397 CL22_WR_OVER_CL45(bp, phy,
1753 params->phy_addr, 2398 MDIO_REG_BANK_CL73_IEEEB0,
1754 MDIO_REG_BANK_CL73_IEEEB0, 2399 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1755 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 2400 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1756 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1757 return; 2401 return;
1758 } 2402 }
1759 /* Step 2: Check CL73 state machine */ 2403 /* Step 2: Check CL73 state machine */
1760 CL45_RD_OVER_CL22(bp, params->port, 2404 CL22_RD_OVER_CL45(bp, phy,
1761 params->phy_addr, 2405 MDIO_REG_BANK_CL73_USERB0,
1762 MDIO_REG_BANK_CL73_USERB0, 2406 MDIO_CL73_USERB0_CL73_USTAT1,
1763 MDIO_CL73_USERB0_CL73_USTAT1, 2407 &ustat_val);
1764 &ustat_val);
1765 if ((ustat_val & 2408 if ((ustat_val &
1766 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK | 2409 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1767 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) != 2410 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
@@ -1771,13 +2414,14 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
1771 "ustat_val(0x8371) = 0x%x\n", ustat_val); 2414 "ustat_val(0x8371) = 0x%x\n", ustat_val);
1772 return; 2415 return;
1773 } 2416 }
1774 /* Step 3: Check CL37 Message Pages received to indicate LP 2417 /*
1775 supports only CL37 */ 2418 * Step 3: Check CL37 Message Pages received to indicate LP
1776 CL45_RD_OVER_CL22(bp, params->port, 2419 * supports only CL37
1777 params->phy_addr, 2420 */
1778 MDIO_REG_BANK_REMOTE_PHY, 2421 CL22_RD_OVER_CL45(bp, phy,
1779 MDIO_REMOTE_PHY_MISC_RX_STATUS, 2422 MDIO_REG_BANK_REMOTE_PHY,
1780 &cl37_fsm_recieved); 2423 MDIO_REMOTE_PHY_MISC_RX_STATUS,
2424 &cl37_fsm_recieved);
1781 if ((cl37_fsm_recieved & 2425 if ((cl37_fsm_recieved &
1782 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG | 2426 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1783 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) != 2427 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
@@ -1788,29 +2432,53 @@ static void bnx2x_check_fallback_to_cl37(struct link_params *params)
1788 cl37_fsm_recieved); 2432 cl37_fsm_recieved);
1789 return; 2433 return;
1790 } 2434 }
1791 /* The combined cl37/cl73 fsm state information indicating that we are 2435 /*
1792 connected to a device which does not support cl73, but does support 2436 * The combined cl37/cl73 fsm state information indicating that
1793 cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */ 2437 * we are connected to a device which does not support cl73, but
2438 * does support cl37 BAM. In this case we disable cl73 and
2439 * restart cl37 auto-neg
2440 */
2441
1794 /* Disable CL73 */ 2442 /* Disable CL73 */
1795 CL45_WR_OVER_CL22(bp, params->port, 2443 CL22_WR_OVER_CL45(bp, phy,
1796 params->phy_addr, 2444 MDIO_REG_BANK_CL73_IEEEB0,
1797 MDIO_REG_BANK_CL73_IEEEB0, 2445 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1798 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, 2446 0);
1799 0);
1800 /* Restart CL37 autoneg */ 2447 /* Restart CL37 autoneg */
1801 bnx2x_restart_autoneg(params, 0); 2448 bnx2x_restart_autoneg(phy, params, 0);
1802 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n"); 2449 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
1803} 2450}
1804static u8 bnx2x_link_settings_status(struct link_params *params, 2451
1805 struct link_vars *vars, 2452static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
1806 u32 gp_status, 2453 struct link_params *params,
1807 u8 ext_phy_link_up) 2454 struct link_vars *vars,
2455 u32 gp_status)
2456{
2457 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
2458 vars->link_status |=
2459 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
2460
2461 if (bnx2x_direct_parallel_detect_used(phy, params))
2462 vars->link_status |=
2463 LINK_STATUS_PARALLEL_DETECTION_USED;
2464}
2465
2466static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
2467 struct link_params *params,
2468 struct link_vars *vars)
1808{ 2469{
1809 struct bnx2x *bp = params->bp; 2470 struct bnx2x *bp = params->bp;
1810 u16 new_line_speed; 2471 u16 new_line_speed, gp_status;
1811 u8 rc = 0; 2472 u8 rc = 0;
1812 vars->link_status = 0;
1813 2473
2474 /* Read gp_status */
2475 CL22_RD_OVER_CL45(bp, phy,
2476 MDIO_REG_BANK_GP_STATUS,
2477 MDIO_GP_STATUS_TOP_AN_STATUS1,
2478 &gp_status);
2479
2480 if (phy->req_line_speed == SPEED_AUTO_NEG)
2481 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
1814 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) { 2482 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1815 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n", 2483 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1816 gp_status); 2484 gp_status);
@@ -1823,7 +2491,12 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1823 else 2491 else
1824 vars->duplex = DUPLEX_HALF; 2492 vars->duplex = DUPLEX_HALF;
1825 2493
1826 bnx2x_flow_ctrl_resolve(params, vars, gp_status); 2494 if (SINGLE_MEDIA_DIRECT(params)) {
2495 bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
2496 if (phy->req_line_speed == SPEED_AUTO_NEG)
2497 bnx2x_xgxs_an_resolve(phy, params, vars,
2498 gp_status);
2499 }
1827 2500
1828 switch (gp_status & GP_STATUS_SPEED_MASK) { 2501 switch (gp_status & GP_STATUS_SPEED_MASK) {
1829 case GP_STATUS_10M: 2502 case GP_STATUS_10M:
@@ -1905,56 +2578,7 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1905 return -EINVAL; 2578 return -EINVAL;
1906 } 2579 }
1907 2580
1908 /* Upon link speed change set the NIG into drain mode.
1909 Comes to deals with possible FIFO glitch due to clk change
1910 when speed is decreased without link down indicator */
1911 if (new_line_speed != vars->line_speed) {
1912 if (XGXS_EXT_PHY_TYPE(params->ext_phy_config) !=
1913 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT &&
1914 ext_phy_link_up) {
1915 DP(NETIF_MSG_LINK, "Internal link speed %d is"
1916 " different than the external"
1917 " link speed %d\n", new_line_speed,
1918 vars->line_speed);
1919 vars->phy_link_up = 0;
1920 return 0;
1921 }
1922 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1923 + params->port*4, 0);
1924 msleep(1);
1925 }
1926 vars->line_speed = new_line_speed; 2581 vars->line_speed = new_line_speed;
1927 vars->link_status |= LINK_STATUS_SERDES_LINK;
1928
1929 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1930 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1931 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1932 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1933 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
1934 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1935 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
1936 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1937 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
1938 vars->autoneg = AUTO_NEG_ENABLED;
1939
1940 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1941 vars->autoneg |= AUTO_NEG_COMPLETE;
1942 vars->link_status |=
1943 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1944 }
1945
1946 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1947 vars->link_status |=
1948 LINK_STATUS_PARALLEL_DETECTION_USED;
1949
1950 }
1951 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1952 vars->link_status |=
1953 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1954
1955 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1956 vars->link_status |=
1957 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1958 2582
1959 } else { /* link_down */ 2583 } else { /* link_down */
1960 DP(NETIF_MSG_LINK, "phy link down\n"); 2584 DP(NETIF_MSG_LINK, "phy link down\n");
@@ -1963,40 +2587,34 @@ static u8 bnx2x_link_settings_status(struct link_params *params,
1963 2587
1964 vars->duplex = DUPLEX_FULL; 2588 vars->duplex = DUPLEX_FULL;
1965 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 2589 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1966 vars->autoneg = AUTO_NEG_DISABLED;
1967 vars->mac_type = MAC_TYPE_NONE; 2590 vars->mac_type = MAC_TYPE_NONE;
1968 2591
1969 if ((params->req_line_speed == SPEED_AUTO_NEG) && 2592 if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
1970 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 2593 SINGLE_MEDIA_DIRECT(params)) {
1971 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT))) {
1972 /* Check signal is detected */ 2594 /* Check signal is detected */
1973 bnx2x_check_fallback_to_cl37(params); 2595 bnx2x_check_fallback_to_cl37(phy, params);
1974 } 2596 }
1975 } 2597 }
1976 2598
1977 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n", 2599 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n",
1978 gp_status, vars->phy_link_up, vars->line_speed); 2600 gp_status, vars->phy_link_up, vars->line_speed);
1979 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x" 2601 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x link_status 0x%x\n",
1980 " autoneg 0x%x\n", 2602 vars->duplex, vars->flow_ctrl, vars->link_status);
1981 vars->duplex,
1982 vars->flow_ctrl, vars->autoneg);
1983 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1984
1985 return rc; 2603 return rc;
1986} 2604}
1987 2605
1988static void bnx2x_set_gmii_tx_driver(struct link_params *params) 2606static void bnx2x_set_gmii_tx_driver(struct link_params *params)
1989{ 2607{
1990 struct bnx2x *bp = params->bp; 2608 struct bnx2x *bp = params->bp;
2609 struct bnx2x_phy *phy = &params->phy[INT_PHY];
1991 u16 lp_up2; 2610 u16 lp_up2;
1992 u16 tx_driver; 2611 u16 tx_driver;
1993 u16 bank; 2612 u16 bank;
1994 2613
1995 /* read precomp */ 2614 /* read precomp */
1996 CL45_RD_OVER_CL22(bp, params->port, 2615 CL22_RD_OVER_CL45(bp, phy,
1997 params->phy_addr, 2616 MDIO_REG_BANK_OVER_1G,
1998 MDIO_REG_BANK_OVER_1G, 2617 MDIO_OVER_1G_LP_UP2, &lp_up2);
1999 MDIO_OVER_1G_LP_UP2, &lp_up2);
2000 2618
2001 /* bits [10:7] at lp_up2, positioned at [15:12] */ 2619 /* bits [10:7] at lp_up2, positioned at [15:12] */
2002 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >> 2620 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
@@ -2008,26 +2626,24 @@ static void bnx2x_set_gmii_tx_driver(struct link_params *params)
2008 2626
2009 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3; 2627 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
2010 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) { 2628 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
2011 CL45_RD_OVER_CL22(bp, params->port, 2629 CL22_RD_OVER_CL45(bp, phy,
2012 params->phy_addr, 2630 bank,
2013 bank, 2631 MDIO_TX0_TX_DRIVER, &tx_driver);
2014 MDIO_TX0_TX_DRIVER, &tx_driver);
2015 2632
2016 /* replace tx_driver bits [15:12] */ 2633 /* replace tx_driver bits [15:12] */
2017 if (lp_up2 != 2634 if (lp_up2 !=
2018 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) { 2635 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
2019 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK; 2636 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
2020 tx_driver |= lp_up2; 2637 tx_driver |= lp_up2;
2021 CL45_WR_OVER_CL22(bp, params->port, 2638 CL22_WR_OVER_CL45(bp, phy,
2022 params->phy_addr, 2639 bank,
2023 bank, 2640 MDIO_TX0_TX_DRIVER, tx_driver);
2024 MDIO_TX0_TX_DRIVER, tx_driver);
2025 } 2641 }
2026 } 2642 }
2027} 2643}
2028 2644
2029static u8 bnx2x_emac_program(struct link_params *params, 2645static u8 bnx2x_emac_program(struct link_params *params,
2030 u32 line_speed, u32 duplex) 2646 struct link_vars *vars)
2031{ 2647{
2032 struct bnx2x *bp = params->bp; 2648 struct bnx2x *bp = params->bp;
2033 u8 port = params->port; 2649 u8 port = params->port;
@@ -2035,11 +2651,11 @@ static u8 bnx2x_emac_program(struct link_params *params,
2035 2651
2036 DP(NETIF_MSG_LINK, "setting link speed & duplex\n"); 2652 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
2037 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 + 2653 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
2038 EMAC_REG_EMAC_MODE, 2654 EMAC_REG_EMAC_MODE,
2039 (EMAC_MODE_25G_MODE | 2655 (EMAC_MODE_25G_MODE |
2040 EMAC_MODE_PORT_MII_10M | 2656 EMAC_MODE_PORT_MII_10M |
2041 EMAC_MODE_HALF_DUPLEX)); 2657 EMAC_MODE_HALF_DUPLEX));
2042 switch (line_speed) { 2658 switch (vars->line_speed) {
2043 case SPEED_10: 2659 case SPEED_10:
2044 mode |= EMAC_MODE_PORT_MII_10M; 2660 mode |= EMAC_MODE_PORT_MII_10M;
2045 break; 2661 break;
@@ -2058,384 +2674,1276 @@ static u8 bnx2x_emac_program(struct link_params *params,
2058 2674
2059 default: 2675 default:
2060 /* 10G not valid for EMAC */ 2676 /* 10G not valid for EMAC */
2061 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed); 2677 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2678 vars->line_speed);
2062 return -EINVAL; 2679 return -EINVAL;
2063 } 2680 }
2064 2681
2065 if (duplex == DUPLEX_HALF) 2682 if (vars->duplex == DUPLEX_HALF)
2066 mode |= EMAC_MODE_HALF_DUPLEX; 2683 mode |= EMAC_MODE_HALF_DUPLEX;
2067 bnx2x_bits_en(bp, 2684 bnx2x_bits_en(bp,
2068 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE, 2685 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2069 mode); 2686 mode);
2070 2687
2071 bnx2x_set_led(params, LED_MODE_OPER, line_speed); 2688 bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
2072 return 0; 2689 return 0;
2073} 2690}
2074 2691
2075/*****************************************************************************/ 2692static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
2076/* External Phy section */ 2693 struct link_params *params)
2077/*****************************************************************************/
2078void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
2079{ 2694{
2080 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2695
2081 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 2696 u16 bank, i = 0;
2082 msleep(1); 2697 struct bnx2x *bp = params->bp;
2083 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2698
2084 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); 2699 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
2700 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
2701 CL22_WR_OVER_CL45(bp, phy,
2702 bank,
2703 MDIO_RX0_RX_EQ_BOOST,
2704 phy->rx_preemphasis[i]);
2705 }
2706
2707 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
2708 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
2709 CL22_WR_OVER_CL45(bp, phy,
2710 bank,
2711 MDIO_TX0_TX_DRIVER,
2712 phy->tx_preemphasis[i]);
2713 }
2085} 2714}
2086 2715
2087static void bnx2x_ext_phy_reset(struct link_params *params, 2716static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
2088 struct link_vars *vars) 2717 struct link_params *params,
2718 struct link_vars *vars)
2089{ 2719{
2090 struct bnx2x *bp = params->bp; 2720 struct bnx2x *bp = params->bp;
2091 u32 ext_phy_type; 2721 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
2092 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 2722 (params->loopback_mode == LOOPBACK_XGXS));
2723 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2724 if (SINGLE_MEDIA_DIRECT(params) &&
2725 (params->feature_config_flags &
2726 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
2727 bnx2x_set_preemphasis(phy, params);
2093 2728
2094 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port); 2729 /* forced speed requested? */
2095 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 2730 if (vars->line_speed != SPEED_AUTO_NEG ||
2096 /* The PHY reset is controled by GPIO 1 2731 (SINGLE_MEDIA_DIRECT(params) &&
2097 * Give it 1ms of reset pulse 2732 params->loopback_mode == LOOPBACK_EXT)) {
2098 */ 2733 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2099 if (vars->phy_flags & PHY_XGXS_FLAG) {
2100 2734
2101 switch (ext_phy_type) { 2735 /* disable autoneg */
2102 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 2736 bnx2x_set_autoneg(phy, params, vars, 0);
2103 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2104 break;
2105 2737
2106 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 2738 /* program speed and duplex */
2107 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 2739 bnx2x_program_serdes(phy, params, vars);
2108 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
2109 2740
2110 /* Restore normal power mode*/ 2741 } else { /* AN_mode */
2111 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2742 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2112 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2113 params->port);
2114 2743
2115 /* HW reset */ 2744 /* AN enabled */
2116 bnx2x_ext_phy_hw_reset(bp, params->port); 2745 bnx2x_set_brcm_cl37_advertisment(phy, params);
2117 2746
2118 bnx2x_cl45_write(bp, params->port, 2747 /* program duplex & pause advertisement (for aneg) */
2119 ext_phy_type, 2748 bnx2x_set_ieee_aneg_advertisment(phy, params,
2120 ext_phy_addr, 2749 vars->ieee_fc);
2121 MDIO_PMA_DEVAD,
2122 MDIO_PMA_REG_CTRL, 0xa040);
2123 break;
2124 2750
2125 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 2751 /* enable autoneg */
2126 break; 2752 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
2127 2753
2128 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 2754 /* enable and restart AN */
2755 bnx2x_restart_autoneg(phy, params, enable_cl73);
2756 }
2129 2757
2130 /* Restore normal power mode*/ 2758 } else { /* SGMII mode */
2131 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2759 DP(NETIF_MSG_LINK, "SGMII\n");
2132 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2133 params->port);
2134 2760
2135 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2761 bnx2x_initialize_sgmii_process(phy, params, vars);
2136 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 2762 }
2137 params->port); 2763}
2138 2764
2139 bnx2x_cl45_write(bp, params->port, 2765static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2140 ext_phy_type, 2766 struct link_params *params,
2141 ext_phy_addr, 2767 struct link_vars *vars)
2142 MDIO_PMA_DEVAD, 2768{
2143 MDIO_PMA_REG_CTRL, 2769 u8 rc;
2144 1<<15); 2770 vars->phy_flags |= PHY_SGMII_FLAG;
2145 break; 2771 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2772 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2773 rc = bnx2x_reset_unicore(params, phy, 1);
2774 /* reset the SerDes and wait for reset bit return low */
2775 if (rc != 0)
2776 return rc;
2777 bnx2x_set_aer_mmd_serdes(params->bp, phy);
2146 2778
2147 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 2779 return rc;
2148 DP(NETIF_MSG_LINK, "XGXS 8072\n"); 2780}
2149
2150 /* Unset Low Power Mode and SW reset */
2151 /* Restore normal power mode*/
2152 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
2153 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
2154 params->port);
2155
2156 bnx2x_cl45_write(bp, params->port,
2157 ext_phy_type,
2158 ext_phy_addr,
2159 MDIO_PMA_DEVAD,
2160 MDIO_PMA_REG_CTRL,
2161 1<<15);
2162 break;
2163 2781
2164 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 2782static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2165 DP(NETIF_MSG_LINK, "XGXS 8073\n"); 2783 struct link_params *params,
2784 struct link_vars *vars)
2785{
2786 u8 rc;
2787 vars->phy_flags = PHY_XGXS_FLAG;
2788 if ((phy->req_line_speed &&
2789 ((phy->req_line_speed == SPEED_100) ||
2790 (phy->req_line_speed == SPEED_10))) ||
2791 (!phy->req_line_speed &&
2792 (phy->speed_cap_mask >=
2793 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2794 (phy->speed_cap_mask <
2795 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2796 ))
2797 vars->phy_flags |= PHY_SGMII_FLAG;
2798 else
2799 vars->phy_flags &= ~PHY_SGMII_FLAG;
2166 2800
2167 /* Restore normal power mode*/ 2801 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2168 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2802 bnx2x_set_aer_mmd_xgxs(params, phy);
2169 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 2803 bnx2x_set_master_ln(params, phy);
2170 params->port);
2171 2804
2172 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1, 2805 rc = bnx2x_reset_unicore(params, phy, 0);
2173 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 2806 /* reset the SerDes and wait for reset bit return low */
2174 params->port); 2807 if (rc != 0)
2175 break; 2808 return rc;
2176 2809
2177 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 2810 bnx2x_set_aer_mmd_xgxs(params, phy);
2178 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
2179 2811
2180 /* Restore normal power mode*/ 2812 /* setting the masterLn_def again after the reset */
2181 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2813 bnx2x_set_master_ln(params, phy);
2182 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 2814 bnx2x_set_swap_lanes(params, phy);
2183 params->port);
2184 2815
2185 /* HW reset */ 2816 return rc;
2186 bnx2x_ext_phy_hw_reset(bp, params->port); 2817}
2187 break;
2188 2818
2189 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481: 2819static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
2190 /* Restore normal power mode*/ 2820 struct bnx2x_phy *phy,
2191 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 2821 struct link_params *params)
2192 MISC_REGISTERS_GPIO_OUTPUT_HIGH, 2822{
2193 params->port); 2823 u16 cnt, ctrl;
2194 2824 /* Wait for soft reset to get cleared up to 1 sec */
2195 /* HW reset */ 2825 for (cnt = 0; cnt < 1000; cnt++) {
2196 bnx2x_ext_phy_hw_reset(bp, params->port); 2826 bnx2x_cl45_read(bp, phy,
2197 2827 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
2198 bnx2x_cl45_write(bp, params->port, 2828 if (!(ctrl & (1<<15)))
2199 ext_phy_type,
2200 ext_phy_addr,
2201 MDIO_PMA_DEVAD,
2202 MDIO_PMA_REG_CTRL,
2203 1<<15);
2204 break;
2205 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
2206 break;
2207 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2208 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
2209 break; 2829 break;
2830 msleep(1);
2831 }
2210 2832
2211 default: 2833 if (cnt == 1000)
2212 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", 2834 netdev_err(bp->dev, "Warning: PHY was not initialized,"
2213 params->ext_phy_config); 2835 " Port %d\n",
2214 break; 2836 params->port);
2837 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
2838 return cnt;
2839}
2840
2841static void bnx2x_link_int_enable(struct link_params *params)
2842{
2843 u8 port = params->port;
2844 u32 mask;
2845 struct bnx2x *bp = params->bp;
2846
2847 /* Setting the status to report on link up for either XGXS or SerDes */
2848 if (params->switch_cfg == SWITCH_CFG_10G) {
2849 mask = (NIG_MASK_XGXS0_LINK10G |
2850 NIG_MASK_XGXS0_LINK_STATUS);
2851 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
2852 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2853 params->phy[INT_PHY].type !=
2854 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
2855 mask |= NIG_MASK_MI_INT;
2856 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2215 } 2857 }
2216 2858
2217 } else { /* SerDes */ 2859 } else { /* SerDes */
2218 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 2860 mask = NIG_MASK_SERDES0_LINK_STATUS;
2219 switch (ext_phy_type) { 2861 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
2220 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: 2862 if (!(SINGLE_MEDIA_DIRECT(params)) &&
2221 DP(NETIF_MSG_LINK, "SerDes Direct\n"); 2863 params->phy[INT_PHY].type !=
2222 break; 2864 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
2865 mask |= NIG_MASK_MI_INT;
2866 DP(NETIF_MSG_LINK, "enabled external phy int\n");
2867 }
2868 }
2869 bnx2x_bits_en(bp,
2870 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
2871 mask);
2872
2873 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
2874 (params->switch_cfg == SWITCH_CFG_10G),
2875 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
2876 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
2877 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
2878 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
2879 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
2880 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
2881 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
2882 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
2883}
2884
2885static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
2886 u8 exp_mi_int)
2887{
2888 u32 latch_status = 0;
2889
2890 /*
2891 * Disable the MI INT ( external phy int ) by writing 1 to the
2892 * status register. Link down indication is high-active-signal,
2893 * so in this case we need to write the status to clear the XOR
2894 */
2895 /* Read Latched signals */
2896 latch_status = REG_RD(bp,
2897 NIG_REG_LATCH_STATUS_0 + port*8);
2898 DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
2899 /* Handle only those with latched-signal=up.*/
2900 if (exp_mi_int)
2901 bnx2x_bits_en(bp,
2902 NIG_REG_STATUS_INTERRUPT_PORT0
2903 + port*4,
2904 NIG_STATUS_EMAC0_MI_INT);
2905 else
2906 bnx2x_bits_dis(bp,
2907 NIG_REG_STATUS_INTERRUPT_PORT0
2908 + port*4,
2909 NIG_STATUS_EMAC0_MI_INT);
2910
2911 if (latch_status & 1) {
2912
2913 /* For all latched-signal=up : Re-Arm Latch signals */
2914 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
2915 (latch_status & 0xfffe) | (latch_status & 1));
2916 }
2917 /* For all latched-signal=up,Write original_signal to status */
2918}
2919
2920static void bnx2x_link_int_ack(struct link_params *params,
2921 struct link_vars *vars, u8 is_10g)
2922{
2923 struct bnx2x *bp = params->bp;
2924 u8 port = params->port;
2925
2926 /*
2927 * First reset all status we assume only one line will be
2928 * change at a time
2929 */
2930 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2931 (NIG_STATUS_XGXS0_LINK10G |
2932 NIG_STATUS_XGXS0_LINK_STATUS |
2933 NIG_STATUS_SERDES0_LINK_STATUS));
2934 if (vars->phy_link_up) {
2935 if (is_10g) {
2936 /*
2937 * Disable the 10G link interrupt by writing 1 to the
2938 * status register
2939 */
2940 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
2941 bnx2x_bits_en(bp,
2942 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2943 NIG_STATUS_XGXS0_LINK10G);
2944
2945 } else if (params->switch_cfg == SWITCH_CFG_10G) {
2946 /*
2947 * Disable the link interrupt by writing 1 to the
2948 * relevant lane in the status register
2949 */
2950 u32 ser_lane = ((params->lane_config &
2951 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2952 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2953
2954 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
2955 vars->line_speed);
2956 bnx2x_bits_en(bp,
2957 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2958 ((1 << ser_lane) <<
2959 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
2960
2961 } else { /* SerDes */
2962 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
2963 /*
2964 * Disable the link interrupt by writing 1 to the status
2965 * register
2966 */
2967 bnx2x_bits_en(bp,
2968 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
2969 NIG_STATUS_SERDES0_LINK_STATUS);
2970 }
2971
2972 }
2973}
2974
2975static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
2976{
2977 u8 *str_ptr = str;
2978 u32 mask = 0xf0000000;
2979 u8 shift = 8*4;
2980 u8 digit;
2981 u8 remove_leading_zeros = 1;
2982 if (*len < 10) {
2983 /* Need more than 10chars for this format */
2984 *str_ptr = '\0';
2985 (*len)--;
2986 return -EINVAL;
2987 }
2988 while (shift > 0) {
2989
2990 shift -= 4;
2991 digit = ((num & mask) >> shift);
2992 if (digit == 0 && remove_leading_zeros) {
2993 mask = mask >> 4;
2994 continue;
2995 } else if (digit < 0xa)
2996 *str_ptr = digit + '0';
2997 else
2998 *str_ptr = digit - 0xa + 'a';
2999 remove_leading_zeros = 0;
3000 str_ptr++;
3001 (*len)--;
3002 mask = mask >> 4;
3003 if (shift == 4*4) {
3004 *str_ptr = '.';
3005 str_ptr++;
3006 (*len)--;
3007 remove_leading_zeros = 1;
3008 }
3009 }
3010 return 0;
3011}
3012
3013
3014static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
3015{
3016 str[0] = '\0';
3017 (*len)--;
3018 return 0;
3019}
3020
3021u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3022 u8 *version, u16 len)
3023{
3024 struct bnx2x *bp;
3025 u32 spirom_ver = 0;
3026 u8 status = 0;
3027 u8 *ver_p = version;
3028 u16 remain_len = len;
3029 if (version == NULL || params == NULL)
3030 return -EINVAL;
3031 bp = params->bp;
3032
3033 /* Extract first external phy*/
3034 version[0] = '\0';
3035 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
3036
3037 if (params->phy[EXT_PHY1].format_fw_ver) {
3038 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
3039 ver_p,
3040 &remain_len);
3041 ver_p += (len - remain_len);
3042 }
3043 if ((params->num_phys == MAX_PHYS) &&
3044 (params->phy[EXT_PHY2].ver_addr != 0)) {
3045 spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
3046 if (params->phy[EXT_PHY2].format_fw_ver) {
3047 *ver_p = '/';
3048 ver_p++;
3049 remain_len--;
3050 status |= params->phy[EXT_PHY2].format_fw_ver(
3051 spirom_ver,
3052 ver_p,
3053 &remain_len);
3054 ver_p = version + (len - remain_len);
3055 }
3056 }
3057 *ver_p = '\0';
3058 return status;
3059}
3060
3061static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
3062 struct link_params *params)
3063{
3064 u8 port = params->port;
3065 struct bnx2x *bp = params->bp;
2223 3066
2224 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: 3067 if (phy->req_line_speed != SPEED_1000) {
2225 DP(NETIF_MSG_LINK, "SerDes 5482\n"); 3068 u32 md_devad;
2226 bnx2x_ext_phy_hw_reset(bp, params->port); 3069
3070 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3071
3072 /* change the uni_phy_addr in the nig */
3073 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3074 port*0x18));
3075
3076 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3077
3078 bnx2x_cl45_write(bp, phy,
3079 5,
3080 (MDIO_REG_BANK_AER_BLOCK +
3081 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3082 0x2800);
3083
3084 bnx2x_cl45_write(bp, phy,
3085 5,
3086 (MDIO_REG_BANK_CL73_IEEEB0 +
3087 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3088 0x6041);
3089 msleep(200);
3090 /* set aer mmd back */
3091 bnx2x_set_aer_mmd_xgxs(params, phy);
3092
3093 /* and md_devad */
3094 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, md_devad);
3095 } else {
3096 u16 mii_ctrl;
3097 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3098 bnx2x_cl45_read(bp, phy, 5,
3099 (MDIO_REG_BANK_COMBO_IEEE0 +
3100 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3101 &mii_ctrl);
3102 bnx2x_cl45_write(bp, phy, 5,
3103 (MDIO_REG_BANK_COMBO_IEEE0 +
3104 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
3105 mii_ctrl |
3106 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
3107 }
3108}
3109
3110u8 bnx2x_set_led(struct link_params *params,
3111 struct link_vars *vars, u8 mode, u32 speed)
3112{
3113 u8 port = params->port;
3114 u16 hw_led_mode = params->hw_led_mode;
3115 u8 rc = 0, phy_idx;
3116 u32 tmp;
3117 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3118 struct bnx2x *bp = params->bp;
3119 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3120 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3121 speed, hw_led_mode);
3122 /* In case */
3123 for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
3124 if (params->phy[phy_idx].set_link_led) {
3125 params->phy[phy_idx].set_link_led(
3126 &params->phy[phy_idx], params, mode);
3127 }
3128 }
3129
3130 switch (mode) {
3131 case LED_MODE_FRONT_PANEL_OFF:
3132 case LED_MODE_OFF:
3133 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3134 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3135 SHARED_HW_CFG_LED_MAC1);
3136
3137 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3138 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3139 break;
3140
3141 case LED_MODE_OPER:
3142 /*
3143 * For all other phys, OPER mode is same as ON, so in case
3144 * link is down, do nothing
3145 */
3146 if (!vars->link_up)
2227 break; 3147 break;
3148 case LED_MODE_ON:
3149 if (params->phy[EXT_PHY1].type ==
3150 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727 &&
3151 CHIP_IS_E2(bp) && params->num_phys == 2) {
3152 /*
3153 * This is a work-around for E2+8727 Configurations
3154 */
3155 if (mode == LED_MODE_ON ||
3156 speed == SPEED_10000){
3157 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3158 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3159
3160 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3161 EMAC_WR(bp, EMAC_REG_EMAC_LED,
3162 (tmp | EMAC_LED_OVERRIDE));
3163 return rc;
3164 }
3165 } else if (SINGLE_MEDIA_DIRECT(params)) {
3166 /*
3167 * This is a work-around for HW issue found when link
3168 * is up in CL73
3169 */
3170 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
3171 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
3172 } else {
3173 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3174 }
2228 3175
2229 default: 3176 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
2230 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", 3177 /* Set blinking rate to ~15.9Hz */
2231 params->ext_phy_config); 3178 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3179 LED_BLINK_RATE_VAL);
3180 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3181 port*4, 1);
3182 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3183 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
3184
3185 if (CHIP_IS_E1(bp) &&
3186 ((speed == SPEED_2500) ||
3187 (speed == SPEED_1000) ||
3188 (speed == SPEED_100) ||
3189 (speed == SPEED_10))) {
3190 /*
3191 * On Everest 1 Ax chip versions for speeds less than
3192 * 10G LED scheme is different
3193 */
3194 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3195 + port*4, 1);
3196 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3197 port*4, 0);
3198 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3199 port*4, 1);
3200 }
3201 break;
3202
3203 default:
3204 rc = -EINVAL;
3205 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3206 mode);
3207 break;
3208 }
3209 return rc;
3210
3211}
3212
3213/*
3214 * This function comes to reflect the actual link state read DIRECTLY from the
3215 * HW
3216 */
3217u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars,
3218 u8 is_serdes)
3219{
3220 struct bnx2x *bp = params->bp;
3221 u16 gp_status = 0, phy_index = 0;
3222 u8 ext_phy_link_up = 0, serdes_phy_type;
3223 struct link_vars temp_vars;
3224
3225 CL22_RD_OVER_CL45(bp, &params->phy[INT_PHY],
3226 MDIO_REG_BANK_GP_STATUS,
3227 MDIO_GP_STATUS_TOP_AN_STATUS1,
3228 &gp_status);
3229 /* link is up only if both local phy and external phy are up */
3230 if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
3231 return -ESRCH;
3232
3233 switch (params->num_phys) {
3234 case 1:
3235 /* No external PHY */
3236 return 0;
3237 case 2:
3238 ext_phy_link_up = params->phy[EXT_PHY1].read_status(
3239 &params->phy[EXT_PHY1],
3240 params, &temp_vars);
3241 break;
3242 case 3: /* Dual Media */
3243 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3244 phy_index++) {
3245 serdes_phy_type = ((params->phy[phy_index].media_type ==
3246 ETH_PHY_SFP_FIBER) ||
3247 (params->phy[phy_index].media_type ==
3248 ETH_PHY_XFP_FIBER));
3249
3250 if (is_serdes != serdes_phy_type)
3251 continue;
3252 if (params->phy[phy_index].read_status) {
3253 ext_phy_link_up |=
3254 params->phy[phy_index].read_status(
3255 &params->phy[phy_index],
3256 params, &temp_vars);
3257 }
3258 }
3259 break;
3260 }
3261 if (ext_phy_link_up)
3262 return 0;
3263 return -ESRCH;
3264}
3265
3266static u8 bnx2x_link_initialize(struct link_params *params,
3267 struct link_vars *vars)
3268{
3269 u8 rc = 0;
3270 u8 phy_index, non_ext_phy;
3271 struct bnx2x *bp = params->bp;
3272 /*
3273 * In case of external phy existence, the line speed would be the
3274 * line speed linked up by the external phy. In case it is direct
3275 * only, then the line_speed during initialization will be
3276 * equal to the req_line_speed
3277 */
3278 vars->line_speed = params->phy[INT_PHY].req_line_speed;
3279
3280 /*
3281 * Initialize the internal phy in case this is a direct board
3282 * (no external phys), or this board has external phy which requires
3283 * to first.
3284 */
3285
3286 if (params->phy[INT_PHY].config_init)
3287 params->phy[INT_PHY].config_init(
3288 &params->phy[INT_PHY],
3289 params, vars);
3290
3291 /* init ext phy and enable link state int */
3292 non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
3293 (params->loopback_mode == LOOPBACK_XGXS));
3294
3295 if (non_ext_phy ||
3296 (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
3297 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3298 struct bnx2x_phy *phy = &params->phy[INT_PHY];
3299 if (vars->line_speed == SPEED_AUTO_NEG)
3300 bnx2x_set_parallel_detection(phy, params);
3301 bnx2x_init_internal_phy(phy, params, vars);
3302 }
3303
3304 /* Init external phy*/
3305 if (!non_ext_phy)
3306 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3307 phy_index++) {
3308 /*
3309 * No need to initialize second phy in case of first
3310 * phy only selection. In case of second phy, we do
3311 * need to initialize the first phy, since they are
3312 * connected.
3313 */
3314 if (phy_index == EXT_PHY2 &&
3315 (bnx2x_phy_selection(params) ==
3316 PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
3317 DP(NETIF_MSG_LINK, "Ignoring second phy\n");
3318 continue;
3319 }
3320 params->phy[phy_index].config_init(
3321 &params->phy[phy_index],
3322 params, vars);
3323 }
3324
3325 /* Reset the interrupt indication after phy was initialized */
3326 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
3327 params->port*4,
3328 (NIG_STATUS_XGXS0_LINK10G |
3329 NIG_STATUS_XGXS0_LINK_STATUS |
3330 NIG_STATUS_SERDES0_LINK_STATUS |
3331 NIG_MASK_MI_INT));
3332 return rc;
3333}
3334
3335static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
3336 struct link_params *params)
3337{
3338 /* reset the SerDes/XGXS */
3339 REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
3340 (0x1ff << (params->port*16)));
3341}
3342
3343static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
3344 struct link_params *params)
3345{
3346 struct bnx2x *bp = params->bp;
3347 u8 gpio_port;
3348 /* HW reset */
3349 if (CHIP_IS_E2(bp))
3350 gpio_port = BP_PATH(bp);
3351 else
3352 gpio_port = params->port;
3353 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3354 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3355 gpio_port);
3356 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3357 MISC_REGISTERS_GPIO_OUTPUT_LOW,
3358 gpio_port);
3359 DP(NETIF_MSG_LINK, "reset external PHY\n");
3360}
3361
3362static u8 bnx2x_update_link_down(struct link_params *params,
3363 struct link_vars *vars)
3364{
3365 struct bnx2x *bp = params->bp;
3366 u8 port = params->port;
3367
3368 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
3369 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
3370
3371 /* indicate no mac active */
3372 vars->mac_type = MAC_TYPE_NONE;
3373
3374 /* update shared memory */
3375 vars->link_status = 0;
3376 vars->line_speed = 0;
3377 bnx2x_update_mng(params, vars->link_status);
3378
3379 /* activate nig drain */
3380 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3381
3382 /* disable emac */
3383 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3384
3385 msleep(10);
3386
3387 /* reset BigMac */
3388 bnx2x_bmac_rx_disable(bp, params->port);
3389 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
3390 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
3391 return 0;
3392}
3393
3394static u8 bnx2x_update_link_up(struct link_params *params,
3395 struct link_vars *vars,
3396 u8 link_10g)
3397{
3398 struct bnx2x *bp = params->bp;
3399 u8 port = params->port;
3400 u8 rc = 0;
3401
3402 vars->link_status |= LINK_STATUS_LINK_UP;
3403
3404 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
3405 vars->link_status |=
3406 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
3407
3408 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
3409 vars->link_status |=
3410 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
3411
3412 if (link_10g) {
3413 bnx2x_bmac_enable(params, vars, 0);
3414 bnx2x_set_led(params, vars,
3415 LED_MODE_OPER, SPEED_10000);
3416 } else {
3417 rc = bnx2x_emac_program(params, vars);
3418
3419 bnx2x_emac_enable(params, vars, 0);
3420
3421 /* AN complete? */
3422 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
3423 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
3424 SINGLE_MEDIA_DIRECT(params))
3425 bnx2x_set_gmii_tx_driver(params);
3426 }
3427
3428 /* PBF - link up */
3429 if (!(CHIP_IS_E2(bp)))
3430 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
3431 vars->line_speed);
3432
3433 /* disable drain */
3434 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
3435
3436 /* update shared memory */
3437 bnx2x_update_mng(params, vars->link_status);
3438 msleep(20);
3439 return rc;
3440}
3441/*
3442 * The bnx2x_link_update function should be called upon link
3443 * interrupt.
3444 * Link is considered up as follows:
3445 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
3446 * to be up
3447 * - SINGLE_MEDIA - The link between the 577xx and the external
3448 * phy (XGXS) need to up as well as the external link of the
3449 * phy (PHY_EXT1)
3450 * - DUAL_MEDIA - The link between the 577xx and the first
3451 * external phy needs to be up, and at least one of the 2
3452 * external phy link must be up.
3453 */
3454u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
3455{
3456 struct bnx2x *bp = params->bp;
3457 struct link_vars phy_vars[MAX_PHYS];
3458 u8 port = params->port;
3459 u8 link_10g, phy_index;
3460 u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
3461 u8 is_mi_int = 0;
3462 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
3463 u8 active_external_phy = INT_PHY;
3464 vars->link_status = 0;
3465 for (phy_index = INT_PHY; phy_index < params->num_phys;
3466 phy_index++) {
3467 phy_vars[phy_index].flow_ctrl = 0;
3468 phy_vars[phy_index].link_status = 0;
3469 phy_vars[phy_index].line_speed = 0;
3470 phy_vars[phy_index].duplex = DUPLEX_FULL;
3471 phy_vars[phy_index].phy_link_up = 0;
3472 phy_vars[phy_index].link_up = 0;
3473 }
3474
3475 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
3476 port, (vars->phy_flags & PHY_XGXS_FLAG),
3477 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3478
3479 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
3480 port*0x18) > 0);
3481 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
3482 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3483 is_mi_int,
3484 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
3485
3486 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3487 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3488 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3489
3490 /* disable emac */
3491 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
3492
3493 /*
3494 * Step 1:
3495 * Check external link change only for external phys, and apply
3496 * priority selection between them in case the link on both phys
3497 * is up. Note that the instead of the common vars, a temporary
3498 * vars argument is used since each phy may have different link/
3499 * speed/duplex result
3500 */
3501 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3502 phy_index++) {
3503 struct bnx2x_phy *phy = &params->phy[phy_index];
3504 if (!phy->read_status)
3505 continue;
3506 /* Read link status and params of this ext phy */
3507 cur_link_up = phy->read_status(phy, params,
3508 &phy_vars[phy_index]);
3509 if (cur_link_up) {
3510 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
3511 phy_index);
3512 } else {
3513 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
3514 phy_index);
3515 continue;
3516 }
3517
3518 if (!ext_phy_link_up) {
3519 ext_phy_link_up = 1;
3520 active_external_phy = phy_index;
3521 } else {
3522 switch (bnx2x_phy_selection(params)) {
3523 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
3524 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
3525 /*
3526 * In this option, the first PHY makes sure to pass the
3527 * traffic through itself only.
3528 * Its not clear how to reset the link on the second phy
3529 */
3530 active_external_phy = EXT_PHY1;
3531 break;
3532 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
3533 /*
3534 * In this option, the first PHY makes sure to pass the
3535 * traffic through the second PHY.
3536 */
3537 active_external_phy = EXT_PHY2;
3538 break;
3539 default:
3540 /*
3541 * Link indication on both PHYs with the following cases
3542 * is invalid:
3543 * - FIRST_PHY means that second phy wasn't initialized,
3544 * hence its link is expected to be down
3545 * - SECOND_PHY means that first phy should not be able
3546 * to link up by itself (using configuration)
3547 * - DEFAULT should be overriden during initialiazation
3548 */
3549 DP(NETIF_MSG_LINK, "Invalid link indication"
3550 "mpc=0x%x. DISABLING LINK !!!\n",
3551 params->multi_phy_config);
3552 ext_phy_link_up = 0;
3553 break;
3554 }
3555 }
3556 }
3557 prev_line_speed = vars->line_speed;
3558 /*
3559 * Step 2:
3560 * Read the status of the internal phy. In case of
3561 * DIRECT_SINGLE_MEDIA board, this link is the external link,
3562 * otherwise this is the link between the 577xx and the first
3563 * external phy
3564 */
3565 if (params->phy[INT_PHY].read_status)
3566 params->phy[INT_PHY].read_status(
3567 &params->phy[INT_PHY],
3568 params, vars);
3569 /*
3570 * The INT_PHY flow control reside in the vars. This include the
3571 * case where the speed or flow control are not set to AUTO.
3572 * Otherwise, the active external phy flow control result is set
3573 * to the vars. The ext_phy_line_speed is needed to check if the
3574 * speed is different between the internal phy and external phy.
3575 * This case may be result of intermediate link speed change.
3576 */
3577 if (active_external_phy > INT_PHY) {
3578 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
3579 /*
3580 * Link speed is taken from the XGXS. AN and FC result from
3581 * the external phy.
3582 */
3583 vars->link_status |= phy_vars[active_external_phy].link_status;
3584
3585 /*
3586 * if active_external_phy is first PHY and link is up - disable
3587 * disable TX on second external PHY
3588 */
3589 if (active_external_phy == EXT_PHY1) {
3590 if (params->phy[EXT_PHY2].phy_specific_func) {
3591 DP(NETIF_MSG_LINK, "Disabling TX on"
3592 " EXT_PHY2\n");
3593 params->phy[EXT_PHY2].phy_specific_func(
3594 &params->phy[EXT_PHY2],
3595 params, DISABLE_TX);
3596 }
3597 }
3598
3599 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
3600 vars->duplex = phy_vars[active_external_phy].duplex;
3601 if (params->phy[active_external_phy].supported &
3602 SUPPORTED_FIBRE)
3603 vars->link_status |= LINK_STATUS_SERDES_LINK;
3604 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
3605 active_external_phy);
3606 }
3607
3608 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
3609 phy_index++) {
3610 if (params->phy[phy_index].flags &
3611 FLAGS_REARM_LATCH_SIGNAL) {
3612 bnx2x_rearm_latch_signal(bp, port,
3613 phy_index ==
3614 active_external_phy);
2232 break; 3615 break;
2233 } 3616 }
2234 } 3617 }
3618 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
3619 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
3620 vars->link_status, ext_phy_line_speed);
3621 /*
3622 * Upon link speed change set the NIG into drain mode. Comes to
3623 * deals with possible FIFO glitch due to clk change when speed
3624 * is decreased without link down indicator
3625 */
3626
3627 if (vars->phy_link_up) {
3628 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
3629 (ext_phy_line_speed != vars->line_speed)) {
3630 DP(NETIF_MSG_LINK, "Internal link speed %d is"
3631 " different than the external"
3632 " link speed %d\n", vars->line_speed,
3633 ext_phy_line_speed);
3634 vars->phy_link_up = 0;
3635 } else if (prev_line_speed != vars->line_speed) {
3636 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
3637 0);
3638 msleep(1);
3639 }
3640 }
3641
3642 /* anything 10 and over uses the bmac */
3643 link_10g = ((vars->line_speed == SPEED_10000) ||
3644 (vars->line_speed == SPEED_12000) ||
3645 (vars->line_speed == SPEED_12500) ||
3646 (vars->line_speed == SPEED_13000) ||
3647 (vars->line_speed == SPEED_15000) ||
3648 (vars->line_speed == SPEED_16000));
3649
3650 bnx2x_link_int_ack(params, vars, link_10g);
3651
3652 /*
3653 * In case external phy link is up, and internal link is down
3654 * (not initialized yet probably after link initialization, it
3655 * needs to be initialized.
3656 * Note that after link down-up as result of cable plug, the xgxs
3657 * link would probably become up again without the need
3658 * initialize it
3659 */
3660 if (!(SINGLE_MEDIA_DIRECT(params))) {
3661 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
3662 " init_preceding = %d\n", ext_phy_link_up,
3663 vars->phy_link_up,
3664 params->phy[EXT_PHY1].flags &
3665 FLAGS_INIT_XGXS_FIRST);
3666 if (!(params->phy[EXT_PHY1].flags &
3667 FLAGS_INIT_XGXS_FIRST)
3668 && ext_phy_link_up && !vars->phy_link_up) {
3669 vars->line_speed = ext_phy_line_speed;
3670 if (vars->line_speed < SPEED_1000)
3671 vars->phy_flags |= PHY_SGMII_FLAG;
3672 else
3673 vars->phy_flags &= ~PHY_SGMII_FLAG;
3674 bnx2x_init_internal_phy(&params->phy[INT_PHY],
3675 params,
3676 vars);
3677 }
3678 }
3679 /*
3680 * Link is up only if both local phy and external phy (in case of
3681 * non-direct board) are up
3682 */
3683 vars->link_up = (vars->phy_link_up &&
3684 (ext_phy_link_up ||
3685 SINGLE_MEDIA_DIRECT(params)));
3686
3687 if (vars->link_up)
3688 rc = bnx2x_update_link_up(params, vars, link_10g);
3689 else
3690 rc = bnx2x_update_link_down(params, vars);
3691
3692 return rc;
3693}
3694
3695
3696/*****************************************************************************/
3697/* External Phy section */
3698/*****************************************************************************/
3699void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
3700{
3701 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3702 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
3703 msleep(1);
3704 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3705 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
2235} 3706}
2236 3707
2237static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port, 3708static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2238 u32 shmem_base, u32 spirom_ver) 3709 u32 spirom_ver, u32 ver_addr)
2239{ 3710{
2240 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n", 3711 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
2241 (u16)(spirom_ver>>16), (u16)spirom_ver, port); 3712 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
2242 REG_WR(bp, shmem_base + 3713
2243 offsetof(struct shmem_region, 3714 if (ver_addr)
2244 port_mb[port].ext_phy_fw_version), 3715 REG_WR(bp, ver_addr, spirom_ver);
2245 spirom_ver);
2246} 3716}
2247 3717
2248static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port, 3718static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
2249 u32 ext_phy_type, u8 ext_phy_addr, 3719 struct bnx2x_phy *phy,
2250 u32 shmem_base) 3720 u8 port)
2251{ 3721{
2252 u16 fw_ver1, fw_ver2; 3722 u16 fw_ver1, fw_ver2;
2253 3723
2254 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, 3724 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
2255 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 3725 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2256 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr, MDIO_PMA_DEVAD, 3726 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
2257 MDIO_PMA_REG_ROM_VER2, &fw_ver2); 3727 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2258 bnx2x_save_spirom_version(bp, port, shmem_base, 3728 bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
2259 (u32)(fw_ver1<<16 | fw_ver2)); 3729 phy->ver_addr);
2260} 3730}
2261 3731
2262 3732static void bnx2x_ext_phy_set_pause(struct link_params *params,
2263static void bnx2x_save_8481_spirom_version(struct bnx2x *bp, u8 port, 3733 struct bnx2x_phy *phy,
2264 u8 ext_phy_addr, u32 shmem_base) 3734 struct link_vars *vars)
2265{ 3735{
2266 u16 val, fw_ver1, fw_ver2, cnt; 3736 u16 val;
2267 /* For the 32 bits registers in 8481, access via MDIO2ARM interface.*/ 3737 struct bnx2x *bp = params->bp;
2268 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */ 3738 /* read modify write pause advertizing */
2269 bnx2x_cl45_write(bp, port, 3739 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
2270 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2271 ext_phy_addr, MDIO_PMA_DEVAD,
2272 0xA819, 0x0014);
2273 bnx2x_cl45_write(bp, port,
2274 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2275 ext_phy_addr,
2276 MDIO_PMA_DEVAD,
2277 0xA81A,
2278 0xc200);
2279 bnx2x_cl45_write(bp, port,
2280 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2281 ext_phy_addr,
2282 MDIO_PMA_DEVAD,
2283 0xA81B,
2284 0x0000);
2285 bnx2x_cl45_write(bp, port,
2286 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2287 ext_phy_addr,
2288 MDIO_PMA_DEVAD,
2289 0xA81C,
2290 0x0300);
2291 bnx2x_cl45_write(bp, port,
2292 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
2293 ext_phy_addr,
2294 MDIO_PMA_DEVAD,
2295 0xA817,
2296 0x0009);
2297 3740
2298 for (cnt = 0; cnt < 100; cnt++) { 3741 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2299 bnx2x_cl45_read(bp, port, 3742
2300 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3743 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2301 ext_phy_addr, 3744 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2302 MDIO_PMA_DEVAD, 3745 if ((vars->ieee_fc &
2303 0xA818, 3746 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2304 &val); 3747 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2305 if (val & 1) 3748 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2306 break;
2307 udelay(5);
2308 } 3749 }
2309 if (cnt == 100) { 3750 if ((vars->ieee_fc &
2310 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n"); 3751 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2311 bnx2x_save_spirom_version(bp, port, 3752 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2312 shmem_base, 0); 3753 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
2313 return;
2314 } 3754 }
3755 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3756 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3757}
2315 3758
3759static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3760 struct link_params *params,
3761 struct link_vars *vars)
3762{
3763 struct bnx2x *bp = params->bp;
3764 u16 ld_pause; /* local */
3765 u16 lp_pause; /* link partner */
3766 u16 pause_result;
3767 u8 ret = 0;
3768 /* read twice */
2316 3769
2317 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */ 3770 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
2318 bnx2x_cl45_write(bp, port, 3771
2319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3772 if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
2320 ext_phy_addr, MDIO_PMA_DEVAD, 3773 vars->flow_ctrl = phy->req_flow_ctrl;
2321 0xA819, 0x0000); 3774 else if (phy->req_line_speed != SPEED_AUTO_NEG)
2322 bnx2x_cl45_write(bp, port, 3775 vars->flow_ctrl = params->req_fc_auto_adv;
2323 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3776 else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
2324 ext_phy_addr, MDIO_PMA_DEVAD, 3777 ret = 1;
2325 0xA81A, 0xc200); 3778 bnx2x_cl45_read(bp, phy,
2326 bnx2x_cl45_write(bp, port, 3779 MDIO_AN_DEVAD,
2327 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3780 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
2328 ext_phy_addr, MDIO_PMA_DEVAD, 3781 bnx2x_cl45_read(bp, phy,
2329 0xA817, 0x000A); 3782 MDIO_AN_DEVAD,
2330 for (cnt = 0; cnt < 100; cnt++) { 3783 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
2331 bnx2x_cl45_read(bp, port, 3784 pause_result = (ld_pause &
2332 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3785 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
2333 ext_phy_addr, 3786 pause_result |= (lp_pause &
2334 MDIO_PMA_DEVAD, 3787 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
2335 0xA818, 3788 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
2336 &val); 3789 pause_result);
2337 if (val & 1) 3790 bnx2x_pause_resolve(vars, pause_result);
2338 break;
2339 udelay(5);
2340 } 3791 }
2341 if (cnt == 100) { 3792 return ret;
2342 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(2)\n"); 3793}
2343 bnx2x_save_spirom_version(bp, port, 3794
2344 shmem_base, 0); 3795static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
3796 struct bnx2x_phy *phy,
3797 struct link_vars *vars)
3798{
3799 u16 val;
3800 bnx2x_cl45_read(bp, phy,
3801 MDIO_AN_DEVAD,
3802 MDIO_AN_REG_STATUS, &val);
3803 bnx2x_cl45_read(bp, phy,
3804 MDIO_AN_DEVAD,
3805 MDIO_AN_REG_STATUS, &val);
3806 if (val & (1<<5))
3807 vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
3808 if ((val & (1<<0)) == 0)
3809 vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
3810}
3811
3812/******************************************************************/
3813/* common BCM8073/BCM8727 PHY SECTION */
3814/******************************************************************/
3815static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
3816 struct link_params *params,
3817 struct link_vars *vars)
3818{
3819 struct bnx2x *bp = params->bp;
3820 if (phy->req_line_speed == SPEED_10 ||
3821 phy->req_line_speed == SPEED_100) {
3822 vars->flow_ctrl = phy->req_flow_ctrl;
2345 return; 3823 return;
2346 } 3824 }
2347 3825
2348 /* lower 16 bits of the register SPI_FW_STATUS */ 3826 if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
2349 bnx2x_cl45_read(bp, port, 3827 (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
2350 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3828 u16 pause_result;
2351 ext_phy_addr, 3829 u16 ld_pause; /* local */
2352 MDIO_PMA_DEVAD, 3830 u16 lp_pause; /* link partner */
2353 0xA81B, 3831 bnx2x_cl45_read(bp, phy,
2354 &fw_ver1); 3832 MDIO_AN_DEVAD,
2355 /* upper 16 bits of register SPI_FW_STATUS */ 3833 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
2356 bnx2x_cl45_read(bp, port, 3834
2357 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481, 3835 bnx2x_cl45_read(bp, phy,
2358 ext_phy_addr, 3836 MDIO_AN_DEVAD,
2359 MDIO_PMA_DEVAD, 3837 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
2360 0xA81C, 3838 pause_result = (ld_pause &
2361 &fw_ver2); 3839 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
3840 pause_result |= (lp_pause &
3841 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
2362 3842
2363 bnx2x_save_spirom_version(bp, port, 3843 bnx2x_pause_resolve(vars, pause_result);
2364 shmem_base, (fw_ver2<<16) | fw_ver1); 3844 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
3845 pause_result);
3846 }
2365} 3847}
2366 3848static u8 bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
2367static void bnx2x_bcm8072_external_rom_boot(struct link_params *params) 3849 struct bnx2x_phy *phy,
3850 u8 port)
2368{ 3851{
2369 struct bnx2x *bp = params->bp; 3852 u32 count = 0;
2370 u8 port = params->port; 3853 u16 fw_ver1, fw_msgout;
2371 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 3854 u8 rc = 0;
2372 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2373 3855
2374 /* Need to wait 200ms after reset */ 3856 /* Boot port from external ROM */
2375 msleep(200); 3857 /* EDC grst */
2376 /* Boot port from external ROM 3858 bnx2x_cl45_write(bp, phy,
2377 * Set ser_boot_ctl bit in the MISC_CTRL1 register 3859 MDIO_PMA_DEVAD,
2378 */ 3860 MDIO_PMA_REG_GEN_CTRL,
2379 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 3861 0x0001);
2380 MDIO_PMA_DEVAD, 3862
2381 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 3863 /* ucode reboot and rst */
3864 bnx2x_cl45_write(bp, phy,
3865 MDIO_PMA_DEVAD,
3866 MDIO_PMA_REG_GEN_CTRL,
3867 0x008c);
3868
3869 bnx2x_cl45_write(bp, phy,
3870 MDIO_PMA_DEVAD,
3871 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2382 3872
2383 /* Reset internal microprocessor */ 3873 /* Reset internal microprocessor */
2384 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 3874 bnx2x_cl45_write(bp, phy,
2385 MDIO_PMA_DEVAD, 3875 MDIO_PMA_DEVAD,
2386 MDIO_PMA_REG_GEN_CTRL, 3876 MDIO_PMA_REG_GEN_CTRL,
2387 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP); 3877 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2388 /* set micro reset = 0 */ 3878
2389 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 3879 /* Release srst bit */
2390 MDIO_PMA_DEVAD, 3880 bnx2x_cl45_write(bp, phy,
2391 MDIO_PMA_REG_GEN_CTRL, 3881 MDIO_PMA_DEVAD,
2392 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET); 3882 MDIO_PMA_REG_GEN_CTRL,
2393 /* Reset internal microprocessor */ 3883 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2394 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 3884
2395 MDIO_PMA_DEVAD, 3885 /* Delay 100ms per the PHY specifications */
2396 MDIO_PMA_REG_GEN_CTRL,
2397 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2398 /* wait for 100ms for code download via SPI port */
2399 msleep(100); 3886 msleep(100);
2400 3887
3888 /* 8073 sometimes taking longer to download */
3889 do {
3890 count++;
3891 if (count > 300) {
3892 DP(NETIF_MSG_LINK,
3893 "bnx2x_8073_8727_external_rom_boot port %x:"
3894 "Download failed. fw version = 0x%x\n",
3895 port, fw_ver1);
3896 rc = -EINVAL;
3897 break;
3898 }
3899
3900 bnx2x_cl45_read(bp, phy,
3901 MDIO_PMA_DEVAD,
3902 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
3903 bnx2x_cl45_read(bp, phy,
3904 MDIO_PMA_DEVAD,
3905 MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
3906
3907 msleep(1);
3908 } while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
3909 ((fw_msgout & 0xff) != 0x03 && (phy->type ==
3910 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
3911
2401 /* Clear ser_boot_ctl bit */ 3912 /* Clear ser_boot_ctl bit */
2402 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 3913 bnx2x_cl45_write(bp, phy,
2403 MDIO_PMA_DEVAD, 3914 MDIO_PMA_DEVAD,
2404 MDIO_PMA_REG_MISC_CTRL1, 0x0000); 3915 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2405 /* Wait 100ms */ 3916 bnx2x_save_bcm_spirom_ver(bp, phy, port);
2406 msleep(100);
2407 3917
2408 bnx2x_save_bcm_spirom_ver(bp, port, 3918 DP(NETIF_MSG_LINK,
2409 ext_phy_type, 3919 "bnx2x_8073_8727_external_rom_boot port %x:"
2410 ext_phy_addr, 3920 "Download complete. fw version = 0x%x\n",
2411 params->shmem_base); 3921 port, fw_ver1);
3922
3923 return rc;
2412} 3924}
2413 3925
2414static u8 bnx2x_8073_is_snr_needed(struct link_params *params) 3926/******************************************************************/
3927/* BCM8073 PHY SECTION */
3928/******************************************************************/
3929static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
2415{ 3930{
2416 /* This is only required for 8073A1, version 102 only */ 3931 /* This is only required for 8073A1, version 102 only */
2417
2418 struct bnx2x *bp = params->bp;
2419 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2420 u16 val; 3932 u16 val;
2421 3933
2422 /* Read 8073 HW revision*/ 3934 /* Read 8073 HW revision*/
2423 bnx2x_cl45_read(bp, params->port, 3935 bnx2x_cl45_read(bp, phy,
2424 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 3936 MDIO_PMA_DEVAD,
2425 ext_phy_addr, 3937 MDIO_PMA_REG_8073_CHIP_REV, &val);
2426 MDIO_PMA_DEVAD,
2427 MDIO_PMA_REG_8073_CHIP_REV, &val);
2428 3938
2429 if (val != 1) { 3939 if (val != 1) {
2430 /* No need to workaround in 8073 A1 */ 3940 /* No need to workaround in 8073 A1 */
2431 return 0; 3941 return 0;
2432 } 3942 }
2433 3943
2434 bnx2x_cl45_read(bp, params->port, 3944 bnx2x_cl45_read(bp, phy,
2435 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 3945 MDIO_PMA_DEVAD,
2436 ext_phy_addr, 3946 MDIO_PMA_REG_ROM_VER2, &val);
2437 MDIO_PMA_DEVAD,
2438 MDIO_PMA_REG_ROM_VER2, &val);
2439 3947
2440 /* SNR should be applied only for version 0x102 */ 3948 /* SNR should be applied only for version 0x102 */
2441 if (val != 0x102) 3949 if (val != 0x102)
@@ -2444,17 +3952,13 @@ static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2444 return 1; 3952 return 1;
2445} 3953}
2446 3954
2447static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params) 3955static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
2448{ 3956{
2449 struct bnx2x *bp = params->bp;
2450 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2451 u16 val, cnt, cnt1 ; 3957 u16 val, cnt, cnt1 ;
2452 3958
2453 bnx2x_cl45_read(bp, params->port, 3959 bnx2x_cl45_read(bp, phy,
2454 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 3960 MDIO_PMA_DEVAD,
2455 ext_phy_addr, 3961 MDIO_PMA_REG_8073_CHIP_REV, &val);
2456 MDIO_PMA_DEVAD,
2457 MDIO_PMA_REG_8073_CHIP_REV, &val);
2458 3962
2459 if (val > 0) { 3963 if (val > 0) {
2460 /* No need to workaround in 8073 A1 */ 3964 /* No need to workaround in 8073 A1 */
@@ -2462,32 +3966,34 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2462 } 3966 }
2463 /* XAUI workaround in 8073 A0: */ 3967 /* XAUI workaround in 8073 A0: */
2464 3968
2465 /* After loading the boot ROM and restarting Autoneg, 3969 /*
2466 poll Dev1, Reg $C820: */ 3970 * After loading the boot ROM and restarting Autoneg, poll
3971 * Dev1, Reg $C820:
3972 */
2467 3973
2468 for (cnt = 0; cnt < 1000; cnt++) { 3974 for (cnt = 0; cnt < 1000; cnt++) {
2469 bnx2x_cl45_read(bp, params->port, 3975 bnx2x_cl45_read(bp, phy,
2470 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 3976 MDIO_PMA_DEVAD,
2471 ext_phy_addr, 3977 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2472 MDIO_PMA_DEVAD, 3978 &val);
2473 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, 3979 /*
2474 &val); 3980 * If bit [14] = 0 or bit [13] = 0, continue on with
2475 /* If bit [14] = 0 or bit [13] = 0, continue on with 3981 * system initialization (XAUI work-around not required, as
2476 system initialization (XAUI work-around not required, 3982 * these bits indicate 2.5G or 1G link up).
2477 as these bits indicate 2.5G or 1G link up). */ 3983 */
2478 if (!(val & (1<<14)) || !(val & (1<<13))) { 3984 if (!(val & (1<<14)) || !(val & (1<<13))) {
2479 DP(NETIF_MSG_LINK, "XAUI work-around not required\n"); 3985 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2480 return 0; 3986 return 0;
2481 } else if (!(val & (1<<15))) { 3987 } else if (!(val & (1<<15))) {
2482 DP(NETIF_MSG_LINK, "clc bit 15 went off\n"); 3988 DP(NETIF_MSG_LINK, "bit 15 went off\n");
2483 /* If bit 15 is 0, then poll Dev1, Reg $C841 until 3989 /*
2484 it's MSB (bit 15) goes to 1 (indicating that the 3990 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
2485 XAUI workaround has completed), 3991 * MSB (bit15) goes to 1 (indicating that the XAUI
2486 then continue on with system initialization.*/ 3992 * workaround has completed), then continue on with
3993 * system initialization.
3994 */
2487 for (cnt1 = 0; cnt1 < 1000; cnt1++) { 3995 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2488 bnx2x_cl45_read(bp, params->port, 3996 bnx2x_cl45_read(bp, phy,
2489 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2490 ext_phy_addr,
2491 MDIO_PMA_DEVAD, 3997 MDIO_PMA_DEVAD,
2492 MDIO_PMA_REG_8073_XAUI_WA, &val); 3998 MDIO_PMA_REG_8073_XAUI_WA, &val);
2493 if (val & (1<<15)) { 3999 if (val & (1<<15)) {
@@ -2505,206 +4011,527 @@ static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2505 return -EINVAL; 4011 return -EINVAL;
2506} 4012}
2507 4013
2508static void bnx2x_bcm8073_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, 4014static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
2509 u8 ext_phy_addr,
2510 u32 ext_phy_type,
2511 u32 shmem_base)
2512{ 4015{
2513 /* Boot port from external ROM */ 4016 /* Force KR or KX */
2514 /* EDC grst */ 4017 bnx2x_cl45_write(bp, phy,
2515 bnx2x_cl45_write(bp, port, 4018 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
2516 ext_phy_type, 4019 bnx2x_cl45_write(bp, phy,
2517 ext_phy_addr, 4020 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
2518 MDIO_PMA_DEVAD, 4021 bnx2x_cl45_write(bp, phy,
2519 MDIO_PMA_REG_GEN_CTRL, 4022 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
2520 0x0001); 4023 bnx2x_cl45_write(bp, phy,
2521 4024 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
2522 /* ucode reboot and rst */
2523 bnx2x_cl45_write(bp, port,
2524 ext_phy_type,
2525 ext_phy_addr,
2526 MDIO_PMA_DEVAD,
2527 MDIO_PMA_REG_GEN_CTRL,
2528 0x008c);
2529
2530 bnx2x_cl45_write(bp, port,
2531 ext_phy_type,
2532 ext_phy_addr,
2533 MDIO_PMA_DEVAD,
2534 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2535
2536 /* Reset internal microprocessor */
2537 bnx2x_cl45_write(bp, port,
2538 ext_phy_type,
2539 ext_phy_addr,
2540 MDIO_PMA_DEVAD,
2541 MDIO_PMA_REG_GEN_CTRL,
2542 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2543
2544 /* Release srst bit */
2545 bnx2x_cl45_write(bp, port,
2546 ext_phy_type,
2547 ext_phy_addr,
2548 MDIO_PMA_DEVAD,
2549 MDIO_PMA_REG_GEN_CTRL,
2550 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2551
2552 /* wait for 100ms for code download via SPI port */
2553 msleep(100);
2554
2555 /* Clear ser_boot_ctl bit */
2556 bnx2x_cl45_write(bp, port,
2557 ext_phy_type,
2558 ext_phy_addr,
2559 MDIO_PMA_DEVAD,
2560 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2561
2562 bnx2x_save_bcm_spirom_ver(bp, port,
2563 ext_phy_type,
2564 ext_phy_addr,
2565 shmem_base);
2566} 4025}
2567 4026
2568static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port, 4027static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2569 u8 ext_phy_addr, 4028 struct bnx2x_phy *phy,
2570 u32 shmem_base) 4029 struct link_vars *vars)
2571{ 4030{
2572 bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, 4031 u16 cl37_val;
2573 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 4032 struct bnx2x *bp = params->bp;
2574 shmem_base); 4033 bnx2x_cl45_read(bp, phy,
2575} 4034 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2576 4035
2577static void bnx2x_bcm8727_external_rom_boot(struct bnx2x *bp, u8 port, 4036 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2578 u8 ext_phy_addr, 4037 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2579 u32 shmem_base) 4038 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2580{ 4039 if ((vars->ieee_fc &
2581 bnx2x_bcm8073_bcm8727_external_rom_boot(bp, port, ext_phy_addr, 4040 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2582 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 4041 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2583 shmem_base); 4042 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
4043 }
4044 if ((vars->ieee_fc &
4045 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
4046 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
4047 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
4048 }
4049 if ((vars->ieee_fc &
4050 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
4051 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
4052 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
4053 }
4054 DP(NETIF_MSG_LINK,
4055 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2584 4056
4057 bnx2x_cl45_write(bp, phy,
4058 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
4059 msleep(500);
2585} 4060}
2586 4061
2587static void bnx2x_bcm8726_external_rom_boot(struct link_params *params) 4062static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
4063 struct link_params *params,
4064 struct link_vars *vars)
2588{ 4065{
2589 struct bnx2x *bp = params->bp; 4066 struct bnx2x *bp = params->bp;
2590 u8 port = params->port; 4067 u16 val = 0, tmp1;
2591 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 4068 u8 gpio_port;
2592 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 4069 DP(NETIF_MSG_LINK, "Init 8073\n");
2593 4070
2594 /* Need to wait 100ms after reset */ 4071 if (CHIP_IS_E2(bp))
2595 msleep(100); 4072 gpio_port = BP_PATH(bp);
4073 else
4074 gpio_port = params->port;
4075 /* Restore normal power mode*/
4076 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4077 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
2596 4078
2597 /* Micro controller re-boot */ 4079 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
2598 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 4080 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
2599 MDIO_PMA_DEVAD, 4081
2600 MDIO_PMA_REG_GEN_CTRL, 4082 /* enable LASI */
2601 0x018B); 4083 bnx2x_cl45_write(bp, phy,
4084 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
4085 bnx2x_cl45_write(bp, phy,
4086 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
4087
4088 bnx2x_8073_set_pause_cl37(params, phy, vars);
4089
4090 bnx2x_cl45_read(bp, phy,
4091 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4092
4093 bnx2x_cl45_read(bp, phy,
4094 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4095
4096 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
4097
4098 /* Swap polarity if required - Must be done only in non-1G mode */
4099 if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4100 /* Configure the 8073 to swap _P and _N of the KR lines */
4101 DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
4102 /* 10G Rx/Tx and 1G Tx signal polarity swap */
4103 bnx2x_cl45_read(bp, phy,
4104 MDIO_PMA_DEVAD,
4105 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
4106 bnx2x_cl45_write(bp, phy,
4107 MDIO_PMA_DEVAD,
4108 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
4109 (val | (3<<9)));
4110 }
2602 4111
2603 /* Set soft reset */
2604 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2605 MDIO_PMA_DEVAD,
2606 MDIO_PMA_REG_GEN_CTRL,
2607 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2608 4112
2609 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 4113 /* Enable CL37 BAM */
2610 MDIO_PMA_DEVAD, 4114 if (REG_RD(bp, params->shmem_base +
2611 MDIO_PMA_REG_MISC_CTRL1, 0x0001); 4115 offsetof(struct shmem_region, dev_info.
4116 port_hw_config[params->port].default_cfg)) &
4117 PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
4118
4119 bnx2x_cl45_read(bp, phy,
4120 MDIO_AN_DEVAD,
4121 MDIO_AN_REG_8073_BAM, &val);
4122 bnx2x_cl45_write(bp, phy,
4123 MDIO_AN_DEVAD,
4124 MDIO_AN_REG_8073_BAM, val | 1);
4125 DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
4126 }
4127 if (params->loopback_mode == LOOPBACK_EXT) {
4128 bnx2x_807x_force_10G(bp, phy);
4129 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
4130 return 0;
4131 } else {
4132 bnx2x_cl45_write(bp, phy,
4133 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
4134 }
4135 if (phy->req_line_speed != SPEED_AUTO_NEG) {
4136 if (phy->req_line_speed == SPEED_10000) {
4137 val = (1<<7);
4138 } else if (phy->req_line_speed == SPEED_2500) {
4139 val = (1<<5);
4140 /*
4141 * Note that 2.5G works only when used with 1G
4142 * advertisement
4143 */
4144 } else
4145 val = (1<<5);
4146 } else {
4147 val = 0;
4148 if (phy->speed_cap_mask &
4149 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4150 val |= (1<<7);
4151
4152 /* Note that 2.5G works only when used with 1G advertisement */
4153 if (phy->speed_cap_mask &
4154 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4155 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4156 val |= (1<<5);
4157 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
4158 }
4159
4160 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
4161 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
4162
4163 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4164 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
4165 (phy->req_line_speed == SPEED_2500)) {
4166 u16 phy_ver;
4167 /* Allow 2.5G for A1 and above */
4168 bnx2x_cl45_read(bp, phy,
4169 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
4170 &phy_ver);
4171 DP(NETIF_MSG_LINK, "Add 2.5G\n");
4172 if (phy_ver > 0)
4173 tmp1 |= 1;
4174 else
4175 tmp1 &= 0xfffe;
4176 } else {
4177 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4178 tmp1 &= 0xfffe;
4179 }
2612 4180
2613 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 4181 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
2614 MDIO_PMA_DEVAD, 4182 /* Add support for CL37 (passive mode) II */
2615 MDIO_PMA_REG_GEN_CTRL,
2616 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2617 4183
2618 /* wait for 150ms for microcode load */ 4184 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
2619 msleep(150); 4185 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
4186 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
4187 0x20 : 0x40)));
2620 4188
2621 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */ 4189 /* Add support for CL37 (passive mode) III */
2622 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr, 4190 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
2623 MDIO_PMA_DEVAD,
2624 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2625 4191
2626 msleep(200); 4192 /*
2627 bnx2x_save_bcm_spirom_ver(bp, port, 4193 * The SNR will improve about 2db by changing BW and FEE main
2628 ext_phy_type, 4194 * tap. Rest commands are executed after link is up
2629 ext_phy_addr, 4195 * Change FFE main cursor to 5 in EDC register
2630 params->shmem_base); 4196 */
4197 if (bnx2x_8073_is_snr_needed(bp, phy))
4198 bnx2x_cl45_write(bp, phy,
4199 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
4200 0xFB0C);
4201
4202 /* Enable FEC (Forware Error Correction) Request in the AN */
4203 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
4204 tmp1 |= (1<<15);
4205 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
4206
4207 bnx2x_ext_phy_set_pause(params, phy, vars);
4208
4209 /* Restart autoneg */
4210 msleep(500);
4211 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
4212 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
4213 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
4214 return 0;
4215}
4216
4217static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
4218 struct link_params *params,
4219 struct link_vars *vars)
4220{
4221 struct bnx2x *bp = params->bp;
4222 u8 link_up = 0;
4223 u16 val1, val2;
4224 u16 link_status = 0;
4225 u16 an1000_status = 0;
4226
4227 bnx2x_cl45_read(bp, phy,
4228 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4229
4230 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
4231
4232 /* clear the interrupt LASI status register */
4233 bnx2x_cl45_read(bp, phy,
4234 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4235 bnx2x_cl45_read(bp, phy,
4236 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4237 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4238 /* Clear MSG-OUT */
4239 bnx2x_cl45_read(bp, phy,
4240 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4241
4242 /* Check the LASI */
4243 bnx2x_cl45_read(bp, phy,
4244 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
4245
4246 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
4247
4248 /* Check the link status */
4249 bnx2x_cl45_read(bp, phy,
4250 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4251 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
4252
4253 bnx2x_cl45_read(bp, phy,
4254 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4255 bnx2x_cl45_read(bp, phy,
4256 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4257 link_up = ((val1 & 4) == 4);
4258 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
4259
4260 if (link_up &&
4261 ((phy->req_line_speed != SPEED_10000))) {
4262 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
4263 return 0;
4264 }
4265 bnx2x_cl45_read(bp, phy,
4266 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4267 bnx2x_cl45_read(bp, phy,
4268 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4269
4270 /* Check the link status on 1.1.2 */
4271 bnx2x_cl45_read(bp, phy,
4272 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4273 bnx2x_cl45_read(bp, phy,
4274 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4275 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4276 "an_link_status=0x%x\n", val2, val1, an1000_status);
4277
4278 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
4279 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
4280 /*
4281 * The SNR will improve about 2dbby changing the BW and FEE main
4282 * tap. The 1st write to change FFE main tap is set before
4283 * restart AN. Change PLL Bandwidth in EDC register
4284 */
4285 bnx2x_cl45_write(bp, phy,
4286 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
4287 0x26BC);
4288
4289 /* Change CDR Bandwidth in EDC register */
4290 bnx2x_cl45_write(bp, phy,
4291 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
4292 0x0333);
4293 }
4294 bnx2x_cl45_read(bp, phy,
4295 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4296 &link_status);
4297
4298 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
4299 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4300 link_up = 1;
4301 vars->line_speed = SPEED_10000;
4302 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4303 params->port);
4304 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
4305 link_up = 1;
4306 vars->line_speed = SPEED_2500;
4307 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
4308 params->port);
4309 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4310 link_up = 1;
4311 vars->line_speed = SPEED_1000;
4312 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4313 params->port);
4314 } else {
4315 link_up = 0;
4316 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4317 params->port);
4318 }
4319
4320 if (link_up) {
4321 /* Swap polarity if required */
4322 if (params->lane_config &
4323 PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
4324 /* Configure the 8073 to swap P and N of the KR lines */
4325 bnx2x_cl45_read(bp, phy,
4326 MDIO_XS_DEVAD,
4327 MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
4328 /*
4329 * Set bit 3 to invert Rx in 1G mode and clear this bit
4330 * when it`s in 10G mode.
4331 */
4332 if (vars->line_speed == SPEED_1000) {
4333 DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
4334 "the 8073\n");
4335 val1 |= (1<<3);
4336 } else
4337 val1 &= ~(1<<3);
4338
4339 bnx2x_cl45_write(bp, phy,
4340 MDIO_XS_DEVAD,
4341 MDIO_XS_REG_8073_RX_CTRL_PCIE,
4342 val1);
4343 }
4344 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
4345 bnx2x_8073_resolve_fc(phy, params, vars);
4346 vars->duplex = DUPLEX_FULL;
4347 }
4348 return link_up;
4349}
4350
4351static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
4352 struct link_params *params)
4353{
4354 struct bnx2x *bp = params->bp;
4355 u8 gpio_port;
4356 if (CHIP_IS_E2(bp))
4357 gpio_port = BP_PATH(bp);
4358 else
4359 gpio_port = params->port;
4360 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
4361 gpio_port);
4362 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4363 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4364 gpio_port);
4365}
4366
4367/******************************************************************/
4368/* BCM8705 PHY SECTION */
4369/******************************************************************/
4370static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
4371 struct link_params *params,
4372 struct link_vars *vars)
4373{
4374 struct bnx2x *bp = params->bp;
4375 DP(NETIF_MSG_LINK, "init 8705\n");
4376 /* Restore normal power mode*/
4377 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4378 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
4379 /* HW reset */
4380 bnx2x_ext_phy_hw_reset(bp, params->port);
4381 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
4382 bnx2x_wait_reset_complete(bp, phy, params);
4383
4384 bnx2x_cl45_write(bp, phy,
4385 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
4386 bnx2x_cl45_write(bp, phy,
4387 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
4388 bnx2x_cl45_write(bp, phy,
4389 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
4390 bnx2x_cl45_write(bp, phy,
4391 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
4392 /* BCM8705 doesn't have microcode, hence the 0 */
4393 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
4394 return 0;
4395}
4396
4397static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
4398 struct link_params *params,
4399 struct link_vars *vars)
4400{
4401 u8 link_up = 0;
4402 u16 val1, rx_sd;
4403 struct bnx2x *bp = params->bp;
4404 DP(NETIF_MSG_LINK, "read status 8705\n");
4405 bnx2x_cl45_read(bp, phy,
4406 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4407 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4408
4409 bnx2x_cl45_read(bp, phy,
4410 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
4411 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4412
4413 bnx2x_cl45_read(bp, phy,
4414 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4415
4416 bnx2x_cl45_read(bp, phy,
4417 MDIO_PMA_DEVAD, 0xc809, &val1);
4418 bnx2x_cl45_read(bp, phy,
4419 MDIO_PMA_DEVAD, 0xc809, &val1);
4420
4421 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4422 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
4423 if (link_up) {
4424 vars->line_speed = SPEED_10000;
4425 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4426 }
4427 return link_up;
2631} 4428}
2632 4429
2633static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, u8 port, 4430/******************************************************************/
2634 u32 ext_phy_type, u8 ext_phy_addr, 4431/* SFP+ module Section */
2635 u8 tx_en) 4432/******************************************************************/
4433static u8 bnx2x_get_gpio_port(struct link_params *params)
4434{
4435 u8 gpio_port;
4436 u32 swap_val, swap_override;
4437 struct bnx2x *bp = params->bp;
4438 if (CHIP_IS_E2(bp))
4439 gpio_port = BP_PATH(bp);
4440 else
4441 gpio_port = params->port;
4442 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
4443 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
4444 return gpio_port ^ (swap_val && swap_override);
4445}
4446static void bnx2x_sfp_set_transmitter(struct link_params *params,
4447 struct bnx2x_phy *phy,
4448 u8 tx_en)
2636{ 4449{
2637 u16 val; 4450 u16 val;
4451 u8 port = params->port;
4452 struct bnx2x *bp = params->bp;
4453 u32 tx_en_mode;
2638 4454
2639 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2640 tx_en, port);
2641 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ 4455 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
2642 bnx2x_cl45_read(bp, port, 4456 tx_en_mode = REG_RD(bp, params->shmem_base +
2643 ext_phy_type, 4457 offsetof(struct shmem_region,
2644 ext_phy_addr, 4458 dev_info.port_hw_config[port].sfp_ctrl)) &
2645 MDIO_PMA_DEVAD, 4459 PORT_HW_CFG_TX_LASER_MASK;
2646 MDIO_PMA_REG_PHY_IDENTIFIER, 4460 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
2647 &val); 4461 "mode = %x\n", tx_en, port, tx_en_mode);
2648 4462 switch (tx_en_mode) {
2649 if (tx_en) 4463 case PORT_HW_CFG_TX_LASER_MDIO:
2650 val &= ~(1<<15); 4464
2651 else 4465 bnx2x_cl45_read(bp, phy,
2652 val |= (1<<15); 4466 MDIO_PMA_DEVAD,
4467 MDIO_PMA_REG_PHY_IDENTIFIER,
4468 &val);
4469
4470 if (tx_en)
4471 val &= ~(1<<15);
4472 else
4473 val |= (1<<15);
4474
4475 bnx2x_cl45_write(bp, phy,
4476 MDIO_PMA_DEVAD,
4477 MDIO_PMA_REG_PHY_IDENTIFIER,
4478 val);
4479 break;
4480 case PORT_HW_CFG_TX_LASER_GPIO0:
4481 case PORT_HW_CFG_TX_LASER_GPIO1:
4482 case PORT_HW_CFG_TX_LASER_GPIO2:
4483 case PORT_HW_CFG_TX_LASER_GPIO3:
4484 {
4485 u16 gpio_pin;
4486 u8 gpio_port, gpio_mode;
4487 if (tx_en)
4488 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
4489 else
4490 gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
2653 4491
2654 bnx2x_cl45_write(bp, port, 4492 gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
2655 ext_phy_type, 4493 gpio_port = bnx2x_get_gpio_port(params);
2656 ext_phy_addr, 4494 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
2657 MDIO_PMA_DEVAD, 4495 break;
2658 MDIO_PMA_REG_PHY_IDENTIFIER, 4496 }
2659 val); 4497 default:
4498 DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
4499 break;
4500 }
2660} 4501}
2661 4502
2662static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params, 4503static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2663 u16 addr, u8 byte_cnt, u8 *o_buf) 4504 struct link_params *params,
4505 u16 addr, u8 byte_cnt, u8 *o_buf)
2664{ 4506{
2665 struct bnx2x *bp = params->bp; 4507 struct bnx2x *bp = params->bp;
2666 u16 val = 0; 4508 u16 val = 0;
2667 u16 i; 4509 u16 i;
2668 u8 port = params->port;
2669 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2670 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2671
2672 if (byte_cnt > 16) { 4510 if (byte_cnt > 16) {
2673 DP(NETIF_MSG_LINK, "Reading from eeprom is" 4511 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2674 " is limited to 0xf\n"); 4512 " is limited to 0xf\n");
2675 return -EINVAL; 4513 return -EINVAL;
2676 } 4514 }
2677 /* Set the read command byte count */ 4515 /* Set the read command byte count */
2678 bnx2x_cl45_write(bp, port, 4516 bnx2x_cl45_write(bp, phy,
2679 ext_phy_type, 4517 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2680 ext_phy_addr, 4518 (byte_cnt | 0xa000));
2681 MDIO_PMA_DEVAD,
2682 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2683 (byte_cnt | 0xa000));
2684 4519
2685 /* Set the read command address */ 4520 /* Set the read command address */
2686 bnx2x_cl45_write(bp, port, 4521 bnx2x_cl45_write(bp, phy,
2687 ext_phy_type, 4522 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2688 ext_phy_addr, 4523 addr);
2689 MDIO_PMA_DEVAD,
2690 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2691 addr);
2692 4524
2693 /* Activate read command */ 4525 /* Activate read command */
2694 bnx2x_cl45_write(bp, port, 4526 bnx2x_cl45_write(bp, phy,
2695 ext_phy_type, 4527 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2696 ext_phy_addr, 4528 0x2c0f);
2697 MDIO_PMA_DEVAD,
2698 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2699 0x2c0f);
2700 4529
2701 /* Wait up to 500us for command complete status */ 4530 /* Wait up to 500us for command complete status */
2702 for (i = 0; i < 100; i++) { 4531 for (i = 0; i < 100; i++) {
2703 bnx2x_cl45_read(bp, port, 4532 bnx2x_cl45_read(bp, phy,
2704 ext_phy_type, 4533 MDIO_PMA_DEVAD,
2705 ext_phy_addr, 4534 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2706 MDIO_PMA_DEVAD,
2707 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2708 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 4535 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2709 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) 4536 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2710 break; 4537 break;
@@ -2721,36 +4548,30 @@ static u8 bnx2x_8726_read_sfp_module_eeprom(struct link_params *params,
2721 4548
2722 /* Read the buffer */ 4549 /* Read the buffer */
2723 for (i = 0; i < byte_cnt; i++) { 4550 for (i = 0; i < byte_cnt; i++) {
2724 bnx2x_cl45_read(bp, port, 4551 bnx2x_cl45_read(bp, phy,
2725 ext_phy_type, 4552 MDIO_PMA_DEVAD,
2726 ext_phy_addr, 4553 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2727 MDIO_PMA_DEVAD,
2728 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2729 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK); 4554 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2730 } 4555 }
2731 4556
2732 for (i = 0; i < 100; i++) { 4557 for (i = 0; i < 100; i++) {
2733 bnx2x_cl45_read(bp, port, 4558 bnx2x_cl45_read(bp, phy,
2734 ext_phy_type, 4559 MDIO_PMA_DEVAD,
2735 ext_phy_addr, 4560 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2736 MDIO_PMA_DEVAD,
2737 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2738 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 4561 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2739 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) 4562 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2740 return 0;; 4563 return 0;
2741 msleep(1); 4564 msleep(1);
2742 } 4565 }
2743 return -EINVAL; 4566 return -EINVAL;
2744} 4567}
2745 4568
2746static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params, 4569static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2747 u16 addr, u8 byte_cnt, u8 *o_buf) 4570 struct link_params *params,
4571 u16 addr, u8 byte_cnt, u8 *o_buf)
2748{ 4572{
2749 struct bnx2x *bp = params->bp; 4573 struct bnx2x *bp = params->bp;
2750 u16 val, i; 4574 u16 val, i;
2751 u8 port = params->port;
2752 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
2753 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2754 4575
2755 if (byte_cnt > 16) { 4576 if (byte_cnt > 16) {
2756 DP(NETIF_MSG_LINK, "Reading from eeprom is" 4577 DP(NETIF_MSG_LINK, "Reading from eeprom is"
@@ -2759,54 +4580,44 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2759 } 4580 }
2760 4581
2761 /* Need to read from 1.8000 to clear it */ 4582 /* Need to read from 1.8000 to clear it */
2762 bnx2x_cl45_read(bp, port, 4583 bnx2x_cl45_read(bp, phy,
2763 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 4584 MDIO_PMA_DEVAD,
2764 ext_phy_addr, 4585 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2765 MDIO_PMA_DEVAD, 4586 &val);
2766 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2767 &val);
2768 4587
2769 /* Set the read command byte count */ 4588 /* Set the read command byte count */
2770 bnx2x_cl45_write(bp, port, 4589 bnx2x_cl45_write(bp, phy,
2771 ext_phy_type, 4590 MDIO_PMA_DEVAD,
2772 ext_phy_addr, 4591 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2773 MDIO_PMA_DEVAD, 4592 ((byte_cnt < 2) ? 2 : byte_cnt));
2774 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2775 ((byte_cnt < 2) ? 2 : byte_cnt));
2776 4593
2777 /* Set the read command address */ 4594 /* Set the read command address */
2778 bnx2x_cl45_write(bp, port, 4595 bnx2x_cl45_write(bp, phy,
2779 ext_phy_type, 4596 MDIO_PMA_DEVAD,
2780 ext_phy_addr, 4597 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2781 MDIO_PMA_DEVAD, 4598 addr);
2782 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2783 addr);
2784 /* Set the destination address */ 4599 /* Set the destination address */
2785 bnx2x_cl45_write(bp, port, 4600 bnx2x_cl45_write(bp, phy,
2786 ext_phy_type, 4601 MDIO_PMA_DEVAD,
2787 ext_phy_addr, 4602 0x8004,
2788 MDIO_PMA_DEVAD, 4603 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2789 0x8004,
2790 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2791 4604
2792 /* Activate read command */ 4605 /* Activate read command */
2793 bnx2x_cl45_write(bp, port, 4606 bnx2x_cl45_write(bp, phy,
2794 ext_phy_type, 4607 MDIO_PMA_DEVAD,
2795 ext_phy_addr, 4608 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2796 MDIO_PMA_DEVAD, 4609 0x8002);
2797 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, 4610 /*
2798 0x8002); 4611 * Wait appropriate time for two-wire command to finish before
2799 /* Wait appropriate time for two-wire command to finish before 4612 * polling the status register
2800 polling the status register */ 4613 */
2801 msleep(1); 4614 msleep(1);
2802 4615
2803 /* Wait up to 500us for command complete status */ 4616 /* Wait up to 500us for command complete status */
2804 for (i = 0; i < 100; i++) { 4617 for (i = 0; i < 100; i++) {
2805 bnx2x_cl45_read(bp, port, 4618 bnx2x_cl45_read(bp, phy,
2806 ext_phy_type, 4619 MDIO_PMA_DEVAD,
2807 ext_phy_addr, 4620 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2808 MDIO_PMA_DEVAD,
2809 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2810 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 4621 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2811 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) 4622 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2812 break; 4623 break;
@@ -2818,60 +4629,57 @@ static u8 bnx2x_8727_read_sfp_module_eeprom(struct link_params *params,
2818 DP(NETIF_MSG_LINK, 4629 DP(NETIF_MSG_LINK,
2819 "Got bad status 0x%x when reading from SFP+ EEPROM\n", 4630 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2820 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK)); 4631 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2821 return -EINVAL; 4632 return -EFAULT;
2822 } 4633 }
2823 4634
2824 /* Read the buffer */ 4635 /* Read the buffer */
2825 for (i = 0; i < byte_cnt; i++) { 4636 for (i = 0; i < byte_cnt; i++) {
2826 bnx2x_cl45_read(bp, port, 4637 bnx2x_cl45_read(bp, phy,
2827 ext_phy_type, 4638 MDIO_PMA_DEVAD,
2828 ext_phy_addr, 4639 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2829 MDIO_PMA_DEVAD,
2830 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2831 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK); 4640 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2832 } 4641 }
2833 4642
2834 for (i = 0; i < 100; i++) { 4643 for (i = 0; i < 100; i++) {
2835 bnx2x_cl45_read(bp, port, 4644 bnx2x_cl45_read(bp, phy,
2836 ext_phy_type, 4645 MDIO_PMA_DEVAD,
2837 ext_phy_addr, 4646 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2838 MDIO_PMA_DEVAD,
2839 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2840 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) == 4647 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2841 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE) 4648 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
2842 return 0;; 4649 return 0;
2843 msleep(1); 4650 msleep(1);
2844 } 4651 }
2845 4652
2846 return -EINVAL; 4653 return -EINVAL;
2847} 4654}
2848 4655
2849u8 bnx2x_read_sfp_module_eeprom(struct link_params *params, u16 addr, 4656u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2850 u8 byte_cnt, u8 *o_buf) 4657 struct link_params *params, u16 addr,
4658 u8 byte_cnt, u8 *o_buf)
2851{ 4659{
2852 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 4660 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2853 4661 return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
2854 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) 4662 byte_cnt, o_buf);
2855 return bnx2x_8726_read_sfp_module_eeprom(params, addr, 4663 else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2856 byte_cnt, o_buf); 4664 return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
2857 else if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) 4665 byte_cnt, o_buf);
2858 return bnx2x_8727_read_sfp_module_eeprom(params, addr,
2859 byte_cnt, o_buf);
2860 return -EINVAL; 4666 return -EINVAL;
2861} 4667}
2862 4668
2863static u8 bnx2x_get_edc_mode(struct link_params *params, 4669static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
2864 u16 *edc_mode) 4670 struct link_params *params,
4671 u16 *edc_mode)
2865{ 4672{
2866 struct bnx2x *bp = params->bp; 4673 struct bnx2x *bp = params->bp;
2867 u8 val, check_limiting_mode = 0; 4674 u8 val, check_limiting_mode = 0;
2868 *edc_mode = EDC_MODE_LIMITING; 4675 *edc_mode = EDC_MODE_LIMITING;
2869 4676
2870 /* First check for copper cable */ 4677 /* First check for copper cable */
2871 if (bnx2x_read_sfp_module_eeprom(params, 4678 if (bnx2x_read_sfp_module_eeprom(phy,
2872 SFP_EEPROM_CON_TYPE_ADDR, 4679 params,
2873 1, 4680 SFP_EEPROM_CON_TYPE_ADDR,
2874 &val) != 0) { 4681 1,
4682 &val) != 0) {
2875 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n"); 4683 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
2876 return -EINVAL; 4684 return -EINVAL;
2877 } 4685 }
@@ -2881,9 +4689,12 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
2881 { 4689 {
2882 u8 copper_module_type; 4690 u8 copper_module_type;
2883 4691
2884 /* Check if its active cable( includes SFP+ module) 4692 /*
2885 of passive cable*/ 4693 * Check if its active cable (includes SFP+ module)
2886 if (bnx2x_read_sfp_module_eeprom(params, 4694 * of passive cable
4695 */
4696 if (bnx2x_read_sfp_module_eeprom(phy,
4697 params,
2887 SFP_EEPROM_FC_TX_TECH_ADDR, 4698 SFP_EEPROM_FC_TX_TECH_ADDR,
2888 1, 4699 1,
2889 &copper_module_type) != 4700 &copper_module_type) !=
@@ -2923,10 +4734,11 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
2923 4734
2924 if (check_limiting_mode) { 4735 if (check_limiting_mode) {
2925 u8 options[SFP_EEPROM_OPTIONS_SIZE]; 4736 u8 options[SFP_EEPROM_OPTIONS_SIZE];
2926 if (bnx2x_read_sfp_module_eeprom(params, 4737 if (bnx2x_read_sfp_module_eeprom(phy,
2927 SFP_EEPROM_OPTIONS_ADDR, 4738 params,
2928 SFP_EEPROM_OPTIONS_SIZE, 4739 SFP_EEPROM_OPTIONS_ADDR,
2929 options) != 0) { 4740 SFP_EEPROM_OPTIONS_SIZE,
4741 options) != 0) {
2930 DP(NETIF_MSG_LINK, "Failed to read Option" 4742 DP(NETIF_MSG_LINK, "Failed to read Option"
2931 " field from module EEPROM\n"); 4743 " field from module EEPROM\n");
2932 return -EINVAL; 4744 return -EINVAL;
@@ -2939,17 +4751,19 @@ static u8 bnx2x_get_edc_mode(struct link_params *params,
2939 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode); 4751 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
2940 return 0; 4752 return 0;
2941} 4753}
2942 4754/*
2943/* This function read the relevant field from the module ( SFP+ ), 4755 * This function read the relevant field from the module (SFP+), and verify it
2944 and verify it is compliant with this board */ 4756 * is compliant with this board
2945static u8 bnx2x_verify_sfp_module(struct link_params *params) 4757 */
4758static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
4759 struct link_params *params)
2946{ 4760{
2947 struct bnx2x *bp = params->bp; 4761 struct bnx2x *bp = params->bp;
2948 u32 val; 4762 u32 val, cmd;
2949 u32 fw_resp; 4763 u32 fw_resp, fw_cmd_param;
2950 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1]; 4764 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2951 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1]; 4765 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2952 4766 phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
2953 val = REG_RD(bp, params->shmem_base + 4767 val = REG_RD(bp, params->shmem_base +
2954 offsetof(struct shmem_region, dev_info. 4768 offsetof(struct shmem_region, dev_info.
2955 port_feature_config[params->port].config)); 4769 port_feature_config[params->port].config));
@@ -2959,162 +4773,72 @@ static u8 bnx2x_verify_sfp_module(struct link_params *params)
2959 return 0; 4773 return 0;
2960 } 4774 }
2961 4775
2962 /* Ask the FW to validate the module */ 4776 if (params->feature_config_flags &
2963 if (!(params->feature_config_flags & 4777 FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
2964 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) { 4778 /* Use specific phy request */
4779 cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
4780 } else if (params->feature_config_flags &
4781 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
4782 /* Use first phy request only in case of non-dual media*/
4783 if (DUAL_MEDIA(params)) {
4784 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
4785 "verification\n");
4786 return -EINVAL;
4787 }
4788 cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
4789 } else {
4790 /* No support in OPT MDL detection */
2965 DP(NETIF_MSG_LINK, "FW does not support OPT MDL " 4791 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2966 "verification\n"); 4792 "verification\n");
2967 return -EINVAL; 4793 return -EINVAL;
2968 } 4794 }
2969 4795
2970 fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL); 4796 fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
4797 fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
2971 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) { 4798 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2972 DP(NETIF_MSG_LINK, "Approved module\n"); 4799 DP(NETIF_MSG_LINK, "Approved module\n");
2973 return 0; 4800 return 0;
2974 } 4801 }
2975 4802
2976 /* format the warning message */ 4803 /* format the warning message */
2977 if (bnx2x_read_sfp_module_eeprom(params, 4804 if (bnx2x_read_sfp_module_eeprom(phy,
2978 SFP_EEPROM_VENDOR_NAME_ADDR, 4805 params,
2979 SFP_EEPROM_VENDOR_NAME_SIZE, 4806 SFP_EEPROM_VENDOR_NAME_ADDR,
2980 (u8 *)vendor_name)) 4807 SFP_EEPROM_VENDOR_NAME_SIZE,
4808 (u8 *)vendor_name))
2981 vendor_name[0] = '\0'; 4809 vendor_name[0] = '\0';
2982 else 4810 else
2983 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0'; 4811 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
2984 if (bnx2x_read_sfp_module_eeprom(params, 4812 if (bnx2x_read_sfp_module_eeprom(phy,
2985 SFP_EEPROM_PART_NO_ADDR, 4813 params,
2986 SFP_EEPROM_PART_NO_SIZE, 4814 SFP_EEPROM_PART_NO_ADDR,
2987 (u8 *)vendor_pn)) 4815 SFP_EEPROM_PART_NO_SIZE,
4816 (u8 *)vendor_pn))
2988 vendor_pn[0] = '\0'; 4817 vendor_pn[0] = '\0';
2989 else 4818 else
2990 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0'; 4819 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
2991 4820
2992 netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected, Port %d from %s part number %s\n", 4821 netdev_err(bp->dev, "Warning: Unqualified SFP+ module detected,"
2993 params->port, vendor_name, vendor_pn); 4822 " Port %d from %s part number %s\n",
4823 params->port, vendor_name, vendor_pn);
4824 phy->flags |= FLAGS_SFP_NOT_APPROVED;
2994 return -EINVAL; 4825 return -EINVAL;
2995} 4826}
2996 4827
2997static u8 bnx2x_bcm8726_set_limiting_mode(struct link_params *params, 4828static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
2998 u16 edc_mode) 4829 struct link_params *params)
2999{
3000 struct bnx2x *bp = params->bp;
3001 u8 port = params->port;
3002 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3003 u16 cur_limiting_mode;
3004
3005 bnx2x_cl45_read(bp, port,
3006 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3007 ext_phy_addr,
3008 MDIO_PMA_DEVAD,
3009 MDIO_PMA_REG_ROM_VER2,
3010 &cur_limiting_mode);
3011 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
3012 cur_limiting_mode);
3013
3014 if (edc_mode == EDC_MODE_LIMITING) {
3015 DP(NETIF_MSG_LINK,
3016 "Setting LIMITING MODE\n");
3017 bnx2x_cl45_write(bp, port,
3018 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3019 ext_phy_addr,
3020 MDIO_PMA_DEVAD,
3021 MDIO_PMA_REG_ROM_VER2,
3022 EDC_MODE_LIMITING);
3023 } else { /* LRM mode ( default )*/
3024
3025 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
3026
3027 /* Changing to LRM mode takes quite few seconds.
3028 So do it only if current mode is limiting
3029 ( default is LRM )*/
3030 if (cur_limiting_mode != EDC_MODE_LIMITING)
3031 return 0;
3032
3033 bnx2x_cl45_write(bp, port,
3034 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3035 ext_phy_addr,
3036 MDIO_PMA_DEVAD,
3037 MDIO_PMA_REG_LRM_MODE,
3038 0);
3039 bnx2x_cl45_write(bp, port,
3040 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3041 ext_phy_addr,
3042 MDIO_PMA_DEVAD,
3043 MDIO_PMA_REG_ROM_VER2,
3044 0x128);
3045 bnx2x_cl45_write(bp, port,
3046 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3047 ext_phy_addr,
3048 MDIO_PMA_DEVAD,
3049 MDIO_PMA_REG_MISC_CTRL0,
3050 0x4008);
3051 bnx2x_cl45_write(bp, port,
3052 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
3053 ext_phy_addr,
3054 MDIO_PMA_DEVAD,
3055 MDIO_PMA_REG_LRM_MODE,
3056 0xaaaa);
3057 }
3058 return 0;
3059}
3060
3061static u8 bnx2x_bcm8727_set_limiting_mode(struct link_params *params,
3062 u16 edc_mode)
3063{
3064 struct bnx2x *bp = params->bp;
3065 u8 port = params->port;
3066 u16 phy_identifier;
3067 u16 rom_ver2_val;
3068 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3069
3070 bnx2x_cl45_read(bp, port,
3071 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3072 ext_phy_addr,
3073 MDIO_PMA_DEVAD,
3074 MDIO_PMA_REG_PHY_IDENTIFIER,
3075 &phy_identifier);
3076
3077 bnx2x_cl45_write(bp, port,
3078 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3079 ext_phy_addr,
3080 MDIO_PMA_DEVAD,
3081 MDIO_PMA_REG_PHY_IDENTIFIER,
3082 (phy_identifier & ~(1<<9)));
3083
3084 bnx2x_cl45_read(bp, port,
3085 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3086 ext_phy_addr,
3087 MDIO_PMA_DEVAD,
3088 MDIO_PMA_REG_ROM_VER2,
3089 &rom_ver2_val);
3090 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
3091 bnx2x_cl45_write(bp, port,
3092 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3093 ext_phy_addr,
3094 MDIO_PMA_DEVAD,
3095 MDIO_PMA_REG_ROM_VER2,
3096 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
3097
3098 bnx2x_cl45_write(bp, port,
3099 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
3100 ext_phy_addr,
3101 MDIO_PMA_DEVAD,
3102 MDIO_PMA_REG_PHY_IDENTIFIER,
3103 (phy_identifier | (1<<9)));
3104
3105 return 0;
3106}
3107
3108 4830
3109static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
3110{ 4831{
3111 u8 val; 4832 u8 val;
3112 struct bnx2x *bp = params->bp; 4833 struct bnx2x *bp = params->bp;
3113 u16 timeout; 4834 u16 timeout;
3114 /* Initialization time after hot-plug may take up to 300ms for some 4835 /*
3115 phys type ( e.g. JDSU ) */ 4836 * Initialization time after hot-plug may take up to 300ms for
4837 * some phys type ( e.g. JDSU )
4838 */
4839
3116 for (timeout = 0; timeout < 60; timeout++) { 4840 for (timeout = 0; timeout < 60; timeout++) {
3117 if (bnx2x_read_sfp_module_eeprom(params, 1, 1, &val) 4841 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
3118 == 0) { 4842 == 0) {
3119 DP(NETIF_MSG_LINK, "SFP+ module initialization " 4843 DP(NETIF_MSG_LINK, "SFP+ module initialization "
3120 "took %d ms\n", timeout * 5); 4844 "took %d ms\n", timeout * 5);
@@ -3126,28 +4850,26 @@ static u8 bnx2x_wait_for_sfp_module_initialized(struct link_params *params)
3126} 4850}
3127 4851
3128static void bnx2x_8727_power_module(struct bnx2x *bp, 4852static void bnx2x_8727_power_module(struct bnx2x *bp,
3129 struct link_params *params, 4853 struct bnx2x_phy *phy,
3130 u8 ext_phy_addr, u8 is_power_up) { 4854 u8 is_power_up) {
3131 /* Make sure GPIOs are not using for LED mode */ 4855 /* Make sure GPIOs are not using for LED mode */
3132 u16 val; 4856 u16 val;
3133 u8 port = params->port;
3134 /* 4857 /*
3135 * In the GPIO register, bit 4 is use to detemine if the GPIOs are 4858 * In the GPIO register, bit 4 is use to determine if the GPIOs are
3136 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for 4859 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
3137 * output 4860 * output
3138 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0 4861 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
3139 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1 4862 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
3140 * where the 1st bit is the over-current(only input), and 2nd bit is 4863 * where the 1st bit is the over-current(only input), and 2nd bit is
3141 * for power( only output ) 4864 * for power( only output )
3142 */ 4865 *
3143
3144 /*
3145 * In case of NOC feature is disabled and power is up, set GPIO control 4866 * In case of NOC feature is disabled and power is up, set GPIO control
3146 * as input to enable listening of over-current indication 4867 * as input to enable listening of over-current indication
3147 */ 4868 */
3148 4869 if (phy->flags & FLAGS_NOC)
3149 if (!(params->feature_config_flags & 4870 return;
3150 FEATURE_CONFIG_BCM8727_NOC) && is_power_up) 4871 if (!(phy->flags &
4872 FLAGS_NOC) && is_power_up)
3151 val = (1<<4); 4873 val = (1<<4);
3152 else 4874 else
3153 /* 4875 /*
@@ -3156,21 +4878,156 @@ static void bnx2x_8727_power_module(struct bnx2x *bp,
3156 */ 4878 */
3157 val = ((!(is_power_up)) << 1); 4879 val = ((!(is_power_up)) << 1);
3158 4880
3159 bnx2x_cl45_write(bp, port, 4881 bnx2x_cl45_write(bp, phy,
3160 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 4882 MDIO_PMA_DEVAD,
3161 ext_phy_addr, 4883 MDIO_PMA_REG_8727_GPIO_CTRL,
3162 MDIO_PMA_DEVAD, 4884 val);
3163 MDIO_PMA_REG_8727_GPIO_CTRL, 4885}
3164 val); 4886
4887static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
4888 struct bnx2x_phy *phy,
4889 u16 edc_mode)
4890{
4891 u16 cur_limiting_mode;
4892
4893 bnx2x_cl45_read(bp, phy,
4894 MDIO_PMA_DEVAD,
4895 MDIO_PMA_REG_ROM_VER2,
4896 &cur_limiting_mode);
4897 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
4898 cur_limiting_mode);
4899
4900 if (edc_mode == EDC_MODE_LIMITING) {
4901 DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
4902 bnx2x_cl45_write(bp, phy,
4903 MDIO_PMA_DEVAD,
4904 MDIO_PMA_REG_ROM_VER2,
4905 EDC_MODE_LIMITING);
4906 } else { /* LRM mode ( default )*/
4907
4908 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
4909
4910 /*
4911 * Changing to LRM mode takes quite few seconds. So do it only
4912 * if current mode is limiting (default is LRM)
4913 */
4914 if (cur_limiting_mode != EDC_MODE_LIMITING)
4915 return 0;
4916
4917 bnx2x_cl45_write(bp, phy,
4918 MDIO_PMA_DEVAD,
4919 MDIO_PMA_REG_LRM_MODE,
4920 0);
4921 bnx2x_cl45_write(bp, phy,
4922 MDIO_PMA_DEVAD,
4923 MDIO_PMA_REG_ROM_VER2,
4924 0x128);
4925 bnx2x_cl45_write(bp, phy,
4926 MDIO_PMA_DEVAD,
4927 MDIO_PMA_REG_MISC_CTRL0,
4928 0x4008);
4929 bnx2x_cl45_write(bp, phy,
4930 MDIO_PMA_DEVAD,
4931 MDIO_PMA_REG_LRM_MODE,
4932 0xaaaa);
4933 }
4934 return 0;
4935}
4936
4937static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
4938 struct bnx2x_phy *phy,
4939 u16 edc_mode)
4940{
4941 u16 phy_identifier;
4942 u16 rom_ver2_val;
4943 bnx2x_cl45_read(bp, phy,
4944 MDIO_PMA_DEVAD,
4945 MDIO_PMA_REG_PHY_IDENTIFIER,
4946 &phy_identifier);
4947
4948 bnx2x_cl45_write(bp, phy,
4949 MDIO_PMA_DEVAD,
4950 MDIO_PMA_REG_PHY_IDENTIFIER,
4951 (phy_identifier & ~(1<<9)));
4952
4953 bnx2x_cl45_read(bp, phy,
4954 MDIO_PMA_DEVAD,
4955 MDIO_PMA_REG_ROM_VER2,
4956 &rom_ver2_val);
4957 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
4958 bnx2x_cl45_write(bp, phy,
4959 MDIO_PMA_DEVAD,
4960 MDIO_PMA_REG_ROM_VER2,
4961 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
4962
4963 bnx2x_cl45_write(bp, phy,
4964 MDIO_PMA_DEVAD,
4965 MDIO_PMA_REG_PHY_IDENTIFIER,
4966 (phy_identifier | (1<<9)));
4967
4968 return 0;
3165} 4969}
3166 4970
3167static u8 bnx2x_sfp_module_detection(struct link_params *params) 4971static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
4972 struct link_params *params,
4973 u32 action)
4974{
4975 struct bnx2x *bp = params->bp;
4976
4977 switch (action) {
4978 case DISABLE_TX:
4979 bnx2x_sfp_set_transmitter(params, phy, 0);
4980 break;
4981 case ENABLE_TX:
4982 if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
4983 bnx2x_sfp_set_transmitter(params, phy, 1);
4984 break;
4985 default:
4986 DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
4987 action);
4988 return;
4989 }
4990}
4991
4992static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
4993 u8 gpio_mode)
4994{
4995 struct bnx2x *bp = params->bp;
4996
4997 u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
4998 offsetof(struct shmem_region,
4999 dev_info.port_hw_config[params->port].sfp_ctrl)) &
5000 PORT_HW_CFG_FAULT_MODULE_LED_MASK;
5001 switch (fault_led_gpio) {
5002 case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
5003 return;
5004 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
5005 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
5006 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
5007 case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
5008 {
5009 u8 gpio_port = bnx2x_get_gpio_port(params);
5010 u16 gpio_pin = fault_led_gpio -
5011 PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
5012 DP(NETIF_MSG_LINK, "Set fault module-detected led "
5013 "pin %x port %x mode %x\n",
5014 gpio_pin, gpio_port, gpio_mode);
5015 bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
5016 }
5017 break;
5018 default:
5019 DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
5020 fault_led_gpio);
5021 }
5022}
5023
5024static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
5025 struct link_params *params)
3168{ 5026{
3169 struct bnx2x *bp = params->bp; 5027 struct bnx2x *bp = params->bp;
3170 u16 edc_mode; 5028 u16 edc_mode;
3171 u8 rc = 0; 5029 u8 rc = 0;
3172 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5030
3173 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3174 u32 val = REG_RD(bp, params->shmem_base + 5031 u32 val = REG_RD(bp, params->shmem_base +
3175 offsetof(struct shmem_region, dev_info. 5032 offsetof(struct shmem_region, dev_info.
3176 port_feature_config[params->port].config)); 5033 port_feature_config[params->port].config));
@@ -3178,45 +5035,42 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
3178 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n", 5035 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
3179 params->port); 5036 params->port);
3180 5037
3181 if (bnx2x_get_edc_mode(params, &edc_mode) != 0) { 5038 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
3182 DP(NETIF_MSG_LINK, "Failed to get valid module type\n"); 5039 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
3183 return -EINVAL; 5040 return -EINVAL;
3184 } else if (bnx2x_verify_sfp_module(params) != 5041 } else if (bnx2x_verify_sfp_module(phy, params) != 0) {
3185 0) {
3186 /* check SFP+ module compatibility */ 5042 /* check SFP+ module compatibility */
3187 DP(NETIF_MSG_LINK, "Module verification failed!!\n"); 5043 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
3188 rc = -EINVAL; 5044 rc = -EINVAL;
3189 /* Turn on fault module-detected led */ 5045 /* Turn on fault module-detected led */
3190 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, 5046 bnx2x_set_sfp_module_fault_led(params,
3191 MISC_REGISTERS_GPIO_HIGH, 5047 MISC_REGISTERS_GPIO_HIGH);
3192 params->port); 5048
3193 if ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && 5049 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
3194 ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 5050 ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3195 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { 5051 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
3196 /* Shutdown SFP+ module */ 5052 /* Shutdown SFP+ module */
3197 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n"); 5053 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
3198 bnx2x_8727_power_module(bp, params, 5054 bnx2x_8727_power_module(bp, phy, 0);
3199 ext_phy_addr, 0);
3200 return rc; 5055 return rc;
3201 } 5056 }
3202 } else { 5057 } else {
3203 /* Turn off fault module-detected led */ 5058 /* Turn off fault module-detected led */
3204 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); 5059 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
3205 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
3206 MISC_REGISTERS_GPIO_LOW,
3207 params->port);
3208 } 5060 }
3209 5061
3210 /* power up the SFP module */ 5062 /* power up the SFP module */
3211 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) 5063 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
3212 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1); 5064 bnx2x_8727_power_module(bp, phy, 1);
3213 5065
3214 /* Check and set limiting mode / LRM mode on 8726. 5066 /*
3215 On 8727 it is done automatically */ 5067 * Check and set limiting mode / LRM mode on 8726. On 8727 it
3216 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) 5068 * is done automatically
3217 bnx2x_bcm8726_set_limiting_mode(params, edc_mode); 5069 */
5070 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
5071 bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
3218 else 5072 else
3219 bnx2x_bcm8727_set_limiting_mode(params, edc_mode); 5073 bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
3220 /* 5074 /*
3221 * Enable transmit for this module if the module is approved, or 5075 * Enable transmit for this module if the module is approved, or
3222 * if unapproved modules should also enable the Tx laser 5076 * if unapproved modules should also enable the Tx laser
@@ -3224,11 +5078,9 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
3224 if (rc == 0 || 5078 if (rc == 0 ||
3225 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != 5079 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
3226 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 5080 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3227 bnx2x_sfp_set_transmitter(bp, params->port, 5081 bnx2x_sfp_set_transmitter(params, phy, 1);
3228 ext_phy_type, ext_phy_addr, 1);
3229 else 5082 else
3230 bnx2x_sfp_set_transmitter(bp, params->port, 5083 bnx2x_sfp_set_transmitter(params, phy, 0);
3231 ext_phy_type, ext_phy_addr, 0);
3232 5084
3233 return rc; 5085 return rc;
3234} 5086}
@@ -3236,2729 +5088,2537 @@ static u8 bnx2x_sfp_module_detection(struct link_params *params)
3236void bnx2x_handle_module_detect_int(struct link_params *params) 5088void bnx2x_handle_module_detect_int(struct link_params *params)
3237{ 5089{
3238 struct bnx2x *bp = params->bp; 5090 struct bnx2x *bp = params->bp;
5091 struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
3239 u32 gpio_val; 5092 u32 gpio_val;
3240 u8 port = params->port; 5093 u8 port = params->port;
3241 5094
3242 /* Set valid module led off */ 5095 /* Set valid module led off */
3243 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, 5096 bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
3244 MISC_REGISTERS_GPIO_HIGH,
3245 params->port);
3246 5097
3247 /* Get current gpio val refelecting module plugged in / out*/ 5098 /* Get current gpio val reflecting module plugged in / out*/
3248 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); 5099 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
3249 5100
3250 /* Call the handling function in case module is detected */ 5101 /* Call the handling function in case module is detected */
3251 if (gpio_val == 0) { 5102 if (gpio_val == 0) {
3252 5103
3253 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, 5104 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3254 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR, 5105 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
3255 port); 5106 port);
3256 5107
3257 if (bnx2x_wait_for_sfp_module_initialized(params) == 5108 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
3258 0) 5109 bnx2x_sfp_module_detection(phy, params);
3259 bnx2x_sfp_module_detection(params);
3260 else 5110 else
3261 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); 5111 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
3262 } else { 5112 } else {
3263 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3264
3265 u32 ext_phy_type =
3266 XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3267 u32 val = REG_RD(bp, params->shmem_base + 5113 u32 val = REG_RD(bp, params->shmem_base +
3268 offsetof(struct shmem_region, dev_info. 5114 offsetof(struct shmem_region, dev_info.
3269 port_feature_config[params->port]. 5115 port_feature_config[params->port].
3270 config)); 5116 config));
3271 5117
3272 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3, 5118 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
3273 MISC_REGISTERS_GPIO_INT_OUTPUT_SET, 5119 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
3274 port); 5120 port);
3275 /* Module was plugged out. */ 5121 /*
3276 /* Disable transmit for this module */ 5122 * Module was plugged out.
5123 * Disable transmit for this module
5124 */
3277 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 5125 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3278 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 5126 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
3279 bnx2x_sfp_set_transmitter(bp, params->port, 5127 bnx2x_sfp_set_transmitter(params, phy, 0);
3280 ext_phy_type, ext_phy_addr, 0);
3281 } 5128 }
3282} 5129}
3283 5130
3284static void bnx2x_bcm807x_force_10G(struct link_params *params) 5131/******************************************************************/
3285{ 5132/* common BCM8706/BCM8726 PHY SECTION */
3286 struct bnx2x *bp = params->bp; 5133/******************************************************************/
3287 u8 port = params->port; 5134static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
3288 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5135 struct link_params *params,
3289 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 5136 struct link_vars *vars)
3290
3291 /* Force KR or KX */
3292 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3293 MDIO_PMA_DEVAD,
3294 MDIO_PMA_REG_CTRL,
3295 0x2040);
3296 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3297 MDIO_PMA_DEVAD,
3298 MDIO_PMA_REG_10G_CTRL2,
3299 0x000b);
3300 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3301 MDIO_PMA_DEVAD,
3302 MDIO_PMA_REG_BCM_CTRL,
3303 0x0000);
3304 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3305 MDIO_AN_DEVAD,
3306 MDIO_AN_REG_CTRL,
3307 0x0000);
3308}
3309
3310static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
3311{ 5137{
5138 u8 link_up = 0;
5139 u16 val1, val2, rx_sd, pcs_status;
3312 struct bnx2x *bp = params->bp; 5140 struct bnx2x *bp = params->bp;
3313 u8 port = params->port; 5141 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3314 u16 val; 5142 /* Clear RX Alarm*/
3315 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5143 bnx2x_cl45_read(bp, phy,
3316 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 5144 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
3317 5145 /* clear LASI indication*/
3318 bnx2x_cl45_read(bp, params->port, 5146 bnx2x_cl45_read(bp, phy,
3319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 5147 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3320 ext_phy_addr, 5148 bnx2x_cl45_read(bp, phy,
3321 MDIO_PMA_DEVAD, 5149 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
3322 MDIO_PMA_REG_8073_CHIP_REV, &val); 5150 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
3323 5151
3324 if (val == 0) { 5152 bnx2x_cl45_read(bp, phy,
3325 /* Mustn't set low power mode in 8073 A0 */ 5153 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3326 return; 5154 bnx2x_cl45_read(bp, phy,
5155 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
5156 bnx2x_cl45_read(bp, phy,
5157 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5158 bnx2x_cl45_read(bp, phy,
5159 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
5160
5161 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
5162 " link_status 0x%x\n", rx_sd, pcs_status, val2);
5163 /*
5164 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
5165 * are set, or if the autoneg bit 1 is set
5166 */
5167 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
5168 if (link_up) {
5169 if (val2 & (1<<1))
5170 vars->line_speed = SPEED_1000;
5171 else
5172 vars->line_speed = SPEED_10000;
5173 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5174 vars->duplex = DUPLEX_FULL;
3327 } 5175 }
3328 5176 return link_up;
3329 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
3330 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3331 MDIO_XS_DEVAD,
3332 MDIO_XS_PLL_SEQUENCER, &val);
3333 val &= ~(1<<13);
3334 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3335 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3336
3337 /* PLL controls */
3338 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3339 MDIO_XS_DEVAD, 0x805E, 0x1077);
3340 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3341 MDIO_XS_DEVAD, 0x805D, 0x0000);
3342 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3343 MDIO_XS_DEVAD, 0x805C, 0x030B);
3344 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3345 MDIO_XS_DEVAD, 0x805B, 0x1240);
3346 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3347 MDIO_XS_DEVAD, 0x805A, 0x2490);
3348
3349 /* Tx Controls */
3350 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3351 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
3352 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3353 MDIO_XS_DEVAD, 0x80A6, 0x9041);
3354 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3355 MDIO_XS_DEVAD, 0x80A5, 0x4640);
3356
3357 /* Rx Controls */
3358 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3359 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
3360 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3361 MDIO_XS_DEVAD, 0x80FD, 0x9249);
3362 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3363 MDIO_XS_DEVAD, 0x80FC, 0x2015);
3364
3365 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
3366 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
3367 MDIO_XS_DEVAD,
3368 MDIO_XS_PLL_SEQUENCER, &val);
3369 val |= (1<<13);
3370 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
3371 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
3372} 5177}
3373 5178
3374static void bnx2x_8073_set_pause_cl37(struct link_params *params, 5179/******************************************************************/
3375 struct link_vars *vars) 5180/* BCM8706 PHY SECTION */
5181/******************************************************************/
5182static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
5183 struct link_params *params,
5184 struct link_vars *vars)
3376{ 5185{
5186 u32 tx_en_mode;
5187 u16 cnt, val, tmp1;
3377 struct bnx2x *bp = params->bp; 5188 struct bnx2x *bp = params->bp;
3378 u16 cl37_val; 5189 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3379 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5190 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3380 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 5191 /* HW reset */
3381 5192 bnx2x_ext_phy_hw_reset(bp, params->port);
3382 bnx2x_cl45_read(bp, params->port, 5193 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3383 ext_phy_type, 5194 bnx2x_wait_reset_complete(bp, phy, params);
3384 ext_phy_addr,
3385 MDIO_AN_DEVAD,
3386 MDIO_AN_REG_CL37_FC_LD, &cl37_val);
3387
3388 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3389 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3390 5195
3391 if ((vars->ieee_fc & 5196 /* Wait until fw is loaded */
3392 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) == 5197 for (cnt = 0; cnt < 100; cnt++) {
3393 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) { 5198 bnx2x_cl45_read(bp, phy,
3394 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC; 5199 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
5200 if (val)
5201 break;
5202 msleep(10);
3395 } 5203 }
3396 if ((vars->ieee_fc & 5204 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
3397 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) == 5205 if ((params->feature_config_flags &
3398 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) { 5206 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3399 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC; 5207 u8 i;
5208 u16 reg;
5209 for (i = 0; i < 4; i++) {
5210 reg = MDIO_XS_8706_REG_BANK_RX0 +
5211 i*(MDIO_XS_8706_REG_BANK_RX1 -
5212 MDIO_XS_8706_REG_BANK_RX0);
5213 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
5214 /* Clear first 3 bits of the control */
5215 val &= ~0x7;
5216 /* Set control bits according to configuration */
5217 val |= (phy->rx_preemphasis[i] & 0x7);
5218 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
5219 " reg 0x%x <-- val 0x%x\n", reg, val);
5220 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
5221 }
3400 } 5222 }
3401 if ((vars->ieee_fc & 5223 /* Force speed */
3402 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) == 5224 if (phy->req_line_speed == SPEED_10000) {
3403 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) { 5225 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3404 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH; 5226
5227 bnx2x_cl45_write(bp, phy,
5228 MDIO_PMA_DEVAD,
5229 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
5230 bnx2x_cl45_write(bp, phy,
5231 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5232 } else {
5233 /* Force 1Gbps using autoneg with 1G advertisement */
5234
5235 /* Allow CL37 through CL73 */
5236 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
5237 bnx2x_cl45_write(bp, phy,
5238 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5239
5240 /* Enable Full-Duplex advertisement on CL37 */
5241 bnx2x_cl45_write(bp, phy,
5242 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
5243 /* Enable CL37 AN */
5244 bnx2x_cl45_write(bp, phy,
5245 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5246 /* 1G support */
5247 bnx2x_cl45_write(bp, phy,
5248 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
5249
5250 /* Enable clause 73 AN */
5251 bnx2x_cl45_write(bp, phy,
5252 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5253 bnx2x_cl45_write(bp, phy,
5254 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5255 0x0400);
5256 bnx2x_cl45_write(bp, phy,
5257 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5258 0x0004);
3405 } 5259 }
3406 DP(NETIF_MSG_LINK, 5260 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
3407 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3408
3409 bnx2x_cl45_write(bp, params->port,
3410 ext_phy_type,
3411 ext_phy_addr,
3412 MDIO_AN_DEVAD,
3413 MDIO_AN_REG_CL37_FC_LD, cl37_val);
3414 msleep(500);
3415}
3416
3417static void bnx2x_ext_phy_set_pause(struct link_params *params,
3418 struct link_vars *vars)
3419{
3420 struct bnx2x *bp = params->bp;
3421 u16 val;
3422 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
3423 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3424
3425 /* read modify write pause advertizing */
3426 bnx2x_cl45_read(bp, params->port,
3427 ext_phy_type,
3428 ext_phy_addr,
3429 MDIO_AN_DEVAD,
3430 MDIO_AN_REG_ADV_PAUSE, &val);
3431 5261
3432 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH; 5262 /*
3433 5263 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
3434 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */ 5264 * power mode, if TX Laser is disabled
3435 5265 */
3436 if ((vars->ieee_fc &
3437 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3438 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3439 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3440 }
3441 if ((vars->ieee_fc &
3442 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3443 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3444 val |=
3445 MDIO_AN_REG_ADV_PAUSE_PAUSE;
3446 }
3447 DP(NETIF_MSG_LINK,
3448 "Ext phy AN advertize 0x%x\n", val);
3449 bnx2x_cl45_write(bp, params->port,
3450 ext_phy_type,
3451 ext_phy_addr,
3452 MDIO_AN_DEVAD,
3453 MDIO_AN_REG_ADV_PAUSE, val);
3454}
3455static void bnx2x_set_preemphasis(struct link_params *params)
3456{
3457 u16 bank, i = 0;
3458 struct bnx2x *bp = params->bp;
3459 5266
3460 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3; 5267 tx_en_mode = REG_RD(bp, params->shmem_base +
3461 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) { 5268 offsetof(struct shmem_region,
3462 CL45_WR_OVER_CL22(bp, params->port, 5269 dev_info.port_hw_config[params->port].sfp_ctrl))
3463 params->phy_addr, 5270 & PORT_HW_CFG_TX_LASER_MASK;
3464 bank, 5271
3465 MDIO_RX0_RX_EQ_BOOST, 5272 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
3466 params->xgxs_config_rx[i]); 5273 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
5274 bnx2x_cl45_read(bp, phy,
5275 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
5276 tmp1 |= 0x1;
5277 bnx2x_cl45_write(bp, phy,
5278 MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
3467 } 5279 }
3468 5280
3469 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3; 5281 return 0;
3470 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
3471 CL45_WR_OVER_CL22(bp, params->port,
3472 params->phy_addr,
3473 bank,
3474 MDIO_TX0_TX_DRIVER,
3475 params->xgxs_config_tx[i]);
3476 }
3477} 5282}
3478 5283
3479 5284static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
3480static void bnx2x_8481_set_led4(struct link_params *params, 5285 struct link_params *params,
3481 u32 ext_phy_type, u8 ext_phy_addr) 5286 struct link_vars *vars)
3482{
3483 struct bnx2x *bp = params->bp;
3484
3485 /* PHYC_CTL_LED_CTL */
3486 bnx2x_cl45_write(bp, params->port,
3487 ext_phy_type,
3488 ext_phy_addr,
3489 MDIO_PMA_DEVAD,
3490 MDIO_PMA_REG_8481_LINK_SIGNAL, 0xa482);
3491
3492 /* Unmask LED4 for 10G link */
3493 bnx2x_cl45_write(bp, params->port,
3494 ext_phy_type,
3495 ext_phy_addr,
3496 MDIO_PMA_DEVAD,
3497 MDIO_PMA_REG_8481_SIGNAL_MASK, (1<<6));
3498 /* 'Interrupt Mask' */
3499 bnx2x_cl45_write(bp, params->port,
3500 ext_phy_type,
3501 ext_phy_addr,
3502 MDIO_AN_DEVAD,
3503 0xFFFB, 0xFFFD);
3504}
3505static void bnx2x_8481_set_legacy_led_mode(struct link_params *params,
3506 u32 ext_phy_type, u8 ext_phy_addr)
3507{ 5287{
3508 struct bnx2x *bp = params->bp; 5288 return bnx2x_8706_8726_read_status(phy, params, vars);
3509
3510 /* LED1 (10G Link): Disable LED1 when 10/100/1000 link */
3511 /* LED2 (1G/100/10 Link): Enable LED2 when 10/100/1000 link) */
3512 bnx2x_cl45_write(bp, params->port,
3513 ext_phy_type,
3514 ext_phy_addr,
3515 MDIO_AN_DEVAD,
3516 MDIO_AN_REG_8481_LEGACY_SHADOW,
3517 (1<<15) | (0xd << 10) | (0xc<<4) | 0xe);
3518} 5289}
3519 5290
3520static void bnx2x_8481_set_10G_led_mode(struct link_params *params, 5291/******************************************************************/
3521 u32 ext_phy_type, u8 ext_phy_addr) 5292/* BCM8726 PHY SECTION */
5293/******************************************************************/
5294static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
5295 struct link_params *params)
3522{ 5296{
3523 struct bnx2x *bp = params->bp; 5297 struct bnx2x *bp = params->bp;
3524 u16 val1; 5298 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
5299 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
5300}
3525 5301
3526 /* LED1 (10G Link) */ 5302static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
3527 /* Enable continuse based on source 7(10G-link) */ 5303 struct link_params *params)
3528 bnx2x_cl45_read(bp, params->port,
3529 ext_phy_type,
3530 ext_phy_addr,
3531 MDIO_PMA_DEVAD,
3532 MDIO_PMA_REG_8481_LINK_SIGNAL,
3533 &val1);
3534 /* Set bit 2 to 0, and bits [1:0] to 10 */
3535 val1 &= ~((1<<0) | (1<<2) | (1<<7)); /* Clear bits 0,2,7*/
3536 val1 |= ((1<<1) | (1<<6)); /* Set bit 1, 6 */
3537
3538 bnx2x_cl45_write(bp, params->port,
3539 ext_phy_type,
3540 ext_phy_addr,
3541 MDIO_PMA_DEVAD,
3542 MDIO_PMA_REG_8481_LINK_SIGNAL,
3543 val1);
3544
3545 /* Unmask LED1 for 10G link */
3546 bnx2x_cl45_read(bp, params->port,
3547 ext_phy_type,
3548 ext_phy_addr,
3549 MDIO_PMA_DEVAD,
3550 MDIO_PMA_REG_8481_LED1_MASK,
3551 &val1);
3552 /* Set bit 2 to 0, and bits [1:0] to 10 */
3553 val1 |= (1<<7);
3554 bnx2x_cl45_write(bp, params->port,
3555 ext_phy_type,
3556 ext_phy_addr,
3557 MDIO_PMA_DEVAD,
3558 MDIO_PMA_REG_8481_LED1_MASK,
3559 val1);
3560
3561 /* LED2 (1G/100/10G Link) */
3562 /* Mask LED2 for 10G link */
3563 bnx2x_cl45_write(bp, params->port,
3564 ext_phy_type,
3565 ext_phy_addr,
3566 MDIO_PMA_DEVAD,
3567 MDIO_PMA_REG_8481_LED2_MASK,
3568 0);
3569
3570 /* Unmask LED3 for 10G link */
3571 bnx2x_cl45_write(bp, params->port,
3572 ext_phy_type,
3573 ext_phy_addr,
3574 MDIO_PMA_DEVAD,
3575 MDIO_PMA_REG_8481_LED3_MASK,
3576 0x6);
3577 bnx2x_cl45_write(bp, params->port,
3578 ext_phy_type,
3579 ext_phy_addr,
3580 MDIO_PMA_DEVAD,
3581 MDIO_PMA_REG_8481_LED3_BLINK,
3582 0);
3583}
3584
3585
3586static void bnx2x_init_internal_phy(struct link_params *params,
3587 struct link_vars *vars,
3588 u8 enable_cl73)
3589{ 5304{
3590 struct bnx2x *bp = params->bp; 5305 struct bnx2x *bp = params->bp;
5306 /* Need to wait 100ms after reset */
5307 msleep(100);
3591 5308
3592 if (!(vars->phy_flags & PHY_SGMII_FLAG)) { 5309 /* Micro controller re-boot */
3593 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 5310 bnx2x_cl45_write(bp, phy,
3594 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && 5311 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
3595 (params->feature_config_flags &
3596 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
3597 bnx2x_set_preemphasis(params);
3598 5312
3599 /* forced speed requested? */ 5313 /* Set soft reset */
3600 if (vars->line_speed != SPEED_AUTO_NEG || 5314 bnx2x_cl45_write(bp, phy,
3601 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) == 5315 MDIO_PMA_DEVAD,
3602 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) && 5316 MDIO_PMA_REG_GEN_CTRL,
3603 params->loopback_mode == LOOPBACK_EXT)) { 5317 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
3604 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3605 5318
3606 /* disable autoneg */ 5319 bnx2x_cl45_write(bp, phy,
3607 bnx2x_set_autoneg(params, vars, 0); 5320 MDIO_PMA_DEVAD,
5321 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
3608 5322
3609 /* program speed and duplex */ 5323 bnx2x_cl45_write(bp, phy,
3610 bnx2x_program_serdes(params, vars); 5324 MDIO_PMA_DEVAD,
5325 MDIO_PMA_REG_GEN_CTRL,
5326 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
3611 5327
3612 } else { /* AN_mode */ 5328 /* wait for 150ms for microcode load */
3613 DP(NETIF_MSG_LINK, "not SGMII, AN\n"); 5329 msleep(150);
3614
3615 /* AN enabled */
3616 bnx2x_set_brcm_cl37_advertisment(params);
3617 5330
3618 /* program duplex & pause advertisement (for aneg) */ 5331 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
3619 bnx2x_set_ieee_aneg_advertisment(params, 5332 bnx2x_cl45_write(bp, phy,
3620 vars->ieee_fc); 5333 MDIO_PMA_DEVAD,
5334 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
3621 5335
3622 /* enable autoneg */ 5336 msleep(200);
3623 bnx2x_set_autoneg(params, vars, enable_cl73); 5337 bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
5338}
3624 5339
3625 /* enable and restart AN */ 5340static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
3626 bnx2x_restart_autoneg(params, enable_cl73); 5341 struct link_params *params,
5342 struct link_vars *vars)
5343{
5344 struct bnx2x *bp = params->bp;
5345 u16 val1;
5346 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
5347 if (link_up) {
5348 bnx2x_cl45_read(bp, phy,
5349 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
5350 &val1);
5351 if (val1 & (1<<15)) {
5352 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5353 link_up = 0;
5354 vars->line_speed = 0;
3627 } 5355 }
3628
3629 } else { /* SGMII mode */
3630 DP(NETIF_MSG_LINK, "SGMII\n");
3631
3632 bnx2x_initialize_sgmii_process(params, vars);
3633 } 5356 }
5357 return link_up;
3634} 5358}
3635 5359
3636static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars) 5360
5361static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
5362 struct link_params *params,
5363 struct link_vars *vars)
3637{ 5364{
3638 struct bnx2x *bp = params->bp; 5365 struct bnx2x *bp = params->bp;
3639 u32 ext_phy_type; 5366 u32 val;
3640 u8 ext_phy_addr; 5367 u32 swap_val, swap_override, aeu_gpio_mask, offset;
3641 u16 cnt; 5368 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3642 u16 ctrl = 0;
3643 u16 val = 0;
3644 u8 rc = 0;
3645 5369
3646 if (vars->phy_flags & PHY_XGXS_FLAG) { 5370 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
3647 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5371 bnx2x_wait_reset_complete(bp, phy, params);
3648 5372
3649 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 5373 bnx2x_8726_external_rom_boot(phy, params);
3650 /* Make sure that the soft reset is off (expect for the 8072:
3651 * due to the lock, it will be done inside the specific
3652 * handling)
3653 */
3654 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3655 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3656 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
3657 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
3658 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
3659 /* Wait for soft reset to get cleared upto 1 sec */
3660 for (cnt = 0; cnt < 1000; cnt++) {
3661 bnx2x_cl45_read(bp, params->port,
3662 ext_phy_type,
3663 ext_phy_addr,
3664 MDIO_PMA_DEVAD,
3665 MDIO_PMA_REG_CTRL, &ctrl);
3666 if (!(ctrl & (1<<15)))
3667 break;
3668 msleep(1);
3669 }
3670 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
3671 ctrl, cnt);
3672 }
3673 5374
3674 switch (ext_phy_type) { 5375 /*
3675 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 5376 * Need to call module detected on initialization since the module
3676 break; 5377 * detection triggered by actual module insertion might occur before
5378 * driver is loaded, and when driver is loaded, it reset all
5379 * registers, including the transmitter
5380 */
5381 bnx2x_sfp_module_detection(phy, params);
5382
5383 if (phy->req_line_speed == SPEED_1000) {
5384 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5385 bnx2x_cl45_write(bp, phy,
5386 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5387 bnx2x_cl45_write(bp, phy,
5388 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5389 bnx2x_cl45_write(bp, phy,
5390 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
5391 bnx2x_cl45_write(bp, phy,
5392 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5393 0x400);
5394 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5395 (phy->speed_cap_mask &
5396 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
5397 ((phy->speed_cap_mask &
5398 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5399 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5400 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5401 /* Set Flow control */
5402 bnx2x_ext_phy_set_pause(params, phy, vars);
5403 bnx2x_cl45_write(bp, phy,
5404 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
5405 bnx2x_cl45_write(bp, phy,
5406 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
5407 bnx2x_cl45_write(bp, phy,
5408 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
5409 bnx2x_cl45_write(bp, phy,
5410 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
5411 bnx2x_cl45_write(bp, phy,
5412 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
5413 /*
5414 * Enable RX-ALARM control to receive interrupt for 1G speed
5415 * change
5416 */
5417 bnx2x_cl45_write(bp, phy,
5418 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
5419 bnx2x_cl45_write(bp, phy,
5420 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5421 0x400);
5422
5423 } else { /* Default 10G. Set only LASI control */
5424 bnx2x_cl45_write(bp, phy,
5425 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
5426 }
3677 5427
3678 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 5428 /* Set TX PreEmphasis if needed */
3679 DP(NETIF_MSG_LINK, "XGXS 8705\n"); 5429 if ((params->feature_config_flags &
3680 5430 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3681 bnx2x_cl45_write(bp, params->port, 5431 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3682 ext_phy_type, 5432 "TX_CTRL2 0x%x\n",
3683 ext_phy_addr, 5433 phy->tx_preemphasis[0],
3684 MDIO_PMA_DEVAD, 5434 phy->tx_preemphasis[1]);
3685 MDIO_PMA_REG_MISC_CTRL, 5435 bnx2x_cl45_write(bp, phy,
3686 0x8288); 5436 MDIO_PMA_DEVAD,
3687 bnx2x_cl45_write(bp, params->port, 5437 MDIO_PMA_REG_8726_TX_CTRL1,
3688 ext_phy_type, 5438 phy->tx_preemphasis[0]);
3689 ext_phy_addr, 5439
3690 MDIO_PMA_DEVAD, 5440 bnx2x_cl45_write(bp, phy,
3691 MDIO_PMA_REG_PHY_IDENTIFIER, 5441 MDIO_PMA_DEVAD,
3692 0x7fbf); 5442 MDIO_PMA_REG_8726_TX_CTRL2,
3693 bnx2x_cl45_write(bp, params->port, 5443 phy->tx_preemphasis[1]);
3694 ext_phy_type, 5444 }
3695 ext_phy_addr,
3696 MDIO_PMA_DEVAD,
3697 MDIO_PMA_REG_CMU_PLL_BYPASS,
3698 0x0100);
3699 bnx2x_cl45_write(bp, params->port,
3700 ext_phy_type,
3701 ext_phy_addr,
3702 MDIO_WIS_DEVAD,
3703 MDIO_WIS_REG_LASI_CNTL, 0x1);
3704
3705 /* BCM8705 doesn't have microcode, hence the 0 */
3706 bnx2x_save_spirom_version(bp, params->port,
3707 params->shmem_base, 0);
3708 break;
3709 5445
3710 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 5446 /* Set GPIO3 to trigger SFP+ module insertion/removal */
3711 /* Wait until fw is loaded */ 5447 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
3712 for (cnt = 0; cnt < 100; cnt++) { 5448 MISC_REGISTERS_GPIO_INPUT_HI_Z, params->port);
3713 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3714 ext_phy_addr, MDIO_PMA_DEVAD,
3715 MDIO_PMA_REG_ROM_VER1, &val);
3716 if (val)
3717 break;
3718 msleep(10);
3719 }
3720 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized "
3721 "after %d ms\n", cnt);
3722 if ((params->feature_config_flags &
3723 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3724 u8 i;
3725 u16 reg;
3726 for (i = 0; i < 4; i++) {
3727 reg = MDIO_XS_8706_REG_BANK_RX0 +
3728 i*(MDIO_XS_8706_REG_BANK_RX1 -
3729 MDIO_XS_8706_REG_BANK_RX0);
3730 bnx2x_cl45_read(bp, params->port,
3731 ext_phy_type,
3732 ext_phy_addr,
3733 MDIO_XS_DEVAD,
3734 reg, &val);
3735 /* Clear first 3 bits of the control */
3736 val &= ~0x7;
3737 /* Set control bits according to
3738 configuation */
3739 val |= (params->xgxs_config_rx[i] &
3740 0x7);
3741 DP(NETIF_MSG_LINK, "Setting RX"
3742 "Equalizer to BCM8706 reg 0x%x"
3743 " <-- val 0x%x\n", reg, val);
3744 bnx2x_cl45_write(bp, params->port,
3745 ext_phy_type,
3746 ext_phy_addr,
3747 MDIO_XS_DEVAD,
3748 reg, val);
3749 }
3750 }
3751 /* Force speed */
3752 if (params->req_line_speed == SPEED_10000) {
3753 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3754
3755 bnx2x_cl45_write(bp, params->port,
3756 ext_phy_type,
3757 ext_phy_addr,
3758 MDIO_PMA_DEVAD,
3759 MDIO_PMA_REG_DIGITAL_CTRL,
3760 0x400);
3761 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3762 ext_phy_addr, MDIO_PMA_DEVAD,
3763 MDIO_PMA_REG_LASI_CTRL, 1);
3764 } else {
3765 /* Force 1Gbps using autoneg with 1G
3766 advertisment */
3767
3768 /* Allow CL37 through CL73 */
3769 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3770 bnx2x_cl45_write(bp, params->port,
3771 ext_phy_type,
3772 ext_phy_addr,
3773 MDIO_AN_DEVAD,
3774 MDIO_AN_REG_CL37_CL73,
3775 0x040c);
3776
3777 /* Enable Full-Duplex advertisment on CL37 */
3778 bnx2x_cl45_write(bp, params->port,
3779 ext_phy_type,
3780 ext_phy_addr,
3781 MDIO_AN_DEVAD,
3782 MDIO_AN_REG_CL37_FC_LP,
3783 0x0020);
3784 /* Enable CL37 AN */
3785 bnx2x_cl45_write(bp, params->port,
3786 ext_phy_type,
3787 ext_phy_addr,
3788 MDIO_AN_DEVAD,
3789 MDIO_AN_REG_CL37_AN,
3790 0x1000);
3791 /* 1G support */
3792 bnx2x_cl45_write(bp, params->port,
3793 ext_phy_type,
3794 ext_phy_addr,
3795 MDIO_AN_DEVAD,
3796 MDIO_AN_REG_ADV, (1<<5));
3797
3798 /* Enable clause 73 AN */
3799 bnx2x_cl45_write(bp, params->port,
3800 ext_phy_type,
3801 ext_phy_addr,
3802 MDIO_AN_DEVAD,
3803 MDIO_AN_REG_CTRL,
3804 0x1200);
3805 bnx2x_cl45_write(bp, params->port,
3806 ext_phy_type,
3807 ext_phy_addr,
3808 MDIO_PMA_DEVAD,
3809 MDIO_PMA_REG_RX_ALARM_CTRL,
3810 0x0400);
3811 bnx2x_cl45_write(bp, params->port,
3812 ext_phy_type,
3813 ext_phy_addr,
3814 MDIO_PMA_DEVAD,
3815 MDIO_PMA_REG_LASI_CTRL, 0x0004);
3816 5449
3817 } 5450 /* The GPIO should be swapped if the swap register is set and active */
3818 bnx2x_save_bcm_spirom_ver(bp, params->port, 5451 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
3819 ext_phy_type, 5452 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
3820 ext_phy_addr,
3821 params->shmem_base);
3822 break;
3823 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
3824 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3825 bnx2x_bcm8726_external_rom_boot(params);
3826
3827 /* Need to call module detected on initialization since
3828 the module detection triggered by actual module
3829 insertion might occur before driver is loaded, and when
3830 driver is loaded, it reset all registers, including the
3831 transmitter */
3832 bnx2x_sfp_module_detection(params);
3833
3834 /* Set Flow control */
3835 bnx2x_ext_phy_set_pause(params, vars);
3836 if (params->req_line_speed == SPEED_1000) {
3837 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3838 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3839 ext_phy_addr, MDIO_PMA_DEVAD,
3840 MDIO_PMA_REG_CTRL, 0x40);
3841 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3842 ext_phy_addr, MDIO_PMA_DEVAD,
3843 MDIO_PMA_REG_10G_CTRL2, 0xD);
3844 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3845 ext_phy_addr, MDIO_PMA_DEVAD,
3846 MDIO_PMA_REG_LASI_CTRL, 0x5);
3847 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3848 ext_phy_addr, MDIO_PMA_DEVAD,
3849 MDIO_PMA_REG_RX_ALARM_CTRL,
3850 0x400);
3851 } else if ((params->req_line_speed ==
3852 SPEED_AUTO_NEG) &&
3853 ((params->speed_cap_mask &
3854 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
3855 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
3856 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3857 ext_phy_addr, MDIO_AN_DEVAD,
3858 MDIO_AN_REG_ADV, 0x20);
3859 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3860 ext_phy_addr, MDIO_AN_DEVAD,
3861 MDIO_AN_REG_CL37_CL73, 0x040c);
3862 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3863 ext_phy_addr, MDIO_AN_DEVAD,
3864 MDIO_AN_REG_CL37_FC_LD, 0x0020);
3865 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3866 ext_phy_addr, MDIO_AN_DEVAD,
3867 MDIO_AN_REG_CL37_AN, 0x1000);
3868 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3869 ext_phy_addr, MDIO_AN_DEVAD,
3870 MDIO_AN_REG_CTRL, 0x1200);
3871
3872 /* Enable RX-ALARM control to receive
3873 interrupt for 1G speed change */
3874 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3875 ext_phy_addr, MDIO_PMA_DEVAD,
3876 MDIO_PMA_REG_LASI_CTRL, 0x4);
3877 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3878 ext_phy_addr, MDIO_PMA_DEVAD,
3879 MDIO_PMA_REG_RX_ALARM_CTRL,
3880 0x400);
3881
3882 } else { /* Default 10G. Set only LASI control */
3883 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3884 ext_phy_addr, MDIO_PMA_DEVAD,
3885 MDIO_PMA_REG_LASI_CTRL, 1);
3886 }
3887 5453
3888 /* Set TX PreEmphasis if needed */ 5454 /* Select function upon port-swap configuration */
3889 if ((params->feature_config_flags & 5455 if (params->port == 0) {
3890 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) { 5456 offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
3891 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x," 5457 aeu_gpio_mask = (swap_val && swap_override) ?
3892 "TX_CTRL2 0x%x\n", 5458 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1 :
3893 params->xgxs_config_tx[0], 5459 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0;
3894 params->xgxs_config_tx[1]); 5460 } else {
3895 bnx2x_cl45_write(bp, params->port, 5461 offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
3896 ext_phy_type, 5462 aeu_gpio_mask = (swap_val && swap_override) ?
3897 ext_phy_addr, 5463 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_0 :
3898 MDIO_PMA_DEVAD, 5464 AEU_INPUTS_ATTN_BITS_GPIO3_FUNCTION_1;
3899 MDIO_PMA_REG_8726_TX_CTRL1, 5465 }
3900 params->xgxs_config_tx[0]); 5466 val = REG_RD(bp, offset);
3901 5467 /* add GPIO3 to group */
3902 bnx2x_cl45_write(bp, params->port, 5468 val |= aeu_gpio_mask;
3903 ext_phy_type, 5469 REG_WR(bp, offset, val);
3904 ext_phy_addr, 5470 return 0;
3905 MDIO_PMA_DEVAD,
3906 MDIO_PMA_REG_8726_TX_CTRL2,
3907 params->xgxs_config_tx[1]);
3908 }
3909 break;
3910 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3911 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3912 {
3913 u16 tmp1;
3914 u16 rx_alarm_ctrl_val;
3915 u16 lasi_ctrl_val;
3916 if (ext_phy_type ==
3917 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
3918 rx_alarm_ctrl_val = 0x400;
3919 lasi_ctrl_val = 0x0004;
3920 } else {
3921 rx_alarm_ctrl_val = (1<<2);
3922 lasi_ctrl_val = 0x0004;
3923 }
3924 5471
3925 /* enable LASI */ 5472}
3926 bnx2x_cl45_write(bp, params->port,
3927 ext_phy_type,
3928 ext_phy_addr,
3929 MDIO_PMA_DEVAD,
3930 MDIO_PMA_REG_RX_ALARM_CTRL,
3931 rx_alarm_ctrl_val);
3932
3933 bnx2x_cl45_write(bp, params->port,
3934 ext_phy_type,
3935 ext_phy_addr,
3936 MDIO_PMA_DEVAD,
3937 MDIO_PMA_REG_LASI_CTRL,
3938 lasi_ctrl_val);
3939
3940 bnx2x_8073_set_pause_cl37(params, vars);
3941
3942 if (ext_phy_type ==
3943 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072)
3944 bnx2x_bcm8072_external_rom_boot(params);
3945 else
3946 /* In case of 8073 with long xaui lines,
3947 don't set the 8073 xaui low power*/
3948 bnx2x_bcm8073_set_xaui_low_power_mode(params);
3949
3950 bnx2x_cl45_read(bp, params->port,
3951 ext_phy_type,
3952 ext_phy_addr,
3953 MDIO_PMA_DEVAD,
3954 MDIO_PMA_REG_M8051_MSGOUT_REG,
3955 &tmp1);
3956
3957 bnx2x_cl45_read(bp, params->port,
3958 ext_phy_type,
3959 ext_phy_addr,
3960 MDIO_PMA_DEVAD,
3961 MDIO_PMA_REG_RX_ALARM, &tmp1);
3962
3963 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
3964 "0x%x\n", tmp1);
3965
3966 /* If this is forced speed, set to KR or KX
3967 * (all other are not supported)
3968 */
3969 if (params->loopback_mode == LOOPBACK_EXT) {
3970 bnx2x_bcm807x_force_10G(params);
3971 DP(NETIF_MSG_LINK,
3972 "Forced speed 10G on 807X\n");
3973 break;
3974 } else {
3975 bnx2x_cl45_write(bp, params->port,
3976 ext_phy_type, ext_phy_addr,
3977 MDIO_PMA_DEVAD,
3978 MDIO_PMA_REG_BCM_CTRL,
3979 0x0002);
3980 }
3981 if (params->req_line_speed != SPEED_AUTO_NEG) {
3982 if (params->req_line_speed == SPEED_10000) {
3983 val = (1<<7);
3984 } else if (params->req_line_speed ==
3985 SPEED_2500) {
3986 val = (1<<5);
3987 /* Note that 2.5G works only
3988 when used with 1G advertisment */
3989 } else
3990 val = (1<<5);
3991 } else {
3992
3993 val = 0;
3994 if (params->speed_cap_mask &
3995 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3996 val |= (1<<7);
3997
3998 /* Note that 2.5G works only when
3999 used with 1G advertisment */
4000 if (params->speed_cap_mask &
4001 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
4002 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
4003 val |= (1<<5);
4004 DP(NETIF_MSG_LINK,
4005 "807x autoneg val = 0x%x\n", val);
4006 }
4007 5473
4008 bnx2x_cl45_write(bp, params->port, 5474static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
4009 ext_phy_type, 5475 struct link_params *params)
4010 ext_phy_addr, 5476{
4011 MDIO_AN_DEVAD, 5477 struct bnx2x *bp = params->bp;
4012 MDIO_AN_REG_ADV, val); 5478 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
4013 if (ext_phy_type == 5479 /* Set serial boot control for external load */
4014 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) { 5480 bnx2x_cl45_write(bp, phy,
4015 bnx2x_cl45_read(bp, params->port, 5481 MDIO_PMA_DEVAD,
4016 ext_phy_type, 5482 MDIO_PMA_REG_GEN_CTRL, 0x0001);
4017 ext_phy_addr, 5483}
4018 MDIO_AN_DEVAD,
4019 MDIO_AN_REG_8073_2_5G, &tmp1);
4020
4021 if (((params->speed_cap_mask &
4022 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
4023 (params->req_line_speed ==
4024 SPEED_AUTO_NEG)) ||
4025 (params->req_line_speed ==
4026 SPEED_2500)) {
4027 u16 phy_ver;
4028 /* Allow 2.5G for A1 and above */
4029 bnx2x_cl45_read(bp, params->port,
4030 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4031 ext_phy_addr,
4032 MDIO_PMA_DEVAD,
4033 MDIO_PMA_REG_8073_CHIP_REV, &phy_ver);
4034 DP(NETIF_MSG_LINK, "Add 2.5G\n");
4035 if (phy_ver > 0)
4036 tmp1 |= 1;
4037 else
4038 tmp1 &= 0xfffe;
4039 } else {
4040 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
4041 tmp1 &= 0xfffe;
4042 }
4043
4044 bnx2x_cl45_write(bp, params->port,
4045 ext_phy_type,
4046 ext_phy_addr,
4047 MDIO_AN_DEVAD,
4048 MDIO_AN_REG_8073_2_5G, tmp1);
4049 }
4050 5484
4051 /* Add support for CL37 (passive mode) II */ 5485/******************************************************************/
4052 5486/* BCM8727 PHY SECTION */
4053 bnx2x_cl45_read(bp, params->port, 5487/******************************************************************/
4054 ext_phy_type,
4055 ext_phy_addr,
4056 MDIO_AN_DEVAD,
4057 MDIO_AN_REG_CL37_FC_LD,
4058 &tmp1);
4059
4060 bnx2x_cl45_write(bp, params->port,
4061 ext_phy_type,
4062 ext_phy_addr,
4063 MDIO_AN_DEVAD,
4064 MDIO_AN_REG_CL37_FC_LD, (tmp1 |
4065 ((params->req_duplex == DUPLEX_FULL) ?
4066 0x20 : 0x40)));
4067
4068 /* Add support for CL37 (passive mode) III */
4069 bnx2x_cl45_write(bp, params->port,
4070 ext_phy_type,
4071 ext_phy_addr,
4072 MDIO_AN_DEVAD,
4073 MDIO_AN_REG_CL37_AN, 0x1000);
4074
4075 if (ext_phy_type ==
4076 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4077 /* The SNR will improve about 2db by changing
4078 BW and FEE main tap. Rest commands are executed
4079 after link is up*/
4080 /*Change FFE main cursor to 5 in EDC register*/
4081 if (bnx2x_8073_is_snr_needed(params))
4082 bnx2x_cl45_write(bp, params->port,
4083 ext_phy_type,
4084 ext_phy_addr,
4085 MDIO_PMA_DEVAD,
4086 MDIO_PMA_REG_EDC_FFE_MAIN,
4087 0xFB0C);
4088
4089 /* Enable FEC (Forware Error Correction)
4090 Request in the AN */
4091 bnx2x_cl45_read(bp, params->port,
4092 ext_phy_type,
4093 ext_phy_addr,
4094 MDIO_AN_DEVAD,
4095 MDIO_AN_REG_ADV2, &tmp1);
4096
4097 tmp1 |= (1<<15);
4098
4099 bnx2x_cl45_write(bp, params->port,
4100 ext_phy_type,
4101 ext_phy_addr,
4102 MDIO_AN_DEVAD,
4103 MDIO_AN_REG_ADV2, tmp1);
4104 5488
4105 } 5489static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
5490 struct link_params *params, u8 mode)
5491{
5492 struct bnx2x *bp = params->bp;
5493 u16 led_mode_bitmask = 0;
5494 u16 gpio_pins_bitmask = 0;
5495 u16 val;
5496 /* Only NOC flavor requires to set the LED specifically */
5497 if (!(phy->flags & FLAGS_NOC))
5498 return;
5499 switch (mode) {
5500 case LED_MODE_FRONT_PANEL_OFF:
5501 case LED_MODE_OFF:
5502 led_mode_bitmask = 0;
5503 gpio_pins_bitmask = 0x03;
5504 break;
5505 case LED_MODE_ON:
5506 led_mode_bitmask = 0;
5507 gpio_pins_bitmask = 0x02;
5508 break;
5509 case LED_MODE_OPER:
5510 led_mode_bitmask = 0x60;
5511 gpio_pins_bitmask = 0x11;
5512 break;
5513 }
5514 bnx2x_cl45_read(bp, phy,
5515 MDIO_PMA_DEVAD,
5516 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5517 &val);
5518 val &= 0xff8f;
5519 val |= led_mode_bitmask;
5520 bnx2x_cl45_write(bp, phy,
5521 MDIO_PMA_DEVAD,
5522 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
5523 val);
5524 bnx2x_cl45_read(bp, phy,
5525 MDIO_PMA_DEVAD,
5526 MDIO_PMA_REG_8727_GPIO_CTRL,
5527 &val);
5528 val &= 0xffe0;
5529 val |= gpio_pins_bitmask;
5530 bnx2x_cl45_write(bp, phy,
5531 MDIO_PMA_DEVAD,
5532 MDIO_PMA_REG_8727_GPIO_CTRL,
5533 val);
5534}
5535static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5536 struct link_params *params) {
5537 u32 swap_val, swap_override;
5538 u8 port;
5539 /*
5540 * The PHY reset is controlled by GPIO 1. Fake the port number
5541 * to cancel the swap done in set_gpio()
5542 */
5543 struct bnx2x *bp = params->bp;
5544 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5545 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5546 port = (swap_val && swap_override) ^ 1;
5547 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5548 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5549}
4106 5550
4107 bnx2x_ext_phy_set_pause(params, vars); 5551static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
4108 5552 struct link_params *params,
4109 /* Restart autoneg */ 5553 struct link_vars *vars)
4110 msleep(500); 5554{
4111 bnx2x_cl45_write(bp, params->port, 5555 u32 tx_en_mode;
4112 ext_phy_type, 5556 u16 tmp1, val, mod_abs, tmp2;
4113 ext_phy_addr, 5557 u16 rx_alarm_ctrl_val;
4114 MDIO_AN_DEVAD, 5558 u16 lasi_ctrl_val;
4115 MDIO_AN_REG_CTRL, 0x1200); 5559 struct bnx2x *bp = params->bp;
4116 DP(NETIF_MSG_LINK, "807x Autoneg Restart: " 5560 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4117 "Advertise 1G=%x, 10G=%x\n",
4118 ((val & (1<<5)) > 0),
4119 ((val & (1<<7)) > 0));
4120 break;
4121 }
4122 5561
4123 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 5562 bnx2x_wait_reset_complete(bp, phy, params);
4124 { 5563 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4125 u16 tmp1; 5564 lasi_ctrl_val = 0x0004;
4126 u16 rx_alarm_ctrl_val;
4127 u16 lasi_ctrl_val;
4128
4129 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
4130
4131 u16 mod_abs;
4132 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
4133 lasi_ctrl_val = 0x0004;
4134
4135 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4136 /* enable LASI */
4137 bnx2x_cl45_write(bp, params->port,
4138 ext_phy_type,
4139 ext_phy_addr,
4140 MDIO_PMA_DEVAD,
4141 MDIO_PMA_REG_RX_ALARM_CTRL,
4142 rx_alarm_ctrl_val);
4143
4144 bnx2x_cl45_write(bp, params->port,
4145 ext_phy_type,
4146 ext_phy_addr,
4147 MDIO_PMA_DEVAD,
4148 MDIO_PMA_REG_LASI_CTRL,
4149 lasi_ctrl_val);
4150
4151 /* Initially configure MOD_ABS to interrupt when
4152 module is presence( bit 8) */
4153 bnx2x_cl45_read(bp, params->port,
4154 ext_phy_type,
4155 ext_phy_addr,
4156 MDIO_PMA_DEVAD,
4157 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4158 /* Set EDC off by setting OPTXLOS signal input to low
4159 (bit 9).
4160 When the EDC is off it locks onto a reference clock and
4161 avoids becoming 'lost'.*/
4162 mod_abs &= ~((1<<8) | (1<<9));
4163 bnx2x_cl45_write(bp, params->port,
4164 ext_phy_type,
4165 ext_phy_addr,
4166 MDIO_PMA_DEVAD,
4167 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4168
4169 /* Make MOD_ABS give interrupt on change */
4170 bnx2x_cl45_read(bp, params->port,
4171 ext_phy_type,
4172 ext_phy_addr,
4173 MDIO_PMA_DEVAD,
4174 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4175 &val);
4176 val |= (1<<12);
4177 bnx2x_cl45_write(bp, params->port,
4178 ext_phy_type,
4179 ext_phy_addr,
4180 MDIO_PMA_DEVAD,
4181 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4182 val);
4183
4184 /* Set 8727 GPIOs to input to allow reading from the
4185 8727 GPIO0 status which reflect SFP+ module
4186 over-current */
4187
4188 bnx2x_cl45_read(bp, params->port,
4189 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4190 ext_phy_addr,
4191 MDIO_PMA_DEVAD,
4192 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4193 &val);
4194 val &= 0xff8f; /* Reset bits 4-6 */
4195 bnx2x_cl45_write(bp, params->port,
4196 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4197 ext_phy_addr,
4198 MDIO_PMA_DEVAD,
4199 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4200 val);
4201
4202 bnx2x_8727_power_module(bp, params, ext_phy_addr, 1);
4203 bnx2x_bcm8073_set_xaui_low_power_mode(params);
4204
4205 bnx2x_cl45_read(bp, params->port,
4206 ext_phy_type,
4207 ext_phy_addr,
4208 MDIO_PMA_DEVAD,
4209 MDIO_PMA_REG_M8051_MSGOUT_REG,
4210 &tmp1);
4211
4212 bnx2x_cl45_read(bp, params->port,
4213 ext_phy_type,
4214 ext_phy_addr,
4215 MDIO_PMA_DEVAD,
4216 MDIO_PMA_REG_RX_ALARM, &tmp1);
4217
4218 /* Set option 1G speed */
4219 if (params->req_line_speed == SPEED_1000) {
4220
4221 DP(NETIF_MSG_LINK, "Setting 1G force\n");
4222 bnx2x_cl45_write(bp, params->port,
4223 ext_phy_type,
4224 ext_phy_addr,
4225 MDIO_PMA_DEVAD,
4226 MDIO_PMA_REG_CTRL, 0x40);
4227 bnx2x_cl45_write(bp, params->port,
4228 ext_phy_type,
4229 ext_phy_addr,
4230 MDIO_PMA_DEVAD,
4231 MDIO_PMA_REG_10G_CTRL2, 0xD);
4232 bnx2x_cl45_read(bp, params->port,
4233 ext_phy_type,
4234 ext_phy_addr,
4235 MDIO_PMA_DEVAD,
4236 MDIO_PMA_REG_10G_CTRL2, &tmp1);
4237 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
4238
4239 } else if ((params->req_line_speed ==
4240 SPEED_AUTO_NEG) &&
4241 ((params->speed_cap_mask &
4242 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G))) {
4243
4244 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
4245 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4246 ext_phy_addr, MDIO_AN_DEVAD,
4247 MDIO_PMA_REG_8727_MISC_CTRL, 0);
4248 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4249 ext_phy_addr, MDIO_AN_DEVAD,
4250 MDIO_AN_REG_CL37_AN, 0x1300);
4251 } else {
4252 /* Since the 8727 has only single reset pin,
4253 need to set the 10G registers although it is
4254 default */
4255 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4256 ext_phy_addr, MDIO_AN_DEVAD,
4257 MDIO_AN_REG_CTRL, 0x0020);
4258 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4259 ext_phy_addr, MDIO_AN_DEVAD,
4260 0x7, 0x0100);
4261 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4262 ext_phy_addr, MDIO_PMA_DEVAD,
4263 MDIO_PMA_REG_CTRL, 0x2040);
4264 bnx2x_cl45_write(bp, params->port, ext_phy_type,
4265 ext_phy_addr, MDIO_PMA_DEVAD,
4266 MDIO_PMA_REG_10G_CTRL2, 0x0008);
4267 }
4268 5565
4269 /* Set 2-wire transfer rate of SFP+ module EEPROM 5566 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
4270 * to 100Khz since some DACs(direct attached cables) do 5567 /* enable LASI */
4271 * not work at 400Khz. 5568 bnx2x_cl45_write(bp, phy,
4272 */ 5569 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4273 bnx2x_cl45_write(bp, params->port, 5570 rx_alarm_ctrl_val);
4274 ext_phy_type,
4275 ext_phy_addr,
4276 MDIO_PMA_DEVAD,
4277 MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4278 0xa001);
4279
4280 /* Set TX PreEmphasis if needed */
4281 if ((params->feature_config_flags &
4282 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
4283 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
4284 "TX_CTRL2 0x%x\n",
4285 params->xgxs_config_tx[0],
4286 params->xgxs_config_tx[1]);
4287 bnx2x_cl45_write(bp, params->port,
4288 ext_phy_type,
4289 ext_phy_addr,
4290 MDIO_PMA_DEVAD,
4291 MDIO_PMA_REG_8727_TX_CTRL1,
4292 params->xgxs_config_tx[0]);
4293
4294 bnx2x_cl45_write(bp, params->port,
4295 ext_phy_type,
4296 ext_phy_addr,
4297 MDIO_PMA_DEVAD,
4298 MDIO_PMA_REG_8727_TX_CTRL2,
4299 params->xgxs_config_tx[1]);
4300 }
4301 5571
4302 break; 5572 bnx2x_cl45_write(bp, phy,
4303 } 5573 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
4304 5574
4305 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 5575 /*
4306 { 5576 * Initially configure MOD_ABS to interrupt when module is
4307 u16 fw_ver1, fw_ver2; 5577 * presence( bit 8)
4308 DP(NETIF_MSG_LINK, 5578 */
4309 "Setting the SFX7101 LASI indication\n"); 5579 bnx2x_cl45_read(bp, phy,
5580 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
5581 /*
5582 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
5583 * When the EDC is off it locks onto a reference clock and avoids
5584 * becoming 'lost'
5585 */
5586 mod_abs &= ~(1<<8);
5587 if (!(phy->flags & FLAGS_NOC))
5588 mod_abs &= ~(1<<9);
5589 bnx2x_cl45_write(bp, phy,
5590 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4310 5591
4311 bnx2x_cl45_write(bp, params->port,
4312 ext_phy_type,
4313 ext_phy_addr,
4314 MDIO_PMA_DEVAD,
4315 MDIO_PMA_REG_LASI_CTRL, 0x1);
4316 DP(NETIF_MSG_LINK,
4317 "Setting the SFX7101 LED to blink on traffic\n");
4318 bnx2x_cl45_write(bp, params->port,
4319 ext_phy_type,
4320 ext_phy_addr,
4321 MDIO_PMA_DEVAD,
4322 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4323
4324 bnx2x_ext_phy_set_pause(params, vars);
4325 /* Restart autoneg */
4326 bnx2x_cl45_read(bp, params->port,
4327 ext_phy_type,
4328 ext_phy_addr,
4329 MDIO_AN_DEVAD,
4330 MDIO_AN_REG_CTRL, &val);
4331 val |= 0x200;
4332 bnx2x_cl45_write(bp, params->port,
4333 ext_phy_type,
4334 ext_phy_addr,
4335 MDIO_AN_DEVAD,
4336 MDIO_AN_REG_CTRL, val);
4337
4338 /* Save spirom version */
4339 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4340 ext_phy_addr, MDIO_PMA_DEVAD,
4341 MDIO_PMA_REG_7101_VER1, &fw_ver1);
4342
4343 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4344 ext_phy_addr, MDIO_PMA_DEVAD,
4345 MDIO_PMA_REG_7101_VER2, &fw_ver2);
4346
4347 bnx2x_save_spirom_version(params->bp, params->port,
4348 params->shmem_base,
4349 (u32)(fw_ver1<<16 | fw_ver2));
4350 break;
4351 }
4352 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
4353 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
4354 /* This phy uses the NIG latch mechanism since link
4355 indication arrives through its LED4 and not via
4356 its LASI signal, so we get steady signal
4357 instead of clear on read */
4358 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
4359 1 << NIG_LATCH_BC_ENABLE_MI_INT);
4360
4361 bnx2x_cl45_write(bp, params->port,
4362 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
4363 ext_phy_addr,
4364 MDIO_PMA_DEVAD,
4365 MDIO_PMA_REG_CTRL, 0x0000);
4366
4367 bnx2x_8481_set_led4(params, ext_phy_type, ext_phy_addr);
4368 if (params->req_line_speed == SPEED_AUTO_NEG) {
4369
4370 u16 autoneg_val, an_1000_val, an_10_100_val;
4371 /* set 1000 speed advertisement */
4372 bnx2x_cl45_read(bp, params->port,
4373 ext_phy_type,
4374 ext_phy_addr,
4375 MDIO_AN_DEVAD,
4376 MDIO_AN_REG_8481_1000T_CTRL,
4377 &an_1000_val);
4378
4379 if (params->speed_cap_mask &
4380 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) {
4381 an_1000_val |= (1<<8);
4382 if (params->req_duplex == DUPLEX_FULL)
4383 an_1000_val |= (1<<9);
4384 DP(NETIF_MSG_LINK, "Advertising 1G\n");
4385 } else
4386 an_1000_val &= ~((1<<8) | (1<<9));
4387
4388 bnx2x_cl45_write(bp, params->port,
4389 ext_phy_type,
4390 ext_phy_addr,
4391 MDIO_AN_DEVAD,
4392 MDIO_AN_REG_8481_1000T_CTRL,
4393 an_1000_val);
4394
4395 /* set 100 speed advertisement */
4396 bnx2x_cl45_read(bp, params->port,
4397 ext_phy_type,
4398 ext_phy_addr,
4399 MDIO_AN_DEVAD,
4400 MDIO_AN_REG_8481_LEGACY_AN_ADV,
4401 &an_10_100_val);
4402
4403 if (params->speed_cap_mask &
4404 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
4405 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) {
4406 an_10_100_val |= (1<<7);
4407 if (params->req_duplex == DUPLEX_FULL)
4408 an_10_100_val |= (1<<8);
4409 DP(NETIF_MSG_LINK,
4410 "Advertising 100M\n");
4411 } else
4412 an_10_100_val &= ~((1<<7) | (1<<8));
4413
4414 /* set 10 speed advertisement */
4415 if (params->speed_cap_mask &
4416 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
4417 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) {
4418 an_10_100_val |= (1<<5);
4419 if (params->req_duplex == DUPLEX_FULL)
4420 an_10_100_val |= (1<<6);
4421 DP(NETIF_MSG_LINK, "Advertising 10M\n");
4422 }
4423 else
4424 an_10_100_val &= ~((1<<5) | (1<<6));
4425
4426 bnx2x_cl45_write(bp, params->port,
4427 ext_phy_type,
4428 ext_phy_addr,
4429 MDIO_AN_DEVAD,
4430 MDIO_AN_REG_8481_LEGACY_AN_ADV,
4431 an_10_100_val);
4432
4433 bnx2x_cl45_read(bp, params->port,
4434 ext_phy_type,
4435 ext_phy_addr,
4436 MDIO_AN_DEVAD,
4437 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4438 &autoneg_val);
4439
4440 /* Disable forced speed */
4441 autoneg_val &= ~(1<<6|1<<13);
4442
4443 /* Enable autoneg and restart autoneg
4444 for legacy speeds */
4445 autoneg_val |= (1<<9|1<<12);
4446
4447 if (params->req_duplex == DUPLEX_FULL)
4448 autoneg_val |= (1<<8);
4449 else
4450 autoneg_val &= ~(1<<8);
4451
4452 bnx2x_cl45_write(bp, params->port,
4453 ext_phy_type,
4454 ext_phy_addr,
4455 MDIO_AN_DEVAD,
4456 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4457 autoneg_val);
4458
4459 if (params->speed_cap_mask &
4460 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) {
4461 DP(NETIF_MSG_LINK, "Advertising 10G\n");
4462 /* Restart autoneg for 10G*/
4463
4464 bnx2x_cl45_write(bp, params->port,
4465 ext_phy_type,
4466 ext_phy_addr,
4467 MDIO_AN_DEVAD,
4468 MDIO_AN_REG_CTRL, 0x3200);
4469 }
4470 } else {
4471 /* Force speed */
4472 u16 autoneg_ctrl, pma_ctrl;
4473 bnx2x_cl45_read(bp, params->port,
4474 ext_phy_type,
4475 ext_phy_addr,
4476 MDIO_AN_DEVAD,
4477 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4478 &autoneg_ctrl);
4479
4480 /* Disable autoneg */
4481 autoneg_ctrl &= ~(1<<12);
4482
4483 /* Set 1000 force */
4484 switch (params->req_line_speed) {
4485 case SPEED_10000:
4486 DP(NETIF_MSG_LINK,
4487 "Unable to set 10G force !\n");
4488 break;
4489 case SPEED_1000:
4490 bnx2x_cl45_read(bp, params->port,
4491 ext_phy_type,
4492 ext_phy_addr,
4493 MDIO_PMA_DEVAD,
4494 MDIO_PMA_REG_CTRL,
4495 &pma_ctrl);
4496 autoneg_ctrl &= ~(1<<13);
4497 autoneg_ctrl |= (1<<6);
4498 pma_ctrl &= ~(1<<13);
4499 pma_ctrl |= (1<<6);
4500 DP(NETIF_MSG_LINK,
4501 "Setting 1000M force\n");
4502 bnx2x_cl45_write(bp, params->port,
4503 ext_phy_type,
4504 ext_phy_addr,
4505 MDIO_PMA_DEVAD,
4506 MDIO_PMA_REG_CTRL,
4507 pma_ctrl);
4508 break;
4509 case SPEED_100:
4510 autoneg_ctrl |= (1<<13);
4511 autoneg_ctrl &= ~(1<<6);
4512 DP(NETIF_MSG_LINK,
4513 "Setting 100M force\n");
4514 break;
4515 case SPEED_10:
4516 autoneg_ctrl &= ~(1<<13);
4517 autoneg_ctrl &= ~(1<<6);
4518 DP(NETIF_MSG_LINK,
4519 "Setting 10M force\n");
4520 break;
4521 }
4522 5592
4523 /* Duplex mode */ 5593 /* Make MOD_ABS give interrupt on change */
4524 if (params->req_duplex == DUPLEX_FULL) { 5594 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
4525 autoneg_ctrl |= (1<<8); 5595 &val);
4526 DP(NETIF_MSG_LINK, 5596 val |= (1<<12);
4527 "Setting full duplex\n"); 5597 if (phy->flags & FLAGS_NOC)
4528 } else 5598 val |= (3<<5);
4529 autoneg_ctrl &= ~(1<<8);
4530
4531 /* Update autoneg ctrl and pma ctrl */
4532 bnx2x_cl45_write(bp, params->port,
4533 ext_phy_type,
4534 ext_phy_addr,
4535 MDIO_AN_DEVAD,
4536 MDIO_AN_REG_8481_LEGACY_MII_CTRL,
4537 autoneg_ctrl);
4538 }
4539 5599
4540 /* Save spirom version */ 5600 /*
4541 bnx2x_save_8481_spirom_version(bp, params->port, 5601 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
4542 ext_phy_addr, 5602 * status which reflect SFP+ module over-current
4543 params->shmem_base); 5603 */
4544 break; 5604 if (!(phy->flags & FLAGS_NOC))
4545 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 5605 val &= 0xff8f; /* Reset bits 4-6 */
4546 DP(NETIF_MSG_LINK, 5606 bnx2x_cl45_write(bp, phy,
4547 "XGXS PHY Failure detected 0x%x\n", 5607 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
4548 params->ext_phy_config); 5608
4549 rc = -EINVAL; 5609 bnx2x_8727_power_module(bp, phy, 1);
4550 break; 5610
4551 default: 5611 bnx2x_cl45_read(bp, phy,
4552 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n", 5612 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4553 params->ext_phy_config); 5613
4554 rc = -EINVAL; 5614 bnx2x_cl45_read(bp, phy,
4555 break; 5615 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
5616
5617 /* Set option 1G speed */
5618 if (phy->req_line_speed == SPEED_1000) {
5619 DP(NETIF_MSG_LINK, "Setting 1G force\n");
5620 bnx2x_cl45_write(bp, phy,
5621 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
5622 bnx2x_cl45_write(bp, phy,
5623 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
5624 bnx2x_cl45_read(bp, phy,
5625 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
5626 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
5627 /*
5628 * Power down the XAUI until link is up in case of dual-media
5629 * and 1G
5630 */
5631 if (DUAL_MEDIA(params)) {
5632 bnx2x_cl45_read(bp, phy,
5633 MDIO_PMA_DEVAD,
5634 MDIO_PMA_REG_8727_PCS_GP, &val);
5635 val |= (3<<10);
5636 bnx2x_cl45_write(bp, phy,
5637 MDIO_PMA_DEVAD,
5638 MDIO_PMA_REG_8727_PCS_GP, val);
4556 } 5639 }
5640 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5641 ((phy->speed_cap_mask &
5642 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
5643 ((phy->speed_cap_mask &
5644 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
5645 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
5646
5647 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
5648 bnx2x_cl45_write(bp, phy,
5649 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
5650 bnx2x_cl45_write(bp, phy,
5651 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
5652 } else {
5653 /*
5654 * Since the 8727 has only single reset pin, need to set the 10G
5655 * registers although it is default
5656 */
5657 bnx2x_cl45_write(bp, phy,
5658 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
5659 0x0020);
5660 bnx2x_cl45_write(bp, phy,
5661 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
5662 bnx2x_cl45_write(bp, phy,
5663 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
5664 bnx2x_cl45_write(bp, phy,
5665 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
5666 0x0008);
5667 }
4557 5668
4558 } else { /* SerDes */ 5669 /*
4559 5670 * Set 2-wire transfer rate of SFP+ module EEPROM
4560 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 5671 * to 100Khz since some DACs(direct attached cables) do
4561 switch (ext_phy_type) { 5672 * not work at 400Khz.
4562 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: 5673 */
4563 DP(NETIF_MSG_LINK, "SerDes Direct\n"); 5674 bnx2x_cl45_write(bp, phy,
4564 break; 5675 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
4565 5676 0xa001);
4566 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: 5677
4567 DP(NETIF_MSG_LINK, "SerDes 5482\n"); 5678 /* Set TX PreEmphasis if needed */
4568 break; 5679 if ((params->feature_config_flags &
5680 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
5681 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
5682 phy->tx_preemphasis[0],
5683 phy->tx_preemphasis[1]);
5684 bnx2x_cl45_write(bp, phy,
5685 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
5686 phy->tx_preemphasis[0]);
5687
5688 bnx2x_cl45_write(bp, phy,
5689 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
5690 phy->tx_preemphasis[1]);
5691 }
4569 5692
4570 default: 5693 /*
4571 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n", 5694 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
4572 params->ext_phy_config); 5695 * power mode, if TX Laser is disabled
4573 break; 5696 */
4574 } 5697 tx_en_mode = REG_RD(bp, params->shmem_base +
5698 offsetof(struct shmem_region,
5699 dev_info.port_hw_config[params->port].sfp_ctrl))
5700 & PORT_HW_CFG_TX_LASER_MASK;
5701
5702 if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
5703
5704 DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
5705 bnx2x_cl45_read(bp, phy,
5706 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
5707 tmp2 |= 0x1000;
5708 tmp2 &= 0xFFEF;
5709 bnx2x_cl45_write(bp, phy,
5710 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
4575 } 5711 }
4576 return rc; 5712
5713 return 0;
4577} 5714}
4578 5715
4579static void bnx2x_8727_handle_mod_abs(struct link_params *params) 5716static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
5717 struct link_params *params)
4580{ 5718{
4581 struct bnx2x *bp = params->bp; 5719 struct bnx2x *bp = params->bp;
4582 u16 mod_abs, rx_alarm_status; 5720 u16 mod_abs, rx_alarm_status;
4583 u8 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config);
4584 u32 val = REG_RD(bp, params->shmem_base + 5721 u32 val = REG_RD(bp, params->shmem_base +
4585 offsetof(struct shmem_region, dev_info. 5722 offsetof(struct shmem_region, dev_info.
4586 port_feature_config[params->port]. 5723 port_feature_config[params->port].
4587 config)); 5724 config));
4588 bnx2x_cl45_read(bp, params->port, 5725 bnx2x_cl45_read(bp, phy,
4589 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 5726 MDIO_PMA_DEVAD,
4590 ext_phy_addr, 5727 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4591 MDIO_PMA_DEVAD,
4592 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
4593 if (mod_abs & (1<<8)) { 5728 if (mod_abs & (1<<8)) {
4594 5729
4595 /* Module is absent */ 5730 /* Module is absent */
4596 DP(NETIF_MSG_LINK, "MOD_ABS indication " 5731 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4597 "show module is absent\n"); 5732 "show module is absent\n");
4598 5733
4599 /* 1. Set mod_abs to detect next module 5734 /*
4600 presence event 5735 * 1. Set mod_abs to detect next module
4601 2. Set EDC off by setting OPTXLOS signal input to low 5736 * presence event
4602 (bit 9). 5737 * 2. Set EDC off by setting OPTXLOS signal input to low
4603 When the EDC is off it locks onto a reference clock and 5738 * (bit 9).
4604 avoids becoming 'lost'.*/ 5739 * When the EDC is off it locks onto a reference clock and
4605 mod_abs &= ~((1<<8)|(1<<9)); 5740 * avoids becoming 'lost'.
4606 bnx2x_cl45_write(bp, params->port, 5741 */
4607 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 5742 mod_abs &= ~(1<<8);
4608 ext_phy_addr, 5743 if (!(phy->flags & FLAGS_NOC))
4609 MDIO_PMA_DEVAD, 5744 mod_abs &= ~(1<<9);
4610 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); 5745 bnx2x_cl45_write(bp, phy,
4611 5746 MDIO_PMA_DEVAD,
4612 /* Clear RX alarm since it stays up as long as 5747 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4613 the mod_abs wasn't changed */ 5748
4614 bnx2x_cl45_read(bp, params->port, 5749 /*
4615 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 5750 * Clear RX alarm since it stays up as long as
4616 ext_phy_addr, 5751 * the mod_abs wasn't changed
4617 MDIO_PMA_DEVAD, 5752 */
4618 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status); 5753 bnx2x_cl45_read(bp, phy,
5754 MDIO_PMA_DEVAD,
5755 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4619 5756
4620 } else { 5757 } else {
4621 /* Module is present */ 5758 /* Module is present */
4622 DP(NETIF_MSG_LINK, "MOD_ABS indication " 5759 DP(NETIF_MSG_LINK, "MOD_ABS indication "
4623 "show module is present\n"); 5760 "show module is present\n");
4624 /* First thing, disable transmitter, 5761 /*
4625 and if the module is ok, the 5762 * First disable transmitter, and if the module is ok, the
4626 module_detection will enable it*/ 5763 * module_detection will enable it
4627 5764 * 1. Set mod_abs to detect next module absent event ( bit 8)
4628 /* 1. Set mod_abs to detect next module 5765 * 2. Restore the default polarity of the OPRXLOS signal and
4629 absent event ( bit 8) 5766 * this signal will then correctly indicate the presence or
4630 2. Restore the default polarity of the OPRXLOS signal and 5767 * absence of the Rx signal. (bit 9)
4631 this signal will then correctly indicate the presence or 5768 */
4632 absence of the Rx signal. (bit 9) */ 5769 mod_abs |= (1<<8);
4633 mod_abs |= ((1<<8)|(1<<9)); 5770 if (!(phy->flags & FLAGS_NOC))
4634 bnx2x_cl45_write(bp, params->port, 5771 mod_abs |= (1<<9);
4635 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 5772 bnx2x_cl45_write(bp, phy,
4636 ext_phy_addr, 5773 MDIO_PMA_DEVAD,
4637 MDIO_PMA_DEVAD, 5774 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4638 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs); 5775
4639 5776 /*
4640 /* Clear RX alarm since it stays up as long as 5777 * Clear RX alarm since it stays up as long as the mod_abs
4641 the mod_abs wasn't changed. This is need to be done 5778 * wasn't changed. This is need to be done before calling the
4642 before calling the module detection, otherwise it will clear 5779 * module detection, otherwise it will clear* the link update
4643 the link update alarm */ 5780 * alarm
4644 bnx2x_cl45_read(bp, params->port, 5781 */
4645 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 5782 bnx2x_cl45_read(bp, phy,
4646 ext_phy_addr, 5783 MDIO_PMA_DEVAD,
4647 MDIO_PMA_DEVAD, 5784 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4648 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4649 5785
4650 5786
4651 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 5787 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
4652 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 5788 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
4653 bnx2x_sfp_set_transmitter(bp, params->port, 5789 bnx2x_sfp_set_transmitter(params, phy, 0);
4654 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
4655 ext_phy_addr, 0);
4656 5790
4657 if (bnx2x_wait_for_sfp_module_initialized(params) 5791 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
4658 == 0) 5792 bnx2x_sfp_module_detection(phy, params);
4659 bnx2x_sfp_module_detection(params);
4660 else 5793 else
4661 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n"); 5794 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
4662 } 5795 }
4663 5796
4664 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", 5797 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4665 rx_alarm_status); 5798 rx_alarm_status);
4666 /* No need to check link status in case of 5799 /* No need to check link status in case of module plugged in/out */
4667 module plugged in/out */
4668} 5800}
4669 5801
5802static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
5803 struct link_params *params,
5804 struct link_vars *vars)
4670 5805
4671static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
4672 struct link_vars *vars,
4673 u8 is_mi_int)
4674{ 5806{
4675 struct bnx2x *bp = params->bp; 5807 struct bnx2x *bp = params->bp;
4676 u32 ext_phy_type; 5808 u8 link_up = 0;
4677 u8 ext_phy_addr; 5809 u16 link_status = 0;
4678 u16 val1 = 0, val2; 5810 u16 rx_alarm_status, lasi_ctrl, val1;
4679 u16 rx_sd, pcs_status; 5811
4680 u8 ext_phy_link_up = 0; 5812 /* If PHY is not initialized, do not check link status */
4681 u8 port = params->port; 5813 bnx2x_cl45_read(bp, phy,
5814 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
5815 &lasi_ctrl);
5816 if (!lasi_ctrl)
5817 return 0;
4682 5818
4683 if (vars->phy_flags & PHY_XGXS_FLAG) { 5819 /* Check the LASI */
4684 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 5820 bnx2x_cl45_read(bp, phy,
4685 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 5821 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4686 switch (ext_phy_type) { 5822 &rx_alarm_status);
4687 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 5823 vars->line_speed = 0;
4688 DP(NETIF_MSG_LINK, "XGXS Direct\n"); 5824 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
4689 ext_phy_link_up = 1;
4690 break;
4691 5825
4692 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 5826 bnx2x_cl45_read(bp, phy,
4693 DP(NETIF_MSG_LINK, "XGXS 8705\n"); 5827 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4694 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4695 ext_phy_addr,
4696 MDIO_WIS_DEVAD,
4697 MDIO_WIS_REG_LASI_STATUS, &val1);
4698 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4699
4700 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4701 ext_phy_addr,
4702 MDIO_WIS_DEVAD,
4703 MDIO_WIS_REG_LASI_STATUS, &val1);
4704 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
4705
4706 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4707 ext_phy_addr,
4708 MDIO_PMA_DEVAD,
4709 MDIO_PMA_REG_RX_SD, &rx_sd);
4710
4711 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4712 ext_phy_addr,
4713 1,
4714 0xc809, &val1);
4715 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4716 ext_phy_addr,
4717 1,
4718 0xc809, &val1);
4719
4720 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
4721 ext_phy_link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) &&
4722 ((val1 & (1<<8)) == 0));
4723 if (ext_phy_link_up)
4724 vars->line_speed = SPEED_10000;
4725 break;
4726 5828
4727 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 5829 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
4728 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4729 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
4730 /* Clear RX Alarm*/
4731 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4732 ext_phy_addr,
4733 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4734 &val2);
4735 /* clear LASI indication*/
4736 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4737 ext_phy_addr,
4738 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4739 &val1);
4740 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4741 ext_phy_addr,
4742 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS,
4743 &val2);
4744 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x-->"
4745 "0x%x\n", val1, val2);
4746
4747 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4748 ext_phy_addr,
4749 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD,
4750 &rx_sd);
4751 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4752 ext_phy_addr,
4753 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS,
4754 &pcs_status);
4755 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4756 ext_phy_addr,
4757 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4758 &val2);
4759 bnx2x_cl45_read(bp, params->port, ext_phy_type,
4760 ext_phy_addr,
4761 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS,
4762 &val2);
4763
4764 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x"
4765 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
4766 rx_sd, pcs_status, val2);
4767 /* link is up if both bit 0 of pmd_rx_sd and
4768 * bit 0 of pcs_status are set, or if the autoneg bit
4769 1 is set
4770 */
4771 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
4772 (val2 & (1<<1)));
4773 if (ext_phy_link_up) {
4774 if (ext_phy_type ==
4775 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
4776 /* If transmitter is disabled,
4777 ignore false link up indication */
4778 bnx2x_cl45_read(bp, params->port,
4779 ext_phy_type,
4780 ext_phy_addr,
4781 MDIO_PMA_DEVAD,
4782 MDIO_PMA_REG_PHY_IDENTIFIER,
4783 &val1);
4784 if (val1 & (1<<15)) {
4785 DP(NETIF_MSG_LINK, "Tx is "
4786 "disabled\n");
4787 ext_phy_link_up = 0;
4788 break;
4789 }
4790 }
4791 if (val2 & (1<<1))
4792 vars->line_speed = SPEED_1000;
4793 else
4794 vars->line_speed = SPEED_10000;
4795 }
4796 break;
4797 5830
4798 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 5831 /* Clear MSG-OUT */
4799 { 5832 bnx2x_cl45_read(bp, phy,
4800 u16 link_status = 0; 5833 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4801 u16 rx_alarm_status;
4802 /* Check the LASI */
4803 bnx2x_cl45_read(bp, params->port,
4804 ext_phy_type,
4805 ext_phy_addr,
4806 MDIO_PMA_DEVAD,
4807 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4808
4809 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
4810 rx_alarm_status);
4811
4812 bnx2x_cl45_read(bp, params->port,
4813 ext_phy_type,
4814 ext_phy_addr,
4815 MDIO_PMA_DEVAD,
4816 MDIO_PMA_REG_LASI_STATUS, &val1);
4817 5834
4818 DP(NETIF_MSG_LINK, 5835 /*
4819 "8727 LASI status 0x%x\n", 5836 * If a module is present and there is need to check
4820 val1); 5837 * for over current
5838 */
5839 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
5840 /* Check over-current using 8727 GPIO0 input*/
5841 bnx2x_cl45_read(bp, phy,
5842 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
5843 &val1);
5844
5845 if ((val1 & (1<<8)) == 0) {
5846 DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
5847 " on port %d\n", params->port);
5848 netdev_err(bp->dev, "Error: Power fault on Port %d has"
5849 " been detected and the power to "
5850 "that SFP+ module has been removed"
5851 " to prevent failure of the card."
5852 " Please remove the SFP+ module and"
5853 " restart the system to clear this"
5854 " error.\n",
5855 params->port);
5856 /* Disable all RX_ALARMs except for mod_abs */
5857 bnx2x_cl45_write(bp, phy,
5858 MDIO_PMA_DEVAD,
5859 MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
4821 5860
4822 /* Clear MSG-OUT */ 5861 bnx2x_cl45_read(bp, phy,
4823 bnx2x_cl45_read(bp, params->port, 5862 MDIO_PMA_DEVAD,
4824 ext_phy_type, 5863 MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
4825 ext_phy_addr, 5864 /* Wait for module_absent_event */
4826 MDIO_PMA_DEVAD, 5865 val1 |= (1<<8);
4827 MDIO_PMA_REG_M8051_MSGOUT_REG, 5866 bnx2x_cl45_write(bp, phy,
4828 &val1); 5867 MDIO_PMA_DEVAD,
5868 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
5869 /* Clear RX alarm */
5870 bnx2x_cl45_read(bp, phy,
5871 MDIO_PMA_DEVAD,
5872 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
5873 return 0;
5874 }
5875 } /* Over current check */
5876
5877 /* When module absent bit is set, check module */
5878 if (rx_alarm_status & (1<<5)) {
5879 bnx2x_8727_handle_mod_abs(phy, params);
5880 /* Enable all mod_abs and link detection bits */
5881 bnx2x_cl45_write(bp, phy,
5882 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
5883 ((1<<5) | (1<<2)));
5884 }
5885 DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
5886 bnx2x_8727_specific_func(phy, params, ENABLE_TX);
5887 /* If transmitter is disabled, ignore false link up indication */
5888 bnx2x_cl45_read(bp, phy,
5889 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
5890 if (val1 & (1<<15)) {
5891 DP(NETIF_MSG_LINK, "Tx is disabled\n");
5892 return 0;
5893 }
4829 5894
4830 /* 5895 bnx2x_cl45_read(bp, phy,
4831 * If a module is present and there is need to check 5896 MDIO_PMA_DEVAD,
4832 * for over current 5897 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
4833 */
4834 if (!(params->feature_config_flags &
4835 FEATURE_CONFIG_BCM8727_NOC) &&
4836 !(rx_alarm_status & (1<<5))) {
4837 /* Check over-current using 8727 GPIO0 input*/
4838 bnx2x_cl45_read(bp, params->port,
4839 ext_phy_type,
4840 ext_phy_addr,
4841 MDIO_PMA_DEVAD,
4842 MDIO_PMA_REG_8727_GPIO_CTRL,
4843 &val1);
4844
4845 if ((val1 & (1<<8)) == 0) {
4846 DP(NETIF_MSG_LINK, "8727 Power fault"
4847 " has been detected on "
4848 "port %d\n",
4849 params->port);
4850 netdev_err(bp->dev, "Error: Power fault on Port %d has been detected and the power to that SFP+ module has been removed to prevent failure of the card. Please remove the SFP+ module and restart the system to clear this error.\n",
4851 params->port);
4852 /*
4853 * Disable all RX_ALARMs except for
4854 * mod_abs
4855 */
4856 bnx2x_cl45_write(bp, params->port,
4857 ext_phy_type,
4858 ext_phy_addr,
4859 MDIO_PMA_DEVAD,
4860 MDIO_PMA_REG_RX_ALARM_CTRL,
4861 (1<<5));
4862
4863 bnx2x_cl45_read(bp, params->port,
4864 ext_phy_type,
4865 ext_phy_addr,
4866 MDIO_PMA_DEVAD,
4867 MDIO_PMA_REG_PHY_IDENTIFIER,
4868 &val1);
4869 /* Wait for module_absent_event */
4870 val1 |= (1<<8);
4871 bnx2x_cl45_write(bp, params->port,
4872 ext_phy_type,
4873 ext_phy_addr,
4874 MDIO_PMA_DEVAD,
4875 MDIO_PMA_REG_PHY_IDENTIFIER,
4876 val1);
4877 /* Clear RX alarm */
4878 bnx2x_cl45_read(bp, params->port,
4879 ext_phy_type,
4880 ext_phy_addr,
4881 MDIO_PMA_DEVAD,
4882 MDIO_PMA_REG_RX_ALARM,
4883 &rx_alarm_status);
4884 break;
4885 }
4886 } /* Over current check */
4887
4888 /* When module absent bit is set, check module */
4889 if (rx_alarm_status & (1<<5)) {
4890 bnx2x_8727_handle_mod_abs(params);
4891 /* Enable all mod_abs and link detection bits */
4892 bnx2x_cl45_write(bp, params->port,
4893 ext_phy_type,
4894 ext_phy_addr,
4895 MDIO_PMA_DEVAD,
4896 MDIO_PMA_REG_RX_ALARM_CTRL,
4897 ((1<<5) | (1<<2)));
4898 }
4899 5898
4900 /* If transmitter is disabled, 5899 /*
4901 ignore false link up indication */ 5900 * Bits 0..2 --> speed detected,
4902 bnx2x_cl45_read(bp, params->port, 5901 * Bits 13..15--> link is down
4903 ext_phy_type, 5902 */
4904 ext_phy_addr, 5903 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4905 MDIO_PMA_DEVAD, 5904 link_up = 1;
4906 MDIO_PMA_REG_PHY_IDENTIFIER, 5905 vars->line_speed = SPEED_10000;
4907 &val1); 5906 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4908 if (val1 & (1<<15)) { 5907 params->port);
4909 DP(NETIF_MSG_LINK, "Tx is disabled\n"); 5908 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4910 ext_phy_link_up = 0; 5909 link_up = 1;
4911 break; 5910 vars->line_speed = SPEED_1000;
4912 } 5911 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
5912 params->port);
5913 } else {
5914 link_up = 0;
5915 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
5916 params->port);
5917 }
5918 if (link_up) {
5919 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5920 vars->duplex = DUPLEX_FULL;
5921 DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
5922 }
4913 5923
4914 bnx2x_cl45_read(bp, params->port, 5924 if ((DUAL_MEDIA(params)) &&
4915 ext_phy_type, 5925 (phy->req_line_speed == SPEED_1000)) {
4916 ext_phy_addr, 5926 bnx2x_cl45_read(bp, phy,
4917 MDIO_PMA_DEVAD, 5927 MDIO_PMA_DEVAD,
4918 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, 5928 MDIO_PMA_REG_8727_PCS_GP, &val1);
4919 &link_status); 5929 /*
4920 5930 * In case of dual-media board and 1G, power up the XAUI side,
4921 /* Bits 0..2 --> speed detected, 5931 * otherwise power it down. For 10G it is done automatically
4922 bits 13..15--> link is down */ 5932 */
4923 if ((link_status & (1<<2)) && 5933 if (link_up)
4924 (!(link_status & (1<<15)))) { 5934 val1 &= ~(3<<10);
4925 ext_phy_link_up = 1; 5935 else
4926 vars->line_speed = SPEED_10000; 5936 val1 |= (3<<10);
4927 } else if ((link_status & (1<<0)) && 5937 bnx2x_cl45_write(bp, phy,
4928 (!(link_status & (1<<13)))) { 5938 MDIO_PMA_DEVAD,
4929 ext_phy_link_up = 1; 5939 MDIO_PMA_REG_8727_PCS_GP, val1);
4930 vars->line_speed = SPEED_1000; 5940 }
4931 DP(NETIF_MSG_LINK, 5941 return link_up;
4932 "port %x: External link" 5942}
4933 " up in 1G\n", params->port);
4934 } else {
4935 ext_phy_link_up = 0;
4936 DP(NETIF_MSG_LINK,
4937 "port %x: External link"
4938 " is down\n", params->port);
4939 }
4940 break;
4941 }
4942 5943
4943 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072: 5944static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
4944 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 5945 struct link_params *params)
4945 { 5946{
4946 u16 link_status = 0; 5947 struct bnx2x *bp = params->bp;
4947 u16 an1000_status = 0; 5948 /* Disable Transmitter */
4948 5949 bnx2x_sfp_set_transmitter(params, phy, 0);
4949 if (ext_phy_type == 5950 /* Clear LASI */
4950 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) { 5951 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
4951 bnx2x_cl45_read(bp, params->port,
4952 ext_phy_type,
4953 ext_phy_addr,
4954 MDIO_PCS_DEVAD,
4955 MDIO_PCS_REG_LASI_STATUS, &val1);
4956 bnx2x_cl45_read(bp, params->port,
4957 ext_phy_type,
4958 ext_phy_addr,
4959 MDIO_PCS_DEVAD,
4960 MDIO_PCS_REG_LASI_STATUS, &val2);
4961 DP(NETIF_MSG_LINK,
4962 "870x LASI status 0x%x->0x%x\n",
4963 val1, val2);
4964 } else {
4965 /* In 8073, port1 is directed through emac0 and
4966 * port0 is directed through emac1
4967 */
4968 bnx2x_cl45_read(bp, params->port,
4969 ext_phy_type,
4970 ext_phy_addr,
4971 MDIO_PMA_DEVAD,
4972 MDIO_PMA_REG_LASI_STATUS, &val1);
4973
4974 DP(NETIF_MSG_LINK,
4975 "8703 LASI status 0x%x\n",
4976 val1);
4977 }
4978 5952
4979 /* clear the interrupt LASI status register */ 5953}
4980 bnx2x_cl45_read(bp, params->port,
4981 ext_phy_type,
4982 ext_phy_addr,
4983 MDIO_PCS_DEVAD,
4984 MDIO_PCS_REG_STATUS, &val2);
4985 bnx2x_cl45_read(bp, params->port,
4986 ext_phy_type,
4987 ext_phy_addr,
4988 MDIO_PCS_DEVAD,
4989 MDIO_PCS_REG_STATUS, &val1);
4990 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
4991 val2, val1);
4992 /* Clear MSG-OUT */
4993 bnx2x_cl45_read(bp, params->port,
4994 ext_phy_type,
4995 ext_phy_addr,
4996 MDIO_PMA_DEVAD,
4997 MDIO_PMA_REG_M8051_MSGOUT_REG,
4998 &val1);
4999
5000 /* Check the LASI */
5001 bnx2x_cl45_read(bp, params->port,
5002 ext_phy_type,
5003 ext_phy_addr,
5004 MDIO_PMA_DEVAD,
5005 MDIO_PMA_REG_RX_ALARM, &val2);
5006
5007 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
5008
5009 /* Check the link status */
5010 bnx2x_cl45_read(bp, params->port,
5011 ext_phy_type,
5012 ext_phy_addr,
5013 MDIO_PCS_DEVAD,
5014 MDIO_PCS_REG_STATUS, &val2);
5015 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
5016
5017 bnx2x_cl45_read(bp, params->port,
5018 ext_phy_type,
5019 ext_phy_addr,
5020 MDIO_PMA_DEVAD,
5021 MDIO_PMA_REG_STATUS, &val2);
5022 bnx2x_cl45_read(bp, params->port,
5023 ext_phy_type,
5024 ext_phy_addr,
5025 MDIO_PMA_DEVAD,
5026 MDIO_PMA_REG_STATUS, &val1);
5027 ext_phy_link_up = ((val1 & 4) == 4);
5028 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
5029 if (ext_phy_type ==
5030 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
5031
5032 if (ext_phy_link_up &&
5033 ((params->req_line_speed !=
5034 SPEED_10000))) {
5035 if (bnx2x_bcm8073_xaui_wa(params)
5036 != 0) {
5037 ext_phy_link_up = 0;
5038 break;
5039 }
5040 }
5041 bnx2x_cl45_read(bp, params->port,
5042 ext_phy_type,
5043 ext_phy_addr,
5044 MDIO_AN_DEVAD,
5045 MDIO_AN_REG_LINK_STATUS,
5046 &an1000_status);
5047 bnx2x_cl45_read(bp, params->port,
5048 ext_phy_type,
5049 ext_phy_addr,
5050 MDIO_AN_DEVAD,
5051 MDIO_AN_REG_LINK_STATUS,
5052 &an1000_status);
5053
5054 /* Check the link status on 1.1.2 */
5055 bnx2x_cl45_read(bp, params->port,
5056 ext_phy_type,
5057 ext_phy_addr,
5058 MDIO_PMA_DEVAD,
5059 MDIO_PMA_REG_STATUS, &val2);
5060 bnx2x_cl45_read(bp, params->port,
5061 ext_phy_type,
5062 ext_phy_addr,
5063 MDIO_PMA_DEVAD,
5064 MDIO_PMA_REG_STATUS, &val1);
5065 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
5066 "an_link_status=0x%x\n",
5067 val2, val1, an1000_status);
5068
5069 ext_phy_link_up = (((val1 & 4) == 4) ||
5070 (an1000_status & (1<<1)));
5071 if (ext_phy_link_up &&
5072 bnx2x_8073_is_snr_needed(params)) {
5073 /* The SNR will improve about 2dbby
5074 changing the BW and FEE main tap.*/
5075
5076 /* The 1st write to change FFE main
5077 tap is set before restart AN */
5078 /* Change PLL Bandwidth in EDC
5079 register */
5080 bnx2x_cl45_write(bp, port, ext_phy_type,
5081 ext_phy_addr,
5082 MDIO_PMA_DEVAD,
5083 MDIO_PMA_REG_PLL_BANDWIDTH,
5084 0x26BC);
5085
5086 /* Change CDR Bandwidth in EDC
5087 register */
5088 bnx2x_cl45_write(bp, port, ext_phy_type,
5089 ext_phy_addr,
5090 MDIO_PMA_DEVAD,
5091 MDIO_PMA_REG_CDR_BANDWIDTH,
5092 0x0333);
5093 }
5094 bnx2x_cl45_read(bp, params->port,
5095 ext_phy_type,
5096 ext_phy_addr,
5097 MDIO_PMA_DEVAD,
5098 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
5099 &link_status);
5100
5101 /* Bits 0..2 --> speed detected,
5102 bits 13..15--> link is down */
5103 if ((link_status & (1<<2)) &&
5104 (!(link_status & (1<<15)))) {
5105 ext_phy_link_up = 1;
5106 vars->line_speed = SPEED_10000;
5107 DP(NETIF_MSG_LINK,
5108 "port %x: External link"
5109 " up in 10G\n", params->port);
5110 } else if ((link_status & (1<<1)) &&
5111 (!(link_status & (1<<14)))) {
5112 ext_phy_link_up = 1;
5113 vars->line_speed = SPEED_2500;
5114 DP(NETIF_MSG_LINK,
5115 "port %x: External link"
5116 " up in 2.5G\n", params->port);
5117 } else if ((link_status & (1<<0)) &&
5118 (!(link_status & (1<<13)))) {
5119 ext_phy_link_up = 1;
5120 vars->line_speed = SPEED_1000;
5121 DP(NETIF_MSG_LINK,
5122 "port %x: External link"
5123 " up in 1G\n", params->port);
5124 } else {
5125 ext_phy_link_up = 0;
5126 DP(NETIF_MSG_LINK,
5127 "port %x: External link"
5128 " is down\n", params->port);
5129 }
5130 } else {
5131 /* See if 1G link is up for the 8072 */
5132 bnx2x_cl45_read(bp, params->port,
5133 ext_phy_type,
5134 ext_phy_addr,
5135 MDIO_AN_DEVAD,
5136 MDIO_AN_REG_LINK_STATUS,
5137 &an1000_status);
5138 bnx2x_cl45_read(bp, params->port,
5139 ext_phy_type,
5140 ext_phy_addr,
5141 MDIO_AN_DEVAD,
5142 MDIO_AN_REG_LINK_STATUS,
5143 &an1000_status);
5144 if (an1000_status & (1<<1)) {
5145 ext_phy_link_up = 1;
5146 vars->line_speed = SPEED_1000;
5147 DP(NETIF_MSG_LINK,
5148 "port %x: External link"
5149 " up in 1G\n", params->port);
5150 } else if (ext_phy_link_up) {
5151 ext_phy_link_up = 1;
5152 vars->line_speed = SPEED_10000;
5153 DP(NETIF_MSG_LINK,
5154 "port %x: External link"
5155 " up in 10G\n", params->port);
5156 }
5157 }
5158 5954
5955/******************************************************************/
5956/* BCM8481/BCM84823/BCM84833 PHY SECTION */
5957/******************************************************************/
5958static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
5959 struct link_params *params)
5960{
5961 u16 val, fw_ver1, fw_ver2, cnt, adj;
5962 struct bnx2x *bp = params->bp;
5159 5963
5160 break; 5964 adj = 0;
5161 } 5965 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
5162 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 5966 adj = -1;
5163 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5164 ext_phy_addr,
5165 MDIO_PMA_DEVAD,
5166 MDIO_PMA_REG_LASI_STATUS, &val2);
5167 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5168 ext_phy_addr,
5169 MDIO_PMA_DEVAD,
5170 MDIO_PMA_REG_LASI_STATUS, &val1);
5171 DP(NETIF_MSG_LINK,
5172 "10G-base-T LASI status 0x%x->0x%x\n",
5173 val2, val1);
5174 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5175 ext_phy_addr,
5176 MDIO_PMA_DEVAD,
5177 MDIO_PMA_REG_STATUS, &val2);
5178 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5179 ext_phy_addr,
5180 MDIO_PMA_DEVAD,
5181 MDIO_PMA_REG_STATUS, &val1);
5182 DP(NETIF_MSG_LINK,
5183 "10G-base-T PMA status 0x%x->0x%x\n",
5184 val2, val1);
5185 ext_phy_link_up = ((val1 & 4) == 4);
5186 /* if link is up
5187 * print the AN outcome of the SFX7101 PHY
5188 */
5189 if (ext_phy_link_up) {
5190 bnx2x_cl45_read(bp, params->port,
5191 ext_phy_type,
5192 ext_phy_addr,
5193 MDIO_AN_DEVAD,
5194 MDIO_AN_REG_MASTER_STATUS,
5195 &val2);
5196 vars->line_speed = SPEED_10000;
5197 DP(NETIF_MSG_LINK,
5198 "SFX7101 AN status 0x%x->Master=%x\n",
5199 val2,
5200 (val2 & (1<<14)));
5201 }
5202 break;
5203 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5204 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5205 /* Check 10G-BaseT link status */
5206 /* Check PMD signal ok */
5207 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5208 ext_phy_addr,
5209 MDIO_AN_DEVAD,
5210 0xFFFA,
5211 &val1);
5212 bnx2x_cl45_read(bp, params->port, ext_phy_type,
5213 ext_phy_addr,
5214 MDIO_PMA_DEVAD,
5215 MDIO_PMA_REG_8481_PMD_SIGNAL,
5216 &val2);
5217 DP(NETIF_MSG_LINK, "PMD_SIGNAL 1.a811 = 0x%x\n", val2);
5218
5219 /* Check link 10G */
5220 if (val2 & (1<<11)) {
5221 vars->line_speed = SPEED_10000;
5222 ext_phy_link_up = 1;
5223 bnx2x_8481_set_10G_led_mode(params,
5224 ext_phy_type,
5225 ext_phy_addr);
5226 } else { /* Check Legacy speed link */
5227 u16 legacy_status, legacy_speed;
5228
5229 /* Enable expansion register 0x42
5230 (Operation mode status) */
5231 bnx2x_cl45_write(bp, params->port,
5232 ext_phy_type,
5233 ext_phy_addr,
5234 MDIO_AN_DEVAD,
5235 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS,
5236 0xf42);
5237
5238 /* Get legacy speed operation status */
5239 bnx2x_cl45_read(bp, params->port,
5240 ext_phy_type,
5241 ext_phy_addr,
5242 MDIO_AN_DEVAD,
5243 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
5244 &legacy_status);
5245
5246 DP(NETIF_MSG_LINK, "Legacy speed status"
5247 " = 0x%x\n", legacy_status);
5248 ext_phy_link_up = ((legacy_status & (1<<11))
5249 == (1<<11));
5250 if (ext_phy_link_up) {
5251 legacy_speed = (legacy_status & (3<<9));
5252 if (legacy_speed == (0<<9))
5253 vars->line_speed = SPEED_10;
5254 else if (legacy_speed == (1<<9))
5255 vars->line_speed =
5256 SPEED_100;
5257 else if (legacy_speed == (2<<9))
5258 vars->line_speed =
5259 SPEED_1000;
5260 else /* Should not happen */
5261 vars->line_speed = 0;
5262
5263 if (legacy_status & (1<<8))
5264 vars->duplex = DUPLEX_FULL;
5265 else
5266 vars->duplex = DUPLEX_HALF;
5267
5268 DP(NETIF_MSG_LINK, "Link is up "
5269 "in %dMbps, is_duplex_full"
5270 "= %d\n",
5271 vars->line_speed,
5272 (vars->duplex == DUPLEX_FULL));
5273 bnx2x_8481_set_legacy_led_mode(params,
5274 ext_phy_type,
5275 ext_phy_addr);
5276 }
5277 }
5278 break;
5279 default:
5280 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
5281 params->ext_phy_config);
5282 ext_phy_link_up = 0;
5283 break;
5284 }
5285 /* Set SGMII mode for external phy */
5286 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5287 if (vars->line_speed < SPEED_1000)
5288 vars->phy_flags |= PHY_SGMII_FLAG;
5289 else
5290 vars->phy_flags &= ~PHY_SGMII_FLAG;
5291 }
5292 5967
5293 } else { /* SerDes */ 5968 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
5294 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 5969 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
5295 switch (ext_phy_type) { 5970 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0014);
5296 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT: 5971 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200);
5297 DP(NETIF_MSG_LINK, "SerDes Direct\n"); 5972 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, 0x0000);
5298 ext_phy_link_up = 1; 5973 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, 0x0300);
5299 break; 5974 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x0009);
5300 5975
5301 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482: 5976 for (cnt = 0; cnt < 100; cnt++) {
5302 DP(NETIF_MSG_LINK, "SerDes 5482\n"); 5977 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val);
5303 ext_phy_link_up = 1; 5978 if (val & 1)
5304 break; 5979 break;
5980 udelay(5);
5981 }
5982 if (cnt == 100) {
5983 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
5984 bnx2x_save_spirom_version(bp, params->port, 0,
5985 phy->ver_addr);
5986 return;
5987 }
5305 5988
5306 default: 5989
5307 DP(NETIF_MSG_LINK, 5990 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
5308 "BAD SerDes ext_phy_config 0x%x\n", 5991 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819 + adj, 0x0000);
5309 params->ext_phy_config); 5992 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A + adj, 0xc200);
5310 ext_phy_link_up = 0; 5993 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817 + adj, 0x000A);
5994 for (cnt = 0; cnt < 100; cnt++) {
5995 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818 + adj, &val);
5996 if (val & 1)
5311 break; 5997 break;
5312 } 5998 udelay(5);
5313 } 5999 }
6000 if (cnt == 100) {
6001 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
6002 bnx2x_save_spirom_version(bp, params->port, 0,
6003 phy->ver_addr);
6004 return;
6005 }
6006
6007 /* lower 16 bits of the register SPI_FW_STATUS */
6008 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B + adj, &fw_ver1);
6009 /* upper 16 bits of register SPI_FW_STATUS */
6010 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C + adj, &fw_ver2);
5314 6011
5315 return ext_phy_link_up; 6012 bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
6013 phy->ver_addr);
5316} 6014}
5317 6015
5318static void bnx2x_link_int_enable(struct link_params *params) 6016static void bnx2x_848xx_set_led(struct bnx2x *bp,
6017 struct bnx2x_phy *phy)
5319{ 6018{
5320 u8 port = params->port; 6019 u16 val, adj;
5321 u32 ext_phy_type;
5322 u32 mask;
5323 struct bnx2x *bp = params->bp;
5324 6020
5325 /* setting the status to report on link up 6021 adj = 0;
5326 for either XGXS or SerDes */ 6022 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
5327 6023 adj = -1;
5328 if (params->switch_cfg == SWITCH_CFG_10G) {
5329 mask = (NIG_MASK_XGXS0_LINK10G |
5330 NIG_MASK_XGXS0_LINK_STATUS);
5331 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5332 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5333 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
5334 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
5335 (ext_phy_type !=
5336 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
5337 mask |= NIG_MASK_MI_INT;
5338 DP(NETIF_MSG_LINK, "enabled external phy int\n");
5339 }
5340 6024
5341 } else { /* SerDes */ 6025 /* PHYC_CTL_LED_CTL */
5342 mask = NIG_MASK_SERDES0_LINK_STATUS; 6026 bnx2x_cl45_read(bp, phy,
5343 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n"); 6027 MDIO_PMA_DEVAD,
5344 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 6028 MDIO_PMA_REG_8481_LINK_SIGNAL + adj, &val);
5345 if ((ext_phy_type != 6029 val &= 0xFE00;
5346 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) && 6030 val |= 0x0092;
5347 (ext_phy_type != 6031
5348 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) { 6032 bnx2x_cl45_write(bp, phy,
5349 mask |= NIG_MASK_MI_INT; 6033 MDIO_PMA_DEVAD,
5350 DP(NETIF_MSG_LINK, "enabled external phy int\n"); 6034 MDIO_PMA_REG_8481_LINK_SIGNAL + adj, val);
5351 } 6035
5352 } 6036 bnx2x_cl45_write(bp, phy,
5353 bnx2x_bits_en(bp, 6037 MDIO_PMA_DEVAD,
5354 NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 6038 MDIO_PMA_REG_8481_LED1_MASK + adj,
5355 mask); 6039 0x80);
6040
6041 bnx2x_cl45_write(bp, phy,
6042 MDIO_PMA_DEVAD,
6043 MDIO_PMA_REG_8481_LED2_MASK + adj,
6044 0x18);
6045
6046 /* Select activity source by Tx and Rx, as suggested by PHY AE */
6047 bnx2x_cl45_write(bp, phy,
6048 MDIO_PMA_DEVAD,
6049 MDIO_PMA_REG_8481_LED3_MASK + adj,
6050 0x0006);
6051
6052 /* Select the closest activity blink rate to that in 10/100/1000 */
6053 bnx2x_cl45_write(bp, phy,
6054 MDIO_PMA_DEVAD,
6055 MDIO_PMA_REG_8481_LED3_BLINK + adj,
6056 0);
6057
6058 bnx2x_cl45_read(bp, phy,
6059 MDIO_PMA_DEVAD,
6060 MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, &val);
6061 val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
6062
6063 bnx2x_cl45_write(bp, phy,
6064 MDIO_PMA_DEVAD,
6065 MDIO_PMA_REG_84823_CTL_LED_CTL_1 + adj, val);
5356 6066
5357 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port, 6067 /* 'Interrupt Mask' */
5358 (params->switch_cfg == SWITCH_CFG_10G), 6068 bnx2x_cl45_write(bp, phy,
5359 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4)); 6069 MDIO_AN_DEVAD,
5360 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n", 6070 0xFFFB, 0xFFFD);
5361 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5362 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5363 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5364 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5365 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5366 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5367} 6071}
5368 6072
5369static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port, 6073static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
5370 u8 is_mi_int) 6074 struct link_params *params,
6075 struct link_vars *vars)
5371{ 6076{
5372 u32 latch_status = 0, is_mi_int_status; 6077 struct bnx2x *bp = params->bp;
5373 /* Disable the MI INT ( external phy int ) 6078 u16 autoneg_val, an_1000_val, an_10_100_val;
5374 * by writing 1 to the status register. Link down indication 6079 /*
5375 * is high-active-signal, so in this case we need to write the 6080 * This phy uses the NIG latch mechanism since link indication
5376 * status to clear the XOR 6081 * arrives through its LED4 and not via its LASI signal, so we
6082 * get steady signal instead of clear on read
5377 */ 6083 */
5378 /* Read Latched signals */ 6084 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
5379 latch_status = REG_RD(bp, 6085 1 << NIG_LATCH_BC_ENABLE_MI_INT);
5380 NIG_REG_LATCH_STATUS_0 + port*8); 6086
5381 is_mi_int_status = REG_RD(bp, 6087 bnx2x_cl45_write(bp, phy,
5382 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4); 6088 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
5383 DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x," 6089
5384 "latch_status = 0x%x\n", 6090 bnx2x_848xx_set_led(bp, phy);
5385 is_mi_int, is_mi_int_status, latch_status); 6091
5386 /* Handle only those with latched-signal=up.*/ 6092 /* set 1000 speed advertisement */
5387 if (latch_status & 1) { 6093 bnx2x_cl45_read(bp, phy,
5388 /* For all latched-signal=up,Write original_signal to status */ 6094 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
5389 if (is_mi_int) 6095 &an_1000_val);
5390 bnx2x_bits_en(bp, 6096
5391 NIG_REG_STATUS_INTERRUPT_PORT0 6097 bnx2x_ext_phy_set_pause(params, phy, vars);
5392 + port*4, 6098 bnx2x_cl45_read(bp, phy,
5393 NIG_STATUS_EMAC0_MI_INT); 6099 MDIO_AN_DEVAD,
5394 else 6100 MDIO_AN_REG_8481_LEGACY_AN_ADV,
5395 bnx2x_bits_dis(bp, 6101 &an_10_100_val);
5396 NIG_REG_STATUS_INTERRUPT_PORT0 6102 bnx2x_cl45_read(bp, phy,
5397 + port*4, 6103 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
5398 NIG_STATUS_EMAC0_MI_INT); 6104 &autoneg_val);
5399 /* For all latched-signal=up : Re-Arm Latch signals */ 6105 /* Disable forced speed */
5400 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8, 6106 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
5401 (latch_status & 0xfffe) | (latch_status & 1)); 6107 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
6108
6109 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6110 (phy->speed_cap_mask &
6111 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
6112 (phy->req_line_speed == SPEED_1000)) {
6113 an_1000_val |= (1<<8);
6114 autoneg_val |= (1<<9 | 1<<12);
6115 if (phy->req_duplex == DUPLEX_FULL)
6116 an_1000_val |= (1<<9);
6117 DP(NETIF_MSG_LINK, "Advertising 1G\n");
6118 } else
6119 an_1000_val &= ~((1<<8) | (1<<9));
6120
6121 bnx2x_cl45_write(bp, phy,
6122 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
6123 an_1000_val);
6124
6125 /* set 10 speed advertisement */
6126 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6127 (phy->speed_cap_mask &
6128 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
6129 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
6130 an_10_100_val |= (1<<7);
6131 /* Enable autoneg and restart autoneg for legacy speeds */
6132 autoneg_val |= (1<<9 | 1<<12);
6133
6134 if (phy->req_duplex == DUPLEX_FULL)
6135 an_10_100_val |= (1<<8);
6136 DP(NETIF_MSG_LINK, "Advertising 100M\n");
6137 }
6138 /* set 10 speed advertisement */
6139 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6140 (phy->speed_cap_mask &
6141 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
6142 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
6143 an_10_100_val |= (1<<5);
6144 autoneg_val |= (1<<9 | 1<<12);
6145 if (phy->req_duplex == DUPLEX_FULL)
6146 an_10_100_val |= (1<<6);
6147 DP(NETIF_MSG_LINK, "Advertising 10M\n");
6148 }
6149
6150 /* Only 10/100 are allowed to work in FORCE mode */
6151 if (phy->req_line_speed == SPEED_100) {
6152 autoneg_val |= (1<<13);
6153 /* Enabled AUTO-MDIX when autoneg is disabled */
6154 bnx2x_cl45_write(bp, phy,
6155 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6156 (1<<15 | 1<<9 | 7<<0));
6157 DP(NETIF_MSG_LINK, "Setting 100M force\n");
5402 } 6158 }
6159 if (phy->req_line_speed == SPEED_10) {
6160 /* Enabled AUTO-MDIX when autoneg is disabled */
6161 bnx2x_cl45_write(bp, phy,
6162 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
6163 (1<<15 | 1<<9 | 7<<0));
6164 DP(NETIF_MSG_LINK, "Setting 10M force\n");
6165 }
6166
6167 bnx2x_cl45_write(bp, phy,
6168 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
6169 an_10_100_val);
6170
6171 if (phy->req_duplex == DUPLEX_FULL)
6172 autoneg_val |= (1<<8);
6173
6174 bnx2x_cl45_write(bp, phy,
6175 MDIO_AN_DEVAD,
6176 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
6177
6178 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
6179 (phy->speed_cap_mask &
6180 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
6181 (phy->req_line_speed == SPEED_10000)) {
6182 DP(NETIF_MSG_LINK, "Advertising 10G\n");
6183 /* Restart autoneg for 10G*/
6184
6185 bnx2x_cl45_write(bp, phy,
6186 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
6187 0x3200);
6188 } else if (phy->req_line_speed != SPEED_10 &&
6189 phy->req_line_speed != SPEED_100) {
6190 bnx2x_cl45_write(bp, phy,
6191 MDIO_AN_DEVAD,
6192 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
6193 1);
6194 }
6195 /* Save spirom version */
6196 bnx2x_save_848xx_spirom_version(phy, params);
6197
6198 return 0;
5403} 6199}
5404/* 6200
5405 * link management 6201static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
5406 */ 6202 struct link_params *params,
5407static void bnx2x_link_int_ack(struct link_params *params, 6203 struct link_vars *vars)
5408 struct link_vars *vars, u8 is_10g,
5409 u8 is_mi_int)
5410{ 6204{
5411 struct bnx2x *bp = params->bp; 6205 struct bnx2x *bp = params->bp;
5412 u8 port = params->port; 6206 /* Restore normal power mode*/
6207 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6208 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5413 6209
5414 /* first reset all status 6210 /* HW reset */
5415 * we assume only one line will be change at a time */ 6211 bnx2x_ext_phy_hw_reset(bp, params->port);
5416 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 6212 bnx2x_wait_reset_complete(bp, phy, params);
5417 (NIG_STATUS_XGXS0_LINK10G |
5418 NIG_STATUS_XGXS0_LINK_STATUS |
5419 NIG_STATUS_SERDES0_LINK_STATUS));
5420 if ((XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5421 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
5422 (XGXS_EXT_PHY_TYPE(params->ext_phy_config)
5423 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
5424 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
5425 }
5426 if (vars->phy_link_up) {
5427 if (is_10g) {
5428 /* Disable the 10G link interrupt
5429 * by writing 1 to the status register
5430 */
5431 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
5432 bnx2x_bits_en(bp,
5433 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5434 NIG_STATUS_XGXS0_LINK10G);
5435 6213
5436 } else if (params->switch_cfg == SWITCH_CFG_10G) { 6214 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
5437 /* Disable the link interrupt 6215 return bnx2x_848xx_cmn_config_init(phy, params, vars);
5438 * by writing 1 to the relevant lane 6216}
5439 * in the status register
5440 */
5441 u32 ser_lane = ((params->lane_config &
5442 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5443 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5444 6217
5445 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n", 6218static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
5446 vars->line_speed); 6219 struct link_params *params,
5447 bnx2x_bits_en(bp, 6220 struct link_vars *vars)
5448 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 6221{
5449 ((1 << ser_lane) << 6222 struct bnx2x *bp = params->bp;
5450 NIG_STATUS_XGXS0_LINK_STATUS_SIZE)); 6223 u8 port, initialize = 1;
6224 u16 val, adj;
6225 u16 temp;
6226 u32 actual_phy_selection, cms_enable;
6227 u8 rc = 0;
5451 6228
5452 } else { /* SerDes */ 6229 /* This is just for MDIO_CTL_REG_84823_MEDIA register. */
5453 DP(NETIF_MSG_LINK, "SerDes phy link up\n"); 6230 adj = 0;
5454 /* Disable the link interrupt 6231 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
5455 * by writing 1 to the status register 6232 adj = 3;
5456 */
5457 bnx2x_bits_en(bp,
5458 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5459 NIG_STATUS_SERDES0_LINK_STATUS);
5460 }
5461 6233
5462 } else { /* link_down */ 6234 msleep(1);
6235 if (CHIP_IS_E2(bp))
6236 port = BP_PATH(bp);
6237 else
6238 port = params->port;
6239 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6240 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
6241 port);
6242 bnx2x_wait_reset_complete(bp, phy, params);
6243 /* Wait for GPHY to come out of reset */
6244 msleep(50);
6245 /*
6246 * BCM84823 requires that XGXS links up first @ 10G for normal behavior
6247 */
6248 temp = vars->line_speed;
6249 vars->line_speed = SPEED_10000;
6250 bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
6251 bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
6252 vars->line_speed = temp;
6253
6254 /* Set dual-media configuration according to configuration */
6255
6256 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
6257 MDIO_CTL_REG_84823_MEDIA + adj, &val);
6258 val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
6259 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
6260 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
6261 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
6262 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
6263 val |= MDIO_CTL_REG_84823_CTRL_MAC_XFI |
6264 MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L;
6265
6266 actual_phy_selection = bnx2x_phy_selection(params);
6267
6268 switch (actual_phy_selection) {
6269 case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6270 /* Do nothing. Essentially this is like the priority copper */
6271 break;
6272 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6273 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
6274 break;
6275 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6276 val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
6277 break;
6278 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
6279 /* Do nothing here. The first PHY won't be initialized at all */
6280 break;
6281 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
6282 val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
6283 initialize = 0;
6284 break;
5463 } 6285 }
6286 if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
6287 val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
6288
6289 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
6290 MDIO_CTL_REG_84823_MEDIA + adj, val);
6291 DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
6292 params->multi_phy_config, val);
6293
6294 if (initialize)
6295 rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
6296 else
6297 bnx2x_save_848xx_spirom_version(phy, params);
6298 cms_enable = REG_RD(bp, params->shmem_base +
6299 offsetof(struct shmem_region,
6300 dev_info.port_hw_config[params->port].default_cfg)) &
6301 PORT_HW_CFG_ENABLE_CMS_MASK;
6302
6303 bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
6304 MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
6305 if (cms_enable)
6306 val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
6307 else
6308 val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
6309 bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
6310 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
6311
6312
6313 return rc;
5464} 6314}
5465 6315
5466static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len) 6316static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
6317 struct link_params *params,
6318 struct link_vars *vars)
5467{ 6319{
5468 u8 *str_ptr = str; 6320 struct bnx2x *bp = params->bp;
5469 u32 mask = 0xf0000000; 6321 u16 val, val1, val2, adj;
5470 u8 shift = 8*4; 6322 u8 link_up = 0;
5471 u8 digit; 6323
5472 if (len < 10) { 6324 /* Reg offset adjustment for 84833 */
5473 /* Need more than 10chars for this format */ 6325 adj = 0;
5474 *str_ptr = '\0'; 6326 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
5475 return -EINVAL; 6327 adj = -1;
5476 } 6328
5477 while (shift > 0) { 6329 /* Check 10G-BaseT link status */
6330 /* Check PMD signal ok */
6331 bnx2x_cl45_read(bp, phy,
6332 MDIO_AN_DEVAD, 0xFFFA, &val1);
6333 bnx2x_cl45_read(bp, phy,
6334 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL + adj,
6335 &val2);
6336 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
6337
6338 /* Check link 10G */
6339 if (val2 & (1<<11)) {
6340 vars->line_speed = SPEED_10000;
6341 vars->duplex = DUPLEX_FULL;
6342 link_up = 1;
6343 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6344 } else { /* Check Legacy speed link */
6345 u16 legacy_status, legacy_speed;
6346
6347 /* Enable expansion register 0x42 (Operation mode status) */
6348 bnx2x_cl45_write(bp, phy,
6349 MDIO_AN_DEVAD,
6350 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
6351
6352 /* Get legacy speed operation status */
6353 bnx2x_cl45_read(bp, phy,
6354 MDIO_AN_DEVAD,
6355 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
6356 &legacy_status);
6357
6358 DP(NETIF_MSG_LINK, "Legacy speed status"
6359 " = 0x%x\n", legacy_status);
6360 link_up = ((legacy_status & (1<<11)) == (1<<11));
6361 if (link_up) {
6362 legacy_speed = (legacy_status & (3<<9));
6363 if (legacy_speed == (0<<9))
6364 vars->line_speed = SPEED_10;
6365 else if (legacy_speed == (1<<9))
6366 vars->line_speed = SPEED_100;
6367 else if (legacy_speed == (2<<9))
6368 vars->line_speed = SPEED_1000;
6369 else /* Should not happen */
6370 vars->line_speed = 0;
5478 6371
5479 shift -= 4; 6372 if (legacy_status & (1<<8))
5480 digit = ((num & mask) >> shift); 6373 vars->duplex = DUPLEX_FULL;
5481 if (digit < 0xa) 6374 else
5482 *str_ptr = digit + '0'; 6375 vars->duplex = DUPLEX_HALF;
5483 else 6376
5484 *str_ptr = digit - 0xa + 'a'; 6377 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
5485 str_ptr++; 6378 " is_duplex_full= %d\n", vars->line_speed,
5486 mask = mask >> 4; 6379 (vars->duplex == DUPLEX_FULL));
5487 if (shift == 4*4) { 6380 /* Check legacy speed AN resolution */
5488 *str_ptr = ':'; 6381 bnx2x_cl45_read(bp, phy,
5489 str_ptr++; 6382 MDIO_AN_DEVAD,
6383 MDIO_AN_REG_8481_LEGACY_MII_STATUS,
6384 &val);
6385 if (val & (1<<5))
6386 vars->link_status |=
6387 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6388 bnx2x_cl45_read(bp, phy,
6389 MDIO_AN_DEVAD,
6390 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
6391 &val);
6392 if ((val & (1<<0)) == 0)
6393 vars->link_status |=
6394 LINK_STATUS_PARALLEL_DETECTION_USED;
5490 } 6395 }
5491 } 6396 }
5492 *str_ptr = '\0'; 6397 if (link_up) {
5493 return 0; 6398 DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
6399 vars->line_speed);
6400 bnx2x_ext_phy_resolve_fc(phy, params, vars);
6401 }
6402
6403 return link_up;
5494} 6404}
5495 6405
5496u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded, 6406static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
5497 u8 *version, u16 len)
5498{ 6407{
5499 struct bnx2x *bp; 6408 u8 status = 0;
5500 u32 ext_phy_type = 0; 6409 u32 spirom_ver;
5501 u32 spirom_ver = 0; 6410 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
5502 u8 status; 6411 status = bnx2x_format_ver(spirom_ver, str, len);
6412 return status;
6413}
5503 6414
5504 if (version == NULL || params == NULL) 6415static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
5505 return -EINVAL; 6416 struct link_params *params)
5506 bp = params->bp; 6417{
6418 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6419 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
6420 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6421 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
6422}
5507 6423
5508 spirom_ver = REG_RD(bp, params->shmem_base + 6424static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
5509 offsetof(struct shmem_region, 6425 struct link_params *params)
5510 port_mb[params->port].ext_phy_fw_version)); 6426{
6427 bnx2x_cl45_write(params->bp, phy,
6428 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6429 bnx2x_cl45_write(params->bp, phy,
6430 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
6431}
5511 6432
5512 status = 0; 6433static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
5513 /* reset the returned value to zero */ 6434 struct link_params *params)
5514 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 6435{
5515 switch (ext_phy_type) { 6436 struct bnx2x *bp = params->bp;
5516 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 6437 u8 port;
6438 if (CHIP_IS_E2(bp))
6439 port = BP_PATH(bp);
6440 else
6441 port = params->port;
6442 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
6443 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6444 port);
6445}
5517 6446
5518 if (len < 5) 6447static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
5519 return -EINVAL; 6448 struct link_params *params, u8 mode)
6449{
6450 struct bnx2x *bp = params->bp;
6451 u16 val;
5520 6452
5521 version[0] = (spirom_ver & 0xFF); 6453 switch (mode) {
5522 version[1] = (spirom_ver & 0xFF00) >> 8; 6454 case LED_MODE_OFF:
5523 version[2] = (spirom_ver & 0xFF0000) >> 16;
5524 version[3] = (spirom_ver & 0xFF000000) >> 24;
5525 version[4] = '\0';
5526 6455
5527 break; 6456 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", params->port);
5528 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5529 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
5530 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
5531 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
5532 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
5533 status = bnx2x_format_ver(spirom_ver, version, len);
5534 break;
5535 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
5536 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
5537 spirom_ver = ((spirom_ver & 0xF80) >> 7) << 16 |
5538 (spirom_ver & 0x7F);
5539 status = bnx2x_format_ver(spirom_ver, version, len);
5540 break;
5541 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
5542 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
5543 version[0] = '\0';
5544 break;
5545 6457
5546 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE: 6458 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5547 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:" 6459 SHARED_HW_CFG_LED_EXTPHY1) {
5548 " type is FAILURE!\n"); 6460
5549 status = -EINVAL; 6461 /* Set LED masks */
6462 bnx2x_cl45_write(bp, phy,
6463 MDIO_PMA_DEVAD,
6464 MDIO_PMA_REG_8481_LED1_MASK,
6465 0x0);
6466
6467 bnx2x_cl45_write(bp, phy,
6468 MDIO_PMA_DEVAD,
6469 MDIO_PMA_REG_8481_LED2_MASK,
6470 0x0);
6471
6472 bnx2x_cl45_write(bp, phy,
6473 MDIO_PMA_DEVAD,
6474 MDIO_PMA_REG_8481_LED3_MASK,
6475 0x0);
6476
6477 bnx2x_cl45_write(bp, phy,
6478 MDIO_PMA_DEVAD,
6479 MDIO_PMA_REG_8481_LED5_MASK,
6480 0x0);
6481
6482 } else {
6483 bnx2x_cl45_write(bp, phy,
6484 MDIO_PMA_DEVAD,
6485 MDIO_PMA_REG_8481_LED1_MASK,
6486 0x0);
6487 }
5550 break; 6488 break;
6489 case LED_MODE_FRONT_PANEL_OFF:
5551 6490
5552 default: 6491 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
6492 params->port);
6493
6494 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6495 SHARED_HW_CFG_LED_EXTPHY1) {
6496
6497 /* Set LED masks */
6498 bnx2x_cl45_write(bp, phy,
6499 MDIO_PMA_DEVAD,
6500 MDIO_PMA_REG_8481_LED1_MASK,
6501 0x0);
6502
6503 bnx2x_cl45_write(bp, phy,
6504 MDIO_PMA_DEVAD,
6505 MDIO_PMA_REG_8481_LED2_MASK,
6506 0x0);
6507
6508 bnx2x_cl45_write(bp, phy,
6509 MDIO_PMA_DEVAD,
6510 MDIO_PMA_REG_8481_LED3_MASK,
6511 0x0);
6512
6513 bnx2x_cl45_write(bp, phy,
6514 MDIO_PMA_DEVAD,
6515 MDIO_PMA_REG_8481_LED5_MASK,
6516 0x20);
6517
6518 } else {
6519 bnx2x_cl45_write(bp, phy,
6520 MDIO_PMA_DEVAD,
6521 MDIO_PMA_REG_8481_LED1_MASK,
6522 0x0);
6523 }
5553 break; 6524 break;
5554 } 6525 case LED_MODE_ON:
5555 return status;
5556}
5557 6526
5558static void bnx2x_set_xgxs_loopback(struct link_params *params, 6527 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", params->port);
5559 struct link_vars *vars,
5560 u8 is_10g)
5561{
5562 u8 port = params->port;
5563 struct bnx2x *bp = params->bp;
5564 6528
5565 if (is_10g) { 6529 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
5566 u32 md_devad; 6530 SHARED_HW_CFG_LED_EXTPHY1) {
6531 /* Set control reg */
6532 bnx2x_cl45_read(bp, phy,
6533 MDIO_PMA_DEVAD,
6534 MDIO_PMA_REG_8481_LINK_SIGNAL,
6535 &val);
6536 val &= 0x8000;
6537 val |= 0x2492;
5567 6538
5568 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n"); 6539 bnx2x_cl45_write(bp, phy,
6540 MDIO_PMA_DEVAD,
6541 MDIO_PMA_REG_8481_LINK_SIGNAL,
6542 val);
5569 6543
5570 /* change the uni_phy_addr in the nig */ 6544 /* Set LED masks */
5571 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD + 6545 bnx2x_cl45_write(bp, phy,
5572 port*0x18)); 6546 MDIO_PMA_DEVAD,
6547 MDIO_PMA_REG_8481_LED1_MASK,
6548 0x0);
5573 6549
5574 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5); 6550 bnx2x_cl45_write(bp, phy,
6551 MDIO_PMA_DEVAD,
6552 MDIO_PMA_REG_8481_LED2_MASK,
6553 0x20);
5575 6554
5576 bnx2x_cl45_write(bp, port, 0, 6555 bnx2x_cl45_write(bp, phy,
5577 params->phy_addr, 6556 MDIO_PMA_DEVAD,
5578 5, 6557 MDIO_PMA_REG_8481_LED3_MASK,
5579 (MDIO_REG_BANK_AER_BLOCK + 6558 0x20);
5580 (MDIO_AER_BLOCK_AER_REG & 0xf)),
5581 0x2800);
5582
5583 bnx2x_cl45_write(bp, port, 0,
5584 params->phy_addr,
5585 5,
5586 (MDIO_REG_BANK_CL73_IEEEB0 +
5587 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5588 0x6041);
5589 msleep(200);
5590 /* set aer mmd back */
5591 bnx2x_set_aer_mmd(params, vars);
5592 6559
5593 /* and md_devad */ 6560 bnx2x_cl45_write(bp, phy,
5594 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 6561 MDIO_PMA_DEVAD,
5595 md_devad); 6562 MDIO_PMA_REG_8481_LED5_MASK,
6563 0x0);
6564 } else {
6565 bnx2x_cl45_write(bp, phy,
6566 MDIO_PMA_DEVAD,
6567 MDIO_PMA_REG_8481_LED1_MASK,
6568 0x20);
6569 }
6570 break;
5596 6571
5597 } else { 6572 case LED_MODE_OPER:
5598 u16 mii_control;
5599 6573
5600 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n"); 6574 DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", params->port);
6575
6576 if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
6577 SHARED_HW_CFG_LED_EXTPHY1) {
6578
6579 /* Set control reg */
6580 bnx2x_cl45_read(bp, phy,
6581 MDIO_PMA_DEVAD,
6582 MDIO_PMA_REG_8481_LINK_SIGNAL,
6583 &val);
6584
6585 if (!((val &
6586 MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
6587 >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
6588 DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
6589 bnx2x_cl45_write(bp, phy,
6590 MDIO_PMA_DEVAD,
6591 MDIO_PMA_REG_8481_LINK_SIGNAL,
6592 0xa492);
6593 }
6594
6595 /* Set LED masks */
6596 bnx2x_cl45_write(bp, phy,
6597 MDIO_PMA_DEVAD,
6598 MDIO_PMA_REG_8481_LED1_MASK,
6599 0x10);
6600
6601 bnx2x_cl45_write(bp, phy,
6602 MDIO_PMA_DEVAD,
6603 MDIO_PMA_REG_8481_LED2_MASK,
6604 0x80);
5601 6605
5602 CL45_RD_OVER_CL22(bp, port, 6606 bnx2x_cl45_write(bp, phy,
5603 params->phy_addr, 6607 MDIO_PMA_DEVAD,
5604 MDIO_REG_BANK_COMBO_IEEE0, 6608 MDIO_PMA_REG_8481_LED3_MASK,
5605 MDIO_COMBO_IEEE0_MII_CONTROL, 6609 0x98);
5606 &mii_control); 6610
6611 bnx2x_cl45_write(bp, phy,
6612 MDIO_PMA_DEVAD,
6613 MDIO_PMA_REG_8481_LED5_MASK,
6614 0x40);
6615
6616 } else {
6617 bnx2x_cl45_write(bp, phy,
6618 MDIO_PMA_DEVAD,
6619 MDIO_PMA_REG_8481_LED1_MASK,
6620 0x80);
5607 6621
5608 CL45_WR_OVER_CL22(bp, port, 6622 /* Tell LED3 to blink on source */
5609 params->phy_addr, 6623 bnx2x_cl45_read(bp, phy,
5610 MDIO_REG_BANK_COMBO_IEEE0, 6624 MDIO_PMA_DEVAD,
5611 MDIO_COMBO_IEEE0_MII_CONTROL, 6625 MDIO_PMA_REG_8481_LINK_SIGNAL,
5612 (mii_control | 6626 &val);
5613 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK)); 6627 val &= ~(7<<6);
6628 val |= (1<<6); /* A83B[8:6]= 1 */
6629 bnx2x_cl45_write(bp, phy,
6630 MDIO_PMA_DEVAD,
6631 MDIO_PMA_REG_8481_LINK_SIGNAL,
6632 val);
6633 }
6634 break;
5614 } 6635 }
5615} 6636}
6637/******************************************************************/
6638/* SFX7101 PHY SECTION */
6639/******************************************************************/
6640static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
6641 struct link_params *params)
6642{
6643 struct bnx2x *bp = params->bp;
6644 /* SFX7101_XGXS_TEST1 */
6645 bnx2x_cl45_write(bp, phy,
6646 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
6647}
5616 6648
5617 6649static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
5618static void bnx2x_ext_phy_loopback(struct link_params *params) 6650 struct link_params *params,
6651 struct link_vars *vars)
5619{ 6652{
6653 u16 fw_ver1, fw_ver2, val;
5620 struct bnx2x *bp = params->bp; 6654 struct bnx2x *bp = params->bp;
5621 u8 ext_phy_addr; 6655 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
5622 u32 ext_phy_type;
5623 6656
5624 if (params->switch_cfg == SWITCH_CFG_10G) { 6657 /* Restore normal power mode*/
5625 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 6658 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5626 ext_phy_addr = XGXS_EXT_PHY_ADDR(params->ext_phy_config); 6659 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
5627 /* CL37 Autoneg Enabled */ 6660 /* HW reset */
5628 switch (ext_phy_type) { 6661 bnx2x_ext_phy_hw_reset(bp, params->port);
5629 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT: 6662 bnx2x_wait_reset_complete(bp, phy, params);
5630 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN: 6663
5631 DP(NETIF_MSG_LINK, 6664 bnx2x_cl45_write(bp, phy,
5632 "ext_phy_loopback: We should not get here\n"); 6665 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
5633 break; 6666 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
5634 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705: 6667 bnx2x_cl45_write(bp, phy,
5635 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n"); 6668 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
5636 break; 6669
5637 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706: 6670 bnx2x_ext_phy_set_pause(params, phy, vars);
5638 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n"); 6671 /* Restart autoneg */
5639 break; 6672 bnx2x_cl45_read(bp, phy,
5640 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 6673 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
5641 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n"); 6674 val |= 0x200;
5642 bnx2x_cl45_write(bp, params->port, ext_phy_type, 6675 bnx2x_cl45_write(bp, phy,
5643 ext_phy_addr, 6676 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
5644 MDIO_PMA_DEVAD, 6677
5645 MDIO_PMA_REG_CTRL, 6678 /* Save spirom version */
5646 0x0001); 6679 bnx2x_cl45_read(bp, phy,
5647 break; 6680 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
5648 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101: 6681
5649 /* SFX7101_XGXS_TEST1 */ 6682 bnx2x_cl45_read(bp, phy,
5650 bnx2x_cl45_write(bp, params->port, ext_phy_type, 6683 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
5651 ext_phy_addr, 6684 bnx2x_save_spirom_version(bp, params->port,
5652 MDIO_XS_DEVAD, 6685 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
5653 MDIO_XS_SFX7101_XGXS_TEST1, 6686 return 0;
5654 0x100); 6687}
5655 DP(NETIF_MSG_LINK,
5656 "ext_phy_loopback: set ext phy loopback\n");
5657 break;
5658 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
5659 6688
5660 break; 6689static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
5661 } /* switch external PHY type */ 6690 struct link_params *params,
5662 } else { 6691 struct link_vars *vars)
5663 /* serdes */ 6692{
5664 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config); 6693 struct bnx2x *bp = params->bp;
5665 ext_phy_addr = (params->ext_phy_config & 6694 u8 link_up;
5666 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK) 6695 u16 val1, val2;
5667 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT; 6696 bnx2x_cl45_read(bp, phy,
6697 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
6698 bnx2x_cl45_read(bp, phy,
6699 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
6700 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
6701 val2, val1);
6702 bnx2x_cl45_read(bp, phy,
6703 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
6704 bnx2x_cl45_read(bp, phy,
6705 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
6706 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
6707 val2, val1);
6708 link_up = ((val1 & 4) == 4);
6709 /* if link is up print the AN outcome of the SFX7101 PHY */
6710 if (link_up) {
6711 bnx2x_cl45_read(bp, phy,
6712 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
6713 &val2);
6714 vars->line_speed = SPEED_10000;
6715 vars->duplex = DUPLEX_FULL;
6716 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
6717 val2, (val2 & (1<<14)));
6718 bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
6719 bnx2x_ext_phy_resolve_fc(phy, params, vars);
5668 } 6720 }
6721 return link_up;
5669} 6722}
5670 6723
5671 6724
5672/* 6725static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5673 *------------------------------------------------------------------------
5674 * bnx2x_override_led_value -
5675 *
5676 * Override the led value of the requsted led
5677 *
5678 *------------------------------------------------------------------------
5679 */
5680u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
5681 u32 led_idx, u32 value)
5682{ 6726{
5683 u32 reg_val; 6727 if (*len < 5)
6728 return -EINVAL;
6729 str[0] = (spirom_ver & 0xFF);
6730 str[1] = (spirom_ver & 0xFF00) >> 8;
6731 str[2] = (spirom_ver & 0xFF0000) >> 16;
6732 str[3] = (spirom_ver & 0xFF000000) >> 24;
6733 str[4] = '\0';
6734 *len -= 5;
6735 return 0;
6736}
5684 6737
5685 /* If port 0 then use EMAC0, else use EMAC1*/ 6738void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
5686 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0; 6739{
6740 u16 val, cnt;
5687 6741
5688 DP(NETIF_MSG_LINK, 6742 bnx2x_cl45_read(bp, phy,
5689 "bnx2x_override_led_value() port %x led_idx %d value %d\n", 6743 MDIO_PMA_DEVAD,
5690 port, led_idx, value); 6744 MDIO_PMA_REG_7101_RESET, &val);
5691
5692 switch (led_idx) {
5693 case 0: /* 10MB led */
5694 /* Read the current value of the LED register in
5695 the EMAC block */
5696 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5697 /* Set the OVERRIDE bit to 1 */
5698 reg_val |= EMAC_LED_OVERRIDE;
5699 /* If value is 1, set the 10M_OVERRIDE bit,
5700 otherwise reset it.*/
5701 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
5702 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
5703 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5704 break;
5705 case 1: /*100MB led */
5706 /*Read the current value of the LED register in
5707 the EMAC block */
5708 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5709 /* Set the OVERRIDE bit to 1 */
5710 reg_val |= EMAC_LED_OVERRIDE;
5711 /* If value is 1, set the 100M_OVERRIDE bit,
5712 otherwise reset it.*/
5713 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
5714 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
5715 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5716 break;
5717 case 2: /* 1000MB led */
5718 /* Read the current value of the LED register in the
5719 EMAC block */
5720 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5721 /* Set the OVERRIDE bit to 1 */
5722 reg_val |= EMAC_LED_OVERRIDE;
5723 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
5724 reset it. */
5725 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
5726 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
5727 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5728 break;
5729 case 3: /* 2500MB led */
5730 /* Read the current value of the LED register in the
5731 EMAC block*/
5732 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
5733 /* Set the OVERRIDE bit to 1 */
5734 reg_val |= EMAC_LED_OVERRIDE;
5735 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
5736 reset it.*/
5737 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
5738 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
5739 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5740 break;
5741 case 4: /*10G led */
5742 if (port == 0) {
5743 REG_WR(bp, NIG_REG_LED_10G_P0,
5744 value);
5745 } else {
5746 REG_WR(bp, NIG_REG_LED_10G_P1,
5747 value);
5748 }
5749 break;
5750 case 5: /* TRAFFIC led */
5751 /* Find if the traffic control is via BMAC or EMAC */
5752 if (port == 0)
5753 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
5754 else
5755 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
5756
5757 /* Override the traffic led in the EMAC:*/
5758 if (reg_val == 1) {
5759 /* Read the current value of the LED register in
5760 the EMAC block */
5761 reg_val = REG_RD(bp, emac_base +
5762 EMAC_REG_EMAC_LED);
5763 /* Set the TRAFFIC_OVERRIDE bit to 1 */
5764 reg_val |= EMAC_LED_OVERRIDE;
5765 /* If value is 1, set the TRAFFIC bit, otherwise
5766 reset it.*/
5767 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
5768 (reg_val & ~EMAC_LED_TRAFFIC);
5769 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
5770 } else { /* Override the traffic led in the BMAC: */
5771 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5772 + port*4, 1);
5773 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
5774 value);
5775 }
5776 break;
5777 default:
5778 DP(NETIF_MSG_LINK,
5779 "bnx2x_override_led_value() unknown led index %d "
5780 "(should be 0-5)\n", led_idx);
5781 return -EINVAL;
5782 }
5783 6745
5784 return 0; 6746 for (cnt = 0; cnt < 10; cnt++) {
6747 msleep(50);
6748 /* Writes a self-clearing reset */
6749 bnx2x_cl45_write(bp, phy,
6750 MDIO_PMA_DEVAD,
6751 MDIO_PMA_REG_7101_RESET,
6752 (val | (1<<15)));
6753 /* Wait for clear */
6754 bnx2x_cl45_read(bp, phy,
6755 MDIO_PMA_DEVAD,
6756 MDIO_PMA_REG_7101_RESET, &val);
6757
6758 if ((val & (1<<15)) == 0)
6759 break;
6760 }
5785} 6761}
5786 6762
6763static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
6764 struct link_params *params) {
6765 /* Low power mode is controlled by GPIO 2 */
6766 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
6767 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6768 /* The PHY reset is controlled by GPIO 1 */
6769 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
6770 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
6771}
5787 6772
5788u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed) 6773static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
6774 struct link_params *params, u8 mode)
5789{ 6775{
5790 u8 port = params->port; 6776 u16 val = 0;
5791 u16 hw_led_mode = params->hw_led_mode;
5792 u8 rc = 0;
5793 u32 tmp;
5794 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5795 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
5796 struct bnx2x *bp = params->bp; 6777 struct bnx2x *bp = params->bp;
5797 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5798 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5799 speed, hw_led_mode);
5800 switch (mode) { 6778 switch (mode) {
6779 case LED_MODE_FRONT_PANEL_OFF:
5801 case LED_MODE_OFF: 6780 case LED_MODE_OFF:
5802 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0); 6781 val = 2;
5803 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 6782 break;
5804 SHARED_HW_CFG_LED_MAC1); 6783 case LED_MODE_ON:
5805 6784 val = 1;
5806 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5807 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5808 break; 6785 break;
5809
5810 case LED_MODE_OPER: 6786 case LED_MODE_OPER:
5811 if (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) { 6787 val = 0;
5812 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0); 6788 break;
5813 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1); 6789 }
6790 bnx2x_cl45_write(bp, phy,
6791 MDIO_PMA_DEVAD,
6792 MDIO_PMA_REG_7107_LINK_LED_CNTL,
6793 val);
6794}
6795
6796/******************************************************************/
6797/* STATIC PHY DECLARATION */
6798/******************************************************************/
6799
6800static struct bnx2x_phy phy_null = {
6801 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
6802 .addr = 0,
6803 .flags = FLAGS_INIT_XGXS_FIRST,
6804 .def_md_devad = 0,
6805 .reserved = 0,
6806 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6807 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6808 .mdio_ctrl = 0,
6809 .supported = 0,
6810 .media_type = ETH_PHY_NOT_PRESENT,
6811 .ver_addr = 0,
6812 .req_flow_ctrl = 0,
6813 .req_line_speed = 0,
6814 .speed_cap_mask = 0,
6815 .req_duplex = 0,
6816 .rsrv = 0,
6817 .config_init = (config_init_t)NULL,
6818 .read_status = (read_status_t)NULL,
6819 .link_reset = (link_reset_t)NULL,
6820 .config_loopback = (config_loopback_t)NULL,
6821 .format_fw_ver = (format_fw_ver_t)NULL,
6822 .hw_reset = (hw_reset_t)NULL,
6823 .set_link_led = (set_link_led_t)NULL,
6824 .phy_specific_func = (phy_specific_func_t)NULL
6825};
6826
6827static struct bnx2x_phy phy_serdes = {
6828 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
6829 .addr = 0xff,
6830 .flags = 0,
6831 .def_md_devad = 0,
6832 .reserved = 0,
6833 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6834 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6835 .mdio_ctrl = 0,
6836 .supported = (SUPPORTED_10baseT_Half |
6837 SUPPORTED_10baseT_Full |
6838 SUPPORTED_100baseT_Half |
6839 SUPPORTED_100baseT_Full |
6840 SUPPORTED_1000baseT_Full |
6841 SUPPORTED_2500baseX_Full |
6842 SUPPORTED_TP |
6843 SUPPORTED_Autoneg |
6844 SUPPORTED_Pause |
6845 SUPPORTED_Asym_Pause),
6846 .media_type = ETH_PHY_UNSPECIFIED,
6847 .ver_addr = 0,
6848 .req_flow_ctrl = 0,
6849 .req_line_speed = 0,
6850 .speed_cap_mask = 0,
6851 .req_duplex = 0,
6852 .rsrv = 0,
6853 .config_init = (config_init_t)bnx2x_init_serdes,
6854 .read_status = (read_status_t)bnx2x_link_settings_status,
6855 .link_reset = (link_reset_t)bnx2x_int_link_reset,
6856 .config_loopback = (config_loopback_t)NULL,
6857 .format_fw_ver = (format_fw_ver_t)NULL,
6858 .hw_reset = (hw_reset_t)NULL,
6859 .set_link_led = (set_link_led_t)NULL,
6860 .phy_specific_func = (phy_specific_func_t)NULL
6861};
6862
6863static struct bnx2x_phy phy_xgxs = {
6864 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
6865 .addr = 0xff,
6866 .flags = 0,
6867 .def_md_devad = 0,
6868 .reserved = 0,
6869 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6870 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6871 .mdio_ctrl = 0,
6872 .supported = (SUPPORTED_10baseT_Half |
6873 SUPPORTED_10baseT_Full |
6874 SUPPORTED_100baseT_Half |
6875 SUPPORTED_100baseT_Full |
6876 SUPPORTED_1000baseT_Full |
6877 SUPPORTED_2500baseX_Full |
6878 SUPPORTED_10000baseT_Full |
6879 SUPPORTED_FIBRE |
6880 SUPPORTED_Autoneg |
6881 SUPPORTED_Pause |
6882 SUPPORTED_Asym_Pause),
6883 .media_type = ETH_PHY_UNSPECIFIED,
6884 .ver_addr = 0,
6885 .req_flow_ctrl = 0,
6886 .req_line_speed = 0,
6887 .speed_cap_mask = 0,
6888 .req_duplex = 0,
6889 .rsrv = 0,
6890 .config_init = (config_init_t)bnx2x_init_xgxs,
6891 .read_status = (read_status_t)bnx2x_link_settings_status,
6892 .link_reset = (link_reset_t)bnx2x_int_link_reset,
6893 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
6894 .format_fw_ver = (format_fw_ver_t)NULL,
6895 .hw_reset = (hw_reset_t)NULL,
6896 .set_link_led = (set_link_led_t)NULL,
6897 .phy_specific_func = (phy_specific_func_t)NULL
6898};
6899
6900static struct bnx2x_phy phy_7101 = {
6901 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
6902 .addr = 0xff,
6903 .flags = FLAGS_FAN_FAILURE_DET_REQ,
6904 .def_md_devad = 0,
6905 .reserved = 0,
6906 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6907 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6908 .mdio_ctrl = 0,
6909 .supported = (SUPPORTED_10000baseT_Full |
6910 SUPPORTED_TP |
6911 SUPPORTED_Autoneg |
6912 SUPPORTED_Pause |
6913 SUPPORTED_Asym_Pause),
6914 .media_type = ETH_PHY_BASE_T,
6915 .ver_addr = 0,
6916 .req_flow_ctrl = 0,
6917 .req_line_speed = 0,
6918 .speed_cap_mask = 0,
6919 .req_duplex = 0,
6920 .rsrv = 0,
6921 .config_init = (config_init_t)bnx2x_7101_config_init,
6922 .read_status = (read_status_t)bnx2x_7101_read_status,
6923 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
6924 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
6925 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
6926 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
6927 .set_link_led = (set_link_led_t)bnx2x_7101_set_link_led,
6928 .phy_specific_func = (phy_specific_func_t)NULL
6929};
6930static struct bnx2x_phy phy_8073 = {
6931 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6932 .addr = 0xff,
6933 .flags = FLAGS_HW_LOCK_REQUIRED,
6934 .def_md_devad = 0,
6935 .reserved = 0,
6936 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6937 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6938 .mdio_ctrl = 0,
6939 .supported = (SUPPORTED_10000baseT_Full |
6940 SUPPORTED_2500baseX_Full |
6941 SUPPORTED_1000baseT_Full |
6942 SUPPORTED_FIBRE |
6943 SUPPORTED_Autoneg |
6944 SUPPORTED_Pause |
6945 SUPPORTED_Asym_Pause),
6946 .media_type = ETH_PHY_UNSPECIFIED,
6947 .ver_addr = 0,
6948 .req_flow_ctrl = 0,
6949 .req_line_speed = 0,
6950 .speed_cap_mask = 0,
6951 .req_duplex = 0,
6952 .rsrv = 0,
6953 .config_init = (config_init_t)bnx2x_8073_config_init,
6954 .read_status = (read_status_t)bnx2x_8073_read_status,
6955 .link_reset = (link_reset_t)bnx2x_8073_link_reset,
6956 .config_loopback = (config_loopback_t)NULL,
6957 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
6958 .hw_reset = (hw_reset_t)NULL,
6959 .set_link_led = (set_link_led_t)NULL,
6960 .phy_specific_func = (phy_specific_func_t)NULL
6961};
6962static struct bnx2x_phy phy_8705 = {
6963 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
6964 .addr = 0xff,
6965 .flags = FLAGS_INIT_XGXS_FIRST,
6966 .def_md_devad = 0,
6967 .reserved = 0,
6968 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6969 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6970 .mdio_ctrl = 0,
6971 .supported = (SUPPORTED_10000baseT_Full |
6972 SUPPORTED_FIBRE |
6973 SUPPORTED_Pause |
6974 SUPPORTED_Asym_Pause),
6975 .media_type = ETH_PHY_XFP_FIBER,
6976 .ver_addr = 0,
6977 .req_flow_ctrl = 0,
6978 .req_line_speed = 0,
6979 .speed_cap_mask = 0,
6980 .req_duplex = 0,
6981 .rsrv = 0,
6982 .config_init = (config_init_t)bnx2x_8705_config_init,
6983 .read_status = (read_status_t)bnx2x_8705_read_status,
6984 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
6985 .config_loopback = (config_loopback_t)NULL,
6986 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
6987 .hw_reset = (hw_reset_t)NULL,
6988 .set_link_led = (set_link_led_t)NULL,
6989 .phy_specific_func = (phy_specific_func_t)NULL
6990};
6991static struct bnx2x_phy phy_8706 = {
6992 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
6993 .addr = 0xff,
6994 .flags = FLAGS_INIT_XGXS_FIRST,
6995 .def_md_devad = 0,
6996 .reserved = 0,
6997 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6998 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
6999 .mdio_ctrl = 0,
7000 .supported = (SUPPORTED_10000baseT_Full |
7001 SUPPORTED_1000baseT_Full |
7002 SUPPORTED_FIBRE |
7003 SUPPORTED_Pause |
7004 SUPPORTED_Asym_Pause),
7005 .media_type = ETH_PHY_SFP_FIBER,
7006 .ver_addr = 0,
7007 .req_flow_ctrl = 0,
7008 .req_line_speed = 0,
7009 .speed_cap_mask = 0,
7010 .req_duplex = 0,
7011 .rsrv = 0,
7012 .config_init = (config_init_t)bnx2x_8706_config_init,
7013 .read_status = (read_status_t)bnx2x_8706_read_status,
7014 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
7015 .config_loopback = (config_loopback_t)NULL,
7016 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
7017 .hw_reset = (hw_reset_t)NULL,
7018 .set_link_led = (set_link_led_t)NULL,
7019 .phy_specific_func = (phy_specific_func_t)NULL
7020};
7021
7022static struct bnx2x_phy phy_8726 = {
7023 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
7024 .addr = 0xff,
7025 .flags = (FLAGS_HW_LOCK_REQUIRED |
7026 FLAGS_INIT_XGXS_FIRST),
7027 .def_md_devad = 0,
7028 .reserved = 0,
7029 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7030 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7031 .mdio_ctrl = 0,
7032 .supported = (SUPPORTED_10000baseT_Full |
7033 SUPPORTED_1000baseT_Full |
7034 SUPPORTED_Autoneg |
7035 SUPPORTED_FIBRE |
7036 SUPPORTED_Pause |
7037 SUPPORTED_Asym_Pause),
7038 .media_type = ETH_PHY_SFP_FIBER,
7039 .ver_addr = 0,
7040 .req_flow_ctrl = 0,
7041 .req_line_speed = 0,
7042 .speed_cap_mask = 0,
7043 .req_duplex = 0,
7044 .rsrv = 0,
7045 .config_init = (config_init_t)bnx2x_8726_config_init,
7046 .read_status = (read_status_t)bnx2x_8726_read_status,
7047 .link_reset = (link_reset_t)bnx2x_8726_link_reset,
7048 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
7049 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
7050 .hw_reset = (hw_reset_t)NULL,
7051 .set_link_led = (set_link_led_t)NULL,
7052 .phy_specific_func = (phy_specific_func_t)NULL
7053};
7054
7055static struct bnx2x_phy phy_8727 = {
7056 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
7057 .addr = 0xff,
7058 .flags = FLAGS_FAN_FAILURE_DET_REQ,
7059 .def_md_devad = 0,
7060 .reserved = 0,
7061 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7062 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7063 .mdio_ctrl = 0,
7064 .supported = (SUPPORTED_10000baseT_Full |
7065 SUPPORTED_1000baseT_Full |
7066 SUPPORTED_FIBRE |
7067 SUPPORTED_Pause |
7068 SUPPORTED_Asym_Pause),
7069 .media_type = ETH_PHY_SFP_FIBER,
7070 .ver_addr = 0,
7071 .req_flow_ctrl = 0,
7072 .req_line_speed = 0,
7073 .speed_cap_mask = 0,
7074 .req_duplex = 0,
7075 .rsrv = 0,
7076 .config_init = (config_init_t)bnx2x_8727_config_init,
7077 .read_status = (read_status_t)bnx2x_8727_read_status,
7078 .link_reset = (link_reset_t)bnx2x_8727_link_reset,
7079 .config_loopback = (config_loopback_t)NULL,
7080 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
7081 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
7082 .set_link_led = (set_link_led_t)bnx2x_8727_set_link_led,
7083 .phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
7084};
7085static struct bnx2x_phy phy_8481 = {
7086 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
7087 .addr = 0xff,
7088 .flags = FLAGS_FAN_FAILURE_DET_REQ |
7089 FLAGS_REARM_LATCH_SIGNAL,
7090 .def_md_devad = 0,
7091 .reserved = 0,
7092 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7093 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7094 .mdio_ctrl = 0,
7095 .supported = (SUPPORTED_10baseT_Half |
7096 SUPPORTED_10baseT_Full |
7097 SUPPORTED_100baseT_Half |
7098 SUPPORTED_100baseT_Full |
7099 SUPPORTED_1000baseT_Full |
7100 SUPPORTED_10000baseT_Full |
7101 SUPPORTED_TP |
7102 SUPPORTED_Autoneg |
7103 SUPPORTED_Pause |
7104 SUPPORTED_Asym_Pause),
7105 .media_type = ETH_PHY_BASE_T,
7106 .ver_addr = 0,
7107 .req_flow_ctrl = 0,
7108 .req_line_speed = 0,
7109 .speed_cap_mask = 0,
7110 .req_duplex = 0,
7111 .rsrv = 0,
7112 .config_init = (config_init_t)bnx2x_8481_config_init,
7113 .read_status = (read_status_t)bnx2x_848xx_read_status,
7114 .link_reset = (link_reset_t)bnx2x_8481_link_reset,
7115 .config_loopback = (config_loopback_t)NULL,
7116 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
7117 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
7118 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
7119 .phy_specific_func = (phy_specific_func_t)NULL
7120};
7121
7122static struct bnx2x_phy phy_84823 = {
7123 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
7124 .addr = 0xff,
7125 .flags = FLAGS_FAN_FAILURE_DET_REQ |
7126 FLAGS_REARM_LATCH_SIGNAL,
7127 .def_md_devad = 0,
7128 .reserved = 0,
7129 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7130 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7131 .mdio_ctrl = 0,
7132 .supported = (SUPPORTED_10baseT_Half |
7133 SUPPORTED_10baseT_Full |
7134 SUPPORTED_100baseT_Half |
7135 SUPPORTED_100baseT_Full |
7136 SUPPORTED_1000baseT_Full |
7137 SUPPORTED_10000baseT_Full |
7138 SUPPORTED_TP |
7139 SUPPORTED_Autoneg |
7140 SUPPORTED_Pause |
7141 SUPPORTED_Asym_Pause),
7142 .media_type = ETH_PHY_BASE_T,
7143 .ver_addr = 0,
7144 .req_flow_ctrl = 0,
7145 .req_line_speed = 0,
7146 .speed_cap_mask = 0,
7147 .req_duplex = 0,
7148 .rsrv = 0,
7149 .config_init = (config_init_t)bnx2x_848x3_config_init,
7150 .read_status = (read_status_t)bnx2x_848xx_read_status,
7151 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
7152 .config_loopback = (config_loopback_t)NULL,
7153 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
7154 .hw_reset = (hw_reset_t)NULL,
7155 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
7156 .phy_specific_func = (phy_specific_func_t)NULL
7157};
7158
7159static struct bnx2x_phy phy_84833 = {
7160 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
7161 .addr = 0xff,
7162 .flags = FLAGS_FAN_FAILURE_DET_REQ |
7163 FLAGS_REARM_LATCH_SIGNAL,
7164 .def_md_devad = 0,
7165 .reserved = 0,
7166 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7167 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
7168 .mdio_ctrl = 0,
7169 .supported = (SUPPORTED_10baseT_Half |
7170 SUPPORTED_10baseT_Full |
7171 SUPPORTED_100baseT_Half |
7172 SUPPORTED_100baseT_Full |
7173 SUPPORTED_1000baseT_Full |
7174 SUPPORTED_10000baseT_Full |
7175 SUPPORTED_TP |
7176 SUPPORTED_Autoneg |
7177 SUPPORTED_Pause |
7178 SUPPORTED_Asym_Pause),
7179 .media_type = ETH_PHY_BASE_T,
7180 .ver_addr = 0,
7181 .req_flow_ctrl = 0,
7182 .req_line_speed = 0,
7183 .speed_cap_mask = 0,
7184 .req_duplex = 0,
7185 .rsrv = 0,
7186 .config_init = (config_init_t)bnx2x_848x3_config_init,
7187 .read_status = (read_status_t)bnx2x_848xx_read_status,
7188 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
7189 .config_loopback = (config_loopback_t)NULL,
7190 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
7191 .hw_reset = (hw_reset_t)NULL,
7192 .set_link_led = (set_link_led_t)bnx2x_848xx_set_link_led,
7193 .phy_specific_func = (phy_specific_func_t)NULL
7194};
7195
7196/*****************************************************************/
7197/* */
7198/* Populate the phy according. Main function: bnx2x_populate_phy */
7199/* */
7200/*****************************************************************/
7201
7202static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
7203 struct bnx2x_phy *phy, u8 port,
7204 u8 phy_index)
7205{
7206 /* Get the 4 lanes xgxs config rx and tx */
7207 u32 rx = 0, tx = 0, i;
7208 for (i = 0; i < 2; i++) {
7209 /*
7210 * INT_PHY and EXT_PHY1 share the same value location in the
7211 * shmem. When num_phys is greater than 1, than this value
7212 * applies only to EXT_PHY1
7213 */
7214 if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
7215 rx = REG_RD(bp, shmem_base +
7216 offsetof(struct shmem_region,
7217 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
7218
7219 tx = REG_RD(bp, shmem_base +
7220 offsetof(struct shmem_region,
7221 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
5814 } else { 7222 } else {
5815 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 7223 rx = REG_RD(bp, shmem_base +
5816 hw_led_mode); 7224 offsetof(struct shmem_region,
7225 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
7226
7227 tx = REG_RD(bp, shmem_base +
7228 offsetof(struct shmem_region,
7229 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
5817 } 7230 }
5818 7231
5819 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + 7232 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
5820 port*4, 0); 7233 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
5821 /* Set blinking rate to ~15.9Hz */
5822 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
5823 LED_BLINK_RATE_VAL);
5824 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
5825 port*4, 1);
5826 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5827 EMAC_WR(bp, EMAC_REG_EMAC_LED,
5828 (tmp & (~EMAC_LED_OVERRIDE)));
5829 7234
5830 if (CHIP_IS_E1(bp) && 7235 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
5831 ((speed == SPEED_2500) || 7236 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
5832 (speed == SPEED_1000) || 7237 }
5833 (speed == SPEED_100) || 7238}
5834 (speed == SPEED_10))) {
5835 /* On Everest 1 Ax chip versions for speeds less than
5836 10G LED scheme is different */
5837 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
5838 + port*4, 1);
5839 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
5840 port*4, 0);
5841 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
5842 port*4, 1);
5843 }
5844 break;
5845 7239
5846 default: 7240static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
5847 rc = -EINVAL; 7241 u8 phy_index, u8 port)
5848 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n", 7242{
5849 mode); 7243 u32 ext_phy_config = 0;
7244 switch (phy_index) {
7245 case EXT_PHY1:
7246 ext_phy_config = REG_RD(bp, shmem_base +
7247 offsetof(struct shmem_region,
7248 dev_info.port_hw_config[port].external_phy_config));
5850 break; 7249 break;
7250 case EXT_PHY2:
7251 ext_phy_config = REG_RD(bp, shmem_base +
7252 offsetof(struct shmem_region,
7253 dev_info.port_hw_config[port].external_phy_config2));
7254 break;
7255 default:
7256 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
7257 return -EINVAL;
5851 } 7258 }
5852 return rc;
5853 7259
7260 return ext_phy_config;
5854} 7261}
5855 7262static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
5856u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars) 7263 struct bnx2x_phy *phy)
5857{ 7264{
5858 struct bnx2x *bp = params->bp; 7265 u32 phy_addr;
5859 u16 gp_status = 0; 7266 u32 chip_id;
7267 u32 switch_cfg = (REG_RD(bp, shmem_base +
7268 offsetof(struct shmem_region,
7269 dev_info.port_feature_config[port].link_config)) &
7270 PORT_FEATURE_CONNECTED_SWITCH_MASK);
7271 chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
7272 switch (switch_cfg) {
7273 case SWITCH_CFG_1G:
7274 phy_addr = REG_RD(bp,
7275 NIG_REG_SERDES0_CTRL_PHY_ADDR +
7276 port * 0x10);
7277 *phy = phy_serdes;
7278 break;
7279 case SWITCH_CFG_10G:
7280 phy_addr = REG_RD(bp,
7281 NIG_REG_XGXS0_CTRL_PHY_ADDR +
7282 port * 0x18);
7283 *phy = phy_xgxs;
7284 break;
7285 default:
7286 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
7287 return -EINVAL;
7288 }
7289 phy->addr = (u8)phy_addr;
7290 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
7291 SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
7292 port);
7293 if (CHIP_IS_E2(bp))
7294 phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
7295 else
7296 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
5860 7297
5861 CL45_RD_OVER_CL22(bp, params->port, 7298 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
5862 params->phy_addr, 7299 port, phy->addr, phy->mdio_ctrl);
5863 MDIO_REG_BANK_GP_STATUS,
5864 MDIO_GP_STATUS_TOP_AN_STATUS1,
5865 &gp_status);
5866 /* link is up only if both local phy and external phy are up */
5867 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
5868 bnx2x_ext_phy_is_link_up(params, vars, 1))
5869 return 0;
5870 7300
5871 return -ESRCH; 7301 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
7302 return 0;
5872} 7303}
5873 7304
5874static u8 bnx2x_link_initialize(struct link_params *params, 7305static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
5875 struct link_vars *vars) 7306 u8 phy_index,
7307 u32 shmem_base,
7308 u32 shmem2_base,
7309 u8 port,
7310 struct bnx2x_phy *phy)
5876{ 7311{
5877 struct bnx2x *bp = params->bp; 7312 u32 ext_phy_config, phy_type, config2;
5878 u8 port = params->port; 7313 u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
5879 u8 rc = 0; 7314 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
5880 u8 non_ext_phy; 7315 phy_index, port);
5881 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config); 7316 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
7317 /* Select the phy type */
7318 switch (phy_type) {
7319 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
7320 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
7321 *phy = phy_8073;
7322 break;
7323 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
7324 *phy = phy_8705;
7325 break;
7326 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
7327 *phy = phy_8706;
7328 break;
7329 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7330 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7331 *phy = phy_8726;
7332 break;
7333 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
7334 /* BCM8727_NOC => BCM8727 no over current */
7335 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7336 *phy = phy_8727;
7337 phy->flags |= FLAGS_NOC;
7338 break;
7339 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7340 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
7341 *phy = phy_8727;
7342 break;
7343 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
7344 *phy = phy_8481;
7345 break;
7346 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
7347 *phy = phy_84823;
7348 break;
7349 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
7350 *phy = phy_84833;
7351 break;
7352 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
7353 *phy = phy_7101;
7354 break;
7355 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
7356 *phy = phy_null;
7357 return -EINVAL;
7358 default:
7359 *phy = phy_null;
7360 return 0;
7361 }
5882 7362
5883 /* Activate the external PHY */ 7363 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
5884 bnx2x_ext_phy_reset(params, vars); 7364 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
5885 7365
5886 bnx2x_set_aer_mmd(params, vars); 7366 /*
7367 * The shmem address of the phy version is located on different
7368 * structures. In case this structure is too old, do not set
7369 * the address
7370 */
7371 config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
7372 dev_info.shared_hw_config.config2));
7373 if (phy_index == EXT_PHY1) {
7374 phy->ver_addr = shmem_base + offsetof(struct shmem_region,
7375 port_mb[port].ext_phy_fw_version);
7376
7377 /* Check specific mdc mdio settings */
7378 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
7379 mdc_mdio_access = config2 &
7380 SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
7381 } else {
7382 u32 size = REG_RD(bp, shmem2_base);
5887 7383
5888 if (vars->phy_flags & PHY_XGXS_FLAG) 7384 if (size >
5889 bnx2x_set_master_ln(params); 7385 offsetof(struct shmem2_region, ext_phy_fw_version2)) {
7386 phy->ver_addr = shmem2_base +
7387 offsetof(struct shmem2_region,
7388 ext_phy_fw_version2[port]);
7389 }
7390 /* Check specific mdc mdio settings */
7391 if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
7392 mdc_mdio_access = (config2 &
7393 SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
7394 (SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
7395 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
7396 }
7397 phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
5890 7398
5891 rc = bnx2x_reset_unicore(params); 7399 /*
5892 /* reset the SerDes and wait for reset bit return low */ 7400 * In case mdc/mdio_access of the external phy is different than the
5893 if (rc != 0) 7401 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
5894 return rc; 7402 * to prevent one port interfere with another port's CL45 operations.
7403 */
7404 if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
7405 phy->flags |= FLAGS_HW_LOCK_REQUIRED;
7406 DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
7407 phy_type, port, phy_index);
7408 DP(NETIF_MSG_LINK, " addr=0x%x, mdio_ctl=0x%x\n",
7409 phy->addr, phy->mdio_ctrl);
7410 return 0;
7411}
5895 7412
5896 bnx2x_set_aer_mmd(params, vars); 7413static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
7414 u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
7415{
7416 u8 status = 0;
7417 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
7418 if (phy_index == INT_PHY)
7419 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
7420 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
7421 port, phy);
7422 return status;
7423}
5897 7424
5898 /* setting the masterLn_def again after the reset */ 7425static void bnx2x_phy_def_cfg(struct link_params *params,
5899 if (vars->phy_flags & PHY_XGXS_FLAG) { 7426 struct bnx2x_phy *phy,
5900 bnx2x_set_master_ln(params); 7427 u8 phy_index)
5901 bnx2x_set_swap_lanes(params); 7428{
7429 struct bnx2x *bp = params->bp;
7430 u32 link_config;
7431 /* Populate the default phy configuration for MF mode */
7432 if (phy_index == EXT_PHY2) {
7433 link_config = REG_RD(bp, params->shmem_base +
7434 offsetof(struct shmem_region, dev_info.
7435 port_feature_config[params->port].link_config2));
7436 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7437 offsetof(struct shmem_region,
7438 dev_info.
7439 port_hw_config[params->port].speed_capability_mask2));
7440 } else {
7441 link_config = REG_RD(bp, params->shmem_base +
7442 offsetof(struct shmem_region, dev_info.
7443 port_feature_config[params->port].link_config));
7444 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
7445 offsetof(struct shmem_region,
7446 dev_info.
7447 port_hw_config[params->port].speed_capability_mask));
7448 }
7449 DP(NETIF_MSG_LINK, "Default config phy idx %x cfg 0x%x speed_cap_mask"
7450 " 0x%x\n", phy_index, link_config, phy->speed_cap_mask);
7451
7452 phy->req_duplex = DUPLEX_FULL;
7453 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
7454 case PORT_FEATURE_LINK_SPEED_10M_HALF:
7455 phy->req_duplex = DUPLEX_HALF;
7456 case PORT_FEATURE_LINK_SPEED_10M_FULL:
7457 phy->req_line_speed = SPEED_10;
7458 break;
7459 case PORT_FEATURE_LINK_SPEED_100M_HALF:
7460 phy->req_duplex = DUPLEX_HALF;
7461 case PORT_FEATURE_LINK_SPEED_100M_FULL:
7462 phy->req_line_speed = SPEED_100;
7463 break;
7464 case PORT_FEATURE_LINK_SPEED_1G:
7465 phy->req_line_speed = SPEED_1000;
7466 break;
7467 case PORT_FEATURE_LINK_SPEED_2_5G:
7468 phy->req_line_speed = SPEED_2500;
7469 break;
7470 case PORT_FEATURE_LINK_SPEED_10G_CX4:
7471 phy->req_line_speed = SPEED_10000;
7472 break;
7473 default:
7474 phy->req_line_speed = SPEED_AUTO_NEG;
7475 break;
5902 } 7476 }
5903 7477
5904 if (vars->phy_flags & PHY_XGXS_FLAG) { 7478 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
5905 if ((params->req_line_speed && 7479 case PORT_FEATURE_FLOW_CONTROL_AUTO:
5906 ((params->req_line_speed == SPEED_100) || 7480 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
5907 (params->req_line_speed == SPEED_10))) || 7481 break;
5908 (!params->req_line_speed && 7482 case PORT_FEATURE_FLOW_CONTROL_TX:
5909 (params->speed_cap_mask >= 7483 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
5910 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) && 7484 break;
5911 (params->speed_cap_mask < 7485 case PORT_FEATURE_FLOW_CONTROL_RX:
5912 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) 7486 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
5913 )) { 7487 break;
5914 vars->phy_flags |= PHY_SGMII_FLAG; 7488 case PORT_FEATURE_FLOW_CONTROL_BOTH:
5915 } else { 7489 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
5916 vars->phy_flags &= ~PHY_SGMII_FLAG; 7490 break;
5917 } 7491 default:
7492 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7493 break;
5918 } 7494 }
5919 /* In case of external phy existance, the line speed would be the 7495}
5920 line speed linked up by the external phy. In case it is direct only,
5921 then the line_speed during initialization will be equal to the
5922 req_line_speed*/
5923 vars->line_speed = params->req_line_speed;
5924 7496
5925 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc); 7497u32 bnx2x_phy_selection(struct link_params *params)
7498{
7499 u32 phy_config_swapped, prio_cfg;
7500 u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
7501
7502 phy_config_swapped = params->multi_phy_config &
7503 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7504
7505 prio_cfg = params->multi_phy_config &
7506 PORT_HW_CFG_PHY_SELECTION_MASK;
7507
7508 if (phy_config_swapped) {
7509 switch (prio_cfg) {
7510 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
7511 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
7512 break;
7513 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
7514 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
7515 break;
7516 case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
7517 return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
7518 break;
7519 case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
7520 return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
7521 break;
7522 }
7523 } else
7524 return_cfg = prio_cfg;
5926 7525
5927 /* init ext phy and enable link state int */ 7526 return return_cfg;
5928 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) || 7527}
5929 (params->loopback_mode == LOOPBACK_XGXS_10));
5930 7528
5931 if (non_ext_phy || 7529
5932 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) || 7530u8 bnx2x_phy_probe(struct link_params *params)
5933 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) || 7531{
5934 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) || 7532 u8 phy_index, actual_phy_idx, link_cfg_idx;
5935 (params->loopback_mode == LOOPBACK_EXT_PHY)) { 7533 u32 phy_config_swapped;
5936 if (params->req_line_speed == SPEED_AUTO_NEG) 7534 struct bnx2x *bp = params->bp;
5937 bnx2x_set_parallel_detection(params, vars->phy_flags); 7535 struct bnx2x_phy *phy;
5938 bnx2x_init_internal_phy(params, vars, non_ext_phy); 7536 params->num_phys = 0;
7537 DP(NETIF_MSG_LINK, "Begin phy probe\n");
7538 phy_config_swapped = params->multi_phy_config &
7539 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7540
7541 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
7542 phy_index++) {
7543 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7544 actual_phy_idx = phy_index;
7545 if (phy_config_swapped) {
7546 if (phy_index == EXT_PHY1)
7547 actual_phy_idx = EXT_PHY2;
7548 else if (phy_index == EXT_PHY2)
7549 actual_phy_idx = EXT_PHY1;
7550 }
7551 DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
7552 " actual_phy_idx %x\n", phy_config_swapped,
7553 phy_index, actual_phy_idx);
7554 phy = &params->phy[actual_phy_idx];
7555 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
7556 params->shmem2_base, params->port,
7557 phy) != 0) {
7558 params->num_phys = 0;
7559 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
7560 phy_index);
7561 for (phy_index = INT_PHY;
7562 phy_index < MAX_PHYS;
7563 phy_index++)
7564 *phy = phy_null;
7565 return -EINVAL;
7566 }
7567 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
7568 break;
7569
7570 bnx2x_phy_def_cfg(params, phy, phy_index);
7571 params->num_phys++;
5939 } 7572 }
5940 7573
5941 if (!non_ext_phy) 7574 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
5942 rc |= bnx2x_ext_phy_init(params, vars); 7575 return 0;
7576}
5943 7577
5944 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4, 7578static void set_phy_vars(struct link_params *params)
5945 (NIG_STATUS_XGXS0_LINK10G | 7579{
5946 NIG_STATUS_XGXS0_LINK_STATUS | 7580 struct bnx2x *bp = params->bp;
5947 NIG_STATUS_SERDES0_LINK_STATUS)); 7581 u8 actual_phy_idx, phy_index, link_cfg_idx;
7582 u8 phy_config_swapped = params->multi_phy_config &
7583 PORT_HW_CFG_PHY_SWAPPED_ENABLED;
7584 for (phy_index = INT_PHY; phy_index < params->num_phys;
7585 phy_index++) {
7586 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
7587 actual_phy_idx = phy_index;
7588 if (phy_config_swapped) {
7589 if (phy_index == EXT_PHY1)
7590 actual_phy_idx = EXT_PHY2;
7591 else if (phy_index == EXT_PHY2)
7592 actual_phy_idx = EXT_PHY1;
7593 }
7594 params->phy[actual_phy_idx].req_flow_ctrl =
7595 params->req_flow_ctrl[link_cfg_idx];
5948 7596
5949 return rc; 7597 params->phy[actual_phy_idx].req_line_speed =
7598 params->req_line_speed[link_cfg_idx];
5950 7599
5951} 7600 params->phy[actual_phy_idx].speed_cap_mask =
7601 params->speed_cap_mask[link_cfg_idx];
5952 7602
7603 params->phy[actual_phy_idx].req_duplex =
7604 params->req_duplex[link_cfg_idx];
7605
7606 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
7607 " speed_cap_mask %x\n",
7608 params->phy[actual_phy_idx].req_flow_ctrl,
7609 params->phy[actual_phy_idx].req_line_speed,
7610 params->phy[actual_phy_idx].speed_cap_mask);
7611 }
7612}
5953 7613
5954u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars) 7614u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5955{ 7615{
5956 struct bnx2x *bp = params->bp; 7616 struct bnx2x *bp = params->bp;
5957 u32 val;
5958
5959 DP(NETIF_MSG_LINK, "Phy Initialization started\n"); 7617 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
5960 DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n", 7618 DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
5961 params->req_line_speed, params->req_flow_ctrl); 7619 params->req_line_speed[0], params->req_flow_ctrl[0]);
7620 DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
7621 params->req_line_speed[1], params->req_flow_ctrl[1]);
5962 vars->link_status = 0; 7622 vars->link_status = 0;
5963 vars->phy_link_up = 0; 7623 vars->phy_link_up = 0;
5964 vars->link_up = 0; 7624 vars->link_up = 0;
@@ -5966,11 +7626,7 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5966 vars->duplex = DUPLEX_FULL; 7626 vars->duplex = DUPLEX_FULL;
5967 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 7627 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5968 vars->mac_type = MAC_TYPE_NONE; 7628 vars->mac_type = MAC_TYPE_NONE;
5969 7629 vars->phy_flags = 0;
5970 if (params->switch_cfg == SWITCH_CFG_1G)
5971 vars->phy_flags = PHY_SERDES_FLAG;
5972 else
5973 vars->phy_flags = PHY_XGXS_FLAG;
5974 7630
5975 /* disable attentions */ 7631 /* disable attentions */
5976 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4, 7632 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
@@ -5981,55 +7637,13 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
5981 7637
5982 bnx2x_emac_init(params, vars); 7638 bnx2x_emac_init(params, vars);
5983 7639
5984 if (CHIP_REV_IS_FPGA(bp)) { 7640 if (params->num_phys == 0) {
5985 7641 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
5986 vars->link_up = 1; 7642 return -EINVAL;
5987 vars->line_speed = SPEED_10000; 7643 }
5988 vars->duplex = DUPLEX_FULL; 7644 set_phy_vars(params);
5989 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5990 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5991 /* enable on E1.5 FPGA */
5992 if (CHIP_IS_E1H(bp)) {
5993 vars->flow_ctrl |=
5994 (BNX2X_FLOW_CTRL_TX |
5995 BNX2X_FLOW_CTRL_RX);
5996 vars->link_status |=
5997 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
5998 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
5999 }
6000
6001 bnx2x_emac_enable(params, vars, 0);
6002 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6003 /* disable drain */
6004 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6005
6006 /* update shared memory */
6007 bnx2x_update_mng(params, vars->link_status);
6008
6009 return 0;
6010
6011 } else
6012 if (CHIP_REV_IS_EMUL(bp)) {
6013
6014 vars->link_up = 1;
6015 vars->line_speed = SPEED_10000;
6016 vars->duplex = DUPLEX_FULL;
6017 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6018 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
6019
6020 bnx2x_bmac_enable(params, vars, 0);
6021
6022 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
6023 /* Disable drain */
6024 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
6025 + params->port*4, 0);
6026
6027 /* update shared memory */
6028 bnx2x_update_mng(params, vars->link_status);
6029
6030 return 0;
6031 7645
6032 } else 7646 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
6033 if (params->loopback_mode == LOOPBACK_BMAC) { 7647 if (params->loopback_mode == LOOPBACK_BMAC) {
6034 7648
6035 vars->link_up = 1; 7649 vars->link_up = 1;
@@ -6040,12 +7654,12 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6040 7654
6041 vars->phy_flags = PHY_XGXS_FLAG; 7655 vars->phy_flags = PHY_XGXS_FLAG;
6042 7656
6043 bnx2x_phy_deassert(params, vars->phy_flags); 7657 bnx2x_xgxs_deassert(params);
7658
6044 /* set bmac loopback */ 7659 /* set bmac loopback */
6045 bnx2x_bmac_enable(params, vars, 1); 7660 bnx2x_bmac_enable(params, vars, 1);
6046 7661
6047 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + 7662 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6048 params->port*4, 0);
6049 7663
6050 } else if (params->loopback_mode == LOOPBACK_EMAC) { 7664 } else if (params->loopback_mode == LOOPBACK_EMAC) {
6051 7665
@@ -6057,80 +7671,62 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6057 7671
6058 vars->phy_flags = PHY_XGXS_FLAG; 7672 vars->phy_flags = PHY_XGXS_FLAG;
6059 7673
6060 bnx2x_phy_deassert(params, vars->phy_flags); 7674 bnx2x_xgxs_deassert(params);
6061 /* set bmac loopback */ 7675 /* set bmac loopback */
6062 bnx2x_emac_enable(params, vars, 1); 7676 bnx2x_emac_enable(params, vars, 1);
6063 bnx2x_emac_program(params, vars->line_speed, 7677 bnx2x_emac_program(params, vars);
6064 vars->duplex); 7678 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6065 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
6066 params->port*4, 0);
6067 7679
6068 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) || 7680 } else if ((params->loopback_mode == LOOPBACK_XGXS) ||
6069 (params->loopback_mode == LOOPBACK_EXT_PHY)) { 7681 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6070 7682
6071 vars->link_up = 1; 7683 vars->link_up = 1;
6072 vars->line_speed = SPEED_10000;
6073 vars->duplex = DUPLEX_FULL;
6074 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE; 7684 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
7685 vars->duplex = DUPLEX_FULL;
7686 if (params->req_line_speed[0] == SPEED_1000) {
7687 vars->line_speed = SPEED_1000;
7688 vars->mac_type = MAC_TYPE_EMAC;
7689 } else {
7690 vars->line_speed = SPEED_10000;
7691 vars->mac_type = MAC_TYPE_BMAC;
7692 }
6075 7693
6076 vars->phy_flags = PHY_XGXS_FLAG; 7694 bnx2x_xgxs_deassert(params);
6077
6078 val = REG_RD(bp,
6079 NIG_REG_XGXS0_CTRL_PHY_ADDR+
6080 params->port*0x18);
6081 params->phy_addr = (u8)val;
6082
6083 bnx2x_phy_deassert(params, vars->phy_flags);
6084 bnx2x_link_initialize(params, vars); 7695 bnx2x_link_initialize(params, vars);
6085 7696
6086 vars->mac_type = MAC_TYPE_BMAC; 7697 if (params->req_line_speed[0] == SPEED_1000) {
6087 7698 bnx2x_emac_program(params, vars);
6088 bnx2x_bmac_enable(params, vars, 0); 7699 bnx2x_emac_enable(params, vars, 0);
6089 7700 } else
6090 if (params->loopback_mode == LOOPBACK_XGXS_10) { 7701 bnx2x_bmac_enable(params, vars, 0);
7702 if (params->loopback_mode == LOOPBACK_XGXS) {
6091 /* set 10G XGXS loopback */ 7703 /* set 10G XGXS loopback */
6092 bnx2x_set_xgxs_loopback(params, vars, 1); 7704 params->phy[INT_PHY].config_loopback(
7705 &params->phy[INT_PHY],
7706 params);
7707
6093 } else { 7708 } else {
6094 /* set external phy loopback */ 7709 /* set external phy loopback */
6095 bnx2x_ext_phy_loopback(params); 7710 u8 phy_index;
7711 for (phy_index = EXT_PHY1;
7712 phy_index < params->num_phys; phy_index++) {
7713 if (params->phy[phy_index].config_loopback)
7714 params->phy[phy_index].config_loopback(
7715 &params->phy[phy_index],
7716 params);
7717 }
6096 } 7718 }
6097 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + 7719 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
6098 params->port*4, 0);
6099 7720
6100 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed); 7721 bnx2x_set_led(params, vars,
7722 LED_MODE_OPER, vars->line_speed);
6101 } else 7723 } else
6102 /* No loopback */ 7724 /* No loopback */
6103 { 7725 {
6104 bnx2x_phy_deassert(params, vars->phy_flags); 7726 if (params->switch_cfg == SWITCH_CFG_10G)
6105 switch (params->switch_cfg) { 7727 bnx2x_xgxs_deassert(params);
6106 case SWITCH_CFG_1G: 7728 else
6107 vars->phy_flags |= PHY_SERDES_FLAG; 7729 bnx2x_serdes_deassert(bp, params->port);
6108 if ((params->ext_phy_config &
6109 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
6110 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
6111 vars->phy_flags |= PHY_SGMII_FLAG;
6112 }
6113
6114 val = REG_RD(bp,
6115 NIG_REG_SERDES0_CTRL_PHY_ADDR+
6116 params->port*0x10);
6117
6118 params->phy_addr = (u8)val;
6119
6120 break;
6121 case SWITCH_CFG_10G:
6122 vars->phy_flags |= PHY_XGXS_FLAG;
6123 val = REG_RD(bp,
6124 NIG_REG_XGXS0_CTRL_PHY_ADDR+
6125 params->port*0x18);
6126 params->phy_addr = (u8)val;
6127
6128 break;
6129 default:
6130 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
6131 return -EINVAL;
6132 }
6133 DP(NETIF_MSG_LINK, "Phy address = 0x%x\n", params->phy_addr);
6134 7730
6135 bnx2x_link_initialize(params, vars); 7731 bnx2x_link_initialize(params, vars);
6136 msleep(30); 7732 msleep(30);
@@ -6138,38 +7734,20 @@ u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
6138 } 7734 }
6139 return 0; 7735 return 0;
6140} 7736}
6141
6142static void bnx2x_8726_reset_phy(struct bnx2x *bp, u8 port, u8 ext_phy_addr)
6143{
6144 DP(NETIF_MSG_LINK, "bnx2x_8726_reset_phy port %d\n", port);
6145
6146 /* Set serial boot control for external load */
6147 bnx2x_cl45_write(bp, port,
6148 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726, ext_phy_addr,
6149 MDIO_PMA_DEVAD,
6150 MDIO_PMA_REG_GEN_CTRL, 0x0001);
6151}
6152
6153u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars, 7737u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6154 u8 reset_ext_phy) 7738 u8 reset_ext_phy)
6155{ 7739{
6156 struct bnx2x *bp = params->bp; 7740 struct bnx2x *bp = params->bp;
6157 u32 ext_phy_config = params->ext_phy_config; 7741 u8 phy_index, port = params->port, clear_latch_ind = 0;
6158 u8 port = params->port;
6159 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6160 u32 val = REG_RD(bp, params->shmem_base +
6161 offsetof(struct shmem_region, dev_info.
6162 port_feature_config[params->port].
6163 config));
6164 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port); 7742 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
6165 /* disable attentions */ 7743 /* disable attentions */
6166 vars->link_status = 0; 7744 vars->link_status = 0;
6167 bnx2x_update_mng(params, vars->link_status); 7745 bnx2x_update_mng(params, vars->link_status);
6168 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 7746 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6169 (NIG_MASK_XGXS0_LINK_STATUS | 7747 (NIG_MASK_XGXS0_LINK_STATUS |
6170 NIG_MASK_XGXS0_LINK10G | 7748 NIG_MASK_XGXS0_LINK10G |
6171 NIG_MASK_SERDES0_LINK_STATUS | 7749 NIG_MASK_SERDES0_LINK_STATUS |
6172 NIG_MASK_MI_INT)); 7750 NIG_MASK_MI_INT));
6173 7751
6174 /* activate nig drain */ 7752 /* activate nig drain */
6175 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1); 7753 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
@@ -6185,77 +7763,34 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6185 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0); 7763 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6186 7764
6187 msleep(10); 7765 msleep(10);
6188 /* The PHY reset is controled by GPIO 1 7766 /* The PHY reset is controlled by GPIO 1
6189 * Hold it as vars low 7767 * Hold it as vars low
6190 */ 7768 */
6191 /* clear link led */ 7769 /* clear link led */
6192 bnx2x_set_led(params, LED_MODE_OFF, 0); 7770 bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6193 if (reset_ext_phy) {
6194 switch (ext_phy_type) {
6195 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
6196 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
6197 break;
6198 7771
6199 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 7772 if (reset_ext_phy) {
6200 { 7773 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6201 7774 phy_index++) {
6202 /* Disable Transmitter */ 7775 if (params->phy[phy_index].link_reset)
6203 u8 ext_phy_addr = 7776 params->phy[phy_index].link_reset(
6204 XGXS_EXT_PHY_ADDR(params->ext_phy_config); 7777 &params->phy[phy_index],
6205 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == 7778 params);
6206 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) 7779 if (params->phy[phy_index].flags &
6207 bnx2x_sfp_set_transmitter(bp, port, 7780 FLAGS_REARM_LATCH_SIGNAL)
6208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 7781 clear_latch_ind = 1;
6209 ext_phy_addr, 0);
6210 break;
6211 }
6212 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6213 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
6214 "low power mode\n",
6215 port);
6216 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6217 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6218 port);
6219 break;
6220 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6221 {
6222 u8 ext_phy_addr =
6223 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6224 /* Set soft reset */
6225 bnx2x_8726_reset_phy(bp, params->port, ext_phy_addr);
6226 break;
6227 }
6228 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6229 {
6230 u8 ext_phy_addr =
6231 XGXS_EXT_PHY_ADDR(params->ext_phy_config);
6232 bnx2x_cl45_write(bp, port,
6233 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6234 ext_phy_addr,
6235 MDIO_AN_DEVAD,
6236 MDIO_AN_REG_CTRL, 0x0000);
6237 bnx2x_cl45_write(bp, port,
6238 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
6239 ext_phy_addr,
6240 MDIO_PMA_DEVAD,
6241 MDIO_PMA_REG_CTRL, 1);
6242 break;
6243 }
6244 default:
6245 /* HW reset */
6246 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6247 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6248 port);
6249 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6250 MISC_REGISTERS_GPIO_OUTPUT_LOW,
6251 port);
6252 DP(NETIF_MSG_LINK, "reset external PHY\n");
6253 } 7782 }
6254 } 7783 }
6255 /* reset the SerDes/XGXS */
6256 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6257 (0x1ff << (port*16)));
6258 7784
7785 if (clear_latch_ind) {
7786 /* Clear latching indication */
7787 bnx2x_rearm_latch_signal(bp, port, 0);
7788 bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
7789 1 << NIG_LATCH_BC_ENABLE_MI_INT);
7790 }
7791 if (params->phy[INT_PHY].link_reset)
7792 params->phy[INT_PHY].link_reset(
7793 &params->phy[INT_PHY], params);
6259 /* reset BigMac */ 7794 /* reset BigMac */
6260 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR, 7795 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
6261 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port)); 7796 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
@@ -6269,467 +7804,454 @@ u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
6269 return 0; 7804 return 0;
6270} 7805}
6271 7806
6272static u8 bnx2x_update_link_down(struct link_params *params, 7807/****************************************************************************/
6273 struct link_vars *vars) 7808/* Common function */
6274{ 7809/****************************************************************************/
6275 struct bnx2x *bp = params->bp; 7810static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp,
6276 u8 port = params->port; 7811 u32 shmem_base_path[],
6277 7812 u32 shmem2_base_path[], u8 phy_index,
6278 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port); 7813 u32 chip_id)
6279 bnx2x_set_led(params, LED_MODE_OFF, 0);
6280
6281 /* indicate no mac active */
6282 vars->mac_type = MAC_TYPE_NONE;
6283
6284 /* update shared memory */
6285 vars->link_status = 0;
6286 vars->line_speed = 0;
6287 bnx2x_update_mng(params, vars->link_status);
6288
6289 /* activate nig drain */
6290 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6291
6292 /* disable emac */
6293 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6294
6295 msleep(10);
6296
6297 /* reset BigMac */
6298 bnx2x_bmac_rx_disable(bp, params->port);
6299 REG_WR(bp, GRCBASE_MISC +
6300 MISC_REGISTERS_RESET_REG_2_CLEAR,
6301 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6302 return 0;
6303}
6304
6305static u8 bnx2x_update_link_up(struct link_params *params,
6306 struct link_vars *vars,
6307 u8 link_10g, u32 gp_status)
6308{
6309 struct bnx2x *bp = params->bp;
6310 u8 port = params->port;
6311 u8 rc = 0;
6312
6313 vars->link_status |= LINK_STATUS_LINK_UP;
6314 if (link_10g) {
6315 bnx2x_bmac_enable(params, vars, 0);
6316 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
6317 } else {
6318 rc = bnx2x_emac_program(params, vars->line_speed,
6319 vars->duplex);
6320
6321 bnx2x_emac_enable(params, vars, 0);
6322
6323 /* AN complete? */
6324 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
6325 if (!(vars->phy_flags &
6326 PHY_SGMII_FLAG))
6327 bnx2x_set_gmii_tx_driver(params);
6328 }
6329 }
6330
6331 /* PBF - link up */
6332 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6333 vars->line_speed);
6334
6335 /* disable drain */
6336 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6337
6338 /* update shared memory */
6339 bnx2x_update_mng(params, vars->link_status);
6340 msleep(20);
6341 return rc;
6342}
6343/* This function should called upon link interrupt */
6344/* In case vars->link_up, driver needs to
6345 1. Update the pbf
6346 2. Disable drain
6347 3. Update the shared memory
6348 4. Indicate link up
6349 5. Set LEDs
6350 Otherwise,
6351 1. Update shared memory
6352 2. Reset BigMac
6353 3. Report link down
6354 4. Unset LEDs
6355*/
6356u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6357{
6358 struct bnx2x *bp = params->bp;
6359 u8 port = params->port;
6360 u16 gp_status;
6361 u8 link_10g;
6362 u8 ext_phy_link_up, rc = 0;
6363 u32 ext_phy_type;
6364 u8 is_mi_int = 0;
6365
6366 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6367 port, (vars->phy_flags & PHY_XGXS_FLAG),
6368 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6369
6370 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6371 port*0x18) > 0);
6372 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6373 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6374 is_mi_int,
6375 REG_RD(bp,
6376 NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6377
6378 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6379 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6380 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6381
6382 /* disable emac */
6383 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6384
6385 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
6386
6387 /* Check external link change only for non-direct */
6388 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars, is_mi_int);
6389
6390 /* Read gp_status */
6391 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
6392 MDIO_REG_BANK_GP_STATUS,
6393 MDIO_GP_STATUS_TOP_AN_STATUS1,
6394 &gp_status);
6395
6396 rc = bnx2x_link_settings_status(params, vars, gp_status,
6397 ext_phy_link_up);
6398 if (rc != 0)
6399 return rc;
6400
6401 /* anything 10 and over uses the bmac */
6402 link_10g = ((vars->line_speed == SPEED_10000) ||
6403 (vars->line_speed == SPEED_12000) ||
6404 (vars->line_speed == SPEED_12500) ||
6405 (vars->line_speed == SPEED_13000) ||
6406 (vars->line_speed == SPEED_15000) ||
6407 (vars->line_speed == SPEED_16000));
6408
6409 bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
6410
6411 /* In case external phy link is up, and internal link is down
6412 ( not initialized yet probably after link initialization, it needs
6413 to be initialized.
6414 Note that after link down-up as result of cable plug,
6415 the xgxs link would probably become up again without the need to
6416 initialize it*/
6417
6418 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
6419 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
6420 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) &&
6421 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) &&
6422 (ext_phy_link_up && !vars->phy_link_up))
6423 bnx2x_init_internal_phy(params, vars, 0);
6424
6425 /* link is up only if both local phy and external phy are up */
6426 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
6427
6428 if (vars->link_up)
6429 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
6430 else
6431 rc = bnx2x_update_link_down(params, vars);
6432
6433 return rc;
6434}
6435
6436static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6437{ 7814{
6438 u8 ext_phy_addr[PORT_MAX]; 7815 struct bnx2x_phy phy[PORT_MAX];
7816 struct bnx2x_phy *phy_blk[PORT_MAX];
6439 u16 val; 7817 u16 val;
6440 s8 port; 7818 s8 port = 0;
6441 7819 s8 port_of_path = 0;
7820 u32 swap_val, swap_override;
7821 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7822 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7823 port ^= (swap_val && swap_override);
7824 bnx2x_ext_phy_hw_reset(bp, port);
6442 /* PART1 - Reset both phys */ 7825 /* PART1 - Reset both phys */
6443 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7826 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6444 /* Extract the ext phy address for the port */ 7827 u32 shmem_base, shmem2_base;
6445 u32 ext_phy_config = REG_RD(bp, shmem_base + 7828 /* In E2, same phy is using for port0 of the two paths */
6446 offsetof(struct shmem_region, 7829 if (CHIP_IS_E2(bp)) {
6447 dev_info.port_hw_config[port].external_phy_config)); 7830 shmem_base = shmem_base_path[port];
7831 shmem2_base = shmem2_base_path[port];
7832 port_of_path = 0;
7833 } else {
7834 shmem_base = shmem_base_path[0];
7835 shmem2_base = shmem2_base_path[0];
7836 port_of_path = port;
7837 }
6448 7838
7839 /* Extract the ext phy address for the port */
7840 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
7841 port_of_path, &phy[port]) !=
7842 0) {
7843 DP(NETIF_MSG_LINK, "populate_phy failed\n");
7844 return -EINVAL;
7845 }
6449 /* disable attentions */ 7846 /* disable attentions */
6450 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 7847 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
6451 (NIG_MASK_XGXS0_LINK_STATUS | 7848 port_of_path*4,
6452 NIG_MASK_XGXS0_LINK10G | 7849 (NIG_MASK_XGXS0_LINK_STATUS |
6453 NIG_MASK_SERDES0_LINK_STATUS | 7850 NIG_MASK_XGXS0_LINK10G |
6454 NIG_MASK_MI_INT)); 7851 NIG_MASK_SERDES0_LINK_STATUS |
6455 7852 NIG_MASK_MI_INT));
6456 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6457 7853
6458 /* Need to take the phy out of low power mode in order 7854 /* Need to take the phy out of low power mode in order
6459 to write to access its registers */ 7855 to write to access its registers */
6460 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 7856 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6461 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port); 7857 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
7858 port);
6462 7859
6463 /* Reset the phy */ 7860 /* Reset the phy */
6464 bnx2x_cl45_write(bp, port, 7861 bnx2x_cl45_write(bp, &phy[port],
6465 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7862 MDIO_PMA_DEVAD,
6466 ext_phy_addr[port], 7863 MDIO_PMA_REG_CTRL,
6467 MDIO_PMA_DEVAD, 7864 1<<15);
6468 MDIO_PMA_REG_CTRL,
6469 1<<15);
6470 } 7865 }
6471 7866
6472 /* Add delay of 150ms after reset */ 7867 /* Add delay of 150ms after reset */
6473 msleep(150); 7868 msleep(150);
6474 7869
7870 if (phy[PORT_0].addr & 0x1) {
7871 phy_blk[PORT_0] = &(phy[PORT_1]);
7872 phy_blk[PORT_1] = &(phy[PORT_0]);
7873 } else {
7874 phy_blk[PORT_0] = &(phy[PORT_0]);
7875 phy_blk[PORT_1] = &(phy[PORT_1]);
7876 }
7877
6475 /* PART2 - Download firmware to both phys */ 7878 /* PART2 - Download firmware to both phys */
6476 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7879 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6477 u16 fw_ver1; 7880 if (CHIP_IS_E2(bp))
6478 7881 port_of_path = 0;
6479 bnx2x_bcm8073_external_rom_boot(bp, port, 7882 else
6480 ext_phy_addr[port], shmem_base); 7883 port_of_path = port;
6481 7884
6482 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7885 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
6483 ext_phy_addr[port], 7886 phy_blk[port]->addr);
6484 MDIO_PMA_DEVAD, 7887 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
6485 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 7888 port_of_path))
6486 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6487 DP(NETIF_MSG_LINK,
6488 "bnx2x_8073_common_init_phy port %x:"
6489 "Download failed. fw version = 0x%x\n",
6490 port, fw_ver1);
6491 return -EINVAL; 7889 return -EINVAL;
6492 }
6493 7890
6494 /* Only set bit 10 = 1 (Tx power down) */ 7891 /* Only set bit 10 = 1 (Tx power down) */
6495 bnx2x_cl45_read(bp, port, 7892 bnx2x_cl45_read(bp, phy_blk[port],
6496 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7893 MDIO_PMA_DEVAD,
6497 ext_phy_addr[port], 7894 MDIO_PMA_REG_TX_POWER_DOWN, &val);
6498 MDIO_PMA_DEVAD,
6499 MDIO_PMA_REG_TX_POWER_DOWN, &val);
6500 7895
6501 /* Phase1 of TX_POWER_DOWN reset */ 7896 /* Phase1 of TX_POWER_DOWN reset */
6502 bnx2x_cl45_write(bp, port, 7897 bnx2x_cl45_write(bp, phy_blk[port],
6503 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7898 MDIO_PMA_DEVAD,
6504 ext_phy_addr[port], 7899 MDIO_PMA_REG_TX_POWER_DOWN,
6505 MDIO_PMA_DEVAD, 7900 (val | 1<<10));
6506 MDIO_PMA_REG_TX_POWER_DOWN,
6507 (val | 1<<10));
6508 } 7901 }
6509 7902
6510 /* Toggle Transmitter: Power down and then up with 600ms 7903 /*
6511 delay between */ 7904 * Toggle Transmitter: Power down and then up with 600ms delay
7905 * between
7906 */
6512 msleep(600); 7907 msleep(600);
6513 7908
6514 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */ 7909 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6515 for (port = PORT_MAX - 1; port >= PORT_0; port--) { 7910 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6516 /* Phase2 of POWER_DOWN_RESET */ 7911 /* Phase2 of POWER_DOWN_RESET */
6517 /* Release bit 10 (Release Tx power down) */ 7912 /* Release bit 10 (Release Tx power down) */
6518 bnx2x_cl45_read(bp, port, 7913 bnx2x_cl45_read(bp, phy_blk[port],
6519 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7914 MDIO_PMA_DEVAD,
6520 ext_phy_addr[port], 7915 MDIO_PMA_REG_TX_POWER_DOWN, &val);
6521 MDIO_PMA_DEVAD, 7916
6522 MDIO_PMA_REG_TX_POWER_DOWN, &val); 7917 bnx2x_cl45_write(bp, phy_blk[port],
6523 7918 MDIO_PMA_DEVAD,
6524 bnx2x_cl45_write(bp, port, 7919 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6525 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6526 ext_phy_addr[port],
6527 MDIO_PMA_DEVAD,
6528 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6529 msleep(15); 7920 msleep(15);
6530 7921
6531 /* Read modify write the SPI-ROM version select register */ 7922 /* Read modify write the SPI-ROM version select register */
6532 bnx2x_cl45_read(bp, port, 7923 bnx2x_cl45_read(bp, phy_blk[port],
6533 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073, 7924 MDIO_PMA_DEVAD,
6534 ext_phy_addr[port], 7925 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
6535 MDIO_PMA_DEVAD, 7926 bnx2x_cl45_write(bp, phy_blk[port],
6536 MDIO_PMA_REG_EDC_FFE_MAIN, &val); 7927 MDIO_PMA_DEVAD,
6537 bnx2x_cl45_write(bp, port, 7928 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6538 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
6539 ext_phy_addr[port],
6540 MDIO_PMA_DEVAD,
6541 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6542 7929
6543 /* set GPIO2 back to LOW */ 7930 /* set GPIO2 back to LOW */
6544 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, 7931 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6545 MISC_REGISTERS_GPIO_OUTPUT_LOW, port); 7932 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6546 } 7933 }
6547 return 0; 7934 return 0;
6548
6549} 7935}
6550 7936static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
6551static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base) 7937 u32 shmem_base_path[],
7938 u32 shmem2_base_path[], u8 phy_index,
7939 u32 chip_id)
6552{ 7940{
6553 u8 ext_phy_addr[PORT_MAX]; 7941 u32 val;
6554 s8 port, first_port, i; 7942 s8 port;
6555 u32 swap_val, swap_override; 7943 struct bnx2x_phy phy;
6556 DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n"); 7944 /* Use port1 because of the static port-swap */
6557 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); 7945 /* Enable the module detection interrupt */
6558 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); 7946 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
7947 val |= ((1<<MISC_REGISTERS_GPIO_3)|
7948 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
7949 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6559 7950
6560 bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override)); 7951 bnx2x_ext_phy_hw_reset(bp, 0);
6561 msleep(5); 7952 msleep(5);
7953 for (port = 0; port < PORT_MAX; port++) {
7954 u32 shmem_base, shmem2_base;
6562 7955
6563 if (swap_val && swap_override) 7956 /* In E2, same phy is using for port0 of the two paths */
6564 first_port = PORT_0; 7957 if (CHIP_IS_E2(bp)) {
6565 else 7958 shmem_base = shmem_base_path[port];
6566 first_port = PORT_1; 7959 shmem2_base = shmem2_base_path[port];
6567 7960 } else {
6568 /* PART1 - Reset both phys */ 7961 shmem_base = shmem_base_path[0];
6569 for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { 7962 shmem2_base = shmem2_base_path[0];
7963 }
6570 /* Extract the ext phy address for the port */ 7964 /* Extract the ext phy address for the port */
6571 u32 ext_phy_config = REG_RD(bp, shmem_base + 7965 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
6572 offsetof(struct shmem_region, 7966 port, &phy) !=
6573 dev_info.port_hw_config[port].external_phy_config)); 7967 0) {
7968 DP(NETIF_MSG_LINK, "populate phy failed\n");
7969 return -EINVAL;
7970 }
6574 7971
6575 /* disable attentions */ 7972 /* Reset phy*/
6576 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4, 7973 bnx2x_cl45_write(bp, &phy,
6577 (NIG_MASK_XGXS0_LINK_STATUS | 7974 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
6578 NIG_MASK_XGXS0_LINK10G |
6579 NIG_MASK_SERDES0_LINK_STATUS |
6580 NIG_MASK_MI_INT));
6581 7975
6582 ext_phy_addr[port] = XGXS_EXT_PHY_ADDR(ext_phy_config);
6583 7976
6584 /* Reset the phy */ 7977 /* Set fault module detected LED on */
6585 bnx2x_cl45_write(bp, port, 7978 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6586 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 7979 MISC_REGISTERS_GPIO_HIGH,
6587 ext_phy_addr[port], 7980 port);
6588 MDIO_PMA_DEVAD,
6589 MDIO_PMA_REG_CTRL,
6590 1<<15);
6591 } 7981 }
6592 7982
6593 /* Add delay of 150ms after reset */ 7983 return 0;
6594 msleep(150); 7984}
6595 7985static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
6596 /* PART2 - Download firmware to both phys */ 7986 u8 *io_gpio, u8 *io_port)
6597 for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) { 7987{
6598 u16 fw_ver1;
6599
6600 bnx2x_bcm8727_external_rom_boot(bp, port,
6601 ext_phy_addr[port], shmem_base);
6602 7988
6603 bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727, 7989 u32 phy_gpio_reset = REG_RD(bp, shmem_base +
6604 ext_phy_addr[port], 7990 offsetof(struct shmem_region,
6605 MDIO_PMA_DEVAD, 7991 dev_info.port_hw_config[PORT_0].default_cfg));
6606 MDIO_PMA_REG_ROM_VER1, &fw_ver1); 7992 switch (phy_gpio_reset) {
6607 if (fw_ver1 == 0 || fw_ver1 == 0x4321) { 7993 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
6608 DP(NETIF_MSG_LINK, 7994 *io_gpio = 0;
6609 "bnx2x_8727_common_init_phy port %x:" 7995 *io_port = 0;
6610 "Download failed. fw version = 0x%x\n", 7996 break;
6611 port, fw_ver1); 7997 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
6612 return -EINVAL; 7998 *io_gpio = 1;
6613 } 7999 *io_port = 0;
8000 break;
8001 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
8002 *io_gpio = 2;
8003 *io_port = 0;
8004 break;
8005 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
8006 *io_gpio = 3;
8007 *io_port = 0;
8008 break;
8009 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
8010 *io_gpio = 0;
8011 *io_port = 1;
8012 break;
8013 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
8014 *io_gpio = 1;
8015 *io_port = 1;
8016 break;
8017 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
8018 *io_gpio = 2;
8019 *io_port = 1;
8020 break;
8021 case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
8022 *io_gpio = 3;
8023 *io_port = 1;
8024 break;
8025 default:
8026 /* Don't override the io_gpio and io_port */
8027 break;
6614 } 8028 }
6615
6616 return 0;
6617} 8029}
8030static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
8031 u32 shmem_base_path[],
8032 u32 shmem2_base_path[], u8 phy_index,
8033 u32 chip_id)
8034{
8035 s8 port, reset_gpio;
8036 u32 swap_val, swap_override;
8037 struct bnx2x_phy phy[PORT_MAX];
8038 struct bnx2x_phy *phy_blk[PORT_MAX];
8039 s8 port_of_path;
8040 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8041 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
6618 8042
8043 reset_gpio = MISC_REGISTERS_GPIO_1;
8044 port = 1;
6619 8045
6620static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base) 8046 /*
6621{ 8047 * Retrieve the reset gpio/port which control the reset.
6622 u8 ext_phy_addr; 8048 * Default is GPIO1, PORT1
6623 u32 val; 8049 */
6624 s8 port; 8050 bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
8051 (u8 *)&reset_gpio, (u8 *)&port);
6625 8052
6626 /* Use port1 because of the static port-swap */ 8053 /* Calculate the port based on port swap */
6627 /* Enable the module detection interrupt */ 8054 port ^= (swap_val && swap_override);
6628 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN); 8055
6629 val |= ((1<<MISC_REGISTERS_GPIO_3)| 8056 /* Initiate PHY reset*/
6630 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT))); 8057 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
6631 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val); 8058 port);
8059 msleep(1);
8060 bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
8061 port);
6632 8062
6633 bnx2x_ext_phy_hw_reset(bp, 1);
6634 msleep(5); 8063 msleep(5);
6635 for (port = 0; port < PORT_MAX; port++) { 8064
8065 /* PART1 - Reset both phys */
8066 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
8067 u32 shmem_base, shmem2_base;
8068
8069 /* In E2, same phy is using for port0 of the two paths */
8070 if (CHIP_IS_E2(bp)) {
8071 shmem_base = shmem_base_path[port];
8072 shmem2_base = shmem2_base_path[port];
8073 port_of_path = 0;
8074 } else {
8075 shmem_base = shmem_base_path[0];
8076 shmem2_base = shmem2_base_path[0];
8077 port_of_path = port;
8078 }
8079
6636 /* Extract the ext phy address for the port */ 8080 /* Extract the ext phy address for the port */
6637 u32 ext_phy_config = REG_RD(bp, shmem_base + 8081 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
6638 offsetof(struct shmem_region, 8082 port_of_path, &phy[port]) !=
6639 dev_info.port_hw_config[port].external_phy_config)); 8083 0) {
8084 DP(NETIF_MSG_LINK, "populate phy failed\n");
8085 return -EINVAL;
8086 }
8087 /* disable attentions */
8088 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
8089 port_of_path*4,
8090 (NIG_MASK_XGXS0_LINK_STATUS |
8091 NIG_MASK_XGXS0_LINK10G |
8092 NIG_MASK_SERDES0_LINK_STATUS |
8093 NIG_MASK_MI_INT));
6640 8094
6641 ext_phy_addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
6642 DP(NETIF_MSG_LINK, "8726_common_init : ext_phy_addr = 0x%x\n",
6643 ext_phy_addr);
6644 8095
6645 bnx2x_8726_reset_phy(bp, port, ext_phy_addr); 8096 /* Reset the phy */
8097 bnx2x_cl45_write(bp, &phy[port],
8098 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8099 }
6646 8100
6647 /* Set fault module detected LED on */ 8101 /* Add delay of 150ms after reset */
6648 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, 8102 msleep(150);
6649 MISC_REGISTERS_GPIO_HIGH, 8103 if (phy[PORT_0].addr & 0x1) {
6650 port); 8104 phy_blk[PORT_0] = &(phy[PORT_1]);
8105 phy_blk[PORT_1] = &(phy[PORT_0]);
8106 } else {
8107 phy_blk[PORT_0] = &(phy[PORT_0]);
8108 phy_blk[PORT_1] = &(phy[PORT_1]);
6651 } 8109 }
8110 /* PART2 - Download firmware to both phys */
8111 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
8112 if (CHIP_IS_E2(bp))
8113 port_of_path = 0;
8114 else
8115 port_of_path = port;
8116 DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
8117 phy_blk[port]->addr);
8118 if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
8119 port_of_path))
8120 return -EINVAL;
6652 8121
8122 }
6653 return 0; 8123 return 0;
6654} 8124}
6655 8125
6656 8126static u8 bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
6657static u8 bnx2x_84823_common_init_phy(struct bnx2x *bp, u32 shmem_base) 8127 u32 shmem2_base_path[], u8 phy_index,
6658{ 8128 u32 ext_phy_type, u32 chip_id)
6659 /* HW reset */
6660 bnx2x_ext_phy_hw_reset(bp, 1);
6661 return 0;
6662}
6663u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6664{ 8129{
6665 u8 rc = 0; 8130 u8 rc = 0;
6666 u32 ext_phy_type;
6667
6668 DP(NETIF_MSG_LINK, "Begin common phy init\n");
6669
6670 /* Read the ext_phy_type for arbitrary port(0) */
6671 ext_phy_type = XGXS_EXT_PHY_TYPE(
6672 REG_RD(bp, shmem_base +
6673 offsetof(struct shmem_region,
6674 dev_info.port_hw_config[0].external_phy_config)));
6675 8131
6676 switch (ext_phy_type) { 8132 switch (ext_phy_type) {
6677 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073: 8133 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6678 { 8134 rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
6679 rc = bnx2x_8073_common_init_phy(bp, shmem_base); 8135 shmem2_base_path,
8136 phy_index, chip_id);
6680 break; 8137 break;
6681 }
6682 8138
6683 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727: 8139 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6684 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC: 8140 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6685 rc = bnx2x_8727_common_init_phy(bp, shmem_base); 8141 rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
8142 shmem2_base_path,
8143 phy_index, chip_id);
6686 break; 8144 break;
6687 8145
6688 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726: 8146 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6689 /* GPIO1 affects both ports, so there's need to pull 8147 /*
6690 it for single port alone */ 8148 * GPIO1 affects both ports, so there's need to pull
6691 rc = bnx2x_8726_common_init_phy(bp, shmem_base); 8149 * it for single port alone
8150 */
8151 rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
8152 shmem2_base_path,
8153 phy_index, chip_id);
6692 break; 8154 break;
6693 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823: 8155 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6694 rc = bnx2x_84823_common_init_phy(bp, shmem_base); 8156 rc = -EINVAL;
6695 break; 8157 break;
6696 default: 8158 default:
6697 DP(NETIF_MSG_LINK, 8159 DP(NETIF_MSG_LINK,
6698 "bnx2x_common_init_phy: ext_phy 0x%x not required\n", 8160 "ext_phy 0x%x common init not required\n",
6699 ext_phy_type); 8161 ext_phy_type);
6700 break; 8162 break;
6701 } 8163 }
6702 8164
8165 if (rc != 0)
8166 netdev_err(bp->dev, "Warning: PHY was not initialized,"
8167 " Port %d\n",
8168 0);
6703 return rc; 8169 return rc;
6704} 8170}
6705 8171
6706void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr) 8172u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
8173 u32 shmem2_base_path[], u32 chip_id)
6707{ 8174{
6708 u16 val, cnt; 8175 u8 rc = 0;
8176 u32 phy_ver;
8177 u8 phy_index;
8178 u32 ext_phy_type, ext_phy_config;
8179 DP(NETIF_MSG_LINK, "Begin common phy init\n");
6709 8180
6710 bnx2x_cl45_read(bp, port, 8181 /* Check if common init was already done */
6711 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 8182 phy_ver = REG_RD(bp, shmem_base_path[0] +
6712 phy_addr, 8183 offsetof(struct shmem_region,
6713 MDIO_PMA_DEVAD, 8184 port_mb[PORT_0].ext_phy_fw_version));
6714 MDIO_PMA_REG_7101_RESET, &val); 8185 if (phy_ver) {
8186 DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
8187 phy_ver);
8188 return 0;
8189 }
6715 8190
6716 for (cnt = 0; cnt < 10; cnt++) { 8191 /* Read the ext_phy_type for arbitrary port(0) */
6717 msleep(50); 8192 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
6718 /* Writes a self-clearing reset */ 8193 phy_index++) {
6719 bnx2x_cl45_write(bp, port, 8194 ext_phy_config = bnx2x_get_ext_phy_config(bp,
6720 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 8195 shmem_base_path[0],
6721 phy_addr, 8196 phy_index, 0);
6722 MDIO_PMA_DEVAD, 8197 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6723 MDIO_PMA_REG_7101_RESET, 8198 rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
6724 (val | (1<<15))); 8199 shmem2_base_path,
6725 /* Wait for clear */ 8200 phy_index, ext_phy_type,
6726 bnx2x_cl45_read(bp, port, 8201 chip_id);
6727 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, 8202 }
6728 phy_addr, 8203 return rc;
6729 MDIO_PMA_DEVAD, 8204}
6730 MDIO_PMA_REG_7101_RESET, &val);
6731 8205
6732 if ((val & (1<<15)) == 0) 8206u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
6733 break; 8207{
8208 u8 phy_index;
8209 struct bnx2x_phy phy;
8210 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
8211 phy_index++) {
8212 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8213 0, &phy) != 0) {
8214 DP(NETIF_MSG_LINK, "populate phy failed\n");
8215 return 0;
8216 }
8217
8218 if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
8219 return 1;
8220 }
8221 return 0;
8222}
8223
8224u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
8225 u32 shmem_base,
8226 u32 shmem2_base,
8227 u8 port)
8228{
8229 u8 phy_index, fan_failure_det_req = 0;
8230 struct bnx2x_phy phy;
8231 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8232 phy_index++) {
8233 if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
8234 port, &phy)
8235 != 0) {
8236 DP(NETIF_MSG_LINK, "populate phy failed\n");
8237 return 0;
8238 }
8239 fan_failure_det_req |= (phy.flags &
8240 FLAGS_FAN_FAILURE_DET_REQ);
8241 }
8242 return fan_failure_det_req;
8243}
8244
8245void bnx2x_hw_reset_phy(struct link_params *params)
8246{
8247 u8 phy_index;
8248 for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
8249 phy_index++) {
8250 if (params->phy[phy_index].hw_reset) {
8251 params->phy[phy_index].hw_reset(
8252 &params->phy[phy_index],
8253 params);
8254 params->phy[phy_index] = phy_null;
8255 }
6734 } 8256 }
6735} 8257}