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