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