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