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