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