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