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