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