bnx2x: Change GPIO for any port
[deliverable/linux.git] / drivers / net / bnx2x_link.c
CommitLineData
ea4e040a
YR
1/* Copyright 2008 Broadcom Corporation
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>
24#include <linux/version.h>
25
26#include "bnx2x_reg.h"
27#include "bnx2x_fw_defs.h"
28#include "bnx2x_hsi.h"
29#include "bnx2x_link.h"
30#include "bnx2x.h"
31
32/********************************************************/
33#define SUPPORT_CL73 0 /* Currently no */
34#define ETH_HLEN 14
35#define ETH_OVREHEAD (ETH_HLEN + 8)/* 8 for CRC + VLAN*/
36#define ETH_MIN_PACKET_SIZE 60
37#define ETH_MAX_PACKET_SIZE 1500
38#define ETH_MAX_JUMBO_PACKET_SIZE 9600
39#define MDIO_ACCESS_TIMEOUT 1000
40#define BMAC_CONTROL_RX_ENABLE 2
ea4e040a
YR
41
42/***********************************************************/
43/* Shortcut definitions */
44/***********************************************************/
45
46#define NIG_STATUS_XGXS0_LINK10G \
47 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
48#define NIG_STATUS_XGXS0_LINK_STATUS \
49 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
50#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
51 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
52#define NIG_STATUS_SERDES0_LINK_STATUS \
53 NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
54#define NIG_MASK_MI_INT \
55 NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
56#define NIG_MASK_XGXS0_LINK10G \
57 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
58#define NIG_MASK_XGXS0_LINK_STATUS \
59 NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
60#define NIG_MASK_SERDES0_LINK_STATUS \
61 NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
62
63#define MDIO_AN_CL73_OR_37_COMPLETE \
64 (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
65 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
66
67#define XGXS_RESET_BITS \
68 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW | \
69 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ | \
70 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN | \
71 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
72 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
73
74#define SERDES_RESET_BITS \
75 (MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
76 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ | \
77 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN | \
78 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
79
80#define AUTONEG_CL37 SHARED_HW_CFG_AN_ENABLE_CL37
81#define AUTONEG_CL73 SHARED_HW_CFG_AN_ENABLE_CL73
82#define AUTONEG_BAM SHARED_HW_CFG_AN_ENABLE_BAM
83#define AUTONEG_PARALLEL \
84 SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
85#define AUTONEG_SGMII_FIBER_AUTODET \
86 SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
87#define AUTONEG_REMOTE_PHY SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
88
89#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
90 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
91#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
92 MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
93#define GP_STATUS_SPEED_MASK \
94 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
95#define GP_STATUS_10M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
96#define GP_STATUS_100M MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
97#define GP_STATUS_1G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
98#define GP_STATUS_2_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
99#define GP_STATUS_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
100#define GP_STATUS_6G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
101#define GP_STATUS_10G_HIG \
102 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
103#define GP_STATUS_10G_CX4 \
104 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
105#define GP_STATUS_12G_HIG \
106 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
107#define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
108#define GP_STATUS_13G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
109#define GP_STATUS_15G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
110#define GP_STATUS_16G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
111#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
112#define GP_STATUS_10G_KX4 \
113 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
114
115#define LINK_10THD LINK_STATUS_SPEED_AND_DUPLEX_10THD
116#define LINK_10TFD LINK_STATUS_SPEED_AND_DUPLEX_10TFD
117#define LINK_100TXHD LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
118#define LINK_100T4 LINK_STATUS_SPEED_AND_DUPLEX_100T4
119#define LINK_100TXFD LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
120#define LINK_1000THD LINK_STATUS_SPEED_AND_DUPLEX_1000THD
121#define LINK_1000TFD LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
122#define LINK_1000XFD LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
123#define LINK_2500THD LINK_STATUS_SPEED_AND_DUPLEX_2500THD
124#define LINK_2500TFD LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
125#define LINK_2500XFD LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
126#define LINK_10GTFD LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
127#define LINK_10GXFD LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
128#define LINK_12GTFD LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
129#define LINK_12GXFD LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
130#define LINK_12_5GTFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
131#define LINK_12_5GXFD LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
132#define LINK_13GTFD LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
133#define LINK_13GXFD LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
134#define LINK_15GTFD LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
135#define LINK_15GXFD LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
136#define LINK_16GTFD LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
137#define LINK_16GXFD LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
138
139#define PHY_XGXS_FLAG 0x1
140#define PHY_SGMII_FLAG 0x2
141#define PHY_SERDES_FLAG 0x4
142
143/**********************************************************/
144/* INTERFACE */
145/**********************************************************/
146#define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
147 bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
148 DEFAULT_PHY_DEV_ADDR, \
149 (_bank + (_addr & 0xf)), \
150 _val)
151
152#define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
153 bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
154 DEFAULT_PHY_DEV_ADDR, \
155 (_bank + (_addr & 0xf)), \
156 _val)
157
158static void bnx2x_set_phy_mdio(struct link_params *params)
159{
160 struct bnx2x *bp = params->bp;
161 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
162 params->port*0x18, 0);
163 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
164 DEFAULT_PHY_DEV_ADDR);
165}
166
167static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
168{
169 u32 val = REG_RD(bp, reg);
170
171 val |= bits;
172 REG_WR(bp, reg, val);
173 return val;
174}
175
176static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
177{
178 u32 val = REG_RD(bp, reg);
179
180 val &= ~bits;
181 REG_WR(bp, reg, val);
182 return val;
183}
184
185static void bnx2x_emac_init(struct link_params *params,
186 struct link_vars *vars)
187{
188 /* reset and unreset the emac core */
189 struct bnx2x *bp = params->bp;
190 u8 port = params->port;
191 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
192 u32 val;
193 u16 timeout;
194
195 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
196 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
197 udelay(5);
198 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
199 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
200
201 /* init emac - use read-modify-write */
202 /* self clear reset */
203 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
204 EMAC_WR(EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
205
206 timeout = 200;
207 do
208 {
209 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
210 DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
211 if (!timeout) {
212 DP(NETIF_MSG_LINK, "EMAC timeout!\n");
213 return;
214 }
215 timeout--;
216 }while (val & EMAC_MODE_RESET);
217
218 /* Set mac address */
219 val = ((params->mac_addr[0] << 8) |
220 params->mac_addr[1]);
221 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH, val);
222
223 val = ((params->mac_addr[2] << 24) |
224 (params->mac_addr[3] << 16) |
225 (params->mac_addr[4] << 8) |
226 params->mac_addr[5]);
227 EMAC_WR(EMAC_REG_EMAC_MAC_MATCH + 4, val);
228}
229
230static u8 bnx2x_emac_enable(struct link_params *params,
231 struct link_vars *vars, u8 lb)
232{
233 struct bnx2x *bp = params->bp;
234 u8 port = params->port;
235 u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
236 u32 val;
237
238 DP(NETIF_MSG_LINK, "enabling EMAC\n");
239
240 /* enable emac and not bmac */
241 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
242
243 /* for paladium */
244 if (CHIP_REV_IS_EMUL(bp)) {
245 /* Use lane 1 (of lanes 0-3) */
246 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
247 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
248 port*4, 1);
249 }
250 /* for fpga */
251 else
252
253 if (CHIP_REV_IS_FPGA(bp)) {
254 /* Use lane 1 (of lanes 0-3) */
255 DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
256
257 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
258 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
259 0);
260 } else
261 /* ASIC */
262 if (vars->phy_flags & PHY_XGXS_FLAG) {
263 u32 ser_lane = ((params->lane_config &
264 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
265 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
266
267 DP(NETIF_MSG_LINK, "XGXS\n");
268 /* select the master lanes (out of 0-3) */
269 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
270 port*4, ser_lane);
271 /* select XGXS */
272 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
273 port*4, 1);
274
275 } else { /* SerDes */
276 DP(NETIF_MSG_LINK, "SerDes\n");
277 /* select SerDes */
278 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
279 port*4, 0);
280 }
281
282 /* enable emac */
283 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
284
285 if (CHIP_REV_IS_SLOW(bp)) {
286 /* config GMII mode */
287 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
288 EMAC_WR(EMAC_REG_EMAC_MODE,
289 (val | EMAC_MODE_PORT_GMII));
290 } else { /* ASIC */
291 /* pause enable/disable */
292 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
293 EMAC_RX_MODE_FLOW_EN);
294 if (vars->flow_ctrl & FLOW_CTRL_RX)
295 bnx2x_bits_en(bp, emac_base +
296 EMAC_REG_EMAC_RX_MODE,
297 EMAC_RX_MODE_FLOW_EN);
298
299 bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
8c99e7b0
YR
300 (EMAC_TX_MODE_EXT_PAUSE_EN |
301 EMAC_TX_MODE_FLOW_EN));
ea4e040a
YR
302 if (vars->flow_ctrl & FLOW_CTRL_TX)
303 bnx2x_bits_en(bp, emac_base +
304 EMAC_REG_EMAC_TX_MODE,
8c99e7b0
YR
305 (EMAC_TX_MODE_EXT_PAUSE_EN |
306 EMAC_TX_MODE_FLOW_EN));
ea4e040a
YR
307 }
308
309 /* KEEP_VLAN_TAG, promiscuous */
310 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
311 val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
312 EMAC_WR(EMAC_REG_EMAC_RX_MODE, val);
313
314 /* Set Loopback */
315 val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
316 if (lb)
317 val |= 0x810;
318 else
319 val &= ~0x810;
320 EMAC_WR(EMAC_REG_EMAC_MODE, val);
321
322 /* enable emac for jumbo packets */
323 EMAC_WR(EMAC_REG_EMAC_RX_MTU_SIZE,
324 (EMAC_RX_MTU_SIZE_JUMBO_ENA |
325 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
326
327 /* strip CRC */
328 REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
329
330 /* disable the NIG in/out to the bmac */
331 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
332 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
333 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
334
335 /* enable the NIG in/out to the emac */
336 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
337 val = 0;
338 if (vars->flow_ctrl & FLOW_CTRL_TX)
339 val = 1;
340
341 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
342 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
343
344 if (CHIP_REV_IS_EMUL(bp)) {
345 /* take the BigMac out of reset */
346 REG_WR(bp,
347 GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
348 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
349
350 /* enable access for bmac registers */
351 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
352 }
353
354 vars->mac_type = MAC_TYPE_EMAC;
355 return 0;
356}
357
358
359
360static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
361 u8 is_lb)
362{
363 struct bnx2x *bp = params->bp;
364 u8 port = params->port;
365 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
366 NIG_REG_INGRESS_BMAC0_MEM;
367 u32 wb_data[2];
368 u32 val;
369
370 DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
371 /* reset and unreset the BigMac */
372 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
373 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
374 msleep(1);
375
376 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
377 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
378
379 /* enable access for bmac registers */
380 REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
381
382 /* XGXS control */
383 wb_data[0] = 0x3c;
384 wb_data[1] = 0;
385 REG_WR_DMAE(bp, bmac_addr +
386 BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
387 wb_data, 2);
388
389 /* tx MAC SA */
390 wb_data[0] = ((params->mac_addr[2] << 24) |
391 (params->mac_addr[3] << 16) |
392 (params->mac_addr[4] << 8) |
393 params->mac_addr[5]);
394 wb_data[1] = ((params->mac_addr[0] << 8) |
395 params->mac_addr[1]);
396 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
397 wb_data, 2);
398
399 /* tx control */
400 val = 0xc0;
401 if (vars->flow_ctrl & FLOW_CTRL_TX)
402 val |= 0x800000;
403 wb_data[0] = val;
404 wb_data[1] = 0;
405 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
406 wb_data, 2);
407
408 /* mac control */
409 val = 0x3;
410 if (is_lb) {
411 val |= 0x4;
412 DP(NETIF_MSG_LINK, "enable bmac loopback\n");
413 }
414 wb_data[0] = val;
415 wb_data[1] = 0;
416 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
417 wb_data, 2);
418
419
420 /* set rx mtu */
421 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
422 wb_data[1] = 0;
423 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
424 wb_data, 2);
425
426 /* rx control set to don't strip crc */
427 val = 0x14;
428 if (vars->flow_ctrl & FLOW_CTRL_RX)
429 val |= 0x20;
430 wb_data[0] = val;
431 wb_data[1] = 0;
432 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
433 wb_data, 2);
434
435 /* set tx mtu */
436 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
437 wb_data[1] = 0;
438 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
439 wb_data, 2);
440
441 /* set cnt max size */
442 wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
443 wb_data[1] = 0;
444 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
445 wb_data, 2);
446
447 /* configure safc */
448 wb_data[0] = 0x1000200;
449 wb_data[1] = 0;
450 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
451 wb_data, 2);
452 /* fix for emulation */
453 if (CHIP_REV_IS_EMUL(bp)) {
454 wb_data[0] = 0xf000;
455 wb_data[1] = 0;
456 REG_WR_DMAE(bp,
457 bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
458 wb_data, 2);
459 }
460
461 REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
462 REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
463 REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
464 val = 0;
465 if (vars->flow_ctrl & FLOW_CTRL_TX)
466 val = 1;
467 REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
468 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
469 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
470 REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
471 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
472 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
473
474 vars->mac_type = MAC_TYPE_BMAC;
475 return 0;
476}
477
478static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
479{
480 struct bnx2x *bp = params->bp;
481 u32 val;
482
483 if (phy_flags & PHY_XGXS_FLAG) {
484 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
485 val = XGXS_RESET_BITS;
486
487 } else { /* SerDes */
488 DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
489 val = SERDES_RESET_BITS;
490 }
491
492 val = val << (params->port*16);
493
494 /* reset and unreset the SerDes/XGXS */
495 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
496 val);
497 udelay(500);
498 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
499 val);
500 bnx2x_set_phy_mdio(params);
501}
502
503void bnx2x_link_status_update(struct link_params *params,
504 struct link_vars *vars)
505{
506 struct bnx2x *bp = params->bp;
507 u8 link_10g;
508 u8 port = params->port;
509
510 if (params->switch_cfg == SWITCH_CFG_1G)
511 vars->phy_flags = PHY_SERDES_FLAG;
512 else
513 vars->phy_flags = PHY_XGXS_FLAG;
514 vars->link_status = REG_RD(bp, params->shmem_base +
515 offsetof(struct shmem_region,
516 port_mb[port].link_status));
517
518 vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
519
520 if (vars->link_up) {
521 DP(NETIF_MSG_LINK, "phy link up\n");
522
523 vars->phy_link_up = 1;
524 vars->duplex = DUPLEX_FULL;
525 switch (vars->link_status &
526 LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
527 case LINK_10THD:
528 vars->duplex = DUPLEX_HALF;
529 /* fall thru */
530 case LINK_10TFD:
531 vars->line_speed = SPEED_10;
532 break;
533
534 case LINK_100TXHD:
535 vars->duplex = DUPLEX_HALF;
536 /* fall thru */
537 case LINK_100T4:
538 case LINK_100TXFD:
539 vars->line_speed = SPEED_100;
540 break;
541
542 case LINK_1000THD:
543 vars->duplex = DUPLEX_HALF;
544 /* fall thru */
545 case LINK_1000TFD:
546 vars->line_speed = SPEED_1000;
547 break;
548
549 case LINK_2500THD:
550 vars->duplex = DUPLEX_HALF;
551 /* fall thru */
552 case LINK_2500TFD:
553 vars->line_speed = SPEED_2500;
554 break;
555
556 case LINK_10GTFD:
557 vars->line_speed = SPEED_10000;
558 break;
559
560 case LINK_12GTFD:
561 vars->line_speed = SPEED_12000;
562 break;
563
564 case LINK_12_5GTFD:
565 vars->line_speed = SPEED_12500;
566 break;
567
568 case LINK_13GTFD:
569 vars->line_speed = SPEED_13000;
570 break;
571
572 case LINK_15GTFD:
573 vars->line_speed = SPEED_15000;
574 break;
575
576 case LINK_16GTFD:
577 vars->line_speed = SPEED_16000;
578 break;
579
580 default:
581 break;
582 }
583
584 if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
585 vars->flow_ctrl |= FLOW_CTRL_TX;
586 else
587 vars->flow_ctrl &= ~FLOW_CTRL_TX;
588
589 if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
590 vars->flow_ctrl |= FLOW_CTRL_RX;
591 else
592 vars->flow_ctrl &= ~FLOW_CTRL_RX;
593
594 if (vars->phy_flags & PHY_XGXS_FLAG) {
8c99e7b0
YR
595 if (vars->line_speed &&
596 ((vars->line_speed == SPEED_10) ||
597 (vars->line_speed == SPEED_100))) {
ea4e040a
YR
598 vars->phy_flags |= PHY_SGMII_FLAG;
599 } else {
600 vars->phy_flags &= ~PHY_SGMII_FLAG;
601 }
602 }
603
604 /* anything 10 and over uses the bmac */
605 link_10g = ((vars->line_speed == SPEED_10000) ||
606 (vars->line_speed == SPEED_12000) ||
607 (vars->line_speed == SPEED_12500) ||
608 (vars->line_speed == SPEED_13000) ||
609 (vars->line_speed == SPEED_15000) ||
610 (vars->line_speed == SPEED_16000));
611 if (link_10g)
612 vars->mac_type = MAC_TYPE_BMAC;
613 else
614 vars->mac_type = MAC_TYPE_EMAC;
615
616 } else { /* link down */
617 DP(NETIF_MSG_LINK, "phy link down\n");
618
619 vars->phy_link_up = 0;
620
621 vars->line_speed = 0;
622 vars->duplex = DUPLEX_FULL;
623 vars->flow_ctrl = FLOW_CTRL_NONE;
624
625 /* indicate no mac active */
626 vars->mac_type = MAC_TYPE_NONE;
627 }
628
629 DP(NETIF_MSG_LINK, "link_status 0x%x phy_link_up %x\n",
630 vars->link_status, vars->phy_link_up);
631 DP(NETIF_MSG_LINK, "line_speed %x duplex %x flow_ctrl 0x%x\n",
632 vars->line_speed, vars->duplex, vars->flow_ctrl);
633}
634
635static void bnx2x_update_mng(struct link_params *params, u32 link_status)
636{
637 struct bnx2x *bp = params->bp;
638 REG_WR(bp, params->shmem_base +
639 offsetof(struct shmem_region,
640 port_mb[params->port].link_status),
641 link_status);
642}
643
644static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
645{
646 u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
647 NIG_REG_INGRESS_BMAC0_MEM;
648 u32 wb_data[2];
649 u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
650
651 /* Only if the bmac is out of reset */
652 if (REG_RD(bp, MISC_REG_RESET_REG_2) &
653 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
654 nig_bmac_enable) {
655
656 /* Clear Rx Enable bit in BMAC_CONTROL register */
657 REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
658 wb_data, 2);
659 wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
660 REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
661 wb_data, 2);
662
663 msleep(1);
664 }
665}
666
667static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
668 u32 line_speed)
669{
670 struct bnx2x *bp = params->bp;
671 u8 port = params->port;
672 u32 init_crd, crd;
673 u32 count = 1000;
ea4e040a
YR
674
675 /* disable port */
676 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
677
678 /* wait for init credit */
679 init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
680 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
681 DP(NETIF_MSG_LINK, "init_crd 0x%x crd 0x%x\n", init_crd, crd);
682
683 while ((init_crd != crd) && count) {
684 msleep(5);
685
686 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
687 count--;
688 }
689 crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
690 if (init_crd != crd) {
691 DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
692 init_crd, crd);
693 return -EINVAL;
694 }
695
8c99e7b0
YR
696 if (flow_ctrl & FLOW_CTRL_RX ||
697 line_speed == SPEED_10 ||
698 line_speed == SPEED_100 ||
699 line_speed == SPEED_1000 ||
700 line_speed == SPEED_2500) {
701 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
ea4e040a
YR
702 /* update threshold */
703 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
704 /* update init credit */
8c99e7b0 705 init_crd = 778; /* (800-18-4) */
ea4e040a
YR
706
707 } else {
708 u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
709 ETH_OVREHEAD)/16;
8c99e7b0 710 REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
ea4e040a
YR
711 /* update threshold */
712 REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
713 /* update init credit */
714 switch (line_speed) {
ea4e040a
YR
715 case SPEED_10000:
716 init_crd = thresh + 553 - 22;
717 break;
718
719 case SPEED_12000:
720 init_crd = thresh + 664 - 22;
721 break;
722
723 case SPEED_13000:
724 init_crd = thresh + 742 - 22;
725 break;
726
727 case SPEED_16000:
728 init_crd = thresh + 778 - 22;
729 break;
730 default:
731 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
732 line_speed);
733 return -EINVAL;
734 break;
735 }
736 }
737 REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
738 DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
739 line_speed, init_crd);
740
741 /* probe the credit changes */
742 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
743 msleep(5);
744 REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
745
746 /* enable port */
747 REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
748 return 0;
749}
750
751static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
752{
753 u32 emac_base;
754 switch (ext_phy_type) {
755 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
756 emac_base = GRCBASE_EMAC0;
757 break;
758 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
759 emac_base = (port) ? GRCBASE_EMAC0: GRCBASE_EMAC1;
760 break;
761 default:
762 emac_base = (port) ? GRCBASE_EMAC1: GRCBASE_EMAC0;
763 break;
764 }
765 return emac_base;
766
767}
768
769u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
770 u8 phy_addr, u8 devad, u16 reg, u16 val)
771{
772 u32 tmp, saved_mode;
773 u8 i, rc = 0;
774 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
775
776 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
777 * (a value of 49==0x31) and make sure that the AUTO poll is off
778 */
779 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
780 tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
781 EMAC_MDIO_MODE_CLOCK_CNT);
782 tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
783 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
784 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
785 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
786 udelay(40);
787
788 /* address */
789
790 tmp = ((phy_addr << 21) | (devad << 16) | reg |
791 EMAC_MDIO_COMM_COMMAND_ADDRESS |
792 EMAC_MDIO_COMM_START_BUSY);
793 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
794
795 for (i = 0; i < 50; i++) {
796 udelay(10);
797
798 tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
799 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
800 udelay(5);
801 break;
802 }
803 }
804 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
805 DP(NETIF_MSG_LINK, "write phy register failed\n");
806 rc = -EFAULT;
807 } else {
808 /* data */
809 tmp = ((phy_addr << 21) | (devad << 16) | val |
810 EMAC_MDIO_COMM_COMMAND_WRITE_45 |
811 EMAC_MDIO_COMM_START_BUSY);
812 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
813
814 for (i = 0; i < 50; i++) {
815 udelay(10);
816
817 tmp = REG_RD(bp, mdio_ctrl +
818 EMAC_REG_EMAC_MDIO_COMM);
819 if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
820 udelay(5);
821 break;
822 }
823 }
824 if (tmp & EMAC_MDIO_COMM_START_BUSY) {
825 DP(NETIF_MSG_LINK, "write phy register failed\n");
826 rc = -EFAULT;
827 }
828 }
829
830 /* Restore the saved mode */
831 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
832
833 return rc;
834}
835
836u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
837 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
838{
839 u32 val, saved_mode;
840 u16 i;
841 u8 rc = 0;
842
843 u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
844 /* set clause 45 mode, slow down the MDIO clock to 2.5MHz
845 * (a value of 49==0x31) and make sure that the AUTO poll is off
846 */
847 saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
848 val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
849 EMAC_MDIO_MODE_CLOCK_CNT));
850 val |= (EMAC_MDIO_MODE_CLAUSE_45 |
851 (49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
852 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
853 REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
854 udelay(40);
855
856 /* address */
857 val = ((phy_addr << 21) | (devad << 16) | reg |
858 EMAC_MDIO_COMM_COMMAND_ADDRESS |
859 EMAC_MDIO_COMM_START_BUSY);
860 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
861
862 for (i = 0; i < 50; i++) {
863 udelay(10);
864
865 val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
866 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
867 udelay(5);
868 break;
869 }
870 }
871 if (val & EMAC_MDIO_COMM_START_BUSY) {
872 DP(NETIF_MSG_LINK, "read phy register failed\n");
873
874 *ret_val = 0;
875 rc = -EFAULT;
876
877 } else {
878 /* data */
879 val = ((phy_addr << 21) | (devad << 16) |
880 EMAC_MDIO_COMM_COMMAND_READ_45 |
881 EMAC_MDIO_COMM_START_BUSY);
882 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
883
884 for (i = 0; i < 50; i++) {
885 udelay(10);
886
887 val = REG_RD(bp, mdio_ctrl +
888 EMAC_REG_EMAC_MDIO_COMM);
889 if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
890 *ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
891 break;
892 }
893 }
894 if (val & EMAC_MDIO_COMM_START_BUSY) {
895 DP(NETIF_MSG_LINK, "read phy register failed\n");
896
897 *ret_val = 0;
898 rc = -EFAULT;
899 }
900 }
901
902 /* Restore the saved mode */
903 REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
904
905 return rc;
906}
907
908static void bnx2x_set_aer_mmd(struct link_params *params,
909 struct link_vars *vars)
910{
911 struct bnx2x *bp = params->bp;
912 u32 ser_lane;
913 u16 offset;
914
915 ser_lane = ((params->lane_config &
916 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
917 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
918
919 offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
920 (params->phy_addr + ser_lane) : 0;
921
922 CL45_WR_OVER_CL22(bp, params->port,
923 params->phy_addr,
924 MDIO_REG_BANK_AER_BLOCK,
925 MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
926}
927
928static void bnx2x_set_master_ln(struct link_params *params)
929{
930 struct bnx2x *bp = params->bp;
931 u16 new_master_ln, ser_lane;
932 ser_lane = ((params->lane_config &
933 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
934 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
935
936 /* set the master_ln for AN */
937 CL45_RD_OVER_CL22(bp, params->port,
938 params->phy_addr,
939 MDIO_REG_BANK_XGXS_BLOCK2,
940 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
941 &new_master_ln);
942
943 CL45_WR_OVER_CL22(bp, params->port,
944 params->phy_addr,
945 MDIO_REG_BANK_XGXS_BLOCK2 ,
946 MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
947 (new_master_ln | ser_lane));
948}
949
950static u8 bnx2x_reset_unicore(struct link_params *params)
951{
952 struct bnx2x *bp = params->bp;
953 u16 mii_control;
954 u16 i;
955
956 CL45_RD_OVER_CL22(bp, params->port,
957 params->phy_addr,
958 MDIO_REG_BANK_COMBO_IEEE0,
959 MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
960
961 /* reset the unicore */
962 CL45_WR_OVER_CL22(bp, params->port,
963 params->phy_addr,
964 MDIO_REG_BANK_COMBO_IEEE0,
965 MDIO_COMBO_IEEE0_MII_CONTROL,
966 (mii_control |
967 MDIO_COMBO_IEEO_MII_CONTROL_RESET));
968
969 /* wait for the reset to self clear */
970 for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
971 udelay(5);
972
973 /* the reset erased the previous bank value */
974 CL45_RD_OVER_CL22(bp, params->port,
975 params->phy_addr,
976 MDIO_REG_BANK_COMBO_IEEE0,
977 MDIO_COMBO_IEEE0_MII_CONTROL,
978 &mii_control);
979
980 if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
981 udelay(5);
982 return 0;
983 }
984 }
985
986 DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
987 return -EINVAL;
988
989}
990
991static void bnx2x_set_swap_lanes(struct link_params *params)
992{
993 struct bnx2x *bp = params->bp;
994 /* Each two bits represents a lane number:
995 No swap is 0123 => 0x1b no need to enable the swap */
996 u16 ser_lane, rx_lane_swap, tx_lane_swap;
997
998 ser_lane = ((params->lane_config &
999 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1000 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1001 rx_lane_swap = ((params->lane_config &
1002 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1003 PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1004 tx_lane_swap = ((params->lane_config &
1005 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1006 PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1007
1008 if (rx_lane_swap != 0x1b) {
1009 CL45_WR_OVER_CL22(bp, params->port,
1010 params->phy_addr,
1011 MDIO_REG_BANK_XGXS_BLOCK2,
1012 MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1013 (rx_lane_swap |
1014 MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1015 MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1016 } else {
1017 CL45_WR_OVER_CL22(bp, params->port,
1018 params->phy_addr,
1019 MDIO_REG_BANK_XGXS_BLOCK2,
1020 MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1021 }
1022
1023 if (tx_lane_swap != 0x1b) {
1024 CL45_WR_OVER_CL22(bp, params->port,
1025 params->phy_addr,
1026 MDIO_REG_BANK_XGXS_BLOCK2,
1027 MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1028 (tx_lane_swap |
1029 MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1030 } else {
1031 CL45_WR_OVER_CL22(bp, params->port,
1032 params->phy_addr,
1033 MDIO_REG_BANK_XGXS_BLOCK2,
1034 MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1035 }
1036}
1037
1038static void bnx2x_set_parallel_detection(struct link_params *params,
1039 u8 phy_flags)
1040{
1041 struct bnx2x *bp = params->bp;
1042 u16 control2;
1043
1044 CL45_RD_OVER_CL22(bp, params->port,
1045 params->phy_addr,
1046 MDIO_REG_BANK_SERDES_DIGITAL,
1047 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1048 &control2);
1049
1050
1051 control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1052
1053
1054 CL45_WR_OVER_CL22(bp, params->port,
1055 params->phy_addr,
1056 MDIO_REG_BANK_SERDES_DIGITAL,
1057 MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1058 control2);
1059
1060 if (phy_flags & PHY_XGXS_FLAG) {
1061 DP(NETIF_MSG_LINK, "XGXS\n");
1062
1063 CL45_WR_OVER_CL22(bp, params->port,
1064 params->phy_addr,
1065 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1066 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1067 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1068
1069 CL45_RD_OVER_CL22(bp, params->port,
1070 params->phy_addr,
1071 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1072 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1073 &control2);
1074
1075
1076 control2 |=
1077 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1078
1079 CL45_WR_OVER_CL22(bp, params->port,
1080 params->phy_addr,
1081 MDIO_REG_BANK_10G_PARALLEL_DETECT,
1082 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1083 control2);
1084
1085 /* Disable parallel detection of HiG */
1086 CL45_WR_OVER_CL22(bp, params->port,
1087 params->phy_addr,
1088 MDIO_REG_BANK_XGXS_BLOCK2,
1089 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1090 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1091 MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1092 }
1093}
1094
1095static void bnx2x_set_autoneg(struct link_params *params,
1096 struct link_vars *vars)
1097{
1098 struct bnx2x *bp = params->bp;
1099 u16 reg_val;
1100
1101 /* CL37 Autoneg */
1102
1103 CL45_RD_OVER_CL22(bp, params->port,
1104 params->phy_addr,
1105 MDIO_REG_BANK_COMBO_IEEE0,
1106 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1107
1108 /* CL37 Autoneg Enabled */
8c99e7b0 1109 if (vars->line_speed == SPEED_AUTO_NEG)
ea4e040a
YR
1110 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1111 else /* CL37 Autoneg Disabled */
1112 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1113 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1114
1115 CL45_WR_OVER_CL22(bp, params->port,
1116 params->phy_addr,
1117 MDIO_REG_BANK_COMBO_IEEE0,
1118 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1119
1120 /* Enable/Disable Autodetection */
1121
1122 CL45_RD_OVER_CL22(bp, params->port,
1123 params->phy_addr,
1124 MDIO_REG_BANK_SERDES_DIGITAL,
1125 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1126 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
8c99e7b0 1127 if (vars->line_speed == SPEED_AUTO_NEG)
ea4e040a
YR
1128 reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1129 else
1130 reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1131
1132 CL45_WR_OVER_CL22(bp, params->port,
1133 params->phy_addr,
1134 MDIO_REG_BANK_SERDES_DIGITAL,
1135 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1136
1137 /* Enable TetonII and BAM autoneg */
1138 CL45_RD_OVER_CL22(bp, params->port,
1139 params->phy_addr,
1140 MDIO_REG_BANK_BAM_NEXT_PAGE,
1141 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1142 &reg_val);
8c99e7b0 1143 if (vars->line_speed == SPEED_AUTO_NEG) {
ea4e040a
YR
1144 /* Enable BAM aneg Mode and TetonII aneg Mode */
1145 reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1146 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1147 } else {
1148 /* TetonII and BAM Autoneg Disabled */
1149 reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1150 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1151 }
1152 CL45_WR_OVER_CL22(bp, params->port,
1153 params->phy_addr,
1154 MDIO_REG_BANK_BAM_NEXT_PAGE,
1155 MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1156 reg_val);
1157
1158 /* Enable Clause 73 Aneg */
8c99e7b0 1159 if ((vars->line_speed == SPEED_AUTO_NEG) &&
ea4e040a
YR
1160 (SUPPORT_CL73)) {
1161 /* Enable BAM Station Manager */
1162
1163 CL45_WR_OVER_CL22(bp, params->port,
1164 params->phy_addr,
1165 MDIO_REG_BANK_CL73_USERB0,
1166 MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1167 (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1168 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1169 MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1170
1171 /* Merge CL73 and CL37 aneg resolution */
1172 CL45_RD_OVER_CL22(bp, params->port,
1173 params->phy_addr,
1174 MDIO_REG_BANK_CL73_USERB0,
1175 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1176 &reg_val);
1177
1178 CL45_WR_OVER_CL22(bp, params->port,
1179 params->phy_addr,
1180 MDIO_REG_BANK_CL73_USERB0,
1181 MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1182 (reg_val |
1183 MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1184
1185 /* Set the CL73 AN speed */
1186
1187 CL45_RD_OVER_CL22(bp, params->port,
1188 params->phy_addr,
1189 MDIO_REG_BANK_CL73_IEEEB1,
1190 MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1191 /* In the SerDes we support only the 1G.
1192 In the XGXS we support the 10G KX4
1193 but we currently do not support the KR */
1194 if (vars->phy_flags & PHY_XGXS_FLAG) {
1195 DP(NETIF_MSG_LINK, "XGXS\n");
1196 /* 10G KX4 */
1197 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1198 } else {
1199 DP(NETIF_MSG_LINK, "SerDes\n");
1200 /* 1000M KX */
1201 reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1202 }
1203 CL45_WR_OVER_CL22(bp, params->port,
1204 params->phy_addr,
1205 MDIO_REG_BANK_CL73_IEEEB1,
1206 MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1207
1208 /* CL73 Autoneg Enabled */
1209 reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1210 } else {
1211 /* CL73 Autoneg Disabled */
1212 reg_val = 0;
1213 }
1214 CL45_WR_OVER_CL22(bp, params->port,
1215 params->phy_addr,
1216 MDIO_REG_BANK_CL73_IEEEB0,
1217 MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1218}
1219
1220/* program SerDes, forced speed */
8c99e7b0
YR
1221static void bnx2x_program_serdes(struct link_params *params,
1222 struct link_vars *vars)
ea4e040a
YR
1223{
1224 struct bnx2x *bp = params->bp;
1225 u16 reg_val;
1226
1227 /* program duplex, disable autoneg */
1228
1229 CL45_RD_OVER_CL22(bp, params->port,
1230 params->phy_addr,
1231 MDIO_REG_BANK_COMBO_IEEE0,
1232 MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1233 reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1234 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1235 if (params->req_duplex == DUPLEX_FULL)
1236 reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1237 CL45_WR_OVER_CL22(bp, params->port,
1238 params->phy_addr,
1239 MDIO_REG_BANK_COMBO_IEEE0,
1240 MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1241
1242 /* program speed
1243 - needed only if the speed is greater than 1G (2.5G or 10G) */
8c99e7b0 1244 CL45_RD_OVER_CL22(bp, params->port,
ea4e040a
YR
1245 params->phy_addr,
1246 MDIO_REG_BANK_SERDES_DIGITAL,
1247 MDIO_SERDES_DIGITAL_MISC1, &reg_val);
8c99e7b0
YR
1248 /* clearing the speed value before setting the right speed */
1249 DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1250
1251 reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1252 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1253
1254 if (!((vars->line_speed == SPEED_1000) ||
1255 (vars->line_speed == SPEED_100) ||
1256 (vars->line_speed == SPEED_10))) {
1257
ea4e040a
YR
1258 reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1259 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
8c99e7b0 1260 if (vars->line_speed == SPEED_10000)
ea4e040a
YR
1261 reg_val |=
1262 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
8c99e7b0 1263 if (vars->line_speed == SPEED_13000)
ea4e040a
YR
1264 reg_val |=
1265 MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
8c99e7b0
YR
1266 }
1267
1268 CL45_WR_OVER_CL22(bp, params->port,
ea4e040a
YR
1269 params->phy_addr,
1270 MDIO_REG_BANK_SERDES_DIGITAL,
1271 MDIO_SERDES_DIGITAL_MISC1, reg_val);
8c99e7b0 1272
ea4e040a
YR
1273}
1274
1275static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1276{
1277 struct bnx2x *bp = params->bp;
1278 u16 val = 0;
1279
1280 /* configure the 48 bits for BAM AN */
1281
1282 /* set extended capabilities */
1283 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1284 val |= MDIO_OVER_1G_UP1_2_5G;
1285 if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1286 val |= MDIO_OVER_1G_UP1_10G;
1287 CL45_WR_OVER_CL22(bp, params->port,
1288 params->phy_addr,
1289 MDIO_REG_BANK_OVER_1G,
1290 MDIO_OVER_1G_UP1, val);
1291
1292 CL45_WR_OVER_CL22(bp, params->port,
1293 params->phy_addr,
1294 MDIO_REG_BANK_OVER_1G,
1295 MDIO_OVER_1G_UP3, 0);
1296}
1297
8c99e7b0 1298static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
ea4e040a 1299{
8c99e7b0 1300 *ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
ea4e040a
YR
1301 /* resolve pause mode and advertisement
1302 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1303
1304 switch (params->req_flow_ctrl) {
1305 case FLOW_CTRL_AUTO:
8c99e7b0
YR
1306 if (params->req_fc_auto_adv == FLOW_CTRL_BOTH) {
1307 *ieee_fc |=
ea4e040a
YR
1308 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1309 } else {
8c99e7b0 1310 *ieee_fc |=
ea4e040a
YR
1311 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1312 }
1313 break;
1314 case FLOW_CTRL_TX:
8c99e7b0 1315 *ieee_fc |=
ea4e040a
YR
1316 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1317 break;
1318
1319 case FLOW_CTRL_RX:
1320 case FLOW_CTRL_BOTH:
8c99e7b0 1321 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
ea4e040a
YR
1322 break;
1323
1324 case FLOW_CTRL_NONE:
1325 default:
8c99e7b0 1326 *ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
ea4e040a
YR
1327 break;
1328 }
8c99e7b0 1329}
ea4e040a 1330
8c99e7b0
YR
1331static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1332 u32 ieee_fc)
1333{
1334 struct bnx2x *bp = params->bp;
1335 /* for AN, we are always publishing full duplex */
ea4e040a
YR
1336
1337 CL45_WR_OVER_CL22(bp, params->port,
1338 params->phy_addr,
1339 MDIO_REG_BANK_COMBO_IEEE0,
8c99e7b0 1340 MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
ea4e040a
YR
1341}
1342
1343static void bnx2x_restart_autoneg(struct link_params *params)
1344{
1345 struct bnx2x *bp = params->bp;
1346 DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1347 if (SUPPORT_CL73) {
1348 /* enable and restart clause 73 aneg */
1349 u16 an_ctrl;
1350
1351 CL45_RD_OVER_CL22(bp, params->port,
1352 params->phy_addr,
1353 MDIO_REG_BANK_CL73_IEEEB0,
1354 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1355 &an_ctrl);
1356 CL45_WR_OVER_CL22(bp, params->port,
1357 params->phy_addr,
1358 MDIO_REG_BANK_CL73_IEEEB0,
1359 MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1360 (an_ctrl |
1361 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1362 MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1363
1364 } else {
1365 /* Enable and restart BAM/CL37 aneg */
1366 u16 mii_control;
1367
1368 CL45_RD_OVER_CL22(bp, params->port,
1369 params->phy_addr,
1370 MDIO_REG_BANK_COMBO_IEEE0,
1371 MDIO_COMBO_IEEE0_MII_CONTROL,
1372 &mii_control);
1373 DP(NETIF_MSG_LINK,
1374 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1375 mii_control);
1376 CL45_WR_OVER_CL22(bp, params->port,
1377 params->phy_addr,
1378 MDIO_REG_BANK_COMBO_IEEE0,
1379 MDIO_COMBO_IEEE0_MII_CONTROL,
1380 (mii_control |
1381 MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1382 MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1383 }
1384}
1385
8c99e7b0
YR
1386static void bnx2x_initialize_sgmii_process(struct link_params *params,
1387 struct link_vars *vars)
ea4e040a
YR
1388{
1389 struct bnx2x *bp = params->bp;
1390 u16 control1;
1391
1392 /* in SGMII mode, the unicore is always slave */
1393
1394 CL45_RD_OVER_CL22(bp, params->port,
1395 params->phy_addr,
1396 MDIO_REG_BANK_SERDES_DIGITAL,
1397 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1398 &control1);
1399 control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1400 /* set sgmii mode (and not fiber) */
1401 control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1402 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1403 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1404 CL45_WR_OVER_CL22(bp, params->port,
1405 params->phy_addr,
1406 MDIO_REG_BANK_SERDES_DIGITAL,
1407 MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1408 control1);
1409
1410 /* if forced speed */
8c99e7b0 1411 if (!(vars->line_speed == SPEED_AUTO_NEG)) {
ea4e040a
YR
1412 /* set speed, disable autoneg */
1413 u16 mii_control;
1414
1415 CL45_RD_OVER_CL22(bp, params->port,
1416 params->phy_addr,
1417 MDIO_REG_BANK_COMBO_IEEE0,
1418 MDIO_COMBO_IEEE0_MII_CONTROL,
1419 &mii_control);
1420 mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1421 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1422 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1423
8c99e7b0 1424 switch (vars->line_speed) {
ea4e040a
YR
1425 case SPEED_100:
1426 mii_control |=
1427 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1428 break;
1429 case SPEED_1000:
1430 mii_control |=
1431 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1432 break;
1433 case SPEED_10:
1434 /* there is nothing to set for 10M */
1435 break;
1436 default:
1437 /* invalid speed for SGMII */
8c99e7b0
YR
1438 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1439 vars->line_speed);
ea4e040a
YR
1440 break;
1441 }
1442
1443 /* setting the full duplex */
1444 if (params->req_duplex == DUPLEX_FULL)
1445 mii_control |=
1446 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1447 CL45_WR_OVER_CL22(bp, params->port,
1448 params->phy_addr,
1449 MDIO_REG_BANK_COMBO_IEEE0,
1450 MDIO_COMBO_IEEE0_MII_CONTROL,
1451 mii_control);
1452
1453 } else { /* AN mode */
1454 /* enable and restart AN */
1455 bnx2x_restart_autoneg(params);
1456 }
1457}
1458
1459
1460/*
1461 * link management
1462 */
1463
1464static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
8c99e7b0
YR
1465{ /* LD LP */
1466 switch (pause_result) { /* ASYM P ASYM P */
1467 case 0xb: /* 1 0 1 1 */
ea4e040a
YR
1468 vars->flow_ctrl = FLOW_CTRL_TX;
1469 break;
1470
8c99e7b0 1471 case 0xe: /* 1 1 1 0 */
ea4e040a
YR
1472 vars->flow_ctrl = FLOW_CTRL_RX;
1473 break;
1474
8c99e7b0
YR
1475 case 0x5: /* 0 1 0 1 */
1476 case 0x7: /* 0 1 1 1 */
1477 case 0xd: /* 1 1 0 1 */
1478 case 0xf: /* 1 1 1 1 */
ea4e040a
YR
1479 vars->flow_ctrl = FLOW_CTRL_BOTH;
1480 break;
1481
1482 default:
1483 break;
1484 }
1485}
1486
1487static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1488 struct link_vars *vars)
1489{
1490 struct bnx2x *bp = params->bp;
1491 u8 ext_phy_addr;
8c99e7b0
YR
1492 u16 ld_pause; /* local */
1493 u16 lp_pause; /* link partner */
ea4e040a
YR
1494 u16 an_complete; /* AN complete */
1495 u16 pause_result;
1496 u8 ret = 0;
1497 u32 ext_phy_type;
1498 u8 port = params->port;
1499 ext_phy_addr = ((params->ext_phy_config &
1500 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1501 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1502
1503 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1504 /* read twice */
1505
1506 bnx2x_cl45_read(bp, port,
1507 ext_phy_type,
1508 ext_phy_addr,
1509 MDIO_AN_DEVAD,
1510 MDIO_AN_REG_STATUS, &an_complete);
1511 bnx2x_cl45_read(bp, port,
1512 ext_phy_type,
1513 ext_phy_addr,
1514 MDIO_AN_DEVAD,
1515 MDIO_AN_REG_STATUS, &an_complete);
1516
1517 if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1518 ret = 1;
1519 bnx2x_cl45_read(bp, port,
1520 ext_phy_type,
1521 ext_phy_addr,
1522 MDIO_AN_DEVAD,
1523 MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1524 bnx2x_cl45_read(bp, port,
1525 ext_phy_type,
1526 ext_phy_addr,
1527 MDIO_AN_DEVAD,
1528 MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1529 pause_result = (ld_pause &
1530 MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1531 pause_result |= (lp_pause &
1532 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1533 DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1534 pause_result);
1535 bnx2x_pause_resolve(vars, pause_result);
8c99e7b0
YR
1536 if (vars->flow_ctrl == FLOW_CTRL_NONE &&
1537 ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1538 bnx2x_cl45_read(bp, port,
1539 ext_phy_type,
1540 ext_phy_addr,
1541 MDIO_AN_DEVAD,
1542 MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1543
1544 bnx2x_cl45_read(bp, port,
1545 ext_phy_type,
1546 ext_phy_addr,
1547 MDIO_AN_DEVAD,
1548 MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1549 pause_result = (ld_pause &
1550 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1551 pause_result |= (lp_pause &
1552 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1553
1554 bnx2x_pause_resolve(vars, pause_result);
1555 DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1556 pause_result);
1557 }
ea4e040a
YR
1558 }
1559 return ret;
1560}
1561
1562
1563static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1564 struct link_vars *vars,
1565 u32 gp_status)
1566{
1567 struct bnx2x *bp = params->bp;
1568 u16 ld_pause; /* local driver */
1569 u16 lp_pause; /* link partner */
1570 u16 pause_result;
1571
1572 vars->flow_ctrl = FLOW_CTRL_NONE;
1573
1574 /* resolve from gp_status in case of AN complete and not sgmii */
1575 if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1576 (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1577 (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1578 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1579 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1580 CL45_RD_OVER_CL22(bp, params->port,
1581 params->phy_addr,
1582 MDIO_REG_BANK_COMBO_IEEE0,
1583 MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1584 &ld_pause);
1585 CL45_RD_OVER_CL22(bp, params->port,
1586 params->phy_addr,
1587 MDIO_REG_BANK_COMBO_IEEE0,
1588 MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1589 &lp_pause);
1590 pause_result = (ld_pause &
1591 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1592 pause_result |= (lp_pause &
1593 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1594 DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1595 bnx2x_pause_resolve(vars, pause_result);
1596 } else if ((params->req_flow_ctrl == FLOW_CTRL_AUTO) &&
1597 (bnx2x_ext_phy_resove_fc(params, vars))) {
1598 return;
1599 } else {
8c99e7b0
YR
1600 if (params->req_flow_ctrl == FLOW_CTRL_AUTO)
1601 vars->flow_ctrl = params->req_fc_auto_adv;
1602 else
1603 vars->flow_ctrl = params->req_flow_ctrl;
ea4e040a
YR
1604 }
1605 DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1606}
1607
1608
1609static u8 bnx2x_link_settings_status(struct link_params *params,
1610 struct link_vars *vars,
1611 u32 gp_status)
1612{
1613 struct bnx2x *bp = params->bp;
1614 u8 rc = 0;
1615 vars->link_status = 0;
1616
1617 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1618 DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1619 gp_status);
1620
1621 vars->phy_link_up = 1;
1622 vars->link_status |= LINK_STATUS_LINK_UP;
1623
1624 if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1625 vars->duplex = DUPLEX_FULL;
1626 else
1627 vars->duplex = DUPLEX_HALF;
1628
1629 bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1630
1631 switch (gp_status & GP_STATUS_SPEED_MASK) {
1632 case GP_STATUS_10M:
1633 vars->line_speed = SPEED_10;
1634 if (vars->duplex == DUPLEX_FULL)
1635 vars->link_status |= LINK_10TFD;
1636 else
1637 vars->link_status |= LINK_10THD;
1638 break;
1639
1640 case GP_STATUS_100M:
1641 vars->line_speed = SPEED_100;
1642 if (vars->duplex == DUPLEX_FULL)
1643 vars->link_status |= LINK_100TXFD;
1644 else
1645 vars->link_status |= LINK_100TXHD;
1646 break;
1647
1648 case GP_STATUS_1G:
1649 case GP_STATUS_1G_KX:
1650 vars->line_speed = SPEED_1000;
1651 if (vars->duplex == DUPLEX_FULL)
1652 vars->link_status |= LINK_1000TFD;
1653 else
1654 vars->link_status |= LINK_1000THD;
1655 break;
1656
1657 case GP_STATUS_2_5G:
1658 vars->line_speed = SPEED_2500;
1659 if (vars->duplex == DUPLEX_FULL)
1660 vars->link_status |= LINK_2500TFD;
1661 else
1662 vars->link_status |= LINK_2500THD;
1663 break;
1664
1665 case GP_STATUS_5G:
1666 case GP_STATUS_6G:
1667 DP(NETIF_MSG_LINK,
1668 "link speed unsupported gp_status 0x%x\n",
1669 gp_status);
1670 return -EINVAL;
1671 break;
1672 case GP_STATUS_10G_KX4:
1673 case GP_STATUS_10G_HIG:
1674 case GP_STATUS_10G_CX4:
1675 vars->line_speed = SPEED_10000;
1676 vars->link_status |= LINK_10GTFD;
1677 break;
1678
1679 case GP_STATUS_12G_HIG:
1680 vars->line_speed = SPEED_12000;
1681 vars->link_status |= LINK_12GTFD;
1682 break;
1683
1684 case GP_STATUS_12_5G:
1685 vars->line_speed = SPEED_12500;
1686 vars->link_status |= LINK_12_5GTFD;
1687 break;
1688
1689 case GP_STATUS_13G:
1690 vars->line_speed = SPEED_13000;
1691 vars->link_status |= LINK_13GTFD;
1692 break;
1693
1694 case GP_STATUS_15G:
1695 vars->line_speed = SPEED_15000;
1696 vars->link_status |= LINK_15GTFD;
1697 break;
1698
1699 case GP_STATUS_16G:
1700 vars->line_speed = SPEED_16000;
1701 vars->link_status |= LINK_16GTFD;
1702 break;
1703
1704 default:
1705 DP(NETIF_MSG_LINK,
1706 "link speed unsupported gp_status 0x%x\n",
1707 gp_status);
1708 return -EINVAL;
1709 break;
1710 }
1711
1712 vars->link_status |= LINK_STATUS_SERDES_LINK;
1713
57963ed9
YR
1714 if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1715 ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1716 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1717 (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1718 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
ea4e040a
YR
1719 vars->autoneg = AUTO_NEG_ENABLED;
1720
1721 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1722 vars->autoneg |= AUTO_NEG_COMPLETE;
1723 vars->link_status |=
1724 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1725 }
1726
1727 vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1728 vars->link_status |=
1729 LINK_STATUS_PARALLEL_DETECTION_USED;
1730
1731 }
1732 if (vars->flow_ctrl & FLOW_CTRL_TX)
8c99e7b0
YR
1733 vars->link_status |=
1734 LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
ea4e040a
YR
1735
1736 if (vars->flow_ctrl & FLOW_CTRL_RX)
8c99e7b0
YR
1737 vars->link_status |=
1738 LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
ea4e040a
YR
1739
1740 } else { /* link_down */
1741 DP(NETIF_MSG_LINK, "phy link down\n");
1742
1743 vars->phy_link_up = 0;
57963ed9 1744
ea4e040a
YR
1745 vars->duplex = DUPLEX_FULL;
1746 vars->flow_ctrl = FLOW_CTRL_NONE;
1747 vars->autoneg = AUTO_NEG_DISABLED;
1748 vars->mac_type = MAC_TYPE_NONE;
1749 }
1750
1751 DP(NETIF_MSG_LINK, "gp_status 0x%x phy_link_up %x line_speed %x \n",
1752 gp_status, vars->phy_link_up, vars->line_speed);
1753 DP(NETIF_MSG_LINK, "duplex %x flow_ctrl 0x%x"
1754 " autoneg 0x%x\n",
1755 vars->duplex,
1756 vars->flow_ctrl, vars->autoneg);
1757 DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1758
1759 return rc;
1760}
1761
1762static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1763{
1764 struct bnx2x *bp = params->bp;
1765 u16 lp_up2;
1766 u16 tx_driver;
1767
1768 /* read precomp */
1769
1770 CL45_RD_OVER_CL22(bp, params->port,
1771 params->phy_addr,
1772 MDIO_REG_BANK_OVER_1G,
1773 MDIO_OVER_1G_LP_UP2, &lp_up2);
1774
1775 CL45_RD_OVER_CL22(bp, params->port,
1776 params->phy_addr,
1777 MDIO_REG_BANK_TX0,
1778 MDIO_TX0_TX_DRIVER, &tx_driver);
1779
1780 /* bits [10:7] at lp_up2, positioned at [15:12] */
1781 lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1782 MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1783 MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1784
1785 if ((lp_up2 != 0) &&
1786 (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1787 /* replace tx_driver bits [15:12] */
1788 tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1789 tx_driver |= lp_up2;
1790 CL45_WR_OVER_CL22(bp, params->port,
1791 params->phy_addr,
1792 MDIO_REG_BANK_TX0,
1793 MDIO_TX0_TX_DRIVER, tx_driver);
1794 }
1795}
1796
1797static u8 bnx2x_emac_program(struct link_params *params,
1798 u32 line_speed, u32 duplex)
1799{
1800 struct bnx2x *bp = params->bp;
1801 u8 port = params->port;
1802 u16 mode = 0;
1803
1804 DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1805 bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1806 EMAC_REG_EMAC_MODE,
1807 (EMAC_MODE_25G_MODE |
1808 EMAC_MODE_PORT_MII_10M |
1809 EMAC_MODE_HALF_DUPLEX));
1810 switch (line_speed) {
1811 case SPEED_10:
1812 mode |= EMAC_MODE_PORT_MII_10M;
1813 break;
1814
1815 case SPEED_100:
1816 mode |= EMAC_MODE_PORT_MII;
1817 break;
1818
1819 case SPEED_1000:
1820 mode |= EMAC_MODE_PORT_GMII;
1821 break;
1822
1823 case SPEED_2500:
1824 mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1825 break;
1826
1827 default:
1828 /* 10G not valid for EMAC */
1829 DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1830 return -EINVAL;
1831 }
1832
1833 if (duplex == DUPLEX_HALF)
1834 mode |= EMAC_MODE_HALF_DUPLEX;
1835 bnx2x_bits_en(bp,
1836 GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1837 mode);
1838
1839 bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1840 line_speed, params->hw_led_mode, params->chip_id);
1841 return 0;
1842}
1843
1844/*****************************************************************************/
17de50b7 1845/* External Phy section */
ea4e040a 1846/*****************************************************************************/
17de50b7 1847static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
ea4e040a
YR
1848{
1849 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
17de50b7 1850 MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
ea4e040a
YR
1851 msleep(1);
1852 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
17de50b7 1853 MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
ea4e040a
YR
1854}
1855
1856static void bnx2x_ext_phy_reset(struct link_params *params,
1857 struct link_vars *vars)
1858{
1859 struct bnx2x *bp = params->bp;
1860 u32 ext_phy_type;
1861 u8 ext_phy_addr = ((params->ext_phy_config &
1862 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1863 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1864 DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1865 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1866 /* The PHY reset is controled by GPIO 1
1867 * Give it 1ms of reset pulse
1868 */
1869 if (vars->phy_flags & PHY_XGXS_FLAG) {
1870
1871 switch (ext_phy_type) {
1872 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1873 DP(NETIF_MSG_LINK, "XGXS Direct\n");
1874 break;
1875
1876 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1877 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1878 DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1879
1880 /* Restore normal power mode*/
1881 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
1882 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1883 params->port);
ea4e040a
YR
1884
1885 /* HW reset */
17de50b7 1886 bnx2x_hw_reset(bp, params->port);
ea4e040a
YR
1887
1888 bnx2x_cl45_write(bp, params->port,
1889 ext_phy_type,
1890 ext_phy_addr,
1891 MDIO_PMA_DEVAD,
1892 MDIO_PMA_REG_CTRL, 0xa040);
1893 break;
1894 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1895 /* Unset Low Power Mode and SW reset */
1896 /* Restore normal power mode*/
1897 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
1898 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1899 params->port);
ea4e040a
YR
1900
1901 DP(NETIF_MSG_LINK, "XGXS 8072\n");
1902 bnx2x_cl45_write(bp, params->port,
1903 ext_phy_type,
1904 ext_phy_addr,
1905 MDIO_PMA_DEVAD,
1906 MDIO_PMA_REG_CTRL,
1907 1<<15);
1908 break;
1909 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1910 {
1911 u16 emac_base;
1912 emac_base = (params->port) ? GRCBASE_EMAC0 :
1913 GRCBASE_EMAC1;
1914
1915 /* Restore normal power mode*/
1916 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
1917 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1918 params->port);
ea4e040a
YR
1919
1920 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
17de50b7
EG
1921 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1922 params->port);
ea4e040a
YR
1923
1924 DP(NETIF_MSG_LINK, "XGXS 8073\n");
ea4e040a
YR
1925 }
1926 break;
1927
1928 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1929 DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1930
1931 /* Restore normal power mode*/
1932 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
1933 MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1934 params->port);
ea4e040a
YR
1935
1936 /* HW reset */
17de50b7 1937 bnx2x_hw_reset(bp, params->port);
ea4e040a
YR
1938
1939 break;
1940
1941 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1942 DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1943 break;
1944
1945 default:
1946 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1947 params->ext_phy_config);
1948 break;
1949 }
1950
1951 } else { /* SerDes */
1952 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1953 switch (ext_phy_type) {
1954 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1955 DP(NETIF_MSG_LINK, "SerDes Direct\n");
1956 break;
1957
1958 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1959 DP(NETIF_MSG_LINK, "SerDes 5482\n");
17de50b7 1960 bnx2x_hw_reset(bp, params->port);
ea4e040a
YR
1961 break;
1962
1963 default:
1964 DP(NETIF_MSG_LINK,
1965 "BAD SerDes ext_phy_config 0x%x\n",
1966 params->ext_phy_config);
1967 break;
1968 }
1969 }
1970}
1971
1972static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1973{
1974 struct bnx2x *bp = params->bp;
1975 u8 port = params->port;
1976 u8 ext_phy_addr = ((params->ext_phy_config &
1977 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1978 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1979 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1980 u16 fw_ver1, fw_ver2;
1981
1982 /* Need to wait 200ms after reset */
1983 msleep(200);
1984 /* Boot port from external ROM
1985 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1986 */
1987 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1988 MDIO_PMA_DEVAD,
1989 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
1990
1991 /* Reset internal microprocessor */
1992 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1993 MDIO_PMA_DEVAD,
1994 MDIO_PMA_REG_GEN_CTRL,
1995 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
1996 /* set micro reset = 0 */
1997 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1998 MDIO_PMA_DEVAD,
1999 MDIO_PMA_REG_GEN_CTRL,
2000 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2001 /* Reset internal microprocessor */
2002 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2003 MDIO_PMA_DEVAD,
2004 MDIO_PMA_REG_GEN_CTRL,
2005 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2006 /* wait for 100ms for code download via SPI port */
2007 msleep(100);
2008
2009 /* Clear ser_boot_ctl bit */
2010 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2011 MDIO_PMA_DEVAD,
2012 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2013 /* Wait 100ms */
2014 msleep(100);
2015
2016 /* Print the PHY FW version */
2017 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2018 MDIO_PMA_DEVAD,
2019 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2020 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2021 MDIO_PMA_DEVAD,
2022 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2023 DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2024}
2025
2026static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2027{
2028 /* This is only required for 8073A1, version 102 only */
2029
2030 struct bnx2x *bp = params->bp;
2031 u8 ext_phy_addr = ((params->ext_phy_config &
2032 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2033 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2034 u16 val;
2035
2036 /* Read 8073 HW revision*/
2037 bnx2x_cl45_read(bp, params->port,
2038 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2039 ext_phy_addr,
2040 MDIO_PMA_DEVAD,
2041 0xc801, &val);
2042
2043 if (val != 1) {
2044 /* No need to workaround in 8073 A1 */
2045 return 0;
2046 }
2047
2048 bnx2x_cl45_read(bp, params->port,
2049 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2050 ext_phy_addr,
2051 MDIO_PMA_DEVAD,
2052 MDIO_PMA_REG_ROM_VER2, &val);
2053
2054 /* SNR should be applied only for version 0x102 */
2055 if (val != 0x102)
2056 return 0;
2057
2058 return 1;
2059}
2060
2061static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2062{
2063 struct bnx2x *bp = params->bp;
2064 u8 ext_phy_addr = ((params->ext_phy_config &
2065 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2066 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2067 u16 val, cnt, cnt1 ;
2068
2069 bnx2x_cl45_read(bp, params->port,
2070 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2071 ext_phy_addr,
2072 MDIO_PMA_DEVAD,
2073 0xc801, &val);
2074
2075 if (val > 0) {
2076 /* No need to workaround in 8073 A1 */
2077 return 0;
2078 }
2079 /* XAUI workaround in 8073 A0: */
2080
2081 /* After loading the boot ROM and restarting Autoneg,
2082 poll Dev1, Reg $C820: */
2083
2084 for (cnt = 0; cnt < 1000; cnt++) {
2085 bnx2x_cl45_read(bp, params->port,
2086 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2087 ext_phy_addr,
2088 MDIO_PMA_DEVAD,
2089 0xc820, &val);
2090 /* If bit [14] = 0 or bit [13] = 0, continue on with
2091 system initialization (XAUI work-around not required,
2092 as these bits indicate 2.5G or 1G link up). */
2093 if (!(val & (1<<14)) || !(val & (1<<13))) {
2094 DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2095 return 0;
2096 } else if (!(val & (1<<15))) {
2097 DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2098 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2099 it's MSB (bit 15) goes to 1 (indicating that the
2100 XAUI workaround has completed),
2101 then continue on with system initialization.*/
2102 for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2103 bnx2x_cl45_read(bp, params->port,
2104 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2105 ext_phy_addr,
2106 MDIO_PMA_DEVAD,
2107 0xc841, &val);
2108 if (val & (1<<15)) {
2109 DP(NETIF_MSG_LINK,
2110 "XAUI workaround has completed\n");
2111 return 0;
2112 }
2113 msleep(3);
2114 }
2115 break;
2116 }
2117 msleep(3);
2118 }
2119 DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2120 return -EINVAL;
2121
2122}
2123
2124static void bnx2x_bcm8073_external_rom_boot(struct link_params *params)
2125{
2126 struct bnx2x *bp = params->bp;
2127 u8 port = params->port;
2128 u8 ext_phy_addr = ((params->ext_phy_config &
2129 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2130 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2131 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2132 u16 fw_ver1, fw_ver2, val;
2133 /* Need to wait 100ms after reset */
2134 msleep(100);
2135 /* Boot port from external ROM */
2136 /* EDC grst */
2137 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2138 MDIO_PMA_DEVAD,
2139 MDIO_PMA_REG_GEN_CTRL,
2140 0x0001);
2141
2142 /* ucode reboot and rst */
2143 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2144 MDIO_PMA_DEVAD,
2145 MDIO_PMA_REG_GEN_CTRL,
2146 0x008c);
2147
2148 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2149 MDIO_PMA_DEVAD,
2150 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2151
2152 /* Reset internal microprocessor */
2153 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2154 MDIO_PMA_DEVAD,
2155 MDIO_PMA_REG_GEN_CTRL,
2156 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2157
2158 /* Release srst bit */
2159 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2160 MDIO_PMA_DEVAD,
2161 MDIO_PMA_REG_GEN_CTRL,
2162 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2163
2164 /* wait for 100ms for code download via SPI port */
2165 msleep(100);
2166
2167 /* Clear ser_boot_ctl bit */
2168 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2169 MDIO_PMA_DEVAD,
2170 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2171
2172 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2173 MDIO_PMA_DEVAD,
2174 MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2175 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2176 MDIO_PMA_DEVAD,
2177 MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2178 DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2179
2180 /* Only set bit 10 = 1 (Tx power down) */
2181 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2182 MDIO_PMA_DEVAD,
2183 MDIO_PMA_REG_TX_POWER_DOWN, &val);
2184
2185 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2186 MDIO_PMA_DEVAD,
2187 MDIO_PMA_REG_TX_POWER_DOWN, (val | 1<<10));
2188
2189 msleep(600);
2190 /* Release bit 10 (Release Tx power down) */
2191 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2192 MDIO_PMA_DEVAD,
2193 MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
2194
2195}
2196
2197static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2198{
2199 struct bnx2x *bp = params->bp;
2200 u8 port = params->port;
2201 u16 val;
2202 u8 ext_phy_addr = ((params->ext_phy_config &
2203 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2204 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2205 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2206
2207 bnx2x_cl45_read(bp, params->port,
2208 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2209 ext_phy_addr,
2210 MDIO_PMA_DEVAD,
2211 0xc801, &val);
2212
2213 if (val == 0) {
2214 /* Mustn't set low power mode in 8073 A0 */
2215 return;
2216 }
2217
2218 /* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2219 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2220 MDIO_XS_DEVAD,
2221 MDIO_XS_PLL_SEQUENCER, &val);
2222 val &= ~(1<<13);
2223 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2224 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2225
2226 /* PLL controls */
2227 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2228 MDIO_XS_DEVAD, 0x805E, 0x1077);
2229 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2230 MDIO_XS_DEVAD, 0x805D, 0x0000);
2231 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2232 MDIO_XS_DEVAD, 0x805C, 0x030B);
2233 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2234 MDIO_XS_DEVAD, 0x805B, 0x1240);
2235 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2236 MDIO_XS_DEVAD, 0x805A, 0x2490);
2237
2238 /* Tx Controls */
2239 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2240 MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2241 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2242 MDIO_XS_DEVAD, 0x80A6, 0x9041);
2243 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2244 MDIO_XS_DEVAD, 0x80A5, 0x4640);
2245
2246 /* Rx Controls */
2247 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2248 MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2249 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2250 MDIO_XS_DEVAD, 0x80FD, 0x9249);
2251 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2252 MDIO_XS_DEVAD, 0x80FC, 0x2015);
2253
2254 /* Enable PLL sequencer (use read-modify-write to set bit 13) */
2255 bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2256 MDIO_XS_DEVAD,
2257 MDIO_XS_PLL_SEQUENCER, &val);
2258 val |= (1<<13);
2259 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2260 MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2261}
2262static void bnx2x_bcm807x_force_10G(struct link_params *params)
2263{
2264 struct bnx2x *bp = params->bp;
2265 u8 port = params->port;
2266 u8 ext_phy_addr = ((params->ext_phy_config &
2267 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2268 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2269 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2270
2271 /* Force KR or KX */
2272 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273 MDIO_PMA_DEVAD,
2274 MDIO_PMA_REG_CTRL,
2275 0x2040);
2276 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2277 MDIO_PMA_DEVAD,
2278 MDIO_PMA_REG_10G_CTRL2,
2279 0x000b);
2280 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281 MDIO_PMA_DEVAD,
2282 MDIO_PMA_REG_BCM_CTRL,
2283 0x0000);
2284 bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2285 MDIO_AN_DEVAD,
2286 MDIO_AN_REG_CTRL,
2287 0x0000);
2288}
2289
2290static void bnx2x_ext_phy_set_pause(struct link_params *params,
2291 struct link_vars *vars)
2292{
2293 struct bnx2x *bp = params->bp;
2294 u16 val;
2295 u8 ext_phy_addr = ((params->ext_phy_config &
2296 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2297 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2298 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2299
2300 /* read modify write pause advertizing */
2301 bnx2x_cl45_read(bp, params->port,
2302 ext_phy_type,
2303 ext_phy_addr,
2304 MDIO_AN_DEVAD,
2305 MDIO_AN_REG_ADV_PAUSE, &val);
2306
2307 val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
8c99e7b0 2308
ea4e040a
YR
2309 /* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2310
8c99e7b0
YR
2311 if ((vars->ieee_fc &
2312 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
ea4e040a
YR
2313 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2314 val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2315 }
8c99e7b0
YR
2316 if ((vars->ieee_fc &
2317 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
ea4e040a
YR
2318 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2319 val |=
2320 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2321 }
2322 DP(NETIF_MSG_LINK,
2323 "Ext phy AN advertize 0x%x\n", val);
2324 bnx2x_cl45_write(bp, params->port,
2325 ext_phy_type,
2326 ext_phy_addr,
2327 MDIO_AN_DEVAD,
2328 MDIO_AN_REG_ADV_PAUSE, val);
2329}
2330
57963ed9
YR
2331
2332static void bnx2x_init_internal_phy(struct link_params *params,
2333 struct link_vars *vars)
2334{
2335 struct bnx2x *bp = params->bp;
2336 u8 port = params->port;
2337 if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2338 u16 bank, rx_eq;
2339
2340 rx_eq = ((params->serdes_config &
2341 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2342 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2343
2344 DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2345 for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2346 bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2347 CL45_WR_OVER_CL22(bp, port,
2348 params->phy_addr,
2349 bank ,
2350 MDIO_RX0_RX_EQ_BOOST,
2351 ((rx_eq &
2352 MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2353 MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2354 }
2355
2356 /* forced speed requested? */
2357 if (vars->line_speed != SPEED_AUTO_NEG) {
2358 DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2359
2360 /* disable autoneg */
2361 bnx2x_set_autoneg(params, vars);
2362
2363 /* program speed and duplex */
8c99e7b0 2364 bnx2x_program_serdes(params, vars);
57963ed9
YR
2365
2366 } else { /* AN_mode */
2367 DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2368
2369 /* AN enabled */
2370 bnx2x_set_brcm_cl37_advertisment(params);
2371
2372 /* program duplex & pause advertisement (for aneg) */
2373 bnx2x_set_ieee_aneg_advertisment(params,
8c99e7b0 2374 vars->ieee_fc);
57963ed9
YR
2375
2376 /* enable autoneg */
2377 bnx2x_set_autoneg(params, vars);
2378
2379 /* enable and restart AN */
2380 bnx2x_restart_autoneg(params);
2381 }
2382
2383 } else { /* SGMII mode */
2384 DP(NETIF_MSG_LINK, "SGMII\n");
2385
8c99e7b0 2386 bnx2x_initialize_sgmii_process(params, vars);
57963ed9
YR
2387 }
2388}
2389
ea4e040a
YR
2390static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2391{
2392 struct bnx2x *bp = params->bp;
2393 u32 ext_phy_type;
2394 u8 ext_phy_addr;
2395 u16 cnt;
2396 u16 ctrl = 0;
2397 u16 val = 0;
2398 u8 rc = 0;
2399 if (vars->phy_flags & PHY_XGXS_FLAG) {
2400 ext_phy_addr = ((params->ext_phy_config &
2401 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2402 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2403
2404 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2405 /* Make sure that the soft reset is off (expect for the 8072:
2406 * due to the lock, it will be done inside the specific
2407 * handling)
2408 */
2409 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2410 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2411 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2412 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2413 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2414 /* Wait for soft reset to get cleared upto 1 sec */
2415 for (cnt = 0; cnt < 1000; cnt++) {
2416 bnx2x_cl45_read(bp, params->port,
2417 ext_phy_type,
2418 ext_phy_addr,
2419 MDIO_PMA_DEVAD,
2420 MDIO_PMA_REG_CTRL, &ctrl);
2421 if (!(ctrl & (1<<15)))
2422 break;
2423 msleep(1);
2424 }
2425 DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2426 ctrl, cnt);
2427 }
2428
2429 switch (ext_phy_type) {
2430 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
ea4e040a
YR
2431 break;
2432
2433 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2434 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2435
2436 bnx2x_cl45_write(bp, params->port,
2437 ext_phy_type,
2438 ext_phy_addr,
2439 MDIO_PMA_DEVAD,
2440 MDIO_PMA_REG_MISC_CTRL,
2441 0x8288);
2442 bnx2x_cl45_write(bp, params->port,
2443 ext_phy_type,
2444 ext_phy_addr,
2445 MDIO_PMA_DEVAD,
2446 MDIO_PMA_REG_PHY_IDENTIFIER,
2447 0x7fbf);
2448 bnx2x_cl45_write(bp, params->port,
2449 ext_phy_type,
2450 ext_phy_addr,
2451 MDIO_PMA_DEVAD,
2452 MDIO_PMA_REG_CMU_PLL_BYPASS,
2453 0x0100);
2454 bnx2x_cl45_write(bp, params->port,
2455 ext_phy_type,
2456 ext_phy_addr,
2457 MDIO_WIS_DEVAD,
2458 MDIO_WIS_REG_LASI_CNTL, 0x1);
2459 break;
2460
2461 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2462 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2463
2464 msleep(10);
2465 /* Force speed */
2466 /* First enable LASI */
2467 bnx2x_cl45_write(bp, params->port,
2468 ext_phy_type,
2469 ext_phy_addr,
2470 MDIO_PMA_DEVAD,
2471 MDIO_PMA_REG_RX_ALARM_CTRL,
2472 0x0400);
2473 bnx2x_cl45_write(bp, params->port,
2474 ext_phy_type,
2475 ext_phy_addr,
2476 MDIO_PMA_DEVAD,
2477 MDIO_PMA_REG_LASI_CTRL, 0x0004);
2478
2479 if (params->req_line_speed == SPEED_10000) {
2480 DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2481
2482 bnx2x_cl45_write(bp, params->port,
2483 ext_phy_type,
2484 ext_phy_addr,
2485 MDIO_PMA_DEVAD,
2486 MDIO_PMA_REG_DIGITAL_CTRL,
2487 0x400);
2488 } else {
2489 /* Force 1Gbps using autoneg with 1G
2490 advertisment */
2491
2492 /* Allow CL37 through CL73 */
2493 DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2494 bnx2x_cl45_write(bp, params->port,
2495 ext_phy_type,
2496 ext_phy_addr,
2497 MDIO_AN_DEVAD,
2498 MDIO_AN_REG_CL37_CL73,
2499 0x040c);
2500
2501 /* Enable Full-Duplex advertisment on CL37 */
2502 bnx2x_cl45_write(bp, params->port,
2503 ext_phy_type,
2504 ext_phy_addr,
2505 MDIO_AN_DEVAD,
8c99e7b0 2506 MDIO_AN_REG_CL37_FC_LP,
ea4e040a
YR
2507 0x0020);
2508 /* Enable CL37 AN */
2509 bnx2x_cl45_write(bp, params->port,
2510 ext_phy_type,
2511 ext_phy_addr,
2512 MDIO_AN_DEVAD,
2513 MDIO_AN_REG_CL37_AN,
2514 0x1000);
2515 /* 1G support */
2516 bnx2x_cl45_write(bp, params->port,
2517 ext_phy_type,
2518 ext_phy_addr,
2519 MDIO_AN_DEVAD,
2520 MDIO_AN_REG_ADV, (1<<5));
2521
2522 /* Enable clause 73 AN */
2523 bnx2x_cl45_write(bp, params->port,
2524 ext_phy_type,
2525 ext_phy_addr,
2526 MDIO_AN_DEVAD,
2527 MDIO_AN_REG_CTRL,
2528 0x1200);
2529
2530 }
2531
2532 break;
2533
2534 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2535 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2536 {
2537 u16 tmp1;
2538 u16 rx_alarm_ctrl_val;
2539 u16 lasi_ctrl_val;
2540 if (ext_phy_type ==
2541 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2542 rx_alarm_ctrl_val = 0x400;
2543 lasi_ctrl_val = 0x0004;
2544 } else {
2545 /* In 8073, port1 is directed through emac0 and
2546 * port0 is directed through emac1
2547 */
2548 rx_alarm_ctrl_val = (1<<2);
2549 /*lasi_ctrl_val = 0x0005;*/
2550 lasi_ctrl_val = 0x0004;
2551 }
2552
2553 /* Wait for soft reset to get cleared upto 1 sec */
2554 for (cnt = 0; cnt < 1000; cnt++) {
2555 bnx2x_cl45_read(bp, params->port,
2556 ext_phy_type,
2557 ext_phy_addr,
2558 MDIO_PMA_DEVAD,
2559 MDIO_PMA_REG_CTRL,
2560 &ctrl);
2561 if (!(ctrl & (1<<15)))
2562 break;
2563 msleep(1);
2564 }
2565 DP(NETIF_MSG_LINK,
2566 "807x control reg 0x%x (after %d ms)\n",
2567 ctrl, cnt);
2568
2569 if (ext_phy_type ==
2570 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2571 bnx2x_bcm8072_external_rom_boot(params);
2572 } else {
2573 bnx2x_bcm8073_external_rom_boot(params);
2574 /* In case of 8073 with long xaui lines,
2575 don't set the 8073 xaui low power*/
2576 bnx2x_bcm8073_set_xaui_low_power_mode(params);
2577 }
2578
2579 /* enable LASI */
2580 bnx2x_cl45_write(bp, params->port,
2581 ext_phy_type,
2582 ext_phy_addr,
2583 MDIO_PMA_DEVAD,
2584 MDIO_PMA_REG_RX_ALARM_CTRL,
2585 rx_alarm_ctrl_val);
2586
2587 bnx2x_cl45_write(bp, params->port,
2588 ext_phy_type,
2589 ext_phy_addr,
2590 MDIO_PMA_DEVAD,
2591 MDIO_PMA_REG_LASI_CTRL,
2592 lasi_ctrl_val);
2593
2594 bnx2x_cl45_read(bp, params->port,
2595 ext_phy_type,
2596 ext_phy_addr,
2597 MDIO_PMA_DEVAD,
2598 MDIO_PMA_REG_RX_ALARM, &tmp1);
2599
2600 DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2601 "0x%x\n", tmp1);
2602
2603 /* If this is forced speed, set to KR or KX
2604 * (all other are not supported)
2605 */
2606 if (!(params->req_line_speed == SPEED_AUTO_NEG)) {
2607 if (params->req_line_speed == SPEED_10000) {
2608 bnx2x_bcm807x_force_10G(params);
2609 DP(NETIF_MSG_LINK,
2610 "Forced speed 10G on 807X\n");
2611 break;
2612 } else if (params->req_line_speed ==
2613 SPEED_2500) {
2614 val = (1<<5);
2615 /* Note that 2.5G works only
2616 when used with 1G advertisment */
2617 } else
2618 val = (1<<5);
2619 } else {
2620
2621 val = 0;
2622 if (params->speed_cap_mask &
2623 PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2624 val |= (1<<7);
2625
2626 if (params->speed_cap_mask &
2627 PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
2628 val |= (1<<5);
2629 DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
2630 /*val = ((1<<5)|(1<<7));*/
2631 }
2632
2633 bnx2x_cl45_write(bp, params->port,
2634 ext_phy_type,
2635 ext_phy_addr,
2636 MDIO_AN_DEVAD,
2637 MDIO_AN_REG_ADV, val);
2638
2639 if (ext_phy_type ==
2640 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2641 /* Disable 2.5Ghz */
2642 bnx2x_cl45_read(bp, params->port,
2643 ext_phy_type,
2644 ext_phy_addr,
2645 MDIO_AN_DEVAD,
2646 0x8329, &tmp1);
2647/* SUPPORT_SPEED_CAPABILITY
2648 (Due to the nature of the link order, its not
2649 possible to enable 2.5G within the autoneg
2650 capabilities)
2651 if (params->speed_cap_mask &
2652 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
2653*/
2654 if (params->req_line_speed == SPEED_2500) {
2655 u16 phy_ver;
2656 /* Allow 2.5G for A1 and above */
2657 bnx2x_cl45_read(bp, params->port,
2658 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2659 ext_phy_addr,
2660 MDIO_PMA_DEVAD,
2661 0xc801, &phy_ver);
2662
2663 if (phy_ver > 0)
2664 tmp1 |= 1;
2665 else
2666 tmp1 &= 0xfffe;
2667 }
2668 else
2669 tmp1 &= 0xfffe;
2670
2671 bnx2x_cl45_write(bp, params->port,
2672 ext_phy_type,
2673 ext_phy_addr,
2674 MDIO_AN_DEVAD,
2675 0x8329, tmp1);
2676 }
2677 /* Add support for CL37 (passive mode) I */
2678 bnx2x_cl45_write(bp, params->port,
2679 ext_phy_type,
2680 ext_phy_addr,
2681 MDIO_AN_DEVAD,
8c99e7b0 2682 MDIO_AN_REG_CL37_FC_LD, 0x040c);
ea4e040a
YR
2683 /* Add support for CL37 (passive mode) II */
2684 bnx2x_cl45_write(bp, params->port,
2685 ext_phy_type,
2686 ext_phy_addr,
2687 MDIO_AN_DEVAD,
8c99e7b0 2688 MDIO_AN_REG_CL37_FC_LD, 0x20);
ea4e040a
YR
2689 /* Add support for CL37 (passive mode) III */
2690 bnx2x_cl45_write(bp, params->port,
2691 ext_phy_type,
2692 ext_phy_addr,
2693 MDIO_AN_DEVAD,
2694 MDIO_AN_REG_CL37_AN, 0x1000);
2695 /* Restart autoneg */
2696 msleep(500);
2697
2698 if (ext_phy_type ==
2699 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2700
2701 /* The SNR will improve about 2db by changing the
2702 BW and FEE main tap. Rest commands are executed
2703 after link is up*/
2704 /* Change FFE main cursor to 5 in EDC register */
2705 if (bnx2x_8073_is_snr_needed(params))
2706 bnx2x_cl45_write(bp, params->port,
2707 ext_phy_type,
2708 ext_phy_addr,
2709 MDIO_PMA_DEVAD,
2710 MDIO_PMA_REG_EDC_FFE_MAIN,
2711 0xFB0C);
2712
2713 /* Enable FEC (Forware Error Correction)
2714 Request in the AN */
2715 bnx2x_cl45_read(bp, params->port,
2716 ext_phy_type,
2717 ext_phy_addr,
2718 MDIO_AN_DEVAD,
2719 MDIO_AN_REG_ADV2, &tmp1);
2720
2721 tmp1 |= (1<<15);
2722
2723 bnx2x_cl45_write(bp, params->port,
2724 ext_phy_type,
2725 ext_phy_addr,
2726 MDIO_AN_DEVAD,
2727 MDIO_AN_REG_ADV2, tmp1);
2728 }
2729
2730 bnx2x_ext_phy_set_pause(params, vars);
2731
2732 bnx2x_cl45_write(bp, params->port,
2733 ext_phy_type,
2734 ext_phy_addr,
2735 MDIO_AN_DEVAD,
2736 MDIO_AN_REG_CTRL, 0x1200);
2737 DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2738 "Advertise 1G=%x, 10G=%x\n",
2739 ((val & (1<<5)) > 0),
2740 ((val & (1<<7)) > 0));
2741 break;
2742 }
2743 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2744 DP(NETIF_MSG_LINK,
2745 "Setting the SFX7101 LASI indication\n");
2746
2747 bnx2x_cl45_write(bp, params->port,
2748 ext_phy_type,
2749 ext_phy_addr,
2750 MDIO_PMA_DEVAD,
2751 MDIO_PMA_REG_LASI_CTRL, 0x1);
2752 DP(NETIF_MSG_LINK,
2753 "Setting the SFX7101 LED to blink on traffic\n");
2754 bnx2x_cl45_write(bp, params->port,
2755 ext_phy_type,
2756 ext_phy_addr,
2757 MDIO_PMA_DEVAD,
2758 MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2759
2760 bnx2x_ext_phy_set_pause(params, vars);
2761 /* Restart autoneg */
2762 bnx2x_cl45_read(bp, params->port,
2763 ext_phy_type,
2764 ext_phy_addr,
2765 MDIO_AN_DEVAD,
2766 MDIO_AN_REG_CTRL, &val);
2767 val |= 0x200;
2768 bnx2x_cl45_write(bp, params->port,
2769 ext_phy_type,
2770 ext_phy_addr,
2771 MDIO_AN_DEVAD,
2772 MDIO_AN_REG_CTRL, val);
2773 break;
2774 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2775 DP(NETIF_MSG_LINK,
2776 "XGXS PHY Failure detected 0x%x\n",
2777 params->ext_phy_config);
2778 rc = -EINVAL;
2779 break;
2780 default:
2781 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2782 params->ext_phy_config);
2783 rc = -EINVAL;
2784 break;
2785 }
2786
2787 } else { /* SerDes */
57963ed9 2788
ea4e040a
YR
2789 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2790 switch (ext_phy_type) {
2791 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2792 DP(NETIF_MSG_LINK, "SerDes Direct\n");
2793 break;
2794
2795 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2796 DP(NETIF_MSG_LINK, "SerDes 5482\n");
2797 break;
2798
2799 default:
2800 DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2801 params->ext_phy_config);
2802 break;
2803 }
2804 }
2805 return rc;
2806}
2807
2808
2809static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
8c99e7b0 2810 struct link_vars *vars)
ea4e040a
YR
2811{
2812 struct bnx2x *bp = params->bp;
2813 u32 ext_phy_type;
2814 u8 ext_phy_addr;
2815 u16 val1 = 0, val2;
2816 u16 rx_sd, pcs_status;
2817 u8 ext_phy_link_up = 0;
2818 u8 port = params->port;
2819 if (vars->phy_flags & PHY_XGXS_FLAG) {
2820 ext_phy_addr = ((params->ext_phy_config &
2821 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2822 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2823
2824 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2825 switch (ext_phy_type) {
2826 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2827 DP(NETIF_MSG_LINK, "XGXS Direct\n");
2828 ext_phy_link_up = 1;
2829 break;
2830
2831 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2832 DP(NETIF_MSG_LINK, "XGXS 8705\n");
2833 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2834 ext_phy_addr,
2835 MDIO_WIS_DEVAD,
2836 MDIO_WIS_REG_LASI_STATUS, &val1);
2837 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2838
2839 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2840 ext_phy_addr,
2841 MDIO_WIS_DEVAD,
2842 MDIO_WIS_REG_LASI_STATUS, &val1);
2843 DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2844
2845 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2846 ext_phy_addr,
2847 MDIO_PMA_DEVAD,
2848 MDIO_PMA_REG_RX_SD, &rx_sd);
2849 DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2850 ext_phy_link_up = (rx_sd & 0x1);
8c99e7b0
YR
2851 if (ext_phy_link_up)
2852 vars->line_speed = SPEED_10000;
ea4e040a
YR
2853 break;
2854
2855 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2856 DP(NETIF_MSG_LINK, "XGXS 8706\n");
2857 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2858 ext_phy_addr,
2859 MDIO_PMA_DEVAD,
2860 MDIO_PMA_REG_LASI_STATUS, &val1);
2861 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2862
2863 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2864 ext_phy_addr,
2865 MDIO_PMA_DEVAD,
2866 MDIO_PMA_REG_LASI_STATUS, &val1);
2867 DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2868
2869 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2870 ext_phy_addr,
2871 MDIO_PMA_DEVAD,
2872 MDIO_PMA_REG_RX_SD, &rx_sd);
2873 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2874 ext_phy_addr,
2875 MDIO_PCS_DEVAD,
2876 MDIO_PCS_REG_STATUS, &pcs_status);
2877
2878 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2879 ext_phy_addr,
2880 MDIO_AN_DEVAD,
2881 MDIO_AN_REG_LINK_STATUS, &val2);
2882 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2883 ext_phy_addr,
2884 MDIO_AN_DEVAD,
2885 MDIO_AN_REG_LINK_STATUS, &val2);
2886
2887 DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2888 " pcs_status 0x%x 1Gbps link_status 0x%x\n",
2889 rx_sd, pcs_status, val2);
2890 /* link is up if both bit 0 of pmd_rx_sd and
2891 * bit 0 of pcs_status are set, or if the autoneg bit
2892 1 is set
2893 */
2894 ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2895 (val2 & (1<<1)));
57963ed9
YR
2896 if (ext_phy_link_up) {
2897 if (val2 & (1<<1))
2898 vars->line_speed = SPEED_1000;
2899 else
2900 vars->line_speed = SPEED_10000;
2901 }
2902
ea4e040a
YR
2903 /* clear LASI indication*/
2904 bnx2x_cl45_read(bp, params->port, ext_phy_type,
2905 ext_phy_addr,
2906 MDIO_PMA_DEVAD,
2907 MDIO_PMA_REG_RX_ALARM, &val2);
2908 break;
2909
2910 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2911 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2912 {
2913 if (ext_phy_type ==
2914 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2915 bnx2x_cl45_read(bp, params->port,
2916 ext_phy_type,
2917 ext_phy_addr,
2918 MDIO_PCS_DEVAD,
2919 MDIO_PCS_REG_LASI_STATUS, &val1);
2920 bnx2x_cl45_read(bp, params->port,
2921 ext_phy_type,
2922 ext_phy_addr,
2923 MDIO_PCS_DEVAD,
2924 MDIO_PCS_REG_LASI_STATUS, &val2);
2925 DP(NETIF_MSG_LINK,
2926 "870x LASI status 0x%x->0x%x\n",
2927 val1, val2);
2928
2929 } else {
2930 /* In 8073, port1 is directed through emac0 and
2931 * port0 is directed through emac1
2932 */
2933 bnx2x_cl45_read(bp, params->port,
2934 ext_phy_type,
2935 ext_phy_addr,
2936 MDIO_PMA_DEVAD,
2937 MDIO_PMA_REG_LASI_STATUS, &val1);
2938
2939 bnx2x_cl45_read(bp, params->port,
2940 ext_phy_type,
2941 ext_phy_addr,
2942 MDIO_PMA_DEVAD,
2943 MDIO_PMA_REG_LASI_STATUS, &val2);
2944 DP(NETIF_MSG_LINK,
2945 "8703 LASI status 0x%x->0x%x\n",
2946 val1, val2);
2947 }
2948
2949 /* clear the interrupt LASI status register */
2950 bnx2x_cl45_read(bp, params->port,
2951 ext_phy_type,
2952 ext_phy_addr,
2953 MDIO_PCS_DEVAD,
2954 MDIO_PCS_REG_STATUS, &val2);
2955 bnx2x_cl45_read(bp, params->port,
2956 ext_phy_type,
2957 ext_phy_addr,
2958 MDIO_PCS_DEVAD,
2959 MDIO_PCS_REG_STATUS, &val1);
2960 DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
2961 val2, val1);
2962 /* Check the LASI */
2963 bnx2x_cl45_read(bp, params->port,
2964 ext_phy_type,
2965 ext_phy_addr,
2966 MDIO_PMA_DEVAD,
2967 MDIO_PMA_REG_RX_ALARM, &val2);
2968 bnx2x_cl45_read(bp, params->port,
2969 ext_phy_type,
2970 ext_phy_addr,
2971 MDIO_PMA_DEVAD,
2972 MDIO_PMA_REG_RX_ALARM,
2973 &val1);
2974 DP(NETIF_MSG_LINK, "KR 0x9003 0x%x->0x%x\n",
2975 val2, val1);
2976 /* Check the link status */
2977 bnx2x_cl45_read(bp, params->port,
2978 ext_phy_type,
2979 ext_phy_addr,
2980 MDIO_PCS_DEVAD,
2981 MDIO_PCS_REG_STATUS, &val2);
2982 DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
2983
2984 bnx2x_cl45_read(bp, params->port,
2985 ext_phy_type,
2986 ext_phy_addr,
2987 MDIO_PMA_DEVAD,
2988 MDIO_PMA_REG_STATUS, &val2);
2989 bnx2x_cl45_read(bp, params->port,
2990 ext_phy_type,
2991 ext_phy_addr,
2992 MDIO_PMA_DEVAD,
2993 MDIO_PMA_REG_STATUS, &val1);
2994 ext_phy_link_up = ((val1 & 4) == 4);
2995 DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
2996 if (ext_phy_type ==
2997 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2998 u16 an1000_status = 0;
2999 if (ext_phy_link_up &&
3000 (
3001 (params->req_line_speed != SPEED_10000)
3002 )) {
3003 if (bnx2x_bcm8073_xaui_wa(params)
3004 != 0) {
3005 ext_phy_link_up = 0;
3006 break;
3007 }
3008 bnx2x_cl45_read(bp, params->port,
3009 ext_phy_type,
3010 ext_phy_addr,
3011 MDIO_XS_DEVAD,
3012 0x8304,
3013 &an1000_status);
3014 bnx2x_cl45_read(bp, params->port,
3015 ext_phy_type,
3016 ext_phy_addr,
3017 MDIO_XS_DEVAD,
3018 0x8304,
3019 &an1000_status);
3020 }
3021 /* Check the link status on 1.1.2 */
3022 bnx2x_cl45_read(bp, params->port,
3023 ext_phy_type,
3024 ext_phy_addr,
3025 MDIO_PMA_DEVAD,
3026 MDIO_PMA_REG_STATUS, &val2);
3027 bnx2x_cl45_read(bp, params->port,
3028 ext_phy_type,
3029 ext_phy_addr,
3030 MDIO_PMA_DEVAD,
3031 MDIO_PMA_REG_STATUS, &val1);
3032 DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3033 "an_link_status=0x%x\n",
3034 val2, val1, an1000_status);
3035
3036 ext_phy_link_up = (((val1 & 4) == 4) ||
3037 (an1000_status & (1<<1)));
3038 if (ext_phy_link_up &&
3039 bnx2x_8073_is_snr_needed(params)) {
3040 /* The SNR will improve about 2dbby
3041 changing the BW and FEE main tap.*/
3042
3043 /* The 1st write to change FFE main
3044 tap is set before restart AN */
3045 /* Change PLL Bandwidth in EDC
3046 register */
3047 bnx2x_cl45_write(bp, port, ext_phy_type,
3048 ext_phy_addr,
3049 MDIO_PMA_DEVAD,
3050 MDIO_PMA_REG_PLL_BANDWIDTH,
3051 0x26BC);
3052
3053 /* Change CDR Bandwidth in EDC
3054 register */
3055 bnx2x_cl45_write(bp, port, ext_phy_type,
3056 ext_phy_addr,
3057 MDIO_PMA_DEVAD,
3058 MDIO_PMA_REG_CDR_BANDWIDTH,
3059 0x0333);
3060
3061 }
3062 }
3063 break;
3064 }
3065 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3066 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3067 ext_phy_addr,
3068 MDIO_PMA_DEVAD,
3069 MDIO_PMA_REG_LASI_STATUS, &val2);
3070 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3071 ext_phy_addr,
3072 MDIO_PMA_DEVAD,
3073 MDIO_PMA_REG_LASI_STATUS, &val1);
3074 DP(NETIF_MSG_LINK,
3075 "10G-base-T LASI status 0x%x->0x%x\n",
3076 val2, val1);
3077 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3078 ext_phy_addr,
3079 MDIO_PMA_DEVAD,
3080 MDIO_PMA_REG_STATUS, &val2);
3081 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3082 ext_phy_addr,
3083 MDIO_PMA_DEVAD,
3084 MDIO_PMA_REG_STATUS, &val1);
3085 DP(NETIF_MSG_LINK,
3086 "10G-base-T PMA status 0x%x->0x%x\n",
3087 val2, val1);
3088 ext_phy_link_up = ((val1 & 4) == 4);
3089 /* if link is up
3090 * print the AN outcome of the SFX7101 PHY
3091 */
3092 if (ext_phy_link_up) {
3093 bnx2x_cl45_read(bp, params->port,
3094 ext_phy_type,
3095 ext_phy_addr,
3096 MDIO_AN_DEVAD,
3097 MDIO_AN_REG_MASTER_STATUS,
3098 &val2);
57963ed9 3099 vars->line_speed = SPEED_10000;
ea4e040a
YR
3100 DP(NETIF_MSG_LINK,
3101 "SFX7101 AN status 0x%x->Master=%x\n",
3102 val2,
3103 (val2 & (1<<14)));
3104 }
3105 break;
3106
3107 default:
3108 DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3109 params->ext_phy_config);
3110 ext_phy_link_up = 0;
3111 break;
3112 }
3113
3114 } else { /* SerDes */
3115 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3116 switch (ext_phy_type) {
3117 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3118 DP(NETIF_MSG_LINK, "SerDes Direct\n");
3119 ext_phy_link_up = 1;
3120 break;
3121
3122 case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3123 DP(NETIF_MSG_LINK, "SerDes 5482\n");
3124 ext_phy_link_up = 1;
3125 break;
3126
3127 default:
3128 DP(NETIF_MSG_LINK,
3129 "BAD SerDes ext_phy_config 0x%x\n",
3130 params->ext_phy_config);
3131 ext_phy_link_up = 0;
3132 break;
3133 }
3134 }
3135
3136 return ext_phy_link_up;
3137}
3138
3139static void bnx2x_link_int_enable(struct link_params *params)
3140{
3141 u8 port = params->port;
3142 u32 ext_phy_type;
3143 u32 mask;
3144 struct bnx2x *bp = params->bp;
3145 /* setting the status to report on link up
3146 for either XGXS or SerDes */
3147
3148 if (params->switch_cfg == SWITCH_CFG_10G) {
3149 mask = (NIG_MASK_XGXS0_LINK10G |
3150 NIG_MASK_XGXS0_LINK_STATUS);
3151 DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3152 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3153 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3154 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3155 (ext_phy_type !=
3156 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3157 mask |= NIG_MASK_MI_INT;
3158 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3159 }
3160
3161 } else { /* SerDes */
3162 mask = NIG_MASK_SERDES0_LINK_STATUS;
3163 DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3164 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3165 if ((ext_phy_type !=
3166 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3167 (ext_phy_type !=
3168 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3169 mask |= NIG_MASK_MI_INT;
3170 DP(NETIF_MSG_LINK, "enabled external phy int\n");
3171 }
3172 }
3173 bnx2x_bits_en(bp,
3174 NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3175 mask);
3176 DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3177 (params->switch_cfg == SWITCH_CFG_10G),
3178 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3179
3180 DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3181 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3182 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3183 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3184 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3185 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3186 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3187}
3188
3189
3190/*
3191 * link management
3192 */
3193static void bnx2x_link_int_ack(struct link_params *params,
3194 struct link_vars *vars, u16 is_10g)
3195{
3196 struct bnx2x *bp = params->bp;
3197 u8 port = params->port;
3198
3199 /* first reset all status
3200 * we assume only one line will be change at a time */
3201 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3202 (NIG_STATUS_XGXS0_LINK10G |
3203 NIG_STATUS_XGXS0_LINK_STATUS |
3204 NIG_STATUS_SERDES0_LINK_STATUS));
3205 if (vars->phy_link_up) {
3206 if (is_10g) {
3207 /* Disable the 10G link interrupt
3208 * by writing 1 to the status register
3209 */
3210 DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3211 bnx2x_bits_en(bp,
3212 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3213 NIG_STATUS_XGXS0_LINK10G);
3214
3215 } else if (params->switch_cfg == SWITCH_CFG_10G) {
3216 /* Disable the link interrupt
3217 * by writing 1 to the relevant lane
3218 * in the status register
3219 */
3220 u32 ser_lane = ((params->lane_config &
3221 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3222 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3223
3224 DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3225 bnx2x_bits_en(bp,
3226 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3227 ((1 << ser_lane) <<
3228 NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3229
3230 } else { /* SerDes */
3231 DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3232 /* Disable the link interrupt
3233 * by writing 1 to the status register
3234 */
3235 bnx2x_bits_en(bp,
3236 NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3237 NIG_STATUS_SERDES0_LINK_STATUS);
3238 }
3239
3240 } else { /* link_down */
3241 }
3242}
3243
3244static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3245{
3246 u8 *str_ptr = str;
3247 u32 mask = 0xf0000000;
3248 u8 shift = 8*4;
3249 u8 digit;
3250 if (len < 10) {
3251 /* Need more then 10chars for this format */
3252 *str_ptr = '\0';
3253 return -EINVAL;
3254 }
3255 while (shift > 0) {
3256
3257 shift -= 4;
3258 digit = ((num & mask) >> shift);
3259 if (digit < 0xa)
3260 *str_ptr = digit + '0';
3261 else
3262 *str_ptr = digit - 0xa + 'a';
3263 str_ptr++;
3264 mask = mask >> 4;
3265 if (shift == 4*4) {
3266 *str_ptr = ':';
3267 str_ptr++;
3268 }
3269 }
3270 *str_ptr = '\0';
3271 return 0;
3272}
3273
3274
57963ed9
YR
3275static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3276 u32 ext_phy_type)
ea4e040a
YR
3277{
3278 u32 cnt = 0;
3279 u16 ctrl = 0;
3280 /* Enable EMAC0 in to enable MDIO */
3281 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3282 (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3283 msleep(5);
3284
3285 /* take ext phy out of reset */
3286 bnx2x_set_gpio(bp,
17de50b7
EG
3287 MISC_REGISTERS_GPIO_2,
3288 MISC_REGISTERS_GPIO_HIGH,
3289 port);
ea4e040a
YR
3290
3291 bnx2x_set_gpio(bp,
17de50b7
EG
3292 MISC_REGISTERS_GPIO_1,
3293 MISC_REGISTERS_GPIO_HIGH,
3294 port);
ea4e040a
YR
3295
3296 /* wait for 5ms */
3297 msleep(5);
3298
3299 for (cnt = 0; cnt < 1000; cnt++) {
3300 msleep(1);
3301 bnx2x_cl45_read(bp, port,
57963ed9 3302 ext_phy_type,
ea4e040a
YR
3303 ext_phy_addr,
3304 MDIO_PMA_DEVAD,
3305 MDIO_PMA_REG_CTRL,
3306 &ctrl);
3307 if (!(ctrl & (1<<15))) {
3308 DP(NETIF_MSG_LINK, "Reset completed\n\n");
3309 break;
3310 }
3311 }
3312}
3313
17de50b7 3314static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
ea4e040a
YR
3315{
3316 /* put sf to reset */
ea4e040a 3317 bnx2x_set_gpio(bp,
17de50b7
EG
3318 MISC_REGISTERS_GPIO_1,
3319 MISC_REGISTERS_GPIO_LOW,
3320 port);
3321 bnx2x_set_gpio(bp,
3322 MISC_REGISTERS_GPIO_2,
3323 MISC_REGISTERS_GPIO_LOW,
3324 port);
ea4e040a
YR
3325}
3326
3327u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3328 u8 *version, u16 len)
3329{
3330 struct bnx2x *bp = params->bp;
3331 u32 ext_phy_type = 0;
3332 u16 val = 0;
3333 u8 ext_phy_addr = 0 ;
3334 u8 status = 0 ;
3335 u32 ver_num;
3336
3337 if (version == NULL || params == NULL)
3338 return -EINVAL;
3339
3340 /* reset the returned value to zero */
3341 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3342 ext_phy_addr = ((params->ext_phy_config &
3343 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3344 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3345
3346 switch (ext_phy_type) {
3347 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3348
3349 if (len < 5)
3350 return -EINVAL;
3351
3352 /* Take ext phy out of reset */
3353 if (!driver_loaded)
57963ed9
YR
3354 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3355 ext_phy_type);
ea4e040a
YR
3356
3357 /* wait for 1ms */
3358 msleep(1);
3359
3360 bnx2x_cl45_read(bp, params->port,
3361 ext_phy_type,
3362 ext_phy_addr,
3363 MDIO_PMA_DEVAD,
3364 MDIO_PMA_REG_7101_VER1, &val);
3365 version[2] = (val & 0xFF);
3366 version[3] = ((val & 0xFF00)>>8);
3367
3368 bnx2x_cl45_read(bp, params->port,
3369 ext_phy_type,
3370 ext_phy_addr,
3371 MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3372 &val);
3373 version[0] = (val & 0xFF);
3374 version[1] = ((val & 0xFF00)>>8);
3375 version[4] = '\0';
3376
3377 if (!driver_loaded)
17de50b7 3378 bnx2x_turn_off_sf(bp, params->port);
ea4e040a
YR
3379 break;
3380 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3381 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3382 {
57963ed9
YR
3383 /* Take ext phy out of reset */
3384 if (!driver_loaded)
3385 bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3386 ext_phy_type);
3387
ea4e040a
YR
3388 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3389 ext_phy_addr,
3390 MDIO_PMA_DEVAD,
3391 MDIO_PMA_REG_ROM_VER1, &val);
3392 ver_num = val<<16;
3393 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3394 ext_phy_addr,
3395 MDIO_PMA_DEVAD,
3396 MDIO_PMA_REG_ROM_VER2, &val);
3397 ver_num |= val;
3398 status = bnx2x_format_ver(ver_num, version, len);
3399 break;
3400 }
3401 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3402 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3403
3404 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3405 ext_phy_addr,
3406 MDIO_PMA_DEVAD,
3407 MDIO_PMA_REG_ROM_VER1, &val);
3408 ver_num = val<<16;
3409 bnx2x_cl45_read(bp, params->port, ext_phy_type,
3410 ext_phy_addr,
3411 MDIO_PMA_DEVAD,
3412 MDIO_PMA_REG_ROM_VER2, &val);
3413 ver_num |= val;
3414 status = bnx2x_format_ver(ver_num, version, len);
3415 break;
3416
3417 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3418 break;
3419
3420 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3421 DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3422 " type is FAILURE!\n");
3423 status = -EINVAL;
3424 break;
3425
3426 default:
3427 break;
3428 }
3429 return status;
3430}
3431
3432static void bnx2x_set_xgxs_loopback(struct link_params *params,
3433 struct link_vars *vars,
3434 u8 is_10g)
3435{
3436 u8 port = params->port;
3437 struct bnx2x *bp = params->bp;
3438
3439 if (is_10g) {
3440 u32 md_devad;
3441
3442 DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3443
3444 /* change the uni_phy_addr in the nig */
3445 md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3446 port*0x18));
3447
3448 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3449
3450 bnx2x_cl45_write(bp, port, 0,
3451 params->phy_addr,
3452 5,
3453 (MDIO_REG_BANK_AER_BLOCK +
3454 (MDIO_AER_BLOCK_AER_REG & 0xf)),
3455 0x2800);
3456
3457 bnx2x_cl45_write(bp, port, 0,
3458 params->phy_addr,
3459 5,
3460 (MDIO_REG_BANK_CL73_IEEEB0 +
3461 (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3462 0x6041);
3463
3464 /* set aer mmd back */
3465 bnx2x_set_aer_mmd(params, vars);
3466
3467 /* and md_devad */
3468 REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3469 md_devad);
3470
3471 } else {
3472 u16 mii_control;
3473
3474 DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3475
3476 CL45_RD_OVER_CL22(bp, port,
3477 params->phy_addr,
3478 MDIO_REG_BANK_COMBO_IEEE0,
3479 MDIO_COMBO_IEEE0_MII_CONTROL,
3480 &mii_control);
3481
3482 CL45_WR_OVER_CL22(bp, port,
3483 params->phy_addr,
3484 MDIO_REG_BANK_COMBO_IEEE0,
3485 MDIO_COMBO_IEEE0_MII_CONTROL,
3486 (mii_control |
3487 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3488 }
3489}
3490
3491
3492static void bnx2x_ext_phy_loopback(struct link_params *params)
3493{
3494 struct bnx2x *bp = params->bp;
3495 u8 ext_phy_addr;
3496 u32 ext_phy_type;
3497
3498 if (params->switch_cfg == SWITCH_CFG_10G) {
3499 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3500 /* CL37 Autoneg Enabled */
3501 ext_phy_addr = ((params->ext_phy_config &
3502 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3503 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3504 switch (ext_phy_type) {
3505 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3506 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3507 DP(NETIF_MSG_LINK,
3508 "ext_phy_loopback: We should not get here\n");
3509 break;
3510 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3511 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3512 break;
3513 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3514 DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3515 break;
3516 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3517 /* SFX7101_XGXS_TEST1 */
3518 bnx2x_cl45_write(bp, params->port, ext_phy_type,
3519 ext_phy_addr,
3520 MDIO_XS_DEVAD,
3521 MDIO_XS_SFX7101_XGXS_TEST1,
3522 0x100);
3523 DP(NETIF_MSG_LINK,
3524 "ext_phy_loopback: set ext phy loopback\n");
3525 break;
3526 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3527
3528 break;
3529 } /* switch external PHY type */
3530 } else {
3531 /* serdes */
3532 ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3533 ext_phy_addr = (params->ext_phy_config &
3534 PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3535 >> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3536 }
3537}
3538
3539
3540/*
3541 *------------------------------------------------------------------------
3542 * bnx2x_override_led_value -
3543 *
3544 * Override the led value of the requsted led
3545 *
3546 *------------------------------------------------------------------------
3547 */
3548u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3549 u32 led_idx, u32 value)
3550{
3551 u32 reg_val;
3552
3553 /* If port 0 then use EMAC0, else use EMAC1*/
3554 u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3555
3556 DP(NETIF_MSG_LINK,
3557 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3558 port, led_idx, value);
3559
3560 switch (led_idx) {
3561 case 0: /* 10MB led */
3562 /* Read the current value of the LED register in
3563 the EMAC block */
3564 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3565 /* Set the OVERRIDE bit to 1 */
3566 reg_val |= EMAC_LED_OVERRIDE;
3567 /* If value is 1, set the 10M_OVERRIDE bit,
3568 otherwise reset it.*/
3569 reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3570 (reg_val & ~EMAC_LED_10MB_OVERRIDE);
3571 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3572 break;
3573 case 1: /*100MB led */
3574 /*Read the current value of the LED register in
3575 the EMAC block */
3576 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3577 /* Set the OVERRIDE bit to 1 */
3578 reg_val |= EMAC_LED_OVERRIDE;
3579 /* If value is 1, set the 100M_OVERRIDE bit,
3580 otherwise reset it.*/
3581 reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3582 (reg_val & ~EMAC_LED_100MB_OVERRIDE);
3583 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3584 break;
3585 case 2: /* 1000MB led */
3586 /* Read the current value of the LED register in the
3587 EMAC block */
3588 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3589 /* Set the OVERRIDE bit to 1 */
3590 reg_val |= EMAC_LED_OVERRIDE;
3591 /* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3592 reset it. */
3593 reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3594 (reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3595 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3596 break;
3597 case 3: /* 2500MB led */
3598 /* Read the current value of the LED register in the
3599 EMAC block*/
3600 reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3601 /* Set the OVERRIDE bit to 1 */
3602 reg_val |= EMAC_LED_OVERRIDE;
3603 /* If value is 1, set the 2500M_OVERRIDE bit, otherwise
3604 reset it.*/
3605 reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3606 (reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3607 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3608 break;
3609 case 4: /*10G led */
3610 if (port == 0) {
3611 REG_WR(bp, NIG_REG_LED_10G_P0,
3612 value);
3613 } else {
3614 REG_WR(bp, NIG_REG_LED_10G_P1,
3615 value);
3616 }
3617 break;
3618 case 5: /* TRAFFIC led */
3619 /* Find if the traffic control is via BMAC or EMAC */
3620 if (port == 0)
3621 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3622 else
3623 reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3624
3625 /* Override the traffic led in the EMAC:*/
3626 if (reg_val == 1) {
3627 /* Read the current value of the LED register in
3628 the EMAC block */
3629 reg_val = REG_RD(bp, emac_base +
3630 EMAC_REG_EMAC_LED);
3631 /* Set the TRAFFIC_OVERRIDE bit to 1 */
3632 reg_val |= EMAC_LED_OVERRIDE;
3633 /* If value is 1, set the TRAFFIC bit, otherwise
3634 reset it.*/
3635 reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3636 (reg_val & ~EMAC_LED_TRAFFIC);
3637 REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3638 } else { /* Override the traffic led in the BMAC: */
3639 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3640 + port*4, 1);
3641 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3642 value);
3643 }
3644 break;
3645 default:
3646 DP(NETIF_MSG_LINK,
3647 "bnx2x_override_led_value() unknown led index %d "
3648 "(should be 0-5)\n", led_idx);
3649 return -EINVAL;
3650 }
3651
3652 return 0;
3653}
3654
3655
3656u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3657 u16 hw_led_mode, u32 chip_id)
3658{
3659 u8 rc = 0;
3660 DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3661 DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3662 speed, hw_led_mode);
3663 switch (mode) {
3664 case LED_MODE_OFF:
3665 REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3666 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3667 SHARED_HW_CFG_LED_MAC1);
3668 break;
3669
3670 case LED_MODE_OPER:
3671 REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3672 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3673 port*4, 0);
3674 /* Set blinking rate to ~15.9Hz */
3675 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3676 LED_BLINK_RATE_VAL);
3677 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3678 port*4, 1);
34f80b04
EG
3679 if (!CHIP_IS_E1H(bp) &&
3680 ((speed == SPEED_2500) ||
ea4e040a
YR
3681 (speed == SPEED_1000) ||
3682 (speed == SPEED_100) ||
3683 (speed == SPEED_10))) {
3684 /* On Everest 1 Ax chip versions for speeds less than
3685 10G LED scheme is different */
3686 REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3687 + port*4, 1);
3688 REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3689 port*4, 0);
3690 REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3691 port*4, 1);
3692 }
3693 break;
3694
3695 default:
3696 rc = -EINVAL;
3697 DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3698 mode);
3699 break;
3700 }
3701 return rc;
3702
3703}
3704
3705u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3706{
3707 struct bnx2x *bp = params->bp;
3708 u16 gp_status = 0;
3709
3710 CL45_RD_OVER_CL22(bp, params->port,
3711 params->phy_addr,
3712 MDIO_REG_BANK_GP_STATUS,
3713 MDIO_GP_STATUS_TOP_AN_STATUS1,
3714 &gp_status);
3715 /* link is up only if both local phy and external phy are up */
3716 if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3717 bnx2x_ext_phy_is_link_up(params, vars))
3718 return 0;
3719
3720 return -ESRCH;
3721}
3722
3723static u8 bnx2x_link_initialize(struct link_params *params,
3724 struct link_vars *vars)
3725{
3726 struct bnx2x *bp = params->bp;
3727 u8 port = params->port;
3728 u8 rc = 0;
57963ed9
YR
3729 u8 non_ext_phy;
3730 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
ea4e040a
YR
3731 /* Activate the external PHY */
3732 bnx2x_ext_phy_reset(params, vars);
3733
3734 bnx2x_set_aer_mmd(params, vars);
3735
3736 if (vars->phy_flags & PHY_XGXS_FLAG)
3737 bnx2x_set_master_ln(params);
3738
3739 rc = bnx2x_reset_unicore(params);
3740 /* reset the SerDes and wait for reset bit return low */
3741 if (rc != 0)
3742 return rc;
3743
3744 bnx2x_set_aer_mmd(params, vars);
3745
3746 /* setting the masterLn_def again after the reset */
3747 if (vars->phy_flags & PHY_XGXS_FLAG) {
3748 bnx2x_set_master_ln(params);
3749 bnx2x_set_swap_lanes(params);
3750 }
3751
ea4e040a
YR
3752 if (vars->phy_flags & PHY_XGXS_FLAG) {
3753 if (params->req_line_speed &&
3754 ((params->req_line_speed == SPEED_100) ||
3755 (params->req_line_speed == SPEED_10))) {
3756 vars->phy_flags |= PHY_SGMII_FLAG;
3757 } else {
3758 vars->phy_flags &= ~PHY_SGMII_FLAG;
3759 }
3760 }
57963ed9
YR
3761 /* In case of external phy existance, the line speed would be the
3762 line speed linked up by the external phy. In case it is direct only,
3763 then the line_speed during initialization will be equal to the
3764 req_line_speed*/
3765 vars->line_speed = params->req_line_speed;
ea4e040a 3766
8c99e7b0 3767 bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
ea4e040a 3768
57963ed9
YR
3769 /* init ext phy and enable link state int */
3770 non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3771 (params->loopback_mode == LOOPBACK_XGXS_10) ||
3772 (params->loopback_mode == LOOPBACK_EXT_PHY));
3773
3774 if (non_ext_phy ||
3775 (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3776 if (params->req_line_speed == SPEED_AUTO_NEG)
3777 bnx2x_set_parallel_detection(params, vars->phy_flags);
3778 bnx2x_init_internal_phy(params, vars);
ea4e040a
YR
3779 }
3780
57963ed9
YR
3781 if (!non_ext_phy)
3782 rc |= bnx2x_ext_phy_init(params, vars);
ea4e040a
YR
3783
3784 bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
57963ed9
YR
3785 (NIG_STATUS_XGXS0_LINK10G |
3786 NIG_STATUS_XGXS0_LINK_STATUS |
3787 NIG_STATUS_SERDES0_LINK_STATUS));
ea4e040a
YR
3788
3789 return rc;
3790
3791}
3792
3793
3794u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3795{
3796 struct bnx2x *bp = params->bp;
3797
3798 u32 val;
3799 DP(NETIF_MSG_LINK, "Phy Initialization started\n");
3800 DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3801 params->req_line_speed, params->req_flow_ctrl);
3802 vars->link_status = 0;
57963ed9
YR
3803 vars->phy_link_up = 0;
3804 vars->link_up = 0;
3805 vars->line_speed = 0;
3806 vars->duplex = DUPLEX_FULL;
3807 vars->flow_ctrl = FLOW_CTRL_NONE;
3808 vars->mac_type = MAC_TYPE_NONE;
3809
ea4e040a
YR
3810 if (params->switch_cfg == SWITCH_CFG_1G)
3811 vars->phy_flags = PHY_SERDES_FLAG;
3812 else
3813 vars->phy_flags = PHY_XGXS_FLAG;
3814
3815 /* disable attentions */
3816 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3817 (NIG_MASK_XGXS0_LINK_STATUS |
3818 NIG_MASK_XGXS0_LINK10G |
3819 NIG_MASK_SERDES0_LINK_STATUS |
3820 NIG_MASK_MI_INT));
3821
3822 bnx2x_emac_init(params, vars);
3823
3824 if (CHIP_REV_IS_FPGA(bp)) {
3825 vars->link_up = 1;
3826 vars->line_speed = SPEED_10000;
3827 vars->duplex = DUPLEX_FULL;
3828 vars->flow_ctrl = FLOW_CTRL_NONE;
3829 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
34f80b04
EG
3830 /* enable on E1.5 FPGA */
3831 if (CHIP_IS_E1H(bp)) {
3832 vars->flow_ctrl |=
3833 (FLOW_CTRL_TX | FLOW_CTRL_RX);
3834 vars->link_status |=
3835 (LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3836 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3837 }
ea4e040a
YR
3838
3839 bnx2x_emac_enable(params, vars, 0);
3840 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3841 /* disable drain */
3842 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3843 + params->port*4, 0);
3844
3845 /* update shared memory */
3846 bnx2x_update_mng(params, vars->link_status);
3847
3848 return 0;
3849
3850 } else
3851 if (CHIP_REV_IS_EMUL(bp)) {
3852
3853 vars->link_up = 1;
3854 vars->line_speed = SPEED_10000;
3855 vars->duplex = DUPLEX_FULL;
3856 vars->flow_ctrl = FLOW_CTRL_NONE;
3857 vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3858
3859 bnx2x_bmac_enable(params, vars, 0);
3860
3861 bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3862 /* Disable drain */
3863 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3864 + params->port*4, 0);
3865
3866 /* update shared memory */
3867 bnx2x_update_mng(params, vars->link_status);
3868
3869 return 0;
3870
3871 } else
3872 if (params->loopback_mode == LOOPBACK_BMAC) {
3873 vars->link_up = 1;
3874 vars->line_speed = SPEED_10000;
3875 vars->duplex = DUPLEX_FULL;
3876 vars->flow_ctrl = FLOW_CTRL_NONE;
3877 vars->mac_type = MAC_TYPE_BMAC;
3878
3879 vars->phy_flags = PHY_XGXS_FLAG;
3880
3881 bnx2x_phy_deassert(params, vars->phy_flags);
3882 /* set bmac loopback */
3883 bnx2x_bmac_enable(params, vars, 1);
3884
3885 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3886 params->port*4, 0);
3887 } else if (params->loopback_mode == LOOPBACK_EMAC) {
3888 vars->link_up = 1;
3889 vars->line_speed = SPEED_1000;
3890 vars->duplex = DUPLEX_FULL;
3891 vars->flow_ctrl = FLOW_CTRL_NONE;
3892 vars->mac_type = MAC_TYPE_EMAC;
3893
3894 vars->phy_flags = PHY_XGXS_FLAG;
3895
3896 bnx2x_phy_deassert(params, vars->phy_flags);
3897 /* set bmac loopback */
3898 bnx2x_emac_enable(params, vars, 1);
3899 bnx2x_emac_program(params, vars->line_speed,
3900 vars->duplex);
3901 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3902 params->port*4, 0);
3903 } else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
3904 (params->loopback_mode == LOOPBACK_EXT_PHY)) {
3905 vars->link_up = 1;
3906 vars->line_speed = SPEED_10000;
3907 vars->duplex = DUPLEX_FULL;
3908 vars->flow_ctrl = FLOW_CTRL_NONE;
3909
3910 vars->phy_flags = PHY_XGXS_FLAG;
3911
3912 val = REG_RD(bp,
3913 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3914 params->port*0x18);
3915 params->phy_addr = (u8)val;
3916
3917 bnx2x_phy_deassert(params, vars->phy_flags);
3918 bnx2x_link_initialize(params, vars);
3919
3920 vars->mac_type = MAC_TYPE_BMAC;
3921
3922 bnx2x_bmac_enable(params, vars, 0);
3923
3924 if (params->loopback_mode == LOOPBACK_XGXS_10) {
3925 /* set 10G XGXS loopback */
3926 bnx2x_set_xgxs_loopback(params, vars, 1);
3927 } else {
3928 /* set external phy loopback */
3929 bnx2x_ext_phy_loopback(params);
3930 }
3931 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
3932 params->port*4, 0);
3933 } else
3934 /* No loopback */
3935 {
3936
3937 bnx2x_phy_deassert(params, vars->phy_flags);
3938 switch (params->switch_cfg) {
3939 case SWITCH_CFG_1G:
3940 vars->phy_flags |= PHY_SERDES_FLAG;
3941 if ((params->ext_phy_config &
3942 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
3943 PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
3944 vars->phy_flags |=
3945 PHY_SGMII_FLAG;
3946 }
3947
3948 val = REG_RD(bp,
3949 NIG_REG_SERDES0_CTRL_PHY_ADDR+
3950 params->port*0x10);
3951
3952 params->phy_addr = (u8)val;
3953
3954 break;
3955 case SWITCH_CFG_10G:
3956 vars->phy_flags |= PHY_XGXS_FLAG;
3957 val = REG_RD(bp,
3958 NIG_REG_XGXS0_CTRL_PHY_ADDR+
3959 params->port*0x18);
3960 params->phy_addr = (u8)val;
3961
3962 break;
3963 default:
3964 DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
3965 return -EINVAL;
3966 break;
3967 }
3968
3969 bnx2x_link_initialize(params, vars);
57963ed9 3970 msleep(30);
ea4e040a
YR
3971 bnx2x_link_int_enable(params);
3972 }
3973 return 0;
3974}
3975
3976u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
3977{
3978
3979 struct bnx2x *bp = params->bp;
3980 u32 ext_phy_config = params->ext_phy_config;
3981 u16 hw_led_mode = params->hw_led_mode;
3982 u32 chip_id = params->chip_id;
3983 u8 port = params->port;
3984 u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
3985 /* disable attentions */
3986
3987 vars->link_status = 0;
3988 bnx2x_update_mng(params, vars->link_status);
3989 bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3990 (NIG_MASK_XGXS0_LINK_STATUS |
3991 NIG_MASK_XGXS0_LINK10G |
3992 NIG_MASK_SERDES0_LINK_STATUS |
3993 NIG_MASK_MI_INT));
3994
3995 /* activate nig drain */
3996 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
3997
3998 /* disable nig egress interface */
3999 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4000 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4001
4002 /* Stop BigMac rx */
4003 bnx2x_bmac_rx_disable(bp, port);
4004
4005 /* disable emac */
4006 REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4007
4008 msleep(10);
4009 /* The PHY reset is controled by GPIO 1
4010 * Hold it as vars low
4011 */
4012 /* clear link led */
4013 bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4014 if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4015 if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4016 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4017 /* HW reset */
4018
4019 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
17de50b7
EG
4020 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4021 port);
ea4e040a
YR
4022
4023 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
4024 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4025 port);
ea4e040a
YR
4026
4027 DP(NETIF_MSG_LINK, "reset external PHY\n");
57963ed9
YR
4028 } else if (ext_phy_type ==
4029 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4030 DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
ea4e040a
YR
4031 "low power mode\n",
4032 port);
4033 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
17de50b7
EG
4034 MISC_REGISTERS_GPIO_OUTPUT_LOW,
4035 port);
ea4e040a
YR
4036 }
4037 }
4038 /* reset the SerDes/XGXS */
4039 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4040 (0x1ff << (port*16)));
4041
4042 /* reset BigMac */
4043 REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4044 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4045
4046 /* disable nig ingress interface */
4047 REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4048 REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4049 REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4050 REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4051 vars->link_up = 0;
4052 return 0;
4053}
4054
57963ed9
YR
4055static u8 bnx2x_update_link_down(struct link_params *params,
4056 struct link_vars *vars)
4057{
4058 struct bnx2x *bp = params->bp;
4059 u8 port = params->port;
4060 DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4061 bnx2x_set_led(bp, port, LED_MODE_OFF,
4062 0, params->hw_led_mode,
4063 params->chip_id);
4064
4065 /* indicate no mac active */
4066 vars->mac_type = MAC_TYPE_NONE;
4067
4068 /* update shared memory */
4069 vars->link_status = 0;
4070 vars->line_speed = 0;
4071 bnx2x_update_mng(params, vars->link_status);
4072
4073 /* activate nig drain */
4074 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4075
4076 /* reset BigMac */
4077 bnx2x_bmac_rx_disable(bp, params->port);
4078 REG_WR(bp, GRCBASE_MISC +
4079 MISC_REGISTERS_RESET_REG_2_CLEAR,
4080 (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4081 return 0;
4082}
4083
4084static u8 bnx2x_update_link_up(struct link_params *params,
4085 struct link_vars *vars,
4086 u8 link_10g, u32 gp_status)
4087{
4088 struct bnx2x *bp = params->bp;
4089 u8 port = params->port;
4090 u8 rc = 0;
4091 vars->link_status |= LINK_STATUS_LINK_UP;
4092 if (link_10g) {
4093 bnx2x_bmac_enable(params, vars, 0);
4094 bnx2x_set_led(bp, port, LED_MODE_OPER,
4095 SPEED_10000, params->hw_led_mode,
4096 params->chip_id);
4097
4098 } else {
4099 bnx2x_emac_enable(params, vars, 0);
4100 rc = bnx2x_emac_program(params, vars->line_speed,
4101 vars->duplex);
4102
4103 /* AN complete? */
4104 if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4105 if (!(vars->phy_flags &
4106 PHY_SGMII_FLAG))
4107 bnx2x_set_sgmii_tx_driver(params);
4108 }
4109 }
4110
4111 /* PBF - link up */
4112 rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4113 vars->line_speed);
4114
4115 /* disable drain */
4116 REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4117
4118 /* update shared memory */
4119 bnx2x_update_mng(params, vars->link_status);
4120 return rc;
4121}
ea4e040a
YR
4122/* This function should called upon link interrupt */
4123/* In case vars->link_up, driver needs to
4124 1. Update the pbf
4125 2. Disable drain
4126 3. Update the shared memory
4127 4. Indicate link up
4128 5. Set LEDs
4129 Otherwise,
4130 1. Update shared memory
4131 2. Reset BigMac
4132 3. Report link down
4133 4. Unset LEDs
4134*/
4135u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4136{
4137 struct bnx2x *bp = params->bp;
4138 u8 port = params->port;
ea4e040a 4139 u16 gp_status;
57963ed9
YR
4140 u8 link_10g;
4141 u8 ext_phy_link_up, rc = 0;
4142 u32 ext_phy_type;
ea4e040a
YR
4143
4144 DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4145 port,
4146 (vars->phy_flags & PHY_XGXS_FLAG),
4147 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4148
4149 DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4150 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4151 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4152 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4153
4154 DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4155 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4156 REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4157
57963ed9 4158 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
ea4e040a 4159
57963ed9
YR
4160 /* Check external link change only for non-direct */
4161 ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4162
4163 /* Read gp_status */
4164 CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4165 MDIO_REG_BANK_GP_STATUS,
4166 MDIO_GP_STATUS_TOP_AN_STATUS1,
4167 &gp_status);
ea4e040a
YR
4168
4169 rc = bnx2x_link_settings_status(params, vars, gp_status);
4170 if (rc != 0)
4171 return rc;
4172
4173 /* anything 10 and over uses the bmac */
4174 link_10g = ((vars->line_speed == SPEED_10000) ||
4175 (vars->line_speed == SPEED_12000) ||
4176 (vars->line_speed == SPEED_12500) ||
4177 (vars->line_speed == SPEED_13000) ||
4178 (vars->line_speed == SPEED_15000) ||
4179 (vars->line_speed == SPEED_16000));
4180
4181 bnx2x_link_int_ack(params, vars, link_10g);
4182
57963ed9
YR
4183 /* In case external phy link is up, and internal link is down
4184 ( not initialized yet probably after link initialization, it needs
4185 to be initialized.
4186 Note that after link down-up as result of cable plug,
4187 the xgxs link would probably become up again without the need to
4188 initialize it*/
ea4e040a 4189
57963ed9
YR
4190 if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4191 (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4192 (ext_phy_link_up && !vars->phy_link_up))
4193 bnx2x_init_internal_phy(params, vars);
ea4e040a 4194
57963ed9
YR
4195 /* link is up only if both local phy and external phy are up */
4196 vars->link_up = (ext_phy_link_up && vars->phy_link_up);
ea4e040a 4197
57963ed9
YR
4198 if (vars->link_up)
4199 rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4200 else
4201 rc = bnx2x_update_link_down(params, vars);
ea4e040a
YR
4202
4203 return rc;
4204}
4205
4206static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4207{
4208 u16 val, cnt;
4209
4210 bnx2x_cl45_read(bp, port,
4211 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4212 phy_addr,
4213 MDIO_PMA_DEVAD,
4214 MDIO_PMA_REG_7101_RESET, &val);
4215
4216 for (cnt = 0; cnt < 10; cnt++) {
4217 msleep(50);
4218 /* Writes a self-clearing reset */
4219 bnx2x_cl45_write(bp, port,
4220 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4221 phy_addr,
4222 MDIO_PMA_DEVAD,
4223 MDIO_PMA_REG_7101_RESET,
4224 (val | (1<<15)));
4225 /* Wait for clear */
4226 bnx2x_cl45_read(bp, port,
4227 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4228 phy_addr,
4229 MDIO_PMA_DEVAD,
4230 MDIO_PMA_REG_7101_RESET, &val);
4231
4232 if ((val & (1<<15)) == 0)
4233 break;
4234 }
4235}
4236#define RESERVED_SIZE 256
4237/* max application is 160K bytes - data at end of RAM */
4238#define MAX_APP_SIZE 160*1024 - RESERVED_SIZE
4239
4240/* Header is 14 bytes */
4241#define HEADER_SIZE 14
4242#define DATA_OFFSET HEADER_SIZE
4243
4244#define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4245 bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4246 ext_phy_addr, \
4247 MDIO_PCS_DEVAD, \
4248 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4249
4250/* Programs an image to DSP's flash via the SPI port*/
4251static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4252 u8 ext_phy_addr,
4253 char data[], u32 size)
4254{
4255 const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4256 /* Doesn't include last trans!*/
4257 const u16 last_trans_size = size%4; /* Num bytes on last trans */
4258 u16 trans_cnt, byte_cnt;
4259 u32 data_index;
4260 u16 tmp;
4261 u16 code_started = 0;
4262 u16 image_revision1, image_revision2;
4263 u16 cnt;
4264
4265 DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4266 /* Going to flash*/
4267 if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4268 /* This very often will be the case, because the image is built
4269 with 160Kbytes size whereas the total image size must actually
4270 be 160Kbytes-RESERVED_SIZE */
4271 DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4272 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4273 size = MAX_APP_SIZE+HEADER_SIZE;
4274 }
4275 DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4276 DP(NETIF_MSG_LINK, " %c%c\n", data[0x150], data[0x151]);
4277 /* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4278 and issuing a reset.*/
4279
4280 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
17de50b7 4281 MISC_REGISTERS_GPIO_HIGH, port);
ea4e040a
YR
4282
4283 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4284
4285 /* wait 0.5 sec */
4286 for (cnt = 0; cnt < 100; cnt++)
4287 msleep(5);
4288
4289 /* Make sure we can access the DSP
4290 And it's in the correct mode (waiting for download) */
4291
4292 bnx2x_cl45_read(bp, port,
4293 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4294 ext_phy_addr,
4295 MDIO_PCS_DEVAD,
4296 MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4297
4298 if (tmp != 0x000A) {
4299 DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4300 "Expected 0x000A, read 0x%04X\n", tmp);
4301 DP(NETIF_MSG_LINK, "Download failed\n");
4302 return -EINVAL;
4303 }
4304
4305 /* Mux the SPI interface away from the internal processor */
4306 bnx2x_cl45_write(bp, port,
4307 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4308 ext_phy_addr,
4309 MDIO_PCS_DEVAD,
4310 MDIO_PCS_REG_7101_SPI_MUX, 1);
4311
4312 /* Reset the SPI port */
4313 bnx2x_cl45_write(bp, port,
4314 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4315 ext_phy_addr,
4316 MDIO_PCS_DEVAD,
4317 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4318 bnx2x_cl45_write(bp, port,
4319 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4320 ext_phy_addr,
4321 MDIO_PCS_DEVAD,
4322 MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4323 (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4324 bnx2x_cl45_write(bp, port,
4325 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4326 ext_phy_addr,
4327 MDIO_PCS_DEVAD,
4328 MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4329
4330 /* Erase the flash */
4331 bnx2x_cl45_write(bp, port,
4332 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4333 ext_phy_addr,
4334 MDIO_PCS_DEVAD,
4335 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4336 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4337
4338 bnx2x_cl45_write(bp, port,
4339 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4340 ext_phy_addr,
4341 MDIO_PCS_DEVAD,
4342 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4343 1);
4344
4345 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4346 bnx2x_cl45_write(bp, port,
4347 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4348 ext_phy_addr,
4349 MDIO_PCS_DEVAD,
4350 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4351 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4352
4353 bnx2x_cl45_write(bp, port,
4354 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4355 ext_phy_addr,
4356 MDIO_PCS_DEVAD,
4357 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4358 1);
4359 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4360
4361 /* Wait 10 seconds, the maximum time for the erase to complete */
4362 DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4363 for (cnt = 0; cnt < 1000; cnt++)
4364 msleep(10);
4365
4366 DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4367 data_index = 0;
4368 for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4369 bnx2x_cl45_write(bp, port,
4370 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4371 ext_phy_addr,
4372 MDIO_PCS_DEVAD,
4373 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4374 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4375
4376 bnx2x_cl45_write(bp, port,
4377 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4378 ext_phy_addr,
4379 MDIO_PCS_DEVAD,
4380 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4381 1);
4382 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4383
4384 bnx2x_cl45_write(bp, port,
4385 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4386 ext_phy_addr,
4387 MDIO_PCS_DEVAD,
4388 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4389 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4390
4391 /* Bits 23-16 of address */
4392 bnx2x_cl45_write(bp, port,
4393 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4394 ext_phy_addr,
4395 MDIO_PCS_DEVAD,
4396 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4397 (data_index>>16));
4398 /* Bits 15-8 of address */
4399 bnx2x_cl45_write(bp, port,
4400 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4401 ext_phy_addr,
4402 MDIO_PCS_DEVAD,
4403 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4404 (data_index>>8));
4405
4406 /* Bits 7-0 of address */
4407 bnx2x_cl45_write(bp, port,
4408 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4409 ext_phy_addr,
4410 MDIO_PCS_DEVAD,
4411 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4412 ((u16)data_index));
4413
4414 byte_cnt = 0;
4415 while (byte_cnt < 4 && data_index < size) {
4416 bnx2x_cl45_write(bp, port,
4417 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4418 ext_phy_addr,
4419 MDIO_PCS_DEVAD,
4420 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4421 data[data_index++]);
4422 byte_cnt++;
4423 }
4424
4425 bnx2x_cl45_write(bp, port,
4426 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4427 ext_phy_addr,
4428 MDIO_PCS_DEVAD,
4429 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4430 byte_cnt+4);
4431
4432 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4433 msleep(5); /* Wait 5 ms minimum between transs */
4434
4435 /* Let the user know something's going on.*/
4436 /* a pacifier ever 4K */
4437 if ((data_index % 1023) == 0)
4438 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4439 }
4440
4441 DP(NETIF_MSG_LINK, "\n");
4442 /* Transfer the last block if there is data remaining */
4443 if (last_trans_size) {
4444 bnx2x_cl45_write(bp, port,
4445 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4446 ext_phy_addr,
4447 MDIO_PCS_DEVAD,
4448 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4449 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4450
4451 bnx2x_cl45_write(bp, port,
4452 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4453 ext_phy_addr,
4454 MDIO_PCS_DEVAD,
4455 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4456 1);
4457
4458 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4459
4460 bnx2x_cl45_write(bp, port,
4461 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4462 ext_phy_addr,
4463 MDIO_PCS_DEVAD,
4464 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4465 MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4466
4467 /* Bits 23-16 of address */
4468 bnx2x_cl45_write(bp, port,
4469 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4470 ext_phy_addr,
4471 MDIO_PCS_DEVAD,
4472 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4473 (data_index>>16));
4474 /* Bits 15-8 of address */
4475 bnx2x_cl45_write(bp, port,
4476 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4477 ext_phy_addr,
4478 MDIO_PCS_DEVAD,
4479 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4480 (data_index>>8));
4481
4482 /* Bits 7-0 of address */
4483 bnx2x_cl45_write(bp, port,
4484 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4485 ext_phy_addr,
4486 MDIO_PCS_DEVAD,
4487 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4488 ((u16)data_index));
4489
4490 byte_cnt = 0;
4491 while (byte_cnt < last_trans_size && data_index < size) {
4492 /* Bits 7-0 of address */
4493 bnx2x_cl45_write(bp, port,
4494 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4495 ext_phy_addr,
4496 MDIO_PCS_DEVAD,
4497 MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4498 data[data_index++]);
4499 byte_cnt++;
4500 }
4501
4502 bnx2x_cl45_write(bp, port,
4503 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4504 ext_phy_addr,
4505 MDIO_PCS_DEVAD,
4506 MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4507 byte_cnt+4);
4508
4509 SPI_START_TRANSFER(bp, port, ext_phy_addr);
4510 }
4511
4512 /* DSP Remove Download Mode */
17de50b7
EG
4513 bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4514 MISC_REGISTERS_GPIO_LOW, port);
ea4e040a
YR
4515
4516 bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4517
4518 /* wait 0.5 sec to allow it to run */
4519 for (cnt = 0; cnt < 100; cnt++)
4520 msleep(5);
4521
17de50b7 4522 bnx2x_hw_reset(bp, port);
ea4e040a
YR
4523
4524 for (cnt = 0; cnt < 100; cnt++)
4525 msleep(5);
4526
4527 /* Check that the code is started. In case the download
4528 checksum failed, the code won't be started. */
4529 bnx2x_cl45_read(bp, port,
4530 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4531 ext_phy_addr,
4532 MDIO_PCS_DEVAD,
4533 MDIO_PCS_REG_7101_DSP_ACCESS,
4534 &tmp);
4535
4536 code_started = (tmp & (1<<4));
4537 if (!code_started) {
4538 DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4539 return -EINVAL;
4540 }
4541
4542 /* Verify that the file revision is now equal to the image
4543 revision within the DSP */
4544 bnx2x_cl45_read(bp, port,
4545 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4546 ext_phy_addr,
4547 MDIO_PMA_DEVAD,
4548 MDIO_PMA_REG_7101_VER1,
4549 &image_revision1);
4550
4551 bnx2x_cl45_read(bp, port,
4552 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4553 ext_phy_addr,
4554 MDIO_PMA_DEVAD,
4555 MDIO_PMA_REG_7101_VER2,
4556 &image_revision2);
4557
4558 if (data[0x14e] != (image_revision2&0xFF) ||
4559 data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4560 data[0x150] != (image_revision1&0xFF) ||
4561 data[0x151] != ((image_revision1&0xFF00)>>8)) {
4562 DP(NETIF_MSG_LINK, "Download failed.\n");
4563 return -EINVAL;
4564 }
4565 DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4566 return 0;
4567}
4568
4569u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4570 u8 driver_loaded, char data[], u32 size)
4571{
4572 u8 rc = 0;
4573 u32 ext_phy_type;
4574 u8 ext_phy_addr;
4575 ext_phy_addr = ((ext_phy_config &
4576 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4577 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4578
4579 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4580
4581 switch (ext_phy_type) {
4582 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4583 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4584 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4585 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4586 DP(NETIF_MSG_LINK,
4587 "Flash download not supported for this ext phy\n");
4588 rc = -EINVAL;
4589 break;
4590 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4591 /* Take ext phy out of reset */
4592 if (!driver_loaded)
57963ed9 4593 bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
ea4e040a
YR
4594 rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4595 data, size);
4596 if (!driver_loaded)
17de50b7 4597 bnx2x_turn_off_sf(bp, port);
ea4e040a
YR
4598 break;
4599 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4600 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4601 case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4602 default:
4603 DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
4604 rc = -EINVAL;
4605 break;
4606 }
4607 return rc;
4608}
4609
This page took 0.223002 seconds and 5 git commands to generate.