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