bnx2x_link.c revision a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506a
1/* Copyright 2008-2011 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#include "bnx2x_cmn.h"
29
30
31/********************************************************/
32#define ETH_HLEN			14
33/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
34#define ETH_OVREHEAD			(ETH_HLEN + 8 + 8)
35#define ETH_MIN_PACKET_SIZE		60
36#define ETH_MAX_PACKET_SIZE		1500
37#define ETH_MAX_JUMBO_PACKET_SIZE	9600
38#define MDIO_ACCESS_TIMEOUT		1000
39#define BMAC_CONTROL_RX_ENABLE		2
40#define WC_LANE_MAX			4
41#define I2C_SWITCH_WIDTH		2
42#define I2C_BSC0			0
43#define I2C_BSC1			1
44#define I2C_WA_RETRY_CNT		3
45#define MCPR_IMC_COMMAND_READ_OP	1
46#define MCPR_IMC_COMMAND_WRITE_OP	2
47
48/* LED Blink rate that will achieve ~15.9Hz */
49#define LED_BLINK_RATE_VAL_E3		354
50#define LED_BLINK_RATE_VAL_E1X_E2	480
51/***********************************************************/
52/*			Shortcut definitions		   */
53/***********************************************************/
54
55#define NIG_LATCH_BC_ENABLE_MI_INT 0
56
57#define NIG_STATUS_EMAC0_MI_INT \
58		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
59#define NIG_STATUS_XGXS0_LINK10G \
60		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
61#define NIG_STATUS_XGXS0_LINK_STATUS \
62		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
63#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
64		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
65#define NIG_STATUS_SERDES0_LINK_STATUS \
66		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
67#define NIG_MASK_MI_INT \
68		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
69#define NIG_MASK_XGXS0_LINK10G \
70		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
71#define NIG_MASK_XGXS0_LINK_STATUS \
72		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
73#define NIG_MASK_SERDES0_LINK_STATUS \
74		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
75
76#define MDIO_AN_CL73_OR_37_COMPLETE \
77		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
78		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
79
80#define XGXS_RESET_BITS \
81	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
82	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
83	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
84	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
85	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
86
87#define SERDES_RESET_BITS \
88	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
89	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
90	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
91	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
92
93#define AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
94#define AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
95#define AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
96#define AUTONEG_PARALLEL \
97				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
98#define AUTONEG_SGMII_FIBER_AUTODET \
99				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
100#define AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
101
102#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
103			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
104#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
105			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
106#define GP_STATUS_SPEED_MASK \
107			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
108#define GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
109#define GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
110#define GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
111#define GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
112#define GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
113#define GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
114#define GP_STATUS_10G_HIG \
115			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
116#define GP_STATUS_10G_CX4 \
117			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
118#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
119#define GP_STATUS_10G_KX4 \
120			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
121#define	GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
122#define	GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
123#define	GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
124#define	GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
125#define LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
126#define LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
127#define LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
128#define LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
129#define LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
130#define LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
131#define LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
132#define LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
133#define LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
134#define LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
135#define LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
136#define LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
137#define LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
138#define LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
139#define LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
140
141
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/* BRB thresholds for E2*/
168#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE		170
169#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
170
171#define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE		250
172#define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
173
174#define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE		10
175#define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		90
176
177#define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE			50
178#define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE		250
179
180/* BRB thresholds for E3A0 */
181#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE		290
182#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
183
184#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE		410
185#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
186
187#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE		10
188#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		170
189
190#define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE		50
191#define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE		410
192
193
194/* BRB thresholds for E3B0 2 port mode*/
195#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		1025
196#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
197
198#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE		1025
199#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
200
201#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
202#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	1025
203
204#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE		50
205#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE	1025
206
207/* only for E3B0*/
208#define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR			1025
209#define PFC_E3B0_2P_BRB_FULL_LB_XON_THR			1025
210
211/* Lossy +Lossless GUARANTIED == GUART */
212#define PFC_E3B0_2P_MIX_PAUSE_LB_GUART			284
213/* Lossless +Lossless*/
214#define PFC_E3B0_2P_PAUSE_LB_GUART			236
215/* Lossy +Lossy*/
216#define PFC_E3B0_2P_NON_PAUSE_LB_GUART			342
217
218/* Lossy +Lossless*/
219#define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART		284
220/* Lossless +Lossless*/
221#define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART		236
222/* Lossy +Lossy*/
223#define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART		336
224#define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST		80
225
226#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART		0
227#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST		0
228
229/* BRB thresholds for E3B0 4 port mode */
230#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		304
231#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
232
233#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE		384
234#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
235
236#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
237#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	304
238
239#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE		50
240#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE	384
241
242
243/* only for E3B0*/
244#define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR			304
245#define PFC_E3B0_4P_BRB_FULL_LB_XON_THR			384
246#define PFC_E3B0_4P_LB_GUART				120
247
248#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART		120
249#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST		80
250
251#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART		80
252#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST		120
253
254#define DCBX_INVALID_COS					(0xFF)
255
256#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
257#define ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
258#define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
259#define ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
260#define ETS_E3B0_PBF_MIN_W_VAL				(10000)
261
262#define MAX_PACKET_SIZE					(9700)
263#define WC_UC_TIMEOUT					100
264#define MAX_KR_LINK_RETRY				4
265
266/**********************************************************/
267/*                     INTERFACE                          */
268/**********************************************************/
269
270#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
271	bnx2x_cl45_write(_bp, _phy, \
272		(_phy)->def_md_devad, \
273		(_bank + (_addr & 0xf)), \
274		_val)
275
276#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
277	bnx2x_cl45_read(_bp, _phy, \
278		(_phy)->def_md_devad, \
279		(_bank + (_addr & 0xf)), \
280		_val)
281
282static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
283{
284	u32 val = REG_RD(bp, reg);
285
286	val |= bits;
287	REG_WR(bp, reg, val);
288	return val;
289}
290
291static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
292{
293	u32 val = REG_RD(bp, reg);
294
295	val &= ~bits;
296	REG_WR(bp, reg, val);
297	return val;
298}
299
300/******************************************************************/
301/*			EPIO/GPIO section			  */
302/******************************************************************/
303static void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en)
304{
305	u32 epio_mask, gp_oenable;
306	*en = 0;
307	/* Sanity check */
308	if (epio_pin > 31) {
309		DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
310		return;
311	}
312
313	epio_mask = 1 << epio_pin;
314	/* Set this EPIO to output */
315	gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
316	REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
317
318	*en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
319}
320static void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
321{
322	u32 epio_mask, gp_output, gp_oenable;
323
324	/* Sanity check */
325	if (epio_pin > 31) {
326		DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
327		return;
328	}
329	DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
330	epio_mask = 1 << epio_pin;
331	/* Set this EPIO to output */
332	gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
333	if (en)
334		gp_output |= epio_mask;
335	else
336		gp_output &= ~epio_mask;
337
338	REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
339
340	/* Set the value for this EPIO */
341	gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
342	REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
343}
344
345static void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
346{
347	if (pin_cfg == PIN_CFG_NA)
348		return;
349	if (pin_cfg >= PIN_CFG_EPIO0) {
350		bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
351	} else {
352		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
353		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
354		bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
355	}
356}
357
358static u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val)
359{
360	if (pin_cfg == PIN_CFG_NA)
361		return -EINVAL;
362	if (pin_cfg >= PIN_CFG_EPIO0) {
363		bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
364	} else {
365		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
366		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
367		*val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
368	}
369	return 0;
370
371}
372/******************************************************************/
373/*				ETS section			  */
374/******************************************************************/
375static void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
376{
377	/* ETS disabled configuration*/
378	struct bnx2x *bp = params->bp;
379
380	DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
381
382	/*
383	 * mapping between entry  priority to client number (0,1,2 -debug and
384	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
385	 * 3bits client num.
386	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
387	 * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
388	 */
389
390	REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
391	/*
392	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
393	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
394	 * COS0 entry, 4 - COS1 entry.
395	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
396	 * bit4   bit3	  bit2   bit1	  bit0
397	 * MCP and debug are strict
398	 */
399
400	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
401	/* defines which entries (clients) are subjected to WFQ arbitration */
402	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
403	/*
404	 * For strict priority entries defines the number of consecutive
405	 * slots for the highest priority.
406	 */
407	REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
408	/*
409	 * mapping between the CREDIT_WEIGHT registers and actual client
410	 * numbers
411	 */
412	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
413	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
414	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
415
416	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
417	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
418	REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
419	/* ETS mode disable */
420	REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
421	/*
422	 * If ETS mode is enabled (there is no strict priority) defines a WFQ
423	 * weight for COS0/COS1.
424	 */
425	REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
426	REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
427	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
428	REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
429	REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
430	/* Defines the number of consecutive slots for the strict priority */
431	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
432}
433/******************************************************************************
434* Description:
435*	Getting min_w_val will be set according to line speed .
436*.
437******************************************************************************/
438static u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
439{
440	u32 min_w_val = 0;
441	/* Calculate min_w_val.*/
442	if (vars->link_up) {
443		if (SPEED_20000 == vars->line_speed)
444			min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
445		else
446			min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
447	} else
448		min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
449	/**
450	 *  If the link isn't up (static configuration for example ) The
451	 *  link will be according to 20GBPS.
452	*/
453	return min_w_val;
454}
455/******************************************************************************
456* Description:
457*	Getting credit upper bound form min_w_val.
458*.
459******************************************************************************/
460static u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val)
461{
462	const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val),
463						MAX_PACKET_SIZE);
464	return credit_upper_bound;
465}
466/******************************************************************************
467* Description:
468*	Set credit upper bound for NIG.
469*.
470******************************************************************************/
471static void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
472	const struct link_params *params,
473	const u32 min_w_val)
474{
475	struct bnx2x *bp = params->bp;
476	const u8 port = params->port;
477	const u32 credit_upper_bound =
478	    bnx2x_ets_get_credit_upper_bound(min_w_val);
479
480	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
481		NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
482	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
483		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
484	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
485		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
486	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
487		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
488	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
489		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
490	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
491		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
492
493	if (0 == port) {
494		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
495			credit_upper_bound);
496		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
497			credit_upper_bound);
498		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
499			credit_upper_bound);
500	}
501}
502/******************************************************************************
503* Description:
504*	Will return the NIG ETS registers to init values.Except
505*	credit_upper_bound.
506*	That isn't used in this configuration (No WFQ is enabled) and will be
507*	configured acording to spec
508*.
509******************************************************************************/
510static void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
511					const struct link_vars *vars)
512{
513	struct bnx2x *bp = params->bp;
514	const u8 port = params->port;
515	const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
516	/**
517	 * mapping between entry  priority to client number (0,1,2 -debug and
518	 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
519	 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
520	 * reset value or init tool
521	 */
522	if (port) {
523		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
524		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
525	} else {
526		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
527		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
528	}
529	/**
530	* For strict priority entries defines the number of consecutive
531	* slots for the highest priority.
532	*/
533	/* TODO_ETS - Should be done by reset value or init tool */
534	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
535		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
536	/**
537	 * mapping between the CREDIT_WEIGHT registers and actual client
538	 * numbers
539	 */
540	/* TODO_ETS - Should be done by reset value or init tool */
541	if (port) {
542		/*Port 1 has 6 COS*/
543		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
544		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
545	} else {
546		/*Port 0 has 9 COS*/
547		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
548		       0x43210876);
549		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
550	}
551
552	/**
553	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
554	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
555	 * COS0 entry, 4 - COS1 entry.
556	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
557	 * bit4   bit3	  bit2   bit1	  bit0
558	 * MCP and debug are strict
559	 */
560	if (port)
561		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
562	else
563		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
564	/* defines which entries (clients) are subjected to WFQ arbitration */
565	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
566		   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
567
568	/**
569	* Please notice the register address are note continuous and a
570	* for here is note appropriate.In 2 port mode port0 only COS0-5
571	* can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
572	* port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
573	* are never used for WFQ
574	*/
575	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
576		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
577	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
578		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
579	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
580		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
581	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
582		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
583	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
584		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
585	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
586		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
587	if (0 == port) {
588		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
589		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
590		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
591	}
592
593	bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
594}
595/******************************************************************************
596* Description:
597*	Set credit upper bound for PBF.
598*.
599******************************************************************************/
600static void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
601	const struct link_params *params,
602	const u32 min_w_val)
603{
604	struct bnx2x *bp = params->bp;
605	const u32 credit_upper_bound =
606	    bnx2x_ets_get_credit_upper_bound(min_w_val);
607	const u8 port = params->port;
608	u32 base_upper_bound = 0;
609	u8 max_cos = 0;
610	u8 i = 0;
611	/**
612	* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
613	* port mode port1 has COS0-2 that can be used for WFQ.
614	*/
615	if (0 == port) {
616		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
617		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
618	} else {
619		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
620		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
621	}
622
623	for (i = 0; i < max_cos; i++)
624		REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
625}
626
627/******************************************************************************
628* Description:
629*	Will return the PBF ETS registers to init values.Except
630*	credit_upper_bound.
631*	That isn't used in this configuration (No WFQ is enabled) and will be
632*	configured acording to spec
633*.
634******************************************************************************/
635static void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
636{
637	struct bnx2x *bp = params->bp;
638	const u8 port = params->port;
639	const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
640	u8 i = 0;
641	u32 base_weight = 0;
642	u8 max_cos = 0;
643
644	/**
645	 * mapping between entry  priority to client number 0 - COS0
646	 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
647	 * TODO_ETS - Should be done by reset value or init tool
648	 */
649	if (port)
650		/*  0x688 (|011|0 10|00 1|000) */
651		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
652	else
653		/*  (10 1|100 |011|0 10|00 1|000) */
654		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
655
656	/* TODO_ETS - Should be done by reset value or init tool */
657	if (port)
658		/* 0x688 (|011|0 10|00 1|000)*/
659		REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
660	else
661	/* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
662	REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
663
664	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
665		   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
666
667
668	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
669		   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
670
671	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
672		   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
673	/**
674	* In 2 port mode port0 has COS0-5 that can be used for WFQ.
675	* In 4 port mode port1 has COS0-2 that can be used for WFQ.
676	*/
677	if (0 == port) {
678		base_weight = PBF_REG_COS0_WEIGHT_P0;
679		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
680	} else {
681		base_weight = PBF_REG_COS0_WEIGHT_P1;
682		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
683	}
684
685	for (i = 0; i < max_cos; i++)
686		REG_WR(bp, base_weight + (0x4 * i), 0);
687
688	bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
689}
690/******************************************************************************
691* Description:
692*	E3B0 disable will return basicly the values to init values.
693*.
694******************************************************************************/
695static int bnx2x_ets_e3b0_disabled(const struct link_params *params,
696				   const struct link_vars *vars)
697{
698	struct bnx2x *bp = params->bp;
699
700	if (!CHIP_IS_E3B0(bp)) {
701		DP(NETIF_MSG_LINK,
702		   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
703		return -EINVAL;
704	}
705
706	bnx2x_ets_e3b0_nig_disabled(params, vars);
707
708	bnx2x_ets_e3b0_pbf_disabled(params);
709
710	return 0;
711}
712
713/******************************************************************************
714* Description:
715*	Disable will return basicly the values to init values.
716*.
717******************************************************************************/
718int bnx2x_ets_disabled(struct link_params *params,
719		      struct link_vars *vars)
720{
721	struct bnx2x *bp = params->bp;
722	int bnx2x_status = 0;
723
724	if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
725		bnx2x_ets_e2e3a0_disabled(params);
726	else if (CHIP_IS_E3B0(bp))
727		bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
728	else {
729		DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
730		return -EINVAL;
731	}
732
733	return bnx2x_status;
734}
735
736/******************************************************************************
737* Description
738*	Set the COS mappimg to SP and BW until this point all the COS are not
739*	set as SP or BW.
740******************************************************************************/
741static int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
742				  const struct bnx2x_ets_params *ets_params,
743				  const u8 cos_sp_bitmap,
744				  const u8 cos_bw_bitmap)
745{
746	struct bnx2x *bp = params->bp;
747	const u8 port = params->port;
748	const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
749	const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
750	const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
751	const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
752
753	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
754	       NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
755
756	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
757	       PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
758
759	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
760	       NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
761	       nig_cli_subject2wfq_bitmap);
762
763	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
764	       PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
765	       pbf_cli_subject2wfq_bitmap);
766
767	return 0;
768}
769
770/******************************************************************************
771* Description:
772*	This function is needed because NIG ARB_CREDIT_WEIGHT_X are
773*	not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
774******************************************************************************/
775static int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
776				     const u8 cos_entry,
777				     const u32 min_w_val_nig,
778				     const u32 min_w_val_pbf,
779				     const u16 total_bw,
780				     const u8 bw,
781				     const u8 port)
782{
783	u32 nig_reg_adress_crd_weight = 0;
784	u32 pbf_reg_adress_crd_weight = 0;
785	/* Calculate and set BW for this COS - use 1 instead of 0 for BW */
786	const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
787	const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
788
789	switch (cos_entry) {
790	case 0:
791	    nig_reg_adress_crd_weight =
792		 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
793		     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
794	     pbf_reg_adress_crd_weight = (port) ?
795		 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
796	     break;
797	case 1:
798	     nig_reg_adress_crd_weight = (port) ?
799		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
800		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
801	     pbf_reg_adress_crd_weight = (port) ?
802		 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
803	     break;
804	case 2:
805	     nig_reg_adress_crd_weight = (port) ?
806		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
807		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
808
809		 pbf_reg_adress_crd_weight = (port) ?
810		     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
811	     break;
812	case 3:
813	    if (port)
814			return -EINVAL;
815	     nig_reg_adress_crd_weight =
816		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
817	     pbf_reg_adress_crd_weight =
818		 PBF_REG_COS3_WEIGHT_P0;
819	     break;
820	case 4:
821	    if (port)
822		return -EINVAL;
823	     nig_reg_adress_crd_weight =
824		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
825	     pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
826	     break;
827	case 5:
828	    if (port)
829		return -EINVAL;
830	     nig_reg_adress_crd_weight =
831		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
832	     pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
833	     break;
834	}
835
836	REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
837
838	REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
839
840	return 0;
841}
842/******************************************************************************
843* Description:
844*	Calculate the total BW.A value of 0 isn't legal.
845*.
846******************************************************************************/
847static int bnx2x_ets_e3b0_get_total_bw(
848	const struct link_params *params,
849	const struct bnx2x_ets_params *ets_params,
850	u16 *total_bw)
851{
852	struct bnx2x *bp = params->bp;
853	u8 cos_idx = 0;
854
855	*total_bw = 0 ;
856	/* Calculate total BW requested */
857	for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
858		if (bnx2x_cos_state_bw == ets_params->cos[cos_idx].state) {
859			*total_bw +=
860				ets_params->cos[cos_idx].params.bw_params.bw;
861		}
862	}
863
864	/* Check total BW is valid */
865	if ((100 != *total_bw) || (0 == *total_bw)) {
866		if (0 == *total_bw) {
867			DP(NETIF_MSG_LINK,
868			   "bnx2x_ets_E3B0_config toatl BW shouldn't be 0\n");
869			return -EINVAL;
870		}
871		DP(NETIF_MSG_LINK,
872		   "bnx2x_ets_E3B0_config toatl BW should be 100\n");
873		/**
874		*   We can handle a case whre the BW isn't 100 this can happen
875		*   if the TC are joined.
876		*/
877	}
878	return 0;
879}
880
881/******************************************************************************
882* Description:
883*	Invalidate all the sp_pri_to_cos.
884*.
885******************************************************************************/
886static void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
887{
888	u8 pri = 0;
889	for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
890		sp_pri_to_cos[pri] = DCBX_INVALID_COS;
891}
892/******************************************************************************
893* Description:
894*	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
895*	according to sp_pri_to_cos.
896*.
897******************************************************************************/
898static int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
899					    u8 *sp_pri_to_cos, const u8 pri,
900					    const u8 cos_entry)
901{
902	struct bnx2x *bp = params->bp;
903	const u8 port = params->port;
904	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
905		DCBX_E3B0_MAX_NUM_COS_PORT0;
906
907	if (DCBX_INVALID_COS != sp_pri_to_cos[pri]) {
908		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
909				   "parameter There can't be two COS's with "
910				   "the same strict pri\n");
911		return -EINVAL;
912	}
913
914	if (pri > max_num_of_cos) {
915		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
916			       "parameter Illegal strict priority\n");
917	    return -EINVAL;
918	}
919
920	sp_pri_to_cos[pri] = cos_entry;
921	return 0;
922
923}
924
925/******************************************************************************
926* Description:
927*	Returns the correct value according to COS and priority in
928*	the sp_pri_cli register.
929*.
930******************************************************************************/
931static u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
932					 const u8 pri_set,
933					 const u8 pri_offset,
934					 const u8 entry_size)
935{
936	u64 pri_cli_nig = 0;
937	pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
938						    (pri_set + pri_offset));
939
940	return pri_cli_nig;
941}
942/******************************************************************************
943* Description:
944*	Returns the correct value according to COS and priority in the
945*	sp_pri_cli register for NIG.
946*.
947******************************************************************************/
948static u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
949{
950	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
951	const u8 nig_cos_offset = 3;
952	const u8 nig_pri_offset = 3;
953
954	return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
955		nig_pri_offset, 4);
956
957}
958/******************************************************************************
959* Description:
960*	Returns the correct value according to COS and priority in the
961*	sp_pri_cli register for PBF.
962*.
963******************************************************************************/
964static u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
965{
966	const u8 pbf_cos_offset = 0;
967	const u8 pbf_pri_offset = 0;
968
969	return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
970		pbf_pri_offset, 3);
971
972}
973
974/******************************************************************************
975* Description:
976*	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
977*	according to sp_pri_to_cos.(which COS has higher priority)
978*.
979******************************************************************************/
980static int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
981					     u8 *sp_pri_to_cos)
982{
983	struct bnx2x *bp = params->bp;
984	u8 i = 0;
985	const u8 port = params->port;
986	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
987	u64 pri_cli_nig = 0x210;
988	u32 pri_cli_pbf = 0x0;
989	u8 pri_set = 0;
990	u8 pri_bitmask = 0;
991	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
992		DCBX_E3B0_MAX_NUM_COS_PORT0;
993
994	u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
995
996	/* Set all the strict priority first */
997	for (i = 0; i < max_num_of_cos; i++) {
998		if (DCBX_INVALID_COS != sp_pri_to_cos[i]) {
999			if (DCBX_MAX_NUM_COS <= sp_pri_to_cos[i]) {
1000				DP(NETIF_MSG_LINK,
1001					   "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1002					   "invalid cos entry\n");
1003				return -EINVAL;
1004			}
1005
1006			pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1007			    sp_pri_to_cos[i], pri_set);
1008
1009			pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1010			    sp_pri_to_cos[i], pri_set);
1011			pri_bitmask = 1 << sp_pri_to_cos[i];
1012			/* COS is used remove it from bitmap.*/
1013			if (0 == (pri_bitmask & cos_bit_to_set)) {
1014				DP(NETIF_MSG_LINK,
1015					"bnx2x_ets_e3b0_sp_set_pri_cli_reg "
1016					"invalid There can't be two COS's with"
1017					" the same strict pri\n");
1018				return -EINVAL;
1019			}
1020			cos_bit_to_set &= ~pri_bitmask;
1021			pri_set++;
1022		}
1023	}
1024
1025	/* Set all the Non strict priority i= COS*/
1026	for (i = 0; i < max_num_of_cos; i++) {
1027		pri_bitmask = 1 << i;
1028		/* Check if COS was already used for SP */
1029		if (pri_bitmask & cos_bit_to_set) {
1030			/* COS wasn't used for SP */
1031			pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
1032			    i, pri_set);
1033
1034			pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
1035			    i, pri_set);
1036			/* COS is used remove it from bitmap.*/
1037			cos_bit_to_set &= ~pri_bitmask;
1038			pri_set++;
1039		}
1040	}
1041
1042	if (pri_set != max_num_of_cos) {
1043		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
1044				   "entries were set\n");
1045		return -EINVAL;
1046	}
1047
1048	if (port) {
1049		/* Only 6 usable clients*/
1050		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1051		       (u32)pri_cli_nig);
1052
1053		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1054	} else {
1055		/* Only 9 usable clients*/
1056		const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
1057		const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
1058
1059		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1060		       pri_cli_nig_lsb);
1061		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1062		       pri_cli_nig_msb);
1063
1064		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1065	}
1066	return 0;
1067}
1068
1069/******************************************************************************
1070* Description:
1071*	Configure the COS to ETS according to BW and SP settings.
1072******************************************************************************/
1073int bnx2x_ets_e3b0_config(const struct link_params *params,
1074			 const struct link_vars *vars,
1075			 const struct bnx2x_ets_params *ets_params)
1076{
1077	struct bnx2x *bp = params->bp;
1078	int bnx2x_status = 0;
1079	const u8 port = params->port;
1080	u16 total_bw = 0;
1081	const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
1082	const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
1083	u8 cos_bw_bitmap = 0;
1084	u8 cos_sp_bitmap = 0;
1085	u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
1086	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
1087		DCBX_E3B0_MAX_NUM_COS_PORT0;
1088	u8 cos_entry = 0;
1089
1090	if (!CHIP_IS_E3B0(bp)) {
1091		DP(NETIF_MSG_LINK,
1092		   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
1093		return -EINVAL;
1094	}
1095
1096	if ((ets_params->num_of_cos > max_num_of_cos)) {
1097		DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
1098				   "isn't supported\n");
1099		return -EINVAL;
1100	}
1101
1102	/* Prepare sp strict priority parameters*/
1103	bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1104
1105	/* Prepare BW parameters*/
1106	bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
1107						   &total_bw);
1108	if (0 != bnx2x_status) {
1109		DP(NETIF_MSG_LINK,
1110		   "bnx2x_ets_E3B0_config get_total_bw failed\n");
1111		return -EINVAL;
1112	}
1113
1114	/**
1115	 *  Upper bound is set according to current link speed (min_w_val
1116	 *  should be the same for upper bound and COS credit val).
1117	 */
1118	bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1119	bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1120
1121
1122	for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1123		if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
1124			cos_bw_bitmap |= (1 << cos_entry);
1125			/**
1126			 * The function also sets the BW in HW(not the mappin
1127			 * yet)
1128			 */
1129			bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
1130				bp, cos_entry, min_w_val_nig, min_w_val_pbf,
1131				total_bw,
1132				ets_params->cos[cos_entry].params.bw_params.bw,
1133				 port);
1134		} else if (bnx2x_cos_state_strict ==
1135			ets_params->cos[cos_entry].state){
1136			cos_sp_bitmap |= (1 << cos_entry);
1137
1138			bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
1139				params,
1140				sp_pri_to_cos,
1141				ets_params->cos[cos_entry].params.sp_params.pri,
1142				cos_entry);
1143
1144		} else {
1145			DP(NETIF_MSG_LINK,
1146			   "bnx2x_ets_e3b0_config cos state not valid\n");
1147			return -EINVAL;
1148		}
1149		if (0 != bnx2x_status) {
1150			DP(NETIF_MSG_LINK,
1151			   "bnx2x_ets_e3b0_config set cos bw failed\n");
1152			return bnx2x_status;
1153		}
1154	}
1155
1156	/* Set SP register (which COS has higher priority) */
1157	bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
1158							 sp_pri_to_cos);
1159
1160	if (0 != bnx2x_status) {
1161		DP(NETIF_MSG_LINK,
1162		   "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
1163		return bnx2x_status;
1164	}
1165
1166	/* Set client mapping of BW and strict */
1167	bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
1168					      cos_sp_bitmap,
1169					      cos_bw_bitmap);
1170
1171	if (0 != bnx2x_status) {
1172		DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
1173		return bnx2x_status;
1174	}
1175	return 0;
1176}
1177static void bnx2x_ets_bw_limit_common(const struct link_params *params)
1178{
1179	/* ETS disabled configuration */
1180	struct bnx2x *bp = params->bp;
1181	DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1182	/*
1183	 * defines which entries (clients) are subjected to WFQ arbitration
1184	 * COS0 0x8
1185	 * COS1 0x10
1186	 */
1187	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1188	/*
1189	 * mapping between the ARB_CREDIT_WEIGHT registers and actual
1190	 * client numbers (WEIGHT_0 does not actually have to represent
1191	 * client 0)
1192	 *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1193	 *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1194	 */
1195	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1196
1197	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1198	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1199	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1200	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1201
1202	/* ETS mode enabled*/
1203	REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1204
1205	/* Defines the number of consecutive slots for the strict priority */
1206	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1207	/*
1208	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1209	 * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1210	 * entry, 4 - COS1 entry.
1211	 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1212	 * bit4   bit3	  bit2     bit1	   bit0
1213	 * MCP and debug are strict
1214	 */
1215	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1216
1217	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1218	REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1219	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1220	REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1221	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1222}
1223
1224void bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
1225			const u32 cos1_bw)
1226{
1227	/* ETS disabled configuration*/
1228	struct bnx2x *bp = params->bp;
1229	const u32 total_bw = cos0_bw + cos1_bw;
1230	u32 cos0_credit_weight = 0;
1231	u32 cos1_credit_weight = 0;
1232
1233	DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1234
1235	if ((0 == total_bw) ||
1236	    (0 == cos0_bw) ||
1237	    (0 == cos1_bw)) {
1238		DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1239		return;
1240	}
1241
1242	cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1243		total_bw;
1244	cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1245		total_bw;
1246
1247	bnx2x_ets_bw_limit_common(params);
1248
1249	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1250	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1251
1252	REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1253	REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1254}
1255
1256int bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
1257{
1258	/* ETS disabled configuration*/
1259	struct bnx2x *bp = params->bp;
1260	u32 val	= 0;
1261
1262	DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
1263	/*
1264	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1265	 * as strict.  Bits 0,1,2 - debug and management entries,
1266	 * 3 - COS0 entry, 4 - COS1 entry.
1267	 *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1268	 *  bit4   bit3	  bit2      bit1     bit0
1269	 * MCP and debug are strict
1270	 */
1271	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1272	/*
1273	 * For strict priority entries defines the number of consecutive slots
1274	 * for the highest priority.
1275	 */
1276	REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1277	/* ETS mode disable */
1278	REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1279	/* Defines the number of consecutive slots for the strict priority */
1280	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1281
1282	/* Defines the number of consecutive slots for the strict priority */
1283	REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1284
1285	/*
1286	 * mapping between entry  priority to client number (0,1,2 -debug and
1287	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1288	 * 3bits client num.
1289	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1290	 * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1291	 * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1292	 */
1293	val = (0 == strict_cos) ? 0x2318 : 0x22E0;
1294	REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1295
1296	return 0;
1297}
1298/******************************************************************/
1299/*			PFC section				  */
1300/******************************************************************/
1301
1302static void bnx2x_update_pfc_xmac(struct link_params *params,
1303				  struct link_vars *vars,
1304				  u8 is_lb)
1305{
1306	struct bnx2x *bp = params->bp;
1307	u32 xmac_base;
1308	u32 pause_val, pfc0_val, pfc1_val;
1309
1310	/* XMAC base adrr */
1311	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1312
1313	/* Initialize pause and pfc registers */
1314	pause_val = 0x18000;
1315	pfc0_val = 0xFFFF8000;
1316	pfc1_val = 0x2;
1317
1318	/* No PFC support */
1319	if (!(params->feature_config_flags &
1320	      FEATURE_CONFIG_PFC_ENABLED)) {
1321
1322		/*
1323		 * RX flow control - Process pause frame in receive direction
1324		 */
1325		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1326			pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1327
1328		/*
1329		 * TX flow control - Send pause packet when buffer is full
1330		 */
1331		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1332			pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1333	} else {/* PFC support */
1334		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1335			XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1336			XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1337			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN;
1338	}
1339
1340	/* Write pause and PFC registers */
1341	REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1342	REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1343	REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1344
1345
1346	/* Set MAC address for source TX Pause/PFC frames */
1347	REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1348	       ((params->mac_addr[2] << 24) |
1349		(params->mac_addr[3] << 16) |
1350		(params->mac_addr[4] << 8) |
1351		(params->mac_addr[5])));
1352	REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1353	       ((params->mac_addr[0] << 8) |
1354		(params->mac_addr[1])));
1355
1356	udelay(30);
1357}
1358
1359
1360static void bnx2x_emac_get_pfc_stat(struct link_params *params,
1361				    u32 pfc_frames_sent[2],
1362				    u32 pfc_frames_received[2])
1363{
1364	/* Read pfc statistic */
1365	struct bnx2x *bp = params->bp;
1366	u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1367	u32 val_xon = 0;
1368	u32 val_xoff = 0;
1369
1370	DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
1371
1372	/* PFC received frames */
1373	val_xoff = REG_RD(bp, emac_base +
1374				EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1375	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1376	val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1377	val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1378
1379	pfc_frames_received[0] = val_xon + val_xoff;
1380
1381	/* PFC received sent */
1382	val_xoff = REG_RD(bp, emac_base +
1383				EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1384	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1385	val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1386	val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1387
1388	pfc_frames_sent[0] = val_xon + val_xoff;
1389}
1390
1391/* Read pfc statistic*/
1392void bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1393			 u32 pfc_frames_sent[2],
1394			 u32 pfc_frames_received[2])
1395{
1396	/* Read pfc statistic */
1397	struct bnx2x *bp = params->bp;
1398
1399	DP(NETIF_MSG_LINK, "pfc statistic\n");
1400
1401	if (!vars->link_up)
1402		return;
1403
1404	if (MAC_TYPE_EMAC == vars->mac_type) {
1405		DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n");
1406		bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1407					pfc_frames_received);
1408	}
1409}
1410/******************************************************************/
1411/*			MAC/PBF section				  */
1412/******************************************************************/
1413static void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
1414{
1415	u32 mode, emac_base;
1416	/**
1417	 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1418	 * (a value of 49==0x31) and make sure that the AUTO poll is off
1419	 */
1420
1421	if (CHIP_IS_E2(bp))
1422		emac_base = GRCBASE_EMAC0;
1423	else
1424		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1425	mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1426	mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1427		  EMAC_MDIO_MODE_CLOCK_CNT);
1428	if (USES_WARPCORE(bp))
1429		mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1430	else
1431		mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1432
1433	mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1434	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
1435
1436	udelay(40);
1437}
1438
1439static void bnx2x_emac_init(struct link_params *params,
1440			    struct link_vars *vars)
1441{
1442	/* reset and unreset the emac core */
1443	struct bnx2x *bp = params->bp;
1444	u8 port = params->port;
1445	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1446	u32 val;
1447	u16 timeout;
1448
1449	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1450	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1451	udelay(5);
1452	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1453	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1454
1455	/* init emac - use read-modify-write */
1456	/* self clear reset */
1457	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1458	EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1459
1460	timeout = 200;
1461	do {
1462		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1463		DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1464		if (!timeout) {
1465			DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1466			return;
1467		}
1468		timeout--;
1469	} while (val & EMAC_MODE_RESET);
1470	bnx2x_set_mdio_clk(bp, params->chip_id, port);
1471	/* Set mac address */
1472	val = ((params->mac_addr[0] << 8) |
1473		params->mac_addr[1]);
1474	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1475
1476	val = ((params->mac_addr[2] << 24) |
1477	       (params->mac_addr[3] << 16) |
1478	       (params->mac_addr[4] << 8) |
1479		params->mac_addr[5]);
1480	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1481}
1482
1483static void bnx2x_set_xumac_nig(struct link_params *params,
1484				u16 tx_pause_en,
1485				u8 enable)
1486{
1487	struct bnx2x *bp = params->bp;
1488
1489	REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1490	       enable);
1491	REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1492	       enable);
1493	REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1494	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1495}
1496
1497static void bnx2x_umac_enable(struct link_params *params,
1498			    struct link_vars *vars, u8 lb)
1499{
1500	u32 val;
1501	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1502	struct bnx2x *bp = params->bp;
1503	/* Reset UMAC */
1504	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1505	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1506	usleep_range(1000, 1000);
1507
1508	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1509	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1510
1511	DP(NETIF_MSG_LINK, "enabling UMAC\n");
1512
1513	/**
1514	 * This register determines on which events the MAC will assert
1515	 * error on the i/f to the NIG along w/ EOP.
1516	 */
1517
1518	/**
1519	 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
1520	 * params->port*0x14,      0xfffff.
1521	 */
1522	/* This register opens the gate for the UMAC despite its name */
1523	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1524
1525	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1526		UMAC_COMMAND_CONFIG_REG_PAD_EN |
1527		UMAC_COMMAND_CONFIG_REG_SW_RESET |
1528		UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1529	switch (vars->line_speed) {
1530	case SPEED_10:
1531		val |= (0<<2);
1532		break;
1533	case SPEED_100:
1534		val |= (1<<2);
1535		break;
1536	case SPEED_1000:
1537		val |= (2<<2);
1538		break;
1539	case SPEED_2500:
1540		val |= (3<<2);
1541		break;
1542	default:
1543		DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
1544			       vars->line_speed);
1545		break;
1546	}
1547	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1548		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1549
1550	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1551		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1552
1553	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1554	udelay(50);
1555
1556	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1557	REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1558	       ((params->mac_addr[2] << 24) |
1559		(params->mac_addr[3] << 16) |
1560		(params->mac_addr[4] << 8) |
1561		(params->mac_addr[5])));
1562	REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1563	       ((params->mac_addr[0] << 8) |
1564		(params->mac_addr[1])));
1565
1566	/* Enable RX and TX */
1567	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1568	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1569		UMAC_COMMAND_CONFIG_REG_RX_ENA;
1570	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1571	udelay(50);
1572
1573	/* Remove SW Reset */
1574	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1575
1576	/* Check loopback mode */
1577	if (lb)
1578		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1579	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1580
1581	/*
1582	 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1583	 * length used by the MAC receive logic to check frames.
1584	 */
1585	REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
1586	bnx2x_set_xumac_nig(params,
1587			    ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1588	vars->mac_type = MAC_TYPE_UMAC;
1589
1590}
1591
1592static u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
1593{
1594	u32 port4mode_ovwr_val;
1595	/* Check 4-port override enabled */
1596	port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
1597	if (port4mode_ovwr_val & (1<<0)) {
1598		/* Return 4-port mode override value */
1599		return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1600	}
1601	/* Return 4-port mode from input pin */
1602	return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
1603}
1604
1605/* Define the XMAC mode */
1606static void bnx2x_xmac_init(struct bnx2x *bp, u32 max_speed)
1607{
1608	u32 is_port4mode = bnx2x_is_4_port_mode(bp);
1609
1610	/**
1611	* In 4-port mode, need to set the mode only once, so if XMAC is
1612	* already out of reset, it means the mode has already been set,
1613	* and it must not* reset the XMAC again, since it controls both
1614	* ports of the path
1615	**/
1616
1617	if (is_port4mode && (REG_RD(bp, MISC_REG_RESET_REG_2) &
1618	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
1619		DP(NETIF_MSG_LINK,
1620		   "XMAC already out of reset in 4-port mode\n");
1621		return;
1622	}
1623
1624	/* Hard reset */
1625	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1626	       MISC_REGISTERS_RESET_REG_2_XMAC);
1627	usleep_range(1000, 1000);
1628
1629	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1630	       MISC_REGISTERS_RESET_REG_2_XMAC);
1631	if (is_port4mode) {
1632		DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
1633
1634		/*  Set the number of ports on the system side to up to 2 */
1635		REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1636
1637		/* Set the number of ports on the Warp Core to 10G */
1638		REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1639	} else {
1640		/*  Set the number of ports on the system side to 1 */
1641		REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1642		if (max_speed == SPEED_10000) {
1643			DP(NETIF_MSG_LINK,
1644			   "Init XMAC to 10G x 1 port per path\n");
1645			/* Set the number of ports on the Warp Core to 10G */
1646			REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1647		} else {
1648			DP(NETIF_MSG_LINK,
1649			   "Init XMAC to 20G x 2 ports per path\n");
1650			/* Set the number of ports on the Warp Core to 20G */
1651			REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1652		}
1653	}
1654	/* Soft reset */
1655	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1656	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1657	usleep_range(1000, 1000);
1658
1659	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1660	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1661
1662}
1663
1664static void bnx2x_xmac_disable(struct link_params *params)
1665{
1666	u8 port = params->port;
1667	struct bnx2x *bp = params->bp;
1668	u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1669
1670	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
1671	    MISC_REGISTERS_RESET_REG_2_XMAC) {
1672		/*
1673		 * Send an indication to change the state in the NIG back to XON
1674		 * Clearing this bit enables the next set of this bit to get
1675		 * rising edge
1676		 */
1677		pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1678		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1679		       (pfc_ctrl & ~(1<<1)));
1680		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1681		       (pfc_ctrl | (1<<1)));
1682		DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
1683		REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
1684		usleep_range(1000, 1000);
1685		bnx2x_set_xumac_nig(params, 0, 0);
1686		REG_WR(bp, xmac_base + XMAC_REG_CTRL,
1687		       XMAC_CTRL_REG_SOFT_RESET);
1688	}
1689}
1690
1691static int bnx2x_xmac_enable(struct link_params *params,
1692			     struct link_vars *vars, u8 lb)
1693{
1694	u32 val, xmac_base;
1695	struct bnx2x *bp = params->bp;
1696	DP(NETIF_MSG_LINK, "enabling XMAC\n");
1697
1698	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1699
1700	bnx2x_xmac_init(bp, vars->line_speed);
1701
1702	/*
1703	 * This register determines on which events the MAC will assert
1704	 * error on the i/f to the NIG along w/ EOP.
1705	 */
1706
1707	/*
1708	 * This register tells the NIG whether to send traffic to UMAC
1709	 * or XMAC
1710	 */
1711	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1712
1713	/* Set Max packet size */
1714	REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1715
1716	/* CRC append for Tx packets */
1717	REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1718
1719	/* update PFC */
1720	bnx2x_update_pfc_xmac(params, vars, 0);
1721
1722	/* Enable TX and RX */
1723	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1724
1725	/* Check loopback mode */
1726	if (lb)
1727		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1728	REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
1729	bnx2x_set_xumac_nig(params,
1730			    ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
1731
1732	vars->mac_type = MAC_TYPE_XMAC;
1733
1734	return 0;
1735}
1736static int bnx2x_emac_enable(struct link_params *params,
1737			     struct link_vars *vars, u8 lb)
1738{
1739	struct bnx2x *bp = params->bp;
1740	u8 port = params->port;
1741	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1742	u32 val;
1743
1744	DP(NETIF_MSG_LINK, "enabling EMAC\n");
1745
1746	/* Disable BMAC */
1747	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1748	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1749
1750	/* enable emac and not bmac */
1751	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1752
1753	/* ASIC */
1754	if (vars->phy_flags & PHY_XGXS_FLAG) {
1755		u32 ser_lane = ((params->lane_config &
1756				 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1757				PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1758
1759		DP(NETIF_MSG_LINK, "XGXS\n");
1760		/* select the master lanes (out of 0-3) */
1761		REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1762		/* select XGXS */
1763		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1764
1765	} else { /* SerDes */
1766		DP(NETIF_MSG_LINK, "SerDes\n");
1767		/* select SerDes */
1768		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1769	}
1770
1771	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1772		      EMAC_RX_MODE_RESET);
1773	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1774		      EMAC_TX_MODE_RESET);
1775
1776	if (CHIP_REV_IS_SLOW(bp)) {
1777		/* config GMII mode */
1778		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1779		EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1780	} else { /* ASIC */
1781		/* pause enable/disable */
1782		bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1783			       EMAC_RX_MODE_FLOW_EN);
1784
1785		bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1786			       (EMAC_TX_MODE_EXT_PAUSE_EN |
1787				EMAC_TX_MODE_FLOW_EN));
1788		if (!(params->feature_config_flags &
1789		      FEATURE_CONFIG_PFC_ENABLED)) {
1790			if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1791				bnx2x_bits_en(bp, emac_base +
1792					      EMAC_REG_EMAC_RX_MODE,
1793					      EMAC_RX_MODE_FLOW_EN);
1794
1795			if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1796				bnx2x_bits_en(bp, emac_base +
1797					      EMAC_REG_EMAC_TX_MODE,
1798					      (EMAC_TX_MODE_EXT_PAUSE_EN |
1799					       EMAC_TX_MODE_FLOW_EN));
1800		} else
1801			bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1802				      EMAC_TX_MODE_FLOW_EN);
1803	}
1804
1805	/* KEEP_VLAN_TAG, promiscuous */
1806	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1807	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1808
1809	/*
1810	 * Setting this bit causes MAC control frames (except for pause
1811	 * frames) to be passed on for processing. This setting has no
1812	 * affect on the operation of the pause frames. This bit effects
1813	 * all packets regardless of RX Parser packet sorting logic.
1814	 * Turn the PFC off to make sure we are in Xon state before
1815	 * enabling it.
1816	 */
1817	EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1818	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1819		DP(NETIF_MSG_LINK, "PFC is enabled\n");
1820		/* Enable PFC again */
1821		EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1822			EMAC_REG_RX_PFC_MODE_RX_EN |
1823			EMAC_REG_RX_PFC_MODE_TX_EN |
1824			EMAC_REG_RX_PFC_MODE_PRIORITIES);
1825
1826		EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1827			((0x0101 <<
1828			  EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1829			 (0x00ff <<
1830			  EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1831		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1832	}
1833	EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1834
1835	/* Set Loopback */
1836	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1837	if (lb)
1838		val |= 0x810;
1839	else
1840		val &= ~0x810;
1841	EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1842
1843	/* enable emac */
1844	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
1845
1846	/* enable emac for jumbo packets */
1847	EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1848		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
1849		 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1850
1851	/* strip CRC */
1852	REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1853
1854	/* disable the NIG in/out to the bmac */
1855	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1856	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1857	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1858
1859	/* enable the NIG in/out to the emac */
1860	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1861	val = 0;
1862	if ((params->feature_config_flags &
1863	      FEATURE_CONFIG_PFC_ENABLED) ||
1864	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1865		val = 1;
1866
1867	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1868	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1869
1870	REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1871
1872	vars->mac_type = MAC_TYPE_EMAC;
1873	return 0;
1874}
1875
1876static void bnx2x_update_pfc_bmac1(struct link_params *params,
1877				   struct link_vars *vars)
1878{
1879	u32 wb_data[2];
1880	struct bnx2x *bp = params->bp;
1881	u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1882		NIG_REG_INGRESS_BMAC0_MEM;
1883
1884	u32 val = 0x14;
1885	if ((!(params->feature_config_flags &
1886	      FEATURE_CONFIG_PFC_ENABLED)) &&
1887		(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1888		/* Enable BigMAC to react on received Pause packets */
1889		val |= (1<<5);
1890	wb_data[0] = val;
1891	wb_data[1] = 0;
1892	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1893
1894	/* tx control */
1895	val = 0xc0;
1896	if (!(params->feature_config_flags &
1897	      FEATURE_CONFIG_PFC_ENABLED) &&
1898		(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1899		val |= 0x800000;
1900	wb_data[0] = val;
1901	wb_data[1] = 0;
1902	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1903}
1904
1905static void bnx2x_update_pfc_bmac2(struct link_params *params,
1906				   struct link_vars *vars,
1907				   u8 is_lb)
1908{
1909	/*
1910	 * Set rx control: Strip CRC and enable BigMAC to relay
1911	 * control packets to the system as well
1912	 */
1913	u32 wb_data[2];
1914	struct bnx2x *bp = params->bp;
1915	u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1916		NIG_REG_INGRESS_BMAC0_MEM;
1917	u32 val = 0x14;
1918
1919	if ((!(params->feature_config_flags &
1920	      FEATURE_CONFIG_PFC_ENABLED)) &&
1921		(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1922		/* Enable BigMAC to react on received Pause packets */
1923		val |= (1<<5);
1924	wb_data[0] = val;
1925	wb_data[1] = 0;
1926	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1927	udelay(30);
1928
1929	/* Tx control */
1930	val = 0xc0;
1931	if (!(params->feature_config_flags &
1932				FEATURE_CONFIG_PFC_ENABLED) &&
1933	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1934		val |= 0x800000;
1935	wb_data[0] = val;
1936	wb_data[1] = 0;
1937	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1938
1939	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1940		DP(NETIF_MSG_LINK, "PFC is enabled\n");
1941		/* Enable PFC RX & TX & STATS and set 8 COS  */
1942		wb_data[0] = 0x0;
1943		wb_data[0] |= (1<<0);  /* RX */
1944		wb_data[0] |= (1<<1);  /* TX */
1945		wb_data[0] |= (1<<2);  /* Force initial Xon */
1946		wb_data[0] |= (1<<3);  /* 8 cos */
1947		wb_data[0] |= (1<<5);  /* STATS */
1948		wb_data[1] = 0;
1949		REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
1950			    wb_data, 2);
1951		/* Clear the force Xon */
1952		wb_data[0] &= ~(1<<2);
1953	} else {
1954		DP(NETIF_MSG_LINK, "PFC is disabled\n");
1955		/* disable PFC RX & TX & STATS and set 8 COS */
1956		wb_data[0] = 0x8;
1957		wb_data[1] = 0;
1958	}
1959
1960	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
1961
1962	/*
1963	 * Set Time (based unit is 512 bit time) between automatic
1964	 * re-sending of PP packets amd enable automatic re-send of
1965	 * Per-Priroity Packet as long as pp_gen is asserted and
1966	 * pp_disable is low.
1967	 */
1968	val = 0x8000;
1969	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1970		val |= (1<<16); /* enable automatic re-send */
1971
1972	wb_data[0] = val;
1973	wb_data[1] = 0;
1974	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
1975		    wb_data, 2);
1976
1977	/* mac control */
1978	val = 0x3; /* Enable RX and TX */
1979	if (is_lb) {
1980		val |= 0x4; /* Local loopback */
1981		DP(NETIF_MSG_LINK, "enable bmac loopback\n");
1982	}
1983	/* When PFC enabled, Pass pause frames towards the NIG. */
1984	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1985		val |= ((1<<6)|(1<<5));
1986
1987	wb_data[0] = val;
1988	wb_data[1] = 0;
1989	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
1990}
1991
1992
1993/* PFC BRB internal port configuration params */
1994struct bnx2x_pfc_brb_threshold_val {
1995	u32 pause_xoff;
1996	u32 pause_xon;
1997	u32 full_xoff;
1998	u32 full_xon;
1999};
2000
2001struct bnx2x_pfc_brb_e3b0_val {
2002	u32 full_lb_xoff_th;
2003	u32 full_lb_xon_threshold;
2004	u32 lb_guarantied;
2005	u32 mac_0_class_t_guarantied;
2006	u32 mac_0_class_t_guarantied_hyst;
2007	u32 mac_1_class_t_guarantied;
2008	u32 mac_1_class_t_guarantied_hyst;
2009};
2010
2011struct bnx2x_pfc_brb_th_val {
2012	struct bnx2x_pfc_brb_threshold_val pauseable_th;
2013	struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
2014};
2015static int bnx2x_pfc_brb_get_config_params(
2016				struct link_params *params,
2017				struct bnx2x_pfc_brb_th_val *config_val)
2018{
2019	struct bnx2x *bp = params->bp;
2020	DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
2021	if (CHIP_IS_E2(bp)) {
2022		config_val->pauseable_th.pause_xoff =
2023		    PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2024		config_val->pauseable_th.pause_xon =
2025		    PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
2026		config_val->pauseable_th.full_xoff =
2027		    PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
2028		config_val->pauseable_th.full_xon =
2029		    PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
2030		/* non pause able*/
2031		config_val->non_pauseable_th.pause_xoff =
2032		    PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2033		config_val->non_pauseable_th.pause_xon =
2034		    PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2035		config_val->non_pauseable_th.full_xoff =
2036		    PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2037		config_val->non_pauseable_th.full_xon =
2038		    PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2039	} else if (CHIP_IS_E3A0(bp)) {
2040		config_val->pauseable_th.pause_xoff =
2041		    PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2042		config_val->pauseable_th.pause_xon =
2043		    PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
2044		config_val->pauseable_th.full_xoff =
2045		    PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
2046		config_val->pauseable_th.full_xon =
2047		    PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
2048		/* non pause able*/
2049		config_val->non_pauseable_th.pause_xoff =
2050		    PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2051		config_val->non_pauseable_th.pause_xon =
2052		    PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2053		config_val->non_pauseable_th.full_xoff =
2054		    PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2055		config_val->non_pauseable_th.full_xon =
2056		    PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2057	} else if (CHIP_IS_E3B0(bp)) {
2058		if (params->phy[INT_PHY].flags &
2059		    FLAGS_4_PORT_MODE) {
2060			config_val->pauseable_th.pause_xoff =
2061			    PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2062			config_val->pauseable_th.pause_xon =
2063			    PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2064			config_val->pauseable_th.full_xoff =
2065			    PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2066			config_val->pauseable_th.full_xon =
2067			    PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
2068			/* non pause able*/
2069			config_val->non_pauseable_th.pause_xoff =
2070			    PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2071			config_val->non_pauseable_th.pause_xon =
2072			    PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2073			config_val->non_pauseable_th.full_xoff =
2074			    PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2075			config_val->non_pauseable_th.full_xon =
2076			    PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2077	    } else {
2078		config_val->pauseable_th.pause_xoff =
2079		    PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2080		config_val->pauseable_th.pause_xon =
2081		    PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
2082		config_val->pauseable_th.full_xoff =
2083		    PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
2084		config_val->pauseable_th.full_xon =
2085			PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
2086		/* non pause able*/
2087		config_val->non_pauseable_th.pause_xoff =
2088		    PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
2089		config_val->non_pauseable_th.pause_xon =
2090		    PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
2091		config_val->non_pauseable_th.full_xoff =
2092		    PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
2093		config_val->non_pauseable_th.full_xon =
2094		    PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2095	    }
2096	} else
2097	    return -EINVAL;
2098
2099	return 0;
2100}
2101
2102
2103static void bnx2x_pfc_brb_get_e3b0_config_params(struct link_params *params,
2104						 struct bnx2x_pfc_brb_e3b0_val
2105						 *e3b0_val,
2106						 u32 cos0_pauseable,
2107						 u32 cos1_pauseable)
2108{
2109	if (params->phy[INT_PHY].flags & FLAGS_4_PORT_MODE) {
2110		e3b0_val->full_lb_xoff_th =
2111		    PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2112		e3b0_val->full_lb_xon_threshold =
2113		    PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2114		e3b0_val->lb_guarantied =
2115		    PFC_E3B0_4P_LB_GUART;
2116		e3b0_val->mac_0_class_t_guarantied =
2117		    PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2118		e3b0_val->mac_0_class_t_guarantied_hyst =
2119		    PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2120		e3b0_val->mac_1_class_t_guarantied =
2121		    PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2122		e3b0_val->mac_1_class_t_guarantied_hyst =
2123		    PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2124	} else {
2125		e3b0_val->full_lb_xoff_th =
2126		    PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2127		e3b0_val->full_lb_xon_threshold =
2128		    PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2129		e3b0_val->mac_0_class_t_guarantied_hyst =
2130		    PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2131		e3b0_val->mac_1_class_t_guarantied =
2132		    PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2133		e3b0_val->mac_1_class_t_guarantied_hyst =
2134		    PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2135
2136		if (cos0_pauseable != cos1_pauseable) {
2137			/* nonpauseable= Lossy + pauseable = Lossless*/
2138			e3b0_val->lb_guarantied =
2139			    PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2140			e3b0_val->mac_0_class_t_guarantied =
2141			    PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2142		} else if (cos0_pauseable) {
2143			/* Lossless +Lossless*/
2144			e3b0_val->lb_guarantied =
2145			    PFC_E3B0_2P_PAUSE_LB_GUART;
2146			e3b0_val->mac_0_class_t_guarantied =
2147			    PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2148		} else {
2149			/* Lossy +Lossy*/
2150			e3b0_val->lb_guarantied =
2151			    PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2152			e3b0_val->mac_0_class_t_guarantied =
2153			    PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2154		}
2155	}
2156}
2157static int bnx2x_update_pfc_brb(struct link_params *params,
2158				struct link_vars *vars,
2159				struct bnx2x_nig_brb_pfc_port_params
2160				*pfc_params)
2161{
2162	struct bnx2x *bp = params->bp;
2163	struct bnx2x_pfc_brb_th_val config_val = { {0} };
2164	struct bnx2x_pfc_brb_threshold_val *reg_th_config =
2165	    &config_val.pauseable_th;
2166	struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2167	int set_pfc = params->feature_config_flags &
2168		FEATURE_CONFIG_PFC_ENABLED;
2169	int bnx2x_status = 0;
2170	u8 port = params->port;
2171
2172	/* default - pause configuration */
2173	reg_th_config = &config_val.pauseable_th;
2174	bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2175	if (0 != bnx2x_status)
2176		return bnx2x_status;
2177
2178	if (set_pfc && pfc_params)
2179		/* First COS */
2180		if (!pfc_params->cos0_pauseable)
2181			reg_th_config = &config_val.non_pauseable_th;
2182	/*
2183	 * The number of free blocks below which the pause signal to class 0
2184	 * of MAC #n is asserted. n=0,1
2185	 */
2186	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
2187	       BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
2188	       reg_th_config->pause_xoff);
2189	/*
2190	 * The number of free blocks above which the pause signal to class 0
2191	 * of MAC #n is de-asserted. n=0,1
2192	 */
2193	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
2194	       BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
2195	/*
2196	 * The number of free blocks below which the full signal to class 0
2197	 * of MAC #n is asserted. n=0,1
2198	 */
2199	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
2200	       BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
2201	/*
2202	 * The number of free blocks above which the full signal to class 0
2203	 * of MAC #n is de-asserted. n=0,1
2204	 */
2205	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
2206	       BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2207
2208	if (set_pfc && pfc_params) {
2209		/* Second COS */
2210		if (pfc_params->cos1_pauseable)
2211			reg_th_config = &config_val.pauseable_th;
2212		else
2213			reg_th_config = &config_val.non_pauseable_th;
2214		/*
2215		 * The number of free blocks below which the pause signal to
2216		 * class 1 of MAC #n is asserted. n=0,1
2217		**/
2218		REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
2219		       BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
2220		       reg_th_config->pause_xoff);
2221		/*
2222		 * The number of free blocks above which the pause signal to
2223		 * class 1 of MAC #n is de-asserted. n=0,1
2224		 */
2225		REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
2226		       BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
2227		       reg_th_config->pause_xon);
2228		/*
2229		 * The number of free blocks below which the full signal to
2230		 * class 1 of MAC #n is asserted. n=0,1
2231		 */
2232		REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
2233		       BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
2234		       reg_th_config->full_xoff);
2235		/*
2236		 * The number of free blocks above which the full signal to
2237		 * class 1 of MAC #n is de-asserted. n=0,1
2238		 */
2239		REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
2240		       BRB1_REG_FULL_1_XON_THRESHOLD_0,
2241		       reg_th_config->full_xon);
2242
2243
2244		if (CHIP_IS_E3B0(bp)) {
2245			/*Should be done by init tool */
2246			/*
2247			* BRB_empty_for_dup = BRB1_REG_BRB_EMPTY_THRESHOLD
2248			* reset value
2249			* 944
2250			*/
2251
2252			/**
2253			 * The hysteresis on the guarantied buffer space for the Lb port
2254			 * before signaling XON.
2255			 **/
2256			REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST, 80);
2257
2258			bnx2x_pfc_brb_get_e3b0_config_params(
2259			    params,
2260			    &e3b0_val,
2261			    pfc_params->cos0_pauseable,
2262			    pfc_params->cos1_pauseable);
2263			/**
2264			 * The number of free blocks below which the full signal to the
2265			 * LB port is asserted.
2266			*/
2267			REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
2268				   e3b0_val.full_lb_xoff_th);
2269			/**
2270			 * The number of free blocks above which the full signal to the
2271			 * LB port is de-asserted.
2272			*/
2273			REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
2274				   e3b0_val.full_lb_xon_threshold);
2275			/**
2276			* The number of blocks guarantied for the MAC #n port. n=0,1
2277			*/
2278
2279			/*The number of blocks guarantied for the LB port.*/
2280			REG_WR(bp, BRB1_REG_LB_GUARANTIED,
2281			       e3b0_val.lb_guarantied);
2282
2283			/**
2284			 * The number of blocks guarantied for the MAC #n port.
2285			*/
2286			REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
2287				   2 * e3b0_val.mac_0_class_t_guarantied);
2288			REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
2289				   2 * e3b0_val.mac_1_class_t_guarantied);
2290			/**
2291			 * The number of blocks guarantied for class #t in MAC0. t=0,1
2292			*/
2293			REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
2294			       e3b0_val.mac_0_class_t_guarantied);
2295			REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
2296			       e3b0_val.mac_0_class_t_guarantied);
2297			/**
2298			 * The hysteresis on the guarantied buffer space for class in
2299			 * MAC0.  t=0,1
2300			*/
2301			REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
2302			       e3b0_val.mac_0_class_t_guarantied_hyst);
2303			REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
2304			       e3b0_val.mac_0_class_t_guarantied_hyst);
2305
2306			/**
2307			 * The number of blocks guarantied for class #t in MAC1.t=0,1
2308			*/
2309			REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
2310			       e3b0_val.mac_1_class_t_guarantied);
2311			REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
2312			       e3b0_val.mac_1_class_t_guarantied);
2313			/**
2314			 * The hysteresis on the guarantied buffer space for class #t
2315			* in MAC1.  t=0,1
2316			*/
2317			REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
2318			       e3b0_val.mac_1_class_t_guarantied_hyst);
2319			REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
2320			       e3b0_val.mac_1_class_t_guarantied_hyst);
2321
2322	    }
2323
2324	}
2325
2326	return bnx2x_status;
2327}
2328
2329/******************************************************************************
2330* Description:
2331*  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2332*  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2333******************************************************************************/
2334int bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2335					      u8 cos_entry,
2336					      u32 priority_mask, u8 port)
2337{
2338	u32 nig_reg_rx_priority_mask_add = 0;
2339
2340	switch (cos_entry) {
2341	case 0:
2342	     nig_reg_rx_priority_mask_add = (port) ?
2343		 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2344		 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2345	     break;
2346	case 1:
2347	    nig_reg_rx_priority_mask_add = (port) ?
2348		NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2349		NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2350	    break;
2351	case 2:
2352	    nig_reg_rx_priority_mask_add = (port) ?
2353		NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2354		NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2355	    break;
2356	case 3:
2357	    if (port)
2358		return -EINVAL;
2359	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2360	    break;
2361	case 4:
2362	    if (port)
2363		return -EINVAL;
2364	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2365	    break;
2366	case 5:
2367	    if (port)
2368		return -EINVAL;
2369	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2370	    break;
2371	}
2372
2373	REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2374
2375	return 0;
2376}
2377static void bnx2x_update_mng(struct link_params *params, u32 link_status)
2378{
2379	struct bnx2x *bp = params->bp;
2380
2381	REG_WR(bp, params->shmem_base +
2382	       offsetof(struct shmem_region,
2383			port_mb[params->port].link_status), link_status);
2384}
2385
2386static void bnx2x_update_pfc_nig(struct link_params *params,
2387		struct link_vars *vars,
2388		struct bnx2x_nig_brb_pfc_port_params *nig_params)
2389{
2390	u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2391	u32 llfc_enable = 0, xcm0_out_en = 0, p0_hwpfc_enable = 0;
2392	u32 pkt_priority_to_cos = 0;
2393	struct bnx2x *bp = params->bp;
2394	u8 port = params->port;
2395
2396	int set_pfc = params->feature_config_flags &
2397		FEATURE_CONFIG_PFC_ENABLED;
2398	DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2399
2400	/*
2401	 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2402	 * MAC control frames (that are not pause packets)
2403	 * will be forwarded to the XCM.
2404	 */
2405	xcm_mask = REG_RD(bp,
2406				port ? NIG_REG_LLH1_XCM_MASK :
2407				NIG_REG_LLH0_XCM_MASK);
2408	/*
2409	 * nig params will override non PFC params, since it's possible to
2410	 * do transition from PFC to SAFC
2411	 */
2412	if (set_pfc) {
2413		pause_enable = 0;
2414		llfc_out_en = 0;
2415		llfc_enable = 0;
2416		if (CHIP_IS_E3(bp))
2417			ppp_enable = 0;
2418		else
2419		ppp_enable = 1;
2420		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2421				     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2422		xcm0_out_en = 0;
2423		p0_hwpfc_enable = 1;
2424	} else  {
2425		if (nig_params) {
2426			llfc_out_en = nig_params->llfc_out_en;
2427			llfc_enable = nig_params->llfc_enable;
2428			pause_enable = nig_params->pause_enable;
2429		} else  /*defaul non PFC mode - PAUSE */
2430			pause_enable = 1;
2431
2432		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2433			NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2434		xcm0_out_en = 1;
2435	}
2436
2437	if (CHIP_IS_E3(bp))
2438		REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2439		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2440	REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2441	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2442	REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2443	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
2444	REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2445	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
2446
2447	REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2448	       NIG_REG_PPP_ENABLE_0, ppp_enable);
2449
2450	REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2451	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
2452
2453	REG_WR(bp,  NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2454
2455	/* output enable for RX_XCM # IF */
2456	REG_WR(bp, NIG_REG_XCM0_OUT_EN, xcm0_out_en);
2457
2458	/* HW PFC TX enable */
2459	REG_WR(bp, NIG_REG_P0_HWPFC_ENABLE, p0_hwpfc_enable);
2460
2461	if (nig_params) {
2462		u8 i = 0;
2463		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2464
2465		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2466			bnx2x_pfc_nig_rx_priority_mask(bp, i,
2467		nig_params->rx_cos_priority_mask[i], port);
2468
2469		REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2470		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2471		       nig_params->llfc_high_priority_classes);
2472
2473		REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2474		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2475		       nig_params->llfc_low_priority_classes);
2476	}
2477	REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2478	       NIG_REG_P0_PKT_PRIORITY_TO_COS,
2479	       pkt_priority_to_cos);
2480}
2481
2482int bnx2x_update_pfc(struct link_params *params,
2483		      struct link_vars *vars,
2484		      struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2485{
2486	/*
2487	 * The PFC and pause are orthogonal to one another, meaning when
2488	 * PFC is enabled, the pause are disabled, and when PFC is
2489	 * disabled, pause are set according to the pause result.
2490	 */
2491	u32 val;
2492	struct bnx2x *bp = params->bp;
2493	int bnx2x_status = 0;
2494	u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2495
2496	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2497		vars->link_status |= LINK_STATUS_PFC_ENABLED;
2498	else
2499		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2500
2501	bnx2x_update_mng(params, vars->link_status);
2502
2503	/* update NIG params */
2504	bnx2x_update_pfc_nig(params, vars, pfc_params);
2505
2506	/* update BRB params */
2507	bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2508	if (0 != bnx2x_status)
2509		return bnx2x_status;
2510
2511	if (!vars->link_up)
2512		return bnx2x_status;
2513
2514	DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
2515	if (CHIP_IS_E3(bp))
2516		bnx2x_update_pfc_xmac(params, vars, 0);
2517	else {
2518		val = REG_RD(bp, MISC_REG_RESET_REG_2);
2519		if ((val &
2520		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2521		    == 0) {
2522			DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
2523			bnx2x_emac_enable(params, vars, 0);
2524			return bnx2x_status;
2525		}
2526
2527		if (CHIP_IS_E2(bp))
2528			bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
2529		else
2530			bnx2x_update_pfc_bmac1(params, vars);
2531
2532		val = 0;
2533		if ((params->feature_config_flags &
2534		     FEATURE_CONFIG_PFC_ENABLED) ||
2535		    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2536			val = 1;
2537		REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2538	}
2539	return bnx2x_status;
2540}
2541
2542
2543static int bnx2x_bmac1_enable(struct link_params *params,
2544			      struct link_vars *vars,
2545			      u8 is_lb)
2546{
2547	struct bnx2x *bp = params->bp;
2548	u8 port = params->port;
2549	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2550			       NIG_REG_INGRESS_BMAC0_MEM;
2551	u32 wb_data[2];
2552	u32 val;
2553
2554	DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2555
2556	/* XGXS control */
2557	wb_data[0] = 0x3c;
2558	wb_data[1] = 0;
2559	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2560		    wb_data, 2);
2561
2562	/* tx MAC SA */
2563	wb_data[0] = ((params->mac_addr[2] << 24) |
2564		       (params->mac_addr[3] << 16) |
2565		       (params->mac_addr[4] << 8) |
2566			params->mac_addr[5]);
2567	wb_data[1] = ((params->mac_addr[0] << 8) |
2568			params->mac_addr[1]);
2569	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2570
2571	/* mac control */
2572	val = 0x3;
2573	if (is_lb) {
2574		val |= 0x4;
2575		DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2576	}
2577	wb_data[0] = val;
2578	wb_data[1] = 0;
2579	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2580
2581	/* set rx mtu */
2582	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2583	wb_data[1] = 0;
2584	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2585
2586	bnx2x_update_pfc_bmac1(params, vars);
2587
2588	/* set tx mtu */
2589	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2590	wb_data[1] = 0;
2591	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2592
2593	/* set cnt max size */
2594	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2595	wb_data[1] = 0;
2596	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2597
2598	/* configure safc */
2599	wb_data[0] = 0x1000200;
2600	wb_data[1] = 0;
2601	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2602		    wb_data, 2);
2603
2604	return 0;
2605}
2606
2607static int bnx2x_bmac2_enable(struct link_params *params,
2608			      struct link_vars *vars,
2609			      u8 is_lb)
2610{
2611	struct bnx2x *bp = params->bp;
2612	u8 port = params->port;
2613	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2614			       NIG_REG_INGRESS_BMAC0_MEM;
2615	u32 wb_data[2];
2616
2617	DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2618
2619	wb_data[0] = 0;
2620	wb_data[1] = 0;
2621	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2622	udelay(30);
2623
2624	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2625	wb_data[0] = 0x3c;
2626	wb_data[1] = 0;
2627	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2628		    wb_data, 2);
2629
2630	udelay(30);
2631
2632	/* tx MAC SA */
2633	wb_data[0] = ((params->mac_addr[2] << 24) |
2634		       (params->mac_addr[3] << 16) |
2635		       (params->mac_addr[4] << 8) |
2636			params->mac_addr[5]);
2637	wb_data[1] = ((params->mac_addr[0] << 8) |
2638			params->mac_addr[1]);
2639	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2640		    wb_data, 2);
2641
2642	udelay(30);
2643
2644	/* Configure SAFC */
2645	wb_data[0] = 0x1000200;
2646	wb_data[1] = 0;
2647	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2648		    wb_data, 2);
2649	udelay(30);
2650
2651	/* set rx mtu */
2652	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2653	wb_data[1] = 0;
2654	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2655	udelay(30);
2656
2657	/* set tx mtu */
2658	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2659	wb_data[1] = 0;
2660	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2661	udelay(30);
2662	/* set cnt max size */
2663	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2664	wb_data[1] = 0;
2665	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2666	udelay(30);
2667	bnx2x_update_pfc_bmac2(params, vars, is_lb);
2668
2669	return 0;
2670}
2671
2672static int bnx2x_bmac_enable(struct link_params *params,
2673			     struct link_vars *vars,
2674			     u8 is_lb)
2675{
2676	int rc = 0;
2677	u8 port = params->port;
2678	struct bnx2x *bp = params->bp;
2679	u32 val;
2680	/* reset and unreset the BigMac */
2681	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2682	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2683	msleep(1);
2684
2685	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2686	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2687
2688	/* enable access for bmac registers */
2689	REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2690
2691	/* Enable BMAC according to BMAC type*/
2692	if (CHIP_IS_E2(bp))
2693		rc = bnx2x_bmac2_enable(params, vars, is_lb);
2694	else
2695		rc = bnx2x_bmac1_enable(params, vars, is_lb);
2696	REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2697	REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2698	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2699	val = 0;
2700	if ((params->feature_config_flags &
2701	      FEATURE_CONFIG_PFC_ENABLED) ||
2702	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2703		val = 1;
2704	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2705	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2706	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2707	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2708	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2709	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2710
2711	vars->mac_type = MAC_TYPE_BMAC;
2712	return rc;
2713}
2714
2715static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2716{
2717	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2718			NIG_REG_INGRESS_BMAC0_MEM;
2719	u32 wb_data[2];
2720	u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2721
2722	/* Only if the bmac is out of reset */
2723	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2724			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2725	    nig_bmac_enable) {
2726
2727		if (CHIP_IS_E2(bp)) {
2728			/* Clear Rx Enable bit in BMAC_CONTROL register */
2729			REG_RD_DMAE(bp, bmac_addr +
2730				    BIGMAC2_REGISTER_BMAC_CONTROL,
2731				    wb_data, 2);
2732			wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2733			REG_WR_DMAE(bp, bmac_addr +
2734				    BIGMAC2_REGISTER_BMAC_CONTROL,
2735				    wb_data, 2);
2736		} else {
2737			/* Clear Rx Enable bit in BMAC_CONTROL register */
2738			REG_RD_DMAE(bp, bmac_addr +
2739					BIGMAC_REGISTER_BMAC_CONTROL,
2740					wb_data, 2);
2741			wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2742			REG_WR_DMAE(bp, bmac_addr +
2743					BIGMAC_REGISTER_BMAC_CONTROL,
2744					wb_data, 2);
2745		}
2746		msleep(1);
2747	}
2748}
2749
2750static int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2751			    u32 line_speed)
2752{
2753	struct bnx2x *bp = params->bp;
2754	u8 port = params->port;
2755	u32 init_crd, crd;
2756	u32 count = 1000;
2757
2758	/* disable port */
2759	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2760
2761	/* wait for init credit */
2762	init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2763	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2764	DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2765
2766	while ((init_crd != crd) && count) {
2767		msleep(5);
2768
2769		crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2770		count--;
2771	}
2772	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2773	if (init_crd != crd) {
2774		DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2775			  init_crd, crd);
2776		return -EINVAL;
2777	}
2778
2779	if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
2780	    line_speed == SPEED_10 ||
2781	    line_speed == SPEED_100 ||
2782	    line_speed == SPEED_1000 ||
2783	    line_speed == SPEED_2500) {
2784		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2785		/* update threshold */
2786		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2787		/* update init credit */
2788		init_crd = 778;		/* (800-18-4) */
2789
2790	} else {
2791		u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2792			      ETH_OVREHEAD)/16;
2793		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2794		/* update threshold */
2795		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2796		/* update init credit */
2797		switch (line_speed) {
2798		case SPEED_10000:
2799			init_crd = thresh + 553 - 22;
2800			break;
2801		default:
2802			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2803				  line_speed);
2804			return -EINVAL;
2805		}
2806	}
2807	REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2808	DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2809		 line_speed, init_crd);
2810
2811	/* probe the credit changes */
2812	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2813	msleep(5);
2814	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2815
2816	/* enable port */
2817	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2818	return 0;
2819}
2820
2821/**
2822 * bnx2x_get_emac_base - retrive emac base address
2823 *
2824 * @bp:			driver handle
2825 * @mdc_mdio_access:	access type
2826 * @port:		port id
2827 *
2828 * This function selects the MDC/MDIO access (through emac0 or
2829 * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2830 * phy has a default access mode, which could also be overridden
2831 * by nvram configuration. This parameter, whether this is the
2832 * default phy configuration, or the nvram overrun
2833 * configuration, is passed here as mdc_mdio_access and selects
2834 * the emac_base for the CL45 read/writes operations
2835 */
2836static u32 bnx2x_get_emac_base(struct bnx2x *bp,
2837			       u32 mdc_mdio_access, u8 port)
2838{
2839	u32 emac_base = 0;
2840	switch (mdc_mdio_access) {
2841	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2842		break;
2843	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2844		if (REG_RD(bp, NIG_REG_PORT_SWAP))
2845			emac_base = GRCBASE_EMAC1;
2846		else
2847			emac_base = GRCBASE_EMAC0;
2848		break;
2849	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2850		if (REG_RD(bp, NIG_REG_PORT_SWAP))
2851			emac_base = GRCBASE_EMAC0;
2852		else
2853			emac_base = GRCBASE_EMAC1;
2854		break;
2855	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2856		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2857		break;
2858	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2859		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2860		break;
2861	default:
2862		break;
2863	}
2864	return emac_base;
2865
2866}
2867
2868/******************************************************************/
2869/*			CL22 access functions			  */
2870/******************************************************************/
2871static int bnx2x_cl22_write(struct bnx2x *bp,
2872				       struct bnx2x_phy *phy,
2873				       u16 reg, u16 val)
2874{
2875	u32 tmp, mode;
2876	u8 i;
2877	int rc = 0;
2878	/* Switch to CL22 */
2879	mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2880	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2881	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2882
2883	/* address */
2884	tmp = ((phy->addr << 21) | (reg << 16) | val |
2885	       EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2886	       EMAC_MDIO_COMM_START_BUSY);
2887	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2888
2889	for (i = 0; i < 50; i++) {
2890		udelay(10);
2891
2892		tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2893		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2894			udelay(5);
2895			break;
2896		}
2897	}
2898	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2899		DP(NETIF_MSG_LINK, "write phy register failed\n");
2900		rc = -EFAULT;
2901	}
2902	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2903	return rc;
2904}
2905
2906static int bnx2x_cl22_read(struct bnx2x *bp,
2907				      struct bnx2x_phy *phy,
2908				      u16 reg, u16 *ret_val)
2909{
2910	u32 val, mode;
2911	u16 i;
2912	int rc = 0;
2913
2914	/* Switch to CL22 */
2915	mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2916	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2917	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2918
2919	/* address */
2920	val = ((phy->addr << 21) | (reg << 16) |
2921	       EMAC_MDIO_COMM_COMMAND_READ_22 |
2922	       EMAC_MDIO_COMM_START_BUSY);
2923	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2924
2925	for (i = 0; i < 50; i++) {
2926		udelay(10);
2927
2928		val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2929		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2930			*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2931			udelay(5);
2932			break;
2933		}
2934	}
2935	if (val & EMAC_MDIO_COMM_START_BUSY) {
2936		DP(NETIF_MSG_LINK, "read phy register failed\n");
2937
2938		*ret_val = 0;
2939		rc = -EFAULT;
2940	}
2941	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2942	return rc;
2943}
2944
2945/******************************************************************/
2946/*			CL45 access functions			  */
2947/******************************************************************/
2948static int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
2949			   u8 devad, u16 reg, u16 *ret_val)
2950{
2951	u32 val;
2952	u16 i;
2953	int rc = 0;
2954	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
2955		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2956			      EMAC_MDIO_STATUS_10MB);
2957	/* address */
2958	val = ((phy->addr << 21) | (devad << 16) | reg |
2959	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
2960	       EMAC_MDIO_COMM_START_BUSY);
2961	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2962
2963	for (i = 0; i < 50; i++) {
2964		udelay(10);
2965
2966		val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2967		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2968			udelay(5);
2969			break;
2970		}
2971	}
2972	if (val & EMAC_MDIO_COMM_START_BUSY) {
2973		DP(NETIF_MSG_LINK, "read phy register failed\n");
2974		netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2975		*ret_val = 0;
2976		rc = -EFAULT;
2977	} else {
2978		/* data */
2979		val = ((phy->addr << 21) | (devad << 16) |
2980		       EMAC_MDIO_COMM_COMMAND_READ_45 |
2981		       EMAC_MDIO_COMM_START_BUSY);
2982		REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2983
2984		for (i = 0; i < 50; i++) {
2985			udelay(10);
2986
2987			val = REG_RD(bp, phy->mdio_ctrl +
2988				     EMAC_REG_EMAC_MDIO_COMM);
2989			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2990				*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2991				break;
2992			}
2993		}
2994		if (val & EMAC_MDIO_COMM_START_BUSY) {
2995			DP(NETIF_MSG_LINK, "read phy register failed\n");
2996			netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
2997			*ret_val = 0;
2998			rc = -EFAULT;
2999		}
3000	}
3001	/* Work around for E3 A0 */
3002	if (phy->flags & FLAGS_MDC_MDIO_WA) {
3003		phy->flags ^= FLAGS_DUMMY_READ;
3004		if (phy->flags & FLAGS_DUMMY_READ) {
3005			u16 temp_val;
3006			bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3007		}
3008	}
3009
3010	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3011		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3012			       EMAC_MDIO_STATUS_10MB);
3013	return rc;
3014}
3015
3016static int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3017			    u8 devad, u16 reg, u16 val)
3018{
3019	u32 tmp;
3020	u8 i;
3021	int rc = 0;
3022	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3023		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3024			      EMAC_MDIO_STATUS_10MB);
3025
3026	/* address */
3027
3028	tmp = ((phy->addr << 21) | (devad << 16) | reg |
3029	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3030	       EMAC_MDIO_COMM_START_BUSY);
3031	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3032
3033	for (i = 0; i < 50; i++) {
3034		udelay(10);
3035
3036		tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3037		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3038			udelay(5);
3039			break;
3040		}
3041	}
3042	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3043		DP(NETIF_MSG_LINK, "write phy register failed\n");
3044		netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3045		rc = -EFAULT;
3046
3047	} else {
3048		/* data */
3049		tmp = ((phy->addr << 21) | (devad << 16) | val |
3050		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3051		       EMAC_MDIO_COMM_START_BUSY);
3052		REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3053
3054		for (i = 0; i < 50; i++) {
3055			udelay(10);
3056
3057			tmp = REG_RD(bp, phy->mdio_ctrl +
3058				     EMAC_REG_EMAC_MDIO_COMM);
3059			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3060				udelay(5);
3061				break;
3062			}
3063		}
3064		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3065			DP(NETIF_MSG_LINK, "write phy register failed\n");
3066			netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3067			rc = -EFAULT;
3068		}
3069	}
3070	/* Work around for E3 A0 */
3071	if (phy->flags & FLAGS_MDC_MDIO_WA) {
3072		phy->flags ^= FLAGS_DUMMY_READ;
3073		if (phy->flags & FLAGS_DUMMY_READ) {
3074			u16 temp_val;
3075			bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
3076		}
3077	}
3078	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3079		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3080			       EMAC_MDIO_STATUS_10MB);
3081	return rc;
3082}
3083
3084
3085/******************************************************************/
3086/*			BSC access functions from E3	          */
3087/******************************************************************/
3088static void bnx2x_bsc_module_sel(struct link_params *params)
3089{
3090	int idx;
3091	u32 board_cfg, sfp_ctrl;
3092	u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
3093	struct bnx2x *bp = params->bp;
3094	u8 port = params->port;
3095	/* Read I2C output PINs */
3096	board_cfg = REG_RD(bp, params->shmem_base +
3097			   offsetof(struct shmem_region,
3098				    dev_info.shared_hw_config.board));
3099	i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
3100	i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
3101			SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
3102
3103	/* Read I2C output value */
3104	sfp_ctrl = REG_RD(bp, params->shmem_base +
3105			  offsetof(struct shmem_region,
3106				 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
3107	i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
3108	i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
3109	DP(NETIF_MSG_LINK, "Setting BSC switch\n");
3110	for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
3111		bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
3112}
3113
3114static int bnx2x_bsc_read(struct link_params *params,
3115			  struct bnx2x_phy *phy,
3116			  u8 sl_devid,
3117			  u16 sl_addr,
3118			  u8 lc_addr,
3119			  u8 xfer_cnt,
3120			  u32 *data_array)
3121{
3122	u32 val, i;
3123	int rc = 0;
3124	struct bnx2x *bp = params->bp;
3125
3126	if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
3127		DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
3128		return -EINVAL;
3129	}
3130
3131	if (xfer_cnt > 16) {
3132		DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
3133					xfer_cnt);
3134		return -EINVAL;
3135	}
3136	bnx2x_bsc_module_sel(params);
3137
3138	xfer_cnt = 16 - lc_addr;
3139
3140	/* enable the engine */
3141	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3142	val |= MCPR_IMC_COMMAND_ENABLE;
3143	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3144
3145	/* program slave device ID */
3146	val = (sl_devid << 16) | sl_addr;
3147	REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
3148
3149	/* start xfer with 0 byte to update the address pointer ???*/
3150	val = (MCPR_IMC_COMMAND_ENABLE) |
3151	      (MCPR_IMC_COMMAND_WRITE_OP <<
3152		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3153		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
3154	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3155
3156	/* poll for completion */
3157	i = 0;
3158	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3159	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3160		udelay(10);
3161		val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3162		if (i++ > 1000) {
3163			DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
3164								i);
3165			rc = -EFAULT;
3166			break;
3167		}
3168	}
3169	if (rc == -EFAULT)
3170		return rc;
3171
3172	/* start xfer with read op */
3173	val = (MCPR_IMC_COMMAND_ENABLE) |
3174		(MCPR_IMC_COMMAND_READ_OP <<
3175		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
3176		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
3177		  (xfer_cnt);
3178	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
3179
3180	/* poll for completion */
3181	i = 0;
3182	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3183	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
3184		udelay(10);
3185		val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
3186		if (i++ > 1000) {
3187			DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
3188			rc = -EFAULT;
3189			break;
3190		}
3191	}
3192	if (rc == -EFAULT)
3193		return rc;
3194
3195	for (i = (lc_addr >> 2); i < 4; i++) {
3196		data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
3197#ifdef __BIG_ENDIAN
3198		data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
3199				((data_array[i] & 0x0000ff00) << 8) |
3200				((data_array[i] & 0x00ff0000) >> 8) |
3201				((data_array[i] & 0xff000000) >> 24);
3202#endif
3203	}
3204	return rc;
3205}
3206
3207static void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3208				     u8 devad, u16 reg, u16 or_val)
3209{
3210	u16 val;
3211	bnx2x_cl45_read(bp, phy, devad, reg, &val);
3212	bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
3213}
3214
3215int bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3216		   u8 devad, u16 reg, u16 *ret_val)
3217{
3218	u8 phy_index;
3219	/*
3220	 * Probe for the phy according to the given phy_addr, and execute
3221	 * the read request on it
3222	 */
3223	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3224		if (params->phy[phy_index].addr == phy_addr) {
3225			return bnx2x_cl45_read(params->bp,
3226					       &params->phy[phy_index], devad,
3227					       reg, ret_val);
3228		}
3229	}
3230	return -EINVAL;
3231}
3232
3233int bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3234		    u8 devad, u16 reg, u16 val)
3235{
3236	u8 phy_index;
3237	/*
3238	 * Probe for the phy according to the given phy_addr, and execute
3239	 * the write request on it
3240	 */
3241	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3242		if (params->phy[phy_index].addr == phy_addr) {
3243			return bnx2x_cl45_write(params->bp,
3244						&params->phy[phy_index], devad,
3245						reg, val);
3246		}
3247	}
3248	return -EINVAL;
3249}
3250static u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
3251				  struct link_params *params)
3252{
3253	u8 lane = 0;
3254	struct bnx2x *bp = params->bp;
3255	u32 path_swap, path_swap_ovr;
3256	u8 path, port;
3257
3258	path = BP_PATH(bp);
3259	port = params->port;
3260
3261	if (bnx2x_is_4_port_mode(bp)) {
3262		u32 port_swap, port_swap_ovr;
3263
3264		/*figure out path swap value */
3265		path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
3266		if (path_swap_ovr & 0x1)
3267			path_swap = (path_swap_ovr & 0x2);
3268		else
3269			path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
3270
3271		if (path_swap)
3272			path = path ^ 1;
3273
3274		/*figure out port swap value */
3275		port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
3276		if (port_swap_ovr & 0x1)
3277			port_swap = (port_swap_ovr & 0x2);
3278		else
3279			port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
3280
3281		if (port_swap)
3282			port = port ^ 1;
3283
3284		lane = (port<<1) + path;
3285	} else { /* two port mode - no port swap */
3286
3287		/*figure out path swap value */
3288		path_swap_ovr =
3289			REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
3290		if (path_swap_ovr & 0x1) {
3291			path_swap = (path_swap_ovr & 0x2);
3292		} else {
3293			path_swap =
3294				REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
3295		}
3296		if (path_swap)
3297			path = path ^ 1;
3298
3299		lane = path << 1 ;
3300	}
3301	return lane;
3302}
3303
3304static void bnx2x_set_aer_mmd(struct link_params *params,
3305			      struct bnx2x_phy *phy)
3306{
3307	u32 ser_lane;
3308	u16 offset, aer_val;
3309	struct bnx2x *bp = params->bp;
3310	ser_lane = ((params->lane_config &
3311		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3312		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3313
3314	offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3315		(phy->addr + ser_lane) : 0;
3316
3317	if (USES_WARPCORE(bp)) {
3318		aer_val = bnx2x_get_warpcore_lane(phy, params);
3319		/*
3320		 * In Dual-lane mode, two lanes are joined together,
3321		 * so in order to configure them, the AER broadcast method is
3322		 * used here.
3323		 * 0x200 is the broadcast address for lanes 0,1
3324		 * 0x201 is the broadcast address for lanes 2,3
3325		 */
3326		if (phy->flags & FLAGS_WC_DUAL_MODE)
3327			aer_val = (aer_val >> 1) | 0x200;
3328	} else if (CHIP_IS_E2(bp))
3329		aer_val = 0x3800 + offset - 1;
3330	else
3331		aer_val = 0x3800 + offset;
3332	DP(NETIF_MSG_LINK, "Set AER to 0x%x\n", aer_val);
3333	CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3334			  MDIO_AER_BLOCK_AER_REG, aer_val);
3335
3336}
3337
3338/******************************************************************/
3339/*			Internal phy section			  */
3340/******************************************************************/
3341
3342static void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3343{
3344	u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3345
3346	/* Set Clause 22 */
3347	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3348	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3349	udelay(500);
3350	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3351	udelay(500);
3352	 /* Set Clause 45 */
3353	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3354}
3355
3356static void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3357{
3358	u32 val;
3359
3360	DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3361
3362	val = SERDES_RESET_BITS << (port*16);
3363
3364	/* reset and unreset the SerDes/XGXS */
3365	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3366	udelay(500);
3367	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3368
3369	bnx2x_set_serdes_access(bp, port);
3370
3371	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3372	       DEFAULT_PHY_DEV_ADDR);
3373}
3374
3375static void bnx2x_xgxs_deassert(struct link_params *params)
3376{
3377	struct bnx2x *bp = params->bp;
3378	u8 port;
3379	u32 val;
3380	DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3381	port = params->port;
3382
3383	val = XGXS_RESET_BITS << (port*16);
3384
3385	/* reset and unreset the SerDes/XGXS */
3386	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3387	udelay(500);
3388	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3389
3390	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3391	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3392	       params->phy[INT_PHY].def_md_devad);
3393}
3394
3395static void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
3396				     struct link_params *params, u16 *ieee_fc)
3397{
3398	struct bnx2x *bp = params->bp;
3399	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
3400	/**
3401	 * resolve pause mode and advertisement Please refer to Table
3402	 * 28B-3 of the 802.3ab-1999 spec
3403	 */
3404
3405	switch (phy->req_flow_ctrl) {
3406	case BNX2X_FLOW_CTRL_AUTO:
3407		if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
3408			*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3409		else
3410			*ieee_fc |=
3411			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3412		break;
3413
3414	case BNX2X_FLOW_CTRL_TX:
3415		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
3416		break;
3417
3418	case BNX2X_FLOW_CTRL_RX:
3419	case BNX2X_FLOW_CTRL_BOTH:
3420		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
3421		break;
3422
3423	case BNX2X_FLOW_CTRL_NONE:
3424	default:
3425		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
3426		break;
3427	}
3428	DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
3429}
3430
3431static void set_phy_vars(struct link_params *params,
3432			 struct link_vars *vars)
3433{
3434	struct bnx2x *bp = params->bp;
3435	u8 actual_phy_idx, phy_index, link_cfg_idx;
3436	u8 phy_config_swapped = params->multi_phy_config &
3437			PORT_HW_CFG_PHY_SWAPPED_ENABLED;
3438	for (phy_index = INT_PHY; phy_index < params->num_phys;
3439	      phy_index++) {
3440		link_cfg_idx = LINK_CONFIG_IDX(phy_index);
3441		actual_phy_idx = phy_index;
3442		if (phy_config_swapped) {
3443			if (phy_index == EXT_PHY1)
3444				actual_phy_idx = EXT_PHY2;
3445			else if (phy_index == EXT_PHY2)
3446				actual_phy_idx = EXT_PHY1;
3447		}
3448		params->phy[actual_phy_idx].req_flow_ctrl =
3449			params->req_flow_ctrl[link_cfg_idx];
3450
3451		params->phy[actual_phy_idx].req_line_speed =
3452			params->req_line_speed[link_cfg_idx];
3453
3454		params->phy[actual_phy_idx].speed_cap_mask =
3455			params->speed_cap_mask[link_cfg_idx];
3456
3457		params->phy[actual_phy_idx].req_duplex =
3458			params->req_duplex[link_cfg_idx];
3459
3460		if (params->req_line_speed[link_cfg_idx] ==
3461		    SPEED_AUTO_NEG)
3462			vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
3463
3464		DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
3465			   " speed_cap_mask %x\n",
3466			   params->phy[actual_phy_idx].req_flow_ctrl,
3467			   params->phy[actual_phy_idx].req_line_speed,
3468			   params->phy[actual_phy_idx].speed_cap_mask);
3469	}
3470}
3471
3472static void bnx2x_ext_phy_set_pause(struct link_params *params,
3473				    struct bnx2x_phy *phy,
3474				    struct link_vars *vars)
3475{
3476	u16 val;
3477	struct bnx2x *bp = params->bp;
3478	/* read modify write pause advertizing */
3479	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
3480
3481	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
3482
3483	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
3484	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
3485	if ((vars->ieee_fc &
3486	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
3487	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
3488		val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
3489	}
3490	if ((vars->ieee_fc &
3491	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
3492	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
3493		val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
3494	}
3495	DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
3496	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
3497}
3498
3499static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
3500{						/*  LD	    LP	 */
3501	switch (pause_result) {			/* ASYM P ASYM P */
3502	case 0xb:				/*   1  0   1  1 */
3503		vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
3504		break;
3505
3506	case 0xe:				/*   1  1   1  0 */
3507		vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
3508		break;
3509
3510	case 0x5:				/*   0  1   0  1 */
3511	case 0x7:				/*   0  1   1  1 */
3512	case 0xd:				/*   1  1   0  1 */
3513	case 0xf:				/*   1  1   1  1 */
3514		vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
3515		break;
3516
3517	default:
3518		break;
3519	}
3520	if (pause_result & (1<<0))
3521		vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
3522	if (pause_result & (1<<1))
3523		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
3524}
3525
3526static u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
3527				   struct link_params *params,
3528				   struct link_vars *vars)
3529{
3530	struct bnx2x *bp = params->bp;
3531	u16 ld_pause;		/* local */
3532	u16 lp_pause;		/* link partner */
3533	u16 pause_result;
3534	u8 ret = 0;
3535	/* read twice */
3536
3537	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3538
3539	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
3540		vars->flow_ctrl = phy->req_flow_ctrl;
3541	else if (phy->req_line_speed != SPEED_AUTO_NEG)
3542		vars->flow_ctrl = params->req_fc_auto_adv;
3543	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
3544		ret = 1;
3545		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
3546			bnx2x_cl22_read(bp, phy,
3547					0x4, &ld_pause);
3548			bnx2x_cl22_read(bp, phy,
3549					0x5, &lp_pause);
3550		} else {
3551			bnx2x_cl45_read(bp, phy,
3552					MDIO_AN_DEVAD,
3553					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3554			bnx2x_cl45_read(bp, phy,
3555					MDIO_AN_DEVAD,
3556					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3557		}
3558		pause_result = (ld_pause &
3559				MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
3560		pause_result |= (lp_pause &
3561				 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
3562		DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n",
3563		   pause_result);
3564		bnx2x_pause_resolve(vars, pause_result);
3565	}
3566	return ret;
3567}
3568/******************************************************************/
3569/*			Warpcore section			  */
3570/******************************************************************/
3571/* The init_internal_warpcore should mirror the xgxs,
3572 * i.e. reset the lane (if needed), set aer for the
3573 * init configuration, and set/clear SGMII flag. Internal
3574 * phy init is done purely in phy_init stage.
3575 */
3576static void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
3577					struct link_params *params,
3578					struct link_vars *vars) {
3579	u16 val16 = 0, lane, bam37 = 0;
3580	struct bnx2x *bp = params->bp;
3581	DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
3582
3583	/* Disable Autoneg: re-enable it after adv is done. */
3584	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3585			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
3586
3587	/* Check adding advertisement for 1G KX */
3588	if (((vars->line_speed == SPEED_AUTO_NEG) &&
3589	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
3590	    (vars->line_speed == SPEED_1000)) {
3591		u16 sd_digital;
3592		val16 |= (1<<5);
3593
3594		/* Enable CL37 1G Parallel Detect */
3595		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3596			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
3597		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3598			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3599				 (sd_digital | 0x1));
3600
3601		DP(NETIF_MSG_LINK, "Advertize 1G\n");
3602	}
3603	if (((vars->line_speed == SPEED_AUTO_NEG) &&
3604	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
3605	    (vars->line_speed ==  SPEED_10000)) {
3606		/* Check adding advertisement for 10G KR */
3607		val16 |= (1<<7);
3608		/* Enable 10G Parallel Detect */
3609		bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3610				MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
3611
3612		DP(NETIF_MSG_LINK, "Advertize 10G\n");
3613	}
3614
3615	/* Set Transmit PMD settings */
3616	lane = bnx2x_get_warpcore_lane(phy, params);
3617	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3618		      MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3619		     ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3620		      (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3621		      (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3622	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3623			 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
3624			 0x03f0);
3625	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3626			 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
3627			 0x03f0);
3628
3629	/* Advertised speeds */
3630	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3631			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
3632
3633	/* Advertised and set FEC (Forward Error Correction) */
3634	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3635			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
3636			 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
3637			  MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
3638
3639	/* Enable CL37 BAM */
3640	if (REG_RD(bp, params->shmem_base +
3641		   offsetof(struct shmem_region, dev_info.
3642			    port_hw_config[params->port].default_cfg)) &
3643	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3644		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3645				MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
3646		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3647			MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
3648		DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3649	}
3650
3651	/* Advertise pause */
3652	bnx2x_ext_phy_set_pause(params, phy, vars);
3653
3654	vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
3655
3656	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3657			MDIO_WC_REG_DIGITAL5_MISC7, &val16);
3658
3659	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3660			 MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3661
3662	/* Over 1G - AN local device user page 1 */
3663	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3664			MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3665
3666	/* Enable Autoneg */
3667	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3668			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1000);
3669
3670}
3671
3672static void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
3673				      struct link_params *params,
3674				      struct link_vars *vars)
3675{
3676	struct bnx2x *bp = params->bp;
3677	u16 val;
3678
3679	/* Disable Autoneg */
3680	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3681			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
3682
3683	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3684			 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
3685
3686	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3687			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
3688
3689	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3690			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
3691
3692	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3693			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3694
3695	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3696			MDIO_WC_REG_DIGITAL3_UP1, 0x1);
3697
3698	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3699			 MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
3700
3701	/* Disable CL36 PCS Tx */
3702	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3703			MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
3704
3705	/* Double Wide Single Data Rate @ pll rate */
3706	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3707			MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
3708
3709	/* Leave cl72 training enable, needed for KR */
3710	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3711		MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
3712		0x2);
3713
3714	/* Leave CL72 enabled */
3715	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3716			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3717			 &val);
3718	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3719			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
3720			 val | 0x3800);
3721
3722	/* Set speed via PMA/PMD register */
3723	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3724			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
3725
3726	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
3727			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
3728
3729	/*Enable encoded forced speed */
3730	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3731			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
3732
3733	/* Turn TX scramble payload only the 64/66 scrambler */
3734	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3735			 MDIO_WC_REG_TX66_CONTROL, 0x9);
3736
3737	/* Turn RX scramble payload only the 64/66 scrambler */
3738	bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
3739				 MDIO_WC_REG_RX66_CONTROL, 0xF9);
3740
3741	/* set and clear loopback to cause a reset to 64/66 decoder */
3742	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3743			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
3744	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3745			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
3746
3747}
3748
3749static void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
3750				       struct link_params *params,
3751				       u8 is_xfi)
3752{
3753	struct bnx2x *bp = params->bp;
3754	u16 misc1_val, tap_val, tx_driver_val, lane, val;
3755	/* Hold rxSeqStart */
3756	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3757			MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3758	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3759			 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
3760
3761	/* Hold tx_fifo_reset */
3762	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3763			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3764	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3765			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
3766
3767	/* Disable CL73 AN */
3768	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
3769
3770	/* Disable 100FX Enable and Auto-Detect */
3771	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3772			MDIO_WC_REG_FX100_CTRL1, &val);
3773	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3774			 MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
3775
3776	/* Disable 100FX Idle detect */
3777	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3778			MDIO_WC_REG_FX100_CTRL3, &val);
3779	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3780			 MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
3781
3782	/* Set Block address to Remote PHY & Clear forced_speed[5] */
3783	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3784			MDIO_WC_REG_DIGITAL4_MISC3, &val);
3785	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3786			 MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
3787
3788	/* Turn off auto-detect & fiber mode */
3789	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3790			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3791	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3792			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3793			 (val & 0xFFEE));
3794
3795	/* Set filter_force_link, disable_false_link and parallel_detect */
3796	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3797			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
3798	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3799			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
3800			 ((val | 0x0006) & 0xFFFE));
3801
3802	/* Set XFI / SFI */
3803	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3804			MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
3805
3806	misc1_val &= ~(0x1f);
3807
3808	if (is_xfi) {
3809		misc1_val |= 0x5;
3810		tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3811			   (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3812			   (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3813		tx_driver_val =
3814		      ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3815		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3816		       (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3817
3818	} else {
3819		misc1_val |= 0x9;
3820		tap_val = ((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3821			   (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3822			   (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
3823		tx_driver_val =
3824		      ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3825		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3826		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
3827	}
3828	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3829			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
3830
3831	/* Set Transmit PMD settings */
3832	lane = bnx2x_get_warpcore_lane(phy, params);
3833	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3834			 MDIO_WC_REG_TX_FIR_TAP,
3835			 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
3836	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3837			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3838			 tx_driver_val);
3839
3840	/* Enable fiber mode, enable and invert sig_det */
3841	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3842			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
3843	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3844			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
3845
3846	/* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
3847	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3848			MDIO_WC_REG_DIGITAL4_MISC3, &val);
3849	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3850			 MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
3851
3852	/* 10G XFI Full Duplex */
3853	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3854			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
3855
3856	/* Release tx_fifo_reset */
3857	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3858			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
3859	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3860			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
3861
3862	/* Release rxSeqStart */
3863	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3864			MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
3865	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3866			 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
3867}
3868
3869static void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
3870				       struct bnx2x_phy *phy)
3871{
3872	DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
3873}
3874
3875static void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
3876					 struct bnx2x_phy *phy,
3877					 u16 lane)
3878{
3879	/* Rx0 anaRxControl1G */
3880	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3881			 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
3882
3883	/* Rx2 anaRxControl1G */
3884	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3885			 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
3886
3887	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3888			 MDIO_WC_REG_RX66_SCW0, 0xE070);
3889
3890	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3891			 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
3892
3893	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3894			 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
3895
3896	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3897			 MDIO_WC_REG_RX66_SCW3, 0x8090);
3898
3899	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3900			 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
3901
3902	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3903			 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
3904
3905	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3906			 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
3907
3908	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3909			 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
3910
3911	/* Serdes Digital Misc1 */
3912	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3913			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
3914
3915	/* Serdes Digital4 Misc3 */
3916	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3917			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
3918
3919	/* Set Transmit PMD settings */
3920	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3921			 MDIO_WC_REG_TX_FIR_TAP,
3922			((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
3923			 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
3924			 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
3925			 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
3926	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3927		      MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
3928		     ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
3929		      (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
3930		      (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
3931}
3932
3933static void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
3934					   struct link_params *params,
3935					   u8 fiber_mode)
3936{
3937	struct bnx2x *bp = params->bp;
3938	u16 val16, digctrl_kx1, digctrl_kx2;
3939	u8 lane;
3940
3941	lane = bnx2x_get_warpcore_lane(phy, params);
3942
3943	/* Clear XFI clock comp in non-10G single lane mode. */
3944	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3945			MDIO_WC_REG_RX66_CONTROL, &val16);
3946	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3947			 MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
3948
3949	if (phy->req_line_speed == SPEED_AUTO_NEG) {
3950		/* SGMII Autoneg */
3951		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3952				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3953		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3954				 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
3955				 val16 | 0x1000);
3956		DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
3957	} else {
3958		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3959				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3960		val16 &= 0xcfbf;
3961		switch (phy->req_line_speed) {
3962		case SPEED_10:
3963			break;
3964		case SPEED_100:
3965			val16 |= 0x2000;
3966			break;
3967		case SPEED_1000:
3968			val16 |= 0x0040;
3969			break;
3970		default:
3971			DP(NETIF_MSG_LINK,
3972			   "Speed not supported: 0x%x\n", phy->req_line_speed);
3973			return;
3974		}
3975
3976		if (phy->req_duplex == DUPLEX_FULL)
3977			val16 |= 0x0100;
3978
3979		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3980				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
3981
3982		DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
3983			       phy->req_line_speed);
3984		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3985				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
3986		DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
3987	}
3988
3989	/* SGMII Slave mode and disable signal detect */
3990	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3991			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
3992	if (fiber_mode)
3993		digctrl_kx1 = 1;
3994	else
3995		digctrl_kx1 &= 0xff4a;
3996
3997	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3998			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
3999			digctrl_kx1);
4000
4001	/* Turn off parallel detect */
4002	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4003			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
4004	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4005			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4006			(digctrl_kx2 & ~(1<<2)));
4007
4008	/* Re-enable parallel detect */
4009	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4010			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
4011			(digctrl_kx2 | (1<<2)));
4012
4013	/* Enable autodet */
4014	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4015			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
4016			(digctrl_kx1 | 0x10));
4017}
4018
4019static void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
4020				      struct bnx2x_phy *phy,
4021				      u8 reset)
4022{
4023	u16 val;
4024	/* Take lane out of reset after configuration is finished */
4025	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4026			MDIO_WC_REG_DIGITAL5_MISC6, &val);
4027	if (reset)
4028		val |= 0xC000;
4029	else
4030		val &= 0x3FFF;
4031	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4032			 MDIO_WC_REG_DIGITAL5_MISC6, val);
4033	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4034			 MDIO_WC_REG_DIGITAL5_MISC6, &val);
4035}
4036
4037
4038	/* Clear SFI/XFI link settings registers */
4039static void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
4040				      struct link_params *params,
4041				      u16 lane)
4042{
4043	struct bnx2x *bp = params->bp;
4044	u16 val16;
4045
4046	/* Set XFI clock comp as default. */
4047	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4048			MDIO_WC_REG_RX66_CONTROL, &val16);
4049	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4050			 MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
4051
4052	bnx2x_warpcore_reset_lane(bp, phy, 1);
4053	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
4054	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4055			 MDIO_WC_REG_FX100_CTRL1, 0x014a);
4056	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4057			 MDIO_WC_REG_FX100_CTRL3, 0x0800);
4058	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4059			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
4060	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4061			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
4062	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4063			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
4064	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4065			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
4066	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4067			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
4068	lane = bnx2x_get_warpcore_lane(phy, params);
4069	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4070			 MDIO_WC_REG_TX_FIR_TAP, 0x0000);
4071	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4072			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
4073	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4074			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
4075	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4076			 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
4077	bnx2x_warpcore_reset_lane(bp, phy, 0);
4078}
4079
4080static int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
4081						u32 chip_id,
4082						u32 shmem_base, u8 port,
4083						u8 *gpio_num, u8 *gpio_port)
4084{
4085	u32 cfg_pin;
4086	*gpio_num = 0;
4087	*gpio_port = 0;
4088	if (CHIP_IS_E3(bp)) {
4089		cfg_pin = (REG_RD(bp, shmem_base +
4090				offsetof(struct shmem_region,
4091				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4092				PORT_HW_CFG_E3_MOD_ABS_MASK) >>
4093				PORT_HW_CFG_E3_MOD_ABS_SHIFT;
4094
4095		/*
4096		 * Should not happen. This function called upon interrupt
4097		 * triggered by GPIO ( since EPIO can only generate interrupts
4098		 * to MCP).
4099		 * So if this function was called and none of the GPIOs was set,
4100		 * it means the shit hit the fan.
4101		 */
4102		if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
4103		    (cfg_pin > PIN_CFG_GPIO3_P1)) {
4104			DP(NETIF_MSG_LINK,
4105			   "ERROR: Invalid cfg pin %x for module detect indication\n",
4106			   cfg_pin);
4107			return -EINVAL;
4108		}
4109
4110		*gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
4111		*gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
4112	} else {
4113		*gpio_num = MISC_REGISTERS_GPIO_3;
4114		*gpio_port = port;
4115	}
4116	DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
4117	return 0;
4118}
4119
4120static int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
4121				       struct link_params *params)
4122{
4123	struct bnx2x *bp = params->bp;
4124	u8 gpio_num, gpio_port;
4125	u32 gpio_val;
4126	if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
4127				      params->shmem_base, params->port,
4128				      &gpio_num, &gpio_port) != 0)
4129		return 0;
4130	gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
4131
4132	/* Call the handling function in case module is detected */
4133	if (gpio_val == 0)
4134		return 1;
4135	else
4136		return 0;
4137}
4138static int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4139					struct link_params *params)
4140{
4141	u16 gp2_status_reg0, lane;
4142	struct bnx2x *bp = params->bp;
4143
4144	lane = bnx2x_get_warpcore_lane(phy, params);
4145
4146	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4147				 &gp2_status_reg0);
4148
4149	return (gp2_status_reg0 >> (8+lane)) & 0x1;
4150}
4151
4152static void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4153				       struct link_params *params,
4154				       struct link_vars *vars)
4155{
4156	struct bnx2x *bp = params->bp;
4157	u32 serdes_net_if;
4158	u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4159	u16 lane = bnx2x_get_warpcore_lane(phy, params);
4160
4161	vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4162
4163	if (!vars->turn_to_run_wc_rt)
4164		return;
4165
4166	/* return if there is no link partner */
4167	if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4168		DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4169		return;
4170	}
4171
4172	if (vars->rx_tx_asic_rst) {
4173		serdes_net_if = (REG_RD(bp, params->shmem_base +
4174				offsetof(struct shmem_region, dev_info.
4175				port_hw_config[params->port].default_cfg)) &
4176				PORT_HW_CFG_NET_SERDES_IF_MASK);
4177
4178		switch (serdes_net_if) {
4179		case PORT_HW_CFG_NET_SERDES_IF_KR:
4180			/* Do we get link yet? */
4181			bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4182								&gp_status1);
4183			lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4184				/*10G KR*/
4185			lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4186
4187			DP(NETIF_MSG_LINK,
4188				"gp_status1 0x%x\n", gp_status1);
4189
4190			if (lnkup_kr || lnkup) {
4191					vars->rx_tx_asic_rst = 0;
4192					DP(NETIF_MSG_LINK,
4193					"link up, rx_tx_asic_rst 0x%x\n",
4194					vars->rx_tx_asic_rst);
4195			} else {
4196				/*reset the lane to see if link comes up.*/
4197				bnx2x_warpcore_reset_lane(bp, phy, 1);
4198				bnx2x_warpcore_reset_lane(bp, phy, 0);
4199
4200				/* restart Autoneg */
4201				bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4202					MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4203
4204				vars->rx_tx_asic_rst--;
4205				DP(NETIF_MSG_LINK, "0x%x retry left\n",
4206				vars->rx_tx_asic_rst);
4207			}
4208			break;
4209
4210		default:
4211			break;
4212		}
4213
4214	} /*params->rx_tx_asic_rst*/
4215
4216}
4217
4218static void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
4219				       struct link_params *params,
4220				       struct link_vars *vars)
4221{
4222	struct bnx2x *bp = params->bp;
4223	u32 serdes_net_if;
4224	u8 fiber_mode;
4225	u16 lane = bnx2x_get_warpcore_lane(phy, params);
4226	serdes_net_if = (REG_RD(bp, params->shmem_base +
4227			 offsetof(struct shmem_region, dev_info.
4228				  port_hw_config[params->port].default_cfg)) &
4229			 PORT_HW_CFG_NET_SERDES_IF_MASK);
4230	DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
4231			   "serdes_net_if = 0x%x\n",
4232		       vars->line_speed, serdes_net_if);
4233	bnx2x_set_aer_mmd(params, phy);
4234
4235	vars->phy_flags |= PHY_XGXS_FLAG;
4236	if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
4237	    (phy->req_line_speed &&
4238	     ((phy->req_line_speed == SPEED_100) ||
4239	      (phy->req_line_speed == SPEED_10)))) {
4240		vars->phy_flags |= PHY_SGMII_FLAG;
4241		DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
4242		bnx2x_warpcore_clear_regs(phy, params, lane);
4243		bnx2x_warpcore_set_sgmii_speed(phy, params, 0);
4244	} else {
4245		switch (serdes_net_if) {
4246		case PORT_HW_CFG_NET_SERDES_IF_KR:
4247			/* Enable KR Auto Neg */
4248			if (params->loopback_mode == LOOPBACK_NONE)
4249				bnx2x_warpcore_enable_AN_KR(phy, params, vars);
4250			else {
4251				DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
4252				bnx2x_warpcore_set_10G_KR(phy, params, vars);
4253			}
4254			break;
4255
4256		case PORT_HW_CFG_NET_SERDES_IF_XFI:
4257			bnx2x_warpcore_clear_regs(phy, params, lane);
4258			if (vars->line_speed == SPEED_10000) {
4259				DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
4260				bnx2x_warpcore_set_10G_XFI(phy, params, 1);
4261			} else {
4262				if (SINGLE_MEDIA_DIRECT(params)) {
4263					DP(NETIF_MSG_LINK, "1G Fiber\n");
4264					fiber_mode = 1;
4265				} else {
4266					DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
4267					fiber_mode = 0;
4268				}
4269				bnx2x_warpcore_set_sgmii_speed(phy,
4270								params,
4271								fiber_mode);
4272			}
4273
4274			break;
4275
4276		case PORT_HW_CFG_NET_SERDES_IF_SFI:
4277
4278			bnx2x_warpcore_clear_regs(phy, params, lane);
4279			if (vars->line_speed == SPEED_10000) {
4280				DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
4281				bnx2x_warpcore_set_10G_XFI(phy, params, 0);
4282			} else if (vars->line_speed == SPEED_1000) {
4283				DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4284				bnx2x_warpcore_set_sgmii_speed(phy, params, 1);
4285			}
4286			/* Issue Module detection */
4287			if (bnx2x_is_sfp_module_plugged(phy, params))
4288				bnx2x_sfp_module_detection(phy, params);
4289			break;
4290
4291		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
4292			if (vars->line_speed != SPEED_20000) {
4293				DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4294				return;
4295			}
4296			DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
4297			bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
4298			/* Issue Module detection */
4299
4300			bnx2x_sfp_module_detection(phy, params);
4301			break;
4302
4303		case PORT_HW_CFG_NET_SERDES_IF_KR2:
4304			if (vars->line_speed != SPEED_20000) {
4305				DP(NETIF_MSG_LINK, "Speed not supported yet\n");
4306				return;
4307			}
4308			DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
4309			bnx2x_warpcore_set_20G_KR2(bp, phy);
4310			break;
4311
4312		default:
4313			DP(NETIF_MSG_LINK,
4314			   "Unsupported Serdes Net Interface 0x%x\n",
4315			   serdes_net_if);
4316			return;
4317		}
4318	}
4319
4320	/* Take lane out of reset after configuration is finished */
4321	bnx2x_warpcore_reset_lane(bp, phy, 0);
4322	DP(NETIF_MSG_LINK, "Exit config init\n");
4323}
4324
4325static void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
4326					 struct bnx2x_phy *phy,
4327					 u8 tx_en)
4328{
4329	struct bnx2x *bp = params->bp;
4330	u32 cfg_pin;
4331	u8 port = params->port;
4332
4333	cfg_pin = REG_RD(bp, params->shmem_base +
4334				offsetof(struct shmem_region,
4335				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
4336				PORT_HW_CFG_TX_LASER_MASK;
4337	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
4338	DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
4339	/* For 20G, the expected pin to be used is 3 pins after the current */
4340
4341	bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
4342	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
4343		bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
4344}
4345
4346static void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
4347				      struct link_params *params)
4348{
4349	struct bnx2x *bp = params->bp;
4350	u16 val16;
4351	bnx2x_sfp_e3_set_transmitter(params, phy, 0);
4352	bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
4353	bnx2x_set_aer_mmd(params, phy);
4354	/* Global register */
4355	bnx2x_warpcore_reset_lane(bp, phy, 1);
4356
4357	/* Clear loopback settings (if any) */
4358	/* 10G & 20G */
4359	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4360			MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4361	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4362			 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
4363			 0xBFFF);
4364
4365	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4366			MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4367	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4368			MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
4369
4370	/* Update those 1-copy registers */
4371	CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4372			  MDIO_AER_BLOCK_AER_REG, 0);
4373		/* Enable 1G MDIO (1-copy) */
4374	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4375			MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4376			&val16);
4377	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4378			 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4379			 val16 & ~0x10);
4380
4381	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4382			MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4383	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4384			 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4385			 val16 & 0xff00);
4386
4387}
4388
4389static void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
4390					struct link_params *params)
4391{
4392	struct bnx2x *bp = params->bp;
4393	u16 val16;
4394	u32 lane;
4395	DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
4396		       params->loopback_mode, phy->req_line_speed);
4397
4398	if (phy->req_line_speed < SPEED_10000) {
4399		/* 10/100/1000 */
4400
4401		/* Update those 1-copy registers */
4402		CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
4403				  MDIO_AER_BLOCK_AER_REG, 0);
4404		/* Enable 1G MDIO (1-copy) */
4405		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4406				MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4407				&val16);
4408		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4409				MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
4410				val16 | 0x10);
4411		/* Set 1G loopback based on lane (1-copy) */
4412		lane = bnx2x_get_warpcore_lane(phy, params);
4413		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4414				MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
4415		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4416				MDIO_WC_REG_XGXSBLK1_LANECTRL2,
4417				val16 | (1<<lane));
4418
4419		/* Switch back to 4-copy registers */
4420		bnx2x_set_aer_mmd(params, phy);
4421		/* Global loopback, not recommended. */
4422		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4423				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4424		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4425				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4426				0x4000);
4427	} else {
4428		/* 10G & 20G */
4429		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4430				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4431		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4432				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
4433				 0x4000);
4434
4435		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
4436				MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
4437		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
4438				MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
4439	}
4440}
4441
4442
4443void bnx2x_link_status_update(struct link_params *params,
4444			      struct link_vars *vars)
4445{
4446	struct bnx2x *bp = params->bp;
4447	u8 link_10g_plus;
4448	u8 port = params->port;
4449	u32 sync_offset, media_types;
4450	/* Update PHY configuration */
4451	set_phy_vars(params, vars);
4452
4453	vars->link_status = REG_RD(bp, params->shmem_base +
4454				   offsetof(struct shmem_region,
4455					    port_mb[port].link_status));
4456
4457	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4458	vars->phy_flags = PHY_XGXS_FLAG;
4459	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4460		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
4461
4462	if (vars->link_up) {
4463		DP(NETIF_MSG_LINK, "phy link up\n");
4464
4465		vars->phy_link_up = 1;
4466		vars->duplex = DUPLEX_FULL;
4467		switch (vars->link_status &
4468			LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4469			case LINK_10THD:
4470				vars->duplex = DUPLEX_HALF;
4471				/* fall thru */
4472			case LINK_10TFD:
4473				vars->line_speed = SPEED_10;
4474				break;
4475
4476			case LINK_100TXHD:
4477				vars->duplex = DUPLEX_HALF;
4478				/* fall thru */
4479			case LINK_100T4:
4480			case LINK_100TXFD:
4481				vars->line_speed = SPEED_100;
4482				break;
4483
4484			case LINK_1000THD:
4485				vars->duplex = DUPLEX_HALF;
4486				/* fall thru */
4487			case LINK_1000TFD:
4488				vars->line_speed = SPEED_1000;
4489				break;
4490
4491			case LINK_2500THD:
4492				vars->duplex = DUPLEX_HALF;
4493				/* fall thru */
4494			case LINK_2500TFD:
4495				vars->line_speed = SPEED_2500;
4496				break;
4497
4498			case LINK_10GTFD:
4499				vars->line_speed = SPEED_10000;
4500				break;
4501			case LINK_20GTFD:
4502				vars->line_speed = SPEED_20000;
4503				break;
4504			default:
4505				break;
4506		}
4507		vars->flow_ctrl = 0;
4508		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4509			vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4510
4511		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4512			vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4513
4514		if (!vars->flow_ctrl)
4515			vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4516
4517		if (vars->line_speed &&
4518		    ((vars->line_speed == SPEED_10) ||
4519		     (vars->line_speed == SPEED_100))) {
4520			vars->phy_flags |= PHY_SGMII_FLAG;
4521		} else {
4522			vars->phy_flags &= ~PHY_SGMII_FLAG;
4523		}
4524		if (vars->line_speed &&
4525		    USES_WARPCORE(bp) &&
4526		    (vars->line_speed == SPEED_1000))
4527			vars->phy_flags |= PHY_SGMII_FLAG;
4528		/* anything 10 and over uses the bmac */
4529		link_10g_plus = (vars->line_speed >= SPEED_10000);
4530
4531		if (link_10g_plus) {
4532			if (USES_WARPCORE(bp))
4533				vars->mac_type = MAC_TYPE_XMAC;
4534			else
4535				vars->mac_type = MAC_TYPE_BMAC;
4536		} else {
4537			if (USES_WARPCORE(bp))
4538				vars->mac_type = MAC_TYPE_UMAC;
4539			else
4540				vars->mac_type = MAC_TYPE_EMAC;
4541		}
4542	} else { /* link down */
4543		DP(NETIF_MSG_LINK, "phy link down\n");
4544
4545		vars->phy_link_up = 0;
4546
4547		vars->line_speed = 0;
4548		vars->duplex = DUPLEX_FULL;
4549		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4550
4551		/* indicate no mac active */
4552		vars->mac_type = MAC_TYPE_NONE;
4553		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4554			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4555	}
4556
4557	/* Sync media type */
4558	sync_offset = params->shmem_base +
4559			offsetof(struct shmem_region,
4560				 dev_info.port_hw_config[port].media_type);
4561	media_types = REG_RD(bp, sync_offset);
4562
4563	params->phy[INT_PHY].media_type =
4564		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
4565		PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
4566	params->phy[EXT_PHY1].media_type =
4567		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
4568		PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
4569	params->phy[EXT_PHY2].media_type =
4570		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
4571		PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
4572	DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
4573
4574	/* Sync AEU offset */
4575	sync_offset = params->shmem_base +
4576			offsetof(struct shmem_region,
4577				 dev_info.port_hw_config[port].aeu_int_mask);
4578
4579	vars->aeu_int_mask = REG_RD(bp, sync_offset);
4580
4581	/* Sync PFC status */
4582	if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4583		params->feature_config_flags |=
4584					FEATURE_CONFIG_PFC_ENABLED;
4585	else
4586		params->feature_config_flags &=
4587					~FEATURE_CONFIG_PFC_ENABLED;
4588
4589	DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4590		 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4591	DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4592		 vars->line_speed, vars->duplex, vars->flow_ctrl);
4593}
4594
4595
4596static void bnx2x_set_master_ln(struct link_params *params,
4597				struct bnx2x_phy *phy)
4598{
4599	struct bnx2x *bp = params->bp;
4600	u16 new_master_ln, ser_lane;
4601	ser_lane = ((params->lane_config &
4602		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4603		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4604
4605	/* set the master_ln for AN */
4606	CL22_RD_OVER_CL45(bp, phy,
4607			  MDIO_REG_BANK_XGXS_BLOCK2,
4608			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4609			  &new_master_ln);
4610
4611	CL22_WR_OVER_CL45(bp, phy,
4612			  MDIO_REG_BANK_XGXS_BLOCK2 ,
4613			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4614			  (new_master_ln | ser_lane));
4615}
4616
4617static int bnx2x_reset_unicore(struct link_params *params,
4618			       struct bnx2x_phy *phy,
4619			       u8 set_serdes)
4620{
4621	struct bnx2x *bp = params->bp;
4622	u16 mii_control;
4623	u16 i;
4624	CL22_RD_OVER_CL45(bp, phy,
4625			  MDIO_REG_BANK_COMBO_IEEE0,
4626			  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4627
4628	/* reset the unicore */
4629	CL22_WR_OVER_CL45(bp, phy,
4630			  MDIO_REG_BANK_COMBO_IEEE0,
4631			  MDIO_COMBO_IEEE0_MII_CONTROL,
4632			  (mii_control |
4633			   MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4634	if (set_serdes)
4635		bnx2x_set_serdes_access(bp, params->port);
4636
4637	/* wait for the reset to self clear */
4638	for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4639		udelay(5);
4640
4641		/* the reset erased the previous bank value */
4642		CL22_RD_OVER_CL45(bp, phy,
4643				  MDIO_REG_BANK_COMBO_IEEE0,
4644				  MDIO_COMBO_IEEE0_MII_CONTROL,
4645				  &mii_control);
4646
4647		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4648			udelay(5);
4649			return 0;
4650		}
4651	}
4652
4653	netdev_err(bp->dev,  "Warning: PHY was not initialized,"
4654			      " Port %d\n",
4655			 params->port);
4656	DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4657	return -EINVAL;
4658
4659}
4660
4661static void bnx2x_set_swap_lanes(struct link_params *params,
4662				 struct bnx2x_phy *phy)
4663{
4664	struct bnx2x *bp = params->bp;
4665	/*
4666	 *  Each two bits represents a lane number:
4667	 *  No swap is 0123 => 0x1b no need to enable the swap
4668	 */
4669	u16 ser_lane, rx_lane_swap, tx_lane_swap;
4670
4671	ser_lane = ((params->lane_config &
4672		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4673		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4674	rx_lane_swap = ((params->lane_config &
4675			 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4676			PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4677	tx_lane_swap = ((params->lane_config &
4678			 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4679			PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4680
4681	if (rx_lane_swap != 0x1b) {
4682		CL22_WR_OVER_CL45(bp, phy,
4683				  MDIO_REG_BANK_XGXS_BLOCK2,
4684				  MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4685				  (rx_lane_swap |
4686				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4687				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4688	} else {
4689		CL22_WR_OVER_CL45(bp, phy,
4690				  MDIO_REG_BANK_XGXS_BLOCK2,
4691				  MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4692	}
4693
4694	if (tx_lane_swap != 0x1b) {
4695		CL22_WR_OVER_CL45(bp, phy,
4696				  MDIO_REG_BANK_XGXS_BLOCK2,
4697				  MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4698				  (tx_lane_swap |
4699				   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4700	} else {
4701		CL22_WR_OVER_CL45(bp, phy,
4702				  MDIO_REG_BANK_XGXS_BLOCK2,
4703				  MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4704	}
4705}
4706
4707static void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4708					 struct link_params *params)
4709{
4710	struct bnx2x *bp = params->bp;
4711	u16 control2;
4712	CL22_RD_OVER_CL45(bp, phy,
4713			  MDIO_REG_BANK_SERDES_DIGITAL,
4714			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4715			  &control2);
4716	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4717		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4718	else
4719		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
4720	DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
4721		phy->speed_cap_mask, control2);
4722	CL22_WR_OVER_CL45(bp, phy,
4723			  MDIO_REG_BANK_SERDES_DIGITAL,
4724			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4725			  control2);
4726
4727	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4728	     (phy->speed_cap_mask &
4729		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4730		DP(NETIF_MSG_LINK, "XGXS\n");
4731
4732		CL22_WR_OVER_CL45(bp, phy,
4733				 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4734				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4735				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4736
4737		CL22_RD_OVER_CL45(bp, phy,
4738				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4739				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4740				  &control2);
4741
4742
4743		control2 |=
4744		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4745
4746		CL22_WR_OVER_CL45(bp, phy,
4747				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4748				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4749				  control2);
4750
4751		/* Disable parallel detection of HiG */
4752		CL22_WR_OVER_CL45(bp, phy,
4753				  MDIO_REG_BANK_XGXS_BLOCK2,
4754				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4755				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4756				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4757	}
4758}
4759
4760static void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4761			      struct link_params *params,
4762			      struct link_vars *vars,
4763			      u8 enable_cl73)
4764{
4765	struct bnx2x *bp = params->bp;
4766	u16 reg_val;
4767
4768	/* CL37 Autoneg */
4769	CL22_RD_OVER_CL45(bp, phy,
4770			  MDIO_REG_BANK_COMBO_IEEE0,
4771			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4772
4773	/* CL37 Autoneg Enabled */
4774	if (vars->line_speed == SPEED_AUTO_NEG)
4775		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4776	else /* CL37 Autoneg Disabled */
4777		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4778			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4779
4780	CL22_WR_OVER_CL45(bp, phy,
4781			  MDIO_REG_BANK_COMBO_IEEE0,
4782			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4783
4784	/* Enable/Disable Autodetection */
4785
4786	CL22_RD_OVER_CL45(bp, phy,
4787			  MDIO_REG_BANK_SERDES_DIGITAL,
4788			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4789	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4790		    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4791	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
4792	if (vars->line_speed == SPEED_AUTO_NEG)
4793		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4794	else
4795		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4796
4797	CL22_WR_OVER_CL45(bp, phy,
4798			  MDIO_REG_BANK_SERDES_DIGITAL,
4799			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4800
4801	/* Enable TetonII and BAM autoneg */
4802	CL22_RD_OVER_CL45(bp, phy,
4803			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4804			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4805			  &reg_val);
4806	if (vars->line_speed == SPEED_AUTO_NEG) {
4807		/* Enable BAM aneg Mode and TetonII aneg Mode */
4808		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4809			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4810	} else {
4811		/* TetonII and BAM Autoneg Disabled */
4812		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4813			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4814	}
4815	CL22_WR_OVER_CL45(bp, phy,
4816			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4817			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4818			  reg_val);
4819
4820	if (enable_cl73) {
4821		/* Enable Cl73 FSM status bits */
4822		CL22_WR_OVER_CL45(bp, phy,
4823				  MDIO_REG_BANK_CL73_USERB0,
4824				  MDIO_CL73_USERB0_CL73_UCTRL,
4825				  0xe);
4826
4827		/* Enable BAM Station Manager*/
4828		CL22_WR_OVER_CL45(bp, phy,
4829			MDIO_REG_BANK_CL73_USERB0,
4830			MDIO_CL73_USERB0_CL73_BAM_CTRL1,
4831			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
4832			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
4833			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
4834
4835		/* Advertise CL73 link speeds */
4836		CL22_RD_OVER_CL45(bp, phy,
4837				  MDIO_REG_BANK_CL73_IEEEB1,
4838				  MDIO_CL73_IEEEB1_AN_ADV2,
4839				  &reg_val);
4840		if (phy->speed_cap_mask &
4841		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4842			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
4843		if (phy->speed_cap_mask &
4844		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
4845			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
4846
4847		CL22_WR_OVER_CL45(bp, phy,
4848				  MDIO_REG_BANK_CL73_IEEEB1,
4849				  MDIO_CL73_IEEEB1_AN_ADV2,
4850				  reg_val);
4851
4852		/* CL73 Autoneg Enabled */
4853		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
4854
4855	} else /* CL73 Autoneg Disabled */
4856		reg_val = 0;
4857
4858	CL22_WR_OVER_CL45(bp, phy,
4859			  MDIO_REG_BANK_CL73_IEEEB0,
4860			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
4861}
4862
4863/* program SerDes, forced speed */
4864static void bnx2x_program_serdes(struct bnx2x_phy *phy,
4865				 struct link_params *params,
4866				 struct link_vars *vars)
4867{
4868	struct bnx2x *bp = params->bp;
4869	u16 reg_val;
4870
4871	/* program duplex, disable autoneg and sgmii*/
4872	CL22_RD_OVER_CL45(bp, phy,
4873			  MDIO_REG_BANK_COMBO_IEEE0,
4874			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4875	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
4876		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4877		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
4878	if (phy->req_duplex == DUPLEX_FULL)
4879		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
4880	CL22_WR_OVER_CL45(bp, phy,
4881			  MDIO_REG_BANK_COMBO_IEEE0,
4882			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4883
4884	/*
4885	 * program speed
4886	 *  - needed only if the speed is greater than 1G (2.5G or 10G)
4887	 */
4888	CL22_RD_OVER_CL45(bp, phy,
4889			  MDIO_REG_BANK_SERDES_DIGITAL,
4890			  MDIO_SERDES_DIGITAL_MISC1, &reg_val);
4891	/* clearing the speed value before setting the right speed */
4892	DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
4893
4894	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
4895		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4896
4897	if (!((vars->line_speed == SPEED_1000) ||
4898	      (vars->line_speed == SPEED_100) ||
4899	      (vars->line_speed == SPEED_10))) {
4900
4901		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
4902			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
4903		if (vars->line_speed == SPEED_10000)
4904			reg_val |=
4905				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
4906	}
4907
4908	CL22_WR_OVER_CL45(bp, phy,
4909			  MDIO_REG_BANK_SERDES_DIGITAL,
4910			  MDIO_SERDES_DIGITAL_MISC1, reg_val);
4911
4912}
4913
4914static void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
4915					      struct link_params *params)
4916{
4917	struct bnx2x *bp = params->bp;
4918	u16 val = 0;
4919
4920	/* configure the 48 bits for BAM AN */
4921
4922	/* set extended capabilities */
4923	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
4924		val |= MDIO_OVER_1G_UP1_2_5G;
4925	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
4926		val |= MDIO_OVER_1G_UP1_10G;
4927	CL22_WR_OVER_CL45(bp, phy,
4928			  MDIO_REG_BANK_OVER_1G,
4929			  MDIO_OVER_1G_UP1, val);
4930
4931	CL22_WR_OVER_CL45(bp, phy,
4932			  MDIO_REG_BANK_OVER_1G,
4933			  MDIO_OVER_1G_UP3, 0x400);
4934}
4935
4936static void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
4937					      struct link_params *params,
4938					      u16 ieee_fc)
4939{
4940	struct bnx2x *bp = params->bp;
4941	u16 val;
4942	/* for AN, we are always publishing full duplex */
4943
4944	CL22_WR_OVER_CL45(bp, phy,
4945			  MDIO_REG_BANK_COMBO_IEEE0,
4946			  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
4947	CL22_RD_OVER_CL45(bp, phy,
4948			  MDIO_REG_BANK_CL73_IEEEB1,
4949			  MDIO_CL73_IEEEB1_AN_ADV1, &val);
4950	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
4951	val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
4952	CL22_WR_OVER_CL45(bp, phy,
4953			  MDIO_REG_BANK_CL73_IEEEB1,
4954			  MDIO_CL73_IEEEB1_AN_ADV1, val);
4955}
4956
4957static void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
4958				  struct link_params *params,
4959				  u8 enable_cl73)
4960{
4961	struct bnx2x *bp = params->bp;
4962	u16 mii_control;
4963
4964	DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
4965	/* Enable and restart BAM/CL37 aneg */
4966
4967	if (enable_cl73) {
4968		CL22_RD_OVER_CL45(bp, phy,
4969				  MDIO_REG_BANK_CL73_IEEEB0,
4970				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4971				  &mii_control);
4972
4973		CL22_WR_OVER_CL45(bp, phy,
4974				  MDIO_REG_BANK_CL73_IEEEB0,
4975				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
4976				  (mii_control |
4977				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
4978				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
4979	} else {
4980
4981		CL22_RD_OVER_CL45(bp, phy,
4982				  MDIO_REG_BANK_COMBO_IEEE0,
4983				  MDIO_COMBO_IEEE0_MII_CONTROL,
4984				  &mii_control);
4985		DP(NETIF_MSG_LINK,
4986			 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
4987			 mii_control);
4988		CL22_WR_OVER_CL45(bp, phy,
4989				  MDIO_REG_BANK_COMBO_IEEE0,
4990				  MDIO_COMBO_IEEE0_MII_CONTROL,
4991				  (mii_control |
4992				   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4993				   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
4994	}
4995}
4996
4997static void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
4998					   struct link_params *params,
4999					   struct link_vars *vars)
5000{
5001	struct bnx2x *bp = params->bp;
5002	u16 control1;
5003
5004	/* in SGMII mode, the unicore is always slave */
5005
5006	CL22_RD_OVER_CL45(bp, phy,
5007			  MDIO_REG_BANK_SERDES_DIGITAL,
5008			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5009			  &control1);
5010	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
5011	/* set sgmii mode (and not fiber) */
5012	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
5013		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
5014		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
5015	CL22_WR_OVER_CL45(bp, phy,
5016			  MDIO_REG_BANK_SERDES_DIGITAL,
5017			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5018			  control1);
5019
5020	/* if forced speed */
5021	if (!(vars->line_speed == SPEED_AUTO_NEG)) {
5022		/* set speed, disable autoneg */
5023		u16 mii_control;
5024
5025		CL22_RD_OVER_CL45(bp, phy,
5026				  MDIO_REG_BANK_COMBO_IEEE0,
5027				  MDIO_COMBO_IEEE0_MII_CONTROL,
5028				  &mii_control);
5029		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5030				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
5031				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
5032
5033		switch (vars->line_speed) {
5034		case SPEED_100:
5035			mii_control |=
5036				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5037			break;
5038		case SPEED_1000:
5039			mii_control |=
5040				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5041			break;
5042		case SPEED_10:
5043			/* there is nothing to set for 10M */
5044			break;
5045		default:
5046			/* invalid speed for SGMII */
5047			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5048				  vars->line_speed);
5049			break;
5050		}
5051
5052		/* setting the full duplex */
5053		if (phy->req_duplex == DUPLEX_FULL)
5054			mii_control |=
5055				MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5056		CL22_WR_OVER_CL45(bp, phy,
5057				  MDIO_REG_BANK_COMBO_IEEE0,
5058				  MDIO_COMBO_IEEE0_MII_CONTROL,
5059				  mii_control);
5060
5061	} else { /* AN mode */
5062		/* enable and restart AN */
5063		bnx2x_restart_autoneg(phy, params, 0);
5064	}
5065}
5066
5067
5068/*
5069 * link management
5070 */
5071
5072static int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5073					     struct link_params *params)
5074{
5075	struct bnx2x *bp = params->bp;
5076	u16 pd_10g, status2_1000x;
5077	if (phy->req_line_speed != SPEED_AUTO_NEG)
5078		return 0;
5079	CL22_RD_OVER_CL45(bp, phy,
5080			  MDIO_REG_BANK_SERDES_DIGITAL,
5081			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5082			  &status2_1000x);
5083	CL22_RD_OVER_CL45(bp, phy,
5084			  MDIO_REG_BANK_SERDES_DIGITAL,
5085			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5086			  &status2_1000x);
5087	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
5088		DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
5089			 params->port);
5090		return 1;
5091	}
5092
5093	CL22_RD_OVER_CL45(bp, phy,
5094			  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5095			  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5096			  &pd_10g);
5097
5098	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
5099		DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
5100			 params->port);
5101		return 1;
5102	}
5103	return 0;
5104}
5105
5106static void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5107				    struct link_params *params,
5108				    struct link_vars *vars,
5109				    u32 gp_status)
5110{
5111	struct bnx2x *bp = params->bp;
5112	u16 ld_pause;   /* local driver */
5113	u16 lp_pause;   /* link partner */
5114	u16 pause_result;
5115
5116	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5117
5118	/* resolve from gp_status in case of AN complete and not sgmii */
5119	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO)
5120		vars->flow_ctrl = phy->req_flow_ctrl;
5121	else if (phy->req_line_speed != SPEED_AUTO_NEG)
5122		vars->flow_ctrl = params->req_fc_auto_adv;
5123	else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
5124		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5125		if (bnx2x_direct_parallel_detect_used(phy, params)) {
5126			vars->flow_ctrl = params->req_fc_auto_adv;
5127			return;
5128		}
5129		if ((gp_status &
5130		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5131		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
5132		    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
5133		     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
5134
5135			CL22_RD_OVER_CL45(bp, phy,
5136					  MDIO_REG_BANK_CL73_IEEEB1,
5137					  MDIO_CL73_IEEEB1_AN_ADV1,
5138					  &ld_pause);
5139			CL22_RD_OVER_CL45(bp, phy,
5140					  MDIO_REG_BANK_CL73_IEEEB1,
5141					  MDIO_CL73_IEEEB1_AN_LP_ADV1,
5142					  &lp_pause);
5143			pause_result = (ld_pause &
5144					MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK)
5145					>> 8;
5146			pause_result |= (lp_pause &
5147					MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK)
5148					>> 10;
5149			DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n",
5150				 pause_result);
5151		} else {
5152			CL22_RD_OVER_CL45(bp, phy,
5153					  MDIO_REG_BANK_COMBO_IEEE0,
5154					  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
5155					  &ld_pause);
5156			CL22_RD_OVER_CL45(bp, phy,
5157				MDIO_REG_BANK_COMBO_IEEE0,
5158				MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
5159				&lp_pause);
5160			pause_result = (ld_pause &
5161				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
5162			pause_result |= (lp_pause &
5163				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
5164			DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n",
5165				 pause_result);
5166		}
5167		bnx2x_pause_resolve(vars, pause_result);
5168	}
5169	DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5170}
5171
5172static void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5173					 struct link_params *params)
5174{
5175	struct bnx2x *bp = params->bp;
5176	u16 rx_status, ustat_val, cl37_fsm_received;
5177	DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5178	/* Step 1: Make sure signal is detected */
5179	CL22_RD_OVER_CL45(bp, phy,
5180			  MDIO_REG_BANK_RX0,
5181			  MDIO_RX0_RX_STATUS,
5182			  &rx_status);
5183	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5184	    (MDIO_RX0_RX_STATUS_SIGDET)) {
5185		DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5186			     "rx_status(0x80b0) = 0x%x\n", rx_status);
5187		CL22_WR_OVER_CL45(bp, phy,
5188				  MDIO_REG_BANK_CL73_IEEEB0,
5189				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5190				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5191		return;
5192	}
5193	/* Step 2: Check CL73 state machine */
5194	CL22_RD_OVER_CL45(bp, phy,
5195			  MDIO_REG_BANK_CL73_USERB0,
5196			  MDIO_CL73_USERB0_CL73_USTAT1,
5197			  &ustat_val);
5198	if ((ustat_val &
5199	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5200	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5201	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5202	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5203		DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5204			     "ustat_val(0x8371) = 0x%x\n", ustat_val);
5205		return;
5206	}
5207	/*
5208	 * Step 3: Check CL37 Message Pages received to indicate LP
5209	 * supports only CL37
5210	 */
5211	CL22_RD_OVER_CL45(bp, phy,
5212			  MDIO_REG_BANK_REMOTE_PHY,
5213			  MDIO_REMOTE_PHY_MISC_RX_STATUS,
5214			  &cl37_fsm_received);
5215	if ((cl37_fsm_received &
5216	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5217	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5218	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5219	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5220		DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5221			     "misc_rx_status(0x8330) = 0x%x\n",
5222			 cl37_fsm_received);
5223		return;
5224	}
5225	/*
5226	 * The combined cl37/cl73 fsm state information indicating that
5227	 * we are connected to a device which does not support cl73, but
5228	 * does support cl37 BAM. In this case we disable cl73 and
5229	 * restart cl37 auto-neg
5230	 */
5231
5232	/* Disable CL73 */
5233	CL22_WR_OVER_CL45(bp, phy,
5234			  MDIO_REG_BANK_CL73_IEEEB0,
5235			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5236			  0);
5237	/* Restart CL37 autoneg */
5238	bnx2x_restart_autoneg(phy, params, 0);
5239	DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5240}
5241
5242static void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
5243				  struct link_params *params,
5244				  struct link_vars *vars,
5245				  u32 gp_status)
5246{
5247	if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
5248		vars->link_status |=
5249			LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5250
5251	if (bnx2x_direct_parallel_detect_used(phy, params))
5252		vars->link_status |=
5253			LINK_STATUS_PARALLEL_DETECTION_USED;
5254}
5255static int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
5256				     struct link_params *params,
5257				      struct link_vars *vars,
5258				      u16 is_link_up,
5259				      u16 speed_mask,
5260				      u16 is_duplex)
5261{
5262	struct bnx2x *bp = params->bp;
5263	if (phy->req_line_speed == SPEED_AUTO_NEG)
5264		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
5265	if (is_link_up) {
5266		DP(NETIF_MSG_LINK, "phy link up\n");
5267
5268		vars->phy_link_up = 1;
5269		vars->link_status |= LINK_STATUS_LINK_UP;
5270
5271		switch (speed_mask) {
5272		case GP_STATUS_10M:
5273			vars->line_speed = SPEED_10;
5274			if (vars->duplex == DUPLEX_FULL)
5275				vars->link_status |= LINK_10TFD;
5276			else
5277				vars->link_status |= LINK_10THD;
5278			break;
5279
5280		case GP_STATUS_100M:
5281			vars->line_speed = SPEED_100;
5282			if (vars->duplex == DUPLEX_FULL)
5283				vars->link_status |= LINK_100TXFD;
5284			else
5285				vars->link_status |= LINK_100TXHD;
5286			break;
5287
5288		case GP_STATUS_1G:
5289		case GP_STATUS_1G_KX:
5290			vars->line_speed = SPEED_1000;
5291			if (vars->duplex == DUPLEX_FULL)
5292				vars->link_status |= LINK_1000TFD;
5293			else
5294				vars->link_status |= LINK_1000THD;
5295			break;
5296
5297		case GP_STATUS_2_5G:
5298			vars->line_speed = SPEED_2500;
5299			if (vars->duplex == DUPLEX_FULL)
5300				vars->link_status |= LINK_2500TFD;
5301			else
5302				vars->link_status |= LINK_2500THD;
5303			break;
5304
5305		case GP_STATUS_5G:
5306		case GP_STATUS_6G:
5307			DP(NETIF_MSG_LINK,
5308				 "link speed unsupported  gp_status 0x%x\n",
5309				  speed_mask);
5310			return -EINVAL;
5311
5312		case GP_STATUS_10G_KX4:
5313		case GP_STATUS_10G_HIG:
5314		case GP_STATUS_10G_CX4:
5315		case GP_STATUS_10G_KR:
5316		case GP_STATUS_10G_SFI:
5317		case GP_STATUS_10G_XFI:
5318			vars->line_speed = SPEED_10000;
5319			vars->link_status |= LINK_10GTFD;
5320			break;
5321		case GP_STATUS_20G_DXGXS:
5322			vars->line_speed = SPEED_20000;
5323			vars->link_status |= LINK_20GTFD;
5324			break;
5325		default:
5326			DP(NETIF_MSG_LINK,
5327				  "link speed unsupported gp_status 0x%x\n",
5328				  speed_mask);
5329			return -EINVAL;
5330		}
5331	} else { /* link_down */
5332		DP(NETIF_MSG_LINK, "phy link down\n");
5333
5334		vars->phy_link_up = 0;
5335
5336		vars->duplex = DUPLEX_FULL;
5337		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5338		vars->mac_type = MAC_TYPE_NONE;
5339	}
5340	DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
5341		    vars->phy_link_up, vars->line_speed);
5342	return 0;
5343}
5344
5345static int bnx2x_link_settings_status(struct bnx2x_phy *phy,
5346				      struct link_params *params,
5347				      struct link_vars *vars)
5348{
5349
5350	struct bnx2x *bp = params->bp;
5351
5352	u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
5353	int rc = 0;
5354
5355	/* Read gp_status */
5356	CL22_RD_OVER_CL45(bp, phy,
5357			  MDIO_REG_BANK_GP_STATUS,
5358			  MDIO_GP_STATUS_TOP_AN_STATUS1,
5359			  &gp_status);
5360	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
5361		duplex = DUPLEX_FULL;
5362	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
5363		link_up = 1;
5364	speed_mask = gp_status & GP_STATUS_SPEED_MASK;
5365	DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
5366		       gp_status, link_up, speed_mask);
5367	rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
5368					 duplex);
5369	if (rc == -EINVAL)
5370		return rc;
5371
5372	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
5373		if (SINGLE_MEDIA_DIRECT(params)) {
5374			bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
5375			if (phy->req_line_speed == SPEED_AUTO_NEG)
5376				bnx2x_xgxs_an_resolve(phy, params, vars,
5377						      gp_status);
5378		}
5379	} else { /* link_down */
5380		if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5381		    SINGLE_MEDIA_DIRECT(params)) {
5382			/* Check signal is detected */
5383			bnx2x_check_fallback_to_cl37(phy, params);
5384		}
5385	}
5386
5387	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5388		   vars->duplex, vars->flow_ctrl, vars->link_status);
5389	return rc;
5390}
5391
5392static int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
5393				     struct link_params *params,
5394				     struct link_vars *vars)
5395{
5396
5397	struct bnx2x *bp = params->bp;
5398
5399	u8 lane;
5400	u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
5401	int rc = 0;
5402	lane = bnx2x_get_warpcore_lane(phy, params);
5403	/* Read gp_status */
5404	if (phy->req_line_speed > SPEED_10000) {
5405		u16 temp_link_up;
5406		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5407				1, &temp_link_up);
5408		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5409				1, &link_up);
5410		DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
5411			       temp_link_up, link_up);
5412		link_up &= (1<<2);
5413		if (link_up)
5414			bnx2x_ext_phy_resolve_fc(phy, params, vars);
5415	} else {
5416		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5417				MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
5418		DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
5419		/* Check for either KR or generic link up. */
5420		gp_status1 = ((gp_status1 >> 8) & 0xf) |
5421			((gp_status1 >> 12) & 0xf);
5422		link_up = gp_status1 & (1 << lane);
5423		if (link_up && SINGLE_MEDIA_DIRECT(params)) {
5424			u16 pd, gp_status4;
5425			if (phy->req_line_speed == SPEED_AUTO_NEG) {
5426				/* Check Autoneg complete */
5427				bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5428						MDIO_WC_REG_GP2_STATUS_GP_2_4,
5429						&gp_status4);
5430				if (gp_status4 & ((1<<12)<<lane))
5431					vars->link_status |=
5432					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
5433
5434				/* Check parallel detect used */
5435				bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5436						MDIO_WC_REG_PAR_DET_10G_STATUS,
5437						&pd);
5438				if (pd & (1<<15))
5439					vars->link_status |=
5440					LINK_STATUS_PARALLEL_DETECTION_USED;
5441			}
5442			bnx2x_ext_phy_resolve_fc(phy, params, vars);
5443		}
5444	}
5445
5446	if (lane < 2) {
5447		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5448				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
5449	} else {
5450		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
5451				MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
5452	}
5453	DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
5454
5455	if ((lane & 1) == 0)
5456		gp_speed <<= 8;
5457	gp_speed &= 0x3f00;
5458
5459
5460	rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
5461					 duplex);
5462
5463	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5464		   vars->duplex, vars->flow_ctrl, vars->link_status);
5465	return rc;
5466}
5467static void bnx2x_set_gmii_tx_driver(struct link_params *params)
5468{
5469	struct bnx2x *bp = params->bp;
5470	struct bnx2x_phy *phy = &params->phy[INT_PHY];
5471	u16 lp_up2;
5472	u16 tx_driver;
5473	u16 bank;
5474
5475	/* read precomp */
5476	CL22_RD_OVER_CL45(bp, phy,
5477			  MDIO_REG_BANK_OVER_1G,
5478			  MDIO_OVER_1G_LP_UP2, &lp_up2);
5479
5480	/* bits [10:7] at lp_up2, positioned at [15:12] */
5481	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5482		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5483		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5484
5485	if (lp_up2 == 0)
5486		return;
5487
5488	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5489	      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5490		CL22_RD_OVER_CL45(bp, phy,
5491				  bank,
5492				  MDIO_TX0_TX_DRIVER, &tx_driver);
5493
5494		/* replace tx_driver bits [15:12] */
5495		if (lp_up2 !=
5496		    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5497			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5498			tx_driver |= lp_up2;
5499			CL22_WR_OVER_CL45(bp, phy,
5500					  bank,
5501					  MDIO_TX0_TX_DRIVER, tx_driver);
5502		}
5503	}
5504}
5505
5506static int bnx2x_emac_program(struct link_params *params,
5507			      struct link_vars *vars)
5508{
5509	struct bnx2x *bp = params->bp;
5510	u8 port = params->port;
5511	u16 mode = 0;
5512
5513	DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5514	bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5515		       EMAC_REG_EMAC_MODE,
5516		       (EMAC_MODE_25G_MODE |
5517			EMAC_MODE_PORT_MII_10M |
5518			EMAC_MODE_HALF_DUPLEX));
5519	switch (vars->line_speed) {
5520	case SPEED_10:
5521		mode |= EMAC_MODE_PORT_MII_10M;
5522		break;
5523
5524	case SPEED_100:
5525		mode |= EMAC_MODE_PORT_MII;
5526		break;
5527
5528	case SPEED_1000:
5529		mode |= EMAC_MODE_PORT_GMII;
5530		break;
5531
5532	case SPEED_2500:
5533		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5534		break;
5535
5536	default:
5537		/* 10G not valid for EMAC */
5538		DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5539			   vars->line_speed);
5540		return -EINVAL;
5541	}
5542
5543	if (vars->duplex == DUPLEX_HALF)
5544		mode |= EMAC_MODE_HALF_DUPLEX;
5545	bnx2x_bits_en(bp,
5546		      GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5547		      mode);
5548
5549	bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5550	return 0;
5551}
5552
5553static void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5554				  struct link_params *params)
5555{
5556
5557	u16 bank, i = 0;
5558	struct bnx2x *bp = params->bp;
5559
5560	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5561	      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5562			CL22_WR_OVER_CL45(bp, phy,
5563					  bank,
5564					  MDIO_RX0_RX_EQ_BOOST,
5565					  phy->rx_preemphasis[i]);
5566	}
5567
5568	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5569		      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5570			CL22_WR_OVER_CL45(bp, phy,
5571					  bank,
5572					  MDIO_TX0_TX_DRIVER,
5573					  phy->tx_preemphasis[i]);
5574	}
5575}
5576
5577static void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5578				   struct link_params *params,
5579				   struct link_vars *vars)
5580{
5581	struct bnx2x *bp = params->bp;
5582	u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5583			  (params->loopback_mode == LOOPBACK_XGXS));
5584	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5585		if (SINGLE_MEDIA_DIRECT(params) &&
5586		    (params->feature_config_flags &
5587		     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5588			bnx2x_set_preemphasis(phy, params);
5589
5590		/* forced speed requested? */
5591		if (vars->line_speed != SPEED_AUTO_NEG ||
5592		    (SINGLE_MEDIA_DIRECT(params) &&
5593		     params->loopback_mode == LOOPBACK_EXT)) {
5594			DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5595
5596			/* disable autoneg */
5597			bnx2x_set_autoneg(phy, params, vars, 0);
5598
5599			/* program speed and duplex */
5600			bnx2x_program_serdes(phy, params, vars);
5601
5602		} else { /* AN_mode */
5603			DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5604
5605			/* AN enabled */
5606			bnx2x_set_brcm_cl37_advertisement(phy, params);
5607
5608			/* program duplex & pause advertisement (for aneg) */
5609			bnx2x_set_ieee_aneg_advertisement(phy, params,
5610							  vars->ieee_fc);
5611
5612			/* enable autoneg */
5613			bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5614
5615			/* enable and restart AN */
5616			bnx2x_restart_autoneg(phy, params, enable_cl73);
5617		}
5618
5619	} else { /* SGMII mode */
5620		DP(NETIF_MSG_LINK, "SGMII\n");
5621
5622		bnx2x_initialize_sgmii_process(phy, params, vars);
5623	}
5624}
5625
5626static int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5627			  struct link_params *params,
5628			  struct link_vars *vars)
5629{
5630	int rc;
5631	vars->phy_flags |= PHY_XGXS_FLAG;
5632	if ((phy->req_line_speed &&
5633	     ((phy->req_line_speed == SPEED_100) ||
5634	      (phy->req_line_speed == SPEED_10))) ||
5635	    (!phy->req_line_speed &&
5636	     (phy->speed_cap_mask >=
5637	      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5638	     (phy->speed_cap_mask <
5639	      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5640	    (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5641		vars->phy_flags |= PHY_SGMII_FLAG;
5642	else
5643		vars->phy_flags &= ~PHY_SGMII_FLAG;
5644
5645	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5646	bnx2x_set_aer_mmd(params, phy);
5647	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5648		bnx2x_set_master_ln(params, phy);
5649
5650	rc = bnx2x_reset_unicore(params, phy, 0);
5651	/* reset the SerDes and wait for reset bit return low */
5652	if (rc != 0)
5653		return rc;
5654
5655	bnx2x_set_aer_mmd(params, phy);
5656	/* setting the masterLn_def again after the reset */
5657	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5658		bnx2x_set_master_ln(params, phy);
5659		bnx2x_set_swap_lanes(params, phy);
5660	}
5661
5662	return rc;
5663}
5664
5665static u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
5666				     struct bnx2x_phy *phy,
5667				     struct link_params *params)
5668{
5669	u16 cnt, ctrl;
5670	/* Wait for soft reset to get cleared up to 1 sec */
5671	for (cnt = 0; cnt < 1000; cnt++) {
5672		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
5673			bnx2x_cl22_read(bp, phy,
5674				MDIO_PMA_REG_CTRL, &ctrl);
5675		else
5676			bnx2x_cl45_read(bp, phy,
5677				MDIO_PMA_DEVAD,
5678				MDIO_PMA_REG_CTRL, &ctrl);
5679		if (!(ctrl & (1<<15)))
5680			break;
5681		msleep(1);
5682	}
5683
5684	if (cnt == 1000)
5685		netdev_err(bp->dev,  "Warning: PHY was not initialized,"
5686				      " Port %d\n",
5687			 params->port);
5688	DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5689	return cnt;
5690}
5691
5692static void bnx2x_link_int_enable(struct link_params *params)
5693{
5694	u8 port = params->port;
5695	u32 mask;
5696	struct bnx2x *bp = params->bp;
5697
5698	/* Setting the status to report on link up for either XGXS or SerDes */
5699	if (CHIP_IS_E3(bp)) {
5700		mask = NIG_MASK_XGXS0_LINK_STATUS;
5701		if (!(SINGLE_MEDIA_DIRECT(params)))
5702			mask |= NIG_MASK_MI_INT;
5703	} else if (params->switch_cfg == SWITCH_CFG_10G) {
5704		mask = (NIG_MASK_XGXS0_LINK10G |
5705			NIG_MASK_XGXS0_LINK_STATUS);
5706		DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5707		if (!(SINGLE_MEDIA_DIRECT(params)) &&
5708			params->phy[INT_PHY].type !=
5709				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5710			mask |= NIG_MASK_MI_INT;
5711			DP(NETIF_MSG_LINK, "enabled external phy int\n");
5712		}
5713
5714	} else { /* SerDes */
5715		mask = NIG_MASK_SERDES0_LINK_STATUS;
5716		DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5717		if (!(SINGLE_MEDIA_DIRECT(params)) &&
5718			params->phy[INT_PHY].type !=
5719				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5720			mask |= NIG_MASK_MI_INT;
5721			DP(NETIF_MSG_LINK, "enabled external phy int\n");
5722		}
5723	}
5724	bnx2x_bits_en(bp,
5725		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5726		      mask);
5727
5728	DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5729		 (params->switch_cfg == SWITCH_CFG_10G),
5730		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5731	DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5732		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5733		 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5734		 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5735	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5736	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5737	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5738}
5739
5740static void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5741				     u8 exp_mi_int)
5742{
5743	u32 latch_status = 0;
5744
5745	/*
5746	 * Disable the MI INT ( external phy int ) by writing 1 to the
5747	 * status register. Link down indication is high-active-signal,
5748	 * so in this case we need to write the status to clear the XOR
5749	 */
5750	/* Read Latched signals */
5751	latch_status = REG_RD(bp,
5752				    NIG_REG_LATCH_STATUS_0 + port*8);
5753	DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5754	/* Handle only those with latched-signal=up.*/
5755	if (exp_mi_int)
5756		bnx2x_bits_en(bp,
5757			      NIG_REG_STATUS_INTERRUPT_PORT0
5758			      + port*4,
5759			      NIG_STATUS_EMAC0_MI_INT);
5760	else
5761		bnx2x_bits_dis(bp,
5762			       NIG_REG_STATUS_INTERRUPT_PORT0
5763			       + port*4,
5764			       NIG_STATUS_EMAC0_MI_INT);
5765
5766	if (latch_status & 1) {
5767
5768		/* For all latched-signal=up : Re-Arm Latch signals */
5769		REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
5770		       (latch_status & 0xfffe) | (latch_status & 1));
5771	}
5772	/* For all latched-signal=up,Write original_signal to status */
5773}
5774
5775static void bnx2x_link_int_ack(struct link_params *params,
5776			       struct link_vars *vars, u8 is_10g_plus)
5777{
5778	struct bnx2x *bp = params->bp;
5779	u8 port = params->port;
5780	u32 mask;
5781	/*
5782	 * First reset all status we assume only one line will be
5783	 * change at a time
5784	 */
5785	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5786		       (NIG_STATUS_XGXS0_LINK10G |
5787			NIG_STATUS_XGXS0_LINK_STATUS |
5788			NIG_STATUS_SERDES0_LINK_STATUS));
5789	if (vars->phy_link_up) {
5790		if (USES_WARPCORE(bp))
5791			mask = NIG_STATUS_XGXS0_LINK_STATUS;
5792		else {
5793			if (is_10g_plus)
5794				mask = NIG_STATUS_XGXS0_LINK10G;
5795			else if (params->switch_cfg == SWITCH_CFG_10G) {
5796				/*
5797				 * Disable the link interrupt by writing 1 to
5798				 * the relevant lane in the status register
5799				 */
5800				u32 ser_lane =
5801					((params->lane_config &
5802				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
5803				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
5804				mask = ((1 << ser_lane) <<
5805				       NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
5806			} else
5807				mask = NIG_STATUS_SERDES0_LINK_STATUS;
5808		}
5809		DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
5810			       mask);
5811		bnx2x_bits_en(bp,
5812			      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
5813			      mask);
5814	}
5815}
5816
5817static int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
5818{
5819	u8 *str_ptr = str;
5820	u32 mask = 0xf0000000;
5821	u8 shift = 8*4;
5822	u8 digit;
5823	u8 remove_leading_zeros = 1;
5824	if (*len < 10) {
5825		/* Need more than 10chars for this format */
5826		*str_ptr = '\0';
5827		(*len)--;
5828		return -EINVAL;
5829	}
5830	while (shift > 0) {
5831
5832		shift -= 4;
5833		digit = ((num & mask) >> shift);
5834		if (digit == 0 && remove_leading_zeros) {
5835			mask = mask >> 4;
5836			continue;
5837		} else if (digit < 0xa)
5838			*str_ptr = digit + '0';
5839		else
5840			*str_ptr = digit - 0xa + 'a';
5841		remove_leading_zeros = 0;
5842		str_ptr++;
5843		(*len)--;
5844		mask = mask >> 4;
5845		if (shift == 4*4) {
5846			*str_ptr = '.';
5847			str_ptr++;
5848			(*len)--;
5849			remove_leading_zeros = 1;
5850		}
5851	}
5852	return 0;
5853}
5854
5855
5856static int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
5857{
5858	str[0] = '\0';
5859	(*len)--;
5860	return 0;
5861}
5862
5863int bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
5864				 u8 *version, u16 len)
5865{
5866	struct bnx2x *bp;
5867	u32 spirom_ver = 0;
5868	int status = 0;
5869	u8 *ver_p = version;
5870	u16 remain_len = len;
5871	if (version == NULL || params == NULL)
5872		return -EINVAL;
5873	bp = params->bp;
5874
5875	/* Extract first external phy*/
5876	version[0] = '\0';
5877	spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
5878
5879	if (params->phy[EXT_PHY1].format_fw_ver) {
5880		status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
5881							      ver_p,
5882							      &remain_len);
5883		ver_p += (len - remain_len);
5884	}
5885	if ((params->num_phys == MAX_PHYS) &&
5886	    (params->phy[EXT_PHY2].ver_addr != 0)) {
5887		spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
5888		if (params->phy[EXT_PHY2].format_fw_ver) {
5889			*ver_p = '/';
5890			ver_p++;
5891			remain_len--;
5892			status |= params->phy[EXT_PHY2].format_fw_ver(
5893				spirom_ver,
5894				ver_p,
5895				&remain_len);
5896			ver_p = version + (len - remain_len);
5897		}
5898	}
5899	*ver_p = '\0';
5900	return status;
5901}
5902
5903static void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
5904				    struct link_params *params)
5905{
5906	u8 port = params->port;
5907	struct bnx2x *bp = params->bp;
5908
5909	if (phy->req_line_speed != SPEED_1000) {
5910		u32 md_devad = 0;
5911
5912		DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
5913
5914		if (!CHIP_IS_E3(bp)) {
5915			/* change the uni_phy_addr in the nig */
5916			md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
5917					       port*0x18));
5918
5919			REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5920			       0x5);
5921		}
5922
5923		bnx2x_cl45_write(bp, phy,
5924				 5,
5925				 (MDIO_REG_BANK_AER_BLOCK +
5926				  (MDIO_AER_BLOCK_AER_REG & 0xf)),
5927				 0x2800);
5928
5929		bnx2x_cl45_write(bp, phy,
5930				 5,
5931				 (MDIO_REG_BANK_CL73_IEEEB0 +
5932				  (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
5933				 0x6041);
5934		msleep(200);
5935		/* set aer mmd back */
5936		bnx2x_set_aer_mmd(params, phy);
5937
5938		if (!CHIP_IS_E3(bp)) {
5939			/* and md_devad */
5940			REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
5941			       md_devad);
5942		}
5943	} else {
5944		u16 mii_ctrl;
5945		DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
5946		bnx2x_cl45_read(bp, phy, 5,
5947				(MDIO_REG_BANK_COMBO_IEEE0 +
5948				(MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5949				&mii_ctrl);
5950		bnx2x_cl45_write(bp, phy, 5,
5951				 (MDIO_REG_BANK_COMBO_IEEE0 +
5952				 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
5953				 mii_ctrl |
5954				 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
5955	}
5956}
5957
5958int bnx2x_set_led(struct link_params *params,
5959		  struct link_vars *vars, u8 mode, u32 speed)
5960{
5961	u8 port = params->port;
5962	u16 hw_led_mode = params->hw_led_mode;
5963	int rc = 0;
5964	u8 phy_idx;
5965	u32 tmp;
5966	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
5967	struct bnx2x *bp = params->bp;
5968	DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
5969	DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
5970		 speed, hw_led_mode);
5971	/* In case */
5972	for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
5973		if (params->phy[phy_idx].set_link_led) {
5974			params->phy[phy_idx].set_link_led(
5975				&params->phy[phy_idx], params, mode);
5976		}
5977	}
5978
5979	switch (mode) {
5980	case LED_MODE_FRONT_PANEL_OFF:
5981	case LED_MODE_OFF:
5982		REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
5983		REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
5984		       SHARED_HW_CFG_LED_MAC1);
5985
5986		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
5987		EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
5988		break;
5989
5990	case LED_MODE_OPER:
5991		/*
5992		 * For all other phys, OPER mode is same as ON, so in case
5993		 * link is down, do nothing
5994		 */
5995		if (!vars->link_up)
5996			break;
5997	case LED_MODE_ON:
5998		if (((params->phy[EXT_PHY1].type ==
5999			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
6000			 (params->phy[EXT_PHY1].type ==
6001			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
6002		    CHIP_IS_E2(bp) && params->num_phys == 2) {
6003			/*
6004			 * This is a work-around for E2+8727 Configurations
6005			 */
6006			if (mode == LED_MODE_ON ||
6007				speed == SPEED_10000){
6008				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6009				REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6010
6011				tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6012				EMAC_WR(bp, EMAC_REG_EMAC_LED,
6013					(tmp | EMAC_LED_OVERRIDE));
6014				/*
6015				 * return here without enabling traffic
6016				 * LED blink and setting rate in ON mode.
6017				 * In oper mode, enabling LED blink
6018				 * and setting rate is needed.
6019				 */
6020				if (mode == LED_MODE_ON)
6021					return rc;
6022			}
6023		} else if (SINGLE_MEDIA_DIRECT(params)) {
6024			/*
6025			 * This is a work-around for HW issue found when link
6026			 * is up in CL73
6027			 */
6028			if ((!CHIP_IS_E3(bp)) ||
6029			    (CHIP_IS_E3(bp) &&
6030			     mode == LED_MODE_ON))
6031				REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6032
6033			if (CHIP_IS_E1x(bp) ||
6034			    CHIP_IS_E2(bp) ||
6035			    (mode == LED_MODE_ON))
6036				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6037			else
6038				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6039				       hw_led_mode);
6040		} else
6041			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
6042
6043		REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
6044		/* Set blinking rate to ~15.9Hz */
6045		if (CHIP_IS_E3(bp))
6046			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6047			       LED_BLINK_RATE_VAL_E3);
6048		else
6049			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
6050			       LED_BLINK_RATE_VAL_E1X_E2);
6051		REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
6052		       port*4, 1);
6053		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6054		EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp & (~EMAC_LED_OVERRIDE)));
6055
6056		if (CHIP_IS_E1(bp) &&
6057		    ((speed == SPEED_2500) ||
6058		     (speed == SPEED_1000) ||
6059		     (speed == SPEED_100) ||
6060		     (speed == SPEED_10))) {
6061			/*
6062			 * On Everest 1 Ax chip versions for speeds less than
6063			 * 10G LED scheme is different
6064			 */
6065			REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
6066			       + port*4, 1);
6067			REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
6068			       port*4, 0);
6069			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
6070			       port*4, 1);
6071		}
6072		break;
6073
6074	default:
6075		rc = -EINVAL;
6076		DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
6077			 mode);
6078		break;
6079	}
6080	return rc;
6081
6082}
6083
6084/*
6085 * This function comes to reflect the actual link state read DIRECTLY from the
6086 * HW
6087 */
6088int bnx2x_test_link(struct link_params *params, struct link_vars *vars,
6089		    u8 is_serdes)
6090{
6091	struct bnx2x *bp = params->bp;
6092	u16 gp_status = 0, phy_index = 0;
6093	u8 ext_phy_link_up = 0, serdes_phy_type;
6094	struct link_vars temp_vars;
6095	struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
6096
6097	if (CHIP_IS_E3(bp)) {
6098		u16 link_up;
6099		if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
6100		    > SPEED_10000) {
6101			/* Check 20G link */
6102			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6103					1, &link_up);
6104			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6105					1, &link_up);
6106			link_up &= (1<<2);
6107		} else {
6108			/* Check 10G link and below*/
6109			u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
6110			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
6111					MDIO_WC_REG_GP2_STATUS_GP_2_1,
6112					&gp_status);
6113			gp_status = ((gp_status >> 8) & 0xf) |
6114				((gp_status >> 12) & 0xf);
6115			link_up = gp_status & (1 << lane);
6116		}
6117		if (!link_up)
6118			return -ESRCH;
6119	} else {
6120		CL22_RD_OVER_CL45(bp, int_phy,
6121			  MDIO_REG_BANK_GP_STATUS,
6122			  MDIO_GP_STATUS_TOP_AN_STATUS1,
6123			  &gp_status);
6124	/* link is up only if both local phy and external phy are up */
6125	if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6126		return -ESRCH;
6127	}
6128	/* In XGXS loopback mode, do not check external PHY */
6129	if (params->loopback_mode == LOOPBACK_XGXS)
6130		return 0;
6131
6132	switch (params->num_phys) {
6133	case 1:
6134		/* No external PHY */
6135		return 0;
6136	case 2:
6137		ext_phy_link_up = params->phy[EXT_PHY1].read_status(
6138			&params->phy[EXT_PHY1],
6139			params, &temp_vars);
6140		break;
6141	case 3: /* Dual Media */
6142		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6143		      phy_index++) {
6144			serdes_phy_type = ((params->phy[phy_index].media_type ==
6145					    ETH_PHY_SFP_FIBER) ||
6146					   (params->phy[phy_index].media_type ==
6147					    ETH_PHY_XFP_FIBER) ||
6148					   (params->phy[phy_index].media_type ==
6149					    ETH_PHY_DA_TWINAX));
6150
6151			if (is_serdes != serdes_phy_type)
6152				continue;
6153			if (params->phy[phy_index].read_status) {
6154				ext_phy_link_up |=
6155					params->phy[phy_index].read_status(
6156						&params->phy[phy_index],
6157						params, &temp_vars);
6158			}
6159		}
6160		break;
6161	}
6162	if (ext_phy_link_up)
6163		return 0;
6164	return -ESRCH;
6165}
6166
6167static int bnx2x_link_initialize(struct link_params *params,
6168				 struct link_vars *vars)
6169{
6170	int rc = 0;
6171	u8 phy_index, non_ext_phy;
6172	struct bnx2x *bp = params->bp;
6173	/*
6174	 * In case of external phy existence, the line speed would be the
6175	 * line speed linked up by the external phy. In case it is direct
6176	 * only, then the line_speed during initialization will be
6177	 * equal to the req_line_speed
6178	 */
6179	vars->line_speed = params->phy[INT_PHY].req_line_speed;
6180
6181	/*
6182	 * Initialize the internal phy in case this is a direct board
6183	 * (no external phys), or this board has external phy which requires
6184	 * to first.
6185	 */
6186	if (!USES_WARPCORE(bp))
6187		bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
6188	/* init ext phy and enable link state int */
6189	non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
6190		       (params->loopback_mode == LOOPBACK_XGXS));
6191
6192	if (non_ext_phy ||
6193	    (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
6194	    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6195		struct bnx2x_phy *phy = &params->phy[INT_PHY];
6196		if (vars->line_speed == SPEED_AUTO_NEG &&
6197		    (CHIP_IS_E1x(bp) ||
6198		     CHIP_IS_E2(bp)))
6199			bnx2x_set_parallel_detection(phy, params);
6200			if (params->phy[INT_PHY].config_init)
6201				params->phy[INT_PHY].config_init(phy,
6202								 params,
6203								 vars);
6204	}
6205
6206	/* Init external phy*/
6207	if (non_ext_phy) {
6208		if (params->phy[INT_PHY].supported &
6209		    SUPPORTED_FIBRE)
6210			vars->link_status |= LINK_STATUS_SERDES_LINK;
6211	} else {
6212		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6213		      phy_index++) {
6214			/*
6215			 * No need to initialize second phy in case of first
6216			 * phy only selection. In case of second phy, we do
6217			 * need to initialize the first phy, since they are
6218			 * connected.
6219			 */
6220			if (params->phy[phy_index].supported &
6221			    SUPPORTED_FIBRE)
6222				vars->link_status |= LINK_STATUS_SERDES_LINK;
6223
6224			if (phy_index == EXT_PHY2 &&
6225			    (bnx2x_phy_selection(params) ==
6226			     PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
6227				DP(NETIF_MSG_LINK,
6228				   "Not initializing second phy\n");
6229				continue;
6230			}
6231			params->phy[phy_index].config_init(
6232				&params->phy[phy_index],
6233				params, vars);
6234		}
6235	}
6236	/* Reset the interrupt indication after phy was initialized */
6237	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6238		       params->port*4,
6239		       (NIG_STATUS_XGXS0_LINK10G |
6240			NIG_STATUS_XGXS0_LINK_STATUS |
6241			NIG_STATUS_SERDES0_LINK_STATUS |
6242			NIG_MASK_MI_INT));
6243	bnx2x_update_mng(params, vars->link_status);
6244	return rc;
6245}
6246
6247static void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6248				 struct link_params *params)
6249{
6250	/* reset the SerDes/XGXS */
6251	REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6252	       (0x1ff << (params->port*16)));
6253}
6254
6255static void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6256					struct link_params *params)
6257{
6258	struct bnx2x *bp = params->bp;
6259	u8 gpio_port;
6260	/* HW reset */
6261	if (CHIP_IS_E2(bp))
6262		gpio_port = BP_PATH(bp);
6263	else
6264		gpio_port = params->port;
6265	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6266		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
6267		       gpio_port);
6268	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6269		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
6270		       gpio_port);
6271	DP(NETIF_MSG_LINK, "reset external PHY\n");
6272}
6273
6274static int bnx2x_update_link_down(struct link_params *params,
6275				  struct link_vars *vars)
6276{
6277	struct bnx2x *bp = params->bp;
6278	u8 port = params->port;
6279
6280	DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
6281	bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
6282	vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
6283	/* indicate no mac active */
6284	vars->mac_type = MAC_TYPE_NONE;
6285
6286	/* update shared memory */
6287	vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6288			       LINK_STATUS_LINK_UP |
6289			       LINK_STATUS_PHYSICAL_LINK_FLAG |
6290			       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6291			       LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6292			       LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
6293			       LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK);
6294	vars->line_speed = 0;
6295	bnx2x_update_mng(params, vars->link_status);
6296
6297	/* activate nig drain */
6298	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
6299
6300	/* disable emac */
6301	if (!CHIP_IS_E3(bp))
6302		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6303
6304	msleep(10);
6305	/* reset BigMac/Xmac */
6306	if (CHIP_IS_E1x(bp) ||
6307	    CHIP_IS_E2(bp)) {
6308		bnx2x_bmac_rx_disable(bp, params->port);
6309		REG_WR(bp, GRCBASE_MISC +
6310		       MISC_REGISTERS_RESET_REG_2_CLEAR,
6311	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
6312	}
6313	if (CHIP_IS_E3(bp))
6314		bnx2x_xmac_disable(params);
6315
6316	return 0;
6317}
6318
6319static int bnx2x_update_link_up(struct link_params *params,
6320				struct link_vars *vars,
6321				u8 link_10g)
6322{
6323	struct bnx2x *bp = params->bp;
6324	u8 port = params->port;
6325	int rc = 0;
6326
6327	vars->link_status |= (LINK_STATUS_LINK_UP |
6328			      LINK_STATUS_PHYSICAL_LINK_FLAG);
6329	vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
6330
6331	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6332		vars->link_status |=
6333			LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6334
6335	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6336		vars->link_status |=
6337			LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
6338	if (USES_WARPCORE(bp)) {
6339		if (link_10g) {
6340			if (bnx2x_xmac_enable(params, vars, 0) ==
6341			    -ESRCH) {
6342				DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
6343				vars->link_up = 0;
6344				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6345				vars->link_status &= ~LINK_STATUS_LINK_UP;
6346			}
6347		} else
6348			bnx2x_umac_enable(params, vars, 0);
6349		bnx2x_set_led(params, vars,
6350			      LED_MODE_OPER, vars->line_speed);
6351	}
6352	if ((CHIP_IS_E1x(bp) ||
6353	     CHIP_IS_E2(bp))) {
6354		if (link_10g) {
6355			if (bnx2x_bmac_enable(params, vars, 0) ==
6356			    -ESRCH) {
6357				DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
6358				vars->link_up = 0;
6359				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
6360				vars->link_status &= ~LINK_STATUS_LINK_UP;
6361			}
6362
6363			bnx2x_set_led(params, vars,
6364				      LED_MODE_OPER, SPEED_10000);
6365		} else {
6366			rc = bnx2x_emac_program(params, vars);
6367			bnx2x_emac_enable(params, vars, 0);
6368
6369			/* AN complete? */
6370			if ((vars->link_status &
6371			     LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
6372			    && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
6373			    SINGLE_MEDIA_DIRECT(params))
6374				bnx2x_set_gmii_tx_driver(params);
6375		}
6376	}
6377
6378	/* PBF - link up */
6379	if (CHIP_IS_E1x(bp))
6380		rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6381				       vars->line_speed);
6382
6383	/* disable drain */
6384	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6385
6386	/* update shared memory */
6387	bnx2x_update_mng(params, vars->link_status);
6388	msleep(20);
6389	return rc;
6390}
6391/*
6392 * The bnx2x_link_update function should be called upon link
6393 * interrupt.
6394 * Link is considered up as follows:
6395 * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6396 *   to be up
6397 * - SINGLE_MEDIA - The link between the 577xx and the external
6398 *   phy (XGXS) need to up as well as the external link of the
6399 *   phy (PHY_EXT1)
6400 * - DUAL_MEDIA - The link between the 577xx and the first
6401 *   external phy needs to be up, and at least one of the 2
6402 *   external phy link must be up.
6403 */
6404int bnx2x_link_update(struct link_params *params, struct link_vars *vars)
6405{
6406	struct bnx2x *bp = params->bp;
6407	struct link_vars phy_vars[MAX_PHYS];
6408	u8 port = params->port;
6409	u8 link_10g_plus, phy_index;
6410	u8 ext_phy_link_up = 0, cur_link_up;
6411	int rc = 0;
6412	u8 is_mi_int = 0;
6413	u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6414	u8 active_external_phy = INT_PHY;
6415	vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
6416	for (phy_index = INT_PHY; phy_index < params->num_phys;
6417	      phy_index++) {
6418		phy_vars[phy_index].flow_ctrl = 0;
6419		phy_vars[phy_index].link_status = 0;
6420		phy_vars[phy_index].line_speed = 0;
6421		phy_vars[phy_index].duplex = DUPLEX_FULL;
6422		phy_vars[phy_index].phy_link_up = 0;
6423		phy_vars[phy_index].link_up = 0;
6424		phy_vars[phy_index].fault_detected = 0;
6425	}
6426
6427	if (USES_WARPCORE(bp))
6428		bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
6429
6430	DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6431		 port, (vars->phy_flags & PHY_XGXS_FLAG),
6432		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
6433
6434	is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6435				port*0x18) > 0);
6436	DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6437		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6438		 is_mi_int,
6439		 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
6440
6441	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6442	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6443	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
6444
6445	/* disable emac */
6446	if (!CHIP_IS_E3(bp))
6447		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6448
6449	/*
6450	 * Step 1:
6451	 * Check external link change only for external phys, and apply
6452	 * priority selection between them in case the link on both phys
6453	 * is up. Note that instead of the common vars, a temporary
6454	 * vars argument is used since each phy may have different link/
6455	 * speed/duplex result
6456	 */
6457	for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6458	      phy_index++) {
6459		struct bnx2x_phy *phy = &params->phy[phy_index];
6460		if (!phy->read_status)
6461			continue;
6462		/* Read link status and params of this ext phy */
6463		cur_link_up = phy->read_status(phy, params,
6464					       &phy_vars[phy_index]);
6465		if (cur_link_up) {
6466			DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6467				   phy_index);
6468		} else {
6469			DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6470				   phy_index);
6471			continue;
6472		}
6473
6474		if (!ext_phy_link_up) {
6475			ext_phy_link_up = 1;
6476			active_external_phy = phy_index;
6477		} else {
6478			switch (bnx2x_phy_selection(params)) {
6479			case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6480			case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
6481			/*
6482			 * In this option, the first PHY makes sure to pass the
6483			 * traffic through itself only.
6484			 * Its not clear how to reset the link on the second phy
6485			 */
6486				active_external_phy = EXT_PHY1;
6487				break;
6488			case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
6489			/*
6490			 * In this option, the first PHY makes sure to pass the
6491			 * traffic through the second PHY.
6492			 */
6493				active_external_phy = EXT_PHY2;
6494				break;
6495			default:
6496			/*
6497			 * Link indication on both PHYs with the following cases
6498			 * is invalid:
6499			 * - FIRST_PHY means that second phy wasn't initialized,
6500			 * hence its link is expected to be down
6501			 * - SECOND_PHY means that first phy should not be able
6502			 * to link up by itself (using configuration)
6503			 * - DEFAULT should be overriden during initialiazation
6504			 */
6505				DP(NETIF_MSG_LINK, "Invalid link indication"
6506					   "mpc=0x%x. DISABLING LINK !!!\n",
6507					   params->multi_phy_config);
6508				ext_phy_link_up = 0;
6509				break;
6510			}
6511		}
6512	}
6513	prev_line_speed = vars->line_speed;
6514	/*
6515	 * Step 2:
6516	 * Read the status of the internal phy. In case of
6517	 * DIRECT_SINGLE_MEDIA board, this link is the external link,
6518	 * otherwise this is the link between the 577xx and the first
6519	 * external phy
6520	 */
6521	if (params->phy[INT_PHY].read_status)
6522		params->phy[INT_PHY].read_status(
6523			&params->phy[INT_PHY],
6524			params, vars);
6525	/*
6526	 * The INT_PHY flow control reside in the vars. This include the
6527	 * case where the speed or flow control are not set to AUTO.
6528	 * Otherwise, the active external phy flow control result is set
6529	 * to the vars. The ext_phy_line_speed is needed to check if the
6530	 * speed is different between the internal phy and external phy.
6531	 * This case may be result of intermediate link speed change.
6532	 */
6533	if (active_external_phy > INT_PHY) {
6534		vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
6535		/*
6536		 * Link speed is taken from the XGXS. AN and FC result from
6537		 * the external phy.
6538		 */
6539		vars->link_status |= phy_vars[active_external_phy].link_status;
6540
6541		/*
6542		 * if active_external_phy is first PHY and link is up - disable
6543		 * disable TX on second external PHY
6544		 */
6545		if (active_external_phy == EXT_PHY1) {
6546			if (params->phy[EXT_PHY2].phy_specific_func) {
6547				DP(NETIF_MSG_LINK,
6548				   "Disabling TX on EXT_PHY2\n");
6549				params->phy[EXT_PHY2].phy_specific_func(
6550					&params->phy[EXT_PHY2],
6551					params, DISABLE_TX);
6552			}
6553		}
6554
6555		ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6556		vars->duplex = phy_vars[active_external_phy].duplex;
6557		if (params->phy[active_external_phy].supported &
6558		    SUPPORTED_FIBRE)
6559			vars->link_status |= LINK_STATUS_SERDES_LINK;
6560		else
6561			vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6562		DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6563			   active_external_phy);
6564	}
6565
6566	for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6567	      phy_index++) {
6568		if (params->phy[phy_index].flags &
6569		    FLAGS_REARM_LATCH_SIGNAL) {
6570			bnx2x_rearm_latch_signal(bp, port,
6571						 phy_index ==
6572						 active_external_phy);
6573			break;
6574		}
6575	}
6576	DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6577		   " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6578		   vars->link_status, ext_phy_line_speed);
6579	/*
6580	 * Upon link speed change set the NIG into drain mode. Comes to
6581	 * deals with possible FIFO glitch due to clk change when speed
6582	 * is decreased without link down indicator
6583	 */
6584
6585	if (vars->phy_link_up) {
6586		if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6587		    (ext_phy_line_speed != vars->line_speed)) {
6588			DP(NETIF_MSG_LINK, "Internal link speed %d is"
6589				   " different than the external"
6590				   " link speed %d\n", vars->line_speed,
6591				   ext_phy_line_speed);
6592			vars->phy_link_up = 0;
6593		} else if (prev_line_speed != vars->line_speed) {
6594			REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6595			       0);
6596			msleep(1);
6597		}
6598	}
6599
6600	/* anything 10 and over uses the bmac */
6601	link_10g_plus = (vars->line_speed >= SPEED_10000);
6602
6603	bnx2x_link_int_ack(params, vars, link_10g_plus);
6604
6605	/*
6606	 * In case external phy link is up, and internal link is down
6607	 * (not initialized yet probably after link initialization, it
6608	 * needs to be initialized.
6609	 * Note that after link down-up as result of cable plug, the xgxs
6610	 * link would probably become up again without the need
6611	 * initialize it
6612	 */
6613	if (!(SINGLE_MEDIA_DIRECT(params))) {
6614		DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6615			   " init_preceding = %d\n", ext_phy_link_up,
6616			   vars->phy_link_up,
6617			   params->phy[EXT_PHY1].flags &
6618			   FLAGS_INIT_XGXS_FIRST);
6619		if (!(params->phy[EXT_PHY1].flags &
6620		      FLAGS_INIT_XGXS_FIRST)
6621		    && ext_phy_link_up && !vars->phy_link_up) {
6622			vars->line_speed = ext_phy_line_speed;
6623			if (vars->line_speed < SPEED_1000)
6624				vars->phy_flags |= PHY_SGMII_FLAG;
6625			else
6626				vars->phy_flags &= ~PHY_SGMII_FLAG;
6627
6628			if (params->phy[INT_PHY].config_init)
6629				params->phy[INT_PHY].config_init(
6630					&params->phy[INT_PHY], params,
6631						vars);
6632		}
6633	}
6634	/*
6635	 * Link is up only if both local phy and external phy (in case of
6636	 * non-direct board) are up and no fault detected on active PHY.
6637	 */
6638	vars->link_up = (vars->phy_link_up &&
6639			 (ext_phy_link_up ||
6640			  SINGLE_MEDIA_DIRECT(params)) &&
6641			 (phy_vars[active_external_phy].fault_detected == 0));
6642
6643	if (vars->link_up)
6644		rc = bnx2x_update_link_up(params, vars, link_10g_plus);
6645	else
6646		rc = bnx2x_update_link_down(params, vars);
6647
6648	return rc;
6649}
6650
6651
6652/*****************************************************************************/
6653/*			    External Phy section			     */
6654/*****************************************************************************/
6655void bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6656{
6657	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6658		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6659	msleep(1);
6660	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6661		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6662}
6663
6664static void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6665				      u32 spirom_ver, u32 ver_addr)
6666{
6667	DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6668		 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
6669
6670	if (ver_addr)
6671		REG_WR(bp, ver_addr, spirom_ver);
6672}
6673
6674static void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6675				      struct bnx2x_phy *phy,
6676				      u8 port)
6677{
6678	u16 fw_ver1, fw_ver2;
6679
6680	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6681			MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6682	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6683			MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6684	bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6685				  phy->ver_addr);
6686}
6687
6688static void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6689				       struct bnx2x_phy *phy,
6690				       struct link_vars *vars)
6691{
6692	u16 val;
6693	bnx2x_cl45_read(bp, phy,
6694			MDIO_AN_DEVAD,
6695			MDIO_AN_REG_STATUS, &val);
6696	bnx2x_cl45_read(bp, phy,
6697			MDIO_AN_DEVAD,
6698			MDIO_AN_REG_STATUS, &val);
6699	if (val & (1<<5))
6700		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6701	if ((val & (1<<0)) == 0)
6702		vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6703}
6704
6705/******************************************************************/
6706/*		common BCM8073/BCM8727 PHY SECTION		  */
6707/******************************************************************/
6708static void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6709				  struct link_params *params,
6710				  struct link_vars *vars)
6711{
6712	struct bnx2x *bp = params->bp;
6713	if (phy->req_line_speed == SPEED_10 ||
6714	    phy->req_line_speed == SPEED_100) {
6715		vars->flow_ctrl = phy->req_flow_ctrl;
6716		return;
6717	}
6718
6719	if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6720	    (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6721		u16 pause_result;
6722		u16 ld_pause;		/* local */
6723		u16 lp_pause;		/* link partner */
6724		bnx2x_cl45_read(bp, phy,
6725				MDIO_AN_DEVAD,
6726				MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6727
6728		bnx2x_cl45_read(bp, phy,
6729				MDIO_AN_DEVAD,
6730				MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6731		pause_result = (ld_pause &
6732				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6733		pause_result |= (lp_pause &
6734				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6735
6736		bnx2x_pause_resolve(vars, pause_result);
6737		DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6738			   pause_result);
6739	}
6740}
6741static int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
6742					     struct bnx2x_phy *phy,
6743					     u8 port)
6744{
6745	u32 count = 0;
6746	u16 fw_ver1, fw_msgout;
6747	int rc = 0;
6748
6749	/* Boot port from external ROM  */
6750	/* EDC grst */
6751	bnx2x_cl45_write(bp, phy,
6752			 MDIO_PMA_DEVAD,
6753			 MDIO_PMA_REG_GEN_CTRL,
6754			 0x0001);
6755
6756	/* ucode reboot and rst */
6757	bnx2x_cl45_write(bp, phy,
6758			 MDIO_PMA_DEVAD,
6759			 MDIO_PMA_REG_GEN_CTRL,
6760			 0x008c);
6761
6762	bnx2x_cl45_write(bp, phy,
6763			 MDIO_PMA_DEVAD,
6764			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
6765
6766	/* Reset internal microprocessor */
6767	bnx2x_cl45_write(bp, phy,
6768			 MDIO_PMA_DEVAD,
6769			 MDIO_PMA_REG_GEN_CTRL,
6770			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
6771
6772	/* Release srst bit */
6773	bnx2x_cl45_write(bp, phy,
6774			 MDIO_PMA_DEVAD,
6775			 MDIO_PMA_REG_GEN_CTRL,
6776			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
6777
6778	/* Delay 100ms per the PHY specifications */
6779	msleep(100);
6780
6781	/* 8073 sometimes taking longer to download */
6782	do {
6783		count++;
6784		if (count > 300) {
6785			DP(NETIF_MSG_LINK,
6786				 "bnx2x_8073_8727_external_rom_boot port %x:"
6787				 "Download failed. fw version = 0x%x\n",
6788				 port, fw_ver1);
6789			rc = -EINVAL;
6790			break;
6791		}
6792
6793		bnx2x_cl45_read(bp, phy,
6794				MDIO_PMA_DEVAD,
6795				MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6796		bnx2x_cl45_read(bp, phy,
6797				MDIO_PMA_DEVAD,
6798				MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
6799
6800		msleep(1);
6801	} while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
6802			((fw_msgout & 0xff) != 0x03 && (phy->type ==
6803			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
6804
6805	/* Clear ser_boot_ctl bit */
6806	bnx2x_cl45_write(bp, phy,
6807			 MDIO_PMA_DEVAD,
6808			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
6809	bnx2x_save_bcm_spirom_ver(bp, phy, port);
6810
6811	DP(NETIF_MSG_LINK,
6812		 "bnx2x_8073_8727_external_rom_boot port %x:"
6813		 "Download complete. fw version = 0x%x\n",
6814		 port, fw_ver1);
6815
6816	return rc;
6817}
6818
6819/******************************************************************/
6820/*			BCM8073 PHY SECTION			  */
6821/******************************************************************/
6822static int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
6823{
6824	/* This is only required for 8073A1, version 102 only */
6825	u16 val;
6826
6827	/* Read 8073 HW revision*/
6828	bnx2x_cl45_read(bp, phy,
6829			MDIO_PMA_DEVAD,
6830			MDIO_PMA_REG_8073_CHIP_REV, &val);
6831
6832	if (val != 1) {
6833		/* No need to workaround in 8073 A1 */
6834		return 0;
6835	}
6836
6837	bnx2x_cl45_read(bp, phy,
6838			MDIO_PMA_DEVAD,
6839			MDIO_PMA_REG_ROM_VER2, &val);
6840
6841	/* SNR should be applied only for version 0x102 */
6842	if (val != 0x102)
6843		return 0;
6844
6845	return 1;
6846}
6847
6848static int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
6849{
6850	u16 val, cnt, cnt1 ;
6851
6852	bnx2x_cl45_read(bp, phy,
6853			MDIO_PMA_DEVAD,
6854			MDIO_PMA_REG_8073_CHIP_REV, &val);
6855
6856	if (val > 0) {
6857		/* No need to workaround in 8073 A1 */
6858		return 0;
6859	}
6860	/* XAUI workaround in 8073 A0: */
6861
6862	/*
6863	 * After loading the boot ROM and restarting Autoneg, poll
6864	 * Dev1, Reg $C820:
6865	 */
6866
6867	for (cnt = 0; cnt < 1000; cnt++) {
6868		bnx2x_cl45_read(bp, phy,
6869				MDIO_PMA_DEVAD,
6870				MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
6871				&val);
6872		  /*
6873		   * If bit [14] = 0 or bit [13] = 0, continue on with
6874		   * system initialization (XAUI work-around not required, as
6875		   * these bits indicate 2.5G or 1G link up).
6876		   */
6877		if (!(val & (1<<14)) || !(val & (1<<13))) {
6878			DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
6879			return 0;
6880		} else if (!(val & (1<<15))) {
6881			DP(NETIF_MSG_LINK, "bit 15 went off\n");
6882			/*
6883			 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
6884			 * MSB (bit15) goes to 1 (indicating that the XAUI
6885			 * workaround has completed), then continue on with
6886			 * system initialization.
6887			 */
6888			for (cnt1 = 0; cnt1 < 1000; cnt1++) {
6889				bnx2x_cl45_read(bp, phy,
6890					MDIO_PMA_DEVAD,
6891					MDIO_PMA_REG_8073_XAUI_WA, &val);
6892				if (val & (1<<15)) {
6893					DP(NETIF_MSG_LINK,
6894					  "XAUI workaround has completed\n");
6895					return 0;
6896				 }
6897				 msleep(3);
6898			}
6899			break;
6900		}
6901		msleep(3);
6902	}
6903	DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
6904	return -EINVAL;
6905}
6906
6907static void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
6908{
6909	/* Force KR or KX */
6910	bnx2x_cl45_write(bp, phy,
6911			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
6912	bnx2x_cl45_write(bp, phy,
6913			 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
6914	bnx2x_cl45_write(bp, phy,
6915			 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
6916	bnx2x_cl45_write(bp, phy,
6917			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
6918}
6919
6920static void bnx2x_8073_set_pause_cl37(struct link_params *params,
6921				      struct bnx2x_phy *phy,
6922				      struct link_vars *vars)
6923{
6924	u16 cl37_val;
6925	struct bnx2x *bp = params->bp;
6926	bnx2x_cl45_read(bp, phy,
6927			MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
6928
6929	cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6930	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
6931	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
6932	if ((vars->ieee_fc &
6933	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
6934	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
6935		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
6936	}
6937	if ((vars->ieee_fc &
6938	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
6939	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
6940		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
6941	}
6942	if ((vars->ieee_fc &
6943	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
6944	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
6945		cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
6946	}
6947	DP(NETIF_MSG_LINK,
6948		 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
6949
6950	bnx2x_cl45_write(bp, phy,
6951			 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
6952	msleep(500);
6953}
6954
6955static int bnx2x_8073_config_init(struct bnx2x_phy *phy,
6956				  struct link_params *params,
6957				  struct link_vars *vars)
6958{
6959	struct bnx2x *bp = params->bp;
6960	u16 val = 0, tmp1;
6961	u8 gpio_port;
6962	DP(NETIF_MSG_LINK, "Init 8073\n");
6963
6964	if (CHIP_IS_E2(bp))
6965		gpio_port = BP_PATH(bp);
6966	else
6967		gpio_port = params->port;
6968	/* Restore normal power mode*/
6969	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6970		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6971
6972	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6973		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
6974
6975	/* enable LASI */
6976	bnx2x_cl45_write(bp, phy,
6977			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
6978	bnx2x_cl45_write(bp, phy,
6979			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
6980
6981	bnx2x_8073_set_pause_cl37(params, phy, vars);
6982
6983	bnx2x_cl45_read(bp, phy,
6984			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
6985
6986	bnx2x_cl45_read(bp, phy,
6987			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
6988
6989	DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
6990
6991	/* Swap polarity if required - Must be done only in non-1G mode */
6992	if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
6993		/* Configure the 8073 to swap _P and _N of the KR lines */
6994		DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
6995		/* 10G Rx/Tx and 1G Tx signal polarity swap */
6996		bnx2x_cl45_read(bp, phy,
6997				MDIO_PMA_DEVAD,
6998				MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
6999		bnx2x_cl45_write(bp, phy,
7000				 MDIO_PMA_DEVAD,
7001				 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
7002				 (val | (3<<9)));
7003	}
7004
7005
7006	/* Enable CL37 BAM */
7007	if (REG_RD(bp, params->shmem_base +
7008			 offsetof(struct shmem_region, dev_info.
7009				  port_hw_config[params->port].default_cfg)) &
7010	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
7011
7012		bnx2x_cl45_read(bp, phy,
7013				MDIO_AN_DEVAD,
7014				MDIO_AN_REG_8073_BAM, &val);
7015		bnx2x_cl45_write(bp, phy,
7016				 MDIO_AN_DEVAD,
7017				 MDIO_AN_REG_8073_BAM, val | 1);
7018		DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
7019	}
7020	if (params->loopback_mode == LOOPBACK_EXT) {
7021		bnx2x_807x_force_10G(bp, phy);
7022		DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
7023		return 0;
7024	} else {
7025		bnx2x_cl45_write(bp, phy,
7026				 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
7027	}
7028	if (phy->req_line_speed != SPEED_AUTO_NEG) {
7029		if (phy->req_line_speed == SPEED_10000) {
7030			val = (1<<7);
7031		} else if (phy->req_line_speed ==  SPEED_2500) {
7032			val = (1<<5);
7033			/*
7034			 * Note that 2.5G works only when used with 1G
7035			 * advertisement
7036			 */
7037		} else
7038			val = (1<<5);
7039	} else {
7040		val = 0;
7041		if (phy->speed_cap_mask &
7042			PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
7043			val |= (1<<7);
7044
7045		/* Note that 2.5G works only when used with 1G advertisement */
7046		if (phy->speed_cap_mask &
7047			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
7048			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
7049			val |= (1<<5);
7050		DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
7051	}
7052
7053	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
7054	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
7055
7056	if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
7057	     (phy->req_line_speed == SPEED_AUTO_NEG)) ||
7058	    (phy->req_line_speed == SPEED_2500)) {
7059		u16 phy_ver;
7060		/* Allow 2.5G for A1 and above */
7061		bnx2x_cl45_read(bp, phy,
7062				MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
7063				&phy_ver);
7064		DP(NETIF_MSG_LINK, "Add 2.5G\n");
7065		if (phy_ver > 0)
7066			tmp1 |= 1;
7067		else
7068			tmp1 &= 0xfffe;
7069	} else {
7070		DP(NETIF_MSG_LINK, "Disable 2.5G\n");
7071		tmp1 &= 0xfffe;
7072	}
7073
7074	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
7075	/* Add support for CL37 (passive mode) II */
7076
7077	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
7078	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
7079			 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
7080				  0x20 : 0x40)));
7081
7082	/* Add support for CL37 (passive mode) III */
7083	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
7084
7085	/*
7086	 * The SNR will improve about 2db by changing BW and FEE main
7087	 * tap. Rest commands are executed after link is up
7088	 * Change FFE main cursor to 5 in EDC register
7089	 */
7090	if (bnx2x_8073_is_snr_needed(bp, phy))
7091		bnx2x_cl45_write(bp, phy,
7092				 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
7093				 0xFB0C);
7094
7095	/* Enable FEC (Forware Error Correction) Request in the AN */
7096	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
7097	tmp1 |= (1<<15);
7098	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
7099
7100	bnx2x_ext_phy_set_pause(params, phy, vars);
7101
7102	/* Restart autoneg */
7103	msleep(500);
7104	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7105	DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
7106		   ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
7107	return 0;
7108}
7109
7110static u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
7111				 struct link_params *params,
7112				 struct link_vars *vars)
7113{
7114	struct bnx2x *bp = params->bp;
7115	u8 link_up = 0;
7116	u16 val1, val2;
7117	u16 link_status = 0;
7118	u16 an1000_status = 0;
7119
7120	bnx2x_cl45_read(bp, phy,
7121			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
7122
7123	DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
7124
7125	/* clear the interrupt LASI status register */
7126	bnx2x_cl45_read(bp, phy,
7127			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7128	bnx2x_cl45_read(bp, phy,
7129			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
7130	DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
7131	/* Clear MSG-OUT */
7132	bnx2x_cl45_read(bp, phy,
7133			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7134
7135	/* Check the LASI */
7136	bnx2x_cl45_read(bp, phy,
7137			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
7138
7139	DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
7140
7141	/* Check the link status */
7142	bnx2x_cl45_read(bp, phy,
7143			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7144	DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
7145
7146	bnx2x_cl45_read(bp, phy,
7147			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7148	bnx2x_cl45_read(bp, phy,
7149			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7150	link_up = ((val1 & 4) == 4);
7151	DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
7152
7153	if (link_up &&
7154	     ((phy->req_line_speed != SPEED_10000))) {
7155		if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7156			return 0;
7157	}
7158	bnx2x_cl45_read(bp, phy,
7159			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7160	bnx2x_cl45_read(bp, phy,
7161			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7162
7163	/* Check the link status on 1.1.2 */
7164	bnx2x_cl45_read(bp, phy,
7165			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7166	bnx2x_cl45_read(bp, phy,
7167			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7168	DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
7169		   "an_link_status=0x%x\n", val2, val1, an1000_status);
7170
7171	link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7172	if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
7173		/*
7174		 * The SNR will improve about 2dbby changing the BW and FEE main
7175		 * tap. The 1st write to change FFE main tap is set before
7176		 * restart AN. Change PLL Bandwidth in EDC register
7177		 */
7178		bnx2x_cl45_write(bp, phy,
7179				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
7180				 0x26BC);
7181
7182		/* Change CDR Bandwidth in EDC register */
7183		bnx2x_cl45_write(bp, phy,
7184				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
7185				 0x0333);
7186	}
7187	bnx2x_cl45_read(bp, phy,
7188			MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7189			&link_status);
7190
7191	/* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7192	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7193		link_up = 1;
7194		vars->line_speed = SPEED_10000;
7195		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7196			   params->port);
7197	} else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7198		link_up = 1;
7199		vars->line_speed = SPEED_2500;
7200		DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
7201			   params->port);
7202	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7203		link_up = 1;
7204		vars->line_speed = SPEED_1000;
7205		DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7206			   params->port);
7207	} else {
7208		link_up = 0;
7209		DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7210			   params->port);
7211	}
7212
7213	if (link_up) {
7214		/* Swap polarity if required */
7215		if (params->lane_config &
7216		    PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
7217			/* Configure the 8073 to swap P and N of the KR lines */
7218			bnx2x_cl45_read(bp, phy,
7219					MDIO_XS_DEVAD,
7220					MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
7221			/*
7222			 * Set bit 3 to invert Rx in 1G mode and clear this bit
7223			 * when it`s in 10G mode.
7224			 */
7225			if (vars->line_speed == SPEED_1000) {
7226				DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
7227					      "the 8073\n");
7228				val1 |= (1<<3);
7229			} else
7230				val1 &= ~(1<<3);
7231
7232			bnx2x_cl45_write(bp, phy,
7233					 MDIO_XS_DEVAD,
7234					 MDIO_XS_REG_8073_RX_CTRL_PCIE,
7235					 val1);
7236		}
7237		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7238		bnx2x_8073_resolve_fc(phy, params, vars);
7239		vars->duplex = DUPLEX_FULL;
7240	}
7241	return link_up;
7242}
7243
7244static void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7245				  struct link_params *params)
7246{
7247	struct bnx2x *bp = params->bp;
7248	u8 gpio_port;
7249	if (CHIP_IS_E2(bp))
7250		gpio_port = BP_PATH(bp);
7251	else
7252		gpio_port = params->port;
7253	DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7254	   gpio_port);
7255	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7256		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7257		       gpio_port);
7258}
7259
7260/******************************************************************/
7261/*			BCM8705 PHY SECTION			  */
7262/******************************************************************/
7263static int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7264				  struct link_params *params,
7265				  struct link_vars *vars)
7266{
7267	struct bnx2x *bp = params->bp;
7268	DP(NETIF_MSG_LINK, "init 8705\n");
7269	/* Restore normal power mode*/
7270	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7271		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7272	/* HW reset */
7273	bnx2x_ext_phy_hw_reset(bp, params->port);
7274	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
7275	bnx2x_wait_reset_complete(bp, phy, params);
7276
7277	bnx2x_cl45_write(bp, phy,
7278			 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7279	bnx2x_cl45_write(bp, phy,
7280			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7281	bnx2x_cl45_write(bp, phy,
7282			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7283	bnx2x_cl45_write(bp, phy,
7284			 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7285	/* BCM8705 doesn't have microcode, hence the 0 */
7286	bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7287	return 0;
7288}
7289
7290static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7291				 struct link_params *params,
7292				 struct link_vars *vars)
7293{
7294	u8 link_up = 0;
7295	u16 val1, rx_sd;
7296	struct bnx2x *bp = params->bp;
7297	DP(NETIF_MSG_LINK, "read status 8705\n");
7298	bnx2x_cl45_read(bp, phy,
7299		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7300	DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7301
7302	bnx2x_cl45_read(bp, phy,
7303		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7304	DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
7305
7306	bnx2x_cl45_read(bp, phy,
7307		      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7308
7309	bnx2x_cl45_read(bp, phy,
7310		      MDIO_PMA_DEVAD, 0xc809, &val1);
7311	bnx2x_cl45_read(bp, phy,
7312		      MDIO_PMA_DEVAD, 0xc809, &val1);
7313
7314	DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7315	link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7316	if (link_up) {
7317		vars->line_speed = SPEED_10000;
7318		bnx2x_ext_phy_resolve_fc(phy, params, vars);
7319	}
7320	return link_up;
7321}
7322
7323/******************************************************************/
7324/*			SFP+ module Section			  */
7325/******************************************************************/
7326static void bnx2x_set_disable_pmd_transmit(struct link_params *params,
7327					   struct bnx2x_phy *phy,
7328					   u8 pmd_dis)
7329{
7330	struct bnx2x *bp = params->bp;
7331	/*
7332	 * Disable transmitter only for bootcodes which can enable it afterwards
7333	 * (for D3 link)
7334	 */
7335	if (pmd_dis) {
7336		if (params->feature_config_flags &
7337		     FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
7338			DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
7339		else {
7340			DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
7341			return;
7342		}
7343	} else
7344		DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
7345	bnx2x_cl45_write(bp, phy,
7346			 MDIO_PMA_DEVAD,
7347			 MDIO_PMA_REG_TX_DISABLE, pmd_dis);
7348}
7349
7350static u8 bnx2x_get_gpio_port(struct link_params *params)
7351{
7352	u8 gpio_port;
7353	u32 swap_val, swap_override;
7354	struct bnx2x *bp = params->bp;
7355	if (CHIP_IS_E2(bp))
7356		gpio_port = BP_PATH(bp);
7357	else
7358		gpio_port = params->port;
7359	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7360	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7361	return gpio_port ^ (swap_val && swap_override);
7362}
7363
7364static void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
7365					   struct bnx2x_phy *phy,
7366					   u8 tx_en)
7367{
7368	u16 val;
7369	u8 port = params->port;
7370	struct bnx2x *bp = params->bp;
7371	u32 tx_en_mode;
7372
7373	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7374	tx_en_mode = REG_RD(bp, params->shmem_base +
7375			    offsetof(struct shmem_region,
7376				     dev_info.port_hw_config[port].sfp_ctrl)) &
7377		PORT_HW_CFG_TX_LASER_MASK;
7378	DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7379			   "mode = %x\n", tx_en, port, tx_en_mode);
7380	switch (tx_en_mode) {
7381	case PORT_HW_CFG_TX_LASER_MDIO:
7382
7383		bnx2x_cl45_read(bp, phy,
7384				MDIO_PMA_DEVAD,
7385				MDIO_PMA_REG_PHY_IDENTIFIER,
7386				&val);
7387
7388		if (tx_en)
7389			val &= ~(1<<15);
7390		else
7391			val |= (1<<15);
7392
7393		bnx2x_cl45_write(bp, phy,
7394				 MDIO_PMA_DEVAD,
7395				 MDIO_PMA_REG_PHY_IDENTIFIER,
7396				 val);
7397	break;
7398	case PORT_HW_CFG_TX_LASER_GPIO0:
7399	case PORT_HW_CFG_TX_LASER_GPIO1:
7400	case PORT_HW_CFG_TX_LASER_GPIO2:
7401	case PORT_HW_CFG_TX_LASER_GPIO3:
7402	{
7403		u16 gpio_pin;
7404		u8 gpio_port, gpio_mode;
7405		if (tx_en)
7406			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7407		else
7408			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7409
7410		gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7411		gpio_port = bnx2x_get_gpio_port(params);
7412		bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7413		break;
7414	}
7415	default:
7416		DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7417		break;
7418	}
7419}
7420
7421static void bnx2x_sfp_set_transmitter(struct link_params *params,
7422				      struct bnx2x_phy *phy,
7423				      u8 tx_en)
7424{
7425	struct bnx2x *bp = params->bp;
7426	DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
7427	if (CHIP_IS_E3(bp))
7428		bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
7429	else
7430		bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
7431}
7432
7433static int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7434					     struct link_params *params,
7435					     u16 addr, u8 byte_cnt, u8 *o_buf)
7436{
7437	struct bnx2x *bp = params->bp;
7438	u16 val = 0;
7439	u16 i;
7440	if (byte_cnt > 16) {
7441		DP(NETIF_MSG_LINK,
7442		   "Reading from eeprom is limited to 0xf\n");
7443		return -EINVAL;
7444	}
7445	/* Set the read command byte count */
7446	bnx2x_cl45_write(bp, phy,
7447			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7448			 (byte_cnt | 0xa000));
7449
7450	/* Set the read command address */
7451	bnx2x_cl45_write(bp, phy,
7452			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7453			 addr);
7454
7455	/* Activate read command */
7456	bnx2x_cl45_write(bp, phy,
7457			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7458			 0x2c0f);
7459
7460	/* Wait up to 500us for command complete status */
7461	for (i = 0; i < 100; i++) {
7462		bnx2x_cl45_read(bp, phy,
7463				MDIO_PMA_DEVAD,
7464				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7465		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7466		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7467			break;
7468		udelay(5);
7469	}
7470
7471	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7472		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7473		DP(NETIF_MSG_LINK,
7474			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7475			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7476		return -EINVAL;
7477	}
7478
7479	/* Read the buffer */
7480	for (i = 0; i < byte_cnt; i++) {
7481		bnx2x_cl45_read(bp, phy,
7482				MDIO_PMA_DEVAD,
7483				MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7484		o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
7485	}
7486
7487	for (i = 0; i < 100; i++) {
7488		bnx2x_cl45_read(bp, phy,
7489				MDIO_PMA_DEVAD,
7490				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7491		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7492		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7493			return 0;
7494		msleep(1);
7495	}
7496	return -EINVAL;
7497}
7498
7499static int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7500						 struct link_params *params,
7501						 u16 addr, u8 byte_cnt,
7502						 u8 *o_buf)
7503{
7504	int rc = 0;
7505	u8 i, j = 0, cnt = 0;
7506	u32 data_array[4];
7507	u16 addr32;
7508	struct bnx2x *bp = params->bp;
7509	/*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
7510					" addr %d, cnt %d\n",
7511					addr, byte_cnt);*/
7512	if (byte_cnt > 16) {
7513		DP(NETIF_MSG_LINK,
7514		   "Reading from eeprom is limited to 16 bytes\n");
7515		return -EINVAL;
7516	}
7517
7518	/* 4 byte aligned address */
7519	addr32 = addr & (~0x3);
7520	do {
7521		rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
7522				    data_array);
7523	} while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
7524
7525	if (rc == 0) {
7526		for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
7527			o_buf[j] = *((u8 *)data_array + i);
7528			j++;
7529		}
7530	}
7531
7532	return rc;
7533}
7534
7535static int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7536					     struct link_params *params,
7537					     u16 addr, u8 byte_cnt, u8 *o_buf)
7538{
7539	struct bnx2x *bp = params->bp;
7540	u16 val, i;
7541
7542	if (byte_cnt > 16) {
7543		DP(NETIF_MSG_LINK,
7544		   "Reading from eeprom is limited to 0xf\n");
7545		return -EINVAL;
7546	}
7547
7548	/* Need to read from 1.8000 to clear it */
7549	bnx2x_cl45_read(bp, phy,
7550			MDIO_PMA_DEVAD,
7551			MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7552			&val);
7553
7554	/* Set the read command byte count */
7555	bnx2x_cl45_write(bp, phy,
7556			 MDIO_PMA_DEVAD,
7557			 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7558			 ((byte_cnt < 2) ? 2 : byte_cnt));
7559
7560	/* Set the read command address */
7561	bnx2x_cl45_write(bp, phy,
7562			 MDIO_PMA_DEVAD,
7563			 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7564			 addr);
7565	/* Set the destination address */
7566	bnx2x_cl45_write(bp, phy,
7567			 MDIO_PMA_DEVAD,
7568			 0x8004,
7569			 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
7570
7571	/* Activate read command */
7572	bnx2x_cl45_write(bp, phy,
7573			 MDIO_PMA_DEVAD,
7574			 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7575			 0x8002);
7576	/*
7577	 * Wait appropriate time for two-wire command to finish before
7578	 * polling the status register
7579	 */
7580	msleep(1);
7581
7582	/* Wait up to 500us for command complete status */
7583	for (i = 0; i < 100; i++) {
7584		bnx2x_cl45_read(bp, phy,
7585				MDIO_PMA_DEVAD,
7586				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7587		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7588		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7589			break;
7590		udelay(5);
7591	}
7592
7593	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7594		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7595		DP(NETIF_MSG_LINK,
7596			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7597			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7598		return -EFAULT;
7599	}
7600
7601	/* Read the buffer */
7602	for (i = 0; i < byte_cnt; i++) {
7603		bnx2x_cl45_read(bp, phy,
7604				MDIO_PMA_DEVAD,
7605				MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7606		o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7607	}
7608
7609	for (i = 0; i < 100; i++) {
7610		bnx2x_cl45_read(bp, phy,
7611				MDIO_PMA_DEVAD,
7612				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7613		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7614		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
7615			return 0;
7616		msleep(1);
7617	}
7618
7619	return -EINVAL;
7620}
7621
7622int bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7623				 struct link_params *params, u16 addr,
7624				 u8 byte_cnt, u8 *o_buf)
7625{
7626	int rc = -EINVAL;
7627	switch (phy->type) {
7628	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7629		rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7630						       byte_cnt, o_buf);
7631	break;
7632	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7633	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7634		rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7635						       byte_cnt, o_buf);
7636	break;
7637	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
7638		rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
7639							   byte_cnt, o_buf);
7640	break;
7641	}
7642	return rc;
7643}
7644
7645static int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7646			      struct link_params *params,
7647			      u16 *edc_mode)
7648{
7649	struct bnx2x *bp = params->bp;
7650	u32 sync_offset = 0, phy_idx, media_types;
7651	u8 val, check_limiting_mode = 0;
7652	*edc_mode = EDC_MODE_LIMITING;
7653
7654	phy->media_type = ETH_PHY_UNSPECIFIED;
7655	/* First check for copper cable */
7656	if (bnx2x_read_sfp_module_eeprom(phy,
7657					 params,
7658					 SFP_EEPROM_CON_TYPE_ADDR,
7659					 1,
7660					 &val) != 0) {
7661		DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7662		return -EINVAL;
7663	}
7664
7665	switch (val) {
7666	case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7667	{
7668		u8 copper_module_type;
7669		phy->media_type = ETH_PHY_DA_TWINAX;
7670		/*
7671		 * Check if its active cable (includes SFP+ module)
7672		 * of passive cable
7673		 */
7674		if (bnx2x_read_sfp_module_eeprom(phy,
7675					       params,
7676					       SFP_EEPROM_FC_TX_TECH_ADDR,
7677					       1,
7678					       &copper_module_type) != 0) {
7679			DP(NETIF_MSG_LINK,
7680				"Failed to read copper-cable-type"
7681				" from SFP+ EEPROM\n");
7682			return -EINVAL;
7683		}
7684
7685		if (copper_module_type &
7686		    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7687			DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7688			check_limiting_mode = 1;
7689		} else if (copper_module_type &
7690			SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
7691				DP(NETIF_MSG_LINK,
7692				   "Passive Copper cable detected\n");
7693				*edc_mode =
7694				      EDC_MODE_PASSIVE_DAC;
7695		} else {
7696			DP(NETIF_MSG_LINK,
7697			   "Unknown copper-cable-type 0x%x !!!\n",
7698			   copper_module_type);
7699			return -EINVAL;
7700		}
7701		break;
7702	}
7703	case SFP_EEPROM_CON_TYPE_VAL_LC:
7704		phy->media_type = ETH_PHY_SFP_FIBER;
7705		DP(NETIF_MSG_LINK, "Optic module detected\n");
7706		check_limiting_mode = 1;
7707		break;
7708	default:
7709		DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7710			 val);
7711		return -EINVAL;
7712	}
7713	sync_offset = params->shmem_base +
7714		offsetof(struct shmem_region,
7715			 dev_info.port_hw_config[params->port].media_type);
7716	media_types = REG_RD(bp, sync_offset);
7717	/* Update media type for non-PMF sync */
7718	for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
7719		if (&(params->phy[phy_idx]) == phy) {
7720			media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
7721				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7722			media_types |= ((phy->media_type &
7723					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
7724				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
7725			break;
7726		}
7727	}
7728	REG_WR(bp, sync_offset, media_types);
7729	if (check_limiting_mode) {
7730		u8 options[SFP_EEPROM_OPTIONS_SIZE];
7731		if (bnx2x_read_sfp_module_eeprom(phy,
7732						 params,
7733						 SFP_EEPROM_OPTIONS_ADDR,
7734						 SFP_EEPROM_OPTIONS_SIZE,
7735						 options) != 0) {
7736			DP(NETIF_MSG_LINK,
7737			   "Failed to read Option field from module EEPROM\n");
7738			return -EINVAL;
7739		}
7740		if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
7741			*edc_mode = EDC_MODE_LINEAR;
7742		else
7743			*edc_mode = EDC_MODE_LIMITING;
7744	}
7745	DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
7746	return 0;
7747}
7748/*
7749 * This function read the relevant field from the module (SFP+), and verify it
7750 * is compliant with this board
7751 */
7752static int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
7753				   struct link_params *params)
7754{
7755	struct bnx2x *bp = params->bp;
7756	u32 val, cmd;
7757	u32 fw_resp, fw_cmd_param;
7758	char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
7759	char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
7760	phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
7761	val = REG_RD(bp, params->shmem_base +
7762			 offsetof(struct shmem_region, dev_info.
7763				  port_feature_config[params->port].config));
7764	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
7765	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
7766		DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
7767		return 0;
7768	}
7769
7770	if (params->feature_config_flags &
7771	    FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
7772		/* Use specific phy request */
7773		cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
7774	} else if (params->feature_config_flags &
7775		   FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
7776		/* Use first phy request only in case of non-dual media*/
7777		if (DUAL_MEDIA(params)) {
7778			DP(NETIF_MSG_LINK,
7779			   "FW does not support OPT MDL verification\n");
7780			return -EINVAL;
7781		}
7782		cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
7783	} else {
7784		/* No support in OPT MDL detection */
7785		DP(NETIF_MSG_LINK,
7786		   "FW does not support OPT MDL verification\n");
7787		return -EINVAL;
7788	}
7789
7790	fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
7791	fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
7792	if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
7793		DP(NETIF_MSG_LINK, "Approved module\n");
7794		return 0;
7795	}
7796
7797	/* format the warning message */
7798	if (bnx2x_read_sfp_module_eeprom(phy,
7799					 params,
7800					 SFP_EEPROM_VENDOR_NAME_ADDR,
7801					 SFP_EEPROM_VENDOR_NAME_SIZE,
7802					 (u8 *)vendor_name))
7803		vendor_name[0] = '\0';
7804	else
7805		vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
7806	if (bnx2x_read_sfp_module_eeprom(phy,
7807					 params,
7808					 SFP_EEPROM_PART_NO_ADDR,
7809					 SFP_EEPROM_PART_NO_SIZE,
7810					 (u8 *)vendor_pn))
7811		vendor_pn[0] = '\0';
7812	else
7813		vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
7814
7815	netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
7816			      " Port %d from %s part number %s\n",
7817			 params->port, vendor_name, vendor_pn);
7818	phy->flags |= FLAGS_SFP_NOT_APPROVED;
7819	return -EINVAL;
7820}
7821
7822static int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
7823						 struct link_params *params)
7824
7825{
7826	u8 val;
7827	struct bnx2x *bp = params->bp;
7828	u16 timeout;
7829	/*
7830	 * Initialization time after hot-plug may take up to 300ms for
7831	 * some phys type ( e.g. JDSU )
7832	 */
7833
7834	for (timeout = 0; timeout < 60; timeout++) {
7835		if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
7836		    == 0) {
7837			DP(NETIF_MSG_LINK,
7838			   "SFP+ module initialization took %d ms\n",
7839			   timeout * 5);
7840			return 0;
7841		}
7842		msleep(5);
7843	}
7844	return -EINVAL;
7845}
7846
7847static void bnx2x_8727_power_module(struct bnx2x *bp,
7848				    struct bnx2x_phy *phy,
7849				    u8 is_power_up) {
7850	/* Make sure GPIOs are not using for LED mode */
7851	u16 val;
7852	/*
7853	 * In the GPIO register, bit 4 is use to determine if the GPIOs are
7854	 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
7855	 * output
7856	 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
7857	 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
7858	 * where the 1st bit is the over-current(only input), and 2nd bit is
7859	 * for power( only output )
7860	 *
7861	 * In case of NOC feature is disabled and power is up, set GPIO control
7862	 *  as input to enable listening of over-current indication
7863	 */
7864	if (phy->flags & FLAGS_NOC)
7865		return;
7866	if (is_power_up)
7867		val = (1<<4);
7868	else
7869		/*
7870		 * Set GPIO control to OUTPUT, and set the power bit
7871		 * to according to the is_power_up
7872		 */
7873		val = (1<<1);
7874
7875	bnx2x_cl45_write(bp, phy,
7876			 MDIO_PMA_DEVAD,
7877			 MDIO_PMA_REG_8727_GPIO_CTRL,
7878			 val);
7879}
7880
7881static int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
7882					struct bnx2x_phy *phy,
7883					u16 edc_mode)
7884{
7885	u16 cur_limiting_mode;
7886
7887	bnx2x_cl45_read(bp, phy,
7888			MDIO_PMA_DEVAD,
7889			MDIO_PMA_REG_ROM_VER2,
7890			&cur_limiting_mode);
7891	DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
7892		 cur_limiting_mode);
7893
7894	if (edc_mode == EDC_MODE_LIMITING) {
7895		DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
7896		bnx2x_cl45_write(bp, phy,
7897				 MDIO_PMA_DEVAD,
7898				 MDIO_PMA_REG_ROM_VER2,
7899				 EDC_MODE_LIMITING);
7900	} else { /* LRM mode ( default )*/
7901
7902		DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
7903
7904		/*
7905		 * Changing to LRM mode takes quite few seconds. So do it only
7906		 * if current mode is limiting (default is LRM)
7907		 */
7908		if (cur_limiting_mode != EDC_MODE_LIMITING)
7909			return 0;
7910
7911		bnx2x_cl45_write(bp, phy,
7912				 MDIO_PMA_DEVAD,
7913				 MDIO_PMA_REG_LRM_MODE,
7914				 0);
7915		bnx2x_cl45_write(bp, phy,
7916				 MDIO_PMA_DEVAD,
7917				 MDIO_PMA_REG_ROM_VER2,
7918				 0x128);
7919		bnx2x_cl45_write(bp, phy,
7920				 MDIO_PMA_DEVAD,
7921				 MDIO_PMA_REG_MISC_CTRL0,
7922				 0x4008);
7923		bnx2x_cl45_write(bp, phy,
7924				 MDIO_PMA_DEVAD,
7925				 MDIO_PMA_REG_LRM_MODE,
7926				 0xaaaa);
7927	}
7928	return 0;
7929}
7930
7931static int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
7932					struct bnx2x_phy *phy,
7933					u16 edc_mode)
7934{
7935	u16 phy_identifier;
7936	u16 rom_ver2_val;
7937	bnx2x_cl45_read(bp, phy,
7938			MDIO_PMA_DEVAD,
7939			MDIO_PMA_REG_PHY_IDENTIFIER,
7940			&phy_identifier);
7941
7942	bnx2x_cl45_write(bp, phy,
7943			 MDIO_PMA_DEVAD,
7944			 MDIO_PMA_REG_PHY_IDENTIFIER,
7945			 (phy_identifier & ~(1<<9)));
7946
7947	bnx2x_cl45_read(bp, phy,
7948			MDIO_PMA_DEVAD,
7949			MDIO_PMA_REG_ROM_VER2,
7950			&rom_ver2_val);
7951	/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
7952	bnx2x_cl45_write(bp, phy,
7953			 MDIO_PMA_DEVAD,
7954			 MDIO_PMA_REG_ROM_VER2,
7955			 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
7956
7957	bnx2x_cl45_write(bp, phy,
7958			 MDIO_PMA_DEVAD,
7959			 MDIO_PMA_REG_PHY_IDENTIFIER,
7960			 (phy_identifier | (1<<9)));
7961
7962	return 0;
7963}
7964
7965static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
7966				     struct link_params *params,
7967				     u32 action)
7968{
7969	struct bnx2x *bp = params->bp;
7970
7971	switch (action) {
7972	case DISABLE_TX:
7973		bnx2x_sfp_set_transmitter(params, phy, 0);
7974		break;
7975	case ENABLE_TX:
7976		if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
7977			bnx2x_sfp_set_transmitter(params, phy, 1);
7978		break;
7979	default:
7980		DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
7981		   action);
7982		return;
7983	}
7984}
7985
7986static void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
7987					   u8 gpio_mode)
7988{
7989	struct bnx2x *bp = params->bp;
7990
7991	u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
7992			    offsetof(struct shmem_region,
7993			dev_info.port_hw_config[params->port].sfp_ctrl)) &
7994		PORT_HW_CFG_FAULT_MODULE_LED_MASK;
7995	switch (fault_led_gpio) {
7996	case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
7997		return;
7998	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
7999	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
8000	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
8001	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
8002	{
8003		u8 gpio_port = bnx2x_get_gpio_port(params);
8004		u16 gpio_pin = fault_led_gpio -
8005			PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
8006		DP(NETIF_MSG_LINK, "Set fault module-detected led "
8007				   "pin %x port %x mode %x\n",
8008			       gpio_pin, gpio_port, gpio_mode);
8009		bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
8010	}
8011	break;
8012	default:
8013		DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
8014			       fault_led_gpio);
8015	}
8016}
8017
8018static void bnx2x_set_e3_module_fault_led(struct link_params *params,
8019					  u8 gpio_mode)
8020{
8021	u32 pin_cfg;
8022	u8 port = params->port;
8023	struct bnx2x *bp = params->bp;
8024	pin_cfg = (REG_RD(bp, params->shmem_base +
8025			 offsetof(struct shmem_region,
8026				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
8027		PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
8028		PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
8029	DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
8030		       gpio_mode, pin_cfg);
8031	bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
8032}
8033
8034static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
8035					   u8 gpio_mode)
8036{
8037	struct bnx2x *bp = params->bp;
8038	DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
8039	if (CHIP_IS_E3(bp)) {
8040		/*
8041		 * Low ==> if SFP+ module is supported otherwise
8042		 * High ==> if SFP+ module is not on the approved vendor list
8043		 */
8044		bnx2x_set_e3_module_fault_led(params, gpio_mode);
8045	} else
8046		bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
8047}
8048
8049static void bnx2x_warpcore_power_module(struct link_params *params,
8050					struct bnx2x_phy *phy,
8051					u8 power)
8052{
8053	u32 pin_cfg;
8054	struct bnx2x *bp = params->bp;
8055
8056	pin_cfg = (REG_RD(bp, params->shmem_base +
8057			  offsetof(struct shmem_region,
8058			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
8059			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
8060			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8061
8062	if (pin_cfg == PIN_CFG_NA)
8063		return;
8064	DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
8065		       power, pin_cfg);
8066	/*
8067	 * Low ==> corresponding SFP+ module is powered
8068	 * high ==> the SFP+ module is powered down
8069	 */
8070	bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
8071}
8072
8073static void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
8074				    struct link_params *params)
8075{
8076	bnx2x_warpcore_power_module(params, phy, 0);
8077}
8078
8079static void bnx2x_power_sfp_module(struct link_params *params,
8080				   struct bnx2x_phy *phy,
8081				   u8 power)
8082{
8083	struct bnx2x *bp = params->bp;
8084	DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
8085
8086	switch (phy->type) {
8087	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8088	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8089		bnx2x_8727_power_module(params->bp, phy, power);
8090		break;
8091	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8092		bnx2x_warpcore_power_module(params, phy, power);
8093		break;
8094	default:
8095		break;
8096	}
8097}
8098static void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
8099					     struct bnx2x_phy *phy,
8100					     u16 edc_mode)
8101{
8102	u16 val = 0;
8103	u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8104	struct bnx2x *bp = params->bp;
8105
8106	u8 lane = bnx2x_get_warpcore_lane(phy, params);
8107	/* This is a global register which controls all lanes */
8108	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8109			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8110	val &= ~(0xf << (lane << 2));
8111
8112	switch (edc_mode) {
8113	case EDC_MODE_LINEAR:
8114	case EDC_MODE_LIMITING:
8115		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
8116		break;
8117	case EDC_MODE_PASSIVE_DAC:
8118		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
8119		break;
8120	default:
8121		break;
8122	}
8123
8124	val |= (mode << (lane << 2));
8125	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
8126			 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
8127	/* A must read */
8128	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
8129			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
8130
8131	/* Restart microcode to re-read the new mode */
8132	bnx2x_warpcore_reset_lane(bp, phy, 1);
8133	bnx2x_warpcore_reset_lane(bp, phy, 0);
8134
8135}
8136
8137static void bnx2x_set_limiting_mode(struct link_params *params,
8138				    struct bnx2x_phy *phy,
8139				    u16 edc_mode)
8140{
8141	switch (phy->type) {
8142	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8143		bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
8144		break;
8145	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8146	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8147		bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
8148		break;
8149	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
8150		bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
8151		break;
8152	}
8153}
8154
8155int bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
8156			       struct link_params *params)
8157{
8158	struct bnx2x *bp = params->bp;
8159	u16 edc_mode;
8160	int rc = 0;
8161
8162	u32 val = REG_RD(bp, params->shmem_base +
8163			     offsetof(struct shmem_region, dev_info.
8164				     port_feature_config[params->port].config));
8165
8166	DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
8167		 params->port);
8168	/* Power up module */
8169	bnx2x_power_sfp_module(params, phy, 1);
8170	if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8171		DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
8172		return -EINVAL;
8173	} else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8174		/* check SFP+ module compatibility */
8175		DP(NETIF_MSG_LINK, "Module verification failed!!\n");
8176		rc = -EINVAL;
8177		/* Turn on fault module-detected led */
8178		bnx2x_set_sfp_module_fault_led(params,
8179					       MISC_REGISTERS_GPIO_HIGH);
8180
8181		/* Check if need to power down the SFP+ module */
8182		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8183		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
8184			DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
8185			bnx2x_power_sfp_module(params, phy, 0);
8186			return rc;
8187		}
8188	} else {
8189		/* Turn off fault module-detected led */
8190		bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
8191	}
8192
8193	/*
8194	 * Check and set limiting mode / LRM mode on 8726. On 8727 it
8195	 * is done automatically
8196	 */
8197	bnx2x_set_limiting_mode(params, phy, edc_mode);
8198
8199	/*
8200	 * Enable transmit for this module if the module is approved, or
8201	 * if unapproved modules should also enable the Tx laser
8202	 */
8203	if (rc == 0 ||
8204	    (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8205	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8206		bnx2x_sfp_set_transmitter(params, phy, 1);
8207	else
8208		bnx2x_sfp_set_transmitter(params, phy, 0);
8209
8210	return rc;
8211}
8212
8213void bnx2x_handle_module_detect_int(struct link_params *params)
8214{
8215	struct bnx2x *bp = params->bp;
8216	struct bnx2x_phy *phy;
8217	u32 gpio_val;
8218	u8 gpio_num, gpio_port;
8219	if (CHIP_IS_E3(bp))
8220		phy = &params->phy[INT_PHY];
8221	else
8222		phy = &params->phy[EXT_PHY1];
8223
8224	if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
8225				      params->port, &gpio_num, &gpio_port) ==
8226	    -EINVAL) {
8227		DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
8228		return;
8229	}
8230
8231	/* Set valid module led off */
8232	bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
8233
8234	/* Get current gpio val reflecting module plugged in / out*/
8235	gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
8236
8237	/* Call the handling function in case module is detected */
8238	if (gpio_val == 0) {
8239		bnx2x_power_sfp_module(params, phy, 1);
8240		bnx2x_set_gpio_int(bp, gpio_num,
8241				   MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
8242				   gpio_port);
8243		if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8244			bnx2x_sfp_module_detection(phy, params);
8245		else
8246			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8247	} else {
8248		u32 val = REG_RD(bp, params->shmem_base +
8249				 offsetof(struct shmem_region, dev_info.
8250					  port_feature_config[params->port].
8251					  config));
8252		bnx2x_set_gpio_int(bp, gpio_num,
8253				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
8254				   gpio_port);
8255		/*
8256		 * Module was plugged out.
8257		 * Disable transmit for this module
8258		 */
8259		phy->media_type = ETH_PHY_NOT_PRESENT;
8260		if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8261		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
8262		    CHIP_IS_E3(bp))
8263			bnx2x_sfp_set_transmitter(params, phy, 0);
8264	}
8265}
8266
8267/******************************************************************/
8268/*		Used by 8706 and 8727                             */
8269/******************************************************************/
8270static void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8271				 struct bnx2x_phy *phy,
8272				 u16 alarm_status_offset,
8273				 u16 alarm_ctrl_offset)
8274{
8275	u16 alarm_status, val;
8276	bnx2x_cl45_read(bp, phy,
8277			MDIO_PMA_DEVAD, alarm_status_offset,
8278			&alarm_status);
8279	bnx2x_cl45_read(bp, phy,
8280			MDIO_PMA_DEVAD, alarm_status_offset,
8281			&alarm_status);
8282	/* Mask or enable the fault event. */
8283	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8284	if (alarm_status & (1<<0))
8285		val &= ~(1<<0);
8286	else
8287		val |= (1<<0);
8288	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8289}
8290/******************************************************************/
8291/*		common BCM8706/BCM8726 PHY SECTION		  */
8292/******************************************************************/
8293static u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8294				      struct link_params *params,
8295				      struct link_vars *vars)
8296{
8297	u8 link_up = 0;
8298	u16 val1, val2, rx_sd, pcs_status;
8299	struct bnx2x *bp = params->bp;
8300	DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8301	/* Clear RX Alarm*/
8302	bnx2x_cl45_read(bp, phy,
8303			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8304
8305	bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8306			     MDIO_PMA_LASI_TXCTRL);
8307
8308	/* clear LASI indication*/
8309	bnx2x_cl45_read(bp, phy,
8310			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8311	bnx2x_cl45_read(bp, phy,
8312			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
8313	DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
8314
8315	bnx2x_cl45_read(bp, phy,
8316			MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8317	bnx2x_cl45_read(bp, phy,
8318			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8319	bnx2x_cl45_read(bp, phy,
8320			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8321	bnx2x_cl45_read(bp, phy,
8322			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8323
8324	DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8325			" link_status 0x%x\n", rx_sd, pcs_status, val2);
8326	/*
8327	 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
8328	 * are set, or if the autoneg bit 1 is set
8329	 */
8330	link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8331	if (link_up) {
8332		if (val2 & (1<<1))
8333			vars->line_speed = SPEED_1000;
8334		else
8335			vars->line_speed = SPEED_10000;
8336		bnx2x_ext_phy_resolve_fc(phy, params, vars);
8337		vars->duplex = DUPLEX_FULL;
8338	}
8339
8340	/* Capture 10G link fault. Read twice to clear stale value. */
8341	if (vars->line_speed == SPEED_10000) {
8342		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8343			    MDIO_PMA_LASI_TXSTAT, &val1);
8344		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
8345			    MDIO_PMA_LASI_TXSTAT, &val1);
8346		if (val1 & (1<<0))
8347			vars->fault_detected = 1;
8348	}
8349
8350	return link_up;
8351}
8352
8353/******************************************************************/
8354/*			BCM8706 PHY SECTION			  */
8355/******************************************************************/
8356static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8357				 struct link_params *params,
8358				 struct link_vars *vars)
8359{
8360	u32 tx_en_mode;
8361	u16 cnt, val, tmp1;
8362	struct bnx2x *bp = params->bp;
8363
8364	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8365		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8366	/* HW reset */
8367	bnx2x_ext_phy_hw_reset(bp, params->port);
8368	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
8369	bnx2x_wait_reset_complete(bp, phy, params);
8370
8371	/* Wait until fw is loaded */
8372	for (cnt = 0; cnt < 100; cnt++) {
8373		bnx2x_cl45_read(bp, phy,
8374				MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8375		if (val)
8376			break;
8377		msleep(10);
8378	}
8379	DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8380	if ((params->feature_config_flags &
8381	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8382		u8 i;
8383		u16 reg;
8384		for (i = 0; i < 4; i++) {
8385			reg = MDIO_XS_8706_REG_BANK_RX0 +
8386				i*(MDIO_XS_8706_REG_BANK_RX1 -
8387				   MDIO_XS_8706_REG_BANK_RX0);
8388			bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8389			/* Clear first 3 bits of the control */
8390			val &= ~0x7;
8391			/* Set control bits according to configuration */
8392			val |= (phy->rx_preemphasis[i] & 0x7);
8393			DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8394				   " reg 0x%x <-- val 0x%x\n", reg, val);
8395			bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8396		}
8397	}
8398	/* Force speed */
8399	if (phy->req_line_speed == SPEED_10000) {
8400		DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8401
8402		bnx2x_cl45_write(bp, phy,
8403				 MDIO_PMA_DEVAD,
8404				 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8405		bnx2x_cl45_write(bp, phy,
8406				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8407				 0);
8408		/* Arm LASI for link and Tx fault. */
8409		bnx2x_cl45_write(bp, phy,
8410				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
8411	} else {
8412		/* Force 1Gbps using autoneg with 1G advertisement */
8413
8414		/* Allow CL37 through CL73 */
8415		DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8416		bnx2x_cl45_write(bp, phy,
8417				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8418
8419		/* Enable Full-Duplex advertisement on CL37 */
8420		bnx2x_cl45_write(bp, phy,
8421				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8422		/* Enable CL37 AN */
8423		bnx2x_cl45_write(bp, phy,
8424				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8425		/* 1G support */
8426		bnx2x_cl45_write(bp, phy,
8427				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
8428
8429		/* Enable clause 73 AN */
8430		bnx2x_cl45_write(bp, phy,
8431				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8432		bnx2x_cl45_write(bp, phy,
8433				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8434				 0x0400);
8435		bnx2x_cl45_write(bp, phy,
8436				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8437				 0x0004);
8438	}
8439	bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8440
8441	/*
8442	 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8443	 * power mode, if TX Laser is disabled
8444	 */
8445
8446	tx_en_mode = REG_RD(bp, params->shmem_base +
8447			    offsetof(struct shmem_region,
8448				dev_info.port_hw_config[params->port].sfp_ctrl))
8449			& PORT_HW_CFG_TX_LASER_MASK;
8450
8451	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8452		DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8453		bnx2x_cl45_read(bp, phy,
8454			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8455		tmp1 |= 0x1;
8456		bnx2x_cl45_write(bp, phy,
8457			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8458	}
8459
8460	return 0;
8461}
8462
8463static int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8464				  struct link_params *params,
8465				  struct link_vars *vars)
8466{
8467	return bnx2x_8706_8726_read_status(phy, params, vars);
8468}
8469
8470/******************************************************************/
8471/*			BCM8726 PHY SECTION			  */
8472/******************************************************************/
8473static void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8474				       struct link_params *params)
8475{
8476	struct bnx2x *bp = params->bp;
8477	DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8478	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8479}
8480
8481static void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8482					 struct link_params *params)
8483{
8484	struct bnx2x *bp = params->bp;
8485	/* Need to wait 100ms after reset */
8486	msleep(100);
8487
8488	/* Micro controller re-boot */
8489	bnx2x_cl45_write(bp, phy,
8490			 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
8491
8492	/* Set soft reset */
8493	bnx2x_cl45_write(bp, phy,
8494			 MDIO_PMA_DEVAD,
8495			 MDIO_PMA_REG_GEN_CTRL,
8496			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
8497
8498	bnx2x_cl45_write(bp, phy,
8499			 MDIO_PMA_DEVAD,
8500			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
8501
8502	bnx2x_cl45_write(bp, phy,
8503			 MDIO_PMA_DEVAD,
8504			 MDIO_PMA_REG_GEN_CTRL,
8505			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8506
8507	/* wait for 150ms for microcode load */
8508	msleep(150);
8509
8510	/* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8511	bnx2x_cl45_write(bp, phy,
8512			 MDIO_PMA_DEVAD,
8513			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8514
8515	msleep(200);
8516	bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8517}
8518
8519static u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8520				 struct link_params *params,
8521				 struct link_vars *vars)
8522{
8523	struct bnx2x *bp = params->bp;
8524	u16 val1;
8525	u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
8526	if (link_up) {
8527		bnx2x_cl45_read(bp, phy,
8528				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8529				&val1);
8530		if (val1 & (1<<15)) {
8531			DP(NETIF_MSG_LINK, "Tx is disabled\n");
8532			link_up = 0;
8533			vars->line_speed = 0;
8534		}
8535	}
8536	return link_up;
8537}
8538
8539
8540static int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8541				  struct link_params *params,
8542				  struct link_vars *vars)
8543{
8544	struct bnx2x *bp = params->bp;
8545	DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
8546
8547	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
8548	bnx2x_wait_reset_complete(bp, phy, params);
8549
8550	bnx2x_8726_external_rom_boot(phy, params);
8551
8552	/*
8553	 * Need to call module detected on initialization since the module
8554	 * detection triggered by actual module insertion might occur before
8555	 * driver is loaded, and when driver is loaded, it reset all
8556	 * registers, including the transmitter
8557	 */
8558	bnx2x_sfp_module_detection(phy, params);
8559
8560	if (phy->req_line_speed == SPEED_1000) {
8561		DP(NETIF_MSG_LINK, "Setting 1G force\n");
8562		bnx2x_cl45_write(bp, phy,
8563				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8564		bnx2x_cl45_write(bp, phy,
8565				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8566		bnx2x_cl45_write(bp, phy,
8567				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
8568		bnx2x_cl45_write(bp, phy,
8569				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8570				 0x400);
8571	} else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8572		   (phy->speed_cap_mask &
8573		      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8574		   ((phy->speed_cap_mask &
8575		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8576		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8577		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8578		/* Set Flow control */
8579		bnx2x_ext_phy_set_pause(params, phy, vars);
8580		bnx2x_cl45_write(bp, phy,
8581				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8582		bnx2x_cl45_write(bp, phy,
8583				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8584		bnx2x_cl45_write(bp, phy,
8585				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8586		bnx2x_cl45_write(bp, phy,
8587				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8588		bnx2x_cl45_write(bp, phy,
8589				MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8590		/*
8591		 * Enable RX-ALARM control to receive interrupt for 1G speed
8592		 * change
8593		 */
8594		bnx2x_cl45_write(bp, phy,
8595				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
8596		bnx2x_cl45_write(bp, phy,
8597				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8598				 0x400);
8599
8600	} else { /* Default 10G. Set only LASI control */
8601		bnx2x_cl45_write(bp, phy,
8602				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
8603	}
8604
8605	/* Set TX PreEmphasis if needed */
8606	if ((params->feature_config_flags &
8607	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8608		DP(NETIF_MSG_LINK,
8609		   "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8610			 phy->tx_preemphasis[0],
8611			 phy->tx_preemphasis[1]);
8612		bnx2x_cl45_write(bp, phy,
8613				 MDIO_PMA_DEVAD,
8614				 MDIO_PMA_REG_8726_TX_CTRL1,
8615				 phy->tx_preemphasis[0]);
8616
8617		bnx2x_cl45_write(bp, phy,
8618				 MDIO_PMA_DEVAD,
8619				 MDIO_PMA_REG_8726_TX_CTRL2,
8620				 phy->tx_preemphasis[1]);
8621	}
8622
8623	return 0;
8624
8625}
8626
8627static void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8628				  struct link_params *params)
8629{
8630	struct bnx2x *bp = params->bp;
8631	DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8632	/* Set serial boot control for external load */
8633	bnx2x_cl45_write(bp, phy,
8634			 MDIO_PMA_DEVAD,
8635			 MDIO_PMA_REG_GEN_CTRL, 0x0001);
8636}
8637
8638/******************************************************************/
8639/*			BCM8727 PHY SECTION			  */
8640/******************************************************************/
8641
8642static void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
8643				    struct link_params *params, u8 mode)
8644{
8645	struct bnx2x *bp = params->bp;
8646	u16 led_mode_bitmask = 0;
8647	u16 gpio_pins_bitmask = 0;
8648	u16 val;
8649	/* Only NOC flavor requires to set the LED specifically */
8650	if (!(phy->flags & FLAGS_NOC))
8651		return;
8652	switch (mode) {
8653	case LED_MODE_FRONT_PANEL_OFF:
8654	case LED_MODE_OFF:
8655		led_mode_bitmask = 0;
8656		gpio_pins_bitmask = 0x03;
8657		break;
8658	case LED_MODE_ON:
8659		led_mode_bitmask = 0;
8660		gpio_pins_bitmask = 0x02;
8661		break;
8662	case LED_MODE_OPER:
8663		led_mode_bitmask = 0x60;
8664		gpio_pins_bitmask = 0x11;
8665		break;
8666	}
8667	bnx2x_cl45_read(bp, phy,
8668			MDIO_PMA_DEVAD,
8669			MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8670			&val);
8671	val &= 0xff8f;
8672	val |= led_mode_bitmask;
8673	bnx2x_cl45_write(bp, phy,
8674			 MDIO_PMA_DEVAD,
8675			 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8676			 val);
8677	bnx2x_cl45_read(bp, phy,
8678			MDIO_PMA_DEVAD,
8679			MDIO_PMA_REG_8727_GPIO_CTRL,
8680			&val);
8681	val &= 0xffe0;
8682	val |= gpio_pins_bitmask;
8683	bnx2x_cl45_write(bp, phy,
8684			 MDIO_PMA_DEVAD,
8685			 MDIO_PMA_REG_8727_GPIO_CTRL,
8686			 val);
8687}
8688static void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8689				struct link_params *params) {
8690	u32 swap_val, swap_override;
8691	u8 port;
8692	/*
8693	 * The PHY reset is controlled by GPIO 1. Fake the port number
8694	 * to cancel the swap done in set_gpio()
8695	 */
8696	struct bnx2x *bp = params->bp;
8697	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8698	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8699	port = (swap_val && swap_override) ^ 1;
8700	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8701		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
8702}
8703
8704static int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8705				  struct link_params *params,
8706				  struct link_vars *vars)
8707{
8708	u32 tx_en_mode;
8709	u16 tmp1, val, mod_abs, tmp2;
8710	u16 rx_alarm_ctrl_val;
8711	u16 lasi_ctrl_val;
8712	struct bnx2x *bp = params->bp;
8713	/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8714
8715	bnx2x_wait_reset_complete(bp, phy, params);
8716	rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
8717	/* Should be 0x6 to enable XS on Tx side. */
8718	lasi_ctrl_val = 0x0006;
8719
8720	DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
8721	/* enable LASI */
8722	bnx2x_cl45_write(bp, phy,
8723			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8724			 rx_alarm_ctrl_val);
8725	bnx2x_cl45_write(bp, phy,
8726			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8727			 0);
8728	bnx2x_cl45_write(bp, phy,
8729			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
8730
8731	/*
8732	 * Initially configure MOD_ABS to interrupt when module is
8733	 * presence( bit 8)
8734	 */
8735	bnx2x_cl45_read(bp, phy,
8736			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8737	/*
8738	 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
8739	 * When the EDC is off it locks onto a reference clock and avoids
8740	 * becoming 'lost'
8741	 */
8742	mod_abs &= ~(1<<8);
8743	if (!(phy->flags & FLAGS_NOC))
8744		mod_abs &= ~(1<<9);
8745	bnx2x_cl45_write(bp, phy,
8746			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8747
8748
8749	/* Enable/Disable PHY transmitter output */
8750	bnx2x_set_disable_pmd_transmit(params, phy, 0);
8751
8752	/* Make MOD_ABS give interrupt on change */
8753	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
8754			&val);
8755	val |= (1<<12);
8756	if (phy->flags & FLAGS_NOC)
8757		val |= (3<<5);
8758
8759	/*
8760	 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
8761	 * status which reflect SFP+ module over-current
8762	 */
8763	if (!(phy->flags & FLAGS_NOC))
8764		val &= 0xff8f; /* Reset bits 4-6 */
8765	bnx2x_cl45_write(bp, phy,
8766			 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
8767
8768	bnx2x_8727_power_module(bp, phy, 1);
8769
8770	bnx2x_cl45_read(bp, phy,
8771			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
8772
8773	bnx2x_cl45_read(bp, phy,
8774			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
8775
8776	/* Set option 1G speed */
8777	if (phy->req_line_speed == SPEED_1000) {
8778		DP(NETIF_MSG_LINK, "Setting 1G force\n");
8779		bnx2x_cl45_write(bp, phy,
8780				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8781		bnx2x_cl45_write(bp, phy,
8782				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8783		bnx2x_cl45_read(bp, phy,
8784				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
8785		DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
8786		/*
8787		 * Power down the XAUI until link is up in case of dual-media
8788		 * and 1G
8789		 */
8790		if (DUAL_MEDIA(params)) {
8791			bnx2x_cl45_read(bp, phy,
8792					MDIO_PMA_DEVAD,
8793					MDIO_PMA_REG_8727_PCS_GP, &val);
8794			val |= (3<<10);
8795			bnx2x_cl45_write(bp, phy,
8796					 MDIO_PMA_DEVAD,
8797					 MDIO_PMA_REG_8727_PCS_GP, val);
8798		}
8799	} else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8800		   ((phy->speed_cap_mask &
8801		     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
8802		   ((phy->speed_cap_mask &
8803		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8804		   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8805
8806		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8807		bnx2x_cl45_write(bp, phy,
8808				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
8809		bnx2x_cl45_write(bp, phy,
8810				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
8811	} else {
8812		/*
8813		 * Since the 8727 has only single reset pin, need to set the 10G
8814		 * registers although it is default
8815		 */
8816		bnx2x_cl45_write(bp, phy,
8817				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
8818				 0x0020);
8819		bnx2x_cl45_write(bp, phy,
8820				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
8821		bnx2x_cl45_write(bp, phy,
8822				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
8823		bnx2x_cl45_write(bp, phy,
8824				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
8825				 0x0008);
8826	}
8827
8828	/*
8829	 * Set 2-wire transfer rate of SFP+ module EEPROM
8830	 * to 100Khz since some DACs(direct attached cables) do
8831	 * not work at 400Khz.
8832	 */
8833	bnx2x_cl45_write(bp, phy,
8834			 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
8835			 0xa001);
8836
8837	/* Set TX PreEmphasis if needed */
8838	if ((params->feature_config_flags &
8839	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8840		DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8841			   phy->tx_preemphasis[0],
8842			   phy->tx_preemphasis[1]);
8843		bnx2x_cl45_write(bp, phy,
8844				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
8845				 phy->tx_preemphasis[0]);
8846
8847		bnx2x_cl45_write(bp, phy,
8848				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
8849				 phy->tx_preemphasis[1]);
8850	}
8851
8852	/*
8853	 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8854	 * power mode, if TX Laser is disabled
8855	 */
8856	tx_en_mode = REG_RD(bp, params->shmem_base +
8857			    offsetof(struct shmem_region,
8858				dev_info.port_hw_config[params->port].sfp_ctrl))
8859			& PORT_HW_CFG_TX_LASER_MASK;
8860
8861	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8862
8863		DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8864		bnx2x_cl45_read(bp, phy,
8865			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
8866		tmp2 |= 0x1000;
8867		tmp2 &= 0xFFEF;
8868		bnx2x_cl45_write(bp, phy,
8869			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
8870	}
8871
8872	return 0;
8873}
8874
8875static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
8876				      struct link_params *params)
8877{
8878	struct bnx2x *bp = params->bp;
8879	u16 mod_abs, rx_alarm_status;
8880	u32 val = REG_RD(bp, params->shmem_base +
8881			     offsetof(struct shmem_region, dev_info.
8882				      port_feature_config[params->port].
8883				      config));
8884	bnx2x_cl45_read(bp, phy,
8885			MDIO_PMA_DEVAD,
8886			MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
8887	if (mod_abs & (1<<8)) {
8888
8889		/* Module is absent */
8890		DP(NETIF_MSG_LINK,
8891		   "MOD_ABS indication show module is absent\n");
8892		phy->media_type = ETH_PHY_NOT_PRESENT;
8893		/*
8894		 * 1. Set mod_abs to detect next module
8895		 *    presence event
8896		 * 2. Set EDC off by setting OPTXLOS signal input to low
8897		 *    (bit 9).
8898		 *    When the EDC is off it locks onto a reference clock and
8899		 *    avoids becoming 'lost'.
8900		 */
8901		mod_abs &= ~(1<<8);
8902		if (!(phy->flags & FLAGS_NOC))
8903			mod_abs &= ~(1<<9);
8904		bnx2x_cl45_write(bp, phy,
8905				 MDIO_PMA_DEVAD,
8906				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8907
8908		/*
8909		 * Clear RX alarm since it stays up as long as
8910		 * the mod_abs wasn't changed
8911		 */
8912		bnx2x_cl45_read(bp, phy,
8913				MDIO_PMA_DEVAD,
8914				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
8915
8916	} else {
8917		/* Module is present */
8918		DP(NETIF_MSG_LINK,
8919		   "MOD_ABS indication show module is present\n");
8920		/*
8921		 * First disable transmitter, and if the module is ok, the
8922		 * module_detection will enable it
8923		 * 1. Set mod_abs to detect next module absent event ( bit 8)
8924		 * 2. Restore the default polarity of the OPRXLOS signal and
8925		 * this signal will then correctly indicate the presence or
8926		 * absence of the Rx signal. (bit 9)
8927		 */
8928		mod_abs |= (1<<8);
8929		if (!(phy->flags & FLAGS_NOC))
8930			mod_abs |= (1<<9);
8931		bnx2x_cl45_write(bp, phy,
8932				 MDIO_PMA_DEVAD,
8933				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
8934
8935		/*
8936		 * Clear RX alarm since it stays up as long as the mod_abs
8937		 * wasn't changed. This is need to be done before calling the
8938		 * module detection, otherwise it will clear* the link update
8939		 * alarm
8940		 */
8941		bnx2x_cl45_read(bp, phy,
8942				MDIO_PMA_DEVAD,
8943				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
8944
8945
8946		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8947		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8948			bnx2x_sfp_set_transmitter(params, phy, 0);
8949
8950		if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8951			bnx2x_sfp_module_detection(phy, params);
8952		else
8953			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8954	}
8955
8956	DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
8957		   rx_alarm_status);
8958	/* No need to check link status in case of module plugged in/out */
8959}
8960
8961static u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
8962				 struct link_params *params,
8963				 struct link_vars *vars)
8964
8965{
8966	struct bnx2x *bp = params->bp;
8967	u8 link_up = 0, oc_port = params->port;
8968	u16 link_status = 0;
8969	u16 rx_alarm_status, lasi_ctrl, val1;
8970
8971	/* If PHY is not initialized, do not check link status */
8972	bnx2x_cl45_read(bp, phy,
8973			MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8974			&lasi_ctrl);
8975	if (!lasi_ctrl)
8976		return 0;
8977
8978	/* Check the LASI on Rx */
8979	bnx2x_cl45_read(bp, phy,
8980			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
8981			&rx_alarm_status);
8982	vars->line_speed = 0;
8983	DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
8984
8985	bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
8986			     MDIO_PMA_LASI_TXCTRL);
8987
8988	bnx2x_cl45_read(bp, phy,
8989			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8990
8991	DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
8992
8993	/* Clear MSG-OUT */
8994	bnx2x_cl45_read(bp, phy,
8995			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
8996
8997	/*
8998	 * If a module is present and there is need to check
8999	 * for over current
9000	 */
9001	if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
9002		/* Check over-current using 8727 GPIO0 input*/
9003		bnx2x_cl45_read(bp, phy,
9004				MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
9005				&val1);
9006
9007		if ((val1 & (1<<8)) == 0) {
9008			if (!CHIP_IS_E1x(bp))
9009				oc_port = BP_PATH(bp) + (params->port << 1);
9010			DP(NETIF_MSG_LINK,
9011			   "8727 Power fault has been detected on port %d\n",
9012			   oc_port);
9013			netdev_err(bp->dev, "Error:  Power fault on Port %d has"
9014					    " been detected and the power to "
9015					    "that SFP+ module has been removed"
9016					    " to prevent failure of the card."
9017					    " Please remove the SFP+ module and"
9018					    " restart the system to clear this"
9019					    " error.\n",
9020			 oc_port);
9021			/* Disable all RX_ALARMs except for mod_abs */
9022			bnx2x_cl45_write(bp, phy,
9023					 MDIO_PMA_DEVAD,
9024					 MDIO_PMA_LASI_RXCTRL, (1<<5));
9025
9026			bnx2x_cl45_read(bp, phy,
9027					MDIO_PMA_DEVAD,
9028					MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9029			/* Wait for module_absent_event */
9030			val1 |= (1<<8);
9031			bnx2x_cl45_write(bp, phy,
9032					 MDIO_PMA_DEVAD,
9033					 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
9034			/* Clear RX alarm */
9035			bnx2x_cl45_read(bp, phy,
9036				MDIO_PMA_DEVAD,
9037				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9038			return 0;
9039		}
9040	} /* Over current check */
9041
9042	/* When module absent bit is set, check module */
9043	if (rx_alarm_status & (1<<5)) {
9044		bnx2x_8727_handle_mod_abs(phy, params);
9045		/* Enable all mod_abs and link detection bits */
9046		bnx2x_cl45_write(bp, phy,
9047				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9048				 ((1<<5) | (1<<2)));
9049	}
9050	DP(NETIF_MSG_LINK, "Enabling 8727 TX laser if SFP is approved\n");
9051	bnx2x_8727_specific_func(phy, params, ENABLE_TX);
9052	/* If transmitter is disabled, ignore false link up indication */
9053	bnx2x_cl45_read(bp, phy,
9054			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9055	if (val1 & (1<<15)) {
9056		DP(NETIF_MSG_LINK, "Tx is disabled\n");
9057		return 0;
9058	}
9059
9060	bnx2x_cl45_read(bp, phy,
9061			MDIO_PMA_DEVAD,
9062			MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
9063
9064	/*
9065	 * Bits 0..2 --> speed detected,
9066	 * Bits 13..15--> link is down
9067	 */
9068	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
9069		link_up = 1;
9070		vars->line_speed = SPEED_10000;
9071		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
9072			   params->port);
9073	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
9074		link_up = 1;
9075		vars->line_speed = SPEED_1000;
9076		DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
9077			   params->port);
9078	} else {
9079		link_up = 0;
9080		DP(NETIF_MSG_LINK, "port %x: External link is down\n",
9081			   params->port);
9082	}
9083
9084	/* Capture 10G link fault. */
9085	if (vars->line_speed == SPEED_10000) {
9086		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9087			    MDIO_PMA_LASI_TXSTAT, &val1);
9088
9089		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
9090			    MDIO_PMA_LASI_TXSTAT, &val1);
9091
9092		if (val1 & (1<<0)) {
9093			vars->fault_detected = 1;
9094		}
9095	}
9096
9097	if (link_up) {
9098		bnx2x_ext_phy_resolve_fc(phy, params, vars);
9099		vars->duplex = DUPLEX_FULL;
9100		DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
9101	}
9102
9103	if ((DUAL_MEDIA(params)) &&
9104	    (phy->req_line_speed == SPEED_1000)) {
9105		bnx2x_cl45_read(bp, phy,
9106				MDIO_PMA_DEVAD,
9107				MDIO_PMA_REG_8727_PCS_GP, &val1);
9108		/*
9109		 * In case of dual-media board and 1G, power up the XAUI side,
9110		 * otherwise power it down. For 10G it is done automatically
9111		 */
9112		if (link_up)
9113			val1 &= ~(3<<10);
9114		else
9115			val1 |= (3<<10);
9116		bnx2x_cl45_write(bp, phy,
9117				 MDIO_PMA_DEVAD,
9118				 MDIO_PMA_REG_8727_PCS_GP, val1);
9119	}
9120	return link_up;
9121}
9122
9123static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
9124				  struct link_params *params)
9125{
9126	struct bnx2x *bp = params->bp;
9127
9128	/* Enable/Disable PHY transmitter output */
9129	bnx2x_set_disable_pmd_transmit(params, phy, 1);
9130
9131	/* Disable Transmitter */
9132	bnx2x_sfp_set_transmitter(params, phy, 0);
9133	/* Clear LASI */
9134	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
9135
9136}
9137
9138/******************************************************************/
9139/*		BCM8481/BCM84823/BCM84833 PHY SECTION	          */
9140/******************************************************************/
9141static void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
9142					   struct link_params *params)
9143{
9144	u16 val, fw_ver1, fw_ver2, cnt;
9145	u8 port;
9146	struct bnx2x *bp = params->bp;
9147
9148	port = params->port;
9149
9150	/* For the 32 bits registers in 848xx, access via MDIO2ARM interface.*/
9151	/* (1) set register 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
9152	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
9153	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9154	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
9155	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
9156	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
9157
9158	for (cnt = 0; cnt < 100; cnt++) {
9159		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9160		if (val & 1)
9161			break;
9162		udelay(5);
9163	}
9164	if (cnt == 100) {
9165		DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(1)\n");
9166		bnx2x_save_spirom_version(bp, port, 0,
9167					  phy->ver_addr);
9168		return;
9169	}
9170
9171
9172	/* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
9173	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
9174	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
9175	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
9176	for (cnt = 0; cnt < 100; cnt++) {
9177		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
9178		if (val & 1)
9179			break;
9180		udelay(5);
9181	}
9182	if (cnt == 100) {
9183		DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw version(2)\n");
9184		bnx2x_save_spirom_version(bp, port, 0,
9185					  phy->ver_addr);
9186		return;
9187	}
9188
9189	/* lower 16 bits of the register SPI_FW_STATUS */
9190	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
9191	/* upper 16 bits of register SPI_FW_STATUS */
9192	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
9193
9194	bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9195				  phy->ver_addr);
9196}
9197
9198static void bnx2x_848xx_set_led(struct bnx2x *bp,
9199				struct bnx2x_phy *phy)
9200{
9201	u16 val;
9202
9203	/* PHYC_CTL_LED_CTL */
9204	bnx2x_cl45_read(bp, phy,
9205			MDIO_PMA_DEVAD,
9206			MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
9207	val &= 0xFE00;
9208	val |= 0x0092;
9209
9210	bnx2x_cl45_write(bp, phy,
9211			 MDIO_PMA_DEVAD,
9212			 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
9213
9214	bnx2x_cl45_write(bp, phy,
9215			 MDIO_PMA_DEVAD,
9216			 MDIO_PMA_REG_8481_LED1_MASK,
9217			 0x80);
9218
9219	bnx2x_cl45_write(bp, phy,
9220			 MDIO_PMA_DEVAD,
9221			 MDIO_PMA_REG_8481_LED2_MASK,
9222			 0x18);
9223
9224	/* Select activity source by Tx and Rx, as suggested by PHY AE */
9225	bnx2x_cl45_write(bp, phy,
9226			 MDIO_PMA_DEVAD,
9227			 MDIO_PMA_REG_8481_LED3_MASK,
9228			 0x0006);
9229
9230	/* Select the closest activity blink rate to that in 10/100/1000 */
9231	bnx2x_cl45_write(bp, phy,
9232			MDIO_PMA_DEVAD,
9233			MDIO_PMA_REG_8481_LED3_BLINK,
9234			0);
9235
9236	bnx2x_cl45_read(bp, phy,
9237			MDIO_PMA_DEVAD,
9238			MDIO_PMA_REG_84823_CTL_LED_CTL_1, &val);
9239	val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
9240
9241	bnx2x_cl45_write(bp, phy,
9242			 MDIO_PMA_DEVAD,
9243			 MDIO_PMA_REG_84823_CTL_LED_CTL_1, val);
9244
9245	/* 'Interrupt Mask' */
9246	bnx2x_cl45_write(bp, phy,
9247			 MDIO_AN_DEVAD,
9248			 0xFFFB, 0xFFFD);
9249}
9250
9251static int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9252				       struct link_params *params,
9253				       struct link_vars *vars)
9254{
9255	struct bnx2x *bp = params->bp;
9256	u16 autoneg_val, an_1000_val, an_10_100_val;
9257	u16 tmp_req_line_speed;
9258
9259	tmp_req_line_speed = phy->req_line_speed;
9260	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9261		if (phy->req_line_speed == SPEED_10000)
9262			phy->req_line_speed = SPEED_AUTO_NEG;
9263
9264	/*
9265	 * This phy uses the NIG latch mechanism since link indication
9266	 * arrives through its LED4 and not via its LASI signal, so we
9267	 * get steady signal instead of clear on read
9268	 */
9269	bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9270		      1 << NIG_LATCH_BC_ENABLE_MI_INT);
9271
9272	bnx2x_cl45_write(bp, phy,
9273			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9274
9275	bnx2x_848xx_set_led(bp, phy);
9276
9277	/* set 1000 speed advertisement */
9278	bnx2x_cl45_read(bp, phy,
9279			MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9280			&an_1000_val);
9281
9282	bnx2x_ext_phy_set_pause(params, phy, vars);
9283	bnx2x_cl45_read(bp, phy,
9284			MDIO_AN_DEVAD,
9285			MDIO_AN_REG_8481_LEGACY_AN_ADV,
9286			&an_10_100_val);
9287	bnx2x_cl45_read(bp, phy,
9288			MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9289			&autoneg_val);
9290	/* Disable forced speed */
9291	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9292	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9293
9294	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9295	     (phy->speed_cap_mask &
9296	     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9297	    (phy->req_line_speed == SPEED_1000)) {
9298		an_1000_val |= (1<<8);
9299		autoneg_val |= (1<<9 | 1<<12);
9300		if (phy->req_duplex == DUPLEX_FULL)
9301			an_1000_val |= (1<<9);
9302		DP(NETIF_MSG_LINK, "Advertising 1G\n");
9303	} else
9304		an_1000_val &= ~((1<<8) | (1<<9));
9305
9306	bnx2x_cl45_write(bp, phy,
9307			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9308			 an_1000_val);
9309
9310	/* set 100 speed advertisement */
9311	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9312	     (phy->speed_cap_mask &
9313	      (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
9314	       PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)) &&
9315	     (phy->supported &
9316	      (SUPPORTED_100baseT_Half |
9317	       SUPPORTED_100baseT_Full)))) {
9318		an_10_100_val |= (1<<7);
9319		/* Enable autoneg and restart autoneg for legacy speeds */
9320		autoneg_val |= (1<<9 | 1<<12);
9321
9322		if (phy->req_duplex == DUPLEX_FULL)
9323			an_10_100_val |= (1<<8);
9324		DP(NETIF_MSG_LINK, "Advertising 100M\n");
9325	}
9326	/* set 10 speed advertisement */
9327	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9328	     (phy->speed_cap_mask &
9329	      (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
9330	       PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
9331	     (phy->supported &
9332	      (SUPPORTED_10baseT_Half |
9333	       SUPPORTED_10baseT_Full)))) {
9334		an_10_100_val |= (1<<5);
9335		autoneg_val |= (1<<9 | 1<<12);
9336		if (phy->req_duplex == DUPLEX_FULL)
9337			an_10_100_val |= (1<<6);
9338		DP(NETIF_MSG_LINK, "Advertising 10M\n");
9339	}
9340
9341	/* Only 10/100 are allowed to work in FORCE mode */
9342	if ((phy->req_line_speed == SPEED_100) &&
9343	    (phy->supported &
9344	     (SUPPORTED_100baseT_Half |
9345	      SUPPORTED_100baseT_Full))) {
9346		autoneg_val |= (1<<13);
9347		/* Enabled AUTO-MDIX when autoneg is disabled */
9348		bnx2x_cl45_write(bp, phy,
9349				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9350				 (1<<15 | 1<<9 | 7<<0));
9351		DP(NETIF_MSG_LINK, "Setting 100M force\n");
9352	}
9353	if ((phy->req_line_speed == SPEED_10) &&
9354	    (phy->supported &
9355	     (SUPPORTED_10baseT_Half |
9356	      SUPPORTED_10baseT_Full))) {
9357		/* Enabled AUTO-MDIX when autoneg is disabled */
9358		bnx2x_cl45_write(bp, phy,
9359				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9360				 (1<<15 | 1<<9 | 7<<0));
9361		DP(NETIF_MSG_LINK, "Setting 10M force\n");
9362	}
9363
9364	bnx2x_cl45_write(bp, phy,
9365			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9366			 an_10_100_val);
9367
9368	if (phy->req_duplex == DUPLEX_FULL)
9369		autoneg_val |= (1<<8);
9370
9371	/*
9372	 * Always write this if this is not 84833.
9373	 * For 84833, write it only when it's a forced speed.
9374	 */
9375	if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9376		((autoneg_val & (1<<12)) == 0))
9377		bnx2x_cl45_write(bp, phy,
9378			 MDIO_AN_DEVAD,
9379			 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9380
9381	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9382	    (phy->speed_cap_mask &
9383	     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9384		(phy->req_line_speed == SPEED_10000)) {
9385			DP(NETIF_MSG_LINK, "Advertising 10G\n");
9386			/* Restart autoneg for 10G*/
9387
9388			bnx2x_cl45_write(bp, phy,
9389				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9390				 0x3200);
9391	} else
9392		bnx2x_cl45_write(bp, phy,
9393				 MDIO_AN_DEVAD,
9394				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9395				 1);
9396
9397	/* Save spirom version */
9398	bnx2x_save_848xx_spirom_version(phy, params);
9399
9400	phy->req_line_speed = tmp_req_line_speed;
9401
9402	return 0;
9403}
9404
9405static int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9406				  struct link_params *params,
9407				  struct link_vars *vars)
9408{
9409	struct bnx2x *bp = params->bp;
9410	/* Restore normal power mode*/
9411	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9412		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9413
9414	/* HW reset */
9415	bnx2x_ext_phy_hw_reset(bp, params->port);
9416	bnx2x_wait_reset_complete(bp, phy, params);
9417
9418	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9419	return bnx2x_848xx_cmn_config_init(phy, params, vars);
9420}
9421
9422
9423#define PHY84833_HDSHK_WAIT 300
9424static int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9425				   struct link_params *params,
9426				   struct link_vars *vars)
9427{
9428	u32 idx;
9429	u32 pair_swap;
9430	u16 val;
9431	u16 data;
9432	struct bnx2x *bp = params->bp;
9433	/* Do pair swap */
9434
9435	/* Check for configuration. */
9436	pair_swap = REG_RD(bp, params->shmem_base +
9437			   offsetof(struct shmem_region,
9438			dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
9439		PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
9440
9441	if (pair_swap == 0)
9442		return 0;
9443
9444	data = (u16)pair_swap;
9445
9446	/* Write CMD_OPEN_OVERRIDE to STATUS reg */
9447	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9448			MDIO_84833_TOP_CFG_SCRATCH_REG2,
9449			PHY84833_CMD_OPEN_OVERRIDE);
9450	for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9451		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9452				MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9453		if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9454			break;
9455		msleep(1);
9456	}
9457	if (idx >= PHY84833_HDSHK_WAIT) {
9458		DP(NETIF_MSG_LINK, "Pairswap: FW not ready.\n");
9459		return -EINVAL;
9460	}
9461
9462	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9463			MDIO_84833_TOP_CFG_SCRATCH_REG4,
9464			data);
9465	/* Issue pair swap command */
9466	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9467			MDIO_84833_TOP_CFG_SCRATCH_REG0,
9468			PHY84833_DIAG_CMD_PAIR_SWAP_CHANGE);
9469	for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9470		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9471				MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9472		if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9473			(val == PHY84833_CMD_COMPLETE_ERROR))
9474			break;
9475		msleep(1);
9476	}
9477	if ((idx >= PHY84833_HDSHK_WAIT) ||
9478		(val == PHY84833_CMD_COMPLETE_ERROR)) {
9479		DP(NETIF_MSG_LINK, "Pairswap: override failed.\n");
9480		return -EINVAL;
9481	}
9482	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9483			MDIO_84833_TOP_CFG_SCRATCH_REG2,
9484			PHY84833_CMD_CLEAR_COMPLETE);
9485	DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data);
9486	return 0;
9487}
9488
9489
9490static u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
9491				      u32 shmem_base_path[],
9492				      u32 chip_id)
9493{
9494	u32 reset_pin[2];
9495	u32 idx;
9496	u8 reset_gpios;
9497	if (CHIP_IS_E3(bp)) {
9498		/* Assume that these will be GPIOs, not EPIOs. */
9499		for (idx = 0; idx < 2; idx++) {
9500			/* Map config param to register bit. */
9501			reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9502				offsetof(struct shmem_region,
9503				dev_info.port_hw_config[0].e3_cmn_pin_cfg));
9504			reset_pin[idx] = (reset_pin[idx] &
9505				PORT_HW_CFG_E3_PHY_RESET_MASK) >>
9506				PORT_HW_CFG_E3_PHY_RESET_SHIFT;
9507			reset_pin[idx] -= PIN_CFG_GPIO0_P0;
9508			reset_pin[idx] = (1 << reset_pin[idx]);
9509		}
9510		reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9511	} else {
9512		/* E2, look from diff place of shmem. */
9513		for (idx = 0; idx < 2; idx++) {
9514			reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
9515				offsetof(struct shmem_region,
9516				dev_info.port_hw_config[0].default_cfg));
9517			reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
9518			reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
9519			reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
9520			reset_pin[idx] = (1 << reset_pin[idx]);
9521		}
9522		reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
9523	}
9524
9525	return reset_gpios;
9526}
9527
9528static int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
9529				struct link_params *params)
9530{
9531	struct bnx2x *bp = params->bp;
9532	u8 reset_gpios;
9533	u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
9534				offsetof(struct shmem2_region,
9535				other_shmem_base_addr));
9536
9537	u32 shmem_base_path[2];
9538	shmem_base_path[0] = params->shmem_base;
9539	shmem_base_path[1] = other_shmem_base_addr;
9540
9541	reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9542						  params->chip_id);
9543
9544	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9545	udelay(10);
9546	DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
9547		reset_gpios);
9548
9549	return 0;
9550}
9551
9552static int bnx2x_84833_common_init_phy(struct bnx2x *bp,
9553						u32 shmem_base_path[],
9554						u32 chip_id)
9555{
9556	u8 reset_gpios;
9557
9558	reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
9559
9560	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9561	udelay(10);
9562	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
9563	msleep(800);
9564	DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
9565		reset_gpios);
9566
9567	return 0;
9568}
9569
9570#define PHY84833_CONSTANT_LATENCY 1193
9571static int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9572				   struct link_params *params,
9573				   struct link_vars *vars)
9574{
9575	struct bnx2x *bp = params->bp;
9576	u8 port, initialize = 1;
9577	u16 val;
9578	u16 temp;
9579	u32 actual_phy_selection, cms_enable, idx;
9580	int rc = 0;
9581
9582	msleep(1);
9583
9584	if (!(CHIP_IS_E1(bp)))
9585		port = BP_PATH(bp);
9586	else
9587		port = params->port;
9588
9589	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9590		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9591			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9592			       port);
9593	} else {
9594		/* MDIO reset */
9595		bnx2x_cl45_write(bp, phy,
9596				MDIO_PMA_DEVAD,
9597				MDIO_PMA_REG_CTRL, 0x8000);
9598		/* Bring PHY out of super isolate mode */
9599		bnx2x_cl45_read(bp, phy,
9600				MDIO_CTL_DEVAD,
9601				MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
9602		val &= ~MDIO_84833_SUPER_ISOLATE;
9603		bnx2x_cl45_write(bp, phy,
9604				MDIO_CTL_DEVAD,
9605				MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
9606	}
9607
9608	bnx2x_wait_reset_complete(bp, phy, params);
9609
9610	/* Wait for GPHY to come out of reset */
9611	msleep(50);
9612
9613	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9614		bnx2x_84833_pair_swap_cfg(phy, params, vars);
9615
9616	/*
9617	 * BCM84823 requires that XGXS links up first @ 10G for normal behavior
9618	 */
9619	temp = vars->line_speed;
9620	vars->line_speed = SPEED_10000;
9621	bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
9622	bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
9623	vars->line_speed = temp;
9624
9625	/* Set dual-media configuration according to configuration */
9626
9627	bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9628			MDIO_CTL_REG_84823_MEDIA, &val);
9629	val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9630		 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9631		 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9632		 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9633		 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
9634
9635	if (CHIP_IS_E3(bp)) {
9636		val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9637			 MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
9638	} else {
9639		val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
9640			MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
9641	}
9642
9643	actual_phy_selection = bnx2x_phy_selection(params);
9644
9645	switch (actual_phy_selection) {
9646	case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
9647		/* Do nothing. Essentially this is like the priority copper */
9648		break;
9649	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9650		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9651		break;
9652	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9653		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9654		break;
9655	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9656		/* Do nothing here. The first PHY won't be initialized at all */
9657		break;
9658	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9659		val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9660		initialize = 0;
9661		break;
9662	}
9663	if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9664		val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9665
9666	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9667			 MDIO_CTL_REG_84823_MEDIA, val);
9668	DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9669		   params->multi_phy_config, val);
9670
9671	/* AutogrEEEn */
9672	if (params->feature_config_flags &
9673		FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
9674		/* Ensure that f/w is ready */
9675		for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9676			bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9677					MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9678			if (val == PHY84833_CMD_OPEN_FOR_CMDS)
9679				break;
9680			usleep_range(1000, 1000);
9681		}
9682		if (idx >= PHY84833_HDSHK_WAIT) {
9683			DP(NETIF_MSG_LINK, "AutogrEEEn: FW not ready.\n");
9684			return -EINVAL;
9685		}
9686
9687		/* Select EEE mode */
9688		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9689				MDIO_84833_TOP_CFG_SCRATCH_REG3,
9690				0x2);
9691
9692		/* Set Idle and Latency */
9693		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9694				MDIO_84833_TOP_CFG_SCRATCH_REG4,
9695				PHY84833_CONSTANT_LATENCY + 1);
9696
9697		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9698				MDIO_84833_TOP_CFG_DATA3_REG,
9699				PHY84833_CONSTANT_LATENCY + 1);
9700
9701		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9702				MDIO_84833_TOP_CFG_DATA4_REG,
9703				PHY84833_CONSTANT_LATENCY);
9704
9705		/* Send EEE instruction to command register */
9706		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9707				MDIO_84833_TOP_CFG_SCRATCH_REG0,
9708				PHY84833_DIAG_CMD_SET_EEE_MODE);
9709
9710		/* Ensure that the command has completed */
9711		for (idx = 0; idx < PHY84833_HDSHK_WAIT; idx++) {
9712			bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9713					MDIO_84833_TOP_CFG_SCRATCH_REG2, &val);
9714			if ((val == PHY84833_CMD_COMPLETE_PASS) ||
9715				(val == PHY84833_CMD_COMPLETE_ERROR))
9716				break;
9717			usleep_range(1000, 1000);
9718		}
9719		if ((idx >= PHY84833_HDSHK_WAIT) ||
9720			(val == PHY84833_CMD_COMPLETE_ERROR)) {
9721			DP(NETIF_MSG_LINK, "AutogrEEEn: command failed.\n");
9722			return -EINVAL;
9723		}
9724
9725		/* Reset command handler */
9726		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9727			    MDIO_84833_TOP_CFG_SCRATCH_REG2,
9728			    PHY84833_CMD_CLEAR_COMPLETE);
9729	}
9730
9731	if (initialize)
9732		rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9733	else
9734		bnx2x_save_848xx_spirom_version(phy, params);
9735	/* 84833 PHY has a better feature and doesn't need to support this. */
9736	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9737		cms_enable = REG_RD(bp, params->shmem_base +
9738			offsetof(struct shmem_region,
9739			dev_info.port_hw_config[params->port].default_cfg)) &
9740			PORT_HW_CFG_ENABLE_CMS_MASK;
9741
9742		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9743				MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
9744		if (cms_enable)
9745			val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
9746		else
9747			val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
9748		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9749				 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
9750	}
9751
9752	return rc;
9753}
9754
9755static u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
9756				  struct link_params *params,
9757				  struct link_vars *vars)
9758{
9759	struct bnx2x *bp = params->bp;
9760	u16 val, val1, val2;
9761	u8 link_up = 0;
9762
9763
9764	/* Check 10G-BaseT link status */
9765	/* Check PMD signal ok */
9766	bnx2x_cl45_read(bp, phy,
9767			MDIO_AN_DEVAD, 0xFFFA, &val1);
9768	bnx2x_cl45_read(bp, phy,
9769			MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
9770			&val2);
9771	DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
9772
9773	/* Check link 10G */
9774	if (val2 & (1<<11)) {
9775		vars->line_speed = SPEED_10000;
9776		vars->duplex = DUPLEX_FULL;
9777		link_up = 1;
9778		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
9779	} else { /* Check Legacy speed link */
9780		u16 legacy_status, legacy_speed;
9781
9782		/* Enable expansion register 0x42 (Operation mode status) */
9783		bnx2x_cl45_write(bp, phy,
9784				 MDIO_AN_DEVAD,
9785				 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
9786
9787		/* Get legacy speed operation status */
9788		bnx2x_cl45_read(bp, phy,
9789				MDIO_AN_DEVAD,
9790				MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
9791				&legacy_status);
9792
9793		DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n",
9794		   legacy_status);
9795		link_up = ((legacy_status & (1<<11)) == (1<<11));
9796		if (link_up) {
9797			legacy_speed = (legacy_status & (3<<9));
9798			if (legacy_speed == (0<<9))
9799				vars->line_speed = SPEED_10;
9800			else if (legacy_speed == (1<<9))
9801				vars->line_speed = SPEED_100;
9802			else if (legacy_speed == (2<<9))
9803				vars->line_speed = SPEED_1000;
9804			else /* Should not happen */
9805				vars->line_speed = 0;
9806
9807			if (legacy_status & (1<<8))
9808				vars->duplex = DUPLEX_FULL;
9809			else
9810				vars->duplex = DUPLEX_HALF;
9811
9812			DP(NETIF_MSG_LINK,
9813			   "Link is up in %dMbps, is_duplex_full= %d\n",
9814			   vars->line_speed,
9815			   (vars->duplex == DUPLEX_FULL));
9816			/* Check legacy speed AN resolution */
9817			bnx2x_cl45_read(bp, phy,
9818					MDIO_AN_DEVAD,
9819					MDIO_AN_REG_8481_LEGACY_MII_STATUS,
9820					&val);
9821			if (val & (1<<5))
9822				vars->link_status |=
9823					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
9824			bnx2x_cl45_read(bp, phy,
9825					MDIO_AN_DEVAD,
9826					MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
9827					&val);
9828			if ((val & (1<<0)) == 0)
9829				vars->link_status |=
9830					LINK_STATUS_PARALLEL_DETECTION_USED;
9831		}
9832	}
9833	if (link_up) {
9834		DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
9835			   vars->line_speed);
9836		bnx2x_ext_phy_resolve_fc(phy, params, vars);
9837	}
9838
9839	return link_up;
9840}
9841
9842
9843static int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
9844{
9845	int status = 0;
9846	u32 spirom_ver;
9847	spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
9848	status = bnx2x_format_ver(spirom_ver, str, len);
9849	return status;
9850}
9851
9852static void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
9853				struct link_params *params)
9854{
9855	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9856		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
9857	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
9858		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
9859}
9860
9861static void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
9862					struct link_params *params)
9863{
9864	bnx2x_cl45_write(params->bp, phy,
9865			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
9866	bnx2x_cl45_write(params->bp, phy,
9867			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
9868}
9869
9870static void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
9871				   struct link_params *params)
9872{
9873	struct bnx2x *bp = params->bp;
9874	u8 port;
9875	u16 val16;
9876
9877	if (!(CHIP_IS_E1(bp)))
9878		port = BP_PATH(bp);
9879	else
9880		port = params->port;
9881
9882	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9883		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9884			       MISC_REGISTERS_GPIO_OUTPUT_LOW,
9885			       port);
9886	} else {
9887		bnx2x_cl45_read(bp, phy,
9888				MDIO_CTL_DEVAD,
9889				0x400f, &val16);
9890		bnx2x_cl45_write(bp, phy,
9891				MDIO_PMA_DEVAD,
9892				MDIO_PMA_REG_CTRL, 0x800);
9893	}
9894}
9895
9896static void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
9897				     struct link_params *params, u8 mode)
9898{
9899	struct bnx2x *bp = params->bp;
9900	u16 val;
9901	u8 port;
9902
9903	if (!(CHIP_IS_E1(bp)))
9904		port = BP_PATH(bp);
9905	else
9906		port = params->port;
9907
9908	switch (mode) {
9909	case LED_MODE_OFF:
9910
9911		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
9912
9913		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9914		    SHARED_HW_CFG_LED_EXTPHY1) {
9915
9916			/* Set LED masks */
9917			bnx2x_cl45_write(bp, phy,
9918					MDIO_PMA_DEVAD,
9919					MDIO_PMA_REG_8481_LED1_MASK,
9920					0x0);
9921
9922			bnx2x_cl45_write(bp, phy,
9923					MDIO_PMA_DEVAD,
9924					MDIO_PMA_REG_8481_LED2_MASK,
9925					0x0);
9926
9927			bnx2x_cl45_write(bp, phy,
9928					MDIO_PMA_DEVAD,
9929					MDIO_PMA_REG_8481_LED3_MASK,
9930					0x0);
9931
9932			bnx2x_cl45_write(bp, phy,
9933					MDIO_PMA_DEVAD,
9934					MDIO_PMA_REG_8481_LED5_MASK,
9935					0x0);
9936
9937		} else {
9938			bnx2x_cl45_write(bp, phy,
9939					 MDIO_PMA_DEVAD,
9940					 MDIO_PMA_REG_8481_LED1_MASK,
9941					 0x0);
9942		}
9943		break;
9944	case LED_MODE_FRONT_PANEL_OFF:
9945
9946		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
9947		   port);
9948
9949		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9950		    SHARED_HW_CFG_LED_EXTPHY1) {
9951
9952			/* Set LED masks */
9953			bnx2x_cl45_write(bp, phy,
9954					 MDIO_PMA_DEVAD,
9955					 MDIO_PMA_REG_8481_LED1_MASK,
9956					 0x0);
9957
9958			bnx2x_cl45_write(bp, phy,
9959					 MDIO_PMA_DEVAD,
9960					 MDIO_PMA_REG_8481_LED2_MASK,
9961					 0x0);
9962
9963			bnx2x_cl45_write(bp, phy,
9964					 MDIO_PMA_DEVAD,
9965					 MDIO_PMA_REG_8481_LED3_MASK,
9966					 0x0);
9967
9968			bnx2x_cl45_write(bp, phy,
9969					 MDIO_PMA_DEVAD,
9970					 MDIO_PMA_REG_8481_LED5_MASK,
9971					 0x20);
9972
9973		} else {
9974			bnx2x_cl45_write(bp, phy,
9975					 MDIO_PMA_DEVAD,
9976					 MDIO_PMA_REG_8481_LED1_MASK,
9977					 0x0);
9978		}
9979		break;
9980	case LED_MODE_ON:
9981
9982		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
9983
9984		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
9985		    SHARED_HW_CFG_LED_EXTPHY1) {
9986			/* Set control reg */
9987			bnx2x_cl45_read(bp, phy,
9988					MDIO_PMA_DEVAD,
9989					MDIO_PMA_REG_8481_LINK_SIGNAL,
9990					&val);
9991			val &= 0x8000;
9992			val |= 0x2492;
9993
9994			bnx2x_cl45_write(bp, phy,
9995					 MDIO_PMA_DEVAD,
9996					 MDIO_PMA_REG_8481_LINK_SIGNAL,
9997					 val);
9998
9999			/* Set LED masks */
10000			bnx2x_cl45_write(bp, phy,
10001					 MDIO_PMA_DEVAD,
10002					 MDIO_PMA_REG_8481_LED1_MASK,
10003					 0x0);
10004
10005			bnx2x_cl45_write(bp, phy,
10006					 MDIO_PMA_DEVAD,
10007					 MDIO_PMA_REG_8481_LED2_MASK,
10008					 0x20);
10009
10010			bnx2x_cl45_write(bp, phy,
10011					 MDIO_PMA_DEVAD,
10012					 MDIO_PMA_REG_8481_LED3_MASK,
10013					 0x20);
10014
10015			bnx2x_cl45_write(bp, phy,
10016					 MDIO_PMA_DEVAD,
10017					 MDIO_PMA_REG_8481_LED5_MASK,
10018					 0x0);
10019		} else {
10020			bnx2x_cl45_write(bp, phy,
10021					 MDIO_PMA_DEVAD,
10022					 MDIO_PMA_REG_8481_LED1_MASK,
10023					 0x20);
10024		}
10025		break;
10026
10027	case LED_MODE_OPER:
10028
10029		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
10030
10031		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
10032		    SHARED_HW_CFG_LED_EXTPHY1) {
10033
10034			/* Set control reg */
10035			bnx2x_cl45_read(bp, phy,
10036					MDIO_PMA_DEVAD,
10037					MDIO_PMA_REG_8481_LINK_SIGNAL,
10038					&val);
10039
10040			if (!((val &
10041			       MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
10042			  >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
10043				DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
10044				bnx2x_cl45_write(bp, phy,
10045						 MDIO_PMA_DEVAD,
10046						 MDIO_PMA_REG_8481_LINK_SIGNAL,
10047						 0xa492);
10048			}
10049
10050			/* Set LED masks */
10051			bnx2x_cl45_write(bp, phy,
10052					 MDIO_PMA_DEVAD,
10053					 MDIO_PMA_REG_8481_LED1_MASK,
10054					 0x10);
10055
10056			bnx2x_cl45_write(bp, phy,
10057					 MDIO_PMA_DEVAD,
10058					 MDIO_PMA_REG_8481_LED2_MASK,
10059					 0x80);
10060
10061			bnx2x_cl45_write(bp, phy,
10062					 MDIO_PMA_DEVAD,
10063					 MDIO_PMA_REG_8481_LED3_MASK,
10064					 0x98);
10065
10066			bnx2x_cl45_write(bp, phy,
10067					 MDIO_PMA_DEVAD,
10068					 MDIO_PMA_REG_8481_LED5_MASK,
10069					 0x40);
10070
10071		} else {
10072			bnx2x_cl45_write(bp, phy,
10073					 MDIO_PMA_DEVAD,
10074					 MDIO_PMA_REG_8481_LED1_MASK,
10075					 0x80);
10076
10077			/* Tell LED3 to blink on source */
10078			bnx2x_cl45_read(bp, phy,
10079					MDIO_PMA_DEVAD,
10080					MDIO_PMA_REG_8481_LINK_SIGNAL,
10081					&val);
10082			val &= ~(7<<6);
10083			val |= (1<<6); /* A83B[8:6]= 1 */
10084			bnx2x_cl45_write(bp, phy,
10085					 MDIO_PMA_DEVAD,
10086					 MDIO_PMA_REG_8481_LINK_SIGNAL,
10087					 val);
10088		}
10089		break;
10090	}
10091
10092	/*
10093	 * This is a workaround for E3+84833 until autoneg
10094	 * restart is fixed in f/w
10095	 */
10096	if (CHIP_IS_E3(bp)) {
10097		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
10098				MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
10099	}
10100}
10101
10102/******************************************************************/
10103/*			54618SE PHY SECTION			  */
10104/******************************************************************/
10105static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
10106					       struct link_params *params,
10107					       struct link_vars *vars)
10108{
10109	struct bnx2x *bp = params->bp;
10110	u8 port;
10111	u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
10112	u32 cfg_pin;
10113
10114	DP(NETIF_MSG_LINK, "54618SE cfg init\n");
10115	usleep_range(1000, 1000);
10116
10117	/* This works with E3 only, no need to check the chip
10118	   before determining the port. */
10119	port = params->port;
10120
10121	cfg_pin = (REG_RD(bp, params->shmem_base +
10122			offsetof(struct shmem_region,
10123			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10124			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10125			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10126
10127	/* Drive pin high to bring the GPHY out of reset. */
10128	bnx2x_set_cfg_pin(bp, cfg_pin, 1);
10129
10130	/* wait for GPHY to reset */
10131	msleep(50);
10132
10133	/* reset phy */
10134	bnx2x_cl22_write(bp, phy,
10135			 MDIO_PMA_REG_CTRL, 0x8000);
10136	bnx2x_wait_reset_complete(bp, phy, params);
10137
10138	/*wait for GPHY to reset */
10139	msleep(50);
10140
10141	/* Configure LED4: set to INTR (0x6). */
10142	/* Accessing shadow register 0xe. */
10143	bnx2x_cl22_write(bp, phy,
10144			MDIO_REG_GPHY_SHADOW,
10145			MDIO_REG_GPHY_SHADOW_LED_SEL2);
10146	bnx2x_cl22_read(bp, phy,
10147			MDIO_REG_GPHY_SHADOW,
10148			&temp);
10149	temp &= ~(0xf << 4);
10150	temp |= (0x6 << 4);
10151	bnx2x_cl22_write(bp, phy,
10152			MDIO_REG_GPHY_SHADOW,
10153			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10154	/* Configure INTR based on link status change. */
10155	bnx2x_cl22_write(bp, phy,
10156			MDIO_REG_INTR_MASK,
10157			~MDIO_REG_INTR_MASK_LINK_STATUS);
10158
10159	/* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
10160	bnx2x_cl22_write(bp, phy,
10161			MDIO_REG_GPHY_SHADOW,
10162			MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
10163	bnx2x_cl22_read(bp, phy,
10164			MDIO_REG_GPHY_SHADOW,
10165			&temp);
10166	temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
10167	bnx2x_cl22_write(bp, phy,
10168			MDIO_REG_GPHY_SHADOW,
10169			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
10170
10171	/* Set up fc */
10172	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
10173	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
10174	fc_val = 0;
10175	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
10176			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
10177		fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
10178
10179	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
10180			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
10181		fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
10182
10183	/* read all advertisement */
10184	bnx2x_cl22_read(bp, phy,
10185			0x09,
10186			&an_1000_val);
10187
10188	bnx2x_cl22_read(bp, phy,
10189			0x04,
10190			&an_10_100_val);
10191
10192	bnx2x_cl22_read(bp, phy,
10193			MDIO_PMA_REG_CTRL,
10194			&autoneg_val);
10195
10196	/* Disable forced speed */
10197	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
10198	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
10199			   (1<<11));
10200
10201	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10202			(phy->speed_cap_mask &
10203			PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
10204			(phy->req_line_speed == SPEED_1000)) {
10205		an_1000_val |= (1<<8);
10206		autoneg_val |= (1<<9 | 1<<12);
10207		if (phy->req_duplex == DUPLEX_FULL)
10208			an_1000_val |= (1<<9);
10209		DP(NETIF_MSG_LINK, "Advertising 1G\n");
10210	} else
10211		an_1000_val &= ~((1<<8) | (1<<9));
10212
10213	bnx2x_cl22_write(bp, phy,
10214			0x09,
10215			an_1000_val);
10216	bnx2x_cl22_read(bp, phy,
10217			0x09,
10218			&an_1000_val);
10219
10220	/* set 100 speed advertisement */
10221	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10222			(phy->speed_cap_mask &
10223			(PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
10224			PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
10225		an_10_100_val |= (1<<7);
10226		/* Enable autoneg and restart autoneg for legacy speeds */
10227		autoneg_val |= (1<<9 | 1<<12);
10228
10229		if (phy->req_duplex == DUPLEX_FULL)
10230			an_10_100_val |= (1<<8);
10231		DP(NETIF_MSG_LINK, "Advertising 100M\n");
10232	}
10233
10234	/* set 10 speed advertisement */
10235	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
10236			(phy->speed_cap_mask &
10237			(PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
10238			PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
10239		an_10_100_val |= (1<<5);
10240		autoneg_val |= (1<<9 | 1<<12);
10241		if (phy->req_duplex == DUPLEX_FULL)
10242			an_10_100_val |= (1<<6);
10243		DP(NETIF_MSG_LINK, "Advertising 10M\n");
10244	}
10245
10246	/* Only 10/100 are allowed to work in FORCE mode */
10247	if (phy->req_line_speed == SPEED_100) {
10248		autoneg_val |= (1<<13);
10249		/* Enabled AUTO-MDIX when autoneg is disabled */
10250		bnx2x_cl22_write(bp, phy,
10251				0x18,
10252				(1<<15 | 1<<9 | 7<<0));
10253		DP(NETIF_MSG_LINK, "Setting 100M force\n");
10254	}
10255	if (phy->req_line_speed == SPEED_10) {
10256		/* Enabled AUTO-MDIX when autoneg is disabled */
10257		bnx2x_cl22_write(bp, phy,
10258				0x18,
10259				(1<<15 | 1<<9 | 7<<0));
10260		DP(NETIF_MSG_LINK, "Setting 10M force\n");
10261	}
10262
10263	/* Check if we should turn on Auto-GrEEEn */
10264	bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
10265	if (temp == MDIO_REG_GPHY_ID_54618SE) {
10266		if (params->feature_config_flags &
10267		    FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10268			temp = 6;
10269			DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10270		} else {
10271			temp = 0;
10272			DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
10273		}
10274		bnx2x_cl22_write(bp, phy,
10275				 MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
10276		bnx2x_cl22_write(bp, phy,
10277				 MDIO_REG_GPHY_CL45_DATA_REG,
10278				 MDIO_REG_GPHY_EEE_ADV);
10279		bnx2x_cl22_write(bp, phy,
10280				 MDIO_REG_GPHY_CL45_ADDR_REG,
10281				 (0x1 << 14) | MDIO_AN_DEVAD);
10282		bnx2x_cl22_write(bp, phy,
10283				 MDIO_REG_GPHY_CL45_DATA_REG,
10284				 temp);
10285	}
10286
10287	bnx2x_cl22_write(bp, phy,
10288			0x04,
10289			an_10_100_val | fc_val);
10290
10291	if (phy->req_duplex == DUPLEX_FULL)
10292		autoneg_val |= (1<<8);
10293
10294	bnx2x_cl22_write(bp, phy,
10295			MDIO_PMA_REG_CTRL, autoneg_val);
10296
10297	return 0;
10298}
10299
10300static void bnx2x_54618se_set_link_led(struct bnx2x_phy *phy,
10301				       struct link_params *params, u8 mode)
10302{
10303	struct bnx2x *bp = params->bp;
10304	DP(NETIF_MSG_LINK, "54618SE set link led (mode=%x)\n", mode);
10305	switch (mode) {
10306	case LED_MODE_FRONT_PANEL_OFF:
10307	case LED_MODE_OFF:
10308	case LED_MODE_OPER:
10309	case LED_MODE_ON:
10310	default:
10311		break;
10312	}
10313	return;
10314}
10315
10316static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
10317				     struct link_params *params)
10318{
10319	struct bnx2x *bp = params->bp;
10320	u32 cfg_pin;
10321	u8 port;
10322
10323	/*
10324	 * In case of no EPIO routed to reset the GPHY, put it
10325	 * in low power mode.
10326	 */
10327	bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
10328	/*
10329	 * This works with E3 only, no need to check the chip
10330	 * before determining the port.
10331	 */
10332	port = params->port;
10333	cfg_pin = (REG_RD(bp, params->shmem_base +
10334			offsetof(struct shmem_region,
10335			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
10336			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
10337			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
10338
10339	/* Drive pin low to put GPHY in reset. */
10340	bnx2x_set_cfg_pin(bp, cfg_pin, 0);
10341}
10342
10343static u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
10344				    struct link_params *params,
10345				    struct link_vars *vars)
10346{
10347	struct bnx2x *bp = params->bp;
10348	u16 val;
10349	u8 link_up = 0;
10350	u16 legacy_status, legacy_speed;
10351
10352	/* Get speed operation status */
10353	bnx2x_cl22_read(bp, phy,
10354			0x19,
10355			&legacy_status);
10356	DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
10357
10358	/* Read status to clear the PHY interrupt. */
10359	bnx2x_cl22_read(bp, phy,
10360			MDIO_REG_INTR_STATUS,
10361			&val);
10362
10363	link_up = ((legacy_status & (1<<2)) == (1<<2));
10364
10365	if (link_up) {
10366		legacy_speed = (legacy_status & (7<<8));
10367		if (legacy_speed == (7<<8)) {
10368			vars->line_speed = SPEED_1000;
10369			vars->duplex = DUPLEX_FULL;
10370		} else if (legacy_speed == (6<<8)) {
10371			vars->line_speed = SPEED_1000;
10372			vars->duplex = DUPLEX_HALF;
10373		} else if (legacy_speed == (5<<8)) {
10374			vars->line_speed = SPEED_100;
10375			vars->duplex = DUPLEX_FULL;
10376		}
10377		/* Omitting 100Base-T4 for now */
10378		else if (legacy_speed == (3<<8)) {
10379			vars->line_speed = SPEED_100;
10380			vars->duplex = DUPLEX_HALF;
10381		} else if (legacy_speed == (2<<8)) {
10382			vars->line_speed = SPEED_10;
10383			vars->duplex = DUPLEX_FULL;
10384		} else if (legacy_speed == (1<<8)) {
10385			vars->line_speed = SPEED_10;
10386			vars->duplex = DUPLEX_HALF;
10387		} else /* Should not happen */
10388			vars->line_speed = 0;
10389
10390		DP(NETIF_MSG_LINK,
10391		   "Link is up in %dMbps, is_duplex_full= %d\n",
10392		   vars->line_speed,
10393		   (vars->duplex == DUPLEX_FULL));
10394
10395		/* Check legacy speed AN resolution */
10396		bnx2x_cl22_read(bp, phy,
10397				0x01,
10398				&val);
10399		if (val & (1<<5))
10400			vars->link_status |=
10401				LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10402		bnx2x_cl22_read(bp, phy,
10403				0x06,
10404				&val);
10405		if ((val & (1<<0)) == 0)
10406			vars->link_status |=
10407				LINK_STATUS_PARALLEL_DETECTION_USED;
10408
10409		DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
10410			   vars->line_speed);
10411
10412		/* Report whether EEE is resolved. */
10413		bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
10414		if (val == MDIO_REG_GPHY_ID_54618SE) {
10415			if (vars->link_status &
10416			    LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
10417				val = 0;
10418			else {
10419				bnx2x_cl22_write(bp, phy,
10420					MDIO_REG_GPHY_CL45_ADDR_REG,
10421					MDIO_AN_DEVAD);
10422				bnx2x_cl22_write(bp, phy,
10423					MDIO_REG_GPHY_CL45_DATA_REG,
10424					MDIO_REG_GPHY_EEE_RESOLVED);
10425				bnx2x_cl22_write(bp, phy,
10426					MDIO_REG_GPHY_CL45_ADDR_REG,
10427					(0x1 << 14) | MDIO_AN_DEVAD);
10428				bnx2x_cl22_read(bp, phy,
10429					MDIO_REG_GPHY_CL45_DATA_REG,
10430					&val);
10431			}
10432			DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
10433		}
10434
10435		bnx2x_ext_phy_resolve_fc(phy, params, vars);
10436	}
10437	return link_up;
10438}
10439
10440static void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
10441					  struct link_params *params)
10442{
10443	struct bnx2x *bp = params->bp;
10444	u16 val;
10445	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
10446
10447	DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
10448
10449	/* Enable master/slave manual mmode and set to master */
10450	/* mii write 9 [bits set 11 12] */
10451	bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
10452
10453	/* forced 1G and disable autoneg */
10454	/* set val [mii read 0] */
10455	/* set val [expr $val & [bits clear 6 12 13]] */
10456	/* set val [expr $val | [bits set 6 8]] */
10457	/* mii write 0 $val */
10458	bnx2x_cl22_read(bp, phy, 0x00, &val);
10459	val &= ~((1<<6) | (1<<12) | (1<<13));
10460	val |= (1<<6) | (1<<8);
10461	bnx2x_cl22_write(bp, phy, 0x00, val);
10462
10463	/* Set external loopback and Tx using 6dB coding */
10464	/* mii write 0x18 7 */
10465	/* set val [mii read 0x18] */
10466	/* mii write 0x18 [expr $val | [bits set 10 15]] */
10467	bnx2x_cl22_write(bp, phy, 0x18, 7);
10468	bnx2x_cl22_read(bp, phy, 0x18, &val);
10469	bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
10470
10471	/* This register opens the gate for the UMAC despite its name */
10472	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
10473
10474	/*
10475	 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
10476	 * length used by the MAC receive logic to check frames.
10477	 */
10478	REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
10479}
10480
10481/******************************************************************/
10482/*			SFX7101 PHY SECTION			  */
10483/******************************************************************/
10484static void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10485				       struct link_params *params)
10486{
10487	struct bnx2x *bp = params->bp;
10488	/* SFX7101_XGXS_TEST1 */
10489	bnx2x_cl45_write(bp, phy,
10490			 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10491}
10492
10493static int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10494				  struct link_params *params,
10495				  struct link_vars *vars)
10496{
10497	u16 fw_ver1, fw_ver2, val;
10498	struct bnx2x *bp = params->bp;
10499	DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10500
10501	/* Restore normal power mode*/
10502	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10503		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10504	/* HW reset */
10505	bnx2x_ext_phy_hw_reset(bp, params->port);
10506	bnx2x_wait_reset_complete(bp, phy, params);
10507
10508	bnx2x_cl45_write(bp, phy,
10509			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
10510	DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10511	bnx2x_cl45_write(bp, phy,
10512			 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10513
10514	bnx2x_ext_phy_set_pause(params, phy, vars);
10515	/* Restart autoneg */
10516	bnx2x_cl45_read(bp, phy,
10517			MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10518	val |= 0x200;
10519	bnx2x_cl45_write(bp, phy,
10520			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10521
10522	/* Save spirom version */
10523	bnx2x_cl45_read(bp, phy,
10524			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10525
10526	bnx2x_cl45_read(bp, phy,
10527			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10528	bnx2x_save_spirom_version(bp, params->port,
10529				  (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10530	return 0;
10531}
10532
10533static u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10534				 struct link_params *params,
10535				 struct link_vars *vars)
10536{
10537	struct bnx2x *bp = params->bp;
10538	u8 link_up;
10539	u16 val1, val2;
10540	bnx2x_cl45_read(bp, phy,
10541			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
10542	bnx2x_cl45_read(bp, phy,
10543			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10544	DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10545		   val2, val1);
10546	bnx2x_cl45_read(bp, phy,
10547			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10548	bnx2x_cl45_read(bp, phy,
10549			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10550	DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10551		   val2, val1);
10552	link_up = ((val1 & 4) == 4);
10553	/* if link is up print the AN outcome of the SFX7101 PHY */
10554	if (link_up) {
10555		bnx2x_cl45_read(bp, phy,
10556				MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10557				&val2);
10558		vars->line_speed = SPEED_10000;
10559		vars->duplex = DUPLEX_FULL;
10560		DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10561			   val2, (val2 & (1<<14)));
10562		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10563		bnx2x_ext_phy_resolve_fc(phy, params, vars);
10564	}
10565	return link_up;
10566}
10567
10568static int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10569{
10570	if (*len < 5)
10571		return -EINVAL;
10572	str[0] = (spirom_ver & 0xFF);
10573	str[1] = (spirom_ver & 0xFF00) >> 8;
10574	str[2] = (spirom_ver & 0xFF0000) >> 16;
10575	str[3] = (spirom_ver & 0xFF000000) >> 24;
10576	str[4] = '\0';
10577	*len -= 5;
10578	return 0;
10579}
10580
10581void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
10582{
10583	u16 val, cnt;
10584
10585	bnx2x_cl45_read(bp, phy,
10586			MDIO_PMA_DEVAD,
10587			MDIO_PMA_REG_7101_RESET, &val);
10588
10589	for (cnt = 0; cnt < 10; cnt++) {
10590		msleep(50);
10591		/* Writes a self-clearing reset */
10592		bnx2x_cl45_write(bp, phy,
10593				 MDIO_PMA_DEVAD,
10594				 MDIO_PMA_REG_7101_RESET,
10595				 (val | (1<<15)));
10596		/* Wait for clear */
10597		bnx2x_cl45_read(bp, phy,
10598				MDIO_PMA_DEVAD,
10599				MDIO_PMA_REG_7101_RESET, &val);
10600
10601		if ((val & (1<<15)) == 0)
10602			break;
10603	}
10604}
10605
10606static void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10607				struct link_params *params) {
10608	/* Low power mode is controlled by GPIO 2 */
10609	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10610		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10611	/* The PHY reset is controlled by GPIO 1 */
10612	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10613		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10614}
10615
10616static void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
10617				    struct link_params *params, u8 mode)
10618{
10619	u16 val = 0;
10620	struct bnx2x *bp = params->bp;
10621	switch (mode) {
10622	case LED_MODE_FRONT_PANEL_OFF:
10623	case LED_MODE_OFF:
10624		val = 2;
10625		break;
10626	case LED_MODE_ON:
10627		val = 1;
10628		break;
10629	case LED_MODE_OPER:
10630		val = 0;
10631		break;
10632	}
10633	bnx2x_cl45_write(bp, phy,
10634			 MDIO_PMA_DEVAD,
10635			 MDIO_PMA_REG_7107_LINK_LED_CNTL,
10636			 val);
10637}
10638
10639/******************************************************************/
10640/*			STATIC PHY DECLARATION			  */
10641/******************************************************************/
10642
10643static struct bnx2x_phy phy_null = {
10644	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
10645	.addr		= 0,
10646	.def_md_devad	= 0,
10647	.flags		= FLAGS_INIT_XGXS_FIRST,
10648	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10649	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10650	.mdio_ctrl	= 0,
10651	.supported	= 0,
10652	.media_type	= ETH_PHY_NOT_PRESENT,
10653	.ver_addr	= 0,
10654	.req_flow_ctrl	= 0,
10655	.req_line_speed	= 0,
10656	.speed_cap_mask	= 0,
10657	.req_duplex	= 0,
10658	.rsrv		= 0,
10659	.config_init	= (config_init_t)NULL,
10660	.read_status	= (read_status_t)NULL,
10661	.link_reset	= (link_reset_t)NULL,
10662	.config_loopback = (config_loopback_t)NULL,
10663	.format_fw_ver	= (format_fw_ver_t)NULL,
10664	.hw_reset	= (hw_reset_t)NULL,
10665	.set_link_led	= (set_link_led_t)NULL,
10666	.phy_specific_func = (phy_specific_func_t)NULL
10667};
10668
10669static struct bnx2x_phy phy_serdes = {
10670	.type		= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
10671	.addr		= 0xff,
10672	.def_md_devad	= 0,
10673	.flags		= 0,
10674	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10675	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10676	.mdio_ctrl	= 0,
10677	.supported	= (SUPPORTED_10baseT_Half |
10678			   SUPPORTED_10baseT_Full |
10679			   SUPPORTED_100baseT_Half |
10680			   SUPPORTED_100baseT_Full |
10681			   SUPPORTED_1000baseT_Full |
10682			   SUPPORTED_2500baseX_Full |
10683			   SUPPORTED_TP |
10684			   SUPPORTED_Autoneg |
10685			   SUPPORTED_Pause |
10686			   SUPPORTED_Asym_Pause),
10687	.media_type	= ETH_PHY_BASE_T,
10688	.ver_addr	= 0,
10689	.req_flow_ctrl	= 0,
10690	.req_line_speed	= 0,
10691	.speed_cap_mask	= 0,
10692	.req_duplex	= 0,
10693	.rsrv		= 0,
10694	.config_init	= (config_init_t)bnx2x_xgxs_config_init,
10695	.read_status	= (read_status_t)bnx2x_link_settings_status,
10696	.link_reset	= (link_reset_t)bnx2x_int_link_reset,
10697	.config_loopback = (config_loopback_t)NULL,
10698	.format_fw_ver	= (format_fw_ver_t)NULL,
10699	.hw_reset	= (hw_reset_t)NULL,
10700	.set_link_led	= (set_link_led_t)NULL,
10701	.phy_specific_func = (phy_specific_func_t)NULL
10702};
10703
10704static struct bnx2x_phy phy_xgxs = {
10705	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10706	.addr		= 0xff,
10707	.def_md_devad	= 0,
10708	.flags		= 0,
10709	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10710	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10711	.mdio_ctrl	= 0,
10712	.supported	= (SUPPORTED_10baseT_Half |
10713			   SUPPORTED_10baseT_Full |
10714			   SUPPORTED_100baseT_Half |
10715			   SUPPORTED_100baseT_Full |
10716			   SUPPORTED_1000baseT_Full |
10717			   SUPPORTED_2500baseX_Full |
10718			   SUPPORTED_10000baseT_Full |
10719			   SUPPORTED_FIBRE |
10720			   SUPPORTED_Autoneg |
10721			   SUPPORTED_Pause |
10722			   SUPPORTED_Asym_Pause),
10723	.media_type	= ETH_PHY_CX4,
10724	.ver_addr	= 0,
10725	.req_flow_ctrl	= 0,
10726	.req_line_speed	= 0,
10727	.speed_cap_mask	= 0,
10728	.req_duplex	= 0,
10729	.rsrv		= 0,
10730	.config_init	= (config_init_t)bnx2x_xgxs_config_init,
10731	.read_status	= (read_status_t)bnx2x_link_settings_status,
10732	.link_reset	= (link_reset_t)bnx2x_int_link_reset,
10733	.config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
10734	.format_fw_ver	= (format_fw_ver_t)NULL,
10735	.hw_reset	= (hw_reset_t)NULL,
10736	.set_link_led	= (set_link_led_t)NULL,
10737	.phy_specific_func = (phy_specific_func_t)NULL
10738};
10739static struct bnx2x_phy phy_warpcore = {
10740	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
10741	.addr		= 0xff,
10742	.def_md_devad	= 0,
10743	.flags		= FLAGS_HW_LOCK_REQUIRED,
10744	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10745	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10746	.mdio_ctrl	= 0,
10747	.supported	= (SUPPORTED_10baseT_Half |
10748			     SUPPORTED_10baseT_Full |
10749			     SUPPORTED_100baseT_Half |
10750			     SUPPORTED_100baseT_Full |
10751			     SUPPORTED_1000baseT_Full |
10752			     SUPPORTED_10000baseT_Full |
10753			     SUPPORTED_20000baseKR2_Full |
10754			     SUPPORTED_20000baseMLD2_Full |
10755			     SUPPORTED_FIBRE |
10756			     SUPPORTED_Autoneg |
10757			     SUPPORTED_Pause |
10758			     SUPPORTED_Asym_Pause),
10759	.media_type	= ETH_PHY_UNSPECIFIED,
10760	.ver_addr	= 0,
10761	.req_flow_ctrl	= 0,
10762	.req_line_speed	= 0,
10763	.speed_cap_mask	= 0,
10764	/* req_duplex = */0,
10765	/* rsrv = */0,
10766	.config_init	= (config_init_t)bnx2x_warpcore_config_init,
10767	.read_status	= (read_status_t)bnx2x_warpcore_read_status,
10768	.link_reset	= (link_reset_t)bnx2x_warpcore_link_reset,
10769	.config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
10770	.format_fw_ver	= (format_fw_ver_t)NULL,
10771	.hw_reset	= (hw_reset_t)bnx2x_warpcore_hw_reset,
10772	.set_link_led	= (set_link_led_t)NULL,
10773	.phy_specific_func = (phy_specific_func_t)NULL
10774};
10775
10776
10777static struct bnx2x_phy phy_7101 = {
10778	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
10779	.addr		= 0xff,
10780	.def_md_devad	= 0,
10781	.flags		= FLAGS_FAN_FAILURE_DET_REQ,
10782	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10783	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10784	.mdio_ctrl	= 0,
10785	.supported	= (SUPPORTED_10000baseT_Full |
10786			   SUPPORTED_TP |
10787			   SUPPORTED_Autoneg |
10788			   SUPPORTED_Pause |
10789			   SUPPORTED_Asym_Pause),
10790	.media_type	= ETH_PHY_BASE_T,
10791	.ver_addr	= 0,
10792	.req_flow_ctrl	= 0,
10793	.req_line_speed	= 0,
10794	.speed_cap_mask	= 0,
10795	.req_duplex	= 0,
10796	.rsrv		= 0,
10797	.config_init	= (config_init_t)bnx2x_7101_config_init,
10798	.read_status	= (read_status_t)bnx2x_7101_read_status,
10799	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
10800	.config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
10801	.format_fw_ver	= (format_fw_ver_t)bnx2x_7101_format_ver,
10802	.hw_reset	= (hw_reset_t)bnx2x_7101_hw_reset,
10803	.set_link_led	= (set_link_led_t)bnx2x_7101_set_link_led,
10804	.phy_specific_func = (phy_specific_func_t)NULL
10805};
10806static struct bnx2x_phy phy_8073 = {
10807	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
10808	.addr		= 0xff,
10809	.def_md_devad	= 0,
10810	.flags		= FLAGS_HW_LOCK_REQUIRED,
10811	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10812	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10813	.mdio_ctrl	= 0,
10814	.supported	= (SUPPORTED_10000baseT_Full |
10815			   SUPPORTED_2500baseX_Full |
10816			   SUPPORTED_1000baseT_Full |
10817			   SUPPORTED_FIBRE |
10818			   SUPPORTED_Autoneg |
10819			   SUPPORTED_Pause |
10820			   SUPPORTED_Asym_Pause),
10821	.media_type	= ETH_PHY_KR,
10822	.ver_addr	= 0,
10823	.req_flow_ctrl	= 0,
10824	.req_line_speed	= 0,
10825	.speed_cap_mask	= 0,
10826	.req_duplex	= 0,
10827	.rsrv		= 0,
10828	.config_init	= (config_init_t)bnx2x_8073_config_init,
10829	.read_status	= (read_status_t)bnx2x_8073_read_status,
10830	.link_reset	= (link_reset_t)bnx2x_8073_link_reset,
10831	.config_loopback = (config_loopback_t)NULL,
10832	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
10833	.hw_reset	= (hw_reset_t)NULL,
10834	.set_link_led	= (set_link_led_t)NULL,
10835	.phy_specific_func = (phy_specific_func_t)NULL
10836};
10837static struct bnx2x_phy phy_8705 = {
10838	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
10839	.addr		= 0xff,
10840	.def_md_devad	= 0,
10841	.flags		= FLAGS_INIT_XGXS_FIRST,
10842	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10843	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10844	.mdio_ctrl	= 0,
10845	.supported	= (SUPPORTED_10000baseT_Full |
10846			   SUPPORTED_FIBRE |
10847			   SUPPORTED_Pause |
10848			   SUPPORTED_Asym_Pause),
10849	.media_type	= ETH_PHY_XFP_FIBER,
10850	.ver_addr	= 0,
10851	.req_flow_ctrl	= 0,
10852	.req_line_speed	= 0,
10853	.speed_cap_mask	= 0,
10854	.req_duplex	= 0,
10855	.rsrv		= 0,
10856	.config_init	= (config_init_t)bnx2x_8705_config_init,
10857	.read_status	= (read_status_t)bnx2x_8705_read_status,
10858	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
10859	.config_loopback = (config_loopback_t)NULL,
10860	.format_fw_ver	= (format_fw_ver_t)bnx2x_null_format_ver,
10861	.hw_reset	= (hw_reset_t)NULL,
10862	.set_link_led	= (set_link_led_t)NULL,
10863	.phy_specific_func = (phy_specific_func_t)NULL
10864};
10865static struct bnx2x_phy phy_8706 = {
10866	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
10867	.addr		= 0xff,
10868	.def_md_devad	= 0,
10869	.flags		= FLAGS_INIT_XGXS_FIRST,
10870	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10871	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10872	.mdio_ctrl	= 0,
10873	.supported	= (SUPPORTED_10000baseT_Full |
10874			   SUPPORTED_1000baseT_Full |
10875			   SUPPORTED_FIBRE |
10876			   SUPPORTED_Pause |
10877			   SUPPORTED_Asym_Pause),
10878	.media_type	= ETH_PHY_SFP_FIBER,
10879	.ver_addr	= 0,
10880	.req_flow_ctrl	= 0,
10881	.req_line_speed	= 0,
10882	.speed_cap_mask	= 0,
10883	.req_duplex	= 0,
10884	.rsrv		= 0,
10885	.config_init	= (config_init_t)bnx2x_8706_config_init,
10886	.read_status	= (read_status_t)bnx2x_8706_read_status,
10887	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
10888	.config_loopback = (config_loopback_t)NULL,
10889	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
10890	.hw_reset	= (hw_reset_t)NULL,
10891	.set_link_led	= (set_link_led_t)NULL,
10892	.phy_specific_func = (phy_specific_func_t)NULL
10893};
10894
10895static struct bnx2x_phy phy_8726 = {
10896	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
10897	.addr		= 0xff,
10898	.def_md_devad	= 0,
10899	.flags		= (FLAGS_HW_LOCK_REQUIRED |
10900			   FLAGS_INIT_XGXS_FIRST),
10901	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10902	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10903	.mdio_ctrl	= 0,
10904	.supported	= (SUPPORTED_10000baseT_Full |
10905			   SUPPORTED_1000baseT_Full |
10906			   SUPPORTED_Autoneg |
10907			   SUPPORTED_FIBRE |
10908			   SUPPORTED_Pause |
10909			   SUPPORTED_Asym_Pause),
10910	.media_type	= ETH_PHY_NOT_PRESENT,
10911	.ver_addr	= 0,
10912	.req_flow_ctrl	= 0,
10913	.req_line_speed	= 0,
10914	.speed_cap_mask	= 0,
10915	.req_duplex	= 0,
10916	.rsrv		= 0,
10917	.config_init	= (config_init_t)bnx2x_8726_config_init,
10918	.read_status	= (read_status_t)bnx2x_8726_read_status,
10919	.link_reset	= (link_reset_t)bnx2x_8726_link_reset,
10920	.config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
10921	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
10922	.hw_reset	= (hw_reset_t)NULL,
10923	.set_link_led	= (set_link_led_t)NULL,
10924	.phy_specific_func = (phy_specific_func_t)NULL
10925};
10926
10927static struct bnx2x_phy phy_8727 = {
10928	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
10929	.addr		= 0xff,
10930	.def_md_devad	= 0,
10931	.flags		= FLAGS_FAN_FAILURE_DET_REQ,
10932	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10933	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10934	.mdio_ctrl	= 0,
10935	.supported	= (SUPPORTED_10000baseT_Full |
10936			   SUPPORTED_1000baseT_Full |
10937			   SUPPORTED_FIBRE |
10938			   SUPPORTED_Pause |
10939			   SUPPORTED_Asym_Pause),
10940	.media_type	= ETH_PHY_NOT_PRESENT,
10941	.ver_addr	= 0,
10942	.req_flow_ctrl	= 0,
10943	.req_line_speed	= 0,
10944	.speed_cap_mask	= 0,
10945	.req_duplex	= 0,
10946	.rsrv		= 0,
10947	.config_init	= (config_init_t)bnx2x_8727_config_init,
10948	.read_status	= (read_status_t)bnx2x_8727_read_status,
10949	.link_reset	= (link_reset_t)bnx2x_8727_link_reset,
10950	.config_loopback = (config_loopback_t)NULL,
10951	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
10952	.hw_reset	= (hw_reset_t)bnx2x_8727_hw_reset,
10953	.set_link_led	= (set_link_led_t)bnx2x_8727_set_link_led,
10954	.phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
10955};
10956static struct bnx2x_phy phy_8481 = {
10957	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
10958	.addr		= 0xff,
10959	.def_md_devad	= 0,
10960	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
10961			  FLAGS_REARM_LATCH_SIGNAL,
10962	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10963	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10964	.mdio_ctrl	= 0,
10965	.supported	= (SUPPORTED_10baseT_Half |
10966			   SUPPORTED_10baseT_Full |
10967			   SUPPORTED_100baseT_Half |
10968			   SUPPORTED_100baseT_Full |
10969			   SUPPORTED_1000baseT_Full |
10970			   SUPPORTED_10000baseT_Full |
10971			   SUPPORTED_TP |
10972			   SUPPORTED_Autoneg |
10973			   SUPPORTED_Pause |
10974			   SUPPORTED_Asym_Pause),
10975	.media_type	= ETH_PHY_BASE_T,
10976	.ver_addr	= 0,
10977	.req_flow_ctrl	= 0,
10978	.req_line_speed	= 0,
10979	.speed_cap_mask	= 0,
10980	.req_duplex	= 0,
10981	.rsrv		= 0,
10982	.config_init	= (config_init_t)bnx2x_8481_config_init,
10983	.read_status	= (read_status_t)bnx2x_848xx_read_status,
10984	.link_reset	= (link_reset_t)bnx2x_8481_link_reset,
10985	.config_loopback = (config_loopback_t)NULL,
10986	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
10987	.hw_reset	= (hw_reset_t)bnx2x_8481_hw_reset,
10988	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
10989	.phy_specific_func = (phy_specific_func_t)NULL
10990};
10991
10992static struct bnx2x_phy phy_84823 = {
10993	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
10994	.addr		= 0xff,
10995	.def_md_devad	= 0,
10996	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
10997			  FLAGS_REARM_LATCH_SIGNAL,
10998	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
10999	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11000	.mdio_ctrl	= 0,
11001	.supported	= (SUPPORTED_10baseT_Half |
11002			   SUPPORTED_10baseT_Full |
11003			   SUPPORTED_100baseT_Half |
11004			   SUPPORTED_100baseT_Full |
11005			   SUPPORTED_1000baseT_Full |
11006			   SUPPORTED_10000baseT_Full |
11007			   SUPPORTED_TP |
11008			   SUPPORTED_Autoneg |
11009			   SUPPORTED_Pause |
11010			   SUPPORTED_Asym_Pause),
11011	.media_type	= ETH_PHY_BASE_T,
11012	.ver_addr	= 0,
11013	.req_flow_ctrl	= 0,
11014	.req_line_speed	= 0,
11015	.speed_cap_mask	= 0,
11016	.req_duplex	= 0,
11017	.rsrv		= 0,
11018	.config_init	= (config_init_t)bnx2x_848x3_config_init,
11019	.read_status	= (read_status_t)bnx2x_848xx_read_status,
11020	.link_reset	= (link_reset_t)bnx2x_848x3_link_reset,
11021	.config_loopback = (config_loopback_t)NULL,
11022	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
11023	.hw_reset	= (hw_reset_t)NULL,
11024	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
11025	.phy_specific_func = (phy_specific_func_t)NULL
11026};
11027
11028static struct bnx2x_phy phy_84833 = {
11029	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
11030	.addr		= 0xff,
11031	.def_md_devad	= 0,
11032	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
11033			    FLAGS_REARM_LATCH_SIGNAL,
11034	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11035	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11036	.mdio_ctrl	= 0,
11037	.supported	= (SUPPORTED_100baseT_Half |
11038			   SUPPORTED_100baseT_Full |
11039			   SUPPORTED_1000baseT_Full |
11040			   SUPPORTED_10000baseT_Full |
11041			   SUPPORTED_TP |
11042			   SUPPORTED_Autoneg |
11043			   SUPPORTED_Pause |
11044			   SUPPORTED_Asym_Pause),
11045	.media_type	= ETH_PHY_BASE_T,
11046	.ver_addr	= 0,
11047	.req_flow_ctrl	= 0,
11048	.req_line_speed	= 0,
11049	.speed_cap_mask	= 0,
11050	.req_duplex	= 0,
11051	.rsrv		= 0,
11052	.config_init	= (config_init_t)bnx2x_848x3_config_init,
11053	.read_status	= (read_status_t)bnx2x_848xx_read_status,
11054	.link_reset	= (link_reset_t)bnx2x_848x3_link_reset,
11055	.config_loopback = (config_loopback_t)NULL,
11056	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
11057	.hw_reset	= (hw_reset_t)bnx2x_84833_hw_reset_phy,
11058	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
11059	.phy_specific_func = (phy_specific_func_t)NULL
11060};
11061
11062static struct bnx2x_phy phy_54618se = {
11063	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
11064	.addr		= 0xff,
11065	.def_md_devad	= 0,
11066	.flags		= FLAGS_INIT_XGXS_FIRST,
11067	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11068	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11069	.mdio_ctrl	= 0,
11070	.supported	= (SUPPORTED_10baseT_Half |
11071			   SUPPORTED_10baseT_Full |
11072			   SUPPORTED_100baseT_Half |
11073			   SUPPORTED_100baseT_Full |
11074			   SUPPORTED_1000baseT_Full |
11075			   SUPPORTED_TP |
11076			   SUPPORTED_Autoneg |
11077			   SUPPORTED_Pause |
11078			   SUPPORTED_Asym_Pause),
11079	.media_type	= ETH_PHY_BASE_T,
11080	.ver_addr	= 0,
11081	.req_flow_ctrl	= 0,
11082	.req_line_speed	= 0,
11083	.speed_cap_mask	= 0,
11084	/* req_duplex = */0,
11085	/* rsrv = */0,
11086	.config_init	= (config_init_t)bnx2x_54618se_config_init,
11087	.read_status	= (read_status_t)bnx2x_54618se_read_status,
11088	.link_reset	= (link_reset_t)bnx2x_54618se_link_reset,
11089	.config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
11090	.format_fw_ver	= (format_fw_ver_t)NULL,
11091	.hw_reset	= (hw_reset_t)NULL,
11092	.set_link_led	= (set_link_led_t)bnx2x_54618se_set_link_led,
11093	.phy_specific_func = (phy_specific_func_t)NULL
11094};
11095/*****************************************************************/
11096/*                                                               */
11097/* Populate the phy according. Main function: bnx2x_populate_phy   */
11098/*                                                               */
11099/*****************************************************************/
11100
11101static void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
11102				     struct bnx2x_phy *phy, u8 port,
11103				     u8 phy_index)
11104{
11105	/* Get the 4 lanes xgxs config rx and tx */
11106	u32 rx = 0, tx = 0, i;
11107	for (i = 0; i < 2; i++) {
11108		/*
11109		 * INT_PHY and EXT_PHY1 share the same value location in the
11110		 * shmem. When num_phys is greater than 1, than this value
11111		 * applies only to EXT_PHY1
11112		 */
11113		if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
11114			rx = REG_RD(bp, shmem_base +
11115				    offsetof(struct shmem_region,
11116			  dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
11117
11118			tx = REG_RD(bp, shmem_base +
11119				    offsetof(struct shmem_region,
11120			  dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11121		} else {
11122			rx = REG_RD(bp, shmem_base +
11123				    offsetof(struct shmem_region,
11124			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11125
11126			tx = REG_RD(bp, shmem_base +
11127				    offsetof(struct shmem_region,
11128			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11129		}
11130
11131		phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
11132		phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
11133
11134		phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
11135		phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
11136	}
11137}
11138
11139static u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
11140				    u8 phy_index, u8 port)
11141{
11142	u32 ext_phy_config = 0;
11143	switch (phy_index) {
11144	case EXT_PHY1:
11145		ext_phy_config = REG_RD(bp, shmem_base +
11146					      offsetof(struct shmem_region,
11147			dev_info.port_hw_config[port].external_phy_config));
11148		break;
11149	case EXT_PHY2:
11150		ext_phy_config = REG_RD(bp, shmem_base +
11151					      offsetof(struct shmem_region,
11152			dev_info.port_hw_config[port].external_phy_config2));
11153		break;
11154	default:
11155		DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
11156		return -EINVAL;
11157	}
11158
11159	return ext_phy_config;
11160}
11161static int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11162				  struct bnx2x_phy *phy)
11163{
11164	u32 phy_addr;
11165	u32 chip_id;
11166	u32 switch_cfg = (REG_RD(bp, shmem_base +
11167				       offsetof(struct shmem_region,
11168			dev_info.port_feature_config[port].link_config)) &
11169			  PORT_FEATURE_CONNECTED_SWITCH_MASK);
11170	chip_id = REG_RD(bp, MISC_REG_CHIP_NUM) << 16;
11171	DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
11172	if (USES_WARPCORE(bp)) {
11173		u32 serdes_net_if;
11174		phy_addr = REG_RD(bp,
11175				  MISC_REG_WC0_CTRL_PHY_ADDR);
11176		*phy = phy_warpcore;
11177		if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
11178			phy->flags |= FLAGS_4_PORT_MODE;
11179		else
11180			phy->flags &= ~FLAGS_4_PORT_MODE;
11181			/* Check Dual mode */
11182		serdes_net_if = (REG_RD(bp, shmem_base +
11183					offsetof(struct shmem_region, dev_info.
11184					port_hw_config[port].default_cfg)) &
11185				 PORT_HW_CFG_NET_SERDES_IF_MASK);
11186		/*
11187		 * Set the appropriate supported and flags indications per
11188		 * interface type of the chip
11189		 */
11190		switch (serdes_net_if) {
11191		case PORT_HW_CFG_NET_SERDES_IF_SGMII:
11192			phy->supported &= (SUPPORTED_10baseT_Half |
11193					   SUPPORTED_10baseT_Full |
11194					   SUPPORTED_100baseT_Half |
11195					   SUPPORTED_100baseT_Full |
11196					   SUPPORTED_1000baseT_Full |
11197					   SUPPORTED_FIBRE |
11198					   SUPPORTED_Autoneg |
11199					   SUPPORTED_Pause |
11200					   SUPPORTED_Asym_Pause);
11201			phy->media_type = ETH_PHY_BASE_T;
11202			break;
11203		case PORT_HW_CFG_NET_SERDES_IF_XFI:
11204			phy->media_type = ETH_PHY_XFP_FIBER;
11205			break;
11206		case PORT_HW_CFG_NET_SERDES_IF_SFI:
11207			phy->supported &= (SUPPORTED_1000baseT_Full |
11208					   SUPPORTED_10000baseT_Full |
11209					   SUPPORTED_FIBRE |
11210					   SUPPORTED_Pause |
11211					   SUPPORTED_Asym_Pause);
11212			phy->media_type = ETH_PHY_SFP_FIBER;
11213			break;
11214		case PORT_HW_CFG_NET_SERDES_IF_KR:
11215			phy->media_type = ETH_PHY_KR;
11216			phy->supported &= (SUPPORTED_1000baseT_Full |
11217					   SUPPORTED_10000baseT_Full |
11218					   SUPPORTED_FIBRE |
11219					   SUPPORTED_Autoneg |
11220					   SUPPORTED_Pause |
11221					   SUPPORTED_Asym_Pause);
11222			break;
11223		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
11224			phy->media_type = ETH_PHY_KR;
11225			phy->flags |= FLAGS_WC_DUAL_MODE;
11226			phy->supported &= (SUPPORTED_20000baseMLD2_Full |
11227					   SUPPORTED_FIBRE |
11228					   SUPPORTED_Pause |
11229					   SUPPORTED_Asym_Pause);
11230			break;
11231		case PORT_HW_CFG_NET_SERDES_IF_KR2:
11232			phy->media_type = ETH_PHY_KR;
11233			phy->flags |= FLAGS_WC_DUAL_MODE;
11234			phy->supported &= (SUPPORTED_20000baseKR2_Full |
11235					   SUPPORTED_FIBRE |
11236					   SUPPORTED_Pause |
11237					   SUPPORTED_Asym_Pause);
11238			break;
11239		default:
11240			DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
11241				       serdes_net_if);
11242			break;
11243		}
11244
11245		/*
11246		 * Enable MDC/MDIO work-around for E3 A0 since free running MDC
11247		 * was not set as expected. For B0, ECO will be enabled so there
11248		 * won't be an issue there
11249		 */
11250		if (CHIP_REV(bp) == CHIP_REV_Ax)
11251			phy->flags |= FLAGS_MDC_MDIO_WA;
11252		else
11253			phy->flags |= FLAGS_MDC_MDIO_WA_B0;
11254	} else {
11255		switch (switch_cfg) {
11256		case SWITCH_CFG_1G:
11257			phy_addr = REG_RD(bp,
11258					  NIG_REG_SERDES0_CTRL_PHY_ADDR +
11259					  port * 0x10);
11260			*phy = phy_serdes;
11261			break;
11262		case SWITCH_CFG_10G:
11263			phy_addr = REG_RD(bp,
11264					  NIG_REG_XGXS0_CTRL_PHY_ADDR +
11265					  port * 0x18);
11266			*phy = phy_xgxs;
11267			break;
11268		default:
11269			DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
11270			return -EINVAL;
11271		}
11272	}
11273	phy->addr = (u8)phy_addr;
11274	phy->mdio_ctrl = bnx2x_get_emac_base(bp,
11275					    SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
11276					    port);
11277	if (CHIP_IS_E2(bp))
11278		phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
11279	else
11280		phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
11281
11282	DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11283		   port, phy->addr, phy->mdio_ctrl);
11284
11285	bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
11286	return 0;
11287}
11288
11289static int bnx2x_populate_ext_phy(struct bnx2x *bp,
11290				  u8 phy_index,
11291				  u32 shmem_base,
11292				  u32 shmem2_base,
11293				  u8 port,
11294				  struct bnx2x_phy *phy)
11295{
11296	u32 ext_phy_config, phy_type, config2;
11297	u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
11298	ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11299						  phy_index, port);
11300	phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11301	/* Select the phy type */
11302	switch (phy_type) {
11303	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11304		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
11305		*phy = phy_8073;
11306		break;
11307	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
11308		*phy = phy_8705;
11309		break;
11310	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
11311		*phy = phy_8706;
11312		break;
11313	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11314		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11315		*phy = phy_8726;
11316		break;
11317	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11318		/* BCM8727_NOC => BCM8727 no over current */
11319		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11320		*phy = phy_8727;
11321		phy->flags |= FLAGS_NOC;
11322		break;
11323	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11324	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11325		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11326		*phy = phy_8727;
11327		break;
11328	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
11329		*phy = phy_8481;
11330		break;
11331	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
11332		*phy = phy_84823;
11333		break;
11334	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11335		*phy = phy_84833;
11336		break;
11337	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
11338	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
11339		*phy = phy_54618se;
11340		break;
11341	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
11342		*phy = phy_7101;
11343		break;
11344	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11345		*phy = phy_null;
11346		return -EINVAL;
11347	default:
11348		*phy = phy_null;
11349		return 0;
11350	}
11351
11352	phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
11353	bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11354
11355	/*
11356	 * The shmem address of the phy version is located on different
11357	 * structures. In case this structure is too old, do not set
11358	 * the address
11359	 */
11360	config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
11361					dev_info.shared_hw_config.config2));
11362	if (phy_index == EXT_PHY1) {
11363		phy->ver_addr = shmem_base + offsetof(struct shmem_region,
11364				port_mb[port].ext_phy_fw_version);
11365
11366		/* Check specific mdc mdio settings */
11367		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
11368			mdc_mdio_access = config2 &
11369			SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
11370	} else {
11371		u32 size = REG_RD(bp, shmem2_base);
11372
11373		if (size >
11374		    offsetof(struct shmem2_region, ext_phy_fw_version2)) {
11375			phy->ver_addr = shmem2_base +
11376			    offsetof(struct shmem2_region,
11377				     ext_phy_fw_version2[port]);
11378		}
11379		/* Check specific mdc mdio settings */
11380		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
11381			mdc_mdio_access = (config2 &
11382			SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
11383			(SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
11384			 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
11385	}
11386	phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11387
11388	/*
11389	 * In case mdc/mdio_access of the external phy is different than the
11390	 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11391	 * to prevent one port interfere with another port's CL45 operations.
11392	 */
11393	if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
11394		phy->flags |= FLAGS_HW_LOCK_REQUIRED;
11395	DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
11396		   phy_type, port, phy_index);
11397	DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
11398		   phy->addr, phy->mdio_ctrl);
11399	return 0;
11400}
11401
11402static int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
11403			      u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
11404{
11405	int status = 0;
11406	phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
11407	if (phy_index == INT_PHY)
11408		return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11409	status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11410					port, phy);
11411	return status;
11412}
11413
11414static void bnx2x_phy_def_cfg(struct link_params *params,
11415			      struct bnx2x_phy *phy,
11416			      u8 phy_index)
11417{
11418	struct bnx2x *bp = params->bp;
11419	u32 link_config;
11420	/* Populate the default phy configuration for MF mode */
11421	if (phy_index == EXT_PHY2) {
11422		link_config = REG_RD(bp, params->shmem_base +
11423				     offsetof(struct shmem_region, dev_info.
11424			port_feature_config[params->port].link_config2));
11425		phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11426					     offsetof(struct shmem_region,
11427						      dev_info.
11428			port_hw_config[params->port].speed_capability_mask2));
11429	} else {
11430		link_config = REG_RD(bp, params->shmem_base +
11431				     offsetof(struct shmem_region, dev_info.
11432				port_feature_config[params->port].link_config));
11433		phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11434					     offsetof(struct shmem_region,
11435						      dev_info.
11436			port_hw_config[params->port].speed_capability_mask));
11437	}
11438	DP(NETIF_MSG_LINK,
11439	   "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
11440	   phy_index, link_config, phy->speed_cap_mask);
11441
11442	phy->req_duplex = DUPLEX_FULL;
11443	switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
11444	case PORT_FEATURE_LINK_SPEED_10M_HALF:
11445		phy->req_duplex = DUPLEX_HALF;
11446	case PORT_FEATURE_LINK_SPEED_10M_FULL:
11447		phy->req_line_speed = SPEED_10;
11448		break;
11449	case PORT_FEATURE_LINK_SPEED_100M_HALF:
11450		phy->req_duplex = DUPLEX_HALF;
11451	case PORT_FEATURE_LINK_SPEED_100M_FULL:
11452		phy->req_line_speed = SPEED_100;
11453		break;
11454	case PORT_FEATURE_LINK_SPEED_1G:
11455		phy->req_line_speed = SPEED_1000;
11456		break;
11457	case PORT_FEATURE_LINK_SPEED_2_5G:
11458		phy->req_line_speed = SPEED_2500;
11459		break;
11460	case PORT_FEATURE_LINK_SPEED_10G_CX4:
11461		phy->req_line_speed = SPEED_10000;
11462		break;
11463	default:
11464		phy->req_line_speed = SPEED_AUTO_NEG;
11465		break;
11466	}
11467
11468	switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
11469	case PORT_FEATURE_FLOW_CONTROL_AUTO:
11470		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11471		break;
11472	case PORT_FEATURE_FLOW_CONTROL_TX:
11473		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11474		break;
11475	case PORT_FEATURE_FLOW_CONTROL_RX:
11476		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11477		break;
11478	case PORT_FEATURE_FLOW_CONTROL_BOTH:
11479		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11480		break;
11481	default:
11482		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11483		break;
11484	}
11485}
11486
11487u32 bnx2x_phy_selection(struct link_params *params)
11488{
11489	u32 phy_config_swapped, prio_cfg;
11490	u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11491
11492	phy_config_swapped = params->multi_phy_config &
11493		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11494
11495	prio_cfg = params->multi_phy_config &
11496			PORT_HW_CFG_PHY_SELECTION_MASK;
11497
11498	if (phy_config_swapped) {
11499		switch (prio_cfg) {
11500		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11501		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11502		     break;
11503		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11504		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11505		     break;
11506		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11507		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11508		     break;
11509		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11510		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11511		     break;
11512		}
11513	} else
11514		return_cfg = prio_cfg;
11515
11516	return return_cfg;
11517}
11518
11519
11520int bnx2x_phy_probe(struct link_params *params)
11521{
11522	u8 phy_index, actual_phy_idx, link_cfg_idx;
11523	u32 phy_config_swapped, sync_offset, media_types;
11524	struct bnx2x *bp = params->bp;
11525	struct bnx2x_phy *phy;
11526	params->num_phys = 0;
11527	DP(NETIF_MSG_LINK, "Begin phy probe\n");
11528	phy_config_swapped = params->multi_phy_config &
11529		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11530
11531	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11532	      phy_index++) {
11533		link_cfg_idx = LINK_CONFIG_IDX(phy_index);
11534		actual_phy_idx = phy_index;
11535		if (phy_config_swapped) {
11536			if (phy_index == EXT_PHY1)
11537				actual_phy_idx = EXT_PHY2;
11538			else if (phy_index == EXT_PHY2)
11539				actual_phy_idx = EXT_PHY1;
11540		}
11541		DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11542			       " actual_phy_idx %x\n", phy_config_swapped,
11543			   phy_index, actual_phy_idx);
11544		phy = &params->phy[actual_phy_idx];
11545		if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11546				       params->shmem2_base, params->port,
11547				       phy) != 0) {
11548			params->num_phys = 0;
11549			DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11550				   phy_index);
11551			for (phy_index = INT_PHY;
11552			      phy_index < MAX_PHYS;
11553			      phy_index++)
11554				*phy = phy_null;
11555			return -EINVAL;
11556		}
11557		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11558			break;
11559
11560		sync_offset = params->shmem_base +
11561			offsetof(struct shmem_region,
11562			dev_info.port_hw_config[params->port].media_type);
11563		media_types = REG_RD(bp, sync_offset);
11564
11565		/*
11566		 * Update media type for non-PMF sync only for the first time
11567		 * In case the media type changes afterwards, it will be updated
11568		 * using the update_status function
11569		 */
11570		if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
11571				    (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11572				     actual_phy_idx))) == 0) {
11573			media_types |= ((phy->media_type &
11574					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
11575				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
11576				 actual_phy_idx));
11577		}
11578		REG_WR(bp, sync_offset, media_types);
11579
11580		bnx2x_phy_def_cfg(params, phy, phy_index);
11581		params->num_phys++;
11582	}
11583
11584	DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11585	return 0;
11586}
11587
11588void bnx2x_init_bmac_loopback(struct link_params *params,
11589			      struct link_vars *vars)
11590{
11591	struct bnx2x *bp = params->bp;
11592		vars->link_up = 1;
11593		vars->line_speed = SPEED_10000;
11594		vars->duplex = DUPLEX_FULL;
11595		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11596		vars->mac_type = MAC_TYPE_BMAC;
11597
11598		vars->phy_flags = PHY_XGXS_FLAG;
11599
11600		bnx2x_xgxs_deassert(params);
11601
11602		/* set bmac loopback */
11603		bnx2x_bmac_enable(params, vars, 1);
11604
11605		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11606}
11607
11608void bnx2x_init_emac_loopback(struct link_params *params,
11609			      struct link_vars *vars)
11610{
11611	struct bnx2x *bp = params->bp;
11612		vars->link_up = 1;
11613		vars->line_speed = SPEED_1000;
11614		vars->duplex = DUPLEX_FULL;
11615		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11616		vars->mac_type = MAC_TYPE_EMAC;
11617
11618		vars->phy_flags = PHY_XGXS_FLAG;
11619
11620		bnx2x_xgxs_deassert(params);
11621		/* set bmac loopback */
11622		bnx2x_emac_enable(params, vars, 1);
11623		bnx2x_emac_program(params, vars);
11624		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11625}
11626
11627void bnx2x_init_xmac_loopback(struct link_params *params,
11628			      struct link_vars *vars)
11629{
11630	struct bnx2x *bp = params->bp;
11631	vars->link_up = 1;
11632	if (!params->req_line_speed[0])
11633		vars->line_speed = SPEED_10000;
11634	else
11635		vars->line_speed = params->req_line_speed[0];
11636	vars->duplex = DUPLEX_FULL;
11637	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11638	vars->mac_type = MAC_TYPE_XMAC;
11639	vars->phy_flags = PHY_XGXS_FLAG;
11640	/*
11641	 * Set WC to loopback mode since link is required to provide clock
11642	 * to the XMAC in 20G mode
11643	 */
11644	bnx2x_set_aer_mmd(params, &params->phy[0]);
11645	bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
11646	params->phy[INT_PHY].config_loopback(
11647			&params->phy[INT_PHY],
11648			params);
11649
11650	bnx2x_xmac_enable(params, vars, 1);
11651	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11652}
11653
11654void bnx2x_init_umac_loopback(struct link_params *params,
11655			      struct link_vars *vars)
11656{
11657	struct bnx2x *bp = params->bp;
11658	vars->link_up = 1;
11659	vars->line_speed = SPEED_1000;
11660	vars->duplex = DUPLEX_FULL;
11661	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11662	vars->mac_type = MAC_TYPE_UMAC;
11663	vars->phy_flags = PHY_XGXS_FLAG;
11664	bnx2x_umac_enable(params, vars, 1);
11665
11666	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11667}
11668
11669void bnx2x_init_xgxs_loopback(struct link_params *params,
11670			      struct link_vars *vars)
11671{
11672	struct bnx2x *bp = params->bp;
11673		vars->link_up = 1;
11674		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11675		vars->duplex = DUPLEX_FULL;
11676	if (params->req_line_speed[0] == SPEED_1000)
11677			vars->line_speed = SPEED_1000;
11678	else
11679			vars->line_speed = SPEED_10000;
11680
11681	if (!USES_WARPCORE(bp))
11682		bnx2x_xgxs_deassert(params);
11683	bnx2x_link_initialize(params, vars);
11684
11685	if (params->req_line_speed[0] == SPEED_1000) {
11686		if (USES_WARPCORE(bp))
11687			bnx2x_umac_enable(params, vars, 0);
11688		else {
11689			bnx2x_emac_program(params, vars);
11690			bnx2x_emac_enable(params, vars, 0);
11691		}
11692	} else {
11693		if (USES_WARPCORE(bp))
11694			bnx2x_xmac_enable(params, vars, 0);
11695		else
11696			bnx2x_bmac_enable(params, vars, 0);
11697	}
11698
11699		if (params->loopback_mode == LOOPBACK_XGXS) {
11700			/* set 10G XGXS loopback */
11701			params->phy[INT_PHY].config_loopback(
11702				&params->phy[INT_PHY],
11703				params);
11704
11705		} else {
11706			/* set external phy loopback */
11707			u8 phy_index;
11708			for (phy_index = EXT_PHY1;
11709			      phy_index < params->num_phys; phy_index++) {
11710				if (params->phy[phy_index].config_loopback)
11711					params->phy[phy_index].config_loopback(
11712						&params->phy[phy_index],
11713						params);
11714			}
11715		}
11716		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
11717
11718	bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
11719}
11720
11721int bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
11722{
11723	struct bnx2x *bp = params->bp;
11724	DP(NETIF_MSG_LINK, "Phy Initialization started\n");
11725	DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
11726		   params->req_line_speed[0], params->req_flow_ctrl[0]);
11727	DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
11728		   params->req_line_speed[1], params->req_flow_ctrl[1]);
11729	vars->link_status = 0;
11730	vars->phy_link_up = 0;
11731	vars->link_up = 0;
11732	vars->line_speed = 0;
11733	vars->duplex = DUPLEX_FULL;
11734	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11735	vars->mac_type = MAC_TYPE_NONE;
11736	vars->phy_flags = 0;
11737
11738	/* disable attentions */
11739	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
11740		       (NIG_MASK_XGXS0_LINK_STATUS |
11741			NIG_MASK_XGXS0_LINK10G |
11742			NIG_MASK_SERDES0_LINK_STATUS |
11743			NIG_MASK_MI_INT));
11744
11745	bnx2x_emac_init(params, vars);
11746
11747	if (params->num_phys == 0) {
11748		DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
11749		return -EINVAL;
11750	}
11751	set_phy_vars(params, vars);
11752
11753	DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
11754	switch (params->loopback_mode) {
11755	case LOOPBACK_BMAC:
11756		bnx2x_init_bmac_loopback(params, vars);
11757		break;
11758	case LOOPBACK_EMAC:
11759		bnx2x_init_emac_loopback(params, vars);
11760		break;
11761	case LOOPBACK_XMAC:
11762		bnx2x_init_xmac_loopback(params, vars);
11763		break;
11764	case LOOPBACK_UMAC:
11765		bnx2x_init_umac_loopback(params, vars);
11766		break;
11767	case LOOPBACK_XGXS:
11768	case LOOPBACK_EXT_PHY:
11769		bnx2x_init_xgxs_loopback(params, vars);
11770		break;
11771	default:
11772		if (!CHIP_IS_E3(bp)) {
11773			if (params->switch_cfg == SWITCH_CFG_10G)
11774				bnx2x_xgxs_deassert(params);
11775			else
11776				bnx2x_serdes_deassert(bp, params->port);
11777		}
11778		bnx2x_link_initialize(params, vars);
11779		msleep(30);
11780		bnx2x_link_int_enable(params);
11781		break;
11782	}
11783	return 0;
11784}
11785
11786int bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
11787		     u8 reset_ext_phy)
11788{
11789	struct bnx2x *bp = params->bp;
11790	u8 phy_index, port = params->port, clear_latch_ind = 0;
11791	DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
11792	/* disable attentions */
11793	vars->link_status = 0;
11794	bnx2x_update_mng(params, vars->link_status);
11795	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
11796		       (NIG_MASK_XGXS0_LINK_STATUS |
11797			NIG_MASK_XGXS0_LINK10G |
11798			NIG_MASK_SERDES0_LINK_STATUS |
11799			NIG_MASK_MI_INT));
11800
11801	/* activate nig drain */
11802	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
11803
11804	/* disable nig egress interface */
11805	if (!CHIP_IS_E3(bp)) {
11806		REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
11807		REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
11808	}
11809
11810	/* Stop BigMac rx */
11811	if (!CHIP_IS_E3(bp))
11812		bnx2x_bmac_rx_disable(bp, port);
11813	else
11814		bnx2x_xmac_disable(params);
11815	/* disable emac */
11816	if (!CHIP_IS_E3(bp))
11817		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
11818
11819	msleep(10);
11820	/* The PHY reset is controlled by GPIO 1
11821	 * Hold it as vars low
11822	 */
11823	 /* clear link led */
11824	bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
11825
11826	if (reset_ext_phy) {
11827		bnx2x_set_mdio_clk(bp, params->chip_id, port);
11828		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
11829		      phy_index++) {
11830			if (params->phy[phy_index].link_reset) {
11831				bnx2x_set_aer_mmd(params,
11832						  &params->phy[phy_index]);
11833				params->phy[phy_index].link_reset(
11834					&params->phy[phy_index],
11835					params);
11836			}
11837			if (params->phy[phy_index].flags &
11838			    FLAGS_REARM_LATCH_SIGNAL)
11839				clear_latch_ind = 1;
11840		}
11841	}
11842
11843	if (clear_latch_ind) {
11844		/* Clear latching indication */
11845		bnx2x_rearm_latch_signal(bp, port, 0);
11846		bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
11847			       1 << NIG_LATCH_BC_ENABLE_MI_INT);
11848	}
11849	if (params->phy[INT_PHY].link_reset)
11850		params->phy[INT_PHY].link_reset(
11851			&params->phy[INT_PHY], params);
11852	/* reset BigMac */
11853	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
11854	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
11855
11856	/* disable nig ingress interface */
11857	if (!CHIP_IS_E3(bp)) {
11858		REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
11859		REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
11860	}
11861	vars->link_up = 0;
11862	vars->phy_flags = 0;
11863	return 0;
11864}
11865
11866/****************************************************************************/
11867/*				Common function				    */
11868/****************************************************************************/
11869static int bnx2x_8073_common_init_phy(struct bnx2x *bp,
11870				      u32 shmem_base_path[],
11871				      u32 shmem2_base_path[], u8 phy_index,
11872				      u32 chip_id)
11873{
11874	struct bnx2x_phy phy[PORT_MAX];
11875	struct bnx2x_phy *phy_blk[PORT_MAX];
11876	u16 val;
11877	s8 port = 0;
11878	s8 port_of_path = 0;
11879	u32 swap_val, swap_override;
11880	swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
11881	swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
11882	port ^= (swap_val && swap_override);
11883	bnx2x_ext_phy_hw_reset(bp, port);
11884	/* PART1 - Reset both phys */
11885	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11886		u32 shmem_base, shmem2_base;
11887		/* In E2, same phy is using for port0 of the two paths */
11888		if (CHIP_IS_E1x(bp)) {
11889			shmem_base = shmem_base_path[0];
11890			shmem2_base = shmem2_base_path[0];
11891			port_of_path = port;
11892		} else {
11893			shmem_base = shmem_base_path[port];
11894			shmem2_base = shmem2_base_path[port];
11895			port_of_path = 0;
11896		}
11897
11898		/* Extract the ext phy address for the port */
11899		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
11900				       port_of_path, &phy[port]) !=
11901		    0) {
11902			DP(NETIF_MSG_LINK, "populate_phy failed\n");
11903			return -EINVAL;
11904		}
11905		/* disable attentions */
11906		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
11907			       port_of_path*4,
11908			       (NIG_MASK_XGXS0_LINK_STATUS |
11909				NIG_MASK_XGXS0_LINK10G |
11910				NIG_MASK_SERDES0_LINK_STATUS |
11911				NIG_MASK_MI_INT));
11912
11913		/* Need to take the phy out of low power mode in order
11914			to write to access its registers */
11915		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11916			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
11917			       port);
11918
11919		/* Reset the phy */
11920		bnx2x_cl45_write(bp, &phy[port],
11921				 MDIO_PMA_DEVAD,
11922				 MDIO_PMA_REG_CTRL,
11923				 1<<15);
11924	}
11925
11926	/* Add delay of 150ms after reset */
11927	msleep(150);
11928
11929	if (phy[PORT_0].addr & 0x1) {
11930		phy_blk[PORT_0] = &(phy[PORT_1]);
11931		phy_blk[PORT_1] = &(phy[PORT_0]);
11932	} else {
11933		phy_blk[PORT_0] = &(phy[PORT_0]);
11934		phy_blk[PORT_1] = &(phy[PORT_1]);
11935	}
11936
11937	/* PART2 - Download firmware to both phys */
11938	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11939		if (CHIP_IS_E1x(bp))
11940			port_of_path = port;
11941		else
11942			port_of_path = 0;
11943
11944		DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
11945			   phy_blk[port]->addr);
11946		if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
11947						      port_of_path))
11948			return -EINVAL;
11949
11950		/* Only set bit 10 = 1 (Tx power down) */
11951		bnx2x_cl45_read(bp, phy_blk[port],
11952				MDIO_PMA_DEVAD,
11953				MDIO_PMA_REG_TX_POWER_DOWN, &val);
11954
11955		/* Phase1 of TX_POWER_DOWN reset */
11956		bnx2x_cl45_write(bp, phy_blk[port],
11957				 MDIO_PMA_DEVAD,
11958				 MDIO_PMA_REG_TX_POWER_DOWN,
11959				 (val | 1<<10));
11960	}
11961
11962	/*
11963	 * Toggle Transmitter: Power down and then up with 600ms delay
11964	 * between
11965	 */
11966	msleep(600);
11967
11968	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
11969	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
11970		/* Phase2 of POWER_DOWN_RESET */
11971		/* Release bit 10 (Release Tx power down) */
11972		bnx2x_cl45_read(bp, phy_blk[port],
11973				MDIO_PMA_DEVAD,
11974				MDIO_PMA_REG_TX_POWER_DOWN, &val);
11975
11976		bnx2x_cl45_write(bp, phy_blk[port],
11977				MDIO_PMA_DEVAD,
11978				MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
11979		msleep(15);
11980
11981		/* Read modify write the SPI-ROM version select register */
11982		bnx2x_cl45_read(bp, phy_blk[port],
11983				MDIO_PMA_DEVAD,
11984				MDIO_PMA_REG_EDC_FFE_MAIN, &val);
11985		bnx2x_cl45_write(bp, phy_blk[port],
11986				 MDIO_PMA_DEVAD,
11987				 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
11988
11989		/* set GPIO2 back to LOW */
11990		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
11991			       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
11992	}
11993	return 0;
11994}
11995static int bnx2x_8726_common_init_phy(struct bnx2x *bp,
11996				      u32 shmem_base_path[],
11997				      u32 shmem2_base_path[], u8 phy_index,
11998				      u32 chip_id)
11999{
12000	u32 val;
12001	s8 port;
12002	struct bnx2x_phy phy;
12003	/* Use port1 because of the static port-swap */
12004	/* Enable the module detection interrupt */
12005	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12006	val |= ((1<<MISC_REGISTERS_GPIO_3)|
12007		(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
12008	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12009
12010	bnx2x_ext_phy_hw_reset(bp, 0);
12011	msleep(5);
12012	for (port = 0; port < PORT_MAX; port++) {
12013		u32 shmem_base, shmem2_base;
12014
12015		/* In E2, same phy is using for port0 of the two paths */
12016		if (CHIP_IS_E1x(bp)) {
12017			shmem_base = shmem_base_path[0];
12018			shmem2_base = shmem2_base_path[0];
12019		} else {
12020			shmem_base = shmem_base_path[port];
12021			shmem2_base = shmem2_base_path[port];
12022		}
12023		/* Extract the ext phy address for the port */
12024		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12025				       port, &phy) !=
12026		    0) {
12027			DP(NETIF_MSG_LINK, "populate phy failed\n");
12028			return -EINVAL;
12029		}
12030
12031		/* Reset phy*/
12032		bnx2x_cl45_write(bp, &phy,
12033				 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
12034
12035
12036		/* Set fault module detected LED on */
12037		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
12038			       MISC_REGISTERS_GPIO_HIGH,
12039			       port);
12040	}
12041
12042	return 0;
12043}
12044static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
12045					 u8 *io_gpio, u8 *io_port)
12046{
12047
12048	u32 phy_gpio_reset = REG_RD(bp, shmem_base +
12049					  offsetof(struct shmem_region,
12050				dev_info.port_hw_config[PORT_0].default_cfg));
12051	switch (phy_gpio_reset) {
12052	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
12053		*io_gpio = 0;
12054		*io_port = 0;
12055		break;
12056	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
12057		*io_gpio = 1;
12058		*io_port = 0;
12059		break;
12060	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
12061		*io_gpio = 2;
12062		*io_port = 0;
12063		break;
12064	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
12065		*io_gpio = 3;
12066		*io_port = 0;
12067		break;
12068	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
12069		*io_gpio = 0;
12070		*io_port = 1;
12071		break;
12072	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
12073		*io_gpio = 1;
12074		*io_port = 1;
12075		break;
12076	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
12077		*io_gpio = 2;
12078		*io_port = 1;
12079		break;
12080	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
12081		*io_gpio = 3;
12082		*io_port = 1;
12083		break;
12084	default:
12085		/* Don't override the io_gpio and io_port */
12086		break;
12087	}
12088}
12089
12090static int bnx2x_8727_common_init_phy(struct bnx2x *bp,
12091				      u32 shmem_base_path[],
12092				      u32 shmem2_base_path[], u8 phy_index,
12093				      u32 chip_id)
12094{
12095	s8 port, reset_gpio;
12096	u32 swap_val, swap_override;
12097	struct bnx2x_phy phy[PORT_MAX];
12098	struct bnx2x_phy *phy_blk[PORT_MAX];
12099	s8 port_of_path;
12100	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12101	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12102
12103	reset_gpio = MISC_REGISTERS_GPIO_1;
12104	port = 1;
12105
12106	/*
12107	 * Retrieve the reset gpio/port which control the reset.
12108	 * Default is GPIO1, PORT1
12109	 */
12110	bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
12111				     (u8 *)&reset_gpio, (u8 *)&port);
12112
12113	/* Calculate the port based on port swap */
12114	port ^= (swap_val && swap_override);
12115
12116	/* Initiate PHY reset*/
12117	bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
12118		       port);
12119	msleep(1);
12120	bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12121		       port);
12122
12123	msleep(5);
12124
12125	/* PART1 - Reset both phys */
12126	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12127		u32 shmem_base, shmem2_base;
12128
12129		/* In E2, same phy is using for port0 of the two paths */
12130		if (CHIP_IS_E1x(bp)) {
12131			shmem_base = shmem_base_path[0];
12132			shmem2_base = shmem2_base_path[0];
12133			port_of_path = port;
12134		} else {
12135			shmem_base = shmem_base_path[port];
12136			shmem2_base = shmem2_base_path[port];
12137			port_of_path = 0;
12138		}
12139
12140		/* Extract the ext phy address for the port */
12141		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12142				       port_of_path, &phy[port]) !=
12143				       0) {
12144			DP(NETIF_MSG_LINK, "populate phy failed\n");
12145			return -EINVAL;
12146		}
12147		/* disable attentions */
12148		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12149			       port_of_path*4,
12150			       (NIG_MASK_XGXS0_LINK_STATUS |
12151				NIG_MASK_XGXS0_LINK10G |
12152				NIG_MASK_SERDES0_LINK_STATUS |
12153				NIG_MASK_MI_INT));
12154
12155
12156		/* Reset the phy */
12157		bnx2x_cl45_write(bp, &phy[port],
12158				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
12159	}
12160
12161	/* Add delay of 150ms after reset */
12162	msleep(150);
12163	if (phy[PORT_0].addr & 0x1) {
12164		phy_blk[PORT_0] = &(phy[PORT_1]);
12165		phy_blk[PORT_1] = &(phy[PORT_0]);
12166	} else {
12167		phy_blk[PORT_0] = &(phy[PORT_0]);
12168		phy_blk[PORT_1] = &(phy[PORT_1]);
12169	}
12170	/* PART2 - Download firmware to both phys */
12171	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12172		if (CHIP_IS_E1x(bp))
12173			port_of_path = port;
12174		else
12175			port_of_path = 0;
12176		DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12177			   phy_blk[port]->addr);
12178		if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
12179						      port_of_path))
12180			return -EINVAL;
12181		/* Disable PHY transmitter output */
12182		bnx2x_cl45_write(bp, phy_blk[port],
12183				 MDIO_PMA_DEVAD,
12184				 MDIO_PMA_REG_TX_DISABLE, 1);
12185
12186	}
12187	return 0;
12188}
12189
12190static int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
12191				     u32 shmem2_base_path[], u8 phy_index,
12192				     u32 ext_phy_type, u32 chip_id)
12193{
12194	int rc = 0;
12195
12196	switch (ext_phy_type) {
12197	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12198		rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12199						shmem2_base_path,
12200						phy_index, chip_id);
12201		break;
12202	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
12203	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
12204	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12205		rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12206						shmem2_base_path,
12207						phy_index, chip_id);
12208		break;
12209
12210	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
12211		/*
12212		 * GPIO1 affects both ports, so there's need to pull
12213		 * it for single port alone
12214		 */
12215		rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12216						shmem2_base_path,
12217						phy_index, chip_id);
12218		break;
12219	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
12220		/*
12221		 * GPIO3's are linked, and so both need to be toggled
12222		 * to obtain required 2us pulse.
12223		 */
12224		rc = bnx2x_84833_common_init_phy(bp, shmem_base_path, chip_id);
12225		break;
12226	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12227		rc = -EINVAL;
12228		break;
12229	default:
12230		DP(NETIF_MSG_LINK,
12231			   "ext_phy 0x%x common init not required\n",
12232			   ext_phy_type);
12233		break;
12234	}
12235
12236	if (rc != 0)
12237		netdev_err(bp->dev,  "Warning: PHY was not initialized,"
12238				      " Port %d\n",
12239			 0);
12240	return rc;
12241}
12242
12243int bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
12244			  u32 shmem2_base_path[], u32 chip_id)
12245{
12246	int rc = 0;
12247	u32 phy_ver, val;
12248	u8 phy_index = 0;
12249	u32 ext_phy_type, ext_phy_config;
12250	bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12251	bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
12252	DP(NETIF_MSG_LINK, "Begin common phy init\n");
12253	if (CHIP_IS_E3(bp)) {
12254		/* Enable EPIO */
12255		val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
12256		REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
12257	}
12258	/* Check if common init was already done */
12259	phy_ver = REG_RD(bp, shmem_base_path[0] +
12260			 offsetof(struct shmem_region,
12261				  port_mb[PORT_0].ext_phy_fw_version));
12262	if (phy_ver) {
12263		DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
12264			       phy_ver);
12265		return 0;
12266	}
12267
12268	/* Read the ext_phy_type for arbitrary port(0) */
12269	for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12270	      phy_index++) {
12271		ext_phy_config = bnx2x_get_ext_phy_config(bp,
12272							  shmem_base_path[0],
12273							  phy_index, 0);
12274		ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
12275		rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12276						shmem2_base_path,
12277						phy_index, ext_phy_type,
12278						chip_id);
12279	}
12280	return rc;
12281}
12282
12283static void bnx2x_check_over_curr(struct link_params *params,
12284				  struct link_vars *vars)
12285{
12286	struct bnx2x *bp = params->bp;
12287	u32 cfg_pin;
12288	u8 port = params->port;
12289	u32 pin_val;
12290
12291	cfg_pin = (REG_RD(bp, params->shmem_base +
12292			  offsetof(struct shmem_region,
12293			       dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
12294		   PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
12295		PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
12296
12297	/* Ignore check if no external input PIN available */
12298	if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
12299		return;
12300
12301	if (!pin_val) {
12302		if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
12303			netdev_err(bp->dev, "Error:  Power fault on Port %d has"
12304					    " been detected and the power to "
12305					    "that SFP+ module has been removed"
12306					    " to prevent failure of the card."
12307					    " Please remove the SFP+ module and"
12308					    " restart the system to clear this"
12309					    " error.\n",
12310			 params->port);
12311			vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
12312		}
12313	} else
12314		vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
12315}
12316
12317static void bnx2x_analyze_link_error(struct link_params *params,
12318				     struct link_vars *vars, u32 lss_status)
12319{
12320	struct bnx2x *bp = params->bp;
12321	/* Compare new value with previous value */
12322	u8 led_mode;
12323	u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
12324
12325	if ((lss_status ^ half_open_conn) == 0)
12326		return;
12327
12328	/* If values differ */
12329	DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
12330		       half_open_conn, lss_status);
12331
12332	/*
12333	 * a. Update shmem->link_status accordingly
12334	 * b. Update link_vars->link_up
12335	 */
12336	if (lss_status) {
12337		DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n");
12338		vars->link_status &= ~LINK_STATUS_LINK_UP;
12339		vars->link_up = 0;
12340		vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
12341		/*
12342		 * Set LED mode to off since the PHY doesn't know about these
12343		 * errors
12344		 */
12345		led_mode = LED_MODE_OFF;
12346	} else {
12347		DP(NETIF_MSG_LINK, "Remote Fault cleared\n");
12348		vars->link_status |= LINK_STATUS_LINK_UP;
12349		vars->link_up = 1;
12350		vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
12351		led_mode = LED_MODE_OPER;
12352	}
12353	/* Update the LED according to the link state */
12354	bnx2x_set_led(params, vars, led_mode, SPEED_10000);
12355
12356	/* Update link status in the shared memory */
12357	bnx2x_update_mng(params, vars->link_status);
12358
12359	/* C. Trigger General Attention */
12360	vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
12361	bnx2x_notify_link_changed(bp);
12362}
12363
12364/******************************************************************************
12365* Description:
12366*	This function checks for half opened connection change indication.
12367*	When such change occurs, it calls the bnx2x_analyze_link_error
12368*	to check if Remote Fault is set or cleared. Reception of remote fault
12369*	status message in the MAC indicates that the peer's MAC has detected
12370*	a fault, for example, due to break in the TX side of fiber.
12371*
12372******************************************************************************/
12373static void bnx2x_check_half_open_conn(struct link_params *params,
12374				       struct link_vars *vars)
12375{
12376	struct bnx2x *bp = params->bp;
12377	u32 lss_status = 0;
12378	u32 mac_base;
12379	/* In case link status is physically up @ 10G do */
12380	if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
12381		return;
12382
12383	if (CHIP_IS_E3(bp) &&
12384	    (REG_RD(bp, MISC_REG_RESET_REG_2) &
12385	      (MISC_REGISTERS_RESET_REG_2_XMAC))) {
12386		/* Check E3 XMAC */
12387		/*
12388		 * Note that link speed cannot be queried here, since it may be
12389		 * zero while link is down. In case UMAC is active, LSS will
12390		 * simply not be set
12391		 */
12392		mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12393
12394		/* Clear stick bits (Requires rising edge) */
12395		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
12396		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
12397		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
12398		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
12399		if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
12400			lss_status = 1;
12401
12402		bnx2x_analyze_link_error(params, vars, lss_status);
12403	} else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12404		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
12405		/* Check E1X / E2 BMAC */
12406		u32 lss_status_reg;
12407		u32 wb_data[2];
12408		mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
12409			NIG_REG_INGRESS_BMAC0_MEM;
12410		/*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
12411		if (CHIP_IS_E2(bp))
12412			lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
12413		else
12414			lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
12415
12416		REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
12417		lss_status = (wb_data[0] > 0);
12418
12419		bnx2x_analyze_link_error(params, vars, lss_status);
12420	}
12421}
12422
12423void bnx2x_period_func(struct link_params *params, struct link_vars *vars)
12424{
12425	struct bnx2x *bp = params->bp;
12426	u16 phy_idx;
12427	for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
12428		if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
12429			bnx2x_set_aer_mmd(params, &params->phy[phy_idx]);
12430			bnx2x_check_half_open_conn(params, vars);
12431			break;
12432		}
12433	}
12434
12435	if (CHIP_IS_E3(bp)) {
12436		struct bnx2x_phy *phy = &params->phy[INT_PHY];
12437		bnx2x_set_aer_mmd(params, phy);
12438		bnx2x_check_over_curr(params, vars);
12439		bnx2x_warpcore_config_runtime(phy, params, vars);
12440	}
12441
12442}
12443
12444u8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
12445{
12446	u8 phy_index;
12447	struct bnx2x_phy phy;
12448	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12449	      phy_index++) {
12450		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12451				       0, &phy) != 0) {
12452			DP(NETIF_MSG_LINK, "populate phy failed\n");
12453			return 0;
12454		}
12455
12456		if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
12457			return 1;
12458	}
12459	return 0;
12460}
12461
12462u8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
12463			     u32 shmem_base,
12464			     u32 shmem2_base,
12465			     u8 port)
12466{
12467	u8 phy_index, fan_failure_det_req = 0;
12468	struct bnx2x_phy phy;
12469	for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12470	      phy_index++) {
12471		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12472				       port, &phy)
12473		    != 0) {
12474			DP(NETIF_MSG_LINK, "populate phy failed\n");
12475			return 0;
12476		}
12477		fan_failure_det_req |= (phy.flags &
12478					FLAGS_FAN_FAILURE_DET_REQ);
12479	}
12480	return fan_failure_det_req;
12481}
12482
12483void bnx2x_hw_reset_phy(struct link_params *params)
12484{
12485	u8 phy_index;
12486	struct bnx2x *bp = params->bp;
12487	bnx2x_update_mng(params, 0);
12488	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12489		       (NIG_MASK_XGXS0_LINK_STATUS |
12490			NIG_MASK_XGXS0_LINK10G |
12491			NIG_MASK_SERDES0_LINK_STATUS |
12492			NIG_MASK_MI_INT));
12493
12494	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12495	      phy_index++) {
12496		if (params->phy[phy_index].hw_reset) {
12497			params->phy[phy_index].hw_reset(
12498				&params->phy[phy_index],
12499				params);
12500			params->phy[phy_index] = phy_null;
12501		}
12502	}
12503}
12504
12505void bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
12506			    u32 chip_id, u32 shmem_base, u32 shmem2_base,
12507			    u8 port)
12508{
12509	u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
12510	u32 val;
12511	u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
12512	if (CHIP_IS_E3(bp)) {
12513		if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
12514					      shmem_base,
12515					      port,
12516					      &gpio_num,
12517					      &gpio_port) != 0)
12518			return;
12519	} else {
12520		struct bnx2x_phy phy;
12521		for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12522		      phy_index++) {
12523			if (bnx2x_populate_phy(bp, phy_index, shmem_base,
12524					       shmem2_base, port, &phy)
12525			    != 0) {
12526				DP(NETIF_MSG_LINK, "populate phy failed\n");
12527				return;
12528			}
12529			if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
12530				gpio_num = MISC_REGISTERS_GPIO_3;
12531				gpio_port = port;
12532				break;
12533			}
12534		}
12535	}
12536
12537	if (gpio_num == 0xff)
12538		return;
12539
12540	/* Set GPIO3 to trigger SFP+ module insertion/removal */
12541	bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
12542
12543	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12544	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
12545	gpio_port ^= (swap_val && swap_override);
12546
12547	vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
12548		(gpio_num + (gpio_port << 2));
12549
12550	sync_offset = shmem_base +
12551		offsetof(struct shmem_region,
12552			 dev_info.port_hw_config[port].aeu_int_mask);
12553	REG_WR(bp, sync_offset, vars->aeu_int_mask);
12554
12555	DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
12556		       gpio_num, gpio_port, vars->aeu_int_mask);
12557
12558	if (port == 0)
12559		offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
12560	else
12561		offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
12562
12563	/* Open appropriate AEU for interrupts */
12564	aeu_mask = REG_RD(bp, offset);
12565	aeu_mask |= vars->aeu_int_mask;
12566	REG_WR(bp, offset, aeu_mask);
12567
12568	/* Enable the GPIO to trigger interrupt */
12569	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12570	val |= 1 << (gpio_num + (gpio_port << 2));
12571	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12572}
12573