bnx2x: Adjust alignment of split PHY functions
[linux-2.6-block.git] / drivers / net / bnx2x / bnx2x_link.c
CommitLineData
d05c26ce 1/* Copyright 2008-2009 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
ea4e040a
YR
31#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
32#define ETH_MIN_PACKET_SIZE 60
33#define ETH_MAX_PACKET_SIZE 1500
34#define ETH_MAX_JUMBO_PACKET_SIZE 9600
35#define MDIO_ACCESS_TIMEOUT 1000
36#define BMAC_CONTROL_RX_ENABLE 2
ea4e040a
YR
37
38/***********************************************************/
3196a88a 39/* Shortcut definitions */
ea4e040a
YR
40/***********************************************************/
41
2f904460
EG
42#define NIG_LATCH_BC_ENABLE_MI_INT 0
43
44#define NIG_STATUS_EMAC0_MI_INT \
45 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
ea4e040a
YR
46#define NIG_STATUS_XGXS0_LINK10G \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48#define NIG_STATUS_XGXS0_LINK_STATUS \
49 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52#define NIG_STATUS_SERDES0_LINK_STATUS \
53 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54#define NIG_MASK_MI_INT \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56#define NIG_MASK_XGXS0_LINK10G \
57 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58#define NIG_MASK_XGXS0_LINK_STATUS \
59 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60#define NIG_MASK_SERDES0_LINK_STATUS \
61 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63#define MDIO_AN_CL73_OR_37_COMPLETE \
64 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67#define XGXS_RESET_BITS \
68 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74#define SERDES_RESET_BITS \
75 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
81#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
3196a88a
EG
82#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
83#define AUTONEG_PARALLEL \
ea4e040a 84 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
3196a88a 85#define AUTONEG_SGMII_FIBER_AUTODET \
ea4e040a 86 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
3196a88a 87#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
ea4e040a
YR
88
89#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93#define GP_STATUS_SPEED_MASK \
94 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101#define GP_STATUS_10G_HIG \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103#define GP_STATUS_10G_CX4 \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105#define GP_STATUS_12G_HIG \
106 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112#define GP_STATUS_10G_KX4 \
113 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
116#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
119#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139#define PHY_XGXS_FLAG 0x1
140#define PHY_SGMII_FLAG 0x2
141#define PHY_SERDES_FLAG 0x4
142
589abe3a
EG
143/* */
144#define SFP_EEPROM_CON_TYPE_ADDR 0x2
145 #define SFP_EEPROM_CON_TYPE_VAL_LC 0x7
146 #define SFP_EEPROM_CON_TYPE_VAL_COPPER 0x21
147
4d295db0
EG
148
149#define SFP_EEPROM_COMP_CODE_ADDR 0x3
150 #define SFP_EEPROM_COMP_CODE_SR_MASK (1<<4)
151 #define SFP_EEPROM_COMP_CODE_LR_MASK (1<<5)
152 #define SFP_EEPROM_COMP_CODE_LRM_MASK (1<<6)
153
589abe3a
EG
154#define SFP_EEPROM_FC_TX_TECH_ADDR 0x8
155 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
156 #define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE 0x8
4d295db0 157
589abe3a
EG
158#define SFP_EEPROM_OPTIONS_ADDR 0x40
159 #define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
160#define SFP_EEPROM_OPTIONS_SIZE 2
161
4d295db0
EG
162#define EDC_MODE_LINEAR 0x0022
163#define EDC_MODE_LIMITING 0x0044
164#define EDC_MODE_PASSIVE_DAC 0x0055
165
166
589abe3a 167
ea4e040a
YR
168/**********************************************************/
169/* INTERFACE */
170/**********************************************************/
e10bc84d
YR
171
172#define CL45_WR_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
173 bnx2x_cl45_write(_bp, _phy, \
ea4e040a
YR
174 DEFAULT_PHY_DEV_ADDR, \
175 (_bank + (_addr & 0xf)), \
176 _val)
177
e10bc84d
YR
178#define CL45_RD_OVER_CL22(_bp, _phy, _bank, _addr, _val) \
179 bnx2x_cl45_read(_bp, _phy, \
ea4e040a
YR
180 DEFAULT_PHY_DEV_ADDR, \
181 (_bank + (_addr & 0xf)), \
182 _val)
183
e10bc84d 184static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
ea4e040a 185{
e10bc84d 186 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
ab6ad5a4 187
c1b73990 188 /* Set Clause 22 */
e10bc84d 189 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
c1b73990
EG
190 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
191 udelay(500);
192 REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
193 udelay(500);
194 /* Set Clause 45 */
e10bc84d 195 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
c1b73990 196}
e10bc84d 197
c1b73990
EG
198static void bnx2x_set_phy_mdio(struct link_params *params, u8 phy_flags)
199{
200 struct bnx2x *bp = params->bp;
ab6ad5a4 201
c1b73990
EG
202 if (phy_flags & PHY_XGXS_FLAG) {
203 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
204 params->port*0x18, 0);
205 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
206 DEFAULT_PHY_DEV_ADDR);
207 } else {
e10bc84d 208 bnx2x_set_serdes_access(bp, params->port);
c1b73990
EG
209
210 REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD +
211 params->port*0x10,
212 DEFAULT_PHY_DEV_ADDR);
213 }
ea4e040a
YR
214}
215
216static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
217{
218 u32 val = REG_RD(bp, reg);
219
220 val |= bits;
221 REG_WR(bp, reg, val);
222 return val;
223}
224
225static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
226{
227 u32 val = REG_RD(bp, reg);
228
229 val &= ~bits;
230 REG_WR(bp, reg, val);
231 return val;
232}
233
234static void bnx2x_emac_init(struct link_params *params,
235 struct link_vars *vars)
236{
237 /* reset and unreset the emac core */
238 struct bnx2x *bp = params->bp;
239 u8 port = params->port;
240 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
241 u32 val;
242 u16 timeout;
243
244 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
245 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
246 udelay(5);
247 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
248 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
249
250 /* init emac - use read-modify-write */
251 /* self clear reset */
252 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
3196a88a 253 EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
ea4e040a
YR
254
255 timeout = 200;
3196a88a 256 do {
ea4e040a
YR
257 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
258 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
259 if (!timeout) {
260 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
261 return;
262 }
263 timeout--;
3196a88a 264 } while (val & EMAC_MODE_RESET);
ea4e040a
YR
265
266 /* Set mac address */
267 val = ((params->mac_addr[0] << 8) |
268 params->mac_addr[1]);
3196a88a 269 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
ea4e040a
YR
270
271 val = ((params->mac_addr[2] << 24) |
272 (params->mac_addr[3] << 16) |
273 (params->mac_addr[4] << 8) |
274 params->mac_addr[5]);
3196a88a 275 EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
ea4e040a
YR
276}
277
278static u8 bnx2x_emac_enable(struct link_params *params,
279 struct link_vars *vars, u8 lb)
280{
281 struct bnx2x *bp = params->bp;
282 u8 port = params->port;
283 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
284 u32 val;
285
286 DP(NETIF_MSG_LINK, "enabling EMAC\n");
287
288 /* enable emac and not bmac */
289 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
290
291 /* for paladium */
292 if (CHIP_REV_IS_EMUL(bp)) {
293 /* Use lane 1 (of lanes 0-3) */
294 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
295 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
296 port*4, 1);
297 }
298 /* for fpga */
299 else
300
301 if (CHIP_REV_IS_FPGA(bp)) {
302 /* Use lane 1 (of lanes 0-3) */
303 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
304
305 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
306 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
307 0);
308 } else
309 /* ASIC */
310 if (vars->phy_flags & PHY_XGXS_FLAG) {
311 u32 ser_lane = ((params->lane_config &
312 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
313 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
314
315 DP(NETIF_MSG_LINK, "XGXS\n");
316 /* select the master lanes (out of 0-3) */
317 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
318 port*4, ser_lane);
319 /* select XGXS */
320 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
321 port*4, 1);
322
323 } else { /* SerDes */
324 DP(NETIF_MSG_LINK, "SerDes\n");
325 /* select SerDes */
326 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
327 port*4, 0);
328 }
329
811a2f2d
EG
330 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
331 EMAC_RX_MODE_RESET);
332 bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
333 EMAC_TX_MODE_RESET);
ea4e040a
YR
334
335 if (CHIP_REV_IS_SLOW(bp)) {
336 /* config GMII mode */
337 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
3196a88a 338 EMAC_WR(bp, EMAC_REG_EMAC_MODE,
ea4e040a
YR
339 (val | EMAC_MODE_PORT_GMII));
340 } else { /* ASIC */
341 /* pause enable/disable */
342 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
343 EMAC_RX_MODE_FLOW_EN);
c0700f90 344 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
ea4e040a
YR
345 bnx2x_bits_en(bp, emac_base +
346 EMAC_REG_EMAC_RX_MODE,
347 EMAC_RX_MODE_FLOW_EN);
348
349 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
8c99e7b0
YR
350 (EMAC_TX_MODE_EXT_PAUSE_EN |
351 EMAC_TX_MODE_FLOW_EN));
c0700f90 352 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
ea4e040a
YR
353 bnx2x_bits_en(bp, emac_base +
354 EMAC_REG_EMAC_TX_MODE,
8c99e7b0
YR
355 (EMAC_TX_MODE_EXT_PAUSE_EN |
356 EMAC_TX_MODE_FLOW_EN));
ea4e040a
YR
357 }
358
359 /* KEEP_VLAN_TAG, promiscuous */
360 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
361 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
3196a88a 362 EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
ea4e040a
YR
363
364 /* Set Loopback */
365 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
366 if (lb)
367 val |= 0x810;
368 else
369 val &= ~0x810;
3196a88a 370 EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
ea4e040a 371
6c55c3cd
EG
372 /* enable emac */
373 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
374
ea4e040a 375 /* enable emac for jumbo packets */
3196a88a 376 EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
ea4e040a
YR
377 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
378 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
379
380 /* strip CRC */
381 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
382
383 /* disable the NIG in/out to the bmac */
384 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
385 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
386 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
387
388 /* enable the NIG in/out to the emac */
389 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
390 val = 0;
c0700f90 391 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
ea4e040a
YR
392 val = 1;
393
394 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
395 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
396
397 if (CHIP_REV_IS_EMUL(bp)) {
398 /* take the BigMac out of reset */
399 REG_WR(bp,
400 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
401 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
402
403 /* enable access for bmac registers */
404 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
6f65497b
EG
405 } else
406 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
ea4e040a
YR
407
408 vars->mac_type = MAC_TYPE_EMAC;
409 return 0;
410}
411
412
413
414static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
415 u8 is_lb)
416{
417 struct bnx2x *bp = params->bp;
418 u8 port = params->port;
419 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
420 NIG_REG_INGRESS_BMAC0_MEM;
421 u32 wb_data[2];
422 u32 val;
423
424 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
425 /* reset and unreset the BigMac */
426 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
427 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
428 msleep(1);
429
430 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
431 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
432
433 /* enable access for bmac registers */
434 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
435
436 /* XGXS control */
437 wb_data[0] = 0x3c;
438 wb_data[1] = 0;
439 REG_WR_DMAE(bp, bmac_addr +
440 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
441 wb_data, 2);
442
443 /* tx MAC SA */
444 wb_data[0] = ((params->mac_addr[2] << 24) |
445 (params->mac_addr[3] << 16) |
446 (params->mac_addr[4] << 8) |
447 params->mac_addr[5]);
448 wb_data[1] = ((params->mac_addr[0] << 8) |
449 params->mac_addr[1]);
450 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
451 wb_data, 2);
452
453 /* tx control */
454 val = 0xc0;
c0700f90 455 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
ea4e040a
YR
456 val |= 0x800000;
457 wb_data[0] = val;
458 wb_data[1] = 0;
459 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
460 wb_data, 2);
461
462 /* mac control */
463 val = 0x3;
464 if (is_lb) {
465 val |= 0x4;
466 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
467 }
468 wb_data[0] = val;
469 wb_data[1] = 0;
470 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
471 wb_data, 2);
472
ea4e040a
YR
473 /* set rx mtu */
474 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
475 wb_data[1] = 0;
476 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
477 wb_data, 2);
478
479 /* rx control set to don't strip crc */
480 val = 0x14;
c0700f90 481 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
ea4e040a
YR
482 val |= 0x20;
483 wb_data[0] = val;
484 wb_data[1] = 0;
485 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
486 wb_data, 2);
487
488 /* set tx mtu */
489 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
490 wb_data[1] = 0;
491 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
492 wb_data, 2);
493
494 /* set cnt max size */
495 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
496 wb_data[1] = 0;
497 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
498 wb_data, 2);
499
500 /* configure safc */
501 wb_data[0] = 0x1000200;
502 wb_data[1] = 0;
503 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
504 wb_data, 2);
505 /* fix for emulation */
506 if (CHIP_REV_IS_EMUL(bp)) {
507 wb_data[0] = 0xf000;
508 wb_data[1] = 0;
509 REG_WR_DMAE(bp,
510 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
511 wb_data, 2);
512 }
513
514 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
515 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
516 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
517 val = 0;
c0700f90 518 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
ea4e040a
YR
519 val = 1;
520 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
521 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
522 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
523 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
524 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
525 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
526
527 vars->mac_type = MAC_TYPE_BMAC;
528 return 0;
529}
530
531static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
532{
533 struct bnx2x *bp = params->bp;
534 u32 val;
535
536 if (phy_flags & PHY_XGXS_FLAG) {
537 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
538 val = XGXS_RESET_BITS;
539
540 } else { /* SerDes */
541 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
542 val = SERDES_RESET_BITS;
543 }
544
545 val = val << (params->port*16);
546
547 /* reset and unreset the SerDes/XGXS */
548 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
549 val);
550 udelay(500);
551 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
552 val);
c1b73990 553 bnx2x_set_phy_mdio(params, phy_flags);
ea4e040a
YR
554}
555
556void bnx2x_link_status_update(struct link_params *params,
557 struct link_vars *vars)
558{
559 struct bnx2x *bp = params->bp;
560 u8 link_10g;
561 u8 port = params->port;
562
563 if (params->switch_cfg == SWITCH_CFG_1G)
564 vars->phy_flags = PHY_SERDES_FLAG;
565 else
566 vars->phy_flags = PHY_XGXS_FLAG;
567 vars->link_status = REG_RD(bp, params->shmem_base +
568 offsetof(struct shmem_region,
569 port_mb[port].link_status));
570
571 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
572
573 if (vars->link_up) {
574 DP(NETIF_MSG_LINK, "phy link up\n");
575
576 vars->phy_link_up = 1;
577 vars->duplex = DUPLEX_FULL;
578 switch (vars->link_status &
579 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
580 case LINK_10THD:
581 vars->duplex = DUPLEX_HALF;
582 /* fall thru */
583 case LINK_10TFD:
584 vars->line_speed = SPEED_10;
585 break;
586
587 case LINK_100TXHD:
588 vars->duplex = DUPLEX_HALF;
589 /* fall thru */
590 case LINK_100T4:
591 case LINK_100TXFD:
592 vars->line_speed = SPEED_100;
593 break;
594
595 case LINK_1000THD:
596 vars->duplex = DUPLEX_HALF;
597 /* fall thru */
598 case LINK_1000TFD:
599 vars->line_speed = SPEED_1000;
600 break;
601
602 case LINK_2500THD:
603 vars->duplex = DUPLEX_HALF;
604 /* fall thru */
605 case LINK_2500TFD:
606 vars->line_speed = SPEED_2500;
607 break;
608
609 case LINK_10GTFD:
610 vars->line_speed = SPEED_10000;
611 break;
612
613 case LINK_12GTFD:
614 vars->line_speed = SPEED_12000;
615 break;
616
617 case LINK_12_5GTFD:
618 vars->line_speed = SPEED_12500;
619 break;
620
621 case LINK_13GTFD:
622 vars->line_speed = SPEED_13000;
623 break;
624
625 case LINK_15GTFD:
626 vars->line_speed = SPEED_15000;
627 break;
628
629 case LINK_16GTFD:
630 vars->line_speed = SPEED_16000;
631 break;
632
633 default:
634 break;
635 }
636
637 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
c0700f90 638 vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
ea4e040a 639 else
c0700f90 640 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
ea4e040a
YR
641
642 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
c0700f90 643 vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
ea4e040a 644 else
c0700f90 645 vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
ea4e040a
YR
646
647 if (vars->phy_flags & PHY_XGXS_FLAG) {
8c99e7b0
YR
648 if (vars->line_speed &&
649 ((vars->line_speed == SPEED_10) ||
650 (vars->line_speed == SPEED_100))) {
ea4e040a
YR
651 vars->phy_flags |= PHY_SGMII_FLAG;
652 } else {
653 vars->phy_flags &= ~PHY_SGMII_FLAG;
654 }
655 }
656
657 /* anything 10 and over uses the bmac */
658 link_10g = ((vars->line_speed == SPEED_10000) ||
659 (vars->line_speed == SPEED_12000) ||
660 (vars->line_speed == SPEED_12500) ||
661 (vars->line_speed == SPEED_13000) ||
662 (vars->line_speed == SPEED_15000) ||
663 (vars->line_speed == SPEED_16000));
664 if (link_10g)
665 vars->mac_type = MAC_TYPE_BMAC;
666 else
667 vars->mac_type = MAC_TYPE_EMAC;
668
669 } else { /* link down */
670 DP(NETIF_MSG_LINK, "phy link down\n");
671
672 vars->phy_link_up = 0;
673
674 vars->line_speed = 0;
675 vars->duplex = DUPLEX_FULL;
c0700f90 676 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
677
678 /* indicate no mac active */
679 vars->mac_type = MAC_TYPE_NONE;
680 }
681
682 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
683 vars->link_status, vars->phy_link_up);
684 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
685 vars->line_speed, vars->duplex, vars->flow_ctrl);
686}
687
688static void bnx2x_update_mng(struct link_params *params, u32 link_status)
689{
690 struct bnx2x *bp = params->bp;
ab6ad5a4 691
ea4e040a
YR
692 REG_WR(bp, params->shmem_base +
693 offsetof(struct shmem_region,
694 port_mb[params->port].link_status),
695 link_status);
696}
697
698static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
699{
700 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
701 NIG_REG_INGRESS_BMAC0_MEM;
702 u32 wb_data[2];
3196a88a 703 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
ea4e040a
YR
704
705 /* Only if the bmac is out of reset */
706 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
707 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
708 nig_bmac_enable) {
709
710 /* Clear Rx Enable bit in BMAC_CONTROL register */
711 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
712 wb_data, 2);
713 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
714 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
715 wb_data, 2);
716
717 msleep(1);
718 }
719}
720
721static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
722 u32 line_speed)
723{
724 struct bnx2x *bp = params->bp;
725 u8 port = params->port;
726 u32 init_crd, crd;
727 u32 count = 1000;
ea4e040a
YR
728
729 /* disable port */
730 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
731
732 /* wait for init credit */
733 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
734 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
735 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
736
737 while ((init_crd != crd) && count) {
738 msleep(5);
739
740 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
741 count--;
742 }
743 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
744 if (init_crd != crd) {
745 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
746 init_crd, crd);
747 return -EINVAL;
748 }
749
c0700f90 750 if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
8c99e7b0
YR
751 line_speed == SPEED_10 ||
752 line_speed == SPEED_100 ||
753 line_speed == SPEED_1000 ||
754 line_speed == SPEED_2500) {
755 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
ea4e040a
YR
756 /* update threshold */
757 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
758 /* update init credit */
8c99e7b0 759 init_crd = 778; /* (800-18-4) */
ea4e040a
YR
760
761 } else {
762 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
763 ETH_OVREHEAD)/16;
8c99e7b0 764 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
ea4e040a
YR
765 /* update threshold */
766 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
767 /* update init credit */
768 switch (line_speed) {
ea4e040a
YR
769 case SPEED_10000:
770 init_crd = thresh + 553 - 22;
771 break;
772
773 case SPEED_12000:
774 init_crd = thresh + 664 - 22;
775 break;
776
777 case SPEED_13000:
778 init_crd = thresh + 742 - 22;
779 break;
780
781 case SPEED_16000:
782 init_crd = thresh + 778 - 22;
783 break;
784 default:
785 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
786 line_speed);
787 return -EINVAL;
ea4e040a
YR
788 }
789 }
790 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
791 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
792 line_speed, init_crd);
793
794 /* probe the credit changes */
795 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
796 msleep(5);
797 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
798
799 /* enable port */
800 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
801 return 0;
802}
803
589abe3a 804static u32 bnx2x_get_emac_base(struct bnx2x *bp, u32 ext_phy_type, u8 port)
ea4e040a
YR
805{
806 u32 emac_base;
ab6ad5a4 807
ea4e040a
YR
808 switch (ext_phy_type) {
809 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
589abe3a 810 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
4d295db0 811 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
589abe3a
EG
812 /* All MDC/MDIO is directed through single EMAC */
813 if (REG_RD(bp, NIG_REG_PORT_SWAP))
814 emac_base = GRCBASE_EMAC0;
815 else
816 emac_base = GRCBASE_EMAC1;
ea4e040a
YR
817 break;
818 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6378c025 819 emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
ea4e040a
YR
820 break;
821 default:
6378c025 822 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
ea4e040a
YR
823 break;
824 }
825 return emac_base;
826
827}
828
e10bc84d
YR
829u8 bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
830 u8 devad, u16 reg, u16 val)
ea4e040a
YR
831{
832 u32 tmp, saved_mode;
833 u8 i, rc = 0;
ea4e040a
YR
834
835 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
836 * (a value of 49==0x31) and make sure that the AUTO poll is off
837 */
589abe3a 838
e10bc84d 839 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
ea4e040a
YR
840 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
841 EMAC_MDIO_MODE_CLOCK_CNT);
842 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
843 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
e10bc84d
YR
844 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
845 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
ea4e040a
YR
846 udelay(40);
847
848 /* address */
849
e10bc84d 850 tmp = ((phy->addr << 21) | (devad << 16) | reg |
ea4e040a
YR
851 EMAC_MDIO_COMM_COMMAND_ADDRESS |
852 EMAC_MDIO_COMM_START_BUSY);
e10bc84d 853 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
ea4e040a
YR
854
855 for (i = 0; i < 50; i++) {
856 udelay(10);
857
e10bc84d
YR
858 tmp = REG_RD(bp, phy->mdio_ctrl +
859 EMAC_REG_EMAC_MDIO_COMM);
ea4e040a
YR
860 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
861 udelay(5);
862 break;
863 }
864 }
865 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
866 DP(NETIF_MSG_LINK, "write phy register failed\n");
867 rc = -EFAULT;
868 } else {
869 /* data */
e10bc84d 870 tmp = ((phy->addr << 21) | (devad << 16) | val |
ea4e040a
YR
871 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
872 EMAC_MDIO_COMM_START_BUSY);
e10bc84d 873 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
ea4e040a
YR
874
875 for (i = 0; i < 50; i++) {
876 udelay(10);
877
e10bc84d 878 tmp = REG_RD(bp, phy->mdio_ctrl +
ea4e040a
YR
879 EMAC_REG_EMAC_MDIO_COMM);
880 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
881 udelay(5);
882 break;
883 }
884 }
885 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
886 DP(NETIF_MSG_LINK, "write phy register failed\n");
887 rc = -EFAULT;
888 }
889 }
890
891 /* Restore the saved mode */
e10bc84d 892 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
ea4e040a
YR
893
894 return rc;
895}
896
e10bc84d
YR
897u8 bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
898 u8 devad, u16 reg, u16 *ret_val)
ea4e040a
YR
899{
900 u32 val, saved_mode;
901 u16 i;
902 u8 rc = 0;
903
ea4e040a
YR
904 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
905 * (a value of 49==0x31) and make sure that the AUTO poll is off
906 */
589abe3a 907
e10bc84d
YR
908 saved_mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
909 val = saved_mode & ~((EMAC_MDIO_MODE_AUTO_POLL |
ea4e040a
YR
910 EMAC_MDIO_MODE_CLOCK_CNT));
911 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
ab6ad5a4 912 (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
e10bc84d
YR
913 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
914 REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
ea4e040a
YR
915 udelay(40);
916
917 /* address */
e10bc84d 918 val = ((phy->addr << 21) | (devad << 16) | reg |
ea4e040a
YR
919 EMAC_MDIO_COMM_COMMAND_ADDRESS |
920 EMAC_MDIO_COMM_START_BUSY);
e10bc84d 921 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
ea4e040a
YR
922
923 for (i = 0; i < 50; i++) {
924 udelay(10);
925
e10bc84d 926 val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
ea4e040a
YR
927 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
928 udelay(5);
929 break;
930 }
931 }
932 if (val & EMAC_MDIO_COMM_START_BUSY) {
933 DP(NETIF_MSG_LINK, "read phy register failed\n");
934
935 *ret_val = 0;
936 rc = -EFAULT;
937
938 } else {
939 /* data */
e10bc84d 940 val = ((phy->addr << 21) | (devad << 16) |
ea4e040a
YR
941 EMAC_MDIO_COMM_COMMAND_READ_45 |
942 EMAC_MDIO_COMM_START_BUSY);
e10bc84d 943 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
ea4e040a
YR
944
945 for (i = 0; i < 50; i++) {
946 udelay(10);
947
e10bc84d 948 val = REG_RD(bp, phy->mdio_ctrl +
ea4e040a
YR
949 EMAC_REG_EMAC_MDIO_COMM);
950 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
951 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
952 break;
953 }
954 }
955 if (val & EMAC_MDIO_COMM_START_BUSY) {
956 DP(NETIF_MSG_LINK, "read phy register failed\n");
957
958 *ret_val = 0;
959 rc = -EFAULT;
960 }
961 }
962
963 /* Restore the saved mode */
e10bc84d 964 REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
ea4e040a
YR
965
966 return rc;
967}
968
e10bc84d
YR
969u8 bnx2x_phy_read(struct link_params *params, u8 phy_addr,
970 u8 devad, u16 reg, u16 *ret_val)
971{
972 u8 phy_index;
973 /**
974 * Probe for the phy according to the given phy_addr, and execute
975 * the read request on it
976 */
977 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
978 if (params->phy[phy_index].addr == phy_addr) {
979 return bnx2x_cl45_read(params->bp,
980 &params->phy[phy_index], devad,
981 reg, ret_val);
982 }
983 }
984 return -EINVAL;
985}
986
987u8 bnx2x_phy_write(struct link_params *params, u8 phy_addr,
988 u8 devad, u16 reg, u16 val)
989{
990 u8 phy_index;
991 /**
992 * Probe for the phy according to the given phy_addr, and execute
993 * the write request on it
994 */
995 for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
996 if (params->phy[phy_index].addr == phy_addr) {
997 return bnx2x_cl45_write(params->bp,
998 &params->phy[phy_index], devad,
999 reg, val);
1000 }
1001 }
1002 return -EINVAL;
1003}
1004
ea4e040a 1005static void bnx2x_set_aer_mmd(struct link_params *params,
e10bc84d 1006 struct bnx2x_phy *phy)
ea4e040a
YR
1007{
1008 struct bnx2x *bp = params->bp;
1009 u32 ser_lane;
1010 u16 offset;
1011
1012 ser_lane = ((params->lane_config &
1013 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1014 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1015
e10bc84d
YR
1016 offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
1017 (phy->addr + ser_lane) : 0;
ea4e040a 1018
e10bc84d 1019 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1020 MDIO_REG_BANK_AER_BLOCK,
1021 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
1022}
1023
e10bc84d
YR
1024static void bnx2x_set_master_ln(struct link_params *params,
1025 struct bnx2x_phy *phy)
ea4e040a
YR
1026{
1027 struct bnx2x *bp = params->bp;
1028 u16 new_master_ln, ser_lane;
1029 ser_lane = ((params->lane_config &
1030 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1031 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1032
1033 /* set the master_ln for AN */
e10bc84d 1034 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1035 MDIO_REG_BANK_XGXS_BLOCK2,
1036 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1037 &new_master_ln);
1038
e10bc84d 1039 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1040 MDIO_REG_BANK_XGXS_BLOCK2 ,
1041 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
1042 (new_master_ln | ser_lane));
1043}
1044
e10bc84d
YR
1045static u8 bnx2x_reset_unicore(struct link_params *params,
1046 struct bnx2x_phy *phy,
1047 u8 set_serdes)
ea4e040a
YR
1048{
1049 struct bnx2x *bp = params->bp;
1050 u16 mii_control;
1051 u16 i;
1052
e10bc84d 1053 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1054 MDIO_REG_BANK_COMBO_IEEE0,
1055 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
1056
1057 /* reset the unicore */
e10bc84d 1058 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1059 MDIO_REG_BANK_COMBO_IEEE0,
1060 MDIO_COMBO_IEEE0_MII_CONTROL,
1061 (mii_control |
1062 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
e10bc84d
YR
1063 if (set_serdes)
1064 bnx2x_set_serdes_access(bp, params->port);
c1b73990 1065
ea4e040a
YR
1066 /* wait for the reset to self clear */
1067 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
1068 udelay(5);
1069
1070 /* the reset erased the previous bank value */
e10bc84d 1071 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1072 MDIO_REG_BANK_COMBO_IEEE0,
1073 MDIO_COMBO_IEEE0_MII_CONTROL,
1074 &mii_control);
1075
1076 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
1077 udelay(5);
1078 return 0;
1079 }
1080 }
1081
1082 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
1083 return -EINVAL;
1084
1085}
1086
e10bc84d
YR
1087static void bnx2x_set_swap_lanes(struct link_params *params,
1088 struct bnx2x_phy *phy)
ea4e040a
YR
1089{
1090 struct bnx2x *bp = params->bp;
1091 /* Each two bits represents a lane number:
1092 No swap is 0123 => 0x1b no need to enable the swap */
1093 u16 ser_lane, rx_lane_swap, tx_lane_swap;
1094
1095 ser_lane = ((params->lane_config &
1096 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1097 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1098 rx_lane_swap = ((params->lane_config &
1099 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1100 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1101 tx_lane_swap = ((params->lane_config &
1102 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1103 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1104
1105 if (rx_lane_swap != 0x1b) {
e10bc84d 1106 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1107 MDIO_REG_BANK_XGXS_BLOCK2,
1108 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1109 (rx_lane_swap |
1110 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1111 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1112 } else {
e10bc84d 1113 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1114 MDIO_REG_BANK_XGXS_BLOCK2,
1115 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1116 }
1117
1118 if (tx_lane_swap != 0x1b) {
e10bc84d 1119 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1120 MDIO_REG_BANK_XGXS_BLOCK2,
1121 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1122 (tx_lane_swap |
1123 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1124 } else {
e10bc84d 1125 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1126 MDIO_REG_BANK_XGXS_BLOCK2,
1127 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1128 }
1129}
1130
e10bc84d
YR
1131static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
1132 struct link_params *params)
ea4e040a
YR
1133{
1134 struct bnx2x *bp = params->bp;
1135 u16 control2;
e10bc84d 1136 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1137 MDIO_REG_BANK_SERDES_DIGITAL,
1138 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1139 &control2);
18afb0a6
YR
1140 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1141 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1142 else
1143 control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1144 DP(NETIF_MSG_LINK, "params->speed_cap_mask = 0x%x, control2 = 0x%x\n",
1145 params->speed_cap_mask, control2);
e10bc84d 1146 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1147 MDIO_REG_BANK_SERDES_DIGITAL,
1148 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1149 control2);
1150
e10bc84d 1151 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
18afb0a6
YR
1152 (params->speed_cap_mask &
1153 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
ea4e040a
YR
1154 DP(NETIF_MSG_LINK, "XGXS\n");
1155
e10bc84d 1156 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1157 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1158 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1159 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1160
e10bc84d 1161 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1162 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1163 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1164 &control2);
1165
1166
1167 control2 |=
1168 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1169
e10bc84d 1170 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1171 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1172 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1173 control2);
1174
1175 /* Disable parallel detection of HiG */
e10bc84d 1176 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1177 MDIO_REG_BANK_XGXS_BLOCK2,
1178 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1179 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1180 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1181 }
1182}
1183
e10bc84d
YR
1184static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
1185 struct link_params *params,
239d686d
EG
1186 struct link_vars *vars,
1187 u8 enable_cl73)
ea4e040a
YR
1188{
1189 struct bnx2x *bp = params->bp;
1190 u16 reg_val;
1191
1192 /* CL37 Autoneg */
e10bc84d 1193 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1194 MDIO_REG_BANK_COMBO_IEEE0,
1195 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1196
1197 /* CL37 Autoneg Enabled */
8c99e7b0 1198 if (vars->line_speed == SPEED_AUTO_NEG)
ea4e040a
YR
1199 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1200 else /* CL37 Autoneg Disabled */
1201 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1202 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1203
e10bc84d 1204 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1205 MDIO_REG_BANK_COMBO_IEEE0,
1206 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1207
1208 /* Enable/Disable Autodetection */
1209
e10bc84d 1210 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1211 MDIO_REG_BANK_SERDES_DIGITAL,
1212 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
239d686d
EG
1213 reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
1214 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
1215 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
8c99e7b0 1216 if (vars->line_speed == SPEED_AUTO_NEG)
ea4e040a
YR
1217 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1218 else
1219 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1220
e10bc84d 1221 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1222 MDIO_REG_BANK_SERDES_DIGITAL,
1223 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1224
1225 /* Enable TetonII and BAM autoneg */
e10bc84d 1226 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1227 MDIO_REG_BANK_BAM_NEXT_PAGE,
1228 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1229 &reg_val);
8c99e7b0 1230 if (vars->line_speed == SPEED_AUTO_NEG) {
ea4e040a
YR
1231 /* Enable BAM aneg Mode and TetonII aneg Mode */
1232 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1233 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1234 } else {
1235 /* TetonII and BAM Autoneg Disabled */
1236 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1237 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1238 }
e10bc84d 1239 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1240 MDIO_REG_BANK_BAM_NEXT_PAGE,
1241 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1242 reg_val);
1243
239d686d
EG
1244 if (enable_cl73) {
1245 /* Enable Cl73 FSM status bits */
e10bc84d 1246 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1247 MDIO_REG_BANK_CL73_USERB0,
1248 MDIO_CL73_USERB0_CL73_UCTRL,
7846e471 1249 0xe);
239d686d
EG
1250
1251 /* Enable BAM Station Manager*/
e10bc84d 1252 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1253 MDIO_REG_BANK_CL73_USERB0,
1254 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1255 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1256 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1257 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
1258
7846e471 1259 /* Advertise CL73 link speeds */
e10bc84d 1260 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1261 MDIO_REG_BANK_CL73_IEEEB1,
1262 MDIO_CL73_IEEEB1_AN_ADV2,
1263 &reg_val);
7846e471
YR
1264 if (params->speed_cap_mask &
1265 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1266 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1267 if (params->speed_cap_mask &
1268 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
1269 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
239d686d 1270
e10bc84d 1271 CL45_WR_OVER_CL22(bp, phy,
cc81735e
JL
1272 MDIO_REG_BANK_CL73_IEEEB1,
1273 MDIO_CL73_IEEEB1_AN_ADV2,
1274 reg_val);
239d686d 1275
239d686d
EG
1276 /* CL73 Autoneg Enabled */
1277 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1278
1279 } else /* CL73 Autoneg Disabled */
1280 reg_val = 0;
ea4e040a 1281
e10bc84d 1282 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1283 MDIO_REG_BANK_CL73_IEEEB0,
1284 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1285}
1286
1287/* program SerDes, forced speed */
e10bc84d
YR
1288static void bnx2x_program_serdes(struct bnx2x_phy *phy,
1289 struct link_params *params,
8c99e7b0 1290 struct link_vars *vars)
ea4e040a
YR
1291{
1292 struct bnx2x *bp = params->bp;
1293 u16 reg_val;
1294
57937203 1295 /* program duplex, disable autoneg and sgmii*/
e10bc84d 1296 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1297 MDIO_REG_BANK_COMBO_IEEE0,
1298 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1299 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
57937203
EG
1300 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1301 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
ea4e040a
YR
1302 if (params->req_duplex == DUPLEX_FULL)
1303 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
e10bc84d 1304 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1305 MDIO_REG_BANK_COMBO_IEEE0,
1306 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1307
1308 /* program speed
1309 - needed only if the speed is greater than 1G (2.5G or 10G) */
e10bc84d 1310 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1311 MDIO_REG_BANK_SERDES_DIGITAL,
1312 MDIO_SERDES_DIGITAL_MISC1, &reg_val);
8c99e7b0
YR
1313 /* clearing the speed value before setting the right speed */
1314 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1315
1316 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1317 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1318
1319 if (!((vars->line_speed == SPEED_1000) ||
1320 (vars->line_speed == SPEED_100) ||
1321 (vars->line_speed == SPEED_10))) {
1322
ea4e040a
YR
1323 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1324 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
8c99e7b0 1325 if (vars->line_speed == SPEED_10000)
ea4e040a
YR
1326 reg_val |=
1327 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
8c99e7b0 1328 if (vars->line_speed == SPEED_13000)
ea4e040a
YR
1329 reg_val |=
1330 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
8c99e7b0
YR
1331 }
1332
e10bc84d 1333 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1334 MDIO_REG_BANK_SERDES_DIGITAL,
1335 MDIO_SERDES_DIGITAL_MISC1, reg_val);
8c99e7b0 1336
ea4e040a
YR
1337}
1338
e10bc84d
YR
1339static void bnx2x_set_brcm_cl37_advertisment(struct bnx2x_phy *phy,
1340 struct link_params *params)
ea4e040a
YR
1341{
1342 struct bnx2x *bp = params->bp;
1343 u16 val = 0;
1344
1345 /* configure the 48 bits for BAM AN */
1346
1347 /* set extended capabilities */
1348 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1349 val |= MDIO_OVER_1G_UP1_2_5G;
1350 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1351 val |= MDIO_OVER_1G_UP1_10G;
e10bc84d 1352 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1353 MDIO_REG_BANK_OVER_1G,
1354 MDIO_OVER_1G_UP1, val);
1355
e10bc84d 1356 CL45_WR_OVER_CL22(bp, phy,
ea4e040a 1357 MDIO_REG_BANK_OVER_1G,
239d686d 1358 MDIO_OVER_1G_UP3, 0x400);
ea4e040a
YR
1359}
1360
e10bc84d
YR
1361static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
1362 struct link_params *params, u16 *ieee_fc)
ea4e040a 1363{
d5cb9e99 1364 struct bnx2x *bp = params->bp;
8c99e7b0 1365 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
ea4e040a
YR
1366 /* resolve pause mode and advertisement
1367 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1368
1369 switch (params->req_flow_ctrl) {
c0700f90
DM
1370 case BNX2X_FLOW_CTRL_AUTO:
1371 if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
8c99e7b0 1372 *ieee_fc |=
ea4e040a
YR
1373 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1374 } else {
8c99e7b0 1375 *ieee_fc |=
ea4e040a
YR
1376 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1377 }
1378 break;
c0700f90 1379 case BNX2X_FLOW_CTRL_TX:
8c99e7b0 1380 *ieee_fc |=
ea4e040a
YR
1381 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1382 break;
1383
c0700f90
DM
1384 case BNX2X_FLOW_CTRL_RX:
1385 case BNX2X_FLOW_CTRL_BOTH:
8c99e7b0 1386 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
ea4e040a
YR
1387 break;
1388
c0700f90 1389 case BNX2X_FLOW_CTRL_NONE:
ea4e040a 1390 default:
8c99e7b0 1391 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
ea4e040a
YR
1392 break;
1393 }
d5cb9e99 1394 DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
8c99e7b0 1395}
ea4e040a 1396
e10bc84d
YR
1397static void bnx2x_set_ieee_aneg_advertisment(struct bnx2x_phy *phy,
1398 struct link_params *params,
1ef70b9c 1399 u16 ieee_fc)
8c99e7b0
YR
1400{
1401 struct bnx2x *bp = params->bp;
7846e471 1402 u16 val;
8c99e7b0 1403 /* for AN, we are always publishing full duplex */
ea4e040a 1404
e10bc84d 1405 CL45_WR_OVER_CL22(bp, phy,
ea4e040a 1406 MDIO_REG_BANK_COMBO_IEEE0,
1ef70b9c 1407 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
e10bc84d 1408 CL45_RD_OVER_CL22(bp, phy,
7846e471
YR
1409 MDIO_REG_BANK_CL73_IEEEB1,
1410 MDIO_CL73_IEEEB1_AN_ADV1, &val);
1411 val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
1412 val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
e10bc84d 1413 CL45_WR_OVER_CL22(bp, phy,
7846e471
YR
1414 MDIO_REG_BANK_CL73_IEEEB1,
1415 MDIO_CL73_IEEEB1_AN_ADV1, val);
ea4e040a
YR
1416}
1417
e10bc84d
YR
1418static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
1419 struct link_params *params,
1420 u8 enable_cl73)
ea4e040a
YR
1421{
1422 struct bnx2x *bp = params->bp;
3a36f2ef 1423 u16 mii_control;
239d686d 1424
ea4e040a 1425 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
3a36f2ef 1426 /* Enable and restart BAM/CL37 aneg */
ea4e040a 1427
239d686d 1428 if (enable_cl73) {
e10bc84d 1429 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1430 MDIO_REG_BANK_CL73_IEEEB0,
1431 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1432 &mii_control);
1433
e10bc84d 1434 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1435 MDIO_REG_BANK_CL73_IEEEB0,
1436 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1437 (mii_control |
1438 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1439 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1440 } else {
1441
e10bc84d 1442 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1443 MDIO_REG_BANK_COMBO_IEEE0,
1444 MDIO_COMBO_IEEE0_MII_CONTROL,
1445 &mii_control);
1446 DP(NETIF_MSG_LINK,
1447 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1448 mii_control);
e10bc84d 1449 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1450 MDIO_REG_BANK_COMBO_IEEE0,
1451 MDIO_COMBO_IEEE0_MII_CONTROL,
1452 (mii_control |
1453 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1454 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1455 }
ea4e040a
YR
1456}
1457
e10bc84d
YR
1458static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
1459 struct link_params *params,
8c99e7b0 1460 struct link_vars *vars)
ea4e040a
YR
1461{
1462 struct bnx2x *bp = params->bp;
1463 u16 control1;
1464
1465 /* in SGMII mode, the unicore is always slave */
1466
e10bc84d 1467 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1468 MDIO_REG_BANK_SERDES_DIGITAL,
1469 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1470 &control1);
1471 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1472 /* set sgmii mode (and not fiber) */
1473 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1474 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1475 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
e10bc84d 1476 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1477 MDIO_REG_BANK_SERDES_DIGITAL,
1478 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1479 control1);
1480
1481 /* if forced speed */
8c99e7b0 1482 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
ea4e040a
YR
1483 /* set speed, disable autoneg */
1484 u16 mii_control;
1485
e10bc84d 1486 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1487 MDIO_REG_BANK_COMBO_IEEE0,
1488 MDIO_COMBO_IEEE0_MII_CONTROL,
1489 &mii_control);
1490 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1491 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1492 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1493
8c99e7b0 1494 switch (vars->line_speed) {
ea4e040a
YR
1495 case SPEED_100:
1496 mii_control |=
1497 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1498 break;
1499 case SPEED_1000:
1500 mii_control |=
1501 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1502 break;
1503 case SPEED_10:
1504 /* there is nothing to set for 10M */
1505 break;
1506 default:
1507 /* invalid speed for SGMII */
8c99e7b0
YR
1508 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1509 vars->line_speed);
ea4e040a
YR
1510 break;
1511 }
1512
1513 /* setting the full duplex */
1514 if (params->req_duplex == DUPLEX_FULL)
1515 mii_control |=
1516 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
e10bc84d 1517 CL45_WR_OVER_CL22(bp, phy,
ea4e040a
YR
1518 MDIO_REG_BANK_COMBO_IEEE0,
1519 MDIO_COMBO_IEEE0_MII_CONTROL,
1520 mii_control);
1521
1522 } else { /* AN mode */
1523 /* enable and restart AN */
e10bc84d 1524 bnx2x_restart_autoneg(phy, params, 0);
ea4e040a
YR
1525 }
1526}
1527
1528
1529/*
1530 * link management
1531 */
1532
1533static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
8c99e7b0
YR
1534{ /* LD LP */
1535 switch (pause_result) { /* ASYM P ASYM P */
1536 case 0xb: /* 1 0 1 1 */
c0700f90 1537 vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
ea4e040a
YR
1538 break;
1539
8c99e7b0 1540 case 0xe: /* 1 1 1 0 */
c0700f90 1541 vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
ea4e040a
YR
1542 break;
1543
8c99e7b0
YR
1544 case 0x5: /* 0 1 0 1 */
1545 case 0x7: /* 0 1 1 1 */
1546 case 0xd: /* 1 1 0 1 */
1547 case 0xf: /* 1 1 1 1 */
c0700f90 1548 vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
ea4e040a
YR
1549 break;
1550
1551 default:
1552 break;
1553 }
1554}
1555
e10bc84d
YR
1556static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
1557 struct link_params *params,
1558 struct link_vars *vars)
ea4e040a
YR
1559{
1560 struct bnx2x *bp = params->bp;
ab6ad5a4
EG
1561 u16 ld_pause; /* local */
1562 u16 lp_pause; /* link partner */
1563 u16 an_complete; /* AN complete */
ea4e040a
YR
1564 u16 pause_result;
1565 u8 ret = 0;
ea4e040a
YR
1566 /* read twice */
1567
e10bc84d 1568 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
1569 MDIO_AN_DEVAD,
1570 MDIO_AN_REG_STATUS, &an_complete);
e10bc84d 1571 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
1572 MDIO_AN_DEVAD,
1573 MDIO_AN_REG_STATUS, &an_complete);
1574
1575 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1576 ret = 1;
e10bc84d 1577 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
1578 MDIO_AN_DEVAD,
1579 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
e10bc84d 1580 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
1581 MDIO_AN_DEVAD,
1582 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1583 pause_result = (ld_pause &
1584 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1585 pause_result |= (lp_pause &
1586 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
2381a55c 1587 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
ea4e040a
YR
1588 pause_result);
1589 bnx2x_pause_resolve(vars, pause_result);
c0700f90 1590 if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
e10bc84d
YR
1591 phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1592 bnx2x_cl45_read(bp, phy,
8c99e7b0
YR
1593 MDIO_AN_DEVAD,
1594 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1595
e10bc84d 1596 bnx2x_cl45_read(bp, phy,
8c99e7b0
YR
1597 MDIO_AN_DEVAD,
1598 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1599 pause_result = (ld_pause &
1600 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1601 pause_result |= (lp_pause &
1602 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1603
1604 bnx2x_pause_resolve(vars, pause_result);
2381a55c 1605 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
8c99e7b0
YR
1606 pause_result);
1607 }
ea4e040a
YR
1608 }
1609 return ret;
1610}
1611
e10bc84d
YR
1612static u8 bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
1613 struct link_params *params)
15ddd2d0
YR
1614{
1615 struct bnx2x *bp = params->bp;
1616 u16 pd_10g, status2_1000x;
e10bc84d 1617 CL45_RD_OVER_CL22(bp, phy,
15ddd2d0
YR
1618 MDIO_REG_BANK_SERDES_DIGITAL,
1619 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1620 &status2_1000x);
e10bc84d 1621 CL45_RD_OVER_CL22(bp, phy,
15ddd2d0
YR
1622 MDIO_REG_BANK_SERDES_DIGITAL,
1623 MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
1624 &status2_1000x);
1625 if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
1626 DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
1627 params->port);
1628 return 1;
1629 }
1630
e10bc84d 1631 CL45_RD_OVER_CL22(bp, phy,
15ddd2d0
YR
1632 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1633 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
1634 &pd_10g);
1635
1636 if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
1637 DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
1638 params->port);
1639 return 1;
1640 }
1641 return 0;
1642}
ea4e040a 1643
e10bc84d
YR
1644static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
1645 struct link_params *params,
1646 struct link_vars *vars,
1647 u32 gp_status)
ea4e040a
YR
1648{
1649 struct bnx2x *bp = params->bp;
3196a88a
EG
1650 u16 ld_pause; /* local driver */
1651 u16 lp_pause; /* link partner */
ea4e040a
YR
1652 u16 pause_result;
1653
c0700f90 1654 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
1655
1656 /* resolve from gp_status in case of AN complete and not sgmii */
c0700f90 1657 if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
ea4e040a
YR
1658 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1659 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
e10bc84d
YR
1660 (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1661 if (bnx2x_direct_parallel_detect_used(phy, params)) {
15ddd2d0
YR
1662 vars->flow_ctrl = params->req_fc_auto_adv;
1663 return;
1664 }
7846e471
YR
1665 if ((gp_status &
1666 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1667 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
1668 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
1669 MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
1670
e10bc84d 1671 CL45_RD_OVER_CL22(bp, phy,
7846e471
YR
1672 MDIO_REG_BANK_CL73_IEEEB1,
1673 MDIO_CL73_IEEEB1_AN_ADV1,
1674 &ld_pause);
e10bc84d 1675 CL45_RD_OVER_CL22(bp, phy,
7846e471
YR
1676 MDIO_REG_BANK_CL73_IEEEB1,
1677 MDIO_CL73_IEEEB1_AN_LP_ADV1,
1678 &lp_pause);
1679 pause_result = (ld_pause &
1680 MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
1681 >> 8;
1682 pause_result |= (lp_pause &
1683 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
1684 >> 10;
1685 DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
1686 pause_result);
1687 } else {
e10bc84d 1688 CL45_RD_OVER_CL22(bp, phy,
7846e471
YR
1689 MDIO_REG_BANK_COMBO_IEEE0,
1690 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1691 &ld_pause);
e10bc84d 1692 CL45_RD_OVER_CL22(bp, phy,
7846e471
YR
1693 MDIO_REG_BANK_COMBO_IEEE0,
1694 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1695 &lp_pause);
1696 pause_result = (ld_pause &
ea4e040a 1697 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
7846e471 1698 pause_result |= (lp_pause &
ea4e040a 1699 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
7846e471
YR
1700 DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
1701 pause_result);
1702 }
ea4e040a 1703 bnx2x_pause_resolve(vars, pause_result);
c0700f90 1704 } else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
e10bc84d 1705 (bnx2x_ext_phy_resolve_fc(phy, params, vars))) {
ea4e040a
YR
1706 return;
1707 } else {
c0700f90 1708 if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
8c99e7b0
YR
1709 vars->flow_ctrl = params->req_fc_auto_adv;
1710 else
1711 vars->flow_ctrl = params->req_flow_ctrl;
ea4e040a
YR
1712 }
1713 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1714}
1715
e10bc84d
YR
1716static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
1717 struct link_params *params)
239d686d
EG
1718{
1719 struct bnx2x *bp = params->bp;
1720 u16 rx_status, ustat_val, cl37_fsm_recieved;
1721 DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
1722 /* Step 1: Make sure signal is detected */
e10bc84d 1723 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1724 MDIO_REG_BANK_RX0,
1725 MDIO_RX0_RX_STATUS,
1726 &rx_status);
1727 if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
1728 (MDIO_RX0_RX_STATUS_SIGDET)) {
1729 DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
1730 "rx_status(0x80b0) = 0x%x\n", rx_status);
e10bc84d 1731 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1732 MDIO_REG_BANK_CL73_IEEEB0,
1733 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1734 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
1735 return;
1736 }
1737 /* Step 2: Check CL73 state machine */
e10bc84d 1738 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1739 MDIO_REG_BANK_CL73_USERB0,
1740 MDIO_CL73_USERB0_CL73_USTAT1,
1741 &ustat_val);
1742 if ((ustat_val &
1743 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1744 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
1745 (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
1746 MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
1747 DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
1748 "ustat_val(0x8371) = 0x%x\n", ustat_val);
1749 return;
1750 }
1751 /* Step 3: Check CL37 Message Pages received to indicate LP
1752 supports only CL37 */
e10bc84d 1753 CL45_RD_OVER_CL22(bp, phy,
239d686d
EG
1754 MDIO_REG_BANK_REMOTE_PHY,
1755 MDIO_REMOTE_PHY_MISC_RX_STATUS,
1756 &cl37_fsm_recieved);
1757 if ((cl37_fsm_recieved &
1758 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1759 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
1760 (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
1761 MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
1762 DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
1763 "misc_rx_status(0x8330) = 0x%x\n",
1764 cl37_fsm_recieved);
1765 return;
1766 }
1767 /* The combined cl37/cl73 fsm state information indicating that we are
1768 connected to a device which does not support cl73, but does support
1769 cl37 BAM. In this case we disable cl73 and restart cl37 auto-neg */
1770 /* Disable CL73 */
e10bc84d 1771 CL45_WR_OVER_CL22(bp, phy,
239d686d
EG
1772 MDIO_REG_BANK_CL73_IEEEB0,
1773 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1774 0);
1775 /* Restart CL37 autoneg */
e10bc84d 1776 bnx2x_restart_autoneg(phy, params, 0);
239d686d
EG
1777 DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
1778}
b7737c9b
YR
1779static u8 bnx2x_link_settings_status(struct bnx2x_phy *phy,
1780 struct link_params *params,
1781 struct link_vars *vars)
ea4e040a
YR
1782{
1783 struct bnx2x *bp = params->bp;
b7737c9b 1784 u16 new_line_speed , gp_status;
ea4e040a 1785 u8 rc = 0;
e10bc84d 1786 u32 ext_phy_type;
b7737c9b
YR
1787 /* Read gp_status */
1788 CL45_RD_OVER_CL22(bp, phy,
1789 MDIO_REG_BANK_GP_STATUS,
1790 MDIO_GP_STATUS_TOP_AN_STATUS1,
1791 &gp_status);
1792
ea4e040a
YR
1793 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1794 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1795 gp_status);
1796
1797 vars->phy_link_up = 1;
1798 vars->link_status |= LINK_STATUS_LINK_UP;
1799
1800 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1801 vars->duplex = DUPLEX_FULL;
1802 else
1803 vars->duplex = DUPLEX_HALF;
1804
e10bc84d
YR
1805 bnx2x_flow_ctrl_resolve(&params->phy[INT_PHY],
1806 params, vars, gp_status);
ea4e040a
YR
1807
1808 switch (gp_status & GP_STATUS_SPEED_MASK) {
1809 case GP_STATUS_10M:
6c55c3cd 1810 new_line_speed = SPEED_10;
ea4e040a
YR
1811 if (vars->duplex == DUPLEX_FULL)
1812 vars->link_status |= LINK_10TFD;
1813 else
1814 vars->link_status |= LINK_10THD;
1815 break;
1816
1817 case GP_STATUS_100M:
6c55c3cd 1818 new_line_speed = SPEED_100;
ea4e040a
YR
1819 if (vars->duplex == DUPLEX_FULL)
1820 vars->link_status |= LINK_100TXFD;
1821 else
1822 vars->link_status |= LINK_100TXHD;
1823 break;
1824
1825 case GP_STATUS_1G:
1826 case GP_STATUS_1G_KX:
6c55c3cd 1827 new_line_speed = SPEED_1000;
ea4e040a
YR
1828 if (vars->duplex == DUPLEX_FULL)
1829 vars->link_status |= LINK_1000TFD;
1830 else
1831 vars->link_status |= LINK_1000THD;
1832 break;
1833
1834 case GP_STATUS_2_5G:
6c55c3cd 1835 new_line_speed = SPEED_2500;
ea4e040a
YR
1836 if (vars->duplex == DUPLEX_FULL)
1837 vars->link_status |= LINK_2500TFD;
1838 else
1839 vars->link_status |= LINK_2500THD;
1840 break;
1841
1842 case GP_STATUS_5G:
1843 case GP_STATUS_6G:
1844 DP(NETIF_MSG_LINK,
1845 "link speed unsupported gp_status 0x%x\n",
1846 gp_status);
1847 return -EINVAL;
ab6ad5a4 1848
ea4e040a
YR
1849 case GP_STATUS_10G_KX4:
1850 case GP_STATUS_10G_HIG:
1851 case GP_STATUS_10G_CX4:
6c55c3cd 1852 new_line_speed = SPEED_10000;
ea4e040a
YR
1853 vars->link_status |= LINK_10GTFD;
1854 break;
1855
1856 case GP_STATUS_12G_HIG:
6c55c3cd 1857 new_line_speed = SPEED_12000;
ea4e040a
YR
1858 vars->link_status |= LINK_12GTFD;
1859 break;
1860
1861 case GP_STATUS_12_5G:
6c55c3cd 1862 new_line_speed = SPEED_12500;
ea4e040a
YR
1863 vars->link_status |= LINK_12_5GTFD;
1864 break;
1865
1866 case GP_STATUS_13G:
6c55c3cd 1867 new_line_speed = SPEED_13000;
ea4e040a
YR
1868 vars->link_status |= LINK_13GTFD;
1869 break;
1870
1871 case GP_STATUS_15G:
6c55c3cd 1872 new_line_speed = SPEED_15000;
ea4e040a
YR
1873 vars->link_status |= LINK_15GTFD;
1874 break;
1875
1876 case GP_STATUS_16G:
6c55c3cd 1877 new_line_speed = SPEED_16000;
ea4e040a
YR
1878 vars->link_status |= LINK_16GTFD;
1879 break;
1880
1881 default:
1882 DP(NETIF_MSG_LINK,
1883 "link speed unsupported gp_status 0x%x\n",
1884 gp_status);
ab6ad5a4 1885 return -EINVAL;
ea4e040a
YR
1886 }
1887
6c55c3cd 1888 vars->line_speed = new_line_speed;
ea4e040a 1889 vars->link_status |= LINK_STATUS_SERDES_LINK;
e10bc84d 1890 ext_phy_type = params->phy[EXT_PHY1].type;
57963ed9 1891 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
e10bc84d 1892 ((ext_phy_type ==
57963ed9 1893 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
e10bc84d 1894 (ext_phy_type ==
589abe3a 1895 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
e10bc84d 1896 (ext_phy_type ==
b5bbf008 1897 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
e10bc84d 1898 (ext_phy_type ==
2f904460 1899 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726))) {
ea4e040a
YR
1900 vars->autoneg = AUTO_NEG_ENABLED;
1901
1902 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1903 vars->autoneg |= AUTO_NEG_COMPLETE;
1904 vars->link_status |=
1905 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1906 }
1907
1908 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1909 vars->link_status |=
1910 LINK_STATUS_PARALLEL_DETECTION_USED;
1911
1912 }
c0700f90 1913 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
8c99e7b0
YR
1914 vars->link_status |=
1915 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
ea4e040a 1916
c0700f90 1917 if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
8c99e7b0
YR
1918 vars->link_status |=
1919 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
ea4e040a 1920
e10bc84d 1921
ea4e040a
YR
1922 } else { /* link_down */
1923 DP(NETIF_MSG_LINK, "phy link down\n");
1924
1925 vars->phy_link_up = 0;
57963ed9 1926
ea4e040a 1927 vars->duplex = DUPLEX_FULL;
c0700f90 1928 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
1929 vars->autoneg = AUTO_NEG_DISABLED;
1930 vars->mac_type = MAC_TYPE_NONE;
239d686d
EG
1931
1932 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
e10bc84d 1933 (SINGLE_MEDIA_DIRECT(params))) {
239d686d 1934 /* Check signal is detected */
e10bc84d
YR
1935 bnx2x_check_fallback_to_cl37(&params->phy[INT_PHY],
1936 params);
239d686d 1937 }
ea4e040a
YR
1938 }
1939
2381a55c 1940 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x\n",
ea4e040a
YR
1941 gp_status, vars->phy_link_up, vars->line_speed);
1942 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1943 " autoneg 0x%x\n",
1944 vars->duplex,
1945 vars->flow_ctrl, vars->autoneg);
1946 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1947
1948 return rc;
1949}
1950
ed8680a7 1951static void bnx2x_set_gmii_tx_driver(struct link_params *params)
ea4e040a
YR
1952{
1953 struct bnx2x *bp = params->bp;
e10bc84d 1954 struct bnx2x_phy *phy = &params->phy[INT_PHY];
ea4e040a
YR
1955 u16 lp_up2;
1956 u16 tx_driver;
c2c8b03e 1957 u16 bank;
ea4e040a
YR
1958
1959 /* read precomp */
e10bc84d 1960 CL45_RD_OVER_CL22(bp, phy,
ea4e040a
YR
1961 MDIO_REG_BANK_OVER_1G,
1962 MDIO_OVER_1G_LP_UP2, &lp_up2);
1963
ea4e040a
YR
1964 /* bits [10:7] at lp_up2, positioned at [15:12] */
1965 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1966 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1967 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1968
c2c8b03e
EG
1969 if (lp_up2 == 0)
1970 return;
1971
1972 for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
1973 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
e10bc84d 1974 CL45_RD_OVER_CL22(bp, phy,
c2c8b03e
EG
1975 bank,
1976 MDIO_TX0_TX_DRIVER, &tx_driver);
1977
1978 /* replace tx_driver bits [15:12] */
1979 if (lp_up2 !=
1980 (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
1981 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1982 tx_driver |= lp_up2;
e10bc84d 1983 CL45_WR_OVER_CL22(bp, phy,
c2c8b03e
EG
1984 bank,
1985 MDIO_TX0_TX_DRIVER, tx_driver);
1986 }
ea4e040a
YR
1987 }
1988}
1989
1990static u8 bnx2x_emac_program(struct link_params *params,
b7737c9b 1991 struct link_vars *vars)
ea4e040a
YR
1992{
1993 struct bnx2x *bp = params->bp;
1994 u8 port = params->port;
1995 u16 mode = 0;
1996
1997 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1998 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1999 EMAC_REG_EMAC_MODE,
2000 (EMAC_MODE_25G_MODE |
2001 EMAC_MODE_PORT_MII_10M |
2002 EMAC_MODE_HALF_DUPLEX));
b7737c9b 2003 switch (vars->line_speed) {
ea4e040a
YR
2004 case SPEED_10:
2005 mode |= EMAC_MODE_PORT_MII_10M;
2006 break;
2007
2008 case SPEED_100:
2009 mode |= EMAC_MODE_PORT_MII;
2010 break;
2011
2012 case SPEED_1000:
2013 mode |= EMAC_MODE_PORT_GMII;
2014 break;
2015
2016 case SPEED_2500:
2017 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
2018 break;
2019
2020 default:
2021 /* 10G not valid for EMAC */
b7737c9b
YR
2022 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2023 vars->line_speed);
ea4e040a
YR
2024 return -EINVAL;
2025 }
2026
b7737c9b 2027 if (vars->duplex == DUPLEX_HALF)
ea4e040a
YR
2028 mode |= EMAC_MODE_HALF_DUPLEX;
2029 bnx2x_bits_en(bp,
2030 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
2031 mode);
2032
b7737c9b 2033 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
ea4e040a
YR
2034 return 0;
2035}
2036
b7737c9b
YR
2037static u8 bnx2x_init_serdes(struct bnx2x_phy *phy,
2038 struct link_params *params,
2039 struct link_vars *vars)
2040{
2041 u8 rc;
2042 vars->phy_flags |= PHY_SGMII_FLAG;
2043 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2044 bnx2x_set_aer_mmd(params, phy);
2045 rc = bnx2x_reset_unicore(params, phy, 1);
2046 /* reset the SerDes and wait for reset bit return low */
2047 if (rc != 0)
2048 return rc;
2049 bnx2x_set_aer_mmd(params, phy);
2050
2051 return rc;
2052}
2053
2054static u8 bnx2x_init_xgxs(struct bnx2x_phy *phy,
2055 struct link_params *params,
2056 struct link_vars *vars)
2057{
2058 u8 rc;
2059 vars->phy_flags = PHY_XGXS_FLAG;
2060 if ((phy->req_line_speed &&
2061 ((phy->req_line_speed == SPEED_100) ||
2062 (phy->req_line_speed == SPEED_10))) ||
2063 (!phy->req_line_speed &&
2064 (phy->speed_cap_mask >=
2065 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
2066 (phy->speed_cap_mask <
2067 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2068 ))
2069 vars->phy_flags |= PHY_SGMII_FLAG;
2070 else
2071 vars->phy_flags &= ~PHY_SGMII_FLAG;
2072
2073 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
2074 bnx2x_set_aer_mmd(params, phy);
2075 bnx2x_set_master_ln(params, phy);
2076
2077 rc = bnx2x_reset_unicore(params, phy, 0);
2078 /* reset the SerDes and wait for reset bit return low */
2079 if (rc != 0)
2080 return rc;
2081
2082 bnx2x_set_aer_mmd(params, phy);
e10bc84d 2083
b7737c9b
YR
2084 /* setting the masterLn_def again after the reset */
2085 bnx2x_set_master_ln(params, phy);
2086 bnx2x_set_swap_lanes(params, phy);
2087
2088 return rc;
2089}
ea4e040a 2090/*****************************************************************************/
17de50b7 2091/* External Phy section */
ea4e040a 2092/*****************************************************************************/
f57a6025 2093void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
ea4e040a
YR
2094{
2095 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
17de50b7 2096 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
ea4e040a
YR
2097 msleep(1);
2098 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
62b29a5d 2099 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
ea4e040a
YR
2100}
2101
a35da8db
EG
2102static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
2103 u32 shmem_base, u32 spirom_ver)
2104{
ab6ad5a4
EG
2105 DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
2106 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
a35da8db
EG
2107 REG_WR(bp, shmem_base +
2108 offsetof(struct shmem_region,
2109 port_mb[port].ext_phy_fw_version),
2110 spirom_ver);
2111}
2112
2113static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp, u8 port,
e10bc84d
YR
2114 struct bnx2x_phy *phy,
2115 u32 shmem_base)
a35da8db
EG
2116{
2117 u16 fw_ver1, fw_ver2;
ab6ad5a4 2118
e10bc84d 2119 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
a35da8db 2120 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
e10bc84d 2121 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
a35da8db
EG
2122 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2123 bnx2x_save_spirom_version(bp, port, shmem_base,
2124 (u32)(fw_ver1<<16 | fw_ver2));
2125}
2126
e10bc84d
YR
2127static void bnx2x_save_8481_spirom_version(struct bnx2x_phy *phy,
2128 struct link_params *params,
2129 u32 shmem_base)
b1607af5
EG
2130{
2131 u16 val, fw_ver1, fw_ver2, cnt;
e10bc84d
YR
2132 struct bnx2x *bp = params->bp;
2133
2134 /* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
b1607af5 2135 /* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
62b29a5d
YR
2136 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
2137 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
2138 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
2139 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
2140 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
b1607af5
EG
2141
2142 for (cnt = 0; cnt < 100; cnt++) {
62b29a5d 2143 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
b1607af5
EG
2144 if (val & 1)
2145 break;
2146 udelay(5);
2147 }
2148 if (cnt == 100) {
2149 DP(NETIF_MSG_LINK, "Unable to read 8481 phy fw version(1)\n");
e10bc84d 2150 bnx2x_save_spirom_version(bp, params->port,
b1607af5
EG
2151 shmem_base, 0);
2152 return;
2153 }
2154
2155
2156 /* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
62b29a5d
YR
2157 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
2158 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
2159 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
b1607af5 2160 for (cnt = 0; cnt < 100; cnt++) {
62b29a5d 2161 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
b1607af5
EG
2162 if (val & 1)
2163 break;
2164 udelay(5);
2165 }
2166 if (cnt == 100) {
62b29a5d
YR
2167 DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
2168 bnx2x_save_spirom_version(bp, params->port, 0,
2169 phy->ver_addr);
b1607af5
EG
2170 return;
2171 }
2172
2173 /* lower 16 bits of the register SPI_FW_STATUS */
62b29a5d 2174 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
b1607af5 2175 /* upper 16 bits of register SPI_FW_STATUS */
62b29a5d 2176 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
ea4e040a 2177
62b29a5d
YR
2178 bnx2x_save_spirom_version(bp, params->port, (fw_ver2<<16) | fw_ver1,
2179 phy->ver_addr);
ea4e040a
YR
2180}
2181
e10bc84d 2182static u8 bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
ea4e040a
YR
2183{
2184 /* This is only required for 8073A1, version 102 only */
ea4e040a
YR
2185 u16 val;
2186
2187 /* Read 8073 HW revision*/
e10bc84d 2188 bnx2x_cl45_read(bp, phy,
ea4e040a 2189 MDIO_PMA_DEVAD,
052a38e0 2190 MDIO_PMA_REG_8073_CHIP_REV, &val);
ea4e040a
YR
2191
2192 if (val != 1) {
2193 /* No need to workaround in 8073 A1 */
2194 return 0;
2195 }
2196
e10bc84d 2197 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
2198 MDIO_PMA_DEVAD,
2199 MDIO_PMA_REG_ROM_VER2, &val);
2200
2201 /* SNR should be applied only for version 0x102 */
2202 if (val != 0x102)
2203 return 0;
2204
2205 return 1;
2206}
e10bc84d 2207static u8 bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
ea4e040a 2208{
ea4e040a
YR
2209 u16 val, cnt, cnt1 ;
2210
e10bc84d 2211 bnx2x_cl45_read(bp, phy,
ea4e040a 2212 MDIO_PMA_DEVAD,
052a38e0 2213 MDIO_PMA_REG_8073_CHIP_REV, &val);
ea4e040a
YR
2214
2215 if (val > 0) {
2216 /* No need to workaround in 8073 A1 */
2217 return 0;
2218 }
2219 /* XAUI workaround in 8073 A0: */
2220
2221 /* After loading the boot ROM and restarting Autoneg,
2222 poll Dev1, Reg $C820: */
2223
2224 for (cnt = 0; cnt < 1000; cnt++) {
e10bc84d 2225 bnx2x_cl45_read(bp, phy,
ea4e040a 2226 MDIO_PMA_DEVAD,
052a38e0
EG
2227 MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
2228 &val);
ea4e040a
YR
2229 /* If bit [14] = 0 or bit [13] = 0, continue on with
2230 system initialization (XAUI work-around not required,
2231 as these bits indicate 2.5G or 1G link up). */
2232 if (!(val & (1<<14)) || !(val & (1<<13))) {
2233 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2234 return 0;
2235 } else if (!(val & (1<<15))) {
2236 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2237 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2238 it's MSB (bit 15) goes to 1 (indicating that the
2239 XAUI workaround has completed),
2240 then continue on with system initialization.*/
2241 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
e10bc84d 2242 bnx2x_cl45_read(bp, phy,
ea4e040a 2243 MDIO_PMA_DEVAD,
052a38e0 2244 MDIO_PMA_REG_8073_XAUI_WA, &val);
ea4e040a
YR
2245 if (val & (1<<15)) {
2246 DP(NETIF_MSG_LINK,
2247 "XAUI workaround has completed\n");
2248 return 0;
2249 }
2250 msleep(3);
2251 }
2252 break;
2253 }
2254 msleep(3);
2255 }
2256 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2257 return -EINVAL;
ea4e040a
YR
2258}
2259
e10bc84d
YR
2260static void bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
2261 struct bnx2x_phy *phy,
2262 u8 port, u32 shmem_base)
ea4e040a 2263{
6bbca910 2264 /* Boot port from external ROM */
ea4e040a 2265 /* EDC grst */
e10bc84d 2266 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2267 MDIO_PMA_DEVAD,
2268 MDIO_PMA_REG_GEN_CTRL,
2269 0x0001);
2270
2271 /* ucode reboot and rst */
e10bc84d 2272 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2273 MDIO_PMA_DEVAD,
2274 MDIO_PMA_REG_GEN_CTRL,
2275 0x008c);
2276
e10bc84d 2277 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2278 MDIO_PMA_DEVAD,
2279 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2280
2281 /* Reset internal microprocessor */
e10bc84d 2282 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2283 MDIO_PMA_DEVAD,
2284 MDIO_PMA_REG_GEN_CTRL,
2285 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2286
2287 /* Release srst bit */
e10bc84d 2288 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2289 MDIO_PMA_DEVAD,
2290 MDIO_PMA_REG_GEN_CTRL,
2291 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2292
8ca60a68
YR
2293 /* wait for 120ms for code download via SPI port */
2294 msleep(120);
ea4e040a
YR
2295
2296 /* Clear ser_boot_ctl bit */
e10bc84d 2297 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2298 MDIO_PMA_DEVAD,
2299 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
e10bc84d 2300 bnx2x_save_bcm_spirom_ver(bp, port, phy, shmem_base);
6bbca910 2301}
ea4e040a 2302
e10bc84d
YR
2303static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
2304 struct link_params *params)
589abe3a
EG
2305{
2306 struct bnx2x *bp = params->bp;
589abe3a
EG
2307 /* Need to wait 100ms after reset */
2308 msleep(100);
2309
589abe3a 2310 /* Micro controller re-boot */
e10bc84d 2311 bnx2x_cl45_write(bp, phy,
62b29a5d 2312 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
589abe3a
EG
2313
2314 /* Set soft reset */
e10bc84d 2315 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2316 MDIO_PMA_DEVAD,
2317 MDIO_PMA_REG_GEN_CTRL,
2318 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2319
e10bc84d 2320 bnx2x_cl45_write(bp, phy,
cc1cb004 2321 MDIO_PMA_DEVAD,
93f72884 2322 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
cc1cb004 2323
e10bc84d 2324 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2325 MDIO_PMA_DEVAD,
2326 MDIO_PMA_REG_GEN_CTRL,
2327 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2328
cc1cb004
EG
2329 /* wait for 150ms for microcode load */
2330 msleep(150);
589abe3a
EG
2331
2332 /* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
e10bc84d 2333 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2334 MDIO_PMA_DEVAD,
2335 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2336
2337 msleep(200);
e10bc84d
YR
2338 bnx2x_save_bcm_spirom_ver(bp, params->port,
2339 phy,
a35da8db 2340 params->shmem_base);
589abe3a
EG
2341}
2342
e10bc84d
YR
2343static void bnx2x_sfp_set_transmitter(struct bnx2x *bp,
2344 struct bnx2x_phy *phy,
b7737c9b 2345 u8 port,
e10bc84d 2346 u8 tx_en)
589abe3a
EG
2347{
2348 u16 val;
ab6ad5a4 2349
b7737c9b
YR
2350 DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
2351 tx_en, port);
589abe3a 2352 /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
e10bc84d 2353 bnx2x_cl45_read(bp, phy,
589abe3a
EG
2354 MDIO_PMA_DEVAD,
2355 MDIO_PMA_REG_PHY_IDENTIFIER,
2356 &val);
2357
2358 if (tx_en)
2359 val &= ~(1<<15);
2360 else
2361 val |= (1<<15);
2362
e10bc84d 2363 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2364 MDIO_PMA_DEVAD,
2365 MDIO_PMA_REG_PHY_IDENTIFIER,
2366 val);
2367}
2368
e10bc84d
YR
2369static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2370 struct link_params *params,
4d295db0
EG
2371 u16 addr, u8 byte_cnt, u8 *o_buf)
2372{
589abe3a 2373 struct bnx2x *bp = params->bp;
4d295db0
EG
2374 u16 val = 0;
2375 u16 i;
589abe3a
EG
2376 if (byte_cnt > 16) {
2377 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2378 " is limited to 0xf\n");
2379 return -EINVAL;
2380 }
2381 /* Set the read command byte count */
e10bc84d
YR
2382 bnx2x_cl45_write(bp, phy,
2383 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
589abe3a
EG
2384 (byte_cnt | 0xa000));
2385
2386 /* Set the read command address */
e10bc84d
YR
2387 bnx2x_cl45_write(bp, phy,
2388 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
589abe3a
EG
2389 addr);
2390
2391 /* Activate read command */
e10bc84d
YR
2392 bnx2x_cl45_write(bp, phy,
2393 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
589abe3a
EG
2394 0x2c0f);
2395
2396 /* Wait up to 500us for command complete status */
2397 for (i = 0; i < 100; i++) {
e10bc84d 2398 bnx2x_cl45_read(bp, phy,
589abe3a 2399 MDIO_PMA_DEVAD,
4d295db0
EG
2400 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2401 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2402 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
589abe3a
EG
2403 break;
2404 udelay(5);
2405 }
2406
4d295db0
EG
2407 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2408 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
589abe3a
EG
2409 DP(NETIF_MSG_LINK,
2410 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
4d295db0 2411 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
589abe3a
EG
2412 return -EINVAL;
2413 }
2414
2415 /* Read the buffer */
2416 for (i = 0; i < byte_cnt; i++) {
e10bc84d 2417 bnx2x_cl45_read(bp, phy,
589abe3a
EG
2418 MDIO_PMA_DEVAD,
2419 MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
2420 o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
2421 }
2422
2423 for (i = 0; i < 100; i++) {
e10bc84d 2424 bnx2x_cl45_read(bp, phy,
589abe3a 2425 MDIO_PMA_DEVAD,
4d295db0
EG
2426 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2427 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2428 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
e10bc84d 2429 return 0;
4d295db0
EG
2430 msleep(1);
2431 }
2432 return -EINVAL;
2433}
2434
e10bc84d
YR
2435static u8 bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2436 struct link_params *params,
4d295db0
EG
2437 u16 addr, u8 byte_cnt, u8 *o_buf)
2438{
2439 struct bnx2x *bp = params->bp;
2440 u16 val, i;
4d295db0
EG
2441
2442 if (byte_cnt > 16) {
2443 DP(NETIF_MSG_LINK, "Reading from eeprom is"
2444 " is limited to 0xf\n");
2445 return -EINVAL;
2446 }
2447
2448 /* Need to read from 1.8000 to clear it */
e10bc84d 2449 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2450 MDIO_PMA_DEVAD,
2451 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2452 &val);
2453
2454 /* Set the read command byte count */
e10bc84d 2455 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2456 MDIO_PMA_DEVAD,
2457 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
2458 ((byte_cnt < 2) ? 2 : byte_cnt));
2459
2460 /* Set the read command address */
e10bc84d 2461 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2462 MDIO_PMA_DEVAD,
2463 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
2464 addr);
2465 /* Set the destination address */
e10bc84d 2466 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2467 MDIO_PMA_DEVAD,
2468 0x8004,
2469 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
2470
2471 /* Activate read command */
e10bc84d 2472 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2473 MDIO_PMA_DEVAD,
2474 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
2475 0x8002);
2476 /* Wait appropriate time for two-wire command to finish before
2477 polling the status register */
2478 msleep(1);
2479
2480 /* Wait up to 500us for command complete status */
2481 for (i = 0; i < 100; i++) {
e10bc84d 2482 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2483 MDIO_PMA_DEVAD,
2484 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2485 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2486 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
2487 break;
2488 udelay(5);
2489 }
2490
2491 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
2492 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
2493 DP(NETIF_MSG_LINK,
2494 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
2495 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
2496 return -EINVAL;
2497 }
2498
2499 /* Read the buffer */
2500 for (i = 0; i < byte_cnt; i++) {
e10bc84d 2501 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2502 MDIO_PMA_DEVAD,
2503 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
2504 o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
2505 }
2506
2507 for (i = 0; i < 100; i++) {
e10bc84d 2508 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2509 MDIO_PMA_DEVAD,
2510 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
2511 if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
2512 MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
589abe3a
EG
2513 return 0;;
2514 msleep(1);
2515 }
4d295db0 2516
589abe3a
EG
2517 return -EINVAL;
2518}
2519
e10bc84d
YR
2520u8 bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
2521 struct link_params *params, u16 addr,
4d295db0
EG
2522 u8 byte_cnt, u8 *o_buf)
2523{
e10bc84d
YR
2524 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2525 return bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
4d295db0 2526 byte_cnt, o_buf);
e10bc84d
YR
2527 else if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
2528 return bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
4d295db0
EG
2529 byte_cnt, o_buf);
2530 return -EINVAL;
2531}
589abe3a 2532
e10bc84d
YR
2533static u8 bnx2x_get_edc_mode(struct bnx2x_phy *phy,
2534 struct link_params *params,
4d295db0 2535 u16 *edc_mode)
589abe3a
EG
2536{
2537 struct bnx2x *bp = params->bp;
4d295db0
EG
2538 u8 val, check_limiting_mode = 0;
2539 *edc_mode = EDC_MODE_LIMITING;
589abe3a
EG
2540
2541 /* First check for copper cable */
62b29a5d
YR
2542 if (bnx2x_read_sfp_module_eeprom(phy,
2543 params,
2544 SFP_EEPROM_CON_TYPE_ADDR,
2545 1,
2546 &val) != 0) {
4d295db0 2547 DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
589abe3a
EG
2548 return -EINVAL;
2549 }
2550
2551 switch (val) {
2552 case SFP_EEPROM_CON_TYPE_VAL_COPPER:
2553 {
2554 u8 copper_module_type;
ab6ad5a4 2555
589abe3a
EG
2556 /* Check if its active cable( includes SFP+ module)
2557 of passive cable*/
62b29a5d
YR
2558 if (bnx2x_read_sfp_module_eeprom(phy,
2559 params,
589abe3a
EG
2560 SFP_EEPROM_FC_TX_TECH_ADDR,
2561 1,
2562 &copper_module_type) !=
2563 0) {
2564 DP(NETIF_MSG_LINK,
2565 "Failed to read copper-cable-type"
2566 " from SFP+ EEPROM\n");
2567 return -EINVAL;
2568 }
2569
2570 if (copper_module_type &
2571 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
2572 DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
4d295db0 2573 check_limiting_mode = 1;
589abe3a
EG
2574 } else if (copper_module_type &
2575 SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
2576 DP(NETIF_MSG_LINK, "Passive Copper"
2577 " cable detected\n");
4d295db0
EG
2578 *edc_mode =
2579 EDC_MODE_PASSIVE_DAC;
589abe3a
EG
2580 } else {
2581 DP(NETIF_MSG_LINK, "Unknown copper-cable-"
2582 "type 0x%x !!!\n", copper_module_type);
2583 return -EINVAL;
2584 }
2585 break;
2586 }
2587 case SFP_EEPROM_CON_TYPE_VAL_LC:
2588 DP(NETIF_MSG_LINK, "Optic module detected\n");
4d295db0 2589 check_limiting_mode = 1;
589abe3a 2590 break;
589abe3a
EG
2591 default:
2592 DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
2593 val);
2594 return -EINVAL;
2595 }
4d295db0
EG
2596
2597 if (check_limiting_mode) {
2598 u8 options[SFP_EEPROM_OPTIONS_SIZE];
62b29a5d
YR
2599 if (bnx2x_read_sfp_module_eeprom(phy,
2600 params,
2601 SFP_EEPROM_OPTIONS_ADDR,
2602 SFP_EEPROM_OPTIONS_SIZE,
2603 options) != 0) {
4d295db0
EG
2604 DP(NETIF_MSG_LINK, "Failed to read Option"
2605 " field from module EEPROM\n");
2606 return -EINVAL;
2607 }
2608 if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
2609 *edc_mode = EDC_MODE_LINEAR;
2610 else
2611 *edc_mode = EDC_MODE_LIMITING;
2612 }
2613 DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
589abe3a
EG
2614 return 0;
2615}
589abe3a
EG
2616/* This function read the relevant field from the module ( SFP+ ),
2617 and verify it is compliant with this board */
e10bc84d
YR
2618static u8 bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
2619 struct link_params *params)
589abe3a
EG
2620{
2621 struct bnx2x *bp = params->bp;
4d295db0
EG
2622 u32 val;
2623 u32 fw_resp;
2624 char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
2625 char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
2626
2627 val = REG_RD(bp, params->shmem_base +
2628 offsetof(struct shmem_region, dev_info.
2629 port_feature_config[params->port].config));
2630 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2631 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
589abe3a
EG
2632 DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
2633 return 0;
2634 }
2635
4d295db0
EG
2636 /* Ask the FW to validate the module */
2637 if (!(params->feature_config_flags &
2638 FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY)) {
2639 DP(NETIF_MSG_LINK, "FW does not support OPT MDL "
2640 "verification\n");
2641 return -EINVAL;
2642 }
2643
2644 fw_resp = bnx2x_fw_command(bp, DRV_MSG_CODE_VRFY_OPT_MDL);
2645 if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
2646 DP(NETIF_MSG_LINK, "Approved module\n");
589abe3a
EG
2647 return 0;
2648 }
2649
4d295db0 2650 /* format the warning message */
62b29a5d
YR
2651 if (bnx2x_read_sfp_module_eeprom(phy,
2652 params,
589abe3a
EG
2653 SFP_EEPROM_VENDOR_NAME_ADDR,
2654 SFP_EEPROM_VENDOR_NAME_SIZE,
4d295db0
EG
2655 (u8 *)vendor_name))
2656 vendor_name[0] = '\0';
2657 else
2658 vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
62b29a5d
YR
2659 if (bnx2x_read_sfp_module_eeprom(phy,
2660 params,
4d295db0
EG
2661 SFP_EEPROM_PART_NO_ADDR,
2662 SFP_EEPROM_PART_NO_SIZE,
2663 (u8 *)vendor_pn))
2664 vendor_pn[0] = '\0';
2665 else
2666 vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
589abe3a 2667
e10bc84d
YR
2668 netdev_info(bp->dev, "Warning: Unqualified SFP+ module detected,"
2669 " Port %d from %s part number %s\n",
7995c64e 2670 params->port, vendor_name, vendor_pn);
589abe3a
EG
2671 return -EINVAL;
2672}
2673
e10bc84d
YR
2674static u8 bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
2675 struct bnx2x_phy *phy,
62b29a5d 2676 u16 edc_mode)
589abe3a 2677{
cc1cb004 2678 u16 cur_limiting_mode;
cc1cb004 2679
e10bc84d 2680 bnx2x_cl45_read(bp, phy,
cc1cb004
EG
2681 MDIO_PMA_DEVAD,
2682 MDIO_PMA_REG_ROM_VER2,
2683 &cur_limiting_mode);
2684 DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
2685 cur_limiting_mode);
2686
4d295db0 2687 if (edc_mode == EDC_MODE_LIMITING) {
589abe3a 2688 DP(NETIF_MSG_LINK,
4d295db0 2689 "Setting LIMITING MODE\n");
e10bc84d 2690 bnx2x_cl45_write(bp, phy,
62b29a5d
YR
2691 MDIO_PMA_DEVAD,
2692 MDIO_PMA_REG_ROM_VER2,
2693 EDC_MODE_LIMITING);
589abe3a 2694 } else { /* LRM mode ( default )*/
cc1cb004 2695
4d295db0 2696 DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
589abe3a 2697
589abe3a
EG
2698 /* Changing to LRM mode takes quite few seconds.
2699 So do it only if current mode is limiting
2700 ( default is LRM )*/
4d295db0 2701 if (cur_limiting_mode != EDC_MODE_LIMITING)
589abe3a
EG
2702 return 0;
2703
e10bc84d 2704 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2705 MDIO_PMA_DEVAD,
2706 MDIO_PMA_REG_LRM_MODE,
2707 0);
e10bc84d 2708 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2709 MDIO_PMA_DEVAD,
2710 MDIO_PMA_REG_ROM_VER2,
2711 0x128);
e10bc84d 2712 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2713 MDIO_PMA_DEVAD,
2714 MDIO_PMA_REG_MISC_CTRL0,
2715 0x4008);
e10bc84d 2716 bnx2x_cl45_write(bp, phy,
589abe3a
EG
2717 MDIO_PMA_DEVAD,
2718 MDIO_PMA_REG_LRM_MODE,
2719 0xaaaa);
2720 }
2721 return 0;
2722}
2723
e10bc84d
YR
2724static u8 bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
2725 struct bnx2x_phy *phy,
4d295db0
EG
2726 u16 edc_mode)
2727{
4d295db0
EG
2728 u16 phy_identifier;
2729 u16 rom_ver2_val;
e10bc84d 2730 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2731 MDIO_PMA_DEVAD,
2732 MDIO_PMA_REG_PHY_IDENTIFIER,
2733 &phy_identifier);
2734
e10bc84d 2735 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2736 MDIO_PMA_DEVAD,
2737 MDIO_PMA_REG_PHY_IDENTIFIER,
2738 (phy_identifier & ~(1<<9)));
2739
e10bc84d 2740 bnx2x_cl45_read(bp, phy,
4d295db0
EG
2741 MDIO_PMA_DEVAD,
2742 MDIO_PMA_REG_ROM_VER2,
2743 &rom_ver2_val);
2744 /* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
e10bc84d 2745 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2746 MDIO_PMA_DEVAD,
2747 MDIO_PMA_REG_ROM_VER2,
2748 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
2749
e10bc84d 2750 bnx2x_cl45_write(bp, phy,
4d295db0
EG
2751 MDIO_PMA_DEVAD,
2752 MDIO_PMA_REG_PHY_IDENTIFIER,
2753 (phy_identifier | (1<<9)));
2754
2755 return 0;
2756}
2757
2758
e10bc84d
YR
2759static u8 bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
2760 struct link_params *params)
2761
589abe3a
EG
2762{
2763 u8 val;
2764 struct bnx2x *bp = params->bp;
2765 u16 timeout;
2766 /* Initialization time after hot-plug may take up to 300ms for some
2767 phys type ( e.g. JDSU ) */
2768 for (timeout = 0; timeout < 60; timeout++) {
e10bc84d 2769 if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
589abe3a
EG
2770 == 0) {
2771 DP(NETIF_MSG_LINK, "SFP+ module initialization "
2772 "took %d ms\n", timeout * 5);
2773 return 0;
2774 }
2775 msleep(5);
2776 }
2777 return -EINVAL;
2778}
2779
4d295db0 2780static void bnx2x_8727_power_module(struct bnx2x *bp,
e10bc84d
YR
2781 struct bnx2x_phy *phy,
2782 u8 is_power_up) {
4d295db0
EG
2783 /* Make sure GPIOs are not using for LED mode */
2784 u16 val;
4d295db0
EG
2785 /*
2786 * In the GPIO register, bit 4 is use to detemine if the GPIOs are
2787 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
2788 * output
2789 * Bits 0-1 determine the gpios value for OUTPUT in case bit 4 val is 0
2790 * Bits 8-9 determine the gpios value for INPUT in case bit 4 val is 1
2791 * where the 1st bit is the over-current(only input), and 2nd bit is
2792 * for power( only output )
2793 */
2794
2795 /*
2796 * In case of NOC feature is disabled and power is up, set GPIO control
2797 * as input to enable listening of over-current indication
2798 */
b7737c9b
YR
2799 if (phy->flags & FLAGS_NOC)
2800 return;
2801 if (!(phy->flags &
2802 FLAGS_NOC) && is_power_up)
4d295db0
EG
2803 val = (1<<4);
2804 else
2805 /*
2806 * Set GPIO control to OUTPUT, and set the power bit
2807 * to according to the is_power_up
2808 */
2809 val = ((!(is_power_up)) << 1);
2810
e10bc84d 2811 bnx2x_cl45_write(bp, phy,
62b29a5d
YR
2812 MDIO_PMA_DEVAD,
2813 MDIO_PMA_REG_8727_GPIO_CTRL,
2814 val);
4d295db0
EG
2815}
2816
e10bc84d
YR
2817static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
2818 struct link_params *params)
589abe3a
EG
2819{
2820 struct bnx2x *bp = params->bp;
4d295db0
EG
2821 u16 edc_mode;
2822 u8 rc = 0;
e10bc84d 2823
4d295db0
EG
2824 u32 val = REG_RD(bp, params->shmem_base +
2825 offsetof(struct shmem_region, dev_info.
2826 port_feature_config[params->port].config));
589abe3a
EG
2827
2828 DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
2829 params->port);
2830
e10bc84d 2831 if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
589abe3a 2832 DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
4d295db0 2833 return -EINVAL;
e10bc84d 2834 } else if (bnx2x_verify_sfp_module(phy, params) !=
589abe3a
EG
2835 0) {
2836 /* check SFP+ module compatibility */
2837 DP(NETIF_MSG_LINK, "Module verification failed!!\n");
4d295db0 2838 rc = -EINVAL;
589abe3a
EG
2839 /* Turn on fault module-detected led */
2840 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2841 MISC_REGISTERS_GPIO_HIGH,
2842 params->port);
e10bc84d 2843 if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
4d295db0
EG
2844 ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2845 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
2846 /* Shutdown SFP+ module */
2847 DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
62b29a5d 2848 bnx2x_8727_power_module(bp, phy, 0);
4d295db0
EG
2849 return rc;
2850 }
2851 } else {
2852 /* Turn off fault module-detected led */
2853 DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n");
2854 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2855 MISC_REGISTERS_GPIO_LOW,
2856 params->port);
589abe3a
EG
2857 }
2858
4d295db0 2859 /* power up the SFP module */
e10bc84d 2860 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727)
62b29a5d 2861 bnx2x_8727_power_module(bp, phy, 1);
589abe3a 2862
4d295db0
EG
2863 /* Check and set limiting mode / LRM mode on 8726.
2864 On 8727 it is done automatically */
e10bc84d
YR
2865 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726)
2866 bnx2x_8726_set_limiting_mode(bp, phy, edc_mode);
4d295db0 2867 else
e10bc84d 2868 bnx2x_8727_set_limiting_mode(bp, phy, edc_mode);
4d295db0
EG
2869 /*
2870 * Enable transmit for this module if the module is approved, or
2871 * if unapproved modules should also enable the Tx laser
2872 */
2873 if (rc == 0 ||
2874 (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
2875 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
b7737c9b 2876 bnx2x_sfp_set_transmitter(bp, phy, params->port, 1);
4d295db0 2877 else
b7737c9b 2878 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
589abe3a 2879
4d295db0 2880 return rc;
589abe3a
EG
2881}
2882
2883void bnx2x_handle_module_detect_int(struct link_params *params)
2884{
2885 struct bnx2x *bp = params->bp;
e10bc84d 2886 struct bnx2x_phy *phy = &params->phy[EXT_PHY1];
589abe3a
EG
2887 u32 gpio_val;
2888 u8 port = params->port;
ab6ad5a4 2889
589abe3a
EG
2890 /* Set valid module led off */
2891 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
2892 MISC_REGISTERS_GPIO_HIGH,
2893 params->port);
2894
2895 /* Get current gpio val refelecting module plugged in / out*/
e10bc84d 2896 gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
589abe3a
EG
2897
2898 /* Call the handling function in case module is detected */
2899 if (gpio_val == 0) {
2900
2901 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
e10bc84d
YR
2902 MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
2903 port);
589abe3a 2904
e10bc84d
YR
2905 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
2906 bnx2x_sfp_module_detection(phy, params);
589abe3a
EG
2907 else
2908 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
2909 } else {
4d295db0
EG
2910 u32 val = REG_RD(bp, params->shmem_base +
2911 offsetof(struct shmem_region, dev_info.
2912 port_feature_config[params->port].
2913 config));
2914
589abe3a 2915 bnx2x_set_gpio_int(bp, MISC_REGISTERS_GPIO_3,
62b29a5d
YR
2916 MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
2917 port);
589abe3a
EG
2918 /* Module was plugged out. */
2919 /* Disable transmit for this module */
4d295db0
EG
2920 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
2921 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
b7737c9b 2922 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
589abe3a
EG
2923 }
2924}
2925
e10bc84d 2926static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
6bbca910 2927{
6bbca910 2928 /* Force KR or KX */
e10bc84d 2929 bnx2x_cl45_write(bp, phy,
62b29a5d 2930 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
e10bc84d 2931 bnx2x_cl45_write(bp, phy,
62b29a5d 2932 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
e10bc84d 2933 bnx2x_cl45_write(bp, phy,
62b29a5d 2934 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
e10bc84d 2935 bnx2x_cl45_write(bp, phy,
62b29a5d 2936 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
ea4e040a 2937}
ab6ad5a4 2938
e10bc84d
YR
2939static void bnx2x_8073_set_xaui_low_power_mode(struct bnx2x *bp,
2940 struct bnx2x_phy *phy)
ea4e040a 2941{
ea4e040a 2942 u16 val;
e10bc84d 2943 bnx2x_cl45_read(bp, phy,
62b29a5d 2944 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV, &val);
ea4e040a
YR
2945
2946 if (val == 0) {
2947 /* Mustn't set low power mode in 8073 A0 */
2948 return;
2949 }
2950
2951 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
e10bc84d 2952 bnx2x_cl45_read(bp, phy,
62b29a5d 2953 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
ea4e040a 2954 val &= ~(1<<13);
e10bc84d 2955 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
2956 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2957
2958 /* PLL controls */
62b29a5d
YR
2959 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805E, 0x1077);
2960 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805D, 0x0000);
2961 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805C, 0x030B);
2962 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805B, 0x1240);
2963 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x805A, 0x2490);
ea4e040a
YR
2964
2965 /* Tx Controls */
62b29a5d
YR
2966 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2967 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A6, 0x9041);
2968 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80A5, 0x4640);
ea4e040a
YR
2969
2970 /* Rx Controls */
62b29a5d
YR
2971 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2972 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FD, 0x9249);
2973 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, 0x80FC, 0x2015);
ea4e040a
YR
2974
2975 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
62b29a5d 2976 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, &val);
ea4e040a 2977 val |= (1<<13);
62b29a5d 2978 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
ea4e040a 2979}
6bbca910
YR
2980
2981static void bnx2x_8073_set_pause_cl37(struct link_params *params,
e10bc84d
YR
2982 struct bnx2x_phy *phy,
2983 struct link_vars *vars)
ea4e040a 2984{
6bbca910 2985 u16 cl37_val;
e10bc84d
YR
2986 struct bnx2x *bp = params->bp;
2987 bnx2x_cl45_read(bp, phy,
62b29a5d 2988 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
6bbca910
YR
2989
2990 cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2991 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
e10bc84d 2992 bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6bbca910
YR
2993 if ((vars->ieee_fc &
2994 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2995 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2996 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2997 }
2998 if ((vars->ieee_fc &
2999 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3000 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3001 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3002 }
3003 if ((vars->ieee_fc &
3004 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3005 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3006 cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3007 }
3008 DP(NETIF_MSG_LINK,
3009 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
3010
e10bc84d 3011 bnx2x_cl45_write(bp, phy,
62b29a5d 3012 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
6bbca910 3013 msleep(500);
ea4e040a
YR
3014}
3015
3016static void bnx2x_ext_phy_set_pause(struct link_params *params,
e10bc84d
YR
3017 struct bnx2x_phy *phy,
3018 struct link_vars *vars)
ea4e040a 3019{
ea4e040a 3020 u16 val;
e10bc84d 3021 struct bnx2x *bp = params->bp;
ea4e040a 3022 /* read modify write pause advertizing */
62b29a5d 3023 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
ea4e040a
YR
3024
3025 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
8c99e7b0 3026
ea4e040a
YR
3027 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3028
8c99e7b0
YR
3029 if ((vars->ieee_fc &
3030 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
ea4e040a
YR
3031 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3032 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3033 }
8c99e7b0
YR
3034 if ((vars->ieee_fc &
3035 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
ea4e040a 3036 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
62b29a5d 3037 val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
ea4e040a 3038 }
62b29a5d
YR
3039 DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3040 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
ea4e040a 3041}
e10bc84d
YR
3042
3043static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
3044 struct link_params *params)
c2c8b03e 3045{
e10bc84d 3046
c2c8b03e
EG
3047 u16 bank, i = 0;
3048 struct bnx2x *bp = params->bp;
ea4e040a 3049
c2c8b03e
EG
3050 for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
3051 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
e10bc84d 3052 CL45_WR_OVER_CL22(bp, phy,
62b29a5d
YR
3053 bank,
3054 MDIO_RX0_RX_EQ_BOOST,
b7737c9b 3055 phy->rx_preemphasis[i]);
c2c8b03e
EG
3056 }
3057
3058 for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
3059 bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
e10bc84d 3060 CL45_WR_OVER_CL22(bp, phy,
62b29a5d
YR
3061 bank,
3062 MDIO_TX0_TX_DRIVER,
b7737c9b 3063 phy->tx_preemphasis[i]);
c2c8b03e
EG
3064 }
3065}
57963ed9 3066
e10bc84d
YR
3067static void bnx2x_8481_set_led(struct bnx2x *bp,
3068 struct bnx2x_phy *phy)
2f904460 3069{
a1e4be39 3070 u16 val;
e10bc84d
YR
3071
3072 /* PHYC_CTL_LED_CTL */
3073 bnx2x_cl45_read(bp, phy,
a1e4be39
YR
3074 MDIO_PMA_DEVAD,
3075 MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
3076 val &= 0xFE00;
3077 val |= 0x0092;
2f904460 3078
e10bc84d 3079 bnx2x_cl45_write(bp, phy,
a1e4be39
YR
3080 MDIO_PMA_DEVAD,
3081 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
2f904460 3082
e10bc84d 3083 bnx2x_cl45_write(bp, phy,
a1e4be39
YR
3084 MDIO_PMA_DEVAD,
3085 MDIO_PMA_REG_8481_LED1_MASK,
3086 0x80);
2f904460 3087
e10bc84d 3088 bnx2x_cl45_write(bp, phy,
a1e4be39
YR
3089 MDIO_PMA_DEVAD,
3090 MDIO_PMA_REG_8481_LED2_MASK,
3091 0x18);
2f904460 3092
e10bc84d 3093 bnx2x_cl45_write(bp, phy,
a1e4be39
YR
3094 MDIO_PMA_DEVAD,
3095 MDIO_PMA_REG_8481_LED3_MASK,
3096 0x0040);
3097
3098 /* 'Interrupt Mask' */
e10bc84d 3099 bnx2x_cl45_write(bp, phy,
a1e4be39
YR
3100 MDIO_AN_DEVAD,
3101 0xFFFB, 0xFFFD);
2f904460
EG
3102}
3103
e10bc84d
YR
3104static void bnx2x_init_internal_phy(struct bnx2x_phy *phy,
3105 struct link_params *params,
3106 struct link_vars *vars)
57963ed9
YR
3107{
3108 struct bnx2x *bp = params->bp;
e10bc84d
YR
3109 u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
3110 (params->loopback_mode == LOOPBACK_XGXS_10));
57963ed9 3111 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
e10bc84d 3112 if (SINGLE_MEDIA_DIRECT(params) &&
c2c8b03e
EG
3113 (params->feature_config_flags &
3114 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
e10bc84d 3115 bnx2x_set_preemphasis(phy, params);
57963ed9
YR
3116
3117 /* forced speed requested? */
7846e471 3118 if (vars->line_speed != SPEED_AUTO_NEG ||
e10bc84d 3119 (SINGLE_MEDIA_DIRECT(params) &&
7846e471 3120 params->loopback_mode == LOOPBACK_EXT)) {
57963ed9
YR
3121 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
3122
3123 /* disable autoneg */
e10bc84d 3124 bnx2x_set_autoneg(phy, params, vars, 0);
57963ed9
YR
3125
3126 /* program speed and duplex */
e10bc84d 3127 bnx2x_program_serdes(phy, params, vars);
57963ed9
YR
3128
3129 } else { /* AN_mode */
3130 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
3131
3132 /* AN enabled */
e10bc84d 3133 bnx2x_set_brcm_cl37_advertisment(phy, params);
57963ed9
YR
3134
3135 /* program duplex & pause advertisement (for aneg) */
e10bc84d 3136 bnx2x_set_ieee_aneg_advertisment(phy, params,
8c99e7b0 3137 vars->ieee_fc);
57963ed9
YR
3138
3139 /* enable autoneg */
e10bc84d 3140 bnx2x_set_autoneg(phy, params, vars, enable_cl73);
57963ed9
YR
3141
3142 /* enable and restart AN */
e10bc84d 3143 bnx2x_restart_autoneg(phy, params, enable_cl73);
57963ed9
YR
3144 }
3145
3146 } else { /* SGMII mode */
3147 DP(NETIF_MSG_LINK, "SGMII\n");
3148
e10bc84d 3149 bnx2x_initialize_sgmii_process(phy, params, vars);
57963ed9
YR
3150 }
3151}
3152
b7737c9b
YR
3153static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
3154 struct bnx2x_phy *phy)
ea4e040a 3155{
b7737c9b 3156 u16 cnt, ctrl;
62b29a5d
YR
3157 /* Wait for soft reset to get cleared upto 1 sec */
3158 for (cnt = 0; cnt < 1000; cnt++) {
3159 bnx2x_cl45_read(bp, phy,
3160 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, &ctrl);
3161 if (!(ctrl & (1<<15)))
3162 break;
3163 msleep(1);
3164 }
3165 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
3166 return cnt;
b7737c9b 3167}
ea4e040a 3168
b7737c9b
YR
3169static u8 bnx2x_8705_config_init(struct bnx2x_phy *phy,
3170 struct link_params *params,
3171 struct link_vars *vars)
3172{
3173 struct bnx2x *bp = params->bp;
3174 DP(NETIF_MSG_LINK, "init 8705\n");
3175 /* Restore normal power mode*/
3176 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3177 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3178 /* HW reset */
3179 bnx2x_ext_phy_hw_reset(bp, params->port);
3180 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3181 bnx2x_wait_reset_complete(bp, phy);
a35da8db 3182
62b29a5d
YR
3183 bnx2x_cl45_write(bp, phy,
3184 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
3185 bnx2x_cl45_write(bp, phy,
3186 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
3187 bnx2x_cl45_write(bp, phy,
3188 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
3189 bnx2x_cl45_write(bp, phy,
3190 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
3191 /* BCM8705 doesn't have microcode, hence the 0 */
3192 bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
3193 return 0;
b7737c9b
YR
3194}
3195
3196static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
3197 struct link_params *params,
3198 struct link_vars *vars)
3199{
3200 u16 cnt, val;
3201 struct bnx2x *bp = params->bp;
3202 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3203 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3204 /* HW reset */
3205 bnx2x_ext_phy_hw_reset(bp, params->port);
3206 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
3207
3208 bnx2x_wait_reset_complete(bp, phy);
ea4e040a 3209
62b29a5d
YR
3210 /* Wait until fw is loaded */
3211 for (cnt = 0; cnt < 100; cnt++) {
3212 bnx2x_cl45_read(bp, phy,
3213 MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
3214 if (val)
3215 break;
3216 msleep(10);
3217 }
3218 DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
3219 if ((params->feature_config_flags &
3220 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3221 u8 i;
3222 u16 reg;
3223 for (i = 0; i < 4; i++) {
3224 reg = MDIO_XS_8706_REG_BANK_RX0 +
3225 i*(MDIO_XS_8706_REG_BANK_RX1 -
3226 MDIO_XS_8706_REG_BANK_RX0);
3227 bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
3228 /* Clear first 3 bits of the control */
3229 val &= ~0x7;
3230 /* Set control bits according to configuration */
3231 val |= (phy->rx_preemphasis[i] & 0x7);
3232 DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
3233 " reg 0x%x <-- val 0x%x\n", reg, val);
3234 bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
3235 }
3236 }
3237 /* Force speed */
3238 if (phy->req_line_speed == SPEED_10000) {
3239 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
3240
3241 bnx2x_cl45_write(bp, phy,
3242 MDIO_PMA_DEVAD,
3243 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
3244 bnx2x_cl45_write(bp, phy,
3245 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
3246 } else {
3247 /* Force 1Gbps using autoneg with 1G advertisment */
3248
3249 /* Allow CL37 through CL73 */
3250 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
3251 bnx2x_cl45_write(bp, phy,
3252 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
3253
3254 /* Enable Full-Duplex advertisment on CL37 */
3255 bnx2x_cl45_write(bp, phy,
3256 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
3257 /* Enable CL37 AN */
3258 bnx2x_cl45_write(bp, phy,
3259 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
3260 /* 1G support */
3261 bnx2x_cl45_write(bp, phy,
3262 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
3263
3264 /* Enable clause 73 AN */
3265 bnx2x_cl45_write(bp, phy,
3266 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3267 bnx2x_cl45_write(bp, phy,
3268 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
3269 0x0400);
3270 bnx2x_cl45_write(bp, phy,
3271 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL,
3272 0x0004);
3273 }
3274 bnx2x_save_bcm_spirom_ver(bp, params->port, phy, params->shmem_base);
3275 return 0;
b7737c9b
YR
3276}
3277
3278static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
3279 struct link_params *params,
3280 struct link_vars *vars)
3281{
3282 struct bnx2x *bp = params->bp;
3283 DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
3284 /* Restore normal power mode*/
3285 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3286 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3287
3288 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3289 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3290
3291 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
3292 bnx2x_wait_reset_complete(bp, phy);
3293
62b29a5d 3294 bnx2x_8726_external_rom_boot(phy, params);
4d295db0 3295
62b29a5d
YR
3296 /* Need to call module detected on initialization since
3297 the module detection triggered by actual module
3298 insertion might occur before driver is loaded, and when
3299 driver is loaded, it reset all registers, including the
3300 transmitter */
3301 bnx2x_sfp_module_detection(phy, params);
3302
3303 if (phy->req_line_speed == SPEED_1000) {
3304 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3305 bnx2x_cl45_write(bp, phy,
3306 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
3307 bnx2x_cl45_write(bp, phy,
3308 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
3309 bnx2x_cl45_write(bp, phy,
3310 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x5);
3311 bnx2x_cl45_write(bp, phy,
3312 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
3313 0x400);
3314 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
3315 (phy->speed_cap_mask &
3316 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
3317 ((phy->speed_cap_mask &
3318 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
3319 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
3320 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
3321 /* Set Flow control */
3322 bnx2x_ext_phy_set_pause(params, phy, vars);
3323 bnx2x_cl45_write(bp, phy,
3324 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
3325 bnx2x_cl45_write(bp, phy,
3326 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
3327 bnx2x_cl45_write(bp, phy,
3328 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
3329 bnx2x_cl45_write(bp, phy,
3330 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
3331 bnx2x_cl45_write(bp, phy,
3332 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3333 /* Enable RX-ALARM control to receive
3334 interrupt for 1G speed change */
3335 bnx2x_cl45_write(bp, phy,
3336 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x4);
3337 bnx2x_cl45_write(bp, phy,
3338 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
3339 0x400);
3340
3341 } else { /* Default 10G. Set only LASI control */
3342 bnx2x_cl45_write(bp, phy,
3343 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 1);
3344 }
c2c8b03e 3345
62b29a5d
YR
3346 /* Set TX PreEmphasis if needed */
3347 if ((params->feature_config_flags &
3348 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3349 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x,"
3350 "TX_CTRL2 0x%x\n",
b7737c9b
YR
3351 phy->tx_preemphasis[0],
3352 phy->tx_preemphasis[1]);
62b29a5d
YR
3353 bnx2x_cl45_write(bp, phy,
3354 MDIO_PMA_DEVAD,
3355 MDIO_PMA_REG_8726_TX_CTRL1,
b7737c9b 3356 phy->tx_preemphasis[0]);
c2c8b03e 3357
62b29a5d
YR
3358 bnx2x_cl45_write(bp, phy,
3359 MDIO_PMA_DEVAD,
3360 MDIO_PMA_REG_8726_TX_CTRL2,
b7737c9b 3361 phy->tx_preemphasis[1]);
62b29a5d
YR
3362 }
3363 return 0;
b7737c9b
YR
3364
3365}
3366
62b29a5d 3367static u8 bnx2x_8073_config_init(struct bnx2x_phy *phy,
b7737c9b
YR
3368 struct link_params *params,
3369 struct link_vars *vars)
3370{
3371 struct bnx2x *bp = params->bp;
62b29a5d 3372 u16 val = 0, tmp1;
b7737c9b
YR
3373 u8 gpio_port;
3374 DP(NETIF_MSG_LINK, "Init 8073\n");
3375
3376 gpio_port = params->port;
3377 /* Restore normal power mode*/
3378 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3379 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
3380
3381 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
3382 MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
3383
62b29a5d
YR
3384 /* enable LASI */
3385 bnx2x_cl45_write(bp, phy,
3386 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL, (1<<2));
3387 bnx2x_cl45_write(bp, phy,
3388 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x0004);
ea4e040a 3389
62b29a5d 3390 bnx2x_8073_set_pause_cl37(params, phy, vars);
ea4e040a 3391
62b29a5d 3392 bnx2x_8073_set_xaui_low_power_mode(bp, phy);
ea4e040a 3393
62b29a5d
YR
3394 bnx2x_cl45_read(bp, phy,
3395 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
ea4e040a 3396
62b29a5d
YR
3397 bnx2x_cl45_read(bp, phy,
3398 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
ea4e040a 3399
62b29a5d 3400 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
ea4e040a 3401
62b29a5d
YR
3402 /* Enable CL37 BAM */
3403 bnx2x_cl45_read(bp, phy,
3404 MDIO_AN_DEVAD,
3405 MDIO_AN_REG_8073_BAM, &val);
3406 bnx2x_cl45_write(bp, phy,
3407 MDIO_AN_DEVAD,
3408 MDIO_AN_REG_8073_BAM, val | 1);
ea4e040a 3409
62b29a5d
YR
3410 if (params->loopback_mode == LOOPBACK_EXT) {
3411 bnx2x_807x_force_10G(bp, phy);
3412 DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
3413 return 0;
3414 } else {
3415 bnx2x_cl45_write(bp, phy,
3416 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
3417 }
3418 if (phy->req_line_speed != SPEED_AUTO_NEG) {
3419 if (phy->req_line_speed == SPEED_10000) {
3420 val = (1<<7);
3421 } else if (phy->req_line_speed == SPEED_2500) {
3422 val = (1<<5);
3423 /* Note that 2.5G works only
3424 when used with 1G advertisment */
3425 } else
3426 val = (1<<5);
3427 } else {
3428 val = 0;
3429 if (phy->speed_cap_mask &
3430 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
3431 val |= (1<<7);
3432
3433 /* Note that 2.5G works only when
3434 used with 1G advertisment */
3435 if (phy->speed_cap_mask &
3436 (PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
3437 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
3438 val |= (1<<5);
3439 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
3440 }
e10bc84d 3441
62b29a5d
YR
3442 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
3443 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
6bbca910 3444
62b29a5d
YR
3445 if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
3446 (phy->req_line_speed == SPEED_AUTO_NEG)) ||
3447 (phy->req_line_speed == SPEED_2500)) {
3448 u16 phy_ver;
3449 /* Allow 2.5G for A1 and above */
3450 bnx2x_cl45_read(bp, phy,
3451 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
3452 &phy_ver);
3453 DP(NETIF_MSG_LINK, "Add 2.5G\n");
3454 if (phy_ver > 0)
3455 tmp1 |= 1;
3456 else
3457 tmp1 &= 0xfffe;
3458 } else {
3459 DP(NETIF_MSG_LINK, "Disable 2.5G\n");
3460 tmp1 &= 0xfffe;
3461 }
6bbca910 3462
62b29a5d
YR
3463 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
3464 /* Add support for CL37 (passive mode) II */
6bbca910 3465
62b29a5d
YR
3466 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
3467 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
3468 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
3469 0x20 : 0x40)));
ea4e040a 3470
62b29a5d
YR
3471 /* Add support for CL37 (passive mode) III */
3472 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
6bbca910 3473
62b29a5d
YR
3474 /* The SNR will improve about 2db by changing
3475 BW and FEE main tap. Rest commands are executed
3476 after link is up*/
3477 if (bnx2x_8073_is_snr_needed(bp, phy))
3478 bnx2x_cl45_write(bp, phy,
3479 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
3480 0xFB0C);
ea4e040a 3481
62b29a5d
YR
3482 /* Enable FEC (Forware Error Correction) Request in the AN */
3483 bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
3484 tmp1 |= (1<<15);
3485 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
ea4e040a 3486
62b29a5d 3487 bnx2x_ext_phy_set_pause(params, phy, vars);
ea4e040a 3488
62b29a5d
YR
3489 /* Restart autoneg */
3490 msleep(500);
3491 bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
3492 DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
3493 ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
3494 return 0;
b7737c9b 3495}
4d295db0 3496
b7737c9b
YR
3497static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
3498 struct link_params *params,
3499 struct link_vars *vars)
3500{
3501 u16 tmp1, val, mod_abs;
3502 u16 rx_alarm_ctrl_val;
3503 u16 lasi_ctrl_val;
3504 struct bnx2x *bp = params->bp;
3505 /* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
ea4e040a 3506
62b29a5d
YR
3507 bnx2x_wait_reset_complete(bp, phy);
3508 rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
3509 lasi_ctrl_val = 0x0004;
4d295db0 3510
62b29a5d
YR
3511 DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
3512 /* enable LASI */
3513 bnx2x_cl45_write(bp, phy,
3514 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
3515 rx_alarm_ctrl_val);
4d295db0 3516
62b29a5d
YR
3517 bnx2x_cl45_write(bp, phy,
3518 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, lasi_ctrl_val);
ea4e040a 3519
62b29a5d
YR
3520 /* Initially configure MOD_ABS to interrupt when
3521 module is presence( bit 8) */
3522 bnx2x_cl45_read(bp, phy,
3523 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
3524 /* Set EDC off by setting OPTXLOS signal input to low
3525 (bit 9).
3526 When the EDC is off it locks onto a reference clock and
3527 avoids becoming 'lost'.*/
3528 mod_abs &= ~((1<<8) | (1<<9));
3529 bnx2x_cl45_write(bp, phy,
3530 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
28577185 3531
4d295db0 3532
62b29a5d
YR
3533 /* Make MOD_ABS give interrupt on change */
3534 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3535 &val);
3536 val |= (1<<12);
3537 bnx2x_cl45_write(bp, phy,
3538 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
3539 /* Set 8727 GPIOs to input to allow reading from the
3540 8727 GPIO0 status which reflect SFP+ module
3541 over-current */
3542
3543 bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
3544 &val);
3545 val &= 0xff8f; /* Reset bits 4-6 */
3546 bnx2x_cl45_write(bp, phy,
3547 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
4d295db0 3548
62b29a5d 3549 bnx2x_8727_power_module(bp, phy, 1);
4d295db0 3550
62b29a5d
YR
3551 bnx2x_cl45_read(bp, phy,
3552 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
4d295db0 3553
62b29a5d
YR
3554 bnx2x_cl45_read(bp, phy,
3555 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &tmp1);
4d295db0 3556
62b29a5d
YR
3557 /* Set option 1G speed */
3558 if (phy->req_line_speed == SPEED_1000) {
3559 DP(NETIF_MSG_LINK, "Setting 1G force\n");
3560 bnx2x_cl45_write(bp, phy,
3561 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
3562 bnx2x_cl45_write(bp, phy,
3563 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
3564 bnx2x_cl45_read(bp, phy,
3565 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
3566 DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
3567 } else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
3568 ((phy->speed_cap_mask &
3569 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
3570 ((phy->speed_cap_mask &
3571 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
3572 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
3573
3574 DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
3575 bnx2x_cl45_write(bp, phy,
3576 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
3577 bnx2x_cl45_write(bp, phy,
3578 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
3579 } else {
3580 /**
3581 * Since the 8727 has only single reset pin, need to set the 10G
3582 * registers although it is default
3583 */
3584 bnx2x_cl45_write(bp, phy,
3585 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
3586 0x0020);
3587 bnx2x_cl45_write(bp, phy,
3588 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
3589 bnx2x_cl45_write(bp, phy,
3590 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
3591 bnx2x_cl45_write(bp, phy,
3592 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
3593 0x0008);
3594 }
4d295db0 3595
62b29a5d
YR
3596
3597 /* Set 2-wire transfer rate of SFP+ module EEPROM
3598 * to 100Khz since some DACs(direct attached cables) do
3599 * not work at 400Khz.
3600 */
3601 bnx2x_cl45_write(bp, phy,
3602 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
3603 0xa001);
3604
3605 /* Set TX PreEmphasis if needed */
3606 if ((params->feature_config_flags &
3607 FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
3608 DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
3609 phy->tx_preemphasis[0],
b7737c9b 3610 phy->tx_preemphasis[1]);
62b29a5d
YR
3611 bnx2x_cl45_write(bp, phy,
3612 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
3613 phy->tx_preemphasis[0]);
4d295db0 3614
62b29a5d
YR
3615 bnx2x_cl45_write(bp, phy,
3616 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
3617 phy->tx_preemphasis[1]);
3618 }
3619
3620 return 0;
b7737c9b
YR
3621}
3622
3623static u8 bnx2x_7101_config_init(struct bnx2x_phy *phy,
3624 struct link_params *params,
3625 struct link_vars *vars)
3626{
3627 u16 fw_ver1, fw_ver2, val;
3628 struct bnx2x *bp = params->bp;
3629 DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
3630
3631 /* Restore normal power mode*/
3632 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3633 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3634 /* HW reset */
3635 bnx2x_ext_phy_hw_reset(bp, params->port);
62b29a5d 3636 bnx2x_wait_reset_complete(bp, phy);
4d295db0 3637
62b29a5d
YR
3638 bnx2x_cl45_write(bp, phy,
3639 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0x1);
3640 DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
3641 bnx2x_cl45_write(bp, phy,
3642 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
4d295db0 3643
62b29a5d
YR
3644 bnx2x_ext_phy_set_pause(params, phy, vars);
3645 /* Restart autoneg */
3646 bnx2x_cl45_read(bp, phy,
3647 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
3648 val |= 0x200;
3649 bnx2x_cl45_write(bp, phy,
3650 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
a35da8db 3651
62b29a5d
YR
3652 /* Save spirom version */
3653 bnx2x_cl45_read(bp, phy,
3654 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
a35da8db 3655
62b29a5d
YR
3656 bnx2x_cl45_read(bp, phy,
3657 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
3658 bnx2x_save_spirom_version(bp, params->port,
3659 (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
3660 return 0;
b7737c9b
YR
3661}
3662
3663static u8 bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
3664 struct link_params *params,
3665 struct link_vars *vars)
3666{
3667 struct bnx2x *bp = params->bp;
62b29a5d
YR
3668 u16 autoneg_val, an_1000_val, an_10_100_val;
3669 bnx2x_wait_reset_complete(bp, phy);
3670 bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
3671 1 << NIG_LATCH_BC_ENABLE_MI_INT);
3672
3673 bnx2x_cl45_write(bp, phy,
3674 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
3675 bnx2x_8481_set_led(bp, phy);
3676 /* set 1000 speed advertisement */
3677 bnx2x_cl45_read(bp, phy,
3678 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
3679 &an_1000_val);
a1e4be39 3680
62b29a5d
YR
3681 bnx2x_ext_phy_set_pause(params, phy, vars);
3682 bnx2x_cl45_read(bp, phy,
3683 MDIO_AN_DEVAD,
3684 MDIO_AN_REG_8481_LEGACY_AN_ADV,
3685 &an_10_100_val);
3686 bnx2x_cl45_read(bp, phy,
3687 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
3688 &autoneg_val);
3689 /* Disable forced speed */
3690 autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
3691 an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
3692
3693 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3694 (phy->speed_cap_mask &
3695 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3696 (phy->req_line_speed == SPEED_1000)) {
3697 an_1000_val |= (1<<8);
3698 autoneg_val |= (1<<9 | 1<<12);
3699 if (phy->req_duplex == DUPLEX_FULL)
3700 an_1000_val |= (1<<9);
3701 DP(NETIF_MSG_LINK, "Advertising 1G\n");
3702 } else
3703 an_1000_val &= ~((1<<8) | (1<<9));
2f904460 3704
62b29a5d
YR
3705 bnx2x_cl45_write(bp, phy,
3706 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
3707 an_1000_val);
3708
3709 /* set 10 speed advertisement */
3710 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3711 (phy->speed_cap_mask &
3712 (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
3713 PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
3714 an_10_100_val |= (1<<7);
3715 /* Enable autoneg and restart autoneg for legacy speeds */
3716 autoneg_val |= (1<<9 | 1<<12);
3717
3718 if (phy->req_duplex == DUPLEX_FULL)
3719 an_10_100_val |= (1<<8);
3720 DP(NETIF_MSG_LINK, "Advertising 100M\n");
3721 }
3722 /* set 10 speed advertisement */
3723 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3724 (phy->speed_cap_mask &
3725 (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
3726 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
3727 an_10_100_val |= (1<<5);
3728 autoneg_val |= (1<<9 | 1<<12);
3729 if (phy->req_duplex == DUPLEX_FULL)
3730 an_10_100_val |= (1<<6);
3731 DP(NETIF_MSG_LINK, "Advertising 10M\n");
3732 }
4f60dab1 3733
62b29a5d
YR
3734 /* Only 10/100 are allowed to work in FORCE mode */
3735 if (phy->req_line_speed == SPEED_100) {
3736 autoneg_val |= (1<<13);
3737 /* Enabled AUTO-MDIX when autoneg is disabled */
3738 bnx2x_cl45_write(bp, phy,
3739 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
3740 (1<<15 | 1<<9 | 7<<0));
3741 DP(NETIF_MSG_LINK, "Setting 100M force\n");
3742 }
3743 if (phy->req_line_speed == SPEED_10) {
3744 /* Enabled AUTO-MDIX when autoneg is disabled */
3745 bnx2x_cl45_write(bp, phy,
3746 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
3747 (1<<15 | 1<<9 | 7<<0));
3748 DP(NETIF_MSG_LINK, "Setting 10M force\n");
3749 }
2f904460 3750
62b29a5d
YR
3751 bnx2x_cl45_write(bp, phy,
3752 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
3753 an_10_100_val);
2f904460 3754
62b29a5d
YR
3755 if (phy->req_duplex == DUPLEX_FULL)
3756 autoneg_val |= (1<<8);
2f904460 3757
62b29a5d
YR
3758 bnx2x_cl45_write(bp, phy,
3759 MDIO_AN_DEVAD,
3760 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
46d15cc7 3761
62b29a5d
YR
3762 if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
3763 (phy->speed_cap_mask &
3764 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3765 (phy->req_line_speed == SPEED_10000)) {
3766 DP(NETIF_MSG_LINK, "Advertising 10G\n");
3767 /* Restart autoneg for 10G*/
2f904460 3768
62b29a5d
YR
3769 bnx2x_cl45_write(bp, phy,
3770 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
3771 0x3200);
3772 } else if (phy->req_line_speed != SPEED_10 &&
3773 phy->req_line_speed != SPEED_100) {
3774 bnx2x_cl45_write(bp, phy,
3775 MDIO_AN_DEVAD,
3776 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
3777 1);
3778 }
3779 /* Save spirom version */
3780 bnx2x_save_8481_spirom_version(phy, params, params->shmem_base);
2f904460 3781
62b29a5d 3782 return 0;
b7737c9b 3783}
ea4e040a 3784
b7737c9b
YR
3785static u8 bnx2x_848x3_config_init(struct bnx2x_phy *phy,
3786 struct link_params *params,
3787 struct link_vars *vars)
3788{
3789 struct bnx2x *bp = params->bp;
3790 u16 temp;
3791 msleep(1);
3792 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
3793 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
3794 params->port);
3795 msleep(200); /* 100 is not enough */
3796
3797 /**
3798 * BCM84823 requires that XGXS links up first @ 10G for normal
3799 * behavior
3800 */
3801 temp = vars->line_speed;
3802 vars->line_speed = SPEED_10000;
3803 bnx2x_set_autoneg(phy, params, vars, 0);
3804 bnx2x_program_serdes(phy, params, vars);
3805 vars->line_speed = temp;
3806 return bnx2x_848xx_cmn_config_init(phy, params, vars);
ea4e040a
YR
3807}
3808
b7737c9b
YR
3809static u8 bnx2x_8481_config_init(struct bnx2x_phy *phy,
3810 struct link_params *params,
3811 struct link_vars *vars)
3812{
3813 struct bnx2x *bp = params->bp;
3814 /* Restore normal power mode*/
3815 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
3816 MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
3817
3818 /* HW reset */
3819 bnx2x_ext_phy_hw_reset(bp, params->port);
3820
3821 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
3822 return bnx2x_848xx_cmn_config_init(phy, params, vars);
3823}
e10bc84d
YR
3824static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
3825 struct link_params *params)
4d295db0
EG
3826{
3827 struct bnx2x *bp = params->bp;
3828 u16 mod_abs, rx_alarm_status;
4d295db0
EG
3829 u32 val = REG_RD(bp, params->shmem_base +
3830 offsetof(struct shmem_region, dev_info.
3831 port_feature_config[params->port].
3832 config));
e10bc84d 3833 bnx2x_cl45_read(bp, phy,
4d295db0
EG
3834 MDIO_PMA_DEVAD,
3835 MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
3836 if (mod_abs & (1<<8)) {
3837
3838 /* Module is absent */
3839 DP(NETIF_MSG_LINK, "MOD_ABS indication "
3840 "show module is absent\n");
3841
3842 /* 1. Set mod_abs to detect next module
3843 presence event
3844 2. Set EDC off by setting OPTXLOS signal input to low
3845 (bit 9).
3846 When the EDC is off it locks onto a reference clock and
3847 avoids becoming 'lost'.*/
3848 mod_abs &= ~((1<<8)|(1<<9));
e10bc84d 3849 bnx2x_cl45_write(bp, phy,
4d295db0
EG
3850 MDIO_PMA_DEVAD,
3851 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
3852
3853 /* Clear RX alarm since it stays up as long as
3854 the mod_abs wasn't changed */
e10bc84d 3855 bnx2x_cl45_read(bp, phy,
4d295db0
EG
3856 MDIO_PMA_DEVAD,
3857 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
3858
3859 } else {
3860 /* Module is present */
3861 DP(NETIF_MSG_LINK, "MOD_ABS indication "
3862 "show module is present\n");
3863 /* First thing, disable transmitter,
3864 and if the module is ok, the
3865 module_detection will enable it*/
3866
3867 /* 1. Set mod_abs to detect next module
3868 absent event ( bit 8)
3869 2. Restore the default polarity of the OPRXLOS signal and
3870 this signal will then correctly indicate the presence or
3871 absence of the Rx signal. (bit 9) */
3872 mod_abs |= ((1<<8)|(1<<9));
e10bc84d 3873 bnx2x_cl45_write(bp, phy,
62b29a5d
YR
3874 MDIO_PMA_DEVAD,
3875 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
4d295db0
EG
3876
3877 /* Clear RX alarm since it stays up as long as
3878 the mod_abs wasn't changed. This is need to be done
3879 before calling the module detection, otherwise it will clear
3880 the link update alarm */
e10bc84d 3881 bnx2x_cl45_read(bp, phy,
62b29a5d
YR
3882 MDIO_PMA_DEVAD,
3883 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4d295db0
EG
3884
3885
3886 if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
3887 PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
b7737c9b 3888 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
4d295db0 3889
e10bc84d
YR
3890 if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
3891 bnx2x_sfp_module_detection(phy, params);
4d295db0
EG
3892 else
3893 DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
3894 }
3895
3896 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
3897 rx_alarm_status);
3898 /* No need to check link status in case of
3899 module plugged in/out */
3900}
3901
b7737c9b 3902static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
e10bc84d 3903 struct link_params *params,
b7737c9b 3904 struct link_vars *vars)
ea4e040a 3905{
62b29a5d 3906 u8 link_up = 0;
b7737c9b
YR
3907 u16 val1, rx_sd;
3908 struct bnx2x *bp = params->bp;
62b29a5d
YR
3909 DP(NETIF_MSG_LINK, "read status 8705\n");
3910 bnx2x_cl45_read(bp, phy,
3911 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3912 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
ea4e040a 3913
62b29a5d
YR
3914 bnx2x_cl45_read(bp, phy,
3915 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
3916 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
ea4e040a 3917
62b29a5d
YR
3918 bnx2x_cl45_read(bp, phy,
3919 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
4d295db0 3920
62b29a5d
YR
3921 bnx2x_cl45_read(bp, phy,
3922 MDIO_PMA_DEVAD, 0xc809, &val1);
3923 bnx2x_cl45_read(bp, phy,
3924 MDIO_PMA_DEVAD, 0xc809, &val1);
4d295db0 3925
62b29a5d
YR
3926 DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
3927 link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
3928 if (link_up) {
3929 vars->line_speed = SPEED_10000;
3930 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3931 }
3932 return link_up;
b7737c9b 3933}
ea4e040a 3934
b7737c9b
YR
3935static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
3936 struct link_params *params,
3937 struct link_vars *vars)
3938{
3939 u8 link_up = 0;
3940 u16 val1, val2, rx_sd, pcs_status;
3941 struct bnx2x *bp = params->bp;
62b29a5d
YR
3942 DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
3943 /* Clear RX Alarm*/
3944 bnx2x_cl45_read(bp, phy,
3945 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
3946 /* clear LASI indication*/
3947 bnx2x_cl45_read(bp, phy,
3948 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
3949 bnx2x_cl45_read(bp, phy,
3950 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
3951 DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
ea4e040a 3952
62b29a5d
YR
3953 bnx2x_cl45_read(bp, phy,
3954 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
3955 bnx2x_cl45_read(bp, phy,
3956 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
3957 bnx2x_cl45_read(bp, phy,
3958 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
3959 bnx2x_cl45_read(bp, phy,
3960 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
3961
3962 DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
3963 " link_status 0x%x\n", rx_sd, pcs_status, val2);
3964 /* link is up if both bit 0 of pmd_rx_sd and
3965 * bit 0 of pcs_status are set, or if the autoneg bit
3966 * 1 is set
3967 */
3968 link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
3969 if (link_up) {
3970 if (val2 & (1<<1))
3971 vars->line_speed = SPEED_1000;
3972 else
3973 vars->line_speed = SPEED_10000;
3974 bnx2x_ext_phy_resolve_fc(phy, params, vars);
3975 }
3976 return link_up;
b7737c9b 3977}
4d295db0 3978
b7737c9b
YR
3979static u8 bnx2x_8706_read_status(struct bnx2x_phy *phy,
3980 struct link_params *params,
3981 struct link_vars *vars)
3982{
3983 return bnx2x_8706_8726_read_status(phy, params, vars);
3984}
3985
3986static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
3987 struct link_params *params,
3988 struct link_vars *vars)
3989{
3990 struct bnx2x *bp = params->bp;
3991 u16 val1;
3992 u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
3993 if (link_up) {
3994 bnx2x_cl45_read(bp, phy,
3995 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
3996 &val1);
3997 if (val1 & (1<<15)) {
3998 DP(NETIF_MSG_LINK, "Tx is disabled\n");
3999 link_up = 0;
4000 vars->line_speed = 0;
4001 }
4002 }
4003 return link_up;
4004}
4005static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
4006 struct link_params *params,
4007 struct link_vars *vars)
4008
4009{
4010 struct bnx2x *bp = params->bp;
62b29a5d
YR
4011 u8 link_up = 0;
4012 u16 link_status = 0;
4013 u16 rx_alarm_status, val1;
4014 /* Check the LASI */
4015 bnx2x_cl45_read(bp, phy,
4016 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM,
4017 &rx_alarm_status);
4018 vars->line_speed = 0;
4019 DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n", rx_alarm_status);
4d295db0 4020
62b29a5d
YR
4021 bnx2x_cl45_read(bp, phy,
4022 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4d295db0 4023
62b29a5d 4024 DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
4d295db0 4025
62b29a5d
YR
4026 /* Clear MSG-OUT */
4027 bnx2x_cl45_read(bp, phy,
4028 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
4d295db0 4029
62b29a5d
YR
4030 /**
4031 * If a module is present and there is need to check
4032 * for over current
4033 */
4034 if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
4035 /* Check over-current using 8727 GPIO0 input*/
4036 bnx2x_cl45_read(bp, phy,
4037 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
4038 &val1);
4039
4040 if ((val1 & (1<<8)) == 0) {
4041 DP(NETIF_MSG_LINK, "8727 Power fault has been detected"
4042 " on port %d\n", params->port);
4043 netdev_err(bp->dev, "Error: Power fault on Port %d has"
4044 " been detected and the power to "
4045 "that SFP+ module has been removed"
4046 " to prevent failure of the card."
4047 " Please remove the SFP+ module and"
4048 " restart the system to clear this"
4049 " error.\n",
4050 params->port);
4d295db0
EG
4051
4052 /*
62b29a5d
YR
4053 * Disable all RX_ALARMs except for
4054 * mod_abs
4d295db0 4055 */
62b29a5d
YR
4056 bnx2x_cl45_write(bp, phy,
4057 MDIO_PMA_DEVAD,
4058 MDIO_PMA_REG_RX_ALARM_CTRL, (1<<5));
4d295db0 4059
e10bc84d 4060 bnx2x_cl45_read(bp, phy,
62b29a5d
YR
4061 MDIO_PMA_DEVAD,
4062 MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
4063 /* Wait for module_absent_event */
4064 val1 |= (1<<8);
4065 bnx2x_cl45_write(bp, phy,
4066 MDIO_PMA_DEVAD,
4067 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
4068 /* Clear RX alarm */
e10bc84d 4069 bnx2x_cl45_read(bp, phy,
62b29a5d
YR
4070 MDIO_PMA_DEVAD,
4071 MDIO_PMA_REG_RX_ALARM, &rx_alarm_status);
4072 return 0;
4073 }
4074 } /* Over current check */
4d295db0 4075
62b29a5d
YR
4076 /* When module absent bit is set, check module */
4077 if (rx_alarm_status & (1<<5)) {
4078 bnx2x_8727_handle_mod_abs(phy, params);
4079 /* Enable all mod_abs and link detection bits */
4080 bnx2x_cl45_write(bp, phy,
4081 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM_CTRL,
4082 ((1<<5) | (1<<2)));
4083 }
4084
4085 /* If transmitter is disabled, ignore false link up indication */
4086 bnx2x_cl45_read(bp, phy,
4087 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
4088 if (val1 & (1<<15)) {
4089 DP(NETIF_MSG_LINK, "Tx is disabled\n");
4090 return 0;
4091 }
4092
4093 bnx2x_cl45_read(bp, phy,
4094 MDIO_PMA_DEVAD,
4095 MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
4096
4097 /* Bits 0..2 --> speed detected,
4098 bits 13..15--> link is down */
4099 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4100 link_up = 1;
4101 vars->line_speed = SPEED_10000;
4102 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4103 link_up = 1;
4104 vars->line_speed = SPEED_1000;
4105 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4106 params->port);
4107 } else {
4108 link_up = 0;
4109 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4110 params->port);
4111 }
4112 if (link_up)
4113 bnx2x_ext_phy_resolve_fc(phy, params, vars);
4114 return link_up;
b7737c9b 4115}
62b29a5d 4116
b7737c9b
YR
4117static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
4118 struct link_params *params,
4119 struct link_vars *vars)
4120{
4121 struct bnx2x *bp = params->bp;
62b29a5d 4122 u8 link_up = 0;
b7737c9b 4123 u16 val1, val2;
62b29a5d
YR
4124 u16 link_status = 0;
4125 u16 an1000_status = 0;
ab6ad5a4 4126
62b29a5d
YR
4127 bnx2x_cl45_read(bp, phy,
4128 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
ea4e040a 4129
62b29a5d 4130 DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
ea4e040a 4131
62b29a5d
YR
4132 /* clear the interrupt LASI status register */
4133 bnx2x_cl45_read(bp, phy,
4134 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4135 bnx2x_cl45_read(bp, phy,
4136 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
4137 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
4138 /* Clear MSG-OUT */
4139 bnx2x_cl45_read(bp, phy,
4140 MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
6bbca910 4141
62b29a5d
YR
4142 /* Check the LASI */
4143 bnx2x_cl45_read(bp, phy,
4144 MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_ALARM, &val2);
6bbca910 4145
62b29a5d 4146 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
6bbca910 4147
62b29a5d
YR
4148 /* Check the link status */
4149 bnx2x_cl45_read(bp, phy,
4150 MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
4151 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
ea4e040a 4152
62b29a5d
YR
4153 bnx2x_cl45_read(bp, phy,
4154 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4155 bnx2x_cl45_read(bp, phy,
4156 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4157 link_up = ((val1 & 4) == 4);
4158 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
6bbca910 4159
62b29a5d
YR
4160 if (link_up &&
4161 ((phy->req_line_speed != SPEED_10000))) {
4162 if (bnx2x_8073_xaui_wa(bp, phy) != 0)
4163 return 0;
4164 }
4165 bnx2x_cl45_read(bp, phy,
4166 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4167 bnx2x_cl45_read(bp, phy,
4168 MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
4169
4170 /* Check the link status on 1.1.2 */
4171 bnx2x_cl45_read(bp, phy,
4172 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4173 bnx2x_cl45_read(bp, phy,
4174 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4175 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
4176 "an_link_status=0x%x\n", val2, val1, an1000_status);
4177
4178 link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
4179 if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
4180 /* The SNR will improve about 2dbby
4181 changing the BW and FEE main tap.*/
4182 /* The 1st write to change FFE main
4183 tap is set before restart AN */
4184 /* Change PLL Bandwidth in EDC
4185 register */
4186 bnx2x_cl45_write(bp, phy,
4187 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
4188 0x26BC);
4189
4190 /* Change CDR Bandwidth in EDC register */
4191 bnx2x_cl45_write(bp, phy,
4192 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
4193 0x0333);
4194 }
4195 bnx2x_cl45_read(bp, phy,
4196 MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
4197 &link_status);
4198
4199 /* Bits 0..2 --> speed detected, bits 13..15--> link is down */
4200 if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
4201 link_up = 1;
4202 vars->line_speed = SPEED_10000;
4203 DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
4204 params->port);
4205 } else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
4206 link_up = 1;
4207 vars->line_speed = SPEED_2500;
4208 DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
4209 params->port);
4210 } else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
4211 link_up = 1;
4212 vars->line_speed = SPEED_1000;
4213 DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
4214 params->port);
4215 } else {
4216 link_up = 0;
4217 DP(NETIF_MSG_LINK, "port %x: External link is down\n",
4218 params->port);
4219 }
6bbca910 4220
62b29a5d 4221 return link_up;
b7737c9b
YR
4222}
4223
4224static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
4225 struct link_params *params,
4226 struct link_vars *vars)
4227{
4228 struct bnx2x *bp = params->bp;
62b29a5d 4229 u8 link_up;
b7737c9b 4230 u16 val1, val2;
62b29a5d
YR
4231 bnx2x_cl45_read(bp, phy,
4232 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val2);
4233 bnx2x_cl45_read(bp, phy,
4234 MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_STATUS, &val1);
4235 DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
4236 val2, val1);
4237 bnx2x_cl45_read(bp, phy,
4238 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
4239 bnx2x_cl45_read(bp, phy,
4240 MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
4241 DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
4242 val2, val1);
4243 link_up = ((val1 & 4) == 4);
4244 /* if link is up
4245 * print the AN outcome of the SFX7101 PHY
4246 */
4247 if (link_up) {
4248 bnx2x_cl45_read(bp, phy,
4249 MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
4250 &val2);
4251 vars->line_speed = SPEED_10000;
4252 DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
4253 val2, (val2 & (1<<14)));
4254 }
4255 return link_up;
b7737c9b
YR
4256}
4257
4258static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
4259 struct link_params *params,
4260 struct link_vars *vars)
4261{
4262 struct bnx2x *bp = params->bp;
62b29a5d
YR
4263 u16 val, val1, val2;
4264 u8 link_up = 0;
b7737c9b 4265
62b29a5d
YR
4266 /* Check 10G-BaseT link status */
4267 /* Check PMD signal ok */
4268 bnx2x_cl45_read(bp, phy,
4269 MDIO_AN_DEVAD, 0xFFFA, &val1);
4270 bnx2x_cl45_read(bp, phy,
4271 MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
4272 &val2);
4273 DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
4274
4275 /* Check link 10G */
4276 if (val2 & (1<<11)) {
4277 vars->line_speed = SPEED_10000;
4278 link_up = 1;
4279 } else { /* Check Legacy speed link */
4280 u16 legacy_status, legacy_speed;
4281
4282 /* Enable expansion register 0x42 (Operation mode status) */
4283 bnx2x_cl45_write(bp, phy,
4284 MDIO_AN_DEVAD,
4285 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
4286
4287 /* Get legacy speed operation status */
4288 bnx2x_cl45_read(bp, phy,
4289 MDIO_AN_DEVAD,
4290 MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
4291 &legacy_status);
4292
4293 DP(NETIF_MSG_LINK, "Legacy speed status"
4294 " = 0x%x\n", legacy_status);
4295 link_up = ((legacy_status & (1<<11)) == (1<<11));
4296 if (link_up) {
4297 legacy_speed = (legacy_status & (3<<9));
4298 if (legacy_speed == (0<<9))
4299 vars->line_speed = SPEED_10;
4300 else if (legacy_speed == (1<<9))
4301 vars->line_speed = SPEED_100;
4302 else if (legacy_speed == (2<<9))
4303 vars->line_speed = SPEED_1000;
4304 else /* Should not happen */
4305 vars->line_speed = 0;
4306
4307 if (legacy_status & (1<<8))
4308 vars->duplex = DUPLEX_FULL;
4309 else
4310 vars->duplex = DUPLEX_HALF;
4311
4312 DP(NETIF_MSG_LINK, "Link is up in %dMbps,"
4313 " is_duplex_full= %d\n", vars->line_speed,
4314 (vars->duplex == DUPLEX_FULL));
4315
4316 /* Check legacy speed AN resolution */
e10bc84d 4317 bnx2x_cl45_read(bp, phy,
62b29a5d
YR
4318 MDIO_AN_DEVAD,
4319 MDIO_AN_REG_8481_LEGACY_MII_STATUS,
4320 &val);
4321 if (val & (1<<5))
4322 vars->link_status |=
4323 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
e10bc84d 4324 bnx2x_cl45_read(bp, phy,
62b29a5d
YR
4325 MDIO_AN_DEVAD,
4326 MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
4327 &val);
4328 if ((val & (1<<0)) == 0)
4329 vars->link_status |=
4330 LINK_STATUS_PARALLEL_DETECTION_USED;
4331 }
4332 }
4333 return link_up;
ea4e040a 4334}
ea4e040a
YR
4335static void bnx2x_link_int_enable(struct link_params *params)
4336{
4337 u8 port = params->port;
ea4e040a
YR
4338 u32 mask;
4339 struct bnx2x *bp = params->bp;
ab6ad5a4 4340
ea4e040a
YR
4341 /* setting the status to report on link up
4342 for either XGXS or SerDes */
4343
4344 if (params->switch_cfg == SWITCH_CFG_10G) {
4345 mask = (NIG_MASK_XGXS0_LINK10G |
4346 NIG_MASK_XGXS0_LINK_STATUS);
4347 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
e10bc84d
YR
4348 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4349 params->phy[INT_PHY].type !=
4350 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
ea4e040a
YR
4351 mask |= NIG_MASK_MI_INT;
4352 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4353 }
4354
4355 } else { /* SerDes */
4356 mask = NIG_MASK_SERDES0_LINK_STATUS;
4357 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
e10bc84d
YR
4358 if (!(SINGLE_MEDIA_DIRECT(params)) &&
4359 params->phy[INT_PHY].type !=
4360 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
ea4e040a
YR
4361 mask |= NIG_MASK_MI_INT;
4362 DP(NETIF_MSG_LINK, "enabled external phy int\n");
4363 }
4364 }
4365 bnx2x_bits_en(bp,
4366 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4367 mask);
ab6ad5a4
EG
4368
4369 DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
ea4e040a
YR
4370 (params->switch_cfg == SWITCH_CFG_10G),
4371 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
ea4e040a
YR
4372 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
4373 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4374 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4375 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
4376 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4377 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4378 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4379}
4380
2f904460
EG
4381static void bnx2x_8481_rearm_latch_signal(struct bnx2x *bp, u8 port,
4382 u8 is_mi_int)
4383{
4384 u32 latch_status = 0, is_mi_int_status;
4385 /* Disable the MI INT ( external phy int )
4386 * by writing 1 to the status register. Link down indication
4387 * is high-active-signal, so in this case we need to write the
4388 * status to clear the XOR
4389 */
4390 /* Read Latched signals */
4391 latch_status = REG_RD(bp,
4392 NIG_REG_LATCH_STATUS_0 + port*8);
4393 is_mi_int_status = REG_RD(bp,
4394 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4);
4395 DP(NETIF_MSG_LINK, "original_signal = 0x%x, nig_status = 0x%x,"
4396 "latch_status = 0x%x\n",
4397 is_mi_int, is_mi_int_status, latch_status);
4398 /* Handle only those with latched-signal=up.*/
4399 if (latch_status & 1) {
4400 /* For all latched-signal=up,Write original_signal to status */
4401 if (is_mi_int)
4402 bnx2x_bits_en(bp,
4403 NIG_REG_STATUS_INTERRUPT_PORT0
4404 + port*4,
4405 NIG_STATUS_EMAC0_MI_INT);
4406 else
4407 bnx2x_bits_dis(bp,
4408 NIG_REG_STATUS_INTERRUPT_PORT0
4409 + port*4,
4410 NIG_STATUS_EMAC0_MI_INT);
4411 /* For all latched-signal=up : Re-Arm Latch signals */
4412 REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
4413 (latch_status & 0xfffe) | (latch_status & 1));
4414 }
4415}
e10bc84d 4416
ea4e040a
YR
4417/*
4418 * link management
4419 */
4420static void bnx2x_link_int_ack(struct link_params *params,
2f904460
EG
4421 struct link_vars *vars, u8 is_10g,
4422 u8 is_mi_int)
ea4e040a
YR
4423{
4424 struct bnx2x *bp = params->bp;
4425 u8 port = params->port;
4426
4427 /* first reset all status
4428 * we assume only one line will be change at a time */
4429 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4430 (NIG_STATUS_XGXS0_LINK10G |
4431 NIG_STATUS_XGXS0_LINK_STATUS |
4432 NIG_STATUS_SERDES0_LINK_STATUS));
e10bc84d 4433 if ((params->phy[EXT_PHY1].type
4f60dab1 4434 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481) ||
e10bc84d 4435 (params->phy[EXT_PHY1].type
4f60dab1 4436 == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823)) {
2f904460
EG
4437 bnx2x_8481_rearm_latch_signal(bp, port, is_mi_int);
4438 }
ea4e040a
YR
4439 if (vars->phy_link_up) {
4440 if (is_10g) {
4441 /* Disable the 10G link interrupt
4442 * by writing 1 to the status register
4443 */
4444 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
4445 bnx2x_bits_en(bp,
4446 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4447 NIG_STATUS_XGXS0_LINK10G);
4448
4449 } else if (params->switch_cfg == SWITCH_CFG_10G) {
4450 /* Disable the link interrupt
4451 * by writing 1 to the relevant lane
4452 * in the status register
4453 */
4454 u32 ser_lane = ((params->lane_config &
4455 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4456 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4457
2f904460
EG
4458 DP(NETIF_MSG_LINK, "%d speed XGXS phy link up\n",
4459 vars->line_speed);
ea4e040a
YR
4460 bnx2x_bits_en(bp,
4461 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4462 ((1 << ser_lane) <<
4463 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
4464
4465 } else { /* SerDes */
4466 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
4467 /* Disable the link interrupt
4468 * by writing 1 to the status register
4469 */
4470 bnx2x_bits_en(bp,
4471 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
4472 NIG_STATUS_SERDES0_LINK_STATUS);
4473 }
4474
ea4e040a
YR
4475 }
4476}
4477
b7737c9b
YR
4478static u8 bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
4479{
4480 if (*len < 5)
4481 return -EINVAL;
4482 str[0] = (spirom_ver & 0xFF);
4483 str[1] = (spirom_ver & 0xFF00) >> 8;
4484 str[2] = (spirom_ver & 0xFF0000) >> 16;
4485 str[3] = (spirom_ver & 0xFF000000) >> 24;
4486 str[4] = '\0';
4487 *len -= 5;
4488 return 0;
4489}
4490
4491static u8 bnx2x_format_ver(u32 num, u8 *str, u16 *len)
ea4e040a
YR
4492{
4493 u8 *str_ptr = str;
4494 u32 mask = 0xf0000000;
4495 u8 shift = 8*4;
4496 u8 digit;
b7737c9b 4497 if (*len < 10) {
025dfdaf 4498 /* Need more than 10chars for this format */
ea4e040a
YR
4499 *str_ptr = '\0';
4500 return -EINVAL;
4501 }
4502 while (shift > 0) {
4503
4504 shift -= 4;
4505 digit = ((num & mask) >> shift);
4506 if (digit < 0xa)
4507 *str_ptr = digit + '0';
4508 else
4509 *str_ptr = digit - 0xa + 'a';
4510 str_ptr++;
4511 mask = mask >> 4;
4512 if (shift == 4*4) {
4513 *str_ptr = ':';
4514 str_ptr++;
4515 }
4516 }
4517 *str_ptr = '\0';
4518 return 0;
4519}
4520
b7737c9b
YR
4521static u8 bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
4522{
4523 u8 status = 0;
4524 u32 spirom_ver;
4525 spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
4526 status = bnx2x_format_ver(spirom_ver, str, len);
4527 return status;
4528}
4529
4530static u8 bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
4531{
4532 str[0] = '\0';
4533 (*len)--;
4534 return 0;
4535}
4536
ea4e040a
YR
4537u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
4538 u8 *version, u16 len)
4539{
0376d5b2 4540 struct bnx2x *bp;
a35da8db 4541 u32 spirom_ver = 0;
b7737c9b
YR
4542 u8 status = 0;
4543 u8 *ver_p = version;
ea4e040a
YR
4544 if (version == NULL || params == NULL)
4545 return -EINVAL;
0376d5b2 4546 bp = params->bp;
ea4e040a 4547
b7737c9b
YR
4548 /* Extract first external phy*/
4549 version[0] = '\0';
4550 spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
ea4e040a 4551
b7737c9b
YR
4552 if (params->phy[EXT_PHY1].format_fw_ver)
4553 status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
4554 ver_p,
4555 &len);
ea4e040a
YR
4556 return status;
4557}
4558
e10bc84d 4559static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
62b29a5d 4560 struct link_params *params)
ea4e040a
YR
4561{
4562 u8 port = params->port;
4563 struct bnx2x *bp = params->bp;
4564
62b29a5d 4565 if (phy->req_line_speed != SPEED_1000) {
6378c025 4566 u32 md_devad;
ea4e040a
YR
4567
4568 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
4569
4570 /* change the uni_phy_addr in the nig */
4571 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
4572 port*0x18));
4573
4574 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
4575
e10bc84d 4576 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
4577 5,
4578 (MDIO_REG_BANK_AER_BLOCK +
4579 (MDIO_AER_BLOCK_AER_REG & 0xf)),
4580 0x2800);
4581
e10bc84d 4582 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
4583 5,
4584 (MDIO_REG_BANK_CL73_IEEEB0 +
4585 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
4586 0x6041);
3858276b 4587 msleep(200);
ea4e040a 4588 /* set aer mmd back */
e10bc84d 4589 bnx2x_set_aer_mmd(params, phy);
ea4e040a
YR
4590
4591 /* and md_devad */
4592 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
4593 md_devad);
4594
4595 } else {
e10bc84d 4596 u16 mii_ctrl;
ea4e040a 4597 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
e10bc84d
YR
4598 bnx2x_cl45_read(bp, phy, 5,
4599 (MDIO_REG_BANK_COMBO_IEEE0 +
4600 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4601 &mii_ctrl);
4602 bnx2x_cl45_write(bp, phy, 5,
4603 (MDIO_REG_BANK_COMBO_IEEE0 +
4604 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
4605 mii_ctrl |
4606 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
ea4e040a
YR
4607 }
4608}
4609
b7737c9b
YR
4610static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
4611 struct link_params *params)
ea4e040a
YR
4612{
4613 struct bnx2x *bp = params->bp;
b7737c9b
YR
4614 DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
4615 bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
4616}
ea4e040a 4617
b7737c9b
YR
4618static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
4619 struct link_params *params)
4620{
4621 struct bnx2x *bp = params->bp;
4622 /* SFX7101_XGXS_TEST1 */
4623 bnx2x_cl45_write(bp, phy,
4624 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
ea4e040a 4625}
ea4e040a
YR
4626/*
4627 *------------------------------------------------------------------------
4628 * bnx2x_override_led_value -
4629 *
e10bc84d 4630 * Override the led value of the requested led
ea4e040a
YR
4631 *
4632 *------------------------------------------------------------------------
4633 */
4634u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
4635 u32 led_idx, u32 value)
4636{
4637 u32 reg_val;
4638
4639 /* If port 0 then use EMAC0, else use EMAC1*/
4640 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
4641
4642 DP(NETIF_MSG_LINK,
4643 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
4644 port, led_idx, value);
4645
4646 switch (led_idx) {
4647 case 0: /* 10MB led */
4648 /* Read the current value of the LED register in
4649 the EMAC block */
4650 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4651 /* Set the OVERRIDE bit to 1 */
4652 reg_val |= EMAC_LED_OVERRIDE;
4653 /* If value is 1, set the 10M_OVERRIDE bit,
4654 otherwise reset it.*/
4655 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
4656 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
4657 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4658 break;
4659 case 1: /*100MB led */
4660 /*Read the current value of the LED register in
4661 the EMAC block */
4662 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4663 /* Set the OVERRIDE bit to 1 */
4664 reg_val |= EMAC_LED_OVERRIDE;
4665 /* If value is 1, set the 100M_OVERRIDE bit,
4666 otherwise reset it.*/
4667 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
4668 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
4669 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4670 break;
4671 case 2: /* 1000MB led */
4672 /* Read the current value of the LED register in the
4673 EMAC block */
4674 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4675 /* Set the OVERRIDE bit to 1 */
4676 reg_val |= EMAC_LED_OVERRIDE;
4677 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
4678 reset it. */
4679 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
4680 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
4681 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4682 break;
4683 case 3: /* 2500MB led */
4684 /* Read the current value of the LED register in the
4685 EMAC block*/
4686 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
4687 /* Set the OVERRIDE bit to 1 */
4688 reg_val |= EMAC_LED_OVERRIDE;
4689 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
4690 reset it.*/
4691 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
4692 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
4693 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4694 break;
4695 case 4: /*10G led */
4696 if (port == 0) {
4697 REG_WR(bp, NIG_REG_LED_10G_P0,
4698 value);
4699 } else {
4700 REG_WR(bp, NIG_REG_LED_10G_P1,
4701 value);
4702 }
4703 break;
4704 case 5: /* TRAFFIC led */
4705 /* Find if the traffic control is via BMAC or EMAC */
4706 if (port == 0)
4707 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
4708 else
4709 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
4710
4711 /* Override the traffic led in the EMAC:*/
4712 if (reg_val == 1) {
4713 /* Read the current value of the LED register in
4714 the EMAC block */
4715 reg_val = REG_RD(bp, emac_base +
4716 EMAC_REG_EMAC_LED);
4717 /* Set the TRAFFIC_OVERRIDE bit to 1 */
4718 reg_val |= EMAC_LED_OVERRIDE;
4719 /* If value is 1, set the TRAFFIC bit, otherwise
4720 reset it.*/
4721 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
4722 (reg_val & ~EMAC_LED_TRAFFIC);
4723 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
4724 } else { /* Override the traffic led in the BMAC: */
4725 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4726 + port*4, 1);
4727 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
4728 value);
4729 }
4730 break;
4731 default:
4732 DP(NETIF_MSG_LINK,
4733 "bnx2x_override_led_value() unknown led index %d "
4734 "(should be 0-5)\n", led_idx);
4735 return -EINVAL;
4736 }
4737
4738 return 0;
4739}
4740
4741
7846e471 4742u8 bnx2x_set_led(struct link_params *params, u8 mode, u32 speed)
ea4e040a 4743{
7846e471
YR
4744 u8 port = params->port;
4745 u16 hw_led_mode = params->hw_led_mode;
ea4e040a 4746 u8 rc = 0;
345b5d52
EG
4747 u32 tmp;
4748 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
7846e471 4749 struct bnx2x *bp = params->bp;
ea4e040a
YR
4750 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
4751 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
4752 speed, hw_led_mode);
4753 switch (mode) {
4754 case LED_MODE_OFF:
4755 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
4756 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4757 SHARED_HW_CFG_LED_MAC1);
345b5d52
EG
4758
4759 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3196a88a 4760 EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
ea4e040a
YR
4761 break;
4762
4763 case LED_MODE_OPER:
e10bc84d 4764 if (SINGLE_MEDIA_DIRECT(params)) {
7846e471
YR
4765 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
4766 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
4767 } else {
4768 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
4769 hw_led_mode);
4770 }
4771
ea4e040a
YR
4772 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
4773 port*4, 0);
4774 /* Set blinking rate to ~15.9Hz */
4775 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
4776 LED_BLINK_RATE_VAL);
4777 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
4778 port*4, 1);
345b5d52 4779 tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3196a88a 4780 EMAC_WR(bp, EMAC_REG_EMAC_LED,
345b5d52
EG
4781 (tmp & (~EMAC_LED_OVERRIDE)));
4782
7846e471 4783 if (CHIP_IS_E1(bp) &&
34f80b04 4784 ((speed == SPEED_2500) ||
ea4e040a
YR
4785 (speed == SPEED_1000) ||
4786 (speed == SPEED_100) ||
4787 (speed == SPEED_10))) {
4788 /* On Everest 1 Ax chip versions for speeds less than
4789 10G LED scheme is different */
4790 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
4791 + port*4, 1);
4792 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
4793 port*4, 0);
4794 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
4795 port*4, 1);
4796 }
4797 break;
4798
4799 default:
4800 rc = -EINVAL;
4801 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
4802 mode);
4803 break;
4804 }
4805 return rc;
4806
4807}
4808
4809u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
4810{
4811 struct bnx2x *bp = params->bp;
4812 u16 gp_status = 0;
4813
e10bc84d 4814 CL45_RD_OVER_CL22(bp, &params->phy[INT_PHY],
ea4e040a
YR
4815 MDIO_REG_BANK_GP_STATUS,
4816 MDIO_GP_STATUS_TOP_AN_STATUS1,
4817 &gp_status);
4818 /* link is up only if both local phy and external phy are up */
b7737c9b
YR
4819 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
4820 u8 ext_phy_link_up = 1;
4821 struct link_vars temp_vars;
4822 if (params->phy[EXT_PHY1].read_status)
4823 ext_phy_link_up &=
4824 params->phy[EXT_PHY1].read_status(
4825 &params->phy[EXT_PHY1],
4826 params, &temp_vars);
4827 if (ext_phy_link_up)
4828 return 0;
4829 }
ea4e040a
YR
4830
4831 return -ESRCH;
4832}
4833
4834static u8 bnx2x_link_initialize(struct link_params *params,
4835 struct link_vars *vars)
4836{
4837 struct bnx2x *bp = params->bp;
4838 u8 port = params->port;
4839 u8 rc = 0;
b7737c9b 4840 u8 phy_index, non_ext_phy;
e10bc84d
YR
4841 struct bnx2x_phy *ext_phy = &params->phy[EXT_PHY1];
4842 struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
ea4e040a 4843 /* Activate the external PHY */
ea4e040a 4844
e10bc84d 4845 bnx2x_set_aer_mmd(params, int_phy);
ea4e040a
YR
4846
4847 if (vars->phy_flags & PHY_XGXS_FLAG)
e10bc84d 4848 bnx2x_set_master_ln(params, int_phy);
ea4e040a 4849
e10bc84d
YR
4850 rc = bnx2x_reset_unicore(params, int_phy,
4851 int_phy->type ==
4852 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT);
ea4e040a
YR
4853 /* reset the SerDes and wait for reset bit return low */
4854 if (rc != 0)
4855 return rc;
4856
e10bc84d 4857 bnx2x_set_aer_mmd(params, int_phy);
ea4e040a
YR
4858
4859 /* setting the masterLn_def again after the reset */
4860 if (vars->phy_flags & PHY_XGXS_FLAG) {
e10bc84d
YR
4861 bnx2x_set_master_ln(params, int_phy);
4862 bnx2x_set_swap_lanes(params, int_phy);
ea4e040a
YR
4863 }
4864
ea4e040a 4865 if (vars->phy_flags & PHY_XGXS_FLAG) {
44722d1d 4866 if ((params->req_line_speed &&
ea4e040a 4867 ((params->req_line_speed == SPEED_100) ||
44722d1d
EG
4868 (params->req_line_speed == SPEED_10))) ||
4869 (!params->req_line_speed &&
4870 (params->speed_cap_mask >=
4871 PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
4872 (params->speed_cap_mask <
4873 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4874 )) {
ea4e040a
YR
4875 vars->phy_flags |= PHY_SGMII_FLAG;
4876 } else {
4877 vars->phy_flags &= ~PHY_SGMII_FLAG;
4878 }
4879 }
57963ed9
YR
4880 /* In case of external phy existance, the line speed would be the
4881 line speed linked up by the external phy. In case it is direct only,
4882 then the line_speed during initialization will be equal to the
4883 req_line_speed*/
4884 vars->line_speed = params->req_line_speed;
ea4e040a 4885
e10bc84d 4886 bnx2x_calc_ieee_aneg_adv(int_phy, params, &vars->ieee_fc);
ea4e040a 4887
57963ed9 4888 /* init ext phy and enable link state int */
e10bc84d
YR
4889 non_ext_phy = ((ext_phy->type ==
4890 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
8660d8c3 4891 (params->loopback_mode == LOOPBACK_XGXS_10));
57963ed9
YR
4892
4893 if (non_ext_phy ||
e10bc84d
YR
4894 (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) ||
4895 (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706) ||
4896 (ext_phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) ||
8660d8c3 4897 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
e10bc84d
YR
4898 if (vars->line_speed == SPEED_AUTO_NEG)
4899 bnx2x_set_parallel_detection(int_phy, params);
4900 bnx2x_init_internal_phy(int_phy, params, vars);
ea4e040a
YR
4901 }
4902
57963ed9 4903 if (!non_ext_phy)
b7737c9b
YR
4904 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
4905 phy_index++) {
4906 params->phy[phy_index].config_init(
4907 &params->phy[phy_index],
4908 params, vars);
4909 }
ea4e040a
YR
4910
4911 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
57963ed9
YR
4912 (NIG_STATUS_XGXS0_LINK10G |
4913 NIG_STATUS_XGXS0_LINK_STATUS |
4914 NIG_STATUS_SERDES0_LINK_STATUS));
ea4e040a
YR
4915
4916 return rc;
ea4e040a
YR
4917}
4918
b7737c9b
YR
4919static void set_phy_vars(struct link_params *params)
4920{
4921 struct bnx2x *bp = params->bp;
4922 u8 actual_phy_idx, phy_index;
4923
4924 for (phy_index = INT_PHY; phy_index < params->num_phys;
4925 phy_index++) {
4926
4927 actual_phy_idx = phy_index;
4928 params->phy[actual_phy_idx].req_flow_ctrl =
4929 params->req_flow_ctrl;
4930
4931 params->phy[actual_phy_idx].req_line_speed =
4932 params->req_line_speed;
4933
4934 params->phy[actual_phy_idx].speed_cap_mask =
4935 params->speed_cap_mask;
4936
4937 params->phy[actual_phy_idx].req_duplex =
4938 params->req_duplex;
4939
4940 DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
4941 " speed_cap_mask %x\n",
4942 params->phy[actual_phy_idx].req_flow_ctrl,
4943 params->phy[actual_phy_idx].req_line_speed,
4944 params->phy[actual_phy_idx].speed_cap_mask);
4945 }
4946}
4947
ea4e040a
YR
4948u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
4949{
4950 struct bnx2x *bp = params->bp;
ea4e040a 4951 u32 val;
ab6ad5a4
EG
4952
4953 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
4954 DP(NETIF_MSG_LINK, "req_speed %d, req_flowctrl %d\n",
4955 params->req_line_speed, params->req_flow_ctrl);
ea4e040a 4956 vars->link_status = 0;
57963ed9
YR
4957 vars->phy_link_up = 0;
4958 vars->link_up = 0;
4959 vars->line_speed = 0;
4960 vars->duplex = DUPLEX_FULL;
c0700f90 4961 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
57963ed9 4962 vars->mac_type = MAC_TYPE_NONE;
b7737c9b 4963 vars->phy_flags = 0;
ea4e040a
YR
4964
4965 /* disable attentions */
4966 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
4967 (NIG_MASK_XGXS0_LINK_STATUS |
4968 NIG_MASK_XGXS0_LINK10G |
4969 NIG_MASK_SERDES0_LINK_STATUS |
4970 NIG_MASK_MI_INT));
4971
4972 bnx2x_emac_init(params, vars);
4973
b7737c9b
YR
4974 if (params->num_phys == 0) {
4975 DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
4976 return -EINVAL;
4977 }
4978 set_phy_vars(params);
4979
4980 DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
ea4e040a 4981 if (CHIP_REV_IS_FPGA(bp)) {
ab6ad5a4 4982
ea4e040a
YR
4983 vars->link_up = 1;
4984 vars->line_speed = SPEED_10000;
4985 vars->duplex = DUPLEX_FULL;
c0700f90 4986 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a 4987 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
34f80b04
EG
4988 /* enable on E1.5 FPGA */
4989 if (CHIP_IS_E1H(bp)) {
4990 vars->flow_ctrl |=
ab6ad5a4
EG
4991 (BNX2X_FLOW_CTRL_TX |
4992 BNX2X_FLOW_CTRL_RX);
34f80b04
EG
4993 vars->link_status |=
4994 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
4995 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
4996 }
ea4e040a
YR
4997
4998 bnx2x_emac_enable(params, vars, 0);
4999 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5000 /* disable drain */
ab6ad5a4 5001 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
ea4e040a
YR
5002
5003 /* update shared memory */
5004 bnx2x_update_mng(params, vars->link_status);
5005
5006 return 0;
5007
5008 } else
5009 if (CHIP_REV_IS_EMUL(bp)) {
5010
5011 vars->link_up = 1;
5012 vars->line_speed = SPEED_10000;
5013 vars->duplex = DUPLEX_FULL;
c0700f90 5014 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
5015 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
5016
5017 bnx2x_bmac_enable(params, vars, 0);
5018
5019 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
5020 /* Disable drain */
5021 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5022 + params->port*4, 0);
5023
5024 /* update shared memory */
5025 bnx2x_update_mng(params, vars->link_status);
5026
5027 return 0;
5028
5029 } else
5030 if (params->loopback_mode == LOOPBACK_BMAC) {
ab6ad5a4 5031
ea4e040a
YR
5032 vars->link_up = 1;
5033 vars->line_speed = SPEED_10000;
5034 vars->duplex = DUPLEX_FULL;
c0700f90 5035 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
5036 vars->mac_type = MAC_TYPE_BMAC;
5037
5038 vars->phy_flags = PHY_XGXS_FLAG;
5039
5040 bnx2x_phy_deassert(params, vars->phy_flags);
e10bc84d 5041
ea4e040a
YR
5042 /* set bmac loopback */
5043 bnx2x_bmac_enable(params, vars, 1);
5044
5045 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5046 params->port*4, 0);
ab6ad5a4 5047
ea4e040a 5048 } else if (params->loopback_mode == LOOPBACK_EMAC) {
ab6ad5a4 5049
ea4e040a
YR
5050 vars->link_up = 1;
5051 vars->line_speed = SPEED_1000;
5052 vars->duplex = DUPLEX_FULL;
c0700f90 5053 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
5054 vars->mac_type = MAC_TYPE_EMAC;
5055
5056 vars->phy_flags = PHY_XGXS_FLAG;
5057
5058 bnx2x_phy_deassert(params, vars->phy_flags);
5059 /* set bmac loopback */
5060 bnx2x_emac_enable(params, vars, 1);
b7737c9b 5061 bnx2x_emac_program(params, vars);
ea4e040a
YR
5062 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5063 params->port*4, 0);
ab6ad5a4 5064
ea4e040a 5065 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
ab6ad5a4
EG
5066 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
5067
ea4e040a
YR
5068 vars->link_up = 1;
5069 vars->line_speed = SPEED_10000;
5070 vars->duplex = DUPLEX_FULL;
c0700f90 5071 vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
ea4e040a
YR
5072
5073 vars->phy_flags = PHY_XGXS_FLAG;
5074
5075 val = REG_RD(bp,
5076 NIG_REG_XGXS0_CTRL_PHY_ADDR+
5077 params->port*0x18);
b7737c9b 5078
ea4e040a
YR
5079 bnx2x_phy_deassert(params, vars->phy_flags);
5080 bnx2x_link_initialize(params, vars);
5081
5082 vars->mac_type = MAC_TYPE_BMAC;
5083
5084 bnx2x_bmac_enable(params, vars, 0);
5085
5086 if (params->loopback_mode == LOOPBACK_XGXS_10) {
5087 /* set 10G XGXS loopback */
b7737c9b
YR
5088 params->phy[INT_PHY].config_loopback(
5089 &params->phy[INT_PHY],
5090 params);
5091
ea4e040a
YR
5092 } else {
5093 /* set external phy loopback */
b7737c9b
YR
5094 u8 phy_index;
5095 for (phy_index = EXT_PHY1;
5096 phy_index < params->num_phys; phy_index++) {
5097 if (params->phy[phy_index].config_loopback)
5098 params->phy[phy_index].config_loopback(
5099 &params->phy[phy_index],
62b29a5d 5100 params);
b7737c9b 5101 }
ea4e040a 5102 }
e10bc84d 5103
ea4e040a
YR
5104 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
5105 params->port*4, 0);
ba71d313 5106
7846e471 5107 bnx2x_set_led(params, LED_MODE_OPER, vars->line_speed);
ea4e040a
YR
5108 } else
5109 /* No loopback */
5110 {
b7737c9b
YR
5111 if (params->switch_cfg == SWITCH_CFG_10G)
5112 vars->phy_flags = PHY_XGXS_FLAG;
ea4e040a 5113 bnx2x_phy_deassert(params, vars->phy_flags);
ea4e040a 5114 bnx2x_link_initialize(params, vars);
57963ed9 5115 msleep(30);
ea4e040a
YR
5116 bnx2x_link_int_enable(params);
5117 }
5118 return 0;
5119}
5120
589abe3a 5121
b7737c9b
YR
5122static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
5123 struct link_params *params)
e10bc84d 5124{
b7737c9b
YR
5125 struct bnx2x *bp = params->bp;
5126 DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
589abe3a 5127 /* Set serial boot control for external load */
e10bc84d 5128 bnx2x_cl45_write(bp, phy,
b7737c9b
YR
5129 MDIO_PMA_DEVAD,
5130 MDIO_PMA_REG_GEN_CTRL, 0x0001);
5131}
5132
5133static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
5134 struct link_params *params)
5135{
5136 struct bnx2x *bp = params->bp;
5137 /* Disable Transmitter */
5138 bnx2x_sfp_set_transmitter(bp, phy, params->port, 0);
5139}
5140static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
5141 struct link_params *params)
5142{
5143 struct bnx2x *bp = params->bp;
5144 u8 gpio_port;
5145 gpio_port = params->port;
5146 DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
5147 gpio_port);
5148 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5149 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5150 gpio_port);
5151}
5152static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
5153 struct link_params *params)
5154{
5155 bnx2x_cl45_write(params->bp, phy,
5156 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
5157 bnx2x_cl45_write(params->bp, phy,
5158 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
5159}
5160
5161static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
5162 struct link_params *params)
5163{
5164 struct bnx2x *bp = params->bp;
5165 u8 port = params->port;
5166 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
5167 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5168 port);
5169}
5170
5171static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
5172 struct link_params *params)
5173{
5174 struct bnx2x *bp = params->bp;
5175 u8 gpio_port;
5176 /* HW reset */
5177 gpio_port = params->port;
5178 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5179 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5180 gpio_port);
5181 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
5182 MISC_REGISTERS_GPIO_OUTPUT_LOW,
5183 gpio_port);
5184 DP(NETIF_MSG_LINK, "reset external PHY\n");
5185}
5186
5187static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
5188 struct link_params *params)
5189{
5190 /* reset the SerDes/XGXS */
5191 REG_WR(params->bp, GRCBASE_MISC +
5192 MISC_REGISTERS_RESET_REG_3_CLEAR,
5193 (0x1ff << (params->port*16)));
589abe3a
EG
5194}
5195
5196u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
5197 u8 reset_ext_phy)
ea4e040a 5198{
ea4e040a 5199 struct bnx2x *bp = params->bp;
e10bc84d 5200
b7737c9b 5201 u8 phy_index, port = params->port;
e10bc84d 5202
d5cb9e99 5203 DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
ea4e040a 5204 /* disable attentions */
ea4e040a
YR
5205 vars->link_status = 0;
5206 bnx2x_update_mng(params, vars->link_status);
5207 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5208 (NIG_MASK_XGXS0_LINK_STATUS |
5209 NIG_MASK_XGXS0_LINK10G |
5210 NIG_MASK_SERDES0_LINK_STATUS |
5211 NIG_MASK_MI_INT));
5212
5213 /* activate nig drain */
5214 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5215
5216 /* disable nig egress interface */
5217 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5218 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5219
5220 /* Stop BigMac rx */
5221 bnx2x_bmac_rx_disable(bp, port);
5222
5223 /* disable emac */
5224 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5225
5226 msleep(10);
5227 /* The PHY reset is controled by GPIO 1
5228 * Hold it as vars low
5229 */
5230 /* clear link led */
7846e471 5231 bnx2x_set_led(params, LED_MODE_OFF, 0);
589abe3a 5232 if (reset_ext_phy) {
b7737c9b
YR
5233 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5234 phy_index++) {
5235 if (params->phy[phy_index].link_reset)
5236 params->phy[phy_index].link_reset(
5237 &params->phy[phy_index],
5238 params);
ea4e040a
YR
5239 }
5240 }
ea4e040a 5241
b7737c9b
YR
5242 if (params->phy[INT_PHY].link_reset)
5243 params->phy[INT_PHY].link_reset(
5244 &params->phy[INT_PHY], params);
ea4e040a
YR
5245 /* reset BigMac */
5246 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
5247 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5248
5249 /* disable nig ingress interface */
5250 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
5251 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
5252 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
5253 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
5254 vars->link_up = 0;
5255 return 0;
5256}
5257
e10bc84d 5258
57963ed9
YR
5259static u8 bnx2x_update_link_down(struct link_params *params,
5260 struct link_vars *vars)
5261{
5262 struct bnx2x *bp = params->bp;
5263 u8 port = params->port;
ab6ad5a4 5264
57963ed9 5265 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
7846e471 5266 bnx2x_set_led(params, LED_MODE_OFF, 0);
57963ed9
YR
5267
5268 /* indicate no mac active */
5269 vars->mac_type = MAC_TYPE_NONE;
5270
5271 /* update shared memory */
5272 vars->link_status = 0;
5273 vars->line_speed = 0;
5274 bnx2x_update_mng(params, vars->link_status);
5275
5276 /* activate nig drain */
5277 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
5278
6c55c3cd
EG
5279 /* disable emac */
5280 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5281
5282 msleep(10);
5283
57963ed9
YR
5284 /* reset BigMac */
5285 bnx2x_bmac_rx_disable(bp, params->port);
5286 REG_WR(bp, GRCBASE_MISC +
5287 MISC_REGISTERS_RESET_REG_2_CLEAR,
5288 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
5289 return 0;
5290}
5291
5292static u8 bnx2x_update_link_up(struct link_params *params,
5293 struct link_vars *vars,
b7737c9b 5294 u8 link_10g)
57963ed9
YR
5295{
5296 struct bnx2x *bp = params->bp;
5297 u8 port = params->port;
5298 u8 rc = 0;
ab6ad5a4 5299
57963ed9
YR
5300 vars->link_status |= LINK_STATUS_LINK_UP;
5301 if (link_10g) {
5302 bnx2x_bmac_enable(params, vars, 0);
7846e471 5303 bnx2x_set_led(params, LED_MODE_OPER, SPEED_10000);
57963ed9 5304 } else {
b7737c9b 5305 rc = bnx2x_emac_program(params, vars);
57963ed9 5306
0c786f02
YR
5307 bnx2x_emac_enable(params, vars, 0);
5308
57963ed9 5309 /* AN complete? */
e10bc84d
YR
5310 if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
5311 && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
5312 SINGLE_MEDIA_DIRECT(params))
5313 bnx2x_set_gmii_tx_driver(params);
57963ed9
YR
5314 }
5315
5316 /* PBF - link up */
5317 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
5318 vars->line_speed);
5319
5320 /* disable drain */
5321 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
5322
5323 /* update shared memory */
5324 bnx2x_update_mng(params, vars->link_status);
6c55c3cd 5325 msleep(20);
57963ed9
YR
5326 return rc;
5327}
b7737c9b
YR
5328/**
5329 * The bnx2x_link_update function should be called upon link
5330 * interrupt.
5331 * Link is considered up as follows:
5332 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
5333 * to be up
5334 * - SINGLE_MEDIA - The link between the 577xx and the external
5335 * phy (XGXS) need to up as well as the external link of the
5336 * phy (PHY_EXT1)
5337 * - DUAL_MEDIA - The link between the 577xx and the first
5338 * external phy needs to be up, and at least one of the 2
5339 * external phy link must be up.
62b29a5d 5340 */
ea4e040a
YR
5341u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
5342{
5343 struct bnx2x *bp = params->bp;
b7737c9b 5344 struct link_vars phy_vars[MAX_PHYS];
ea4e040a 5345 u8 port = params->port;
b7737c9b
YR
5346 u8 link_10g, phy_index;
5347 u8 ext_phy_link_up = 0, cur_link_up, rc = 0;
2f904460 5348 u8 is_mi_int = 0;
b7737c9b
YR
5349 u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
5350 u8 active_external_phy = INT_PHY;
5351 vars->link_status = 0;
5352 for (phy_index = INT_PHY; phy_index < params->num_phys;
5353 phy_index++) {
5354 phy_vars[phy_index].flow_ctrl = 0;
5355 phy_vars[phy_index].link_status = 0;
5356 phy_vars[phy_index].line_speed = 0;
5357 phy_vars[phy_index].duplex = DUPLEX_FULL;
5358 phy_vars[phy_index].phy_link_up = 0;
5359 phy_vars[phy_index].link_up = 0;
5360 }
ea4e040a
YR
5361
5362 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
2f904460
EG
5363 port, (vars->phy_flags & PHY_XGXS_FLAG),
5364 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
ea4e040a 5365
2f904460
EG
5366 is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
5367 port*0x18) > 0);
ea4e040a 5368 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
2f904460
EG
5369 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5370 is_mi_int,
5371 REG_RD(bp,
5372 NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
ea4e040a
YR
5373
5374 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5375 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5376 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5377
6c55c3cd
EG
5378 /* disable emac */
5379 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
5380
b7737c9b
YR
5381 /**
5382 * Step 1:
5383 * Check external link change only for external phys, and apply
5384 * priority selection between them in case the link on both phys
5385 * is up. Note that the instead of the common vars, a temporary
5386 * vars argument is used since each phy may have different link/
5387 * speed/duplex result
5388 */
5389 for (phy_index = EXT_PHY1; phy_index < params->num_phys;
5390 phy_index++) {
5391 struct bnx2x_phy *phy = &params->phy[phy_index];
5392 if (!phy->read_status)
5393 continue;
5394 /* Read link status and params of this ext phy */
5395 cur_link_up = phy->read_status(phy, params,
5396 &phy_vars[phy_index]);
5397 if (cur_link_up) {
5398 DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
5399 phy_index);
5400 } else {
5401 DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
5402 phy_index);
5403 continue;
5404 }
57963ed9 5405
b7737c9b
YR
5406 if (!ext_phy_link_up) {
5407 ext_phy_link_up = 1;
5408 active_external_phy = phy_index;
5409 }
5410 }
5411 prev_line_speed = vars->line_speed;
5412 /**
5413 * Step 2:
5414 * Read the status of the internal phy. In case of
5415 * DIRECT_SINGLE_MEDIA board, this link is the external link,
5416 * otherwise this is the link between the 577xx and the first
5417 * external phy
5418 */
5419 if (params->phy[INT_PHY].read_status)
5420 params->phy[INT_PHY].read_status(
5421 &params->phy[INT_PHY],
5422 params, vars);
5423 /**
5424 * The INT_PHY flow control reside in the vars. This include the
5425 * case where the speed or flow control are not set to AUTO.
5426 * Otherwise, the active external phy flow control result is set
5427 * to the vars. The ext_phy_line_speed is needed to check if the
5428 * speed is different between the internal phy and external phy.
5429 * This case may be result of intermediate link speed change.
5430 */
5431 if (active_external_phy > INT_PHY) {
5432 vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
5433 /**
5434 * Link speed is taken from the XGXS. AN and FC result from
5435 * the external phy.
5436 */
5437 vars->link_status |= phy_vars[active_external_phy].link_status;
5438 ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
5439 vars->duplex = phy_vars[active_external_phy].duplex;
5440 if (params->phy[active_external_phy].supported &
5441 SUPPORTED_FIBRE)
5442 vars->link_status |= LINK_STATUS_SERDES_LINK;
5443 DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
5444 active_external_phy);
5445 }
5446 DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
5447 " ext_phy_line_speed = %d\n", vars->flow_ctrl,
5448 vars->link_status, ext_phy_line_speed);
5449 /**
5450 * Upon link speed change set the NIG into drain mode. Comes to
5451 * deals with possible FIFO glitch due to clk change when speed
5452 * is decreased without link down indicator
5453 */
ea4e040a 5454
b7737c9b
YR
5455 if (vars->phy_link_up) {
5456 if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
5457 (ext_phy_line_speed != vars->line_speed)) {
5458 DP(NETIF_MSG_LINK, "Internal link speed %d is"
5459 " different than the external"
5460 " link speed %d\n", vars->line_speed,
5461 ext_phy_line_speed);
5462 vars->phy_link_up = 0;
5463 } else if (prev_line_speed != vars->line_speed) {
5464 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
5465 + params->port*4, 0);
5466 msleep(1);
5467 }
5468 }
ea4e040a
YR
5469
5470 /* anything 10 and over uses the bmac */
5471 link_10g = ((vars->line_speed == SPEED_10000) ||
5472 (vars->line_speed == SPEED_12000) ||
5473 (vars->line_speed == SPEED_12500) ||
5474 (vars->line_speed == SPEED_13000) ||
5475 (vars->line_speed == SPEED_15000) ||
5476 (vars->line_speed == SPEED_16000));
5477
2f904460 5478 bnx2x_link_int_ack(params, vars, link_10g, is_mi_int);
ea4e040a 5479
b7737c9b
YR
5480 /**
5481 * In case external phy link is up, and internal link is down
5482 * (not initialized yet probably after link initialization, it
5483 * needs to be initialized.
5484 * Note that after link down-up as result of cable plug, the xgxs
5485 * link would probably become up again without the need
5486 * initialize it
5487 */
5488 if (!(SINGLE_MEDIA_DIRECT(params))) {
5489 DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
5490 " init_preceding = %d\n", ext_phy_link_up,
5491 vars->phy_link_up,
5492 params->phy[EXT_PHY1].flags &
5493 FLAGS_INIT_XGXS_FIRST);
5494 if (!(params->phy[EXT_PHY1].flags &
5495 FLAGS_INIT_XGXS_FIRST)
5496 && ext_phy_link_up && !vars->phy_link_up) {
5497 vars->line_speed = ext_phy_line_speed;
5498 if (vars->line_speed < SPEED_1000)
5499 vars->phy_flags |= PHY_SGMII_FLAG;
5500 else
5501 vars->phy_flags &= ~PHY_SGMII_FLAG;
5502 bnx2x_init_internal_phy(&params->phy[INT_PHY],
5503 params,
5504 vars);
5505 }
5506 }
5507 /**
5508 * Link is up only if both local phy and external phy (in case of
5509 * non-direct board) are up
5510 */
5511 vars->link_up = (vars->phy_link_up &&
5512 (ext_phy_link_up ||
5513 SINGLE_MEDIA_DIRECT(params)));
ea4e040a 5514
57963ed9 5515 if (vars->link_up)
b7737c9b 5516 rc = bnx2x_update_link_up(params, vars, link_10g);
57963ed9
YR
5517 else
5518 rc = bnx2x_update_link_down(params, vars);
ea4e040a
YR
5519
5520 return rc;
5521}
5522
b7737c9b
YR
5523static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
5524 struct link_params *params)
5525{
5526 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5527 MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
5528 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5529 MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
5530}
5531
5532static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
5533 struct link_params *params) {
5534 u32 swap_val, swap_override;
5535 u8 port;
5536 /**
5537 * The PHY reset is controlled by GPIO 1. Fake the port number
5538 * to cancel the swap done in set_gpio()
5539 */
5540 struct bnx2x *bp = params->bp;
5541 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
5542 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
5543 port = (swap_val && swap_override) ^ 1;
5544 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
5545 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
5546}
5547
5548static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
5549 struct link_params *params) {
5550 /* Low power mode is controlled by GPIO 2 */
5551 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
5552 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5553 /* The PHY reset is controlled by GPIO 1 */
5554 bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
5555 MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
5556}
5557/******************************************************************/
5558/* STATIC PHY DECLARATION */
5559/******************************************************************/
5560
5561static struct bnx2x_phy phy_null = {
5562 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
5563 .addr = 0,
5564 .flags = FLAGS_INIT_XGXS_FIRST,
5565 .def_md_devad = 0,
5566 .reserved = 0,
5567 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5568 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5569 .mdio_ctrl = 0,
5570 .supported = 0,
5571 .media_type = ETH_PHY_NOT_PRESENT,
5572 .ver_addr = 0,
5573 .req_flow_ctrl = 0,
5574 .req_line_speed = 0,
5575 .speed_cap_mask = 0,
5576 .req_duplex = 0,
5577 .rsrv = 0,
5578 .config_init = (config_init_t)NULL,
5579 .read_status = (read_status_t)NULL,
5580 .link_reset = (link_reset_t)NULL,
5581 .config_loopback = (config_loopback_t)NULL,
5582 .format_fw_ver = (format_fw_ver_t)NULL,
5583 .hw_reset = (hw_reset_t)NULL,
5584 .set_link_led = (set_link_led_t)NULL
5585};
5586
5587static struct bnx2x_phy phy_serdes = {
5588 .type = PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
5589 .addr = 0xff,
5590 .flags = 0,
5591 .def_md_devad = 0,
5592 .reserved = 0,
5593 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5594 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5595 .mdio_ctrl = 0,
5596 .supported = (SUPPORTED_10baseT_Half |
5597 SUPPORTED_10baseT_Full |
5598 SUPPORTED_100baseT_Half |
5599 SUPPORTED_100baseT_Full |
5600 SUPPORTED_1000baseT_Full |
5601 SUPPORTED_2500baseX_Full |
5602 SUPPORTED_TP |
5603 SUPPORTED_Autoneg |
5604 SUPPORTED_Pause |
5605 SUPPORTED_Asym_Pause),
5606 .media_type = ETH_PHY_UNSPECIFIED,
5607 .ver_addr = 0,
5608 .req_flow_ctrl = 0,
5609 .req_line_speed = 0,
5610 .speed_cap_mask = 0,
5611 .req_duplex = 0,
5612 .rsrv = 0,
5613 .config_init = (config_init_t)bnx2x_init_serdes,
5614 .read_status = (read_status_t)bnx2x_link_settings_status,
5615 .link_reset = (link_reset_t)bnx2x_int_link_reset,
5616 .config_loopback = (config_loopback_t)NULL,
5617 .format_fw_ver = (format_fw_ver_t)NULL,
5618 .hw_reset = (hw_reset_t)NULL,
5619 .set_link_led = (set_link_led_t)NULL
5620};
5621
5622static struct bnx2x_phy phy_xgxs = {
5623 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
5624 .addr = 0xff,
5625 .flags = 0,
5626 .def_md_devad = 0,
5627 .reserved = 0,
5628 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5629 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5630 .mdio_ctrl = 0,
5631 .supported = (SUPPORTED_10baseT_Half |
5632 SUPPORTED_10baseT_Full |
5633 SUPPORTED_100baseT_Half |
5634 SUPPORTED_100baseT_Full |
5635 SUPPORTED_1000baseT_Full |
5636 SUPPORTED_2500baseX_Full |
5637 SUPPORTED_10000baseT_Full |
5638 SUPPORTED_FIBRE |
5639 SUPPORTED_Autoneg |
5640 SUPPORTED_Pause |
5641 SUPPORTED_Asym_Pause),
5642 .media_type = ETH_PHY_UNSPECIFIED,
5643 .ver_addr = 0,
5644 .req_flow_ctrl = 0,
5645 .req_line_speed = 0,
5646 .speed_cap_mask = 0,
5647 .req_duplex = 0,
5648 .rsrv = 0,
5649 .config_init = (config_init_t)bnx2x_init_xgxs,
5650 .read_status = (read_status_t)bnx2x_link_settings_status,
5651 .link_reset = (link_reset_t)bnx2x_int_link_reset,
5652 .config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
5653 .format_fw_ver = (format_fw_ver_t)NULL,
5654 .hw_reset = (hw_reset_t)NULL,
5655 .set_link_led = (set_link_led_t)NULL
5656};
5657
5658static struct bnx2x_phy phy_7101 = {
5659 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
5660 .addr = 0xff,
5661 .flags = FLAGS_FAN_FAILURE_DET_REQ,
5662 .def_md_devad = 0,
5663 .reserved = 0,
5664 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5665 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5666 .mdio_ctrl = 0,
5667 .supported = (SUPPORTED_10000baseT_Full |
5668 SUPPORTED_TP |
5669 SUPPORTED_Autoneg |
5670 SUPPORTED_Pause |
5671 SUPPORTED_Asym_Pause),
5672 .media_type = ETH_PHY_BASE_T,
5673 .ver_addr = 0,
5674 .req_flow_ctrl = 0,
5675 .req_line_speed = 0,
5676 .speed_cap_mask = 0,
5677 .req_duplex = 0,
5678 .rsrv = 0,
5679 .config_init = (config_init_t)bnx2x_7101_config_init,
5680 .read_status = (read_status_t)bnx2x_7101_read_status,
5681 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
5682 .config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
5683 .format_fw_ver = (format_fw_ver_t)bnx2x_7101_format_ver,
5684 .hw_reset = (hw_reset_t)bnx2x_7101_hw_reset,
5685 .set_link_led = (set_link_led_t)NULL
5686};
5687static struct bnx2x_phy phy_8073 = {
5688 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
5689 .addr = 0xff,
5690 .flags = FLAGS_HW_LOCK_REQUIRED,
5691 .def_md_devad = 0,
5692 .reserved = 0,
5693 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5694 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5695 .mdio_ctrl = 0,
5696 .supported = (SUPPORTED_10000baseT_Full |
5697 SUPPORTED_2500baseX_Full |
5698 SUPPORTED_1000baseT_Full |
5699 SUPPORTED_FIBRE |
5700 SUPPORTED_Autoneg |
5701 SUPPORTED_Pause |
5702 SUPPORTED_Asym_Pause),
5703 .media_type = ETH_PHY_UNSPECIFIED,
5704 .ver_addr = 0,
5705 .req_flow_ctrl = 0,
5706 .req_line_speed = 0,
5707 .speed_cap_mask = 0,
5708 .req_duplex = 0,
5709 .rsrv = 0,
62b29a5d 5710 .config_init = (config_init_t)bnx2x_8073_config_init,
b7737c9b
YR
5711 .read_status = (read_status_t)bnx2x_8073_read_status,
5712 .link_reset = (link_reset_t)bnx2x_8073_link_reset,
5713 .config_loopback = (config_loopback_t)NULL,
5714 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
5715 .hw_reset = (hw_reset_t)NULL,
5716 .set_link_led = (set_link_led_t)NULL
5717};
5718static struct bnx2x_phy phy_8705 = {
5719 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
5720 .addr = 0xff,
5721 .flags = FLAGS_INIT_XGXS_FIRST,
5722 .def_md_devad = 0,
5723 .reserved = 0,
5724 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5725 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5726 .mdio_ctrl = 0,
5727 .supported = (SUPPORTED_10000baseT_Full |
5728 SUPPORTED_FIBRE |
5729 SUPPORTED_Pause |
5730 SUPPORTED_Asym_Pause),
5731 .media_type = ETH_PHY_XFP_FIBER,
5732 .ver_addr = 0,
5733 .req_flow_ctrl = 0,
5734 .req_line_speed = 0,
5735 .speed_cap_mask = 0,
5736 .req_duplex = 0,
5737 .rsrv = 0,
5738 .config_init = (config_init_t)bnx2x_8705_config_init,
5739 .read_status = (read_status_t)bnx2x_8705_read_status,
5740 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
5741 .config_loopback = (config_loopback_t)NULL,
5742 .format_fw_ver = (format_fw_ver_t)bnx2x_null_format_ver,
5743 .hw_reset = (hw_reset_t)NULL,
5744 .set_link_led = (set_link_led_t)NULL
5745};
5746static struct bnx2x_phy phy_8706 = {
5747 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
5748 .addr = 0xff,
5749 .flags = FLAGS_INIT_XGXS_FIRST,
5750 .def_md_devad = 0,
5751 .reserved = 0,
5752 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5753 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5754 .mdio_ctrl = 0,
5755 .supported = (SUPPORTED_10000baseT_Full |
5756 SUPPORTED_1000baseT_Full |
5757 SUPPORTED_FIBRE |
5758 SUPPORTED_Pause |
5759 SUPPORTED_Asym_Pause),
5760 .media_type = ETH_PHY_SFP_FIBER,
5761 .ver_addr = 0,
5762 .req_flow_ctrl = 0,
5763 .req_line_speed = 0,
5764 .speed_cap_mask = 0,
5765 .req_duplex = 0,
5766 .rsrv = 0,
5767 .config_init = (config_init_t)bnx2x_8706_config_init,
5768 .read_status = (read_status_t)bnx2x_8706_read_status,
5769 .link_reset = (link_reset_t)bnx2x_common_ext_link_reset,
5770 .config_loopback = (config_loopback_t)NULL,
5771 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
5772 .hw_reset = (hw_reset_t)NULL,
5773 .set_link_led = (set_link_led_t)NULL
5774};
5775
5776static struct bnx2x_phy phy_8726 = {
5777 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
5778 .addr = 0xff,
5779 .flags = (FLAGS_HW_LOCK_REQUIRED |
5780 FLAGS_INIT_XGXS_FIRST),
5781 .def_md_devad = 0,
5782 .reserved = 0,
5783 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5784 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5785 .mdio_ctrl = 0,
5786 .supported = (SUPPORTED_10000baseT_Full |
5787 SUPPORTED_1000baseT_Full |
5788 SUPPORTED_Autoneg |
5789 SUPPORTED_FIBRE |
5790 SUPPORTED_Pause |
5791 SUPPORTED_Asym_Pause),
5792 .media_type = ETH_PHY_SFP_FIBER,
5793 .ver_addr = 0,
5794 .req_flow_ctrl = 0,
5795 .req_line_speed = 0,
5796 .speed_cap_mask = 0,
5797 .req_duplex = 0,
5798 .rsrv = 0,
5799 .config_init = (config_init_t)bnx2x_8726_config_init,
5800 .read_status = (read_status_t)bnx2x_8726_read_status,
5801 .link_reset = (link_reset_t)bnx2x_8726_link_reset,
5802 .config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
5803 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
5804 .hw_reset = (hw_reset_t)NULL,
5805 .set_link_led = (set_link_led_t)NULL
5806};
5807
5808static struct bnx2x_phy phy_8727 = {
5809 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
5810 .addr = 0xff,
5811 .flags = FLAGS_FAN_FAILURE_DET_REQ,
5812 .def_md_devad = 0,
5813 .reserved = 0,
5814 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5815 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5816 .mdio_ctrl = 0,
5817 .supported = (SUPPORTED_10000baseT_Full |
5818 SUPPORTED_1000baseT_Full |
5819 SUPPORTED_Autoneg |
5820 SUPPORTED_FIBRE |
5821 SUPPORTED_Pause |
5822 SUPPORTED_Asym_Pause),
5823 .media_type = ETH_PHY_SFP_FIBER,
5824 .ver_addr = 0,
5825 .req_flow_ctrl = 0,
5826 .req_line_speed = 0,
5827 .speed_cap_mask = 0,
5828 .req_duplex = 0,
5829 .rsrv = 0,
5830 .config_init = (config_init_t)bnx2x_8727_config_init,
5831 .read_status = (read_status_t)bnx2x_8727_read_status,
5832 .link_reset = (link_reset_t)bnx2x_8727_link_reset,
5833 .config_loopback = (config_loopback_t)NULL,
5834 .format_fw_ver = (format_fw_ver_t)bnx2x_format_ver,
5835 .hw_reset = (hw_reset_t)bnx2x_8727_hw_reset,
5836 .set_link_led = (set_link_led_t)NULL
5837};
5838static struct bnx2x_phy phy_8481 = {
5839 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
5840 .addr = 0xff,
5841 .flags = FLAGS_FAN_FAILURE_DET_REQ,
5842 .def_md_devad = 0,
5843 .reserved = 0,
5844 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5845 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5846 .mdio_ctrl = 0,
5847 .supported = (SUPPORTED_10baseT_Half |
5848 SUPPORTED_10baseT_Full |
5849 SUPPORTED_100baseT_Half |
5850 SUPPORTED_100baseT_Full |
5851 SUPPORTED_1000baseT_Full |
5852 SUPPORTED_10000baseT_Full |
5853 SUPPORTED_TP |
5854 SUPPORTED_Autoneg |
5855 SUPPORTED_Pause |
5856 SUPPORTED_Asym_Pause),
5857 .media_type = ETH_PHY_BASE_T,
5858 .ver_addr = 0,
5859 .req_flow_ctrl = 0,
5860 .req_line_speed = 0,
5861 .speed_cap_mask = 0,
5862 .req_duplex = 0,
5863 .rsrv = 0,
5864 .config_init = (config_init_t)bnx2x_8481_config_init,
5865 .read_status = (read_status_t)bnx2x_848xx_read_status,
5866 .link_reset = (link_reset_t)bnx2x_8481_link_reset,
5867 .config_loopback = (config_loopback_t)NULL,
5868 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
5869 .hw_reset = (hw_reset_t)bnx2x_8481_hw_reset,
5870 .set_link_led = (set_link_led_t)NULL
5871};
5872
5873static struct bnx2x_phy phy_84823 = {
5874 .type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
5875 .addr = 0xff,
5876 .flags = FLAGS_FAN_FAILURE_DET_REQ,
5877 .def_md_devad = 0,
5878 .reserved = 0,
5879 .rx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5880 .tx_preemphasis = {0xffff, 0xffff, 0xffff, 0xffff},
5881 .mdio_ctrl = 0,
5882 .supported = (SUPPORTED_10baseT_Half |
5883 SUPPORTED_10baseT_Full |
5884 SUPPORTED_100baseT_Half |
5885 SUPPORTED_100baseT_Full |
5886 SUPPORTED_1000baseT_Full |
5887 SUPPORTED_10000baseT_Full |
5888 SUPPORTED_TP |
5889 SUPPORTED_Autoneg |
5890 SUPPORTED_Pause |
5891 SUPPORTED_Asym_Pause),
5892 .media_type = ETH_PHY_BASE_T,
5893 .ver_addr = 0,
5894 .req_flow_ctrl = 0,
5895 .req_line_speed = 0,
5896 .speed_cap_mask = 0,
5897 .req_duplex = 0,
5898 .rsrv = 0,
5899 .config_init = (config_init_t)bnx2x_848x3_config_init,
5900 .read_status = (read_status_t)bnx2x_848xx_read_status,
5901 .link_reset = (link_reset_t)bnx2x_848x3_link_reset,
5902 .config_loopback = (config_loopback_t)NULL,
5903 .format_fw_ver = (format_fw_ver_t)bnx2x_848xx_format_ver,
5904 .hw_reset = (hw_reset_t)NULL,
5905 .set_link_led = (set_link_led_t)NULL
5906};
5907
5908/*****************************************************************/
5909/* */
5910/* Populate the phy according. Main function: bnx2x_populate_phy */
5911/* */
5912/*****************************************************************/
5913
5914static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
5915 struct bnx2x_phy *phy, u8 port,
5916 u8 phy_index)
5917{
5918 /* Get the 4 lanes xgxs config rx and tx */
5919 u32 rx = 0, tx = 0, i;
5920 for (i = 0; i < 2; i++) {
5921 /**
5922 * INT_PHY and EXT_PHY1 share the same value location in the
5923 * shmem. When num_phys is greater than 1, than this value
5924 * applies only to EXT_PHY1
5925 */
5926
5927 rx = REG_RD(bp, shmem_base +
5928 offsetof(struct shmem_region,
5929 dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
5930
5931 tx = REG_RD(bp, shmem_base +
5932 offsetof(struct shmem_region,
5933 dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
5934
5935 phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
5936 phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
5937
5938 phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
5939 phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
5940 }
5941}
5942
e10bc84d
YR
5943static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
5944 u8 phy_index, u8 port)
5945{
5946 u32 ext_phy_config = 0;
5947 switch (phy_index) {
5948 case EXT_PHY1:
5949 ext_phy_config = REG_RD(bp, shmem_base +
5950 offsetof(struct shmem_region,
5951 dev_info.port_hw_config[port].external_phy_config));
5952 break;
5953 default:
5954 DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
5955 return -EINVAL;
5956 }
5957
5958 return ext_phy_config;
5959}
b7737c9b
YR
5960static u8 bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
5961 struct bnx2x_phy *phy)
5962{
5963 u32 phy_addr;
5964 u32 chip_id;
5965 u32 switch_cfg = (REG_RD(bp, shmem_base +
5966 offsetof(struct shmem_region,
5967 dev_info.port_feature_config[port].link_config)) &
5968 PORT_FEATURE_CONNECTED_SWITCH_MASK);
5969 chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
5970 switch (switch_cfg) {
5971 case SWITCH_CFG_1G:
5972 phy_addr = REG_RD(bp,
5973 NIG_REG_SERDES0_CTRL_PHY_ADDR +
5974 port * 0x10);
5975 *phy = phy_serdes;
5976 break;
5977 case SWITCH_CFG_10G:
5978 phy_addr = REG_RD(bp,
5979 NIG_REG_XGXS0_CTRL_PHY_ADDR +
5980 port * 0x18);
5981 *phy = phy_xgxs;
5982 break;
5983 default:
5984 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
5985 return -EINVAL;
5986 }
5987 phy->addr = (u8)phy_addr;
5988 phy->mdio_ctrl = bnx2x_get_emac_base(bp,
5989 phy->type,
5990 port);
5991 phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
5992
5993 DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
5994 port, phy->addr, phy->mdio_ctrl);
5995
5996 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
5997 return 0;
5998}
e10bc84d
YR
5999
6000static u8 bnx2x_populate_ext_phy(struct bnx2x *bp,
6001 u8 phy_index,
6002 u32 shmem_base,
6003 u8 port,
6004 struct bnx2x_phy *phy)
6005{
b7737c9b 6006 u32 ext_phy_config, phy_type;
e10bc84d
YR
6007
6008 ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
6009 phy_index, port);
b7737c9b
YR
6010 phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
6011 /* Select the phy type */
6012 switch (phy_type) {
6013 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6014 *phy = phy_8073;
6015 break;
6016 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
6017 *phy = phy_8705;
6018 break;
6019 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
6020 *phy = phy_8706;
6021 break;
6022 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6023 *phy = phy_8726;
6024 break;
6025 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6026 /* BCM8727_NOC => BCM8727 no over current */
6027 *phy = phy_8727;
6028 phy->flags |= FLAGS_NOC;
6029 break;
6030 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6031 *phy = phy_8727;
6032 break;
6033 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
6034 *phy = phy_8481;
6035 break;
6036 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
6037 *phy = phy_84823;
6038 break;
6039 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
6040 *phy = phy_7101;
6041 break;
6042 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
6043 *phy = phy_null;
6044 return -EINVAL;
6045 default:
6046 *phy = phy_null;
6047 return 0;
6048 }
6049
e10bc84d 6050 phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
b7737c9b 6051 bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
e10bc84d 6052 phy->mdio_ctrl = bnx2x_get_emac_base(bp, phy->type, port);
62b29a5d 6053
e10bc84d
YR
6054 return 0;
6055}
6056
6057static u8 bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
6058 u8 port, struct bnx2x_phy *phy)
6059{
6060 u8 status = 0;
b7737c9b
YR
6061 phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
6062 if (phy_index == INT_PHY)
6063 return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
e10bc84d
YR
6064 status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base,
6065 port, phy);
6066 return status;
6067}
6068
b7737c9b
YR
6069static void bnx2x_phy_def_cfg(struct link_params *params,
6070 struct bnx2x_phy *phy,
6071 u8 actual_phy_idx)
6072{
6073 struct bnx2x *bp = params->bp;
6074 u32 link_config;
6075 /* Populate the default phy configuration for MF mode */
6076 link_config = REG_RD(bp, params->shmem_base +
6077 offsetof(struct shmem_region, dev_info.
6078 port_feature_config[params->port].link_config));
6079 phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
6080 offsetof(struct shmem_region, dev_info.
6081 port_hw_config[params->port].speed_capability_mask));
6082
6083 phy->req_duplex = DUPLEX_FULL;
6084 switch (link_config & PORT_FEATURE_LINK_SPEED_MASK) {
6085 case PORT_FEATURE_LINK_SPEED_10M_HALF:
6086 phy->req_duplex = DUPLEX_HALF;
6087 case PORT_FEATURE_LINK_SPEED_10M_FULL:
6088 phy->req_line_speed = SPEED_10;
6089 break;
6090 case PORT_FEATURE_LINK_SPEED_100M_HALF:
6091 phy->req_duplex = DUPLEX_HALF;
6092 case PORT_FEATURE_LINK_SPEED_100M_FULL:
6093 phy->req_line_speed = SPEED_100;
6094 break;
6095 case PORT_FEATURE_LINK_SPEED_1G:
6096 phy->req_line_speed = SPEED_1000;
6097 break;
6098 case PORT_FEATURE_LINK_SPEED_2_5G:
6099 phy->req_line_speed = SPEED_2500;
6100 break;
6101 case PORT_FEATURE_LINK_SPEED_10G_CX4:
6102 phy->req_line_speed = SPEED_10000;
6103 break;
6104 default:
6105 phy->req_line_speed = SPEED_AUTO_NEG;
6106 break;
6107 }
6108
6109 switch (link_config & PORT_FEATURE_FLOW_CONTROL_MASK) {
6110 case PORT_FEATURE_FLOW_CONTROL_AUTO:
6111 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
6112 break;
6113 case PORT_FEATURE_FLOW_CONTROL_TX:
6114 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
6115 break;
6116 case PORT_FEATURE_FLOW_CONTROL_RX:
6117 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
6118 break;
6119 case PORT_FEATURE_FLOW_CONTROL_BOTH:
6120 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
6121 break;
6122 default:
6123 phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
6124 break;
6125 }
6126}
6127
6128u8 bnx2x_phy_probe(struct link_params *params)
6129{
6130 u8 phy_index, actual_phy_idx, link_cfg_idx;
6131
6132 struct bnx2x *bp = params->bp;
6133 struct bnx2x_phy *phy;
6134 params->num_phys = 0;
6135 DP(NETIF_MSG_LINK, "Begin phy probe\n");
6136
6137 for (phy_index = INT_PHY; phy_index < MAX_PHYS;
6138 phy_index++) {
6139 link_cfg_idx = LINK_CONFIG_IDX(phy_index);
6140 actual_phy_idx = phy_index;
6141
6142 phy = &params->phy[actual_phy_idx];
6143 if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
6144 params->port,
6145 phy) != 0) {
6146 params->num_phys = 0;
6147 DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
6148 phy_index);
6149 for (phy_index = INT_PHY;
6150 phy_index < MAX_PHYS;
6151 phy_index++)
6152 *phy = phy_null;
6153 return -EINVAL;
6154 }
6155 if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
6156 break;
6157
6158 bnx2x_phy_def_cfg(params, phy, actual_phy_idx);
6159 params->num_phys++;
6160 }
6161
6162 DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
6163 return 0;
6164}
6165
6166u32 bnx2x_supported_attr(struct link_params *params, u8 phy_idx)
6167{
6168 if (phy_idx < params->num_phys)
6169 return params->phy[phy_idx].supported;
6170 return 0;
6171}
6172
6173
6bbca910
YR
6174static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6175{
e10bc84d
YR
6176 struct bnx2x_phy phy[PORT_MAX];
6177 struct bnx2x_phy *phy_blk[PORT_MAX];
6bbca910
YR
6178 u16 val;
6179 s8 port;
6180
6181 /* PART1 - Reset both phys */
6182 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6183 /* Extract the ext phy address for the port */
e10bc84d
YR
6184 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base,
6185 port, &phy[port]) !=
6186 0) {
6187 DP(NETIF_MSG_LINK, "populate_phy failed\n");
6188 return -EINVAL;
6189 }
6bbca910
YR
6190 /* disable attentions */
6191 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6192 (NIG_MASK_XGXS0_LINK_STATUS |
6193 NIG_MASK_XGXS0_LINK10G |
6194 NIG_MASK_SERDES0_LINK_STATUS |
6195 NIG_MASK_MI_INT));
6196
6bbca910
YR
6197 /* Need to take the phy out of low power mode in order
6198 to write to access its registers */
6199 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6200 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6201
6202 /* Reset the phy */
e10bc84d 6203 bnx2x_cl45_write(bp, &phy[port],
6bbca910
YR
6204 MDIO_PMA_DEVAD,
6205 MDIO_PMA_REG_CTRL,
6206 1<<15);
6207 }
6208
6209 /* Add delay of 150ms after reset */
6210 msleep(150);
6211
e10bc84d
YR
6212 if (phy[PORT_0].addr & 0x1) {
6213 phy_blk[PORT_0] = &(phy[PORT_1]);
6214 phy_blk[PORT_1] = &(phy[PORT_0]);
6215 } else {
6216 phy_blk[PORT_0] = &(phy[PORT_0]);
6217 phy_blk[PORT_1] = &(phy[PORT_1]);
6218 }
6219
6bbca910
YR
6220 /* PART2 - Download firmware to both phys */
6221 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
6222 u16 fw_ver1;
6223
e10bc84d
YR
6224 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
6225 port, shmem_base);
6bbca910 6226
e10bc84d 6227 bnx2x_cl45_read(bp, phy_blk[port],
6bbca910
YR
6228 MDIO_PMA_DEVAD,
6229 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
16b311cc 6230 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6bbca910 6231 DP(NETIF_MSG_LINK,
16b311cc
EG
6232 "bnx2x_8073_common_init_phy port %x:"
6233 "Download failed. fw version = 0x%x\n",
6234 port, fw_ver1);
6bbca910
YR
6235 return -EINVAL;
6236 }
6237
6238 /* Only set bit 10 = 1 (Tx power down) */
e10bc84d 6239 bnx2x_cl45_read(bp, phy_blk[port],
6bbca910
YR
6240 MDIO_PMA_DEVAD,
6241 MDIO_PMA_REG_TX_POWER_DOWN, &val);
6242
6243 /* Phase1 of TX_POWER_DOWN reset */
e10bc84d 6244 bnx2x_cl45_write(bp, phy_blk[port],
6bbca910
YR
6245 MDIO_PMA_DEVAD,
6246 MDIO_PMA_REG_TX_POWER_DOWN,
6247 (val | 1<<10));
6248 }
6249
6250 /* Toggle Transmitter: Power down and then up with 600ms
6251 delay between */
6252 msleep(600);
6253
6254 /* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
6255 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
f5372251 6256 /* Phase2 of POWER_DOWN_RESET */
6bbca910 6257 /* Release bit 10 (Release Tx power down) */
e10bc84d 6258 bnx2x_cl45_read(bp, phy_blk[port],
6bbca910
YR
6259 MDIO_PMA_DEVAD,
6260 MDIO_PMA_REG_TX_POWER_DOWN, &val);
6261
e10bc84d 6262 bnx2x_cl45_write(bp, phy_blk[port],
6bbca910
YR
6263 MDIO_PMA_DEVAD,
6264 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
6265 msleep(15);
6266
6267 /* Read modify write the SPI-ROM version select register */
e10bc84d 6268 bnx2x_cl45_read(bp, phy_blk[port],
6bbca910
YR
6269 MDIO_PMA_DEVAD,
6270 MDIO_PMA_REG_EDC_FFE_MAIN, &val);
e10bc84d 6271 bnx2x_cl45_write(bp, phy_blk[port],
6bbca910
YR
6272 MDIO_PMA_DEVAD,
6273 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
6274
6275 /* set GPIO2 back to LOW */
6276 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6277 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6278 }
6279 return 0;
6bbca910
YR
6280}
6281
4d295db0
EG
6282static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6283{
bc7f0a05 6284 s8 port, first_port, i;
4d295db0 6285 u32 swap_val, swap_override;
e10bc84d
YR
6286 struct bnx2x_phy phy[PORT_MAX];
6287 struct bnx2x_phy *phy_blk[PORT_MAX];
4d295db0
EG
6288 DP(NETIF_MSG_LINK, "Executing BCM8727 common init\n");
6289 swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
6290 swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
6291
f57a6025 6292 bnx2x_ext_phy_hw_reset(bp, 1 ^ (swap_val && swap_override));
4d295db0
EG
6293 msleep(5);
6294
bc7f0a05
EG
6295 if (swap_val && swap_override)
6296 first_port = PORT_0;
6297 else
6298 first_port = PORT_1;
6299
4d295db0 6300 /* PART1 - Reset both phys */
bc7f0a05 6301 for (i = 0, port = first_port; i < PORT_MAX; i++, port = !port) {
4d295db0 6302 /* Extract the ext phy address for the port */
e10bc84d
YR
6303 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base,
6304 port, &phy[port]) !=
6305 0) {
6306 DP(NETIF_MSG_LINK, "populate phy failed\n");
6307 return -EINVAL;
6308 }
4d295db0
EG
6309 /* disable attentions */
6310 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
6311 (NIG_MASK_XGXS0_LINK_STATUS |
6312 NIG_MASK_XGXS0_LINK10G |
6313 NIG_MASK_SERDES0_LINK_STATUS |
6314 NIG_MASK_MI_INT));
6315
4d295db0
EG
6316
6317 /* Reset the phy */
e10bc84d 6318 bnx2x_cl45_write(bp, &phy[port],
4d295db0
EG
6319 MDIO_PMA_DEVAD,
6320 MDIO_PMA_REG_CTRL,
6321 1<<15);
6322 }
6323
6324 /* Add delay of 150ms after reset */
6325 msleep(150);
e10bc84d
YR
6326 if (phy[PORT_0].addr & 0x1) {
6327 phy_blk[PORT_0] = &(phy[PORT_1]);
6328 phy_blk[PORT_1] = &(phy[PORT_0]);
6329 } else {
6330 phy_blk[PORT_0] = &(phy[PORT_0]);
6331 phy_blk[PORT_1] = &(phy[PORT_1]);
6332 }
4d295db0 6333 /* PART2 - Download firmware to both phys */
e10bc84d 6334 for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4d295db0
EG
6335 u16 fw_ver1;
6336
e10bc84d
YR
6337 bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
6338 port, shmem_base);
6339 bnx2x_cl45_read(bp, phy_blk[port],
4d295db0
EG
6340 MDIO_PMA_DEVAD,
6341 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6342 if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
6343 DP(NETIF_MSG_LINK,
bc7f0a05 6344 "bnx2x_8727_common_init_phy port %x:"
4d295db0
EG
6345 "Download failed. fw version = 0x%x\n",
6346 port, fw_ver1);
6347 return -EINVAL;
6348 }
4d295db0
EG
6349 }
6350
4d295db0
EG
6351 return 0;
6352}
6353
589abe3a
EG
6354static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6355{
589abe3a
EG
6356 u32 val;
6357 s8 port;
e10bc84d 6358 struct bnx2x_phy phy;
589abe3a
EG
6359 /* Use port1 because of the static port-swap */
6360 /* Enable the module detection interrupt */
6361 val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
6362 val |= ((1<<MISC_REGISTERS_GPIO_3)|
6363 (1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
6364 REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
6365
f57a6025 6366 bnx2x_ext_phy_hw_reset(bp, 1);
589abe3a
EG
6367 msleep(5);
6368 for (port = 0; port < PORT_MAX; port++) {
6369 /* Extract the ext phy address for the port */
e10bc84d
YR
6370 if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base,
6371 port, &phy) !=
6372 0) {
6373 DP(NETIF_MSG_LINK, "populate phy failed\n");
6374 return -EINVAL;
6375 }
589abe3a 6376
e10bc84d
YR
6377 /* Reset phy*/
6378 bnx2x_cl45_write(bp, &phy,
6379 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
589abe3a 6380
589abe3a
EG
6381
6382 /* Set fault module detected LED on */
6383 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
6384 MISC_REGISTERS_GPIO_HIGH,
6385 port);
6386 }
6387
6388 return 0;
6389}
6390
6bbca910
YR
6391u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
6392{
6393 u8 rc = 0;
6394 u32 ext_phy_type;
6395
f5372251 6396 DP(NETIF_MSG_LINK, "Begin common phy init\n");
6bbca910
YR
6397
6398 /* Read the ext_phy_type for arbitrary port(0) */
6399 ext_phy_type = XGXS_EXT_PHY_TYPE(
6400 REG_RD(bp, shmem_base +
6401 offsetof(struct shmem_region,
6402 dev_info.port_hw_config[0].external_phy_config)));
6403
6404 switch (ext_phy_type) {
6405 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
6406 {
6407 rc = bnx2x_8073_common_init_phy(bp, shmem_base);
6408 break;
6409 }
4d295db0
EG
6410
6411 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
6412 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
6413 rc = bnx2x_8727_common_init_phy(bp, shmem_base);
6414 break;
6415
589abe3a
EG
6416 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
6417 /* GPIO1 affects both ports, so there's need to pull
6418 it for single port alone */
6419 rc = bnx2x_8726_common_init_phy(bp, shmem_base);
4f60dab1 6420 break;
6bbca910
YR
6421 default:
6422 DP(NETIF_MSG_LINK,
6423 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
6424 ext_phy_type);
6425 break;
6426 }
6427
6428 return rc;
6429}
6430
e10bc84d 6431void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
ea4e040a
YR
6432{
6433 u16 val, cnt;
6434
e10bc84d 6435 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
6436 MDIO_PMA_DEVAD,
6437 MDIO_PMA_REG_7101_RESET, &val);
6438
6439 for (cnt = 0; cnt < 10; cnt++) {
6440 msleep(50);
6441 /* Writes a self-clearing reset */
e10bc84d 6442 bnx2x_cl45_write(bp, phy,
ea4e040a
YR
6443 MDIO_PMA_DEVAD,
6444 MDIO_PMA_REG_7101_RESET,
6445 (val | (1<<15)));
6446 /* Wait for clear */
e10bc84d 6447 bnx2x_cl45_read(bp, phy,
ea4e040a
YR
6448 MDIO_PMA_DEVAD,
6449 MDIO_PMA_REG_7101_RESET, &val);
6450
6451 if ((val & (1<<15)) == 0)
6452 break;
6453 }
6454}