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