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