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