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