185b26ea18ee63be83d65ec6db72ad7857980a04bAriel Elior/* Copyright 2008-2012 Broadcom Corporation
2ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner *
3ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * Unless you and Broadcom execute a separate written software license
4ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * agreement governing use of this software, this software is licensed to you
5ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * under the terms of the GNU General Public License version 2, available
6ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * at http://www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
7ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner *
8ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * Notwithstanding the above, under no circumstances may you combine this
9ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * software in any way with any other Broadcom software provided under a
10ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * license other than the GPL, without Broadcom's express prior written
11ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * consent.
12ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner *
13ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * Written by Yaniv Rosner
14ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner *
15ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner */
16ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
177995c64e5b56ec7fe6032e5fc586f726cde2152bJoe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
187995c64e5b56ec7fe6032e5fc586f726cde2152bJoe Perches
19ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/kernel.h>
20ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/errno.h>
21ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/pci.h>
22ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/netdevice.h>
23ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/delay.h>
24ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/ethtool.h>
25ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include <linux/mutex.h>
26ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
27ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#include "bnx2x.h"
28619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov#include "bnx2x_cmn.h"
29619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov
30ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/********************************************************/
313196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein#define ETH_HLEN			14
32cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner/* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
33cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define ETH_OVREHEAD			(ETH_HLEN + 8 + 8)
34ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define ETH_MIN_PACKET_SIZE		60
35ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define ETH_MAX_PACKET_SIZE		1500
36ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define ETH_MAX_JUMBO_PACKET_SIZE	9600
37ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define MDIO_ACCESS_TIMEOUT		1000
383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define WC_LANE_MAX			4
393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define I2C_SWITCH_WIDTH		2
403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define I2C_BSC0			0
413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define I2C_BSC1			1
423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define I2C_WA_RETRY_CNT		3
433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define MCPR_IMC_COMMAND_READ_OP	1
443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define MCPR_IMC_COMMAND_WRITE_OP	2
45ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4626ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner/* LED Blink rate that will achieve ~15.9Hz */
4726ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner#define LED_BLINK_RATE_VAL_E3		354
4826ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner#define LED_BLINK_RATE_VAL_E1X_E2	480
49ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/***********************************************************/
503196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein/*			Shortcut definitions		   */
51ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/***********************************************************/
52ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
532f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein#define NIG_LATCH_BC_ENABLE_MI_INT 0
542f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein
552f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein#define NIG_STATUS_EMAC0_MI_INT \
562f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
57ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_STATUS_XGXS0_LINK10G \
58ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
59ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_STATUS_XGXS0_LINK_STATUS \
60ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
61ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
62ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
63ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_STATUS_SERDES0_LINK_STATUS \
64ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
65ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_MASK_MI_INT \
66ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
67ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_MASK_XGXS0_LINK10G \
68ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
69ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_MASK_XGXS0_LINK_STATUS \
70ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
71ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define NIG_MASK_SERDES0_LINK_STATUS \
72ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
73ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
74ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define MDIO_AN_CL73_OR_37_COMPLETE \
75ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
76ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
77ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
78ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define XGXS_RESET_BITS \
79ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
80ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
81ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
82ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
83ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
84ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
85ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define SERDES_RESET_BITS \
86ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
87ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
88ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
89ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
90ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
91ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
92ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
93cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
943196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein#define AUTONEG_PARALLEL \
95ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
963196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein#define AUTONEG_SGMII_FIBER_AUTODET \
97ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
983196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein#define AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
99ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
100ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
101ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
102ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
103ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
104ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_SPEED_MASK \
105ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
106ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
107ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
108ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
109ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
110ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
111ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
112ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_10G_HIG \
113ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
114ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_10G_CX4 \
115ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
116ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
117ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define GP_STATUS_10G_KX4 \
118ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
1193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define	GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
1203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define	GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
1213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define	GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
1223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define	GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
123cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
124cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
125ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
126cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
127ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
128ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
129ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
130ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
131ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
132ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
133ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner#define LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
134cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
135cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
1363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
1373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
1386583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1396583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1406583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
141589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein/* */
142589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein#define SFP_EEPROM_CON_TYPE_ADDR		0x2
143cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	#define SFP_EEPROM_CON_TYPE_VAL_LC	0x7
144589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	#define SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
145589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
1464d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
1474d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein#define SFP_EEPROM_COMP_CODE_ADDR		0x3
1484d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	#define SFP_EEPROM_COMP_CODE_SR_MASK	(1<<4)
1494d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	#define SFP_EEPROM_COMP_CODE_LR_MASK	(1<<5)
1504d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	#define SFP_EEPROM_COMP_CODE_LRM_MASK	(1<<6)
1514d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
152589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein#define SFP_EEPROM_FC_TX_TECH_ADDR		0x8
153589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
154cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	#define SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
1554d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
156cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define SFP_EEPROM_OPTIONS_ADDR			0x40
157589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	#define SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
158cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define SFP_EEPROM_OPTIONS_SIZE			2
159589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
160cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define EDC_MODE_LINEAR				0x0022
161cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define EDC_MODE_LIMITING				0x0044
162cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner#define EDC_MODE_PASSIVE_DAC			0x0055
1634d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
164866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner/* BRB default for class 0 E2 */
165866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR	170
166866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR		250
167866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR		10
168866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E2_BRB_MAC_FULL_XON_THR		50
1694d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
1709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* BRB thresholds for E2*/
1719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE		170
1729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
1739380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1749380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE		250
1759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
1769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1779380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE		10
1789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		90
1799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE			50
1819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE		250
1829380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
183866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner/* BRB default for class 0 E3A0 */
184866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR	290
185866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR	410
186866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR	10
187866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR	50
188866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
1899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* BRB thresholds for E3A0 */
1909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE		290
1919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE		0
1929380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1939380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE		410
1949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE		0
1959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE		10
1979380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE		170
1989380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE		50
2009380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE		410
2019380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
202866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner/* BRB default for E3B0 */
203866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR	330
204866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR	490
205866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR	15
206866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR	55
2079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2089380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* BRB thresholds for E3B0 2 port mode*/
2099380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		1025
2109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
2119380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE		1025
2139380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
2149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2159380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
2169380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	1025
2179380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2189380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE		50
2199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE	1025
2209380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2219380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* only for E3B0*/
2229380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR			1025
2239380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_FULL_LB_XON_THR			1025
2249380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2259380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossy +Lossless GUARANTIED == GUART */
2269380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_MIX_PAUSE_LB_GUART			284
2279380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossless +Lossless*/
2289380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_PAUSE_LB_GUART			236
2299380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossy +Lossy*/
2309380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_NON_PAUSE_LB_GUART			342
2319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2329380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossy +Lossless*/
2339380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART		284
2349380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossless +Lossless*/
2359380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART		236
2369380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Lossy +Lossy*/
2379380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART		336
2389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST		80
2399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART		0
2419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST		0
2429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* BRB thresholds for E3B0 4 port mode */
2449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE		304
2459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE	0
2469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE		384
2489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE	0
2499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE		10
2519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE	304
2529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE		50
2549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE	384
2559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* only for E3B0*/
2579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR			304
2589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_FULL_LB_XON_THR			384
2592f751a805e35dcf687473c27282a6602577df541Yaniv Rosner#define PFC_E3B0_4P_LB_GUART		120
2609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART		120
2622f751a805e35dcf687473c27282a6602577df541Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST	80
2639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART		80
2652f751a805e35dcf687473c27282a6602577df541Yaniv Rosner#define PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST	120
2669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
267866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner/* Pause defines*/
268866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR			330
269866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_FULL_LB_XON_THR			490
270866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_LB_GUART		40
271866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
272866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART		40
273866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST	0
274866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
275866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART		40
276866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner#define DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST	0
277866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
278866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner/* ETS defines*/
2799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define DCBX_INVALID_COS					(0xFF)
2809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
281bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov#define ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
282bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov#define ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
2839380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
2849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
2859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define ETS_E3B0_PBF_MIN_W_VAL				(10000)
2869380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner#define MAX_PACKET_SIZE					(9700)
2883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#define WC_UC_TIMEOUT					100
289a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner#define MAX_KR_LINK_RETRY				4
2909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
291ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/**********************************************************/
292ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/*                     INTERFACE                          */
293ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/**********************************************************/
294e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
295cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner#define CL22_WR_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
296e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_cl45_write(_bp, _phy, \
2977aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		(_phy)->def_md_devad, \
298ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		(_bank + (_addr & 0xf)), \
299ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		_val)
300ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
301cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner#define CL22_RD_OVER_CL45(_bp, _phy, _bank, _addr, _val) \
302e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_cl45_read(_bp, _phy, \
3037aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		(_phy)->def_md_devad, \
304ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		(_bank + (_addr & 0xf)), \
305ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		_val)
306ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
307ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosnerstatic u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
308ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
309ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 val = REG_RD(bp, reg);
310ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
311ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val |= bits;
312ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, reg, val);
313ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return val;
314ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
315ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
316ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosnerstatic u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
317ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
318ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 val = REG_RD(bp, reg);
319ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
320ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val &= ~bits;
321ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, reg, val);
322ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return val;
323ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
324ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
325bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
3263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/*			EPIO/GPIO section			  */
3273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
3283deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnerstatic void bnx2x_get_epio(struct bnx2x *bp, u32 epio_pin, u32 *en)
3293deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
3303deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 epio_mask, gp_oenable;
3313deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	*en = 0;
3323deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Sanity check */
3333deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (epio_pin > 31) {
3343deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to get\n", epio_pin);
3353deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		return;
3363deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	}
3373deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
3383deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	epio_mask = 1 << epio_pin;
3393deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Set this EPIO to output */
3403deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
3413deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
3423deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
3433deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	*en = (REG_RD(bp, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
3443deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
3453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_epio(struct bnx2x *bp, u32 epio_pin, u32 en)
3463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
3473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 epio_mask, gp_output, gp_oenable;
3483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Sanity check */
3503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (epio_pin > 31) {
3513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Invalid EPIO pin %d to set\n", epio_pin);
3523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return;
3533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
3543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting EPIO pin %d to %d\n", epio_pin, en);
3553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	epio_mask = 1 << epio_pin;
3563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set this EPIO to output */
3573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	gp_output = REG_RD(bp, MCP_REG_MCPR_GP_OUTPUTS);
3583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (en)
3593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		gp_output |= epio_mask;
3603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
3613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		gp_output &= ~epio_mask;
3623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
3643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set the value for this EPIO */
3663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	gp_oenable = REG_RD(bp, MCP_REG_MCPR_GP_OENABLE);
3673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
3683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
3693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 val)
3713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
3723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (pin_cfg == PIN_CFG_NA)
3733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return;
3743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (pin_cfg >= PIN_CFG_EPIO0) {
3753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
3763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
3773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
3783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
3793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_gpio(bp, gpio_num, (u8)val, gpio_port);
3803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
3813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
3823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3833deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnerstatic u32 bnx2x_get_cfg_pin(struct bnx2x *bp, u32 pin_cfg, u32 *val)
3843deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
3853deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (pin_cfg == PIN_CFG_NA)
3863deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		return -EINVAL;
3873deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (pin_cfg >= PIN_CFG_EPIO0) {
3883deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		bnx2x_get_epio(bp, pin_cfg - PIN_CFG_EPIO0, val);
3893deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	} else {
3903deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
3913deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
3923deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		*val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
3933deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	}
3943deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	return 0;
3953deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
3963deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
3973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
398bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/*				ETS section			  */
399bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
4006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e2e3a0_disabled(struct link_params *params)
401bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
402bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS disabled configuration*/
403bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
404bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
4056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	DP(NETIF_MSG_LINK, "ETS E2E3 disabled configuration\n");
406bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
4072cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
408bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * mapping between entry  priority to client number (0,1,2 -debug and
409bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
410bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * 3bits client num.
411bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
412bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
413bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
414bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
415bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
4162cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
417bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
418bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
419bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * COS0 entry, 4 - COS1 entry.
420bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
421bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * bit4   bit3	  bit2   bit1	  bit0
422bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * MCP and debug are strict
423bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
424bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
425bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
426bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* defines which entries (clients) are subjected to WFQ arbitration */
427bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
4282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
4292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * For strict priority entries defines the number of consecutive
4302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * slots for the highest priority.
4312cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
432bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
4332cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
434bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * mapping between the CREDIT_WEIGHT registers and actual client
435bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * numbers
436bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
437bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
438bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
439bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
440bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
441bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
442bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
443bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
444bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS mode disable */
445bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
4462cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
447bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * If ETS mode is enabled (there is no strict priority) defines a WFQ
448bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * weight for COS0/COS1.
449bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
450bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS0_WEIGHT, 0x2710);
451bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS1_WEIGHT, 0x2710);
452bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
453bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS0_UPPER_BOUND, 0x989680);
454bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS1_UPPER_BOUND, 0x989680);
455bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Defines the number of consecutive slots for the strict priority */
456bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
457bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
4586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
4596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
4606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Getting min_w_val will be set according to line speed .
4616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
4626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
4636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic u32 bnx2x_ets_get_min_w_val_nig(const struct link_vars *vars)
4646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
4656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 min_w_val = 0;
4666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Calculate min_w_val.*/
4676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (vars->link_up) {
468de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner		if (vars->line_speed == SPEED_20000)
4696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
4706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		else
4716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			min_w_val = ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
4726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else
4736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		min_w_val = ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
4746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
4756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 *  If the link isn't up (static configuration for example ) The
4766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 *  link will be according to 20GBPS.
4776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*/
4786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return min_w_val;
4796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
4806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
4816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
4826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Getting credit upper bound form min_w_val.
4836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
4846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
4856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic u32 bnx2x_ets_get_credit_upper_bound(const u32 min_w_val)
4866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
4876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 credit_upper_bound = (u32)MAXVAL((150 * min_w_val),
4886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner						MAX_PACKET_SIZE);
4896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return credit_upper_bound;
4906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
4916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
4926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
4936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Set credit upper bound for NIG.
4946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
4956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
4966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e3b0_set_credit_upper_bound_nig(
4976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const struct link_params *params,
4986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val)
4996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
5006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
5016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
5026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 credit_upper_bound =
5036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    bnx2x_ets_get_credit_upper_bound(min_w_val);
5046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
5056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
5066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
5076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
5086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
5096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
5106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
5116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
5126c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
5136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
5146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
5156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
5166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
5176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
518de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (!port) {
5196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
5206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			credit_upper_bound);
5216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
5226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			credit_upper_bound);
5236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
5246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			credit_upper_bound);
5256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
5266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
5276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
5286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
5296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Will return the NIG ETS registers to init values.Except
5306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	credit_upper_bound.
5316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	That isn't used in this configuration (No WFQ is enabled) and will be
5326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	configured acording to spec
5336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
5346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
5356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e3b0_nig_disabled(const struct link_params *params,
5366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					const struct link_vars *vars)
5376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
5386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
5396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
5406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val = bnx2x_ets_get_min_w_val_nig(vars);
5416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
5426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * mapping between entry  priority to client number (0,1,2 -debug and
5436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
5446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
5456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * reset value or init tool
5466c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 */
5476c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port) {
5486c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
5496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
5506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else {
5516c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
5526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
5536c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
5546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
5556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* For strict priority entries defines the number of consecutive
5566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* slots for the highest priority.
5576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*/
5586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* TODO_ETS - Should be done by reset value or init tool */
5596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
5606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
5616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
5626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * mapping between the CREDIT_WEIGHT registers and actual client
5636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * numbers
5646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 */
5656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* TODO_ETS - Should be done by reset value or init tool */
5666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port) {
5676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/*Port 1 has 6 COS*/
5686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
5696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
5706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else {
5716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/*Port 0 has 9 COS*/
5726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
5736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		       0x43210876);
5746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
5756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
5766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
5776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
5786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
5796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
5806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * COS0 entry, 4 - COS1 entry.
5816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
5826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * bit4   bit3	  bit2   bit1	  bit0
5836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * MCP and debug are strict
5846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 */
5856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port)
5866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
5876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	else
5886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
5896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* defines which entries (clients) are subjected to WFQ arbitration */
5906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
5916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
5926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
5936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
5946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* Please notice the register address are note continuous and a
5956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* for here is note appropriate.In 2 port mode port0 only COS0-5
5966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
5976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
5986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* are never used for WFQ
5996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*/
6006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
6016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
6026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
6036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
6046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
6056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
6066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
6076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
6086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
6096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
6106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
6116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
612de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (!port) {
6136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
6146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
6156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
6166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
6176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
6196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
6206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
6216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
6226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Set credit upper bound for PBF.
6236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
6246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
6256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e3b0_set_credit_upper_bound_pbf(
6266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const struct link_params *params,
6276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val)
6286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
6296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
6306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 credit_upper_bound =
6316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    bnx2x_ets_get_credit_upper_bound(min_w_val);
6326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
6336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 base_upper_bound = 0;
6346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 max_cos = 0;
6356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 i = 0;
6366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
6376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
6386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* port mode port1 has COS0-2 that can be used for WFQ.
6396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*/
640de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (!port) {
6416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
6426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
6436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else {
6446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
6456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
6466c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
6476c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6486c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (i = 0; i < max_cos; i++)
6496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, base_upper_bound + (i << 2), credit_upper_bound);
6506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
6516c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
6536c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
6546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Will return the PBF ETS registers to init values.Except
6556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	credit_upper_bound.
6566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	That isn't used in this configuration (No WFQ is enabled) and will be
6576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	configured acording to spec
6586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
6596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
6606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e3b0_pbf_disabled(const struct link_params *params)
6616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
6626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
6636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
6646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
6656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 i = 0;
6666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 base_weight = 0;
6676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 max_cos = 0;
6686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
6706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * mapping between entry  priority to client number 0 - COS0
6716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
6726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 * TODO_ETS - Should be done by reset value or init tool
6736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 */
6746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port)
6756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/*  0x688 (|011|0 10|00 1|000) */
6766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
6776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	else
6786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/*  (10 1|100 |011|0 10|00 1|000) */
6796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
6806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* TODO_ETS - Should be done by reset value or init tool */
6826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port)
6836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/* 0x688 (|011|0 10|00 1|000)*/
6846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
6856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	else
6866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
6876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
6886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
6906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
6916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
6946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
6956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
6966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
6976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
6986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/**
6996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* In 2 port mode port0 has COS0-5 that can be used for WFQ.
7006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	* In 4 port mode port1 has COS0-2 that can be used for WFQ.
7016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*/
702de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (!port) {
7036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		base_weight = PBF_REG_COS0_WEIGHT_P0;
7046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT0;
7056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else {
7066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		base_weight = PBF_REG_COS0_WEIGHT_P1;
7076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		max_cos = DCBX_E3B0_MAX_NUM_COS_PORT1;
7086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
7096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (i = 0; i < max_cos; i++)
7116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, base_weight + (0x4 * i), 0);
7126c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
7146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
7156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
7166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
7176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	E3B0 disable will return basicly the values to init values.
7186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
7196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
7206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_disabled(const struct link_params *params,
7216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				   const struct link_vars *vars)
7226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
7236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
7246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (!CHIP_IS_E3B0(bp)) {
72694f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
72794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
7286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
7296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
7306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_nig_disabled(params, vars);
7326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_pbf_disabled(params);
7346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
7366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
7376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
7396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
7406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Disable will return basicly the values to init values.
7416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
7426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
7436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerint bnx2x_ets_disabled(struct link_params *params,
7446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		      struct link_vars *vars)
7456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
7466c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
7476c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	int bnx2x_status = 0;
7486c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if ((CHIP_IS_E2(bp)) || (CHIP_IS_E3A0(bp)))
7506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		bnx2x_ets_e2e3a0_disabled(params);
7516c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	else if (CHIP_IS_E3B0(bp))
7526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		bnx2x_status = bnx2x_ets_e3b0_disabled(params, vars);
7536c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	else {
7546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_ets_disabled - chip not supported\n");
7556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
7566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
7576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return bnx2x_status;
7596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
7606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
7626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description
7636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Set the COS mappimg to SP and BW until this point all the COS are not
7646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	set as SP or BW.
7656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
7666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_cli_map(const struct link_params *params,
7676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				  const struct bnx2x_ets_params *ets_params,
7686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				  const u8 cos_sp_bitmap,
7696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				  const u8 cos_bw_bitmap)
7706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
7716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
7726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
7736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
7746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
7756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
7766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
7776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
7796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
7806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
7826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
783bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
7846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
7856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
7866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       nig_cli_subject2wfq_bitmap);
7876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
7896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
7906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	       pbf_cli_subject2wfq_bitmap);
7916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
7936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
7946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
7956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
7966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
7976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	This function is needed because NIG ARB_CREDIT_WEIGHT_X are
7986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
7996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
8006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_set_cos_bw(struct bnx2x *bp,
8016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u8 cos_entry,
8026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u32 min_w_val_nig,
8036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u32 min_w_val_pbf,
8046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u16 total_bw,
8056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u8 bw,
8066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				     const u8 port)
8076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
8086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 nig_reg_adress_crd_weight = 0;
8096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 pbf_reg_adress_crd_weight = 0;
810c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner	/* Calculate and set BW for this COS - use 1 instead of 0 for BW */
811c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner	const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
812c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner	const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
8136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	switch (cos_entry) {
8156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 0:
8166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    nig_reg_adress_crd_weight =
8176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
8186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
8196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     pbf_reg_adress_crd_weight = (port) ?
8206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
8216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 1:
8236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     nig_reg_adress_crd_weight = (port) ?
8246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
8256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
8266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     pbf_reg_adress_crd_weight = (port) ?
8276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
8286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 2:
8306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     nig_reg_adress_crd_weight = (port) ?
8316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
8326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
8336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 pbf_reg_adress_crd_weight = (port) ?
8356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
8366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 3:
8386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    if (port)
8396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			return -EINVAL;
8406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     nig_reg_adress_crd_weight =
8416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
8426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     pbf_reg_adress_crd_weight =
8436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 PBF_REG_COS3_WEIGHT_P0;
8446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 4:
8466c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    if (port)
8476c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
8486c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     nig_reg_adress_crd_weight =
8496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
8506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
8516c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	case 5:
8536c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	    if (port)
8546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
8556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     nig_reg_adress_crd_weight =
8566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
8576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
8586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	     break;
8596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
8606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, nig_reg_adress_crd_weight, cos_bw_nig);
8626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	REG_WR(bp, pbf_reg_adress_crd_weight, cos_bw_pbf);
8646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
8666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
8676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
8686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
8696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Calculate the total BW.A value of 0 isn't legal.
8706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
8716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
8726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_get_total_bw(
8736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const struct link_params *params,
874870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner	struct bnx2x_ets_params *ets_params,
8756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u16 *total_bw)
8766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
8776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
8786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 cos_idx = 0;
879870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner	u8 is_bw_cos_exist = 0;
8806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
8816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	*total_bw = 0 ;
882870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner
8836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Calculate total BW requested */
8846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
885de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner		if (ets_params->cos[cos_idx].state == bnx2x_cos_state_bw) {
886870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner			is_bw_cos_exist = 1;
887870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner			if (!ets_params->cos[cos_idx].params.bw_params.bw) {
888870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config BW"
889870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner						   "was set to 0\n");
890870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				/*
891870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				 * This is to prevent a state when ramrods
892870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				 * can't be sent
893870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				*/
894870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner				ets_params->cos[cos_idx].params.bw_params.bw
895870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner					 = 1;
896870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner			}
897c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner			*total_bw +=
898c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner				ets_params->cos[cos_idx].params.bw_params.bw;
8996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
9006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
9016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
902c482e6c064613b3fd40758ef6c33318462b83789Yaniv Rosner	/* Check total BW is valid */
903de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
904de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner		if (*total_bw == 0) {
90594f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
9062f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			   "bnx2x_ets_E3B0_config total BW shouldn't be 0\n");
9076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			return -EINVAL;
9086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
90994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
9102f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		   "bnx2x_ets_E3B0_config total BW should be 100\n");
9112f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
9122f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * We can handle a case whre the BW isn't 100 this can happen
9132f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * if the TC are joined.
9142f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
9156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
9166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
9176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
9186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
9206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
9216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Invalidate all the sp_pri_to_cos.
9226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
9236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
9246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic void bnx2x_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
9256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
9266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 pri = 0;
9276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (pri = 0; pri < DCBX_MAX_NUM_COS; pri++)
9286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		sp_pri_to_cos[pri] = DCBX_INVALID_COS;
9296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
9306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
9316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
9326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
9336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	according to sp_pri_to_cos.
9346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
9356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
9366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_sp_pri_to_cos_set(const struct link_params *params,
9376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					    u8 *sp_pri_to_cos, const u8 pri,
9386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					    const u8 cos_entry)
9396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
9406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
9416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
9426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
9436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DCBX_E3B0_MAX_NUM_COS_PORT0;
9446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9457e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter	if (pri >= max_num_of_cos) {
9467e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
9477e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter		   "parameter Illegal strict priority\n");
9487e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter	    return -EINVAL;
9497e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter	}
9507e5998aa74065d3ab31d17e667f40ffebf4b8425Dan Carpenter
951de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
9526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_pri_to_cos_set invalid "
95394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				   "parameter There can't be two COS's with "
9546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				   "the same strict pri\n");
9556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
9566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
9576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	sp_pri_to_cos[pri] = cos_entry;
9596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
9606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
9626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
9646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
9656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Returns the correct value according to COS and priority in
9666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	the sp_pri_cli register.
9676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
9686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
9696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic u64 bnx2x_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
9706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					 const u8 pri_set,
9716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					 const u8 pri_offset,
9726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					 const u8 entry_size)
9736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
9746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u64 pri_cli_nig = 0;
9756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
9766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner						    (pri_set + pri_offset));
9776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return pri_cli_nig;
9796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
9806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
9816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
9826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Returns the correct value according to COS and priority in the
9836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	sp_pri_cli register for NIG.
9846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
9856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
9866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic u64 bnx2x_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
9876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
9886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
9896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 nig_cos_offset = 3;
9906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 nig_pri_offset = 3;
9916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return bnx2x_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
9936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		nig_pri_offset, 4);
9946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
9956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
9966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
9976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
9986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Returns the correct value according to COS and priority in the
9996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	sp_pri_cli register for PBF.
10006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
10016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
10026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic u64 bnx2x_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
10036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
10046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 pbf_cos_offset = 0;
10056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 pbf_pri_offset = 0;
10066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return bnx2x_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
10086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		pbf_pri_offset, 3);
10096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
10116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10126c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
10136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
10146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
10156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	according to sp_pri_to_cos.(which COS has higher priority)
10166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*.
10176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
10186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerstatic int bnx2x_ets_e3b0_sp_set_pri_cli_reg(const struct link_params *params,
10196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					     u8 *sp_pri_to_cos)
10206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
10216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
10226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 i = 0;
10236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
10246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
10256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u64 pri_cli_nig = 0x210;
10266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u32 pri_cli_pbf = 0x0;
10276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 pri_set = 0;
10286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 pri_bitmask = 0;
10296c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
10306c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DCBX_E3B0_MAX_NUM_COS_PORT0;
10316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
10336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Set all the strict priority first */
10356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (i = 0; i < max_num_of_cos; i++) {
1036de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner		if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1037de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner			if (sp_pri_to_cos[i] >= DCBX_MAX_NUM_COS) {
10386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				DP(NETIF_MSG_LINK,
10396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					   "bnx2x_ets_e3b0_sp_set_pri_cli_reg "
10406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					   "invalid cos entry\n");
10416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				return -EINVAL;
10426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			}
10436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
10456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			    sp_pri_to_cos[i], pri_set);
10466c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10476c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
10486c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			    sp_pri_to_cos[i], pri_set);
10496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_bitmask = 1 << sp_pri_to_cos[i];
10506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			/* COS is used remove it from bitmap.*/
1051de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner			if (!(pri_bitmask & cos_bit_to_set)) {
10526c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				DP(NETIF_MSG_LINK,
10536c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					"bnx2x_ets_e3b0_sp_set_pri_cli_reg "
10546c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					"invalid There can't be two COS's with"
10556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					" the same strict pri\n");
10566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				return -EINVAL;
10576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			}
10586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			cos_bit_to_set &= ~pri_bitmask;
10596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_set++;
10606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
10616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
10626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10636c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Set all the Non strict priority i= COS*/
10646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (i = 0; i < max_num_of_cos; i++) {
10656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		pri_bitmask = 1 << i;
10666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/* Check if COS was already used for SP */
10676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		if (pri_bitmask & cos_bit_to_set) {
10686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			/* COS wasn't used for SP */
10696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_cli_nig |= bnx2x_e3b0_sp_get_pri_cli_reg_nig(
10706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			    i, pri_set);
10716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_cli_pbf |= bnx2x_e3b0_sp_get_pri_cli_reg_pbf(
10736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			    i, pri_set);
10746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			/* COS is used remove it from bitmap.*/
10756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			cos_bit_to_set &= ~pri_bitmask;
10766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			pri_set++;
10776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
10786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
10796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (pri_set != max_num_of_cos) {
10816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_ets_e3b0_sp_set_pri_cli_reg not all "
10826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				   "entries were set\n");
10836c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
10846c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
10856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (port) {
10876c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/* Only 6 usable clients*/
10886c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
10896c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		       (u32)pri_cli_nig);
10906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
10926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	} else {
10936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		/* Only 9 usable clients*/
10946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
10956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
10966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
10976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
10986c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		       pri_cli_nig_lsb);
10996c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
11006c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		       pri_cli_nig_msb);
11016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		REG_WR(bp, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
11036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
11046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
11056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
11066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner/******************************************************************************
11086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner* Description:
11096c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner*	Configure the COS to ETS according to BW and SP settings.
11106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner******************************************************************************/
11116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosnerint bnx2x_ets_e3b0_config(const struct link_params *params,
11126c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			 const struct link_vars *vars,
1113870516e1733a36021ea3dd303c71adf3ce2c84d3Yaniv Rosner			 struct bnx2x_ets_params *ets_params)
11146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner{
11156c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	struct bnx2x *bp = params->bp;
11166c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	int bnx2x_status = 0;
11176c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 port = params->port;
11186c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u16 total_bw = 0;
11196c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val_nig = bnx2x_ets_get_min_w_val_nig(vars);
11206c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u32 min_w_val_pbf = ETS_E3B0_PBF_MIN_W_VAL;
11216c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 cos_bw_bitmap = 0;
11226c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 cos_sp_bitmap = 0;
11236c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 sp_pri_to_cos[DCBX_MAX_NUM_COS] = {0};
11246c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	const u8 max_num_of_cos = (port) ? DCBX_E3B0_MAX_NUM_COS_PORT1 :
11256c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DCBX_E3B0_MAX_NUM_COS_PORT0;
11266c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	u8 cos_entry = 0;
11276c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11286c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if (!CHIP_IS_E3B0(bp)) {
112994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
113094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "bnx2x_ets_e3b0_disabled the chip isn't E3B0\n");
11316c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
11326c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
11336c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11346c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	if ((ets_params->num_of_cos > max_num_of_cos)) {
11356c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config the number of COS "
11366c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				   "isn't supported\n");
11376c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
11386c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
11396c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11406c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Prepare sp strict priority parameters*/
11416c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
11426c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11436c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Prepare BW parameters*/
11446c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_status = bnx2x_ets_e3b0_get_total_bw(params, ets_params,
11456c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner						   &total_bw);
1146de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (bnx2x_status) {
114794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
114894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "bnx2x_ets_E3B0_config get_total_bw failed\n");
11496c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return -EINVAL;
11506c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
11516c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11522f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
11532f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * Upper bound is set according to current link speed (min_w_val
11542f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * should be the same for upper bound and COS credit val).
11556c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	 */
11566c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
11576c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
11586c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11596c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11606c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
11616c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		if (bnx2x_cos_state_bw == ets_params->cos[cos_entry].state) {
11626c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			cos_bw_bitmap |= (1 << cos_entry);
11632f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			/*
11646c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			 * The function also sets the BW in HW(not the mappin
11656c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			 * yet)
11666c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			 */
11676c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			bnx2x_status = bnx2x_ets_e3b0_set_cos_bw(
11686c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				bp, cos_entry, min_w_val_nig, min_w_val_pbf,
11696c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				total_bw,
11706c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				ets_params->cos[cos_entry].params.bw_params.bw,
11716c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				 port);
11726c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		} else if (bnx2x_cos_state_strict ==
11736c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			ets_params->cos[cos_entry].state){
11746c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			cos_sp_bitmap |= (1 << cos_entry);
11756c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11766c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			bnx2x_status = bnx2x_ets_e3b0_sp_pri_to_cos_set(
11776c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				params,
11786c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				sp_pri_to_cos,
11796c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				ets_params->cos[cos_entry].params.sp_params.pri,
11806c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner				cos_entry);
11816c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11826c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		} else {
118394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
118494f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "bnx2x_ets_e3b0_config cos state not valid\n");
11856c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			return -EINVAL;
11866c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
1187de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner		if (bnx2x_status) {
118894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
118994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "bnx2x_ets_e3b0_config set cos bw failed\n");
11906c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner			return bnx2x_status;
11916c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		}
11926c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
11936c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
11946c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Set SP register (which COS has higher priority) */
11956c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_status = bnx2x_ets_e3b0_sp_set_pri_cli_reg(params,
11966c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner							 sp_pri_to_cos);
11976c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
1198de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (bnx2x_status) {
119994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
120094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "bnx2x_ets_E3B0_config set_pri_cli_reg failed\n");
12016c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return bnx2x_status;
12026c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
12036c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
12046c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	/* Set client mapping of BW and strict */
12056c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	bnx2x_status = bnx2x_ets_e3b0_cli_map(params, ets_params,
12066c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					      cos_sp_bitmap,
12076c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner					      cos_bw_bitmap);
12086c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner
1209de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (bnx2x_status) {
12106c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_ets_E3B0_config SP failed\n");
12116c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner		return bnx2x_status;
12126c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	}
12136c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner	return 0;
12146c3218c6f7e5be6d785486797d48203d54cfd893Yaniv Rosner}
121565a001bad18eb80f6f953e5e0601132f09bfe197Yaniv Rosnerstatic void bnx2x_ets_bw_limit_common(const struct link_params *params)
1216bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1217bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS disabled configuration */
1218bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1219bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
12202cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
12212cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * defines which entries (clients) are subjected to WFQ arbitration
12222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * COS0 0x8
12232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * COS1 0x10
12242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
1225bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
12262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
12272cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * mapping between the ARB_CREDIT_WEIGHT registers and actual
12282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * client numbers (WEIGHT_0 does not actually have to represent
12292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * client 0)
12302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
12312cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
12322cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
1233bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1234bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1235bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1236bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1237bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1238bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1239bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1240bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS mode enabled*/
1241bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_ETS_ENABLED, 1);
1242bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1243bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Defines the number of consecutive slots for the strict priority */
1244bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
12452cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
12462cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
12472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
12482cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * entry, 4 - COS1 entry.
12492cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
12502cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * bit4   bit3	  bit2     bit1	   bit0
12512cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * MCP and debug are strict
12522cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
1253bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1254bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1255bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1256bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS0_UPPER_BOUND,
1257bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1258bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS1_UPPER_BOUND,
1259bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1260bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1261bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1262bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovvoid bnx2x_ets_bw_limit(const struct link_params *params, const u32 cos0_bw,
1263bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			const u32 cos1_bw)
1264bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1265bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS disabled configuration*/
1266bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1267bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	const u32 total_bw = cos0_bw + cos1_bw;
1268bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 cos0_credit_weight = 0;
1269bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 cos1_credit_weight = 0;
1270bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1271bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "ETS enabled BW limit configuration\n");
1272bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1273de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if ((!total_bw) ||
1274de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	    (!cos0_bw) ||
1275de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	    (!cos1_bw)) {
1276cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		DP(NETIF_MSG_LINK, "Total BW can't be zero\n");
1277bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		return;
1278bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
1279bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1280bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	cos0_credit_weight = (cos0_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1281bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		total_bw;
1282bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	cos1_credit_weight = (cos1_bw * ETS_BW_LIMIT_CREDIT_WEIGHT)/
1283bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		total_bw;
1284bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1285bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	bnx2x_ets_bw_limit_common(params);
1286bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1287bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1288bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1289bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1290bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1291bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1292bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1293bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1294fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_ets_strict(const struct link_params *params, const u8 strict_cos)
1295bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1296bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS disabled configuration*/
1297bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1298bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 val	= 0;
1299bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1300bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "ETS enabled strict configuration\n");
13012cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
1302bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * Bitmap of 5bits length. Each bit specifies whether the entry behaves
1303bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * as strict.  Bits 0,1,2 - debug and management entries,
1304bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * 3 - COS0 entry, 4 - COS1 entry.
1305bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1306bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 *  bit4   bit3	  bit2      bit1     bit0
1307bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * MCP and debug are strict
1308bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
1309bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
13102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
1311bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * For strict priority entries defines the number of consecutive slots
1312bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * for the highest priority.
1313bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
1314bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1315bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* ETS mode disable */
1316bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_ETS_ENABLED, 0);
1317bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Defines the number of consecutive slots for the strict priority */
1318bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1319bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1320bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Defines the number of consecutive slots for the strict priority */
1321bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1322bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
13232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
13242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * mapping between entry  priority to client number (0,1,2 -debug and
13252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
13262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * 3bits client num.
13272cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
13282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
13292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
13302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
1331de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	val = (!strict_cos) ? 0x2318 : 0x22E0;
1332bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1333bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1334bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	return 0;
1335bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1336bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
1337e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov/*			PFC section				  */
1338bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
13399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic void bnx2x_update_pfc_xmac(struct link_params *params,
13409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				  struct link_vars *vars,
13419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				  u8 is_lb)
13429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
13439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
13449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 xmac_base;
13459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 pause_val, pfc0_val, pfc1_val;
13469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* XMAC base adrr */
13489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
13499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Initialize pause and pfc registers */
13519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	pause_val = 0x18000;
13529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	pfc0_val = 0xFFFF8000;
13539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	pfc1_val = 0x2;
13549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* No PFC support */
13569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!(params->feature_config_flags &
13579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	      FEATURE_CONFIG_PFC_ENABLED)) {
13589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/*
13609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		 * RX flow control - Process pause frame in receive direction
13619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		 */
13629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
13639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
13649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/*
13669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		 * TX flow control - Send pause packet when buffer is full
13679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		 */
13689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
13699380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
13709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else {/* PFC support */
13719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
13729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
13739380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
137427d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
137527d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner			XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
137627d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		/* Write pause and PFC registers */
137727d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
137827d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
137927d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
138027d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
138127d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner
13829380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
13839380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Write pause and PFC registers */
13859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
13869380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
13879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
13889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
13899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1390b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	/* Set MAC address for source TX Pause/PFC frames */
1391b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_LO,
1392b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	       ((params->mac_addr[2] << 24) |
1393b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[3] << 16) |
1394b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[4] << 8) |
1395b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[5])));
1396b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_CTRL_SA_HI,
1397b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	       ((params->mac_addr[0] << 8) |
1398b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[1])));
13999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1400b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	udelay(30);
1401b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner}
1402bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1403bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1404bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovstatic void bnx2x_emac_get_pfc_stat(struct link_params *params,
1405bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				    u32 pfc_frames_sent[2],
1406bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				    u32 pfc_frames_received[2])
1407bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1408bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Read pfc statistic */
1409bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1410bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1411bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 val_xon = 0;
1412bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 val_xoff = 0;
1413bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1414bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "pfc statistic read from EMAC\n");
1415bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1416bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* PFC received frames */
1417bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xoff = REG_RD(bp, emac_base +
1418bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1419bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1420bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1421bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1422bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1423bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	pfc_frames_received[0] = val_xon + val_xoff;
1424bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1425bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* PFC received sent */
1426bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xoff = REG_RD(bp, emac_base +
1427bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1428bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1429bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xon = REG_RD(bp, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1430bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1431bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1432bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	pfc_frames_sent[0] = val_xon + val_xoff;
1433bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1434bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1435b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner/* Read pfc statistic*/
1436bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovvoid bnx2x_pfc_statistic(struct link_params *params, struct link_vars *vars,
1437bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			 u32 pfc_frames_sent[2],
1438bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			 u32 pfc_frames_received[2])
1439bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1440bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* Read pfc statistic */
1441bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1442b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
1443bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "pfc statistic\n");
1444bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1445bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (!vars->link_up)
1446bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		return;
1447bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1448de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (vars->mac_type == MAC_TYPE_EMAC) {
1449b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		DP(NETIF_MSG_LINK, "About to read PFC stats from EMAC\n");
1450bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		bnx2x_emac_get_pfc_stat(params, pfc_frames_sent,
1451bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					pfc_frames_received);
1452bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
1453bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1454bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
1455bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/*			MAC/PBF section				  */
1456bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov/******************************************************************/
1457a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosnerstatic void bnx2x_set_mdio_clk(struct bnx2x *bp, u32 chip_id, u8 port)
1458a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner{
1459a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	u32 mode, emac_base;
1460a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	/**
1461a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	 * Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1462a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	 * (a value of 49==0x31) and make sure that the AUTO poll is off
1463a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	 */
1464a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner
1465a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	if (CHIP_IS_E2(bp))
1466a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		emac_base = GRCBASE_EMAC0;
1467a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	else
1468a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1469a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	mode = REG_RD(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1470a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	mode &= ~(EMAC_MDIO_MODE_AUTO_POLL |
1471a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		  EMAC_MDIO_MODE_CLOCK_CNT);
14723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (USES_WARPCORE(bp))
14733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		mode |= (74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
14743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
14753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		mode |= (49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT);
1476a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner
1477a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1478a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_MODE, mode);
1479a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner
1480a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	udelay(40);
1481a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner}
14822f751a805e35dcf687473c27282a6602577df541Yaniv Rosnerstatic u8 bnx2x_is_4_port_mode(struct bnx2x *bp)
14832f751a805e35dcf687473c27282a6602577df541Yaniv Rosner{
14842f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	u32 port4mode_ovwr_val;
14852f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/* Check 4-port override enabled */
14862f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	port4mode_ovwr_val = REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR);
14872f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	if (port4mode_ovwr_val & (1<<0)) {
14882f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/* Return 4-port mode override value */
14892f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
14902f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	}
14912f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/* Return 4-port mode from input pin */
14922f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	return (u8)REG_RD(bp, MISC_REG_PORT4MODE_EN);
14932f751a805e35dcf687473c27282a6602577df541Yaniv Rosner}
1494a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner
1495ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosnerstatic void bnx2x_emac_init(struct link_params *params,
1496cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			    struct link_vars *vars)
1497ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
1498ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* reset and unreset the emac core */
1499ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
1500ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u8 port = params->port;
1501ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1502ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 val;
1503ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 timeout;
1504ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1505ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1506cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1507ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	udelay(5);
1508ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1509cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1510ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1511ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* init emac - use read-modify-write */
1512ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* self clear reset */
1513ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
15143196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1515ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1516ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	timeout = 200;
15173196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	do {
1518ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1519ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
1520ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		if (!timeout) {
1521ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			DP(NETIF_MSG_LINK, "EMAC timeout!\n");
1522ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			return;
1523ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
1524ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		timeout--;
15253196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	} while (val & EMAC_MODE_RESET);
1526a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	bnx2x_set_mdio_clk(bp, params->chip_id, port);
1527ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* Set mac address */
1528ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = ((params->mac_addr[0] << 8) |
1529ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		params->mac_addr[1]);
15303196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
1531ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1532ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = ((params->mac_addr[2] << 24) |
1533ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       (params->mac_addr[3] << 16) |
1534ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       (params->mac_addr[4] << 8) |
1535ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		params->mac_addr[5]);
15363196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1537ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
1538ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
15399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic void bnx2x_set_xumac_nig(struct link_params *params,
15409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				u16 tx_pause_en,
15419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				u8 enable)
15429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
15439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
15449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
15469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       enable);
15479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
15489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       enable);
15499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
15509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
15519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
15529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1553ce7c048928473220394bb126b08596e92e998a36Yaniv Rosnerstatic void bnx2x_umac_disable(struct link_params *params)
1554ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner{
1555ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1556ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	struct bnx2x *bp = params->bp;
1557ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	if (!(REG_RD(bp, MISC_REG_RESET_REG_2) &
1558ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		   (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1559ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		return;
1560ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner
1561ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	/* Disable RX and TX */
1562ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, 0);
1563ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner}
1564ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner
15659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic void bnx2x_umac_enable(struct link_params *params,
15669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			    struct link_vars *vars, u8 lb)
15679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
15689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 val;
15699380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
15709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
15719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Reset UMAC */
15729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
15739380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
15749380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	usleep_range(1000, 1000);
15759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
15779380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
15789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	DP(NETIF_MSG_LINK, "enabling UMAC\n");
15809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/**
15829380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * This register determines on which events the MAC will assert
15839380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * error on the i/f to the NIG along w/ EOP.
15849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
15859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15869380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/**
15879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * BD REG_WR(bp, NIG_REG_P0_MAC_RSV_ERR_MASK +
15889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * params->port*0x14,      0xfffff.
15899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
15909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* This register opens the gate for the UMAC despite its name */
15919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
15929380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
15939380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
15949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		UMAC_COMMAND_CONFIG_REG_PAD_EN |
15959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		UMAC_COMMAND_CONFIG_REG_SW_RESET |
15969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
15979380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	switch (vars->line_speed) {
15989380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case SPEED_10:
15999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val |= (0<<2);
16009380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
16019380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case SPEED_100:
16029380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val |= (1<<2);
16039380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
16049380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case SPEED_1000:
16059380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val |= (2<<2);
16069380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
16079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case SPEED_2500:
16089380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val |= (3<<2);
16099380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
16109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	default:
16119380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		DP(NETIF_MSG_LINK, "Invalid speed for UMAC %d\n",
16129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			       vars->line_speed);
16139380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
16149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
16159d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
16169d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
16179d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner
16189d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner	if (!(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
16199d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
16209d5b36be64b42058e7fd12b71266bbf2bb7600fcYaniv Rosner
1621e18c56b2e94080982d4542987a6fcf80b12d9414Mintz Yuval	if (vars->duplex == DUPLEX_HALF)
1622e18c56b2e94080982d4542987a6fcf80b12d9414Mintz Yuval		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1623e18c56b2e94080982d4542987a6fcf80b12d9414Mintz Yuval
16249380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
16259380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	udelay(50);
16269380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1627b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1628b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR0,
1629b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	       ((params->mac_addr[2] << 24) |
1630b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[3] << 16) |
1631b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[4] << 8) |
1632b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[5])));
1633b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_MAC_ADDR1,
1634b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	       ((params->mac_addr[0] << 8) |
1635b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		(params->mac_addr[1])));
1636b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
16379380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Enable RX and TX */
16389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
16399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
16403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		UMAC_COMMAND_CONFIG_REG_RX_ENA;
16419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
16429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	udelay(50);
16439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Remove SW Reset */
16459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
16469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Check loopback mode */
16489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (lb)
16499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
16509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_COMMAND_CONFIG, val);
16519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/*
16539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
16549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * length used by the MAC receive logic to check frames.
16559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
16569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
16579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_set_xumac_nig(params,
16589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			    ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
16599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->mac_type = MAC_TYPE_UMAC;
16609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
16629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* Define the XMAC mode */
1664ce7c048928473220394bb126b08596e92e998a36Yaniv Rosnerstatic void bnx2x_xmac_init(struct link_params *params, u32 max_speed)
16659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
1666ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	struct bnx2x *bp = params->bp;
16679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 is_port4mode = bnx2x_is_4_port_mode(bp);
16689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16692f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
16702f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * In 4-port mode, need to set the mode only once, so if XMAC is
16712f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * already out of reset, it means the mode has already been set,
16722f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * and it must not* reset the XMAC again, since it controls both
16732f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * ports of the path
16742f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
16759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1676ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	if ((CHIP_NUM(bp) == CHIP_NUM_57840) &&
1677ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	    (REG_RD(bp, MISC_REG_RESET_REG_2) &
16789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
167994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
168094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "XMAC already out of reset in 4-port mode\n");
16819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		return;
16829380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
16839380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Hard reset */
16859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
16869380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       MISC_REGISTERS_RESET_REG_2_XMAC);
16879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	usleep_range(1000, 1000);
16889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
16909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       MISC_REGISTERS_RESET_REG_2_XMAC);
16919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (is_port4mode) {
16929380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		DP(NETIF_MSG_LINK, "Init XMAC to 2 ports x 10G per path\n");
16939380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/*  Set the number of ports on the system side to up to 2 */
16959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 1);
16969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
16979380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/* Set the number of ports on the Warp Core to 10G */
16989380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
16999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else {
17009380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/*  Set the number of ports on the system side to 1 */
17019380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, MISC_REG_XMAC_CORE_PORT_MODE, 0);
17029380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (max_speed == SPEED_10000) {
170394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
170494f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Init XMAC to 10G x 1 port per path\n");
17059380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			/* Set the number of ports on the Warp Core to 10G */
17069380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 3);
17079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		} else {
170894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
170994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Init XMAC to 20G x 2 ports per path\n");
17109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			/* Set the number of ports on the Warp Core to 20G */
17119380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			REG_WR(bp, MISC_REG_XMAC_PHY_PORT_MODE, 1);
17129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
17139380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
17149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Soft reset */
17159380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
17169380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
17179380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	usleep_range(1000, 1000);
17189380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
17209380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
17219380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17229380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
17239380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17249380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic void bnx2x_xmac_disable(struct link_params *params)
17259380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
17269380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u8 port = params->port;
17279380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
1728b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner	u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
17299380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17309380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
17319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	    MISC_REGISTERS_RESET_REG_2_XMAC) {
1732b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		/*
1733b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		 * Send an indication to change the state in the NIG back to XON
1734b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		 * Clearing this bit enables the next set of this bit to get
1735b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		 * rising edge
1736b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		 */
1737b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		pfc_ctrl = REG_RD(bp, xmac_base + XMAC_REG_PFC_CTRL_HI);
1738b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1739b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		       (pfc_ctrl & ~(1<<1)));
1740b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_PFC_CTRL_HI,
1741b507766205f85d6d69892287e346a7c264a216b4Yaniv Rosner		       (pfc_ctrl | (1<<1)));
17429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		DP(NETIF_MSG_LINK, "Disable XMAC on port %x\n", port);
17439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, xmac_base + XMAC_REG_CTRL, 0);
17449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
17459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
17469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic int bnx2x_xmac_enable(struct link_params *params,
17489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			     struct link_vars *vars, u8 lb)
17499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
17509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 val, xmac_base;
17519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
17529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	DP(NETIF_MSG_LINK, "enabling XMAC\n");
17539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
17559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
1756ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	bnx2x_xmac_init(params, vars->line_speed);
17579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/*
17599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * This register determines on which events the MAC will assert
17609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * error on the i/f to the NIG along w/ EOP.
17619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
17629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/*
17649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * This register tells the NIG whether to send traffic to UMAC
17659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * or XMAC
17669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
17679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
17689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17699380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Set Max packet size */
17709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
17719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* CRC append for Tx packets */
17739380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
17749380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* update PFC */
17769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_update_pfc_xmac(params, vars, 0);
17779380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Enable TX and RX */
17799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
17809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* Check loopback mode */
17829380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (lb)
17834d7e25d6cc4312b1f949123fea7026fd56441513Yaniv Rosner		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
17849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, xmac_base + XMAC_REG_CTRL, val);
17859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_set_xumac_nig(params,
17869380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			    ((vars->flow_ctrl & BNX2X_FLOW_CTRL_TX) != 0), 1);
17879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->mac_type = MAC_TYPE_XMAC;
17899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
17909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	return 0;
17919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
17922f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
1793fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_emac_enable(struct link_params *params,
17949045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			     struct link_vars *vars, u8 lb)
1795ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
1796ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
1797ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u8 port = params->port;
1798ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1799ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 val;
1800ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1801ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "enabling EMAC\n");
1802ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1803de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	/* Disable BMAC */
1804de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1805de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
1806de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner
1807ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* enable emac and not bmac */
1808ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
1809ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1810ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* ASIC */
1811ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (vars->phy_flags & PHY_XGXS_FLAG) {
1812ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		u32 ser_lane = ((params->lane_config &
1813cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1814cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1815ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1816ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "XGXS\n");
1817ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* select the master lanes (out of 0-3) */
1818cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
1819ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* select XGXS */
1820cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
1821ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1822ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else { /* SerDes */
1823ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "SerDes\n");
1824ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* select SerDes */
1825cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
1826ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
1827ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1828811a2f2d3be9a39bd4e0930501fda8630857748dEilon Greenstein	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1829cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		      EMAC_RX_MODE_RESET);
1830811a2f2d3be9a39bd4e0930501fda8630857748dEilon Greenstein	bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1831cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		      EMAC_TX_MODE_RESET);
1832ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1833ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (CHIP_REV_IS_SLOW(bp)) {
1834ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* config GMII mode */
1835ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1836cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
1837ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else { /* ASIC */
1838ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* pause enable/disable */
1839ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
1840ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			       EMAC_RX_MODE_FLOW_EN);
1841ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1842ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
1843bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			       (EMAC_TX_MODE_EXT_PAUSE_EN |
1844bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				EMAC_TX_MODE_FLOW_EN));
1845bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		if (!(params->feature_config_flags &
1846bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		      FEATURE_CONFIG_PFC_ENABLED)) {
1847bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1848bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				bnx2x_bits_en(bp, emac_base +
1849bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					      EMAC_REG_EMAC_RX_MODE,
1850bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					      EMAC_RX_MODE_FLOW_EN);
1851bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1852bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1853bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				bnx2x_bits_en(bp, emac_base +
1854bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					      EMAC_REG_EMAC_TX_MODE,
1855bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					      (EMAC_TX_MODE_EXT_PAUSE_EN |
1856bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov					       EMAC_TX_MODE_FLOW_EN));
1857bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		} else
1858bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			bnx2x_bits_en(bp, emac_base + EMAC_REG_EMAC_TX_MODE,
1859bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				      EMAC_TX_MODE_FLOW_EN);
1860ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
1861ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1862ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* KEEP_VLAN_TAG, promiscuous */
1863ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
1864ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
1865bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
18662cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
18672cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Setting this bit causes MAC control frames (except for pause
18682cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * frames) to be passed on for processing. This setting has no
18692cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * affect on the operation of the pause frames. This bit effects
18702cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * all packets regardless of RX Parser packet sorting logic.
18712cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Turn the PFC off to make sure we are in Xon state before
18722cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * enabling it.
18732cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
1874bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	EMAC_WR(bp, EMAC_REG_RX_PFC_MODE, 0);
1875bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1876bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		DP(NETIF_MSG_LINK, "PFC is enabled\n");
1877bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* Enable PFC again */
1878bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		EMAC_WR(bp, EMAC_REG_RX_PFC_MODE,
1879bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			EMAC_REG_RX_PFC_MODE_RX_EN |
1880bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			EMAC_REG_RX_PFC_MODE_TX_EN |
1881bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			EMAC_REG_RX_PFC_MODE_PRIORITIES);
1882bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1883bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		EMAC_WR(bp, EMAC_REG_RX_PFC_PARAM,
1884bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			((0x0101 <<
1885bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			  EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
1886bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			 (0x00ff <<
1887bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			  EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
1888bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
1889bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
18903196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
1891ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1892ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* Set Loopback */
1893ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
1894ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (lb)
1895ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val |= 0x810;
1896ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	else
1897ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val &= ~0x810;
18983196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
1899ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
19006c55c3cdc86881383075a933594748b30dd0054bEilon Greenstein	/* enable emac */
19016c55c3cdc86881383075a933594748b30dd0054bEilon Greenstein	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
19026c55c3cdc86881383075a933594748b30dd0054bEilon Greenstein
1903ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* enable emac for jumbo packets */
19043196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
1905ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
1906ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
1907ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1908ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* strip CRC */
1909ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
1910ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1911ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* disable the NIG in/out to the bmac */
1912ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
1913ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
1914ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
1915ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1916ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* enable the NIG in/out to the emac */
1917ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
1918ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = 0;
1919bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if ((params->feature_config_flags &
1920bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	      FEATURE_CONFIG_PFC_ENABLED) ||
1921bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1922ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val = 1;
1923ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1924ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
1925ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
1926ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
192702a23165f807901818c33acd0facc4ab8f3ebdf7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
1928ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1929ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	vars->mac_type = MAC_TYPE_EMAC;
1930ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return 0;
1931ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
1932ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1933bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovstatic void bnx2x_update_pfc_bmac1(struct link_params *params,
1934bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				   struct link_vars *vars)
1935bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
1936bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 wb_data[2];
1937bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
1938bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1939bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		NIG_REG_INGRESS_BMAC0_MEM;
1940bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1941bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 val = 0x14;
1942bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if ((!(params->feature_config_flags &
1943bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	      FEATURE_CONFIG_PFC_ENABLED)) &&
1944bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1945bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* Enable BigMAC to react on received Pause packets */
1946bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		val |= (1<<5);
1947bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	wb_data[0] = val;
1948bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	wb_data[1] = 0;
1949bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
1950bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1951bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* tx control */
1952bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	val = 0xc0;
1953bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (!(params->feature_config_flags &
1954bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	      FEATURE_CONFIG_PFC_ENABLED) &&
1955bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		(vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1956bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		val |= 0x800000;
1957bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	wb_data[0] = val;
1958bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	wb_data[1] = 0;
1959bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
1960bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
1961bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1962bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovstatic void bnx2x_update_pfc_bmac2(struct link_params *params,
1963bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				   struct link_vars *vars,
1964bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				   u8 is_lb)
1965f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov{
1966f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/*
1967f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	 * Set rx control: Strip CRC and enable BigMAC to relay
1968f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	 * control packets to the system as well
1969f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	 */
1970f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 wb_data[2];
1971f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	struct bnx2x *bp = params->bp;
1972f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
1973f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		NIG_REG_INGRESS_BMAC0_MEM;
1974f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 val = 0x14;
1975ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1976bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if ((!(params->feature_config_flags &
1977bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	      FEATURE_CONFIG_PFC_ENABLED)) &&
1978bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		(vars->flow_ctrl & BNX2X_FLOW_CTRL_RX))
1979f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		/* Enable BigMAC to react on received Pause packets */
1980f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		val |= (1<<5);
1981f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = val;
1982f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
1983cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
1984f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
1985ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1986f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* Tx control */
1987f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	val = 0xc0;
1988bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (!(params->feature_config_flags &
1989bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				FEATURE_CONFIG_PFC_ENABLED) &&
1990bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
1991f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		val |= 0x800000;
1992f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = val;
1993f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
1994bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
1995bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
1996bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED) {
1997bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		DP(NETIF_MSG_LINK, "PFC is enabled\n");
1998bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* Enable PFC RX & TX & STATS and set 8 COS  */
1999bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] = 0x0;
2000bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] |= (1<<0);  /* RX */
2001bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] |= (1<<1);  /* TX */
2002bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] |= (1<<2);  /* Force initial Xon */
2003bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] |= (1<<3);  /* 8 cos */
2004bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] |= (1<<5);  /* STATS */
2005bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[1] = 0;
2006bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2007bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			    wb_data, 2);
2008bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* Clear the force Xon */
2009bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] &= ~(1<<2);
2010bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	} else {
2011bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		DP(NETIF_MSG_LINK, "PFC is disabled\n");
2012bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* disable PFC RX & TX & STATS and set 8 COS */
2013bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[0] = 0x8;
2014bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		wb_data[1] = 0;
2015bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
2016bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2017bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2018f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
20192cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
20202cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Set Time (based unit is 512 bit time) between automatic
20212cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * re-sending of PP packets amd enable automatic re-send of
20222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Per-Priroity Packet as long as pp_gen is asserted and
20232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * pp_disable is low.
20242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
2025f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	val = 0x8000;
2026bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2027bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		val |= (1<<16); /* enable automatic re-send */
2028bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2029f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = val;
2030f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2031f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2032cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    wb_data, 2);
2033f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2034f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* mac control */
2035f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	val = 0x3; /* Enable RX and TX */
2036f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (is_lb) {
2037f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		val |= 0x4; /* Local loopback */
2038f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2039f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	}
2040bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* When PFC enabled, Pass pause frames towards the NIG. */
2041bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2042bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		val |= ((1<<6)|(1<<5));
2043f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2044f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = val;
2045f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2046cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2047f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov}
2048f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
20499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner/* PFC BRB internal port configuration params */
20509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstruct bnx2x_pfc_brb_threshold_val {
20519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 pause_xoff;
20529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 pause_xon;
20539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 full_xoff;
20549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 full_xon;
20559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner};
20569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
20579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstruct bnx2x_pfc_brb_e3b0_val {
2058866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	u32 per_class_guaranty_mode;
2059866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	u32 lb_guarantied_hyst;
20609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 full_lb_xoff_th;
20619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 full_lb_xon_threshold;
20629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 lb_guarantied;
20639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 mac_0_class_t_guarantied;
20649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 mac_0_class_t_guarantied_hyst;
20659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 mac_1_class_t_guarantied;
20669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u32 mac_1_class_t_guarantied_hyst;
20679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner};
20689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
20699380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstruct bnx2x_pfc_brb_th_val {
20709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x_pfc_brb_threshold_val pauseable_th;
20719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x_pfc_brb_threshold_val non_pauseable_th;
2072866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	struct bnx2x_pfc_brb_threshold_val default_class0;
2073866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	struct bnx2x_pfc_brb_threshold_val default_class1;
2074866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
20759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner};
20769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic int bnx2x_pfc_brb_get_config_params(
20779380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				struct link_params *params,
20789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				struct bnx2x_pfc_brb_th_val *config_val)
20799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
20809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
20819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting PFC BRB configuration\n");
2082866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
2083866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	config_val->default_class1.pause_xoff = 0;
2084866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	config_val->default_class1.pause_xon = 0;
2085866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	config_val->default_class1.full_xoff = 0;
2086866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	config_val->default_class1.full_xon = 0;
2087866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
20889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (CHIP_IS_E2(bp)) {
2089866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		/*  class0 defaults */
2090866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xoff =
2091866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT0_E2_BRB_MAC_PAUSE_XOFF_THR;
2092866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xon =
20932f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E2_BRB_MAC_PAUSE_XON_THR;
2094866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xoff =
20952f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E2_BRB_MAC_FULL_XOFF_THR;
2096866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xon =
20972f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E2_BRB_MAC_FULL_XON_THR;
2098866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		/*  pause able*/
20999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.pause_xoff =
21002f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
21019380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.pause_xon =
21022f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_PAUSE_XON_THR_PAUSE;
21039380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.full_xoff =
21042f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_FULL_XOFF_THR_PAUSE;
21059380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.full_xon =
21062f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_FULL_XON_THR_PAUSE;
21079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/* non pause able*/
21089380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.pause_xoff =
21092f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
21109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.pause_xon =
21112f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
21129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.full_xoff =
21132f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
21149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.full_xon =
21152f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E2_BRB_MAC_FULL_XON_THR_NON_PAUSE;
21169380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else if (CHIP_IS_E3A0(bp)) {
2117866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		/*  class0 defaults */
2118866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xoff =
2119866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT0_E3A0_BRB_MAC_PAUSE_XOFF_THR;
2120866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xon =
21212f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E3A0_BRB_MAC_PAUSE_XON_THR;
2122866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xoff =
21232f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E3A0_BRB_MAC_FULL_XOFF_THR;
2124866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xon =
21252f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			DEFAULT0_E3A0_BRB_MAC_FULL_XON_THR;
2126866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		/*  pause able */
21279380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.pause_xoff =
21282f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
21299380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.pause_xon =
21302f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_PAUSE_XON_THR_PAUSE;
21319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.full_xoff =
21322f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_FULL_XOFF_THR_PAUSE;
21339380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->pauseable_th.full_xon =
21342f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_FULL_XON_THR_PAUSE;
21359380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		/* non pause able*/
21369380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.pause_xoff =
21372f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
21389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.pause_xon =
21392f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
21409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.full_xoff =
21412f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
21429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		config_val->non_pauseable_th.full_xon =
21432f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			PFC_E3A0_BRB_MAC_FULL_XON_THR_NON_PAUSE;
21449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else if (CHIP_IS_E3B0(bp)) {
2145866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		/*  class0 defaults */
2146866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xoff =
2147866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT0_E3B0_BRB_MAC_PAUSE_XOFF_THR;
2148866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.pause_xon =
2149866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		    DEFAULT0_E3B0_BRB_MAC_PAUSE_XON_THR;
2150866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xoff =
2151866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		    DEFAULT0_E3B0_BRB_MAC_FULL_XOFF_THR;
2152866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		config_val->default_class0.full_xon =
2153866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		    DEFAULT0_E3B0_BRB_MAC_FULL_XON_THR;
2154866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
21559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (params->phy[INT_PHY].flags &
21562f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		    FLAGS_4_PORT_MODE) {
21579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->pauseable_th.pause_xoff =
2158866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
21599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->pauseable_th.pause_xon =
2160866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_PAUSE;
21619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->pauseable_th.full_xoff =
2162866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_PAUSE;
21639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->pauseable_th.full_xon =
2164866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_PAUSE;
21659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			/* non pause able*/
21669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->non_pauseable_th.pause_xoff =
2167866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			PFC_E3B0_4P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
21689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->non_pauseable_th.pause_xon =
2169866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			PFC_E3B0_4P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
21709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->non_pauseable_th.full_xoff =
2171866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			PFC_E3B0_4P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
21729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			config_val->non_pauseable_th.full_xon =
2173866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			PFC_E3B0_4P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
2174866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		} else {
2175866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			config_val->pauseable_th.pause_xoff =
2176866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_PAUSE;
2177866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			config_val->pauseable_th.pause_xon =
21782f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_PAUSE;
21792f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->pauseable_th.full_xoff =
21802f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_PAUSE;
21812f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->pauseable_th.full_xon =
21822f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_PAUSE;
21832f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			/* non pause able*/
21842f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->non_pauseable_th.pause_xoff =
21852f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_PAUSE_XOFF_THR_NON_PAUSE;
21862f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->non_pauseable_th.pause_xon =
21872f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_PAUSE_XON_THR_NON_PAUSE;
21882f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->non_pauseable_th.full_xoff =
21892f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_FULL_XOFF_THR_NON_PAUSE;
21902f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			config_val->non_pauseable_th.full_xon =
21912f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				PFC_E3B0_2P_BRB_MAC_FULL_XON_THR_NON_PAUSE;
21922f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		}
21939380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else
21949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	    return -EINVAL;
21959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
21969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	return 0;
21979380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
21989380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2199866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosnerstatic void bnx2x_pfc_brb_get_e3b0_config_params(
2200866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		struct link_params *params,
2201866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		struct bnx2x_pfc_brb_e3b0_val
2202866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		*e3b0_val,
2203866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		struct bnx2x_nig_brb_pfc_port_params *pfc_params,
2204866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		const u8 pfc_enabled)
22059380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
2206866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	if (pfc_enabled && pfc_params) {
2207866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		e3b0_val->per_class_guaranty_mode = 1;
2208866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		e3b0_val->lb_guarantied_hyst = 80;
2209866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
2210866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		if (params->phy[INT_PHY].flags &
2211866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		    FLAGS_4_PORT_MODE) {
2212866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->full_lb_xoff_th =
2213866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_FULL_LB_XOFF_THR;
2214866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->full_lb_xon_threshold =
2215866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_FULL_LB_XON_THR;
2216866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->lb_guarantied =
2217866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_LB_GUART;
2218866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_0_class_t_guarantied =
2219866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART;
2220866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_0_class_t_guarantied_hyst =
2221866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_0_CLASS_T_GUART_HYST;
2222866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_1_class_t_guarantied =
2223866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART;
2224866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_1_class_t_guarantied_hyst =
2225866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_4P_BRB_MAC_1_CLASS_T_GUART_HYST;
2226866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		} else {
2227866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->full_lb_xoff_th =
2228866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_FULL_LB_XOFF_THR;
2229866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->full_lb_xon_threshold =
2230866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_FULL_LB_XON_THR;
2231866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_0_class_t_guarantied_hyst =
2232866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_MAC_0_CLASS_T_GUART_HYST;
2233866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_1_class_t_guarantied =
2234866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART;
2235866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			e3b0_val->mac_1_class_t_guarantied_hyst =
2236866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				PFC_E3B0_2P_BRB_MAC_1_CLASS_T_GUART_HYST;
2237866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner
2238866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			if (pfc_params->cos0_pauseable !=
2239866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				pfc_params->cos1_pauseable) {
2240866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				/* nonpauseable= Lossy + pauseable = Lossless*/
2241866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->lb_guarantied =
2242866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner					PFC_E3B0_2P_MIX_PAUSE_LB_GUART;
2243866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->mac_0_class_t_guarantied =
2244866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			       PFC_E3B0_2P_MIX_PAUSE_MAC_0_CLASS_T_GUART;
2245866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			} else if (pfc_params->cos0_pauseable) {
2246866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				/* Lossless +Lossless*/
2247866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->lb_guarantied =
2248866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner					PFC_E3B0_2P_PAUSE_LB_GUART;
2249866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->mac_0_class_t_guarantied =
2250866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				   PFC_E3B0_2P_PAUSE_MAC_0_CLASS_T_GUART;
2251866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			} else {
2252866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				/* Lossy +Lossy*/
2253866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->lb_guarantied =
2254866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner					PFC_E3B0_2P_NON_PAUSE_LB_GUART;
2255866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner				e3b0_val->mac_0_class_t_guarantied =
2256866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			       PFC_E3B0_2P_NON_PAUSE_MAC_0_CLASS_T_GUART;
2257866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			}
2258866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		}
2259866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	} else {
2260866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		e3b0_val->per_class_guaranty_mode = 0;
2261866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		e3b0_val->lb_guarantied_hyst = 0;
22629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->full_lb_xoff_th =
2263866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_FULL_LB_XOFF_THR;
22649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->full_lb_xon_threshold =
2265866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_FULL_LB_XON_THR;
22669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->lb_guarantied =
2267866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_LB_GUART;
22689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->mac_0_class_t_guarantied =
2269866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART;
22709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->mac_0_class_t_guarantied_hyst =
2271866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_MAC_0_CLASS_T_GUART_HYST;
22729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->mac_1_class_t_guarantied =
2273866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART;
22749380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		e3b0_val->mac_1_class_t_guarantied_hyst =
2275866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			DEFAULT_E3B0_BRB_MAC_1_CLASS_T_GUART_HYST;
22769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
22779380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
22789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerstatic int bnx2x_update_pfc_brb(struct link_params *params,
22799380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				struct link_vars *vars,
22809380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				struct bnx2x_nig_brb_pfc_port_params
22819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				*pfc_params)
2282bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
2283bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
22849380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x_pfc_brb_th_val config_val = { {0} };
22859380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x_pfc_brb_threshold_val *reg_th_config =
22862f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		&config_val.pauseable_th;
22879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x_pfc_brb_e3b0_val e3b0_val = {0};
2288866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	const int set_pfc = params->feature_config_flags &
2289bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		FEATURE_CONFIG_PFC_ENABLED;
2290866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	const u8 pfc_enabled = (set_pfc && pfc_params);
22919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	int bnx2x_status = 0;
22929380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u8 port = params->port;
2293bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2294bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* default - pause configuration */
22959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	reg_th_config = &config_val.pauseable_th;
22969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_status = bnx2x_pfc_brb_get_config_params(params, &config_val);
2297de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (bnx2x_status)
22989380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		return bnx2x_status;
2299bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2300866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	if (pfc_enabled) {
2301bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* First COS */
2302866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		if (pfc_params->cos0_pauseable)
2303866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			reg_th_config = &config_val.pauseable_th;
2304866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		else
23059380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			reg_th_config = &config_val.non_pauseable_th;
2306866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	} else
2307866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		reg_th_config = &config_val.default_class0;
23082cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
23092cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The number of free blocks below which the pause signal to class 0
23102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * of MAC #n is asserted. n=0,1
23112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
23129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XOFF_THRESHOLD_1 :
23139380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       BRB1_REG_PAUSE_0_XOFF_THRESHOLD_0 ,
23149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       reg_th_config->pause_xoff);
23152cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
23162cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The number of free blocks above which the pause signal to class 0
23172cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * of MAC #n is de-asserted. n=0,1
23182cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
23199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_PAUSE_0_XON_THRESHOLD_1 :
23209380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       BRB1_REG_PAUSE_0_XON_THRESHOLD_0 , reg_th_config->pause_xon);
23212cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
23222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The number of free blocks below which the full signal to class 0
23232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * of MAC #n is asserted. n=0,1
23242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
23259380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XOFF_THRESHOLD_1 :
23269380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       BRB1_REG_FULL_0_XOFF_THRESHOLD_0 , reg_th_config->full_xoff);
23272cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
23282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The number of free blocks above which the full signal to class 0
23292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * of MAC #n is de-asserted. n=0,1
23302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
23319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_FULL_0_XON_THRESHOLD_1 :
23329380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	       BRB1_REG_FULL_0_XON_THRESHOLD_0 , reg_th_config->full_xon);
2333bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2334866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	if (pfc_enabled) {
2335bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		/* Second COS */
23369380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (pfc_params->cos1_pauseable)
23379380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			reg_th_config = &config_val.pauseable_th;
23389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		else
23399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			reg_th_config = &config_val.non_pauseable_th;
2340866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	} else
2341866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		reg_th_config = &config_val.default_class1;
23422f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
23432f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * The number of free blocks below which the pause signal to
23442f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * class 1 of MAC #n is asserted. n=0,1
23452f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
23462f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XOFF_THRESHOLD_1 :
23472f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       BRB1_REG_PAUSE_1_XOFF_THRESHOLD_0,
23482f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       reg_th_config->pause_xoff);
23492f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
23502f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
23512f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * The number of free blocks above which the pause signal to
23522f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * class 1 of MAC #n is de-asserted. n=0,1
23532f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
23542f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_PAUSE_1_XON_THRESHOLD_1 :
23552f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       BRB1_REG_PAUSE_1_XON_THRESHOLD_0,
23562f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       reg_th_config->pause_xon);
23572f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
23582f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * The number of free blocks below which the full signal to
23592f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * class 1 of MAC #n is asserted. n=0,1
23602f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
23612f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_FULL_1_XOFF_THRESHOLD_1 :
23622f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       BRB1_REG_FULL_1_XOFF_THRESHOLD_0,
23632f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       reg_th_config->full_xoff);
23642f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
23652f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * The number of free blocks above which the full signal to
23662f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * class 1 of MAC #n is de-asserted. n=0,1
23672f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
23682f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	REG_WR(bp, (port) ? BRB1_REG_FULL_1_XON_THRESHOLD_1 :
23692f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       BRB1_REG_FULL_1_XON_THRESHOLD_0,
23702f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	       reg_th_config->full_xon);
23719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2372866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner	if (CHIP_IS_E3B0(bp)) {
2373866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		bnx2x_pfc_brb_get_e3b0_config_params(
2374866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			params,
2375866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			&e3b0_val,
2376866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			pfc_params,
2377866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			pfc_enabled);
23789380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2379866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		REG_WR(bp, BRB1_REG_PER_CLASS_GUARANTY_MODE,
2380866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			   e3b0_val.per_class_guaranty_mode);
23819380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
23822f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
23832f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The hysteresis on the guarantied buffer space for the Lb
23842f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * port before signaling XON.
23852f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
2386866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		REG_WR(bp, BRB1_REG_LB_GUARANTIED_HYST,
2387866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner			   e3b0_val.lb_guarantied_hyst);
23882f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
23892f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
23902f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of free blocks below which the full signal to the
23912f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * LB port is asserted.
23922f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
2393866cedae516e1d348fddc0a8782e2480c3169dbaYaniv Rosner		REG_WR(bp, BRB1_REG_FULL_LB_XOFF_THRESHOLD,
23942f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.full_lb_xoff_th);
23952f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
23962f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of free blocks above which the full signal to the
23972f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * LB port is de-asserted.
23982f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
23992f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_FULL_LB_XON_THRESHOLD,
24002f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.full_lb_xon_threshold);
24012f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24022f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of blocks guarantied for the MAC #n port. n=0,1
24032f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24042f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
24052f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/* The number of blocks guarantied for the LB port.*/
24062f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_LB_GUARANTIED,
24072f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.lb_guarantied);
24082f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
24092f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24102f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of blocks guarantied for the MAC #n port.
24112f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24122f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_GUARANTIED_0,
24132f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       2 * e3b0_val.mac_0_class_t_guarantied);
24142f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_GUARANTIED_1,
24152f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       2 * e3b0_val.mac_1_class_t_guarantied);
24162f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24172f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of blocks guarantied for class #t in MAC0. t=0,1
24182f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24192f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED,
24202f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_0_class_t_guarantied);
24212f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED,
24222f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_0_class_t_guarantied);
24232f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24242f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The hysteresis on the guarantied buffer space for class in
24252f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * MAC0.  t=0,1
24262f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24272f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_0_CLASS_0_GUARANTIED_HYST,
24282f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_0_class_t_guarantied_hyst);
24292f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_0_CLASS_1_GUARANTIED_HYST,
24302f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_0_class_t_guarantied_hyst);
24312f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
24322f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24332f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The number of blocks guarantied for class #t in MAC1.t=0,1
24342f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24352f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED,
24362f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_1_class_t_guarantied);
24372f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED,
24382f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_1_class_t_guarantied);
24392f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		/*
24402f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * The hysteresis on the guarantied buffer space for class #t
24412f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 * in MAC1.  t=0,1
24422f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		 */
24432f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_1_CLASS_0_GUARANTIED_HYST,
24442f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_1_class_t_guarantied_hyst);
24452f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		REG_WR(bp, BRB1_REG_MAC_1_CLASS_1_GUARANTIED_HYST,
24462f751a805e35dcf687473c27282a6602577df541Yaniv Rosner		       e3b0_val.mac_1_class_t_guarantied_hyst);
24472f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	}
24489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
24499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	return bnx2x_status;
2450bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
2451bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2452619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov/******************************************************************************
2453619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov* Description:
2454619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov*  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2455619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov*  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2456619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov******************************************************************************/
2457619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarovint bnx2x_pfc_nig_rx_priority_mask(struct bnx2x *bp,
2458619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov					      u8 cos_entry,
2459619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov					      u32 priority_mask, u8 port)
2460619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov{
2461619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	u32 nig_reg_rx_priority_mask_add = 0;
2462619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov
2463619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	switch (cos_entry) {
2464619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 0:
2465619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	     nig_reg_rx_priority_mask_add = (port) ?
2466619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2467619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2468619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	     break;
2469619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 1:
2470619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    nig_reg_rx_priority_mask_add = (port) ?
2471619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2472619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2473619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    break;
2474619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 2:
2475619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    nig_reg_rx_priority_mask_add = (port) ?
2476619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2477619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2478619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    break;
2479619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 3:
2480619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    if (port)
2481619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		return -EINVAL;
2482619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2483619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    break;
2484619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 4:
2485619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    if (port)
2486619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		return -EINVAL;
2487619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2488619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    break;
2489619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	case 5:
2490619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    if (port)
2491619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		return -EINVAL;
2492619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2493619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	    break;
2494619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	}
2495619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov
2496619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	REG_WR(bp, nig_reg_rx_priority_mask_add, priority_mask);
2497619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov
2498619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov	return 0;
2499619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov}
2500b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosnerstatic void bnx2x_update_mng(struct link_params *params, u32 link_status)
2501b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner{
2502b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	struct bnx2x *bp = params->bp;
2503b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
2504b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	REG_WR(bp, params->shmem_base +
2505b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	       offsetof(struct shmem_region,
2506b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner			port_mb[params->port].link_status), link_status);
2507b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner}
2508b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
2509bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarovstatic void bnx2x_update_pfc_nig(struct link_params *params,
2510bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		struct link_vars *vars,
2511bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		struct bnx2x_nig_brb_pfc_port_params *nig_params)
2512bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
2513bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2514127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2515bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 pkt_priority_to_cos = 0;
2516bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
25179380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u8 port = params->port;
25189380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2519bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	int set_pfc = params->feature_config_flags &
2520bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		FEATURE_CONFIG_PFC_ENABLED;
2521bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "updating pfc nig parameters\n");
2522bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
25232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
2524bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2525bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * MAC control frames (that are not pause packets)
2526bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * will be forwarded to the XCM.
2527bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
2528127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	xcm_mask = REG_RD(bp, port ? NIG_REG_LLH1_XCM_MASK :
2529127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner			  NIG_REG_LLH0_XCM_MASK);
25302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
2531bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * nig params will override non PFC params, since it's possible to
2532bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * do transition from PFC to SAFC
2533bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
2534bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (set_pfc) {
2535bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		pause_enable = 0;
2536bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		llfc_out_en = 0;
2537bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		llfc_enable = 0;
25389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (CHIP_IS_E3(bp))
25399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			ppp_enable = 0;
25409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		else
2541bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		ppp_enable = 1;
2542bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2543bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov				     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2544127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner		xcm_out_en = 0;
2545127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner		hwpfc_enable = 1;
2546bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	} else  {
2547bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		if (nig_params) {
2548bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			llfc_out_en = nig_params->llfc_out_en;
2549bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			llfc_enable = nig_params->llfc_enable;
2550bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			pause_enable = nig_params->pause_enable;
2551bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		} else  /*defaul non PFC mode - PAUSE */
2552bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			pause_enable = 1;
2553bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2554bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2555bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov			NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2556127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner		xcm_out_en = 1;
2557bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
2558bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
25599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (CHIP_IS_E3(bp))
25609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, port ? NIG_REG_BRB1_PAUSE_IN_EN :
25619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2562bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_LLFC_OUT_EN_1 :
2563bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2564bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_LLFC_ENABLE_1 :
2565bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
2566bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_PAUSE_ENABLE_1 :
2567bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
2568bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2569bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_PPP_ENABLE_1 :
2570bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_PPP_ENABLE_0, ppp_enable);
2571bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2572bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_LLH1_XCM_MASK :
2573bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
2574bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2575127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	REG_WR(bp, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2576127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	       NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2577bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2578bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* output enable for RX_XCM # IF */
2579127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	REG_WR(bp, port ? NIG_REG_XCM1_OUT_EN :
2580127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	       NIG_REG_XCM0_OUT_EN, xcm_out_en);
2581bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2582bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* HW PFC TX enable */
2583127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	REG_WR(bp, port ? NIG_REG_P1_HWPFC_ENABLE :
2584127302bb42257eef5d357722d670c4ac53327088Yaniv Rosner	       NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2585bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2586bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (nig_params) {
2587619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		u8 i = 0;
2588bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2589bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2590619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2591619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov			bnx2x_pfc_nig_rx_priority_mask(bp, i,
2592619c5cb6885b936c44ae1422ef805b69c6291485Vlad Zolotarov		nig_params->rx_cos_priority_mask[i], port);
2593bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2594bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		REG_WR(bp, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2595bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2596bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		       nig_params->llfc_high_priority_classes);
2597bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2598bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		REG_WR(bp, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2599bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2600bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		       nig_params->llfc_low_priority_classes);
2601bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	}
2602bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	REG_WR(bp, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2603bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       NIG_REG_P0_PKT_PRIORITY_TO_COS,
2604bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	       pkt_priority_to_cos);
2605bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
2606bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
26079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnerint bnx2x_update_pfc(struct link_params *params,
2608bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		      struct link_vars *vars,
2609bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov		      struct bnx2x_nig_brb_pfc_port_params *pfc_params)
2610bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov{
26112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
2612bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * The PFC and pause are orthogonal to one another, meaning when
2613bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * PFC is enabled, the pause are disabled, and when PFC is
2614bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 * disabled, pause are set according to the pause result.
2615bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	 */
2616bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	u32 val;
2617bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	struct bnx2x *bp = params->bp;
26189380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	int bnx2x_status = 0;
26199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u8 bmac_loopback = (params->loopback_mode == LOOPBACK_BMAC);
2620b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
2621b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
2622b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		vars->link_status |= LINK_STATUS_PFC_ENABLED;
2623b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	else
2624b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2625b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
2626b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	bnx2x_update_mng(params, vars->link_status);
2627b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
2628bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* update NIG params */
2629bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	bnx2x_update_pfc_nig(params, vars, pfc_params);
2630bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2631bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	/* update BRB params */
26329380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_status = bnx2x_update_pfc_brb(params, vars, pfc_params);
2633de0396f4003a24a57875b35f2996fdaa47bc1d0dYaniv Rosner	if (bnx2x_status)
26349380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		return bnx2x_status;
2635bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2636bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if (!vars->link_up)
26379380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		return bnx2x_status;
2638bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov
2639bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	DP(NETIF_MSG_LINK, "About to update PFC in BMAC\n");
26409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (CHIP_IS_E3(bp))
26419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_update_pfc_xmac(params, vars, 0);
26429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	else {
26439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val = REG_RD(bp, MISC_REG_RESET_REG_2);
26449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if ((val &
26453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
26469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		    == 0) {
26479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			DP(NETIF_MSG_LINK, "About to update PFC in EMAC\n");
26489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_emac_enable(params, vars, 0);
26499380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			return bnx2x_status;
26509380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
26519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (CHIP_IS_E2(bp))
26529380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_update_pfc_bmac2(params, vars, bmac_loopback);
26539380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		else
26549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_update_pfc_bmac1(params, vars);
26559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
26569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		val = 0;
26579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if ((params->feature_config_flags &
26589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		     FEATURE_CONFIG_PFC_ENABLED) ||
26599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
26609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			val = 1;
26619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
26629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
26639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	return bnx2x_status;
2664bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov}
2665f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
26669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
2667fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_bmac1_enable(struct link_params *params,
2668fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      struct link_vars *vars,
2669fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      u8 is_lb)
2670ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
2671ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
2672ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u8 port = params->port;
2673ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2674ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			       NIG_REG_INGRESS_BMAC0_MEM;
2675ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 wb_data[2];
2676ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 val;
2677ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2678f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	DP(NETIF_MSG_LINK, "Enabling BigMAC1\n");
2679ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2680ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* XGXS control */
2681ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = 0x3c;
2682ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2683cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2684cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    wb_data, 2);
2685ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2686ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* tx MAC SA */
2687ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = ((params->mac_addr[2] << 24) |
2688ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		       (params->mac_addr[3] << 16) |
2689ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		       (params->mac_addr[4] << 8) |
2690ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			params->mac_addr[5]);
2691ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = ((params->mac_addr[0] << 8) |
2692ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			params->mac_addr[1]);
2693cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2694ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2695ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* mac control */
2696ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = 0x3;
2697ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (is_lb) {
2698ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val |= 0x4;
2699ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "enable bmac loopback\n");
2700ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2701ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = val;
2702ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2703cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2704ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2705ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* set rx mtu */
2706ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2707ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2708cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2709ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2710bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	bnx2x_update_pfc_bmac1(params, vars);
2711ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2712ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* set tx mtu */
2713ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2714ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2715cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2716ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2717ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* set cnt max size */
2718ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2719ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2720cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2721ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2722ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* configure safc */
2723ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[0] = 0x1000200;
2724ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	wb_data[1] = 0;
2725ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2726ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		    wb_data, 2);
2727f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2728f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	return 0;
2729f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov}
2730f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2731fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_bmac2_enable(struct link_params *params,
2732fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      struct link_vars *vars,
2733fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      u8 is_lb)
2734f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov{
2735f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	struct bnx2x *bp = params->bp;
2736f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u8 port = params->port;
2737f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2738f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			       NIG_REG_INGRESS_BMAC0_MEM;
2739f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 wb_data[2];
2740f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2741f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	DP(NETIF_MSG_LINK, "Enabling BigMAC2\n");
2742f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2743f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = 0;
2744f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2745cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2746f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2747f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2748f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2749f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = 0x3c;
2750f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2751cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2752cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    wb_data, 2);
2753f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2754f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2755f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2756f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* tx MAC SA */
2757f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = ((params->mac_addr[2] << 24) |
2758f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		       (params->mac_addr[3] << 16) |
2759f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		       (params->mac_addr[4] << 8) |
2760f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			params->mac_addr[5]);
2761f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = ((params->mac_addr[0] << 8) |
2762f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			params->mac_addr[1]);
2763f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2764cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    wb_data, 2);
2765f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2766f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2767f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2768f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* Configure SAFC */
2769f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = 0x1000200;
2770f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2771f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2772cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    wb_data, 2);
2773f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2774f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2775f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* set rx mtu */
2776f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2777f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2778cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2779f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2780f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2781f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* set tx mtu */
2782f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
2783f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2784cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2785f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2786f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* set cnt max size */
2787f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD - 2;
2788f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	wb_data[1] = 0;
2789cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR_DMAE(bp, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2790f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	udelay(30);
2791bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	bnx2x_update_pfc_bmac2(params, vars, is_lb);
2792f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2793f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	return 0;
2794f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov}
2795f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2796fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_bmac_enable(struct link_params *params,
2797fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			     struct link_vars *vars,
2798fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			     u8 is_lb)
2799f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov{
2800fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
2801fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	u8 port = params->port;
2802f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	struct bnx2x *bp = params->bp;
2803f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u32 val;
2804f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* reset and unreset the BigMac */
2805f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2806cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
28071d9c05d4d234493351cc39d8129fe5811147b2ffYaniv Rosner	msleep(1);
2808f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2809f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2810cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2811f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2812f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* enable access for bmac registers */
2813f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2814f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
2815f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	/* Enable BMAC according to BMAC type*/
2816f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (CHIP_IS_E2(bp))
2817f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc = bnx2x_bmac2_enable(params, vars, is_lb);
2818f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
2819f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc = bnx2x_bmac1_enable(params, vars, is_lb);
2820ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2821ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2822ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2823ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	val = 0;
2824bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	if ((params->feature_config_flags &
2825bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	      FEATURE_CONFIG_PFC_ENABLED) ||
2826bcab15c5d780bafb38311f00fcb263d03d2b00f1Vladislav Zolotarov	    (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX))
2827ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val = 1;
2828ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2829ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2830ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2831ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2832ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2833ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2834ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2835ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	vars->mac_type = MAC_TYPE_BMAC;
2836f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	return rc;
2837ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
2838ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2839ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosnerstatic void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
2840ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
2841ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2842cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_REG_INGRESS_BMAC0_MEM;
2843ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 wb_data[2];
28443196a88a8593748bad24824ef5eb8e5aa99698c9Eilon Greenstein	u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2845ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2846ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* Only if the bmac is out of reset */
2847ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
2848ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2849ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	    nig_bmac_enable) {
2850ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2851f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		if (CHIP_IS_E2(bp)) {
2852f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			/* Clear Rx Enable bit in BMAC_CONTROL register */
2853f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			REG_RD_DMAE(bp, bmac_addr +
2854cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				    BIGMAC2_REGISTER_BMAC_CONTROL,
2855cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				    wb_data, 2);
2856f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2857f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			REG_WR_DMAE(bp, bmac_addr +
2858cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				    BIGMAC2_REGISTER_BMAC_CONTROL,
2859cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				    wb_data, 2);
2860f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		} else {
2861f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			/* Clear Rx Enable bit in BMAC_CONTROL register */
2862f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			REG_RD_DMAE(bp, bmac_addr +
2863f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov					BIGMAC_REGISTER_BMAC_CONTROL,
2864f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov					wb_data, 2);
2865f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
2866f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			REG_WR_DMAE(bp, bmac_addr +
2867f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov					BIGMAC_REGISTER_BMAC_CONTROL,
2868f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov					wb_data, 2);
2869f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		}
2870ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		msleep(1);
2871ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2872ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
2873ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2874fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
2875fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			    u32 line_speed)
2876ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
2877ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
2878ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u8 port = params->port;
2879ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 init_crd, crd;
2880ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 count = 1000;
2881ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2882ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* disable port */
2883ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2884ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2885ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* wait for init credit */
2886ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
2887ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2888ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2889ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2890ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	while ((init_crd != crd) && count) {
2891ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		msleep(5);
2892ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2893ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2894ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		count--;
2895ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2896ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
2897ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (init_crd != crd) {
2898ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
2899ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			  init_crd, crd);
2900ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		return -EINVAL;
2901ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2902ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2903c0700f90e5300c63d01c70e157e75e4510dd2981David S. Miller	if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
29048c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	    line_speed == SPEED_10 ||
29058c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	    line_speed == SPEED_100 ||
29068c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	    line_speed == SPEED_1000 ||
29078c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	    line_speed == SPEED_2500) {
29088c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2909ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* update threshold */
2910ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
2911ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* update init credit */
2912cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		init_crd = 778;		/* (800-18-4) */
2913ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2914ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
2915ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
2916ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			      ETH_OVREHEAD)/16;
29178c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2918ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* update threshold */
2919ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2920ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* update init credit */
2921ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		switch (line_speed) {
2922ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case SPEED_10000:
2923ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			init_crd = thresh + 553 - 22;
2924ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
2925ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		default:
2926ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
2927ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				  line_speed);
2928ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			return -EINVAL;
2929ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
2930ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2931ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2932ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
2933ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		 line_speed, init_crd);
2934ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2935ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* probe the credit changes */
2936ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
2937ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	msleep(5);
2938ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
2939ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2940ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* enable port */
2941ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2942ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return 0;
2943ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
2944ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2945e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov/**
2946e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov * bnx2x_get_emac_base - retrive emac base address
29472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner *
2948e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov * @bp:			driver handle
2949e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov * @mdc_mdio_access:	access type
2950e8920674979705392abc4db4ebbe78feb68a4da1Dmitry Kravkov * @port:		port id
29512cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner *
29522cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * This function selects the MDC/MDIO access (through emac0 or
29532cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * emac1) depend on the mdc_mdio_access, port, port swapped. Each
29542cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * phy has a default access mode, which could also be overridden
29552cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * by nvram configuration. This parameter, whether this is the
29562cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * default phy configuration, or the nvram overrun
29572cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * configuration, is passed here as mdc_mdio_access and selects
29582cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * the emac_base for the CL45 read/writes operations
29592cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner */
2960c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosnerstatic u32 bnx2x_get_emac_base(struct bnx2x *bp,
2961c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner			       u32 mdc_mdio_access, u8 port)
2962ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
2963c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	u32 emac_base = 0;
2964c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	switch (mdc_mdio_access) {
2965c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2966c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		break;
2967c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2968c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		if (REG_RD(bp, NIG_REG_PORT_SWAP))
2969c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner			emac_base = GRCBASE_EMAC1;
2970c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		else
2971c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner			emac_base = GRCBASE_EMAC0;
2972c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		break;
2973c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2974589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein		if (REG_RD(bp, NIG_REG_PORT_SWAP))
2975589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein			emac_base = GRCBASE_EMAC0;
2976589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein		else
2977589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein			emac_base = GRCBASE_EMAC1;
2978ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
2979c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2980c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2981c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		break;
2982c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
29836378c0253175e400525ac0efac9dd29f4e573cbfEilon Greenstein		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2984ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
2985ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	default:
2986ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
2987ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
2988ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return emac_base;
2989ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
2990ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
2991ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
29922cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/******************************************************************/
29936583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner/*			CL22 access functions			  */
29946583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner/******************************************************************/
29956583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosnerstatic int bnx2x_cl22_write(struct bnx2x *bp,
29966583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				       struct bnx2x_phy *phy,
29976583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				       u16 reg, u16 val)
29986583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
29996583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u32 tmp, mode;
30006583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u8 i;
30016583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	int rc = 0;
30026583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Switch to CL22 */
30036583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
30046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
30056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
30066583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30076583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* address */
30086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	tmp = ((phy->addr << 21) | (reg << 16) | val |
30096583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       EMAC_MDIO_COMM_COMMAND_WRITE_22 |
30106583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       EMAC_MDIO_COMM_START_BUSY);
30116583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
30126583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30136583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	for (i = 0; i < 50; i++) {
30146583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		udelay(10);
30156583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30166583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
30176583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
30186583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			udelay(5);
30196583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			break;
30206583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		}
30216583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
30226583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
30236583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "write phy register failed\n");
30246583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		rc = -EFAULT;
30256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
30266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
30276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	return rc;
30286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
30296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosnerstatic int bnx2x_cl22_read(struct bnx2x *bp,
30316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				      struct bnx2x_phy *phy,
30326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				      u16 reg, u16 *ret_val)
30336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
30346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u32 val, mode;
30356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u16 i;
30366583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	int rc = 0;
30376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30386583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Switch to CL22 */
30396583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	mode = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
30406583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
30416583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
30426583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30436583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* address */
30446583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	val = ((phy->addr << 21) | (reg << 16) |
30456583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       EMAC_MDIO_COMM_COMMAND_READ_22 |
30466583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	       EMAC_MDIO_COMM_START_BUSY);
30476583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
30486583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30496583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	for (i = 0; i < 50; i++) {
30506583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		udelay(10);
30516583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30526583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
30536583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
30546583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
30556583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			udelay(5);
30566583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			break;
30576583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		}
30586583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
30596583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (val & EMAC_MDIO_COMM_START_BUSY) {
30606583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "read phy register failed\n");
30616583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30626583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		*ret_val = 0;
30636583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		rc = -EFAULT;
30646583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
30656583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
30666583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	return rc;
30676583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
30686583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
30696583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner/******************************************************************/
30702cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/*			CL45 access functions			  */
30712cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/******************************************************************/
3072a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosnerstatic int bnx2x_cl45_read(struct bnx2x *bp, struct bnx2x_phy *phy,
3073a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			   u8 devad, u16 reg, u16 *ret_val)
3074ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
3075a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	u32 val;
3076a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	u16 i;
3077fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
3078157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3079157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3080157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner			      EMAC_MDIO_STATUS_10MB);
3081ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* address */
3082a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	val = ((phy->addr << 21) | (devad << 16) | reg |
3083ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3084ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       EMAC_MDIO_COMM_START_BUSY);
3085a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3086ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3087ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	for (i = 0; i < 50; i++) {
3088ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		udelay(10);
3089ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3090a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		val = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3091a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3092ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			udelay(5);
3093ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
3094ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3095ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
3096a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	if (val & EMAC_MDIO_COMM_START_BUSY) {
3097a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		DP(NETIF_MSG_LINK, "read phy register failed\n");
30986d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner		netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3099a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		*ret_val = 0;
3100ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		rc = -EFAULT;
3101ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
3102ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* data */
3103a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		val = ((phy->addr << 21) | (devad << 16) |
3104a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		       EMAC_MDIO_COMM_COMMAND_READ_45 |
3105ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		       EMAC_MDIO_COMM_START_BUSY);
3106a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
3107ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3108ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		for (i = 0; i < 50; i++) {
3109ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			udelay(10);
3110ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3111a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			val = REG_RD(bp, phy->mdio_ctrl +
3112cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				     EMAC_REG_EMAC_MDIO_COMM);
3113a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
3114a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner				*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
3115ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				break;
3116ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			}
3117ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3118a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		if (val & EMAC_MDIO_COMM_START_BUSY) {
3119a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			DP(NETIF_MSG_LINK, "read phy register failed\n");
31206d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3121a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			*ret_val = 0;
3122ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			rc = -EFAULT;
3123ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3124ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
31253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Work around for E3 A0 */
31263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA) {
31273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		phy->flags ^= FLAGS_DUMMY_READ;
31283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (phy->flags & FLAGS_DUMMY_READ) {
31293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			u16 temp_val;
31303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
31313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
31323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
3133ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3134157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3135157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3136157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner			       EMAC_MDIO_STATUS_10MB);
3137ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return rc;
3138ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
3139ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3140a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosnerstatic int bnx2x_cl45_write(struct bnx2x *bp, struct bnx2x_phy *phy,
3141a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			    u8 devad, u16 reg, u16 val)
3142ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
3143a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	u32 tmp;
3144a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	u8 i;
3145fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
3146157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3147157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner		bnx2x_bits_en(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3148157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner			      EMAC_MDIO_STATUS_10MB);
3149ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3150ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* address */
3151a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner
3152a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	tmp = ((phy->addr << 21) | (devad << 16) | reg |
3153ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3154ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	       EMAC_MDIO_COMM_START_BUSY);
3155a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3156ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3157ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	for (i = 0; i < 50; i++) {
3158ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		udelay(10);
3159ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3160a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		tmp = REG_RD(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3161a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3162ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			udelay(5);
3163ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
3164ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3165ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
3166a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3167a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		DP(NETIF_MSG_LINK, "write phy register failed\n");
31686d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner		netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3169ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		rc = -EFAULT;
3170ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
3171ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* data */
3172a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		tmp = ((phy->addr << 21) | (devad << 16) | val |
3173a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3174ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		       EMAC_MDIO_COMM_START_BUSY);
3175a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		REG_WR(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3176ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3177ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		for (i = 0; i < 50; i++) {
3178ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			udelay(10);
3179ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3180a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			tmp = REG_RD(bp, phy->mdio_ctrl +
3181cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				     EMAC_REG_EMAC_MDIO_COMM);
3182a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3183a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner				udelay(5);
3184ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				break;
3185ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			}
3186ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3187a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3188a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner			DP(NETIF_MSG_LINK, "write phy register failed\n");
31896d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			netdev_err(bp->dev,  "MDC/MDIO access timeout\n");
3190ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			rc = -EFAULT;
3191ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
3192ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
31933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Work around for E3 A0 */
31943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA) {
31953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		phy->flags ^= FLAGS_DUMMY_READ;
31963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (phy->flags & FLAGS_DUMMY_READ) {
31973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			u16 temp_val;
31983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_cl45_read(bp, phy, devad, 0xf, &temp_val);
31993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
32003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
3201157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner	if (phy->flags & FLAGS_MDC_MDIO_WA_B0)
3202157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner		bnx2x_bits_dis(bp, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3203157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner			       EMAC_MDIO_STATUS_10MB);
32043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return rc;
32053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
32063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
32073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/*			BSC access functions from E3	          */
32083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
32093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_bsc_module_sel(struct link_params *params)
32103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
32113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	int idx;
32123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 board_cfg, sfp_ctrl;
32133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 i2c_pins[I2C_SWITCH_WIDTH], i2c_val[I2C_SWITCH_WIDTH];
32143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
32153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 port = params->port;
32163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Read I2C output PINs */
32173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	board_cfg = REG_RD(bp, params->shmem_base +
32183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			   offsetof(struct shmem_region,
32193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				    dev_info.shared_hw_config.board));
32203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i2c_pins[I2C_BSC0] = board_cfg & SHARED_HW_CFG_E3_I2C_MUX0_MASK;
32213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i2c_pins[I2C_BSC1] = (board_cfg & SHARED_HW_CFG_E3_I2C_MUX1_MASK) >>
32223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			SHARED_HW_CFG_E3_I2C_MUX1_SHIFT;
32233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Read I2C output value */
32253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	sfp_ctrl = REG_RD(bp, params->shmem_base +
32263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  offsetof(struct shmem_region,
32273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 dev_info.port_hw_config[port].e3_cmn_pin_cfg));
32283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i2c_val[I2C_BSC0] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX0_MASK) > 0;
32293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i2c_val[I2C_BSC1] = (sfp_ctrl & PORT_HW_CFG_E3_I2C_MUX1_MASK) > 0;
32303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting BSC switch\n");
32313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	for (idx = 0; idx < I2C_SWITCH_WIDTH; idx++)
32323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_cfg_pin(bp, i2c_pins[idx], i2c_val[idx]);
32333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
32343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_bsc_read(struct link_params *params,
32363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  struct bnx2x_phy *phy,
32373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  u8 sl_devid,
32383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  u16 sl_addr,
32393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  u8 lc_addr,
32403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  u8 xfer_cnt,
32413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  u32 *data_array)
32423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
32433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 val, i;
32443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	int rc = 0;
32453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
32463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if ((sl_devid != 0xa0) && (sl_devid != 0xa2)) {
32483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "invalid sl_devid 0x%x\n", sl_devid);
32493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return -EINVAL;
32503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
32513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (xfer_cnt > 16) {
32533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "invalid xfer_cnt %d. Max is 16 bytes\n",
32543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					xfer_cnt);
32553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return -EINVAL;
32563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
32573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_bsc_module_sel(params);
32583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	xfer_cnt = 16 - lc_addr;
32603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* enable the engine */
32623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
32633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val |= MCPR_IMC_COMMAND_ENABLE;
32643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
32653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* program slave device ID */
32673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = (sl_devid << 16) | sl_addr;
32683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_IMC_SLAVE_CONTROL, val);
32693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* start xfer with 0 byte to update the address pointer ???*/
32713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = (MCPR_IMC_COMMAND_ENABLE) |
32723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	      (MCPR_IMC_COMMAND_WRITE_OP <<
32733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
32743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) | (0);
32753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
32763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* poll for completion */
32783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i = 0;
32793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
32803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
32813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		udelay(10);
32823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
32833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (i++ > 1000) {
32843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "wr 0 byte timed out after %d try\n",
32853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner								i);
32863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			rc = -EFAULT;
32873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
32883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
32893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
32903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (rc == -EFAULT)
32913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return rc;
32923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
32933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* start xfer with read op */
32943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = (MCPR_IMC_COMMAND_ENABLE) |
32953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		(MCPR_IMC_COMMAND_READ_OP <<
32963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		MCPR_IMC_COMMAND_OPERATION_BITSHIFT) |
32973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		(lc_addr << MCPR_IMC_COMMAND_TRANSFER_ADDRESS_BITSHIFT) |
32983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		  (xfer_cnt);
32993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	REG_WR(bp, MCP_REG_MCPR_IMC_COMMAND, val);
33003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* poll for completion */
33023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	i = 0;
33033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
33043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	while (((val >> MCPR_IMC_COMMAND_IMC_STATUS_BITSHIFT) & 0x3) != 1) {
33053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		udelay(10);
33063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val = REG_RD(bp, MCP_REG_MCPR_IMC_COMMAND);
33073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (i++ > 1000) {
33083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "rd op timed out after %d try\n", i);
33093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			rc = -EFAULT;
33103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
33113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
33123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
33133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (rc == -EFAULT)
33143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return rc;
33153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	for (i = (lc_addr >> 2); i < 4; i++) {
33173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		data_array[i] = REG_RD(bp, (MCP_REG_MCPR_IMC_DATAREG0 + i*4));
33183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#ifdef __BIG_ENDIAN
33193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		data_array[i] = ((data_array[i] & 0x000000ff) << 24) |
33203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				((data_array[i] & 0x0000ff00) << 8) |
33213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				((data_array[i] & 0x00ff0000) >> 8) |
33223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				((data_array[i] & 0xff000000) >> 24);
33233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner#endif
33243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
3325ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return rc;
3326ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
3327ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
33283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_cl45_read_or_write(struct bnx2x *bp, struct bnx2x_phy *phy,
33293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				     u8 devad, u16 reg, u16 or_val)
33303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
33313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val;
33323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, devad, reg, &val);
33333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, devad, reg, val | or_val);
33343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
33353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
3336fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_phy_read(struct link_params *params, u8 phy_addr,
3337fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner		   u8 devad, u16 reg, u16 *ret_val)
3338e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner{
3339e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	u8 phy_index;
33402cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
3341e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 * Probe for the phy according to the given phy_addr, and execute
3342e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 * the read request on it
3343e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 */
3344e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3345e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		if (params->phy[phy_index].addr == phy_addr) {
3346e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			return bnx2x_cl45_read(params->bp,
3347e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner					       &params->phy[phy_index], devad,
3348e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner					       reg, ret_val);
3349e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		}
3350e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	}
3351e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	return -EINVAL;
3352e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner}
3353e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
3354fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_phy_write(struct link_params *params, u8 phy_addr,
3355fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner		    u8 devad, u16 reg, u16 val)
3356e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner{
3357e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	u8 phy_index;
33582cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
3359e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 * Probe for the phy according to the given phy_addr, and execute
3360e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 * the write request on it
3361e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	 */
3362e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	for (phy_index = 0; phy_index < params->num_phys; phy_index++) {
3363e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		if (params->phy[phy_index].addr == phy_addr) {
3364e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			return bnx2x_cl45_write(params->bp,
3365e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner						&params->phy[phy_index], devad,
3366e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner						reg, val);
3367e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		}
3368e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	}
3369e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	return -EINVAL;
3370e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner}
33713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic u8 bnx2x_get_warpcore_lane(struct bnx2x_phy *phy,
33723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  struct link_params *params)
33733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
33743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 lane = 0;
33753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
33763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 path_swap, path_swap_ovr;
33773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 path, port;
33783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	path = BP_PATH(bp);
33803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	port = params->port;
33813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (bnx2x_is_4_port_mode(bp)) {
33833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u32 port_swap, port_swap_ovr;
33843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*figure out path swap value */
33863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		path_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP_OVWR);
33873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (path_swap_ovr & 0x1)
33883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path_swap = (path_swap_ovr & 0x2);
33893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else
33903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PATH_SWAP);
33913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (path_swap)
33933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path = path ^ 1;
33943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
33953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*figure out port swap value */
33963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		port_swap_ovr = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP_OVWR);
33973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (port_swap_ovr & 0x1)
33983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_swap = (port_swap_ovr & 0x2);
33993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else
34003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_swap = REG_RD(bp, MISC_REG_FOUR_PORT_PORT_SWAP);
34013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
34023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (port_swap)
34033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port = port ^ 1;
34043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
34053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		lane = (port<<1) + path;
34063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else { /* two port mode - no port swap */
34073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
34083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*figure out path swap value */
34093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		path_swap_ovr =
34103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP_OVWR);
34113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (path_swap_ovr & 0x1) {
34123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path_swap = (path_swap_ovr & 0x2);
34133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		} else {
34143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path_swap =
34153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				REG_RD(bp, MISC_REG_TWO_PORT_PATH_SWAP);
34163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
34173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (path_swap)
34183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			path = path ^ 1;
34193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
34203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		lane = path << 1 ;
34213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
34223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return lane;
34233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
3424e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
3425ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosnerstatic void bnx2x_set_aer_mmd(struct link_params *params,
3426ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner			      struct bnx2x_phy *phy)
3427ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
3428ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u32 ser_lane;
3429f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	u16 offset, aer_val;
3430f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	struct bnx2x *bp = params->bp;
3431ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	ser_lane = ((params->lane_config &
3432ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3433ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3434ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3435ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	offset = (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ?
3436ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner		(phy->addr + ser_lane) : 0;
3437ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner
34383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (USES_WARPCORE(bp)) {
34393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		aer_val = bnx2x_get_warpcore_lane(phy, params);
34403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*
34413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * In Dual-lane mode, two lanes are joined together,
34423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * so in order to configure them, the AER broadcast method is
34433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * used here.
34443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * 0x200 is the broadcast address for lanes 0,1
34453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * 0x201 is the broadcast address for lanes 2,3
34463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 */
34473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (phy->flags & FLAGS_WC_DUAL_MODE)
34483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			aer_val = (aer_val >> 1) | 0x200;
34493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else if (CHIP_IS_E2(bp))
345082a0d4757c03687894123b197ec9c40f7dd16800Yaniv Rosner		aer_val = 0x3800 + offset - 1;
3451f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
3452f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		aer_val = 0x3800 + offset;
34532f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
3454cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
3455cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_AER_BLOCK_AER_REG, aer_val);
3456ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner
3457ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
3458ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3459de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
3460de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			Internal phy section			  */
3461de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
3462ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3463de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_set_serdes_access(struct bnx2x *bp, u8 port)
3464de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
3465de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3466ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3467de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set Clause 22 */
3468de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 1);
3469de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245f8000);
3470de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	udelay(500);
3471de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, emac_base + EMAC_REG_EMAC_MDIO_COMM, 0x245d000f);
3472de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	udelay(500);
3473de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 /* Set Clause 45 */
3474de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_ST + port*0x10, 0);
3475ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
3476ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3477de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_serdes_deassert(struct bnx2x *bp, u8 port)
3478ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
3479de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 val;
3480ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3481de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "bnx2x_serdes_deassert\n");
3482ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3483de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val = SERDES_RESET_BITS << (port*16);
3484c1b7399027254a45a4036c548c13eb97c7d0d8faEilon Greenstein
3485de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* reset and unreset the SerDes/XGXS */
3486de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3487de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	udelay(500);
3488de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3489ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3490de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_serdes_access(bp, port);
3491ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
3492cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR(bp, NIG_REG_SERDES0_CTRL_MD_DEVAD + port*0x10,
3493cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       DEFAULT_PHY_DEV_ADDR);
3494de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
3495de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
3496de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_xgxs_deassert(struct link_params *params)
3497de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
3498de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
3499de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port;
3500de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 val;
3501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "bnx2x_xgxs_deassert\n");
3502de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	port = params->port;
3503de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
3504de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val = XGXS_RESET_BITS << (port*16);
3505de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
3506de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* reset and unreset the SerDes/XGXS */
3507de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR, val);
3508de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	udelay(500);
3509de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET, val);
3510de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
3511cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST + port*0x18, 0);
3512de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3513cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       params->phy[INT_PHY].def_md_devad);
3514de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
3515de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
35169045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void bnx2x_calc_ieee_aneg_adv(struct bnx2x_phy *phy,
35179045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner				     struct link_params *params, u16 *ieee_fc)
35189045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
35199045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
35209045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
35219045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	/**
35229045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	 * resolve pause mode and advertisement Please refer to Table
35239045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	 * 28B-3 of the 802.3ab-1999 spec
35249045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	 */
35259045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35269045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	switch (phy->req_flow_ctrl) {
35279045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case BNX2X_FLOW_CTRL_AUTO:
35289045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH)
35299045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
35309045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		else
35319045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			*ieee_fc |=
35329045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
35339045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
35349045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35359045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case BNX2X_FLOW_CTRL_TX:
35369045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
35379045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
35389045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35399045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case BNX2X_FLOW_CTRL_RX:
35409045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case BNX2X_FLOW_CTRL_BOTH:
35419045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
35429045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
35439045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35449045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case BNX2X_FLOW_CTRL_NONE:
35459045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	default:
35469045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
35479045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
35489045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
35499045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "ieee_fc = 0x%x\n", *ieee_fc);
35509045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
35519045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35529045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void set_phy_vars(struct link_params *params,
35539045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			 struct link_vars *vars)
35549045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
35559045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
35569045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u8 actual_phy_idx, phy_index, link_cfg_idx;
35579045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u8 phy_config_swapped = params->multi_phy_config &
35589045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			PORT_HW_CFG_PHY_SWAPPED_ENABLED;
35599045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	for (phy_index = INT_PHY; phy_index < params->num_phys;
35609045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	      phy_index++) {
35619045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		link_cfg_idx = LINK_CONFIG_IDX(phy_index);
35629045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		actual_phy_idx = phy_index;
35639045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		if (phy_config_swapped) {
35649045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			if (phy_index == EXT_PHY1)
35659045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner				actual_phy_idx = EXT_PHY2;
35669045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			else if (phy_index == EXT_PHY2)
35679045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner				actual_phy_idx = EXT_PHY1;
35689045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		}
35699045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		params->phy[actual_phy_idx].req_flow_ctrl =
35709045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			params->req_flow_ctrl[link_cfg_idx];
35719045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35729045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		params->phy[actual_phy_idx].req_line_speed =
35739045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			params->req_line_speed[link_cfg_idx];
35749045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35759045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		params->phy[actual_phy_idx].speed_cap_mask =
35769045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			params->speed_cap_mask[link_cfg_idx];
3577a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
35789045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		params->phy[actual_phy_idx].req_duplex =
35799045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			params->req_duplex[link_cfg_idx];
35809045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35819045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		if (params->req_line_speed[link_cfg_idx] ==
35829045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		    SPEED_AUTO_NEG)
35839045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
35849045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35859045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		DP(NETIF_MSG_LINK, "req_flow_ctrl %x, req_line_speed %x,"
35869045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			   " speed_cap_mask %x\n",
35879045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			   params->phy[actual_phy_idx].req_flow_ctrl,
35889045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			   params->phy[actual_phy_idx].req_line_speed,
35899045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			   params->phy[actual_phy_idx].speed_cap_mask);
35909045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
35919045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
35929045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
35939045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void bnx2x_ext_phy_set_pause(struct link_params *params,
35949045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner				    struct bnx2x_phy *phy,
35959045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner				    struct link_vars *vars)
35969045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
35979045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u16 val;
35989045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
35999045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	/* read modify write pause advertizing */
36009045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, &val);
36019045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36029045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
36039045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36049045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
36059045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
36069045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if ((vars->ieee_fc &
36079045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
36089045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
36099045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
36109045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
36119045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if ((vars->ieee_fc &
36129045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
36139045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
36149045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
36159045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
36169045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "Ext phy AN advertize 0x%x\n", val);
36179045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV_PAUSE, val);
36189045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
36199045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36209045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
36219045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{						/*  LD	    LP	 */
36229045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	switch (pause_result) {			/* ASYM P ASYM P */
36239045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0xb:				/*   1  0   1  1 */
36249045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
36259045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
36269045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36279045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0xe:				/*   1  1   1  0 */
36289045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
36299045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
36309045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36319045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0x5:				/*   0  1   0  1 */
36329045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0x7:				/*   0  1   1  1 */
36339045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0xd:				/*   1  1   0  1 */
36349045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case 0xf:				/*   1  1   1  1 */
36359045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
36369045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
36379045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36389045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	default:
36399045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
36409045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
36419045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if (pause_result & (1<<0))
36429045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->link_status |= LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE;
36439045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if (pause_result & (1<<1))
36449045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->link_status |= LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE;
36459045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
36469045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
36479e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuvalstatic void bnx2x_ext_phy_update_adv_fc(struct bnx2x_phy *phy,
36489e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval					struct link_params *params,
36499e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval					struct link_vars *vars)
36509045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
36519045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u16 ld_pause;		/* local */
36529045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u16 lp_pause;		/* link partner */
36539045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u16 pause_result;
36549e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	struct bnx2x *bp = params->bp;
36559e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) {
36569e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl22_read(bp, phy, 0x4, &ld_pause);
36579e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl22_read(bp, phy, 0x5, &lp_pause);
3658ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner	} else if (CHIP_IS_E3(bp) &&
3659ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		SINGLE_MEDIA_DIRECT(params)) {
3660ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		u8 lane = bnx2x_get_warpcore_lane(phy, params);
3661ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		u16 gp_status, gp_mask;
3662ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		bnx2x_cl45_read(bp, phy,
3663ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				MDIO_AN_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_4,
3664ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				&gp_status);
3665ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		gp_mask = (MDIO_WC_REG_GP2_STATUS_GP_2_4_CL73_AN_CMPL |
3666ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			   MDIO_WC_REG_GP2_STATUS_GP_2_4_CL37_LP_AN_CAP) <<
3667ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			lane;
3668ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		if ((gp_status & gp_mask) == gp_mask) {
3669ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3670ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner					MDIO_AN_REG_ADV_PAUSE, &ld_pause);
3671ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3672ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner					MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
3673ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		} else {
3674ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3675ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner					MDIO_AN_REG_CL37_FC_LD, &ld_pause);
3676ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
3677ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner					MDIO_AN_REG_CL37_FC_LP, &lp_pause);
3678ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			ld_pause = ((ld_pause &
3679ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3680ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				    << 3);
3681ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner			lp_pause = ((lp_pause &
3682ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
3683ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner				    << 3);
3684ca05f29cf515ac4a8e162c8e0eee886727f5dcc7Yaniv Rosner		}
36859e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	} else {
36869e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy,
36879e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_DEVAD,
36889e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_ADV_PAUSE, &ld_pause);
36899e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy,
36909e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_DEVAD,
36919e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
36929e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	}
36939e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	pause_result = (ld_pause &
36949e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
36959e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	pause_result |= (lp_pause &
36969e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
36979e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x\n", pause_result);
36989e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	bnx2x_pause_resolve(vars, pause_result);
36999045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
37009e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval}
37019e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuvalstatic u8 bnx2x_ext_phy_resolve_fc(struct bnx2x_phy *phy,
37029e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				   struct link_params *params,
37039e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				   struct link_vars *vars)
37049e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval{
37059e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	u8 ret = 0;
37069045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
37079e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
37089e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* Update the advertised flow-controled of LD/LP in AN */
37099e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (phy->req_line_speed == SPEED_AUTO_NEG)
37109e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			bnx2x_ext_phy_update_adv_fc(phy, params, vars);
37119e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* But set the flow-control result as the requested one */
37129045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->flow_ctrl = phy->req_flow_ctrl;
37139e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	} else if (phy->req_line_speed != SPEED_AUTO_NEG)
37149045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		vars->flow_ctrl = params->req_fc_auto_adv;
37159045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	else if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
37169045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		ret = 1;
37179e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_ext_phy_update_adv_fc(phy, params, vars);
37189045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
37199045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	return ret;
37209045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
37213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
37223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/*			Warpcore section			  */
37233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/******************************************************************/
37243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner/* The init_internal_warpcore should mirror the xgxs,
37253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner * i.e. reset the lane (if needed), set aer for the
37263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner * init configuration, and set/clear SGMII flag. Internal
37273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner * phy init is done purely in phy_init stage.
37283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner */
37293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_enable_AN_KR(struct bnx2x_phy *phy,
37303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					struct link_params *params,
37313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					struct link_vars *vars) {
3732a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner	u16 val16 = 0, lane, bam37 = 0;
37333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
37343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Enable Auto Negotiation for KR\n");
37356a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	/* Set to default registers that may be overriden by 10G force */
37366a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37376a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
37386a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
37396a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
37406a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37416a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0);
37426a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37436a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0xff);
37446a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37456a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0x5555);
37466a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
37476a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0x0);
37486a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37496a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_RX66_CONTROL, 0x7415);
37506a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37516a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x6190);
3752a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	/* Disable Autoneg: re-enable it after adv is done. */
3753a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
3754a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0);
3755a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
37563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Check adding advertisement for 1G KX */
37573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (((vars->line_speed == SPEED_AUTO_NEG) &&
37583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
37593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	    (vars->line_speed == SPEED_1000)) {
37603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u16 sd_digital;
37613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val16 |= (1<<5);
37623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
37633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Enable CL37 1G Parallel Detect */
37643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
37653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &sd_digital);
37663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
37683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 (sd_digital | 0x1));
37693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
37703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Advertize 1G\n");
37713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
37723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (((vars->line_speed == SPEED_AUTO_NEG) &&
37733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	     (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
37743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	    (vars->line_speed ==  SPEED_10000)) {
37753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Check adding advertisement for 10G KR */
37763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val16 |= (1<<7);
37773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Enable 10G Parallel Detect */
37783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
37793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_PAR_DET_10G_CTRL, 1);
37803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
37813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Advertize 10G\n");
37823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
37833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
37843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set Transmit PMD settings */
37853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	lane = bnx2x_get_warpcore_lane(phy, params);
37863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
37883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		     ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
37893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
37903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      (0x09 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
37913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_OS_DEF_CTRL,
37933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 0x03f0);
37943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
37953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_2P5_DEF_CTRL,
37963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 0x03f0);
37973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
37983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Advertised speeds */
37993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, val16);
38013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38026b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner	/* Advertised and set FEC (Forward Error Correction) */
38036b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38046b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT2,
38056b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner			 (MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_ABILITY |
38066b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner			  MDIO_WC_REG_AN_IEEE1BLK_AN_ADV2_FEC_REQ));
38076b1f3900fc0909fbf3bd672242378015f76b3df8Yaniv Rosner
3808a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner	/* Enable CL37 BAM */
3809a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner	if (REG_RD(bp, params->shmem_base +
3810a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner		   offsetof(struct shmem_region, dev_info.
3811a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner			    port_hw_config[params->port].default_cfg)) &
3812a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
3813a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
3814a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner				MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, &bam37);
3815a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3816a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner			MDIO_WC_REG_DIGITAL6_MP5_NEXTPAGECTRL, bam37 | 1);
3817a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner		DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
3818a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner	}
3819a34bc969a19b3a2364c03c101abb3b4d467089c0Yaniv Rosner
38203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Advertise pause */
38213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_ext_phy_set_pause(params, phy, vars);
38223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38236ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	/*
38246ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	 * Set KR Autoneg Work-Around flag for Warpcore version older than D108
38256ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	 */
38266ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
38276ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner			MDIO_WC_REG_UC_INFO_B1_VERSION, &val16);
38286ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	if (val16 < 0xd108) {
38296ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner		DP(NETIF_MSG_LINK, "Enable AN KR work-around\n");
38306ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner		vars->rx_tx_asic_rst = MAX_KR_LINK_RETRY;
38316ab48a5c86ce778188c173818cb2f1644526e962Yaniv Rosner	}
38323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
38343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DIGITAL5_MISC7, &val16);
38353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL5_MISC7, val16 | 0x100);
3838a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
3839a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	/* Over 1G - AN local device user page 1 */
3840a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
3841a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			MDIO_WC_REG_DIGITAL3_UP1, 0x1f);
3842a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
3843a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	/* Enable Autoneg */
3844a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38451b85ae52733b859e280035330e016731d4a62307Mintz Yuval			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
3846a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
38473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
38483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_10G_KR(struct bnx2x_phy *phy,
38503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_params *params,
38513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_vars *vars)
38523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
38533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
38543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val;
38553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Disable Autoneg */
38573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x7);
38593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_PAR_DET_10G_CTRL, 0);
38623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL, 0x3f00);
38653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_AN_IEEE1BLK_AN_ADVERTISEMENT1, 0);
38683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
38703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
38713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DIGITAL3_UP1, 0x1);
38743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL5_MISC7, 0xa);
38773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Disable CL36 PCS Tx */
38793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_XGXSBLK1_LANECTRL0, 0x0);
38813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Double Wide Single Data Rate @ pll rate */
38833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_XGXSBLK1_LANECTRL1, 0xFFFF);
38853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Leave cl72 training enable, needed for KR */
38873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
38883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		MDIO_WC_REG_PMD_IEEE9BLK_TENGBASE_KR_PMD_CONTROL_REGISTER_150,
38893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		0x2);
38903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Leave CL72 enabled */
38923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
38933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
38943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 &val);
38953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
38963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_CL72_USERB0_CL72_MISC1_CONTROL,
38973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 val | 0x3800);
38983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
38993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set speed via PMA/PMD register */
39003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
39013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
39023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD,
39043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_AUTONEGNP, 0xB);
39053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/*Enable encoded forced speed */
39073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_MISC2, 0x30);
39093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Turn TX scramble payload only the 64/66 scrambler */
39113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX66_CONTROL, 0x9);
39133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Turn RX scramble payload only the 64/66 scrambler */
39153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read_or_write(bp, phy, MDIO_WC_DEVAD,
39163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 MDIO_WC_REG_RX66_CONTROL, 0xF9);
39173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* set and clear loopback to cause a reset to 64/66 decoder */
39193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x4000);
39213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x0);
39233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
39253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_10G_XFI(struct bnx2x_phy *phy,
39273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       struct link_params *params,
39283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       u8 is_xfi)
39293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
39303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
39313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 misc1_val, tap_val, tx_driver_val, lane, val;
39323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Hold rxSeqStart */
39333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
39353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val | 0x8000));
39373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Hold tx_fifo_reset */
39393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
39413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, (val | 0x1));
39433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Disable CL73 AN */
39453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
39463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Disable 100FX Enable and Auto-Detect */
39483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_FX100_CTRL1, &val);
39503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_FX100_CTRL1, (val & 0xFFFA));
39523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Disable 100FX Idle detect */
39543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_FX100_CTRL3, &val);
39563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_FX100_CTRL3, (val | 0x0080));
39583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set Block address to Remote PHY & Clear forced_speed[5] */
39603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DIGITAL4_MISC3, &val);
39623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL4_MISC3, (val & 0xFF7F));
39643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Turn off auto-detect & fiber mode */
39663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
39683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
39703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 (val & 0xFFEE));
39713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set filter_force_link, disable_false_link and parallel_detect */
39733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &val);
39753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
39763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
39773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 ((val | 0x0006) & 0xFFFE));
39783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set XFI / SFI */
39803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
39813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_MISC1, &misc1_val);
39823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	misc1_val &= ~(0x1f);
39843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (is_xfi) {
39863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		misc1_val |= 0x5;
39873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		tap_val = ((0x08 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
39883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			   (0x37 << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
39893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			   (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
39903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		tx_driver_val =
39913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      ((0x00 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
39923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
39933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       (0x03 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
39943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
39953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
39963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		misc1_val |= 0x9;
399725182fc22237f0fb1789c7ac9a79e871a1898ae5Yaniv Rosner		tap_val = ((0x0f << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
399825182fc22237f0fb1789c7ac9a79e871a1898ae5Yaniv Rosner			   (0x2b << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
399925182fc22237f0fb1789c7ac9a79e871a1898ae5Yaniv Rosner			   (0x02 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET));
40003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		tx_driver_val =
400125182fc22237f0fb1789c7ac9a79e871a1898ae5Yaniv Rosner		      ((0x03 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
40023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
400325182fc22237f0fb1789c7ac9a79e871a1898ae5Yaniv Rosner		       (0x06 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET));
40043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
40053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_MISC1, misc1_val);
40073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set Transmit PMD settings */
40093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	lane = bnx2x_get_warpcore_lane(phy, params);
40103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX_FIR_TAP,
40123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 tap_val | MDIO_WC_REG_TX_FIR_TAP_ENABLE);
40133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
40153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 tx_driver_val);
40163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Enable fiber mode, enable and invert sig_det */
40183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
40193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &val);
40203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, val | 0xd);
40223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set Block address to Remote PHY & Set forced_speed[5], 40bit mode */
40243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
40253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DIGITAL4_MISC3, &val);
40263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL4_MISC3, val | 0x8080);
40283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* 10G XFI Full Duplex */
40303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x100);
40323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Release tx_fifo_reset */
40343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
40353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, &val);
40363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, val & 0xFFFE);
40383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Release rxSeqStart */
40403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
40413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, &val);
40423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DSC2B0_DSC_MISC_CTRL0, (val & 0x7FFF));
40443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
40453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_20G_KR2(struct bnx2x *bp,
40473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       struct bnx2x_phy *phy)
40483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
40493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "KR2 still not supported !!!\n");
40503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
40513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_20G_DXGXS(struct bnx2x *bp,
40533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 struct bnx2x_phy *phy,
40543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 u16 lane)
40553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
40563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Rx0 anaRxControl1G */
40573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX0_ANARXCONTROL1G, 0x90);
40593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Rx2 anaRxControl1G */
40613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX2_ANARXCONTROL1G, 0x90);
40633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW0, 0xE070);
40663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW1, 0xC0D0);
40693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW2, 0xA0B0);
40723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW3, 0x8090);
40753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW0_MASK, 0xF0F0);
40783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW1_MASK, 0xF0F0);
40813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW2_MASK, 0xF0F0);
40843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_SCW3_MASK, 0xF0F0);
40873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Serdes Digital Misc1 */
40893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6008);
40913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Serdes Digital4 Misc3 */
40933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8088);
40953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
40963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set Transmit PMD settings */
40973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
40983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX_FIR_TAP,
40993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			((0x12 << MDIO_WC_REG_TX_FIR_TAP_POST_TAP_OFFSET) |
41003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 (0x2d << MDIO_WC_REG_TX_FIR_TAP_MAIN_TAP_OFFSET) |
41013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 (0x00 << MDIO_WC_REG_TX_FIR_TAP_PRE_TAP_OFFSET) |
41023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX_FIR_TAP_ENABLE));
41033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane,
41053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		     ((0x02 << MDIO_WC_REG_TX0_TX_DRIVER_POST2_COEFF_OFFSET) |
41063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IDRIVER_OFFSET) |
41073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		      (0x02 << MDIO_WC_REG_TX0_TX_DRIVER_IPRE_DRIVER_OFFSET)));
41083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
41093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_sgmii_speed(struct bnx2x_phy *phy,
41113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   struct link_params *params,
4112521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					   u8 fiber_mode,
4113521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					   u8 always_autoneg)
41143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
41153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
41163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val16, digctrl_kx1, digctrl_kx2;
41173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Clear XFI clock comp in non-10G single lane mode. */
41193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_RX66_CONTROL, &val16);
41213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_CONTROL, val16 & ~(3<<13));
41233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
4124521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if (always_autoneg || phy->req_line_speed == SPEED_AUTO_NEG) {
41253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* SGMII Autoneg */
41263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
41283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 MDIO_WC_REG_COMBO_IEEE0_MIICTRL,
41303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 val16 | 0x1000);
41313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "set SGMII AUTONEG\n");
41323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
41333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
4135521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		val16 &= 0xcebf;
41363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		switch (phy->req_line_speed) {
41373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case SPEED_10:
41383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
41393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case SPEED_100:
41403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			val16 |= 0x2000;
41413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
41423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case SPEED_1000:
41433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			val16 |= 0x0040;
41443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
41453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		default:
414694f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
414794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Speed not supported: 0x%x\n", phy->req_line_speed);
41483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return;
41493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
41503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
41523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			val16 |= 0x0100;
41533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16);
41563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "set SGMII force speed %d\n",
41583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       phy->req_line_speed);
41593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
41613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "  (readback) %x\n", val16);
41623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
41633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* SGMII Slave mode and disable signal detect */
41653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, &digctrl_kx1);
41673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (fiber_mode)
41683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		digctrl_kx1 = 1;
41693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
41703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		digctrl_kx1 &= 0xff4a;
41713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
41743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			digctrl_kx1);
41753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Turn off parallel detect */
41773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
41783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, &digctrl_kx2);
41793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
41813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			(digctrl_kx2 & ~(1<<2)));
41823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Re-enable parallel detect */
41843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2,
41863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			(digctrl_kx2 | (1<<2)));
41873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Enable autodet */
41893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
41903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1,
41913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			(digctrl_kx1 | 0x10));
41923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
41933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
41943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_reset_lane(struct bnx2x *bp,
41953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct bnx2x_phy *phy,
41963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u8 reset)
41973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
41983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val;
41993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Take lane out of reset after configuration is finished */
42003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
42013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_DIGITAL5_MISC6, &val);
42023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (reset)
42033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val |= 0xC000;
42043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
42053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val &= 0x3FFF;
42063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL5_MISC6, val);
42083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
42093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL5_MISC6, &val);
42103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
42112f751a805e35dcf687473c27282a6602577df541Yaniv Rosner/* Clear SFI/XFI link settings registers */
42123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_clear_regs(struct bnx2x_phy *phy,
42133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_params *params,
42143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u16 lane)
42153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
42163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
42173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val16;
42183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set XFI clock comp as default. */
42203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
42213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_RX66_CONTROL, &val16);
42223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_RX66_CONTROL, val16 | (3<<13));
42243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 1);
42263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0);
42273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_FX100_CTRL1, 0x014a);
42293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_FX100_CTRL3, 0x0800);
42313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_DIGITAL4_MISC3, 0x8008);
42333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X1, 0x0195);
42353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X2, 0x0007);
42373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_CONTROL1000X3, 0x0002);
42393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_SERDESDIGITAL_MISC1, 0x6000);
42413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	lane = bnx2x_get_warpcore_lane(phy, params);
42423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX_FIR_TAP, 0x0000);
42443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_TX0_TX_DRIVER + 0x10*lane, 0x0990);
42463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x2040);
42483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
42493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, 0x0140);
42503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 0);
42513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
42523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_get_mod_abs_int_cfg(struct bnx2x *bp,
42543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						u32 chip_id,
42553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						u32 shmem_base, u8 port,
42563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						u8 *gpio_num, u8 *gpio_port)
42573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
42583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 cfg_pin;
42593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	*gpio_num = 0;
42603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	*gpio_port = 0;
42613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
42623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		cfg_pin = (REG_RD(bp, shmem_base +
42633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				offsetof(struct shmem_region,
42643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
42653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				PORT_HW_CFG_E3_MOD_ABS_MASK) >>
42663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				PORT_HW_CFG_E3_MOD_ABS_SHIFT;
42673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*
42693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * Should not happen. This function called upon interrupt
42703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * triggered by GPIO ( since EPIO can only generate interrupts
42713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * to MCP).
42723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * So if this function was called and none of the GPIOs was set,
42733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * it means the shit hit the fan.
42743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 */
42753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if ((cfg_pin < PIN_CFG_GPIO0_P0) ||
42763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    (cfg_pin > PIN_CFG_GPIO3_P1)) {
427794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
427894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "ERROR: Invalid cfg pin %x for module detect indication\n",
427994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   cfg_pin);
42803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return -EINVAL;
42813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
42823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		*gpio_num = (cfg_pin - PIN_CFG_GPIO0_P0) & 0x3;
42843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		*gpio_port = (cfg_pin - PIN_CFG_GPIO0_P0) >> 2;
42853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
42863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		*gpio_num = MISC_REGISTERS_GPIO_3;
42873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		*gpio_port = port;
42883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
42893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "MOD_ABS int GPIO%d_P%d\n", *gpio_num, *gpio_port);
42903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return 0;
42913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
42923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
42933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_is_sfp_module_plugged(struct bnx2x_phy *phy,
42943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       struct link_params *params)
42953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
42963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
42973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 gpio_num, gpio_port;
42983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 gpio_val;
42993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id,
43003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      params->shmem_base, params->port,
43013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      &gpio_num, &gpio_port) != 0)
43023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return 0;
43033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
43043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
43053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Call the handling function in case module is detected */
43063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (gpio_val == 0)
43073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return 1;
43083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
43093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return 0;
43103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
4311a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosnerstatic int bnx2x_warpcore_get_sigdet(struct bnx2x_phy *phy,
4312a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					struct link_params *params)
4313a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner{
4314a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	u16 gp2_status_reg0, lane;
4315a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	struct bnx2x *bp = params->bp;
4316a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4317a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	lane = bnx2x_get_warpcore_lane(phy, params);
4318a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4319a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, MDIO_WC_REG_GP2_STATUS_GP_2_0,
4320a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				 &gp2_status_reg0);
4321a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4322a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	return (gp2_status_reg0 >> (8+lane)) & 0x1;
4323a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner}
4324a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4325a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosnerstatic void bnx2x_warpcore_config_runtime(struct bnx2x_phy *phy,
4326a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				       struct link_params *params,
4327a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				       struct link_vars *vars)
4328a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner{
4329a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	struct bnx2x *bp = params->bp;
4330a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	u32 serdes_net_if;
4331a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	u16 gp_status1 = 0, lnkup = 0, lnkup_kr = 0;
4332a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	u16 lane = bnx2x_get_warpcore_lane(phy, params);
4333a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4334a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	vars->turn_to_run_wc_rt = vars->turn_to_run_wc_rt ? 0 : 1;
4335a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4336a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	if (!vars->turn_to_run_wc_rt)
4337a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		return;
4338a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4339a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	/* return if there is no link partner */
4340a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	if (!(bnx2x_warpcore_get_sigdet(phy, params))) {
4341a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_warpcore_get_sigdet false\n");
4342a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		return;
4343a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	}
4344a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4345a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	if (vars->rx_tx_asic_rst) {
4346a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		serdes_net_if = (REG_RD(bp, params->shmem_base +
4347a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				offsetof(struct shmem_region, dev_info.
4348a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				port_hw_config[params->port].default_cfg)) &
4349a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				PORT_HW_CFG_NET_SERDES_IF_MASK);
4350a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4351a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		switch (serdes_net_if) {
4352a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_KR:
4353a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			/* Do we get link yet? */
4354a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD, 0x81d1,
4355a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner								&gp_status1);
4356a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			lnkup = (gp_status1 >> (8+lane)) & 0x1;/* 1G */
4357a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				/*10G KR*/
4358a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			lnkup_kr = (gp_status1 >> (12+lane)) & 0x1;
4359a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4360a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			DP(NETIF_MSG_LINK,
4361a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				"gp_status1 0x%x\n", gp_status1);
4362a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4363a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			if (lnkup_kr || lnkup) {
4364a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					vars->rx_tx_asic_rst = 0;
4365a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					DP(NETIF_MSG_LINK,
4366a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					"link up, rx_tx_asic_rst 0x%x\n",
4367a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					vars->rx_tx_asic_rst);
4368a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			} else {
4369a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				/*reset the lane to see if link comes up.*/
4370a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				bnx2x_warpcore_reset_lane(bp, phy, 1);
4371a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				bnx2x_warpcore_reset_lane(bp, phy, 0);
4372a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4373a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				/* restart Autoneg */
4374a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
4375a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner					MDIO_WC_REG_IEEE0BLK_MIICNTL, 0x1200);
4376a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4377a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				vars->rx_tx_asic_rst--;
4378a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				DP(NETIF_MSG_LINK, "0x%x retry left\n",
4379a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner				vars->rx_tx_asic_rst);
4380a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			}
4381a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			break;
4382a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4383a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		default:
4384a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner			break;
4385a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		}
4386a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4387a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	} /*params->rx_tx_asic_rst*/
4388a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
4389a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner}
43903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
43913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_config_init(struct bnx2x_phy *phy,
43923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       struct link_params *params,
43933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       struct link_vars *vars)
43943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
43953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
43963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 serdes_net_if;
43973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 fiber_mode;
43983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 lane = bnx2x_get_warpcore_lane(phy, params);
43993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	serdes_net_if = (REG_RD(bp, params->shmem_base +
44003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 offsetof(struct shmem_region, dev_info.
44013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  port_hw_config[params->port].default_cfg)) &
44023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 PORT_HW_CFG_NET_SERDES_IF_MASK);
44033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Begin Warpcore init, link_speed %d, "
44043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			   "serdes_net_if = 0x%x\n",
44053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       vars->line_speed, serdes_net_if);
44063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_aer_mmd(params, phy);
44073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	vars->phy_flags |= PHY_XGXS_FLAG;
44093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if ((serdes_net_if == PORT_HW_CFG_NET_SERDES_IF_SGMII) ||
44103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	    (phy->req_line_speed &&
44113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	     ((phy->req_line_speed == SPEED_100) ||
44123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	      (phy->req_line_speed == SPEED_10)))) {
44133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		vars->phy_flags |= PHY_SGMII_FLAG;
44143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Setting SGMII mode\n");
44153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_warpcore_clear_regs(phy, params, lane);
4416521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		bnx2x_warpcore_set_sgmii_speed(phy, params, 0, 1);
44173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
44183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		switch (serdes_net_if) {
44193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_KR:
44203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Enable KR Auto Neg */
44216a51c0d17b8fb6ae300ba5bc42a020160944e1b2Yaniv Rosner			if (params->loopback_mode != LOOPBACK_EXT)
44223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_warpcore_enable_AN_KR(phy, params, vars);
44233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			else {
44243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Setting KR 10G-Force\n");
44253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_warpcore_set_10G_KR(phy, params, vars);
44263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
44273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
44283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_XFI:
44303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_warpcore_clear_regs(phy, params, lane);
44313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (vars->line_speed == SPEED_10000) {
44323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Setting 10G XFI\n");
44333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_warpcore_set_10G_XFI(phy, params, 1);
44343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			} else {
44353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				if (SINGLE_MEDIA_DIRECT(params)) {
44363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					DP(NETIF_MSG_LINK, "1G Fiber\n");
44373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					fiber_mode = 1;
44383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				} else {
44393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					DP(NETIF_MSG_LINK, "10/100/1G SGMII\n");
44403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					fiber_mode = 0;
44413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				}
44423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_warpcore_set_sgmii_speed(phy,
44433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner								params,
4444521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner								fiber_mode,
4445521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner								0);
44463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
44473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
44493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_SFI:
44513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_warpcore_clear_regs(phy, params, lane);
44533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (vars->line_speed == SPEED_10000) {
44543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Setting 10G SFI\n");
44553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_warpcore_set_10G_XFI(phy, params, 0);
44563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			} else if (vars->line_speed == SPEED_1000) {
44573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Setting 1G Fiber\n");
4458521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				bnx2x_warpcore_set_sgmii_speed(
4459521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						phy, params, 1, 0);
44603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
44613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Issue Module detection */
44623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (bnx2x_is_sfp_module_plugged(phy, params))
44633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_sfp_module_detection(phy, params);
44643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
44653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
44673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (vars->line_speed != SPEED_20000) {
44683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Speed not supported yet\n");
44693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				return;
44703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
44713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "Setting 20G DXGXS\n");
44723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_warpcore_set_20G_DXGXS(bp, phy, lane);
44733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Issue Module detection */
44743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_sfp_module_detection(phy, params);
44763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
44773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_KR2:
44793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (vars->line_speed != SPEED_20000) {
44803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				DP(NETIF_MSG_LINK, "Speed not supported yet\n");
44813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				return;
44823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
44833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "Setting 20G KR2\n");
44843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_warpcore_set_20G_KR2(bp, phy);
44853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
44863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		default:
448894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
448994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Unsupported Serdes Net Interface 0x%x\n",
449094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   serdes_net_if);
44913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return;
44923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
44933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
44943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
44953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Take lane out of reset after configuration is finished */
44963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 0);
44973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Exit config init\n");
44983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
44993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_sfp_e3_set_transmitter(struct link_params *params,
45013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 struct bnx2x_phy *phy,
45023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 u8 tx_en)
45033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
45043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
45053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 cfg_pin;
45063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 port = params->port;
45073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	cfg_pin = REG_RD(bp, params->shmem_base +
45093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				offsetof(struct shmem_region,
45103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				dev_info.port_hw_config[port].e3_sfp_ctrl)) &
45113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				PORT_HW_CFG_TX_LASER_MASK;
45123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Set the !tx_en since this pin is DISABLE_TX_LASER */
45133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting WC TX to %d\n", tx_en);
45143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* For 20G, the expected pin to be used is 3 pins after the current */
45153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_cfg_pin(bp, cfg_pin, tx_en ^ 1);
45173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_20G)
45183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_cfg_pin(bp, cfg_pin + 3, tx_en ^ 1);
45193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
45203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_link_reset(struct bnx2x_phy *phy,
45223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_params *params)
45233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
45243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
45253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val16;
45263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_sfp_e3_set_transmitter(params, phy, 0);
45273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_mdio_clk(bp, params->chip_id, params->port);
45283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_aer_mmd(params, phy);
45293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Global register */
45303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 1);
45313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Clear loopback settings (if any) */
45333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* 10G & 20G */
45343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
45363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 &
45383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 0xBFFF);
45393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
45423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 & 0xfffe);
45443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Update those 1-copy registers */
45463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
45473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  MDIO_AER_BLOCK_AER_REG, 0);
45483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Enable 1G MDIO (1-copy) */
45493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
45513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			&val16);
45523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
45543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 val16 & ~0x10);
45553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
45583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_XGXSBLK1_LANECTRL2,
45603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 val16 & 0xff00);
45613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
45633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_warpcore_loopback(struct bnx2x_phy *phy,
45653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					struct link_params *params)
45663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
45673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
45683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val16;
45693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 lane;
45703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting Warpcore loopback type %x, speed %d\n",
45713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       params->loopback_mode, phy->req_line_speed);
45723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (phy->req_line_speed < SPEED_10000) {
45743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* 10/100/1000 */
45753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Update those 1-copy registers */
45773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		CL22_WR_OVER_CL45(bp, phy, MDIO_REG_BANK_AER_BLOCK,
45783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  MDIO_AER_BLOCK_AER_REG, 0);
45793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Enable 1G MDIO (1-copy) */
45803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
45823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				&val16);
45833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_XGXSBLK0_XGXSCONTROL,
45853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				val16 | 0x10);
45863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Set 1G loopback based on lane (1-copy) */
45873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		lane = bnx2x_get_warpcore_lane(phy, params);
45883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_XGXSBLK1_LANECTRL2, &val16);
45903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
45913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_XGXSBLK1_LANECTRL2,
45923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				val16 | (1<<lane));
45933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
45943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Switch back to 4-copy registers */
45953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_aer_mmd(params, phy);
45963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
45973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* 10G & 20G */
45983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
45993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, &val16);
46003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
46013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_COMBO_IEEE0_MIICTRL, val16 |
46023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 0x4000);
46033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
46043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
46053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_IEEE0BLK_MIICNTL, &val16);
46063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
46073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_IEEE0BLK_MIICNTL, val16 | 0x1);
46083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
46093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
46103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
46113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
46122f751a805e35dcf687473c27282a6602577df541Yaniv Rosnervoid bnx2x_sync_link(struct link_params *params,
46132f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			   struct link_vars *vars)
4614de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
4615de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
46169380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	u8 link_10g_plus;
4617de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4618de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
46192f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
4620de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->link_up) {
4621de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "phy link up\n");
4622de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4623de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->phy_link_up = 1;
4624de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->duplex = DUPLEX_FULL;
4625de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		switch (vars->link_status &
4626cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
4627de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_10THD:
4628de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_HALF;
4629de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				/* fall thru */
4630de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_10TFD:
4631de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_10;
4632de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
4633de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4634de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_100TXHD:
4635de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_HALF;
4636de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				/* fall thru */
4637de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_100T4:
4638de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_100TXFD:
4639de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_100;
4640de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
4641de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4642de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_1000THD:
4643de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_HALF;
4644de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				/* fall thru */
4645de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_1000TFD:
4646de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_1000;
4647de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
4648de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4649de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_2500THD:
4650de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_HALF;
4651de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				/* fall thru */
4652de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_2500TFD:
4653de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_2500;
4654de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
4655de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4656de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			case LINK_10GTFD:
4657de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_10000;
4658de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
46593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			case LINK_20GTFD:
46603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				vars->line_speed = SPEED_20000;
46613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				break;
4662de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			default:
4663de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				break;
4664de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
4665de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = 0;
4666de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
4667de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
4668de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4669de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
4670de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
4671de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4672de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!vars->flow_ctrl)
4673de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4674de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4675de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (vars->line_speed &&
4676de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    ((vars->line_speed == SPEED_10) ||
4677de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     (vars->line_speed == SPEED_100))) {
4678de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->phy_flags |= PHY_SGMII_FLAG;
4679de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else {
4680de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->phy_flags &= ~PHY_SGMII_FLAG;
4681de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
46823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (vars->line_speed &&
46833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    USES_WARPCORE(bp) &&
46843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    (vars->line_speed == SPEED_1000))
46853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->phy_flags |= PHY_SGMII_FLAG;
4686de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* anything 10 and over uses the bmac */
46879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		link_10g_plus = (vars->line_speed >= SPEED_10000);
46889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
46899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (link_10g_plus) {
46909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			if (USES_WARPCORE(bp))
46919380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				vars->mac_type = MAC_TYPE_XMAC;
46929380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			else
46933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				vars->mac_type = MAC_TYPE_BMAC;
46949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		} else {
46959380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			if (USES_WARPCORE(bp))
46969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				vars->mac_type = MAC_TYPE_UMAC;
46973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			else
46983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				vars->mac_type = MAC_TYPE_EMAC;
46999380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
4700de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* link down */
4701de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "phy link down\n");
4702de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4703de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->phy_link_up = 0;
4704de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4705de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = 0;
4706de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->duplex = DUPLEX_FULL;
4707de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4708de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4709de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* indicate no mac active */
4710de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->mac_type = MAC_TYPE_NONE;
4711de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		if (vars->link_status & LINK_STATUS_PHYSICAL_LINK_FLAG)
4712de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
4713de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
47142f751a805e35dcf687473c27282a6602577df541Yaniv Rosner}
47152f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
47162f751a805e35dcf687473c27282a6602577df541Yaniv Rosnervoid bnx2x_link_status_update(struct link_params *params,
47172f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			      struct link_vars *vars)
47182f751a805e35dcf687473c27282a6602577df541Yaniv Rosner{
47192f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	struct bnx2x *bp = params->bp;
47202f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	u8 port = params->port;
47212f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	u32 sync_offset, media_types;
47222f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/* Update PHY configuration */
47232f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	set_phy_vars(params, vars);
4724de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
47252f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	vars->link_status = REG_RD(bp, params->shmem_base +
47262f751a805e35dcf687473c27282a6602577df541Yaniv Rosner				   offsetof(struct shmem_region,
47272f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    port_mb[port].link_status));
47282f751a805e35dcf687473c27282a6602577df541Yaniv Rosner
47292f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	vars->phy_flags = PHY_XGXS_FLAG;
47302f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	bnx2x_sync_link(params, vars);
47311ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	/* Sync media type */
47321ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	sync_offset = params->shmem_base +
47331ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			offsetof(struct shmem_region,
47341ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				 dev_info.port_hw_config[port].media_type);
47351ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	media_types = REG_RD(bp, sync_offset);
47361ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner
47371ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	params->phy[INT_PHY].media_type =
47381ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) >>
47391ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		PORT_HW_CFG_MEDIA_TYPE_PHY0_SHIFT;
47401ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	params->phy[EXT_PHY1].media_type =
47411ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY1_MASK) >>
47421ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT;
47431ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	params->phy[EXT_PHY2].media_type =
47441ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		(media_types & PORT_HW_CFG_MEDIA_TYPE_PHY2_MASK) >>
47451ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		PORT_HW_CFG_MEDIA_TYPE_PHY2_SHIFT;
47461ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	DP(NETIF_MSG_LINK, "media_types = 0x%x\n", media_types);
47471ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner
4748020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	/* Sync AEU offset */
4749020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	sync_offset = params->shmem_base +
4750020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			offsetof(struct shmem_region,
4751020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				 dev_info.port_hw_config[port].aeu_int_mask);
4752020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
4753020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	vars->aeu_int_mask = REG_RD(bp, sync_offset);
4754020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
4755b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	/* Sync PFC status */
4756b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	if (vars->link_status & LINK_STATUS_PFC_ENABLED)
4757b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		params->feature_config_flags |=
4758b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner					FEATURE_CONFIG_PFC_ENABLED;
4759b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner	else
4760b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner		params->feature_config_flags &=
4761b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner					~FEATURE_CONFIG_PFC_ENABLED;
4762b8d6d0824d064ad447e6aacbce90f3a340d93d65Yaniv Rosner
4763020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x int_mask 0x%x\n",
4764020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		 vars->link_status, vars->phy_link_up, vars->aeu_int_mask);
4765de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
4766de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 vars->line_speed, vars->duplex, vars->flow_ctrl);
4767de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
4768de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4769de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_set_master_ln(struct link_params *params,
4770de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				struct bnx2x_phy *phy)
4771de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
4772de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
4773de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 new_master_ln, ser_lane;
4774cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	ser_lane = ((params->lane_config &
4775de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
4776cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
4777de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4778de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* set the master_ln for AN */
4779cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4780cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_XGXS_BLOCK2,
4781cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4782cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &new_master_ln);
4783de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4784cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4785cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_XGXS_BLOCK2 ,
4786cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
4787cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  (new_master_ln | ser_lane));
4788de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
4789de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4790fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_reset_unicore(struct link_params *params,
4791fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			       struct bnx2x_phy *phy,
4792fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			       u8 set_serdes)
4793de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
4794de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
4795de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 mii_control;
4796de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 i;
4797cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4798cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
4799cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
4800de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4801de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* reset the unicore */
4802cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4803cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
4804cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL,
4805cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  (mii_control |
4806cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			   MDIO_COMBO_IEEO_MII_CONTROL_RESET));
4807de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (set_serdes)
4808de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_set_serdes_access(bp, params->port);
4809de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4810de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* wait for the reset to self clear */
4811de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
4812de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		udelay(5);
4813de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4814de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* the reset erased the previous bank value */
4815cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
4816cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_COMBO_IEEE0,
4817cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_COMBO_IEEE0_MII_CONTROL,
4818cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &mii_control);
4819de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
4820de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
4821de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			udelay(5);
4822de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
4823de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
4824de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
4825ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
48266d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	netdev_err(bp->dev,  "Warning: PHY was not initialized,"
48276d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			      " Port %d\n",
48286d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			 params->port);
4829ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
4830ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return -EINVAL;
4831ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4832ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
4833ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4834e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_set_swap_lanes(struct link_params *params,
4835e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				 struct bnx2x_phy *phy)
4836ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
4837ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
48382cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
48392cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *  Each two bits represents a lane number:
48402cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *  No swap is 0123 => 0x1b no need to enable the swap
48412cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
48422f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	u16 rx_lane_swap, tx_lane_swap;
4843ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4844ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	rx_lane_swap = ((params->lane_config &
4845cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
4846cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
4847ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	tx_lane_swap = ((params->lane_config &
4848cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
4849cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
4850ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4851ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (rx_lane_swap != 0x1b) {
4852cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4853cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_XGXS_BLOCK2,
4854cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_RX_LN_SWAP,
4855cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (rx_lane_swap |
4856cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
4857cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				   MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
4858ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
4859cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4860cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_XGXS_BLOCK2,
4861cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
4862ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
4863ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4864ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	if (tx_lane_swap != 0x1b) {
4865cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4866cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_XGXS_BLOCK2,
4867cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_TX_LN_SWAP,
4868cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (tx_lane_swap |
4869cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				   MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
4870ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
4871cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4872cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_XGXS_BLOCK2,
4873cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
4874ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
4875ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
4876ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4877e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_set_parallel_detection(struct bnx2x_phy *phy,
4878e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner					 struct link_params *params)
4879ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
4880ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
4881ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 control2;
4882cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4883cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
4884cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4885cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &control2);
48867aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
488718afb0a6fa69efb76b7a67a151c0530d63789141Yaniv Rosner		control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
488818afb0a6fa69efb76b7a67a151c0530d63789141Yaniv Rosner	else
488918afb0a6fa69efb76b7a67a151c0530d63789141Yaniv Rosner		control2 &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
48907aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	DP(NETIF_MSG_LINK, "phy->speed_cap_mask = 0x%x, control2 = 0x%x\n",
48917aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		phy->speed_cap_mask, control2);
4892cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4893cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
4894cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
4895cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  control2);
4896ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4897e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
4898c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	     (phy->speed_cap_mask &
489918afb0a6fa69efb76b7a67a151c0530d63789141Yaniv Rosner		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
4900ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "XGXS\n");
4901ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4902cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4903cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_REG_BANK_10G_PARALLEL_DETECT,
4904cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
4905cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
4906ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4907cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
4908cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4909cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4910cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &control2);
4911ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4912ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4913ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		control2 |=
4914ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
4915ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4916cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4917cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_10G_PARALLEL_DETECT,
4918cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
4919cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  control2);
4920ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4921ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* Disable parallel detection of HiG */
4922cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4923cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_XGXS_BLOCK2,
4924cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
4925cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
4926cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
4927ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
4928ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
4929ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4930e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_set_autoneg(struct bnx2x_phy *phy,
4931e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			      struct link_params *params,
4932cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			      struct link_vars *vars,
4933cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			      u8 enable_cl73)
4934ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
4935ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
4936ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 reg_val;
4937ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4938ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* CL37 Autoneg */
4939cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4940cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
4941cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
4942ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4943ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* CL37 Autoneg Enabled */
49448c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	if (vars->line_speed == SPEED_AUTO_NEG)
4945ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
4946ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	else /* CL37 Autoneg Disabled */
4947ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
4948ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
4949ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4950cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4951cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
4952cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
4953ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4954ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* Enable/Disable Autodetection */
4955ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4956cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4957cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
4958cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
4959239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	reg_val &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN |
4960239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		    MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT);
4961239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE;
49628c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	if (vars->line_speed == SPEED_AUTO_NEG)
4963ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4964ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	else
4965ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
4966ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4967cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4968cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
4969cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
4970ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4971ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* Enable TetonII and BAM autoneg */
4972cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
4973cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4974cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4975ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			  &reg_val);
49768c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	if (vars->line_speed == SPEED_AUTO_NEG) {
4977ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* Enable BAM aneg Mode and TetonII aneg Mode */
4978ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4979ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4980ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else {
4981ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* TetonII and BAM Autoneg Disabled */
4982ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
4983ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
4984ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
4985cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
4986cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_BAM_NEXT_PAGE,
4987cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
4988cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  reg_val);
4989ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
4990239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	if (enable_cl73) {
4991239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		/* Enable Cl73 FSM status bits */
4992cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4993cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_USERB0,
4994cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_USERB0_CL73_UCTRL,
4995cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  0xe);
4996239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
4997239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		/* Enable BAM Station Manager*/
4998cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
4999239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			MDIO_REG_BANK_CL73_USERB0,
5000239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			MDIO_CL73_USERB0_CL73_BAM_CTRL1,
5001239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
5002239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
5003239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN);
5004239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
50057846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner		/* Advertise CL73 link speeds */
5006cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
5007cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_IEEEB1,
5008cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB1_AN_ADV2,
5009cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &reg_val);
50107aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		if (phy->speed_cap_mask &
50117846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
50127846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
50137aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		if (phy->speed_cap_mask &
50147846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner		    PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
50157846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
5016239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5017cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
5018cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_IEEEB1,
5019cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB1_AN_ADV2,
5020cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  reg_val);
5021239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5022239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		/* CL73 Autoneg Enabled */
5023239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
5024239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5025239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	} else /* CL73 Autoneg Disabled */
5026239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		reg_val = 0;
5027ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5028cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5029cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_CL73_IEEEB0,
5030cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
5031ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5032ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5033ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/* program SerDes, forced speed */
5034e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_program_serdes(struct bnx2x_phy *phy,
5035e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				 struct link_params *params,
5036cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 struct link_vars *vars)
5037ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5038ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5039ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 reg_val;
5040ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
504157937203aa077520a7e1665bfb7071b3cbb3f5a9Eilon Greenstein	/* program duplex, disable autoneg and sgmii*/
5042cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5043cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
5044cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
5045ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
504657937203aa077520a7e1665bfb7071b3cbb3f5a9Eilon Greenstein		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
504757937203aa077520a7e1665bfb7071b3cbb3f5a9Eilon Greenstein		     MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK);
50487aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->req_duplex == DUPLEX_FULL)
5049ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5050cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5051cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
5052cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
5053ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
50542cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
50552cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * program speed
50562cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *  - needed only if the speed is greater than 1G (2.5G or 10G)
50572cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
5058cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5059cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5060cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_MISC1, &reg_val);
50618c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	/* clearing the speed value before setting the right speed */
50628c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
50638c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner
50648c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
50658c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
50668c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner
50678c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	if (!((vars->line_speed == SPEED_1000) ||
50688c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	      (vars->line_speed == SPEED_100) ||
50698c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	      (vars->line_speed == SPEED_10))) {
50708c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner
5071ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
5072ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
50738c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner		if (vars->line_speed == SPEED_10000)
5074ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			reg_val |=
5075ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
50768c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	}
50778c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner
5078cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5079cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5080cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_MISC1, reg_val);
50818c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner
5082ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5083ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
50849045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void bnx2x_set_brcm_cl37_advertisement(struct bnx2x_phy *phy,
50859045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner					      struct link_params *params)
5086ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5087ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5088ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 val = 0;
5089ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5090ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* configure the 48 bits for BAM AN */
5091ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5092ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* set extended capabilities */
50937aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
5094ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val |= MDIO_OVER_1G_UP1_2_5G;
50957aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
5096ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		val |= MDIO_OVER_1G_UP1_10G;
5097cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5098cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_OVER_1G,
5099cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_OVER_1G_UP1, val);
5100ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5101cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5102cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_OVER_1G,
5103cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_OVER_1G_UP3, 0x400);
5104ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5105ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
51069045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerstatic void bnx2x_set_ieee_aneg_advertisement(struct bnx2x_phy *phy,
51079045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner					      struct link_params *params,
51089045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner					      u16 ieee_fc)
51098c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner{
51108c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	struct bnx2x *bp = params->bp;
51117846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner	u16 val;
51128c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	/* for AN, we are always publishing full duplex */
5113ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5114cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5115cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_COMBO_IEEE0,
5116cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_COMBO_IEEE0_AUTO_NEG_ADV, ieee_fc);
5117cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5118cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_CL73_IEEEB1,
5119cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_CL73_IEEEB1_AN_ADV1, &val);
51207846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner	val &= ~MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_BOTH;
51217846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner	val |= ((ieee_fc<<3) & MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK);
5122cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5123cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_CL73_IEEEB1,
5124cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_CL73_IEEEB1_AN_ADV1, val);
5125ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5126ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5127e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_restart_autoneg(struct bnx2x_phy *phy,
5128e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				  struct link_params *params,
5129e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				  u8 enable_cl73)
5130ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5131ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
51323a36f2efbf9ac5da1d08cb44d237ba35ec354888Eilon Greenstein	u16 mii_control;
5133239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5134ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
51353a36f2efbf9ac5da1d08cb44d237ba35ec354888Eilon Greenstein	/* Enable and restart BAM/CL37 aneg */
5136ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5137239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	if (enable_cl73) {
5138cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
5139cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_IEEEB0,
5140cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5141cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &mii_control);
5142239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5143cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
5144cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_IEEEB0,
5145cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5146cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (mii_control |
5147cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
5148cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
5149239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	} else {
5150239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
5151cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
5152cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_COMBO_IEEE0,
5153cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_COMBO_IEEE0_MII_CONTROL,
5154cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &mii_control);
5155239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		DP(NETIF_MSG_LINK,
5156239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
5157239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			 mii_control);
5158cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
5159cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_COMBO_IEEE0,
5160cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_COMBO_IEEE0_MII_CONTROL,
5161cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (mii_control |
5162cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				   MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5163cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				   MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
5164239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	}
5165ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5166ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5167e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_initialize_sgmii_process(struct bnx2x_phy *phy,
5168e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner					   struct link_params *params,
5169cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					   struct link_vars *vars)
5170ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5171ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5172ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 control1;
5173ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5174ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* in SGMII mode, the unicore is always slave */
5175ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5176cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5177cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5178cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5179cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &control1);
5180ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
5181ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* set sgmii mode (and not fiber) */
5182ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
5183ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
5184ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
5185cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5186cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5187cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
5188cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  control1);
5189ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5190ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* if forced speed */
51918c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner	if (!(vars->line_speed == SPEED_AUTO_NEG)) {
5192ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* set speed, disable autoneg */
5193ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		u16 mii_control;
5194ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5195cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
5196cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_COMBO_IEEE0,
5197cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_COMBO_IEEE0_MII_CONTROL,
5198cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  &mii_control);
5199ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
5200ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
5201ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
5202ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
52038c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner		switch (vars->line_speed) {
5204ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case SPEED_100:
5205ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			mii_control |=
5206ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
5207ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5208ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case SPEED_1000:
5209ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			mii_control |=
5210ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
5211ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5212ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case SPEED_10:
5213ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			/* there is nothing to set for 10M */
5214ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5215ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		default:
5216ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			/* invalid speed for SGMII */
52178c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
52188c99e7b0436473593a68e740d1032909bc5335a1Yaniv Rosner				  vars->line_speed);
5219ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5220ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
5221ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5222ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* setting the full duplex */
52237aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
5224ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			mii_control |=
5225ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
5226cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
5227cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_COMBO_IEEE0,
5228cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_COMBO_IEEE0_MII_CONTROL,
5229cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  mii_control);
5230ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5231ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else { /* AN mode */
5232ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* enable and restart AN */
5233e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_restart_autoneg(phy, params, 0);
5234ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
5235ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5236ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5237ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5238ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner/*
5239ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner * link management
5240ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner */
5241ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5242fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_direct_parallel_detect_used(struct bnx2x_phy *phy,
5243fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     struct link_params *params)
524415ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner{
524515ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	struct bnx2x *bp = params->bp;
524615ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	u16 pd_10g, status2_1000x;
52477aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->req_line_speed != SPEED_AUTO_NEG)
52487aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		return 0;
5249cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5250cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5251cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5252cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &status2_1000x);
5253cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5254cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_SERDES_DIGITAL,
5255cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_SERDES_DIGITAL_A_1000X_STATUS2,
5256cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &status2_1000x);
525715ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	if (status2_1000x & MDIO_SERDES_DIGITAL_A_1000X_STATUS2_AN_DISABLED) {
525815ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner		DP(NETIF_MSG_LINK, "1G parallel detect link on port %d\n",
525915ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner			 params->port);
526015ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner		return 1;
526115ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	}
526215ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner
5263cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5264cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_10G_PARALLEL_DETECT,
5265cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS,
5266cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &pd_10g);
526715ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner
526815ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	if (pd_10g & MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_STATUS_PD_LINK) {
526915ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner		DP(NETIF_MSG_LINK, "10G parallel detect link on port %d\n",
527015ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner			 params->port);
527115ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner		return 1;
527215ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	}
527315ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner	return 0;
527415ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner}
5275ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
52769e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuvalstatic void bnx2x_update_adv_fc(struct bnx2x_phy *phy,
52779e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				struct link_params *params,
52789e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				struct link_vars *vars,
52799e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				u32 gp_status)
52809e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval{
52819e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	u16 ld_pause;   /* local driver */
52829e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	u16 lp_pause;   /* link partner */
52839e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	u16 pause_result;
52849e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	struct bnx2x *bp = params->bp;
52859e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if ((gp_status &
52869e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	     (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
52879e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	      MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) ==
52889e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	    (MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE |
52899e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	     MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_MR_LP_NP_AN_ABLE)) {
52909e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
52919e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy,
52929e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_REG_BANK_CL73_IEEEB1,
52939e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_CL73_IEEEB1_AN_ADV1,
52949e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  &ld_pause);
52959e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy,
52969e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_REG_BANK_CL73_IEEEB1,
52979e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_CL73_IEEEB1_AN_LP_ADV1,
52989e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  &lp_pause);
52999e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		pause_result = (ld_pause &
53009e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_CL73_IEEEB1_AN_ADV1_PAUSE_MASK) >> 8;
53019e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		pause_result |= (lp_pause &
53029e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				 MDIO_CL73_IEEEB1_AN_LP_ADV1_PAUSE_MASK) >> 10;
53039e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		DP(NETIF_MSG_LINK, "pause_result CL73 0x%x\n", pause_result);
53049e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	} else {
53059e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy,
53069e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_REG_BANK_COMBO_IEEE0,
53079e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
53089e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  &ld_pause);
53099e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy,
53109e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			MDIO_REG_BANK_COMBO_IEEE0,
53119e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
53129e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			&lp_pause);
53139e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		pause_result = (ld_pause &
53149e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
53159e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		pause_result |= (lp_pause &
53169e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
53179e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		DP(NETIF_MSG_LINK, "pause_result CL37 0x%x\n", pause_result);
53189e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	}
53199e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	bnx2x_pause_resolve(vars, pause_result);
53209e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
53219e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval}
53229e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
5323e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_flow_ctrl_resolve(struct bnx2x_phy *phy,
5324e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				    struct link_params *params,
5325e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				    struct link_vars *vars,
5326e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				    u32 gp_status)
5327ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5328ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5329c0700f90e5300c63d01c70e157e75e4510dd2981David S. Miller	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5330ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5331ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* resolve from gp_status in case of AN complete and not sgmii */
53329e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if (phy->req_flow_ctrl != BNX2X_FLOW_CTRL_AUTO) {
53339e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* Update the advertised flow-controled of LD/LP in AN */
53349e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (phy->req_line_speed == SPEED_AUTO_NEG)
53359e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			bnx2x_update_adv_fc(phy, params, vars, gp_status);
53369e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* But set the flow-control result as the requested one */
53377aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		vars->flow_ctrl = phy->req_flow_ctrl;
53389e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	} else if (phy->req_line_speed != SPEED_AUTO_NEG)
53397aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		vars->flow_ctrl = params->req_fc_auto_adv;
53407aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	else if ((gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
53417aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		 (!(vars->phy_flags & PHY_SGMII_FLAG))) {
5342e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		if (bnx2x_direct_parallel_detect_used(phy, params)) {
534315ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner			vars->flow_ctrl = params->req_fc_auto_adv;
534415ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner			return;
534515ddd2d0ef4849410a2251587b3652fe6a689fdaYaniv Rosner		}
53469e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_update_adv_fc(phy, params, vars, gp_status);
5347ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
5348ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
5349ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5350ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5351e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosnerstatic void bnx2x_check_fallback_to_cl37(struct bnx2x_phy *phy,
5352e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner					 struct link_params *params)
5353239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein{
5354239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	struct bnx2x *bp = params->bp;
53559045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	u16 rx_status, ustat_val, cl37_fsm_received;
5356239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	DP(NETIF_MSG_LINK, "bnx2x_check_fallback_to_cl37\n");
5357239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	/* Step 1: Make sure signal is detected */
5358cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5359cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_RX0,
5360cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_RX0_RX_STATUS,
5361cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &rx_status);
5362239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	if ((rx_status & MDIO_RX0_RX_STATUS_SIGDET) !=
5363239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	    (MDIO_RX0_RX_STATUS_SIGDET)) {
5364239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		DP(NETIF_MSG_LINK, "Signal is not detected. Restoring CL73."
5365239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			     "rx_status(0x80b0) = 0x%x\n", rx_status);
5366cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_WR_OVER_CL45(bp, phy,
5367cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_REG_BANK_CL73_IEEEB0,
5368cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5369cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN);
5370239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		return;
5371239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	}
5372239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	/* Step 2: Check CL73 state machine */
5373cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5374cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_CL73_USERB0,
5375cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_CL73_USERB0_CL73_USTAT1,
5376cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &ustat_val);
5377239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	if ((ustat_val &
5378239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	     (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5379239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) !=
5380239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	    (MDIO_CL73_USERB0_CL73_USTAT1_LINK_STATUS_CHECK |
5381239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	      MDIO_CL73_USERB0_CL73_USTAT1_AN_GOOD_CHECK_BAM37)) {
5382239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		DP(NETIF_MSG_LINK, "CL73 state-machine is not stable. "
5383239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			     "ustat_val(0x8371) = 0x%x\n", ustat_val);
5384239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		return;
5385239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	}
53862cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
53872cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Step 3: Check CL37 Message Pages received to indicate LP
53882cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * supports only CL37
53892cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
5390cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5391cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_REMOTE_PHY,
5392cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REMOTE_PHY_MISC_RX_STATUS,
53939045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			  &cl37_fsm_received);
53949045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if ((cl37_fsm_received &
5395239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	     (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5396239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	     MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) !=
5397239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	    (MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_OVER1G_MSG |
5398239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	      MDIO_REMOTE_PHY_MISC_RX_STATUS_CL37_FSM_RECEIVED_BRCM_OUI_MSG)) {
5399239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		DP(NETIF_MSG_LINK, "No CL37 FSM were received. "
5400239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			     "misc_rx_status(0x8330) = 0x%x\n",
54019045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			 cl37_fsm_received);
5402239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		return;
5403239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	}
54042cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
54052cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The combined cl37/cl73 fsm state information indicating that
54062cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * we are connected to a device which does not support cl73, but
54072cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * does support cl37 BAM. In this case we disable cl73 and
54082cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * restart cl37 auto-neg
54092cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
54102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner
5411239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	/* Disable CL73 */
5412cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_WR_OVER_CL45(bp, phy,
5413cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_CL73_IEEEB0,
5414cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
5415cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  0);
5416239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	/* Restart CL37 autoneg */
5417e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_restart_autoneg(phy, params, 0);
5418239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein	DP(NETIF_MSG_LINK, "Disabling CL73, and restarting CL37 autoneg\n");
5419239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein}
54207aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
54217aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosnerstatic void bnx2x_xgxs_an_resolve(struct bnx2x_phy *phy,
54227aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner				  struct link_params *params,
54237aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner				  struct link_vars *vars,
54247aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner				  u32 gp_status)
54257aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner{
54267aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE)
54277aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		vars->link_status |=
54287aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner			LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
54297aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
54307aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (bnx2x_direct_parallel_detect_used(phy, params))
54317aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		vars->link_status |=
54327aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner			LINK_STATUS_PARALLEL_DETECTION_USED;
54337aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner}
54343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_get_link_speed_duplex(struct bnx2x_phy *phy,
54353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				     struct link_params *params,
54363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_vars *vars,
54373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u16 is_link_up,
54383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u16 speed_mask,
54393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u16 is_duplex)
5440ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5441ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
54427aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	if (phy->req_line_speed == SPEED_AUTO_NEG)
54437aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_ENABLED;
54443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (is_link_up) {
54453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "phy link up\n");
5446ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5447ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->phy_link_up = 1;
5448ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->link_status |= LINK_STATUS_LINK_UP;
5449ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
54503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		switch (speed_mask) {
5451ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_10M:
54523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_10;
5453ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			if (vars->duplex == DUPLEX_FULL)
5454ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_10TFD;
5455ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			else
5456ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_10THD;
5457ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5458ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5459ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_100M:
54603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_100;
5461ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			if (vars->duplex == DUPLEX_FULL)
5462ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_100TXFD;
5463ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			else
5464ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_100TXHD;
5465ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5466ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5467ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_1G:
5468ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_1G_KX:
54693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_1000;
5470ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			if (vars->duplex == DUPLEX_FULL)
5471ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_1000TFD;
5472ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			else
5473ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_1000THD;
5474ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5475ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5476ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_2_5G:
54773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_2500;
5478ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			if (vars->duplex == DUPLEX_FULL)
5479ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_2500TFD;
5480ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			else
5481ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				vars->link_status |= LINK_2500THD;
5482ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
5483ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5484ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_5G:
5485ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_6G:
5486ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			DP(NETIF_MSG_LINK,
5487ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				 "link speed unsupported  gp_status 0x%x\n",
54883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  speed_mask);
5489ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			return -EINVAL;
5490ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
5491ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_10G_KX4:
5492ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_10G_HIG:
5493ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		case GP_STATUS_10G_CX4:
54943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case GP_STATUS_10G_KR:
54953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case GP_STATUS_10G_SFI:
54963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case GP_STATUS_10G_XFI:
54973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_10000;
5498ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			vars->link_status |= LINK_10GTFD;
5499ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			break;
55003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case GP_STATUS_20G_DXGXS:
55013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->line_speed = SPEED_20000;
55023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			vars->link_status |= LINK_20GTFD;
55033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
5504ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		default:
5505ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner			DP(NETIF_MSG_LINK,
5506ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner				  "link speed unsupported gp_status 0x%x\n",
55073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  speed_mask);
5508ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein			return -EINVAL;
5509ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
5510ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	} else { /* link_down */
5511ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		DP(NETIF_MSG_LINK, "phy link down\n");
5512ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5513ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->phy_link_up = 0;
551457963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
5515ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->duplex = DUPLEX_FULL;
5516c0700f90e5300c63d01c70e157e75e4510dd2981David S. Miller		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
5517ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->mac_type = MAC_TYPE_NONE;
55183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
55193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, " phy_link_up %x line_speed %d\n",
55203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    vars->phy_link_up, vars->line_speed);
55213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return 0;
55223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
55233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
55243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_link_settings_status(struct bnx2x_phy *phy,
55253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_params *params,
55263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct link_vars *vars)
55273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
55283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
55293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
55303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 gp_status, duplex = DUPLEX_HALF, link_up = 0, speed_mask;
55313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	int rc = 0;
55323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
55333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Read gp_status */
55343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
55353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  MDIO_REG_BANK_GP_STATUS,
55363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  MDIO_GP_STATUS_TOP_AN_STATUS1,
55373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  &gp_status);
55383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
55393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		duplex = DUPLEX_FULL;
55403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS)
55413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		link_up = 1;
55423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	speed_mask = gp_status & GP_STATUS_SPEED_MASK;
55433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "gp_status 0x%x, is_link_up %d, speed_mask 0x%x\n",
55443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       gp_status, link_up, speed_mask);
55453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, speed_mask,
55463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 duplex);
55473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (rc == -EINVAL)
55483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return rc;
5549239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein
55503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
55513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (SINGLE_MEDIA_DIRECT(params)) {
55523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_flow_ctrl_resolve(phy, params, vars, gp_status);
55533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (phy->req_line_speed == SPEED_AUTO_NEG)
55543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_xgxs_an_resolve(phy, params, vars,
55553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						      gp_status);
55563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
55573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else { /* link_down */
5558c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
5559c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner		    SINGLE_MEDIA_DIRECT(params)) {
5560239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein			/* Check signal is detected */
5561c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner			bnx2x_check_fallback_to_cl37(phy, params);
5562239d686d494f10ecd83a89ddc4e31f9462ca4901Eilon Greenstein		}
5563ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
5564ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
55659e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	/* Read LP advertised speeds*/
55669e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if (SINGLE_MEDIA_DIRECT(params) &&
55679e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	    (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)) {
55689e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		u16 val;
55699e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
55709e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_CL73_IEEEB1,
55719e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_CL73_IEEEB1_AN_LP_ADV2, &val);
55729e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
55739e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
55749e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
55759e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
55769e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
55779e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
55789e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
55799e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
55809e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
55819e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		CL22_RD_OVER_CL45(bp, phy, MDIO_REG_BANK_OVER_1G,
55829e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  MDIO_OVER_1G_LP_UP1, &val);
55839e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
55849e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & MDIO_OVER_1G_UP1_2_5G)
55859e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
55869e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
55879e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
55889e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
55899e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
55909e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	}
55919e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
5592a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
5593a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		   vars->duplex, vars->flow_ctrl, vars->link_status);
5594ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return rc;
5595ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5596ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
55973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_warpcore_read_status(struct bnx2x_phy *phy,
55983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				     struct link_params *params,
55993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				     struct link_vars *vars)
56003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
56013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
56023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 lane;
56033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 gp_status1, gp_speed, link_up, duplex = DUPLEX_FULL;
56043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	int rc = 0;
56053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	lane = bnx2x_get_warpcore_lane(phy, params);
56063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* Read gp_status */
56073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (phy->req_line_speed > SPEED_10000) {
56083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u16 temp_link_up;
56093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				1, &temp_link_up);
56113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				1, &link_up);
56133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "PCS RX link status = 0x%x-->0x%x\n",
56143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       temp_link_up, link_up);
56153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		link_up &= (1<<2);
56163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (link_up)
56173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_ext_phy_resolve_fc(phy, params, vars);
56183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
56193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_GP2_STATUS_GP_2_1, &gp_status1);
56213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "0x81d1 = 0x%x\n", gp_status1);
56223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Check for either KR or generic link up. */
56233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		gp_status1 = ((gp_status1 >> 8) & 0xf) |
56243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			((gp_status1 >> 12) & 0xf);
56253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		link_up = gp_status1 & (1 << lane);
56263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (link_up && SINGLE_MEDIA_DIRECT(params)) {
56273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			u16 pd, gp_status4;
56283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (phy->req_line_speed == SPEED_AUTO_NEG) {
56293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				/* Check Autoneg complete */
56303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						MDIO_WC_REG_GP2_STATUS_GP_2_4,
56323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						&gp_status4);
56333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				if (gp_status4 & ((1<<12)<<lane))
56343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					vars->link_status |=
56353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
56363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				/* Check parallel detect used */
56383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						MDIO_WC_REG_PAR_DET_10G_STATUS,
56403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						&pd);
56413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				if (pd & (1<<15))
56423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					vars->link_status |=
56433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					LINK_STATUS_PARALLEL_DETECTION_USED;
56443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			}
56453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_ext_phy_resolve_fc(phy, params, vars);
56463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
56473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
56483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56499e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if ((vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) &&
56509e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	    SINGLE_MEDIA_DIRECT(params)) {
56519e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		u16 val;
56529e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56539e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
56549e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_LP_AUTO_NEG2, &val);
56559e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56569e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX)
56579e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
56589e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
56599e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4 |
56609e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			   MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KR))
56619e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
56629e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
56639e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56649e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56659e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_WC_REG_DIGITAL3_LP_UP1, &val);
56669e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56679e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & MDIO_OVER_1G_UP1_2_5G)
56689e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
56699e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_2500XFD_CAPABLE;
56709e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (MDIO_OVER_1G_UP1_10G | MDIO_OVER_1G_UP1_10GH))
56719e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
56729e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
56739e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56749e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	}
56759e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56769e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
56773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (lane < 2) {
56783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_GP2_STATUS_GP_2_2, &gp_speed);
56803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
56813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
56823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				MDIO_WC_REG_GP2_STATUS_GP_2_3, &gp_speed);
56833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
56843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "lane %d gp_speed 0x%x\n", lane, gp_speed);
56853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if ((lane & 1) == 0)
56873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		gp_speed <<= 8;
56883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	gp_speed &= 0x3f00;
56893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	rc = bnx2x_get_link_speed_duplex(phy, params, vars, link_up, gp_speed,
56923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					 duplex);
56933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
56943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x link_status 0x%x\n",
56953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		   vars->duplex, vars->flow_ctrl, vars->link_status);
56963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return rc;
56973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
5698ed8680a7e68fc07d6b2bfa977e8f5f3d3c568d14Eilon Greensteinstatic void bnx2x_set_gmii_tx_driver(struct link_params *params)
5699ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5700ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5701e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x_phy *phy = &params->phy[INT_PHY];
5702ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 lp_up2;
5703ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 tx_driver;
5704c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein	u16 bank;
5705ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5706ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* read precomp */
5707cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner	CL22_RD_OVER_CL45(bp, phy,
5708cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_OVER_1G,
5709cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_OVER_1G_LP_UP2, &lp_up2);
5710ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5711ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	/* bits [10:7] at lp_up2, positioned at [15:12] */
5712ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
5713ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
5714ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
5715ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5716c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein	if (lp_up2 == 0)
5717c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein		return;
5718c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein
5719c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein	for (bank = MDIO_REG_BANK_TX0; bank <= MDIO_REG_BANK_TX3;
5720c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein	      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0)) {
5721cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner		CL22_RD_OVER_CL45(bp, phy,
5722cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  bank,
5723cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  MDIO_TX0_TX_DRIVER, &tx_driver);
5724c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein
5725c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein		/* replace tx_driver bits [15:12] */
5726c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein		if (lp_up2 !=
5727c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein		    (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK)) {
5728c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein			tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
5729c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein			tx_driver |= lp_up2;
5730cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner			CL22_WR_OVER_CL45(bp, phy,
5731cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					  bank,
5732cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					  MDIO_TX0_TX_DRIVER, tx_driver);
5733c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein		}
5734ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
5735ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5736ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5737fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_emac_program(struct link_params *params,
5738fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      struct link_vars *vars)
5739ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5740ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
5741ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u8 port = params->port;
5742ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	u16 mode = 0;
5743ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5744ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
5745ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
5746cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       EMAC_REG_EMAC_MODE,
5747cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       (EMAC_MODE_25G_MODE |
5748cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			EMAC_MODE_PORT_MII_10M |
5749cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			EMAC_MODE_HALF_DUPLEX));
5750b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	switch (vars->line_speed) {
5751ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	case SPEED_10:
5752ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mode |= EMAC_MODE_PORT_MII_10M;
5753ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
5754ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5755ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	case SPEED_100:
5756ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mode |= EMAC_MODE_PORT_MII;
5757ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
5758ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5759ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	case SPEED_1000:
5760ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mode |= EMAC_MODE_PORT_GMII;
5761ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
5762ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5763ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	case SPEED_2500:
5764ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
5765ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		break;
5766ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5767ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	default:
5768ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		/* 10G not valid for EMAC */
5769b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner		DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
5770b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   vars->line_speed);
5771ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		return -EINVAL;
5772ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
5773ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5774b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	if (vars->duplex == DUPLEX_HALF)
5775ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		mode |= EMAC_MODE_HALF_DUPLEX;
5776ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	bnx2x_bits_en(bp,
5777cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		      GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
5778cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		      mode);
5779ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
57807f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
5781ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	return 0;
5782ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5783ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5784de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_set_preemphasis(struct bnx2x_phy *phy,
5785de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_params *params)
5786b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
5787de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5788de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 bank, i = 0;
5789de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
5790de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5791de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (bank = MDIO_REG_BANK_RX0, i = 0; bank <= MDIO_REG_BANK_RX3;
5792de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0), i++) {
5793cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner			CL22_WR_OVER_CL45(bp, phy,
5794de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  bank,
5795de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  MDIO_RX0_RX_EQ_BOOST,
5796de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  phy->rx_preemphasis[i]);
5797de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
5798de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5799de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (bank = MDIO_REG_BANK_TX0, i = 0; bank <= MDIO_REG_BANK_TX3;
5800de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      bank += (MDIO_REG_BANK_TX1 - MDIO_REG_BANK_TX0), i++) {
5801cd2be89b8ed7a50b781fae43a43f20d6ef1a137bYaniv Rosner			CL22_WR_OVER_CL45(bp, phy,
5802de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  bank,
5803de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  MDIO_TX0_TX_DRIVER,
5804de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  phy->tx_preemphasis[i]);
5805de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
5806de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
5807de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5808ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosnerstatic void bnx2x_xgxs_config_init(struct bnx2x_phy *phy,
5809ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner				   struct link_params *params,
5810ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner				   struct link_vars *vars)
5811de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
5812de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
5813de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 enable_cl73 = (SINGLE_MEDIA_DIRECT(params) ||
5814de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			  (params->loopback_mode == LOOPBACK_XGXS));
5815de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
5816de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (SINGLE_MEDIA_DIRECT(params) &&
5817de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    (params->feature_config_flags &
5818de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED))
5819de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_set_preemphasis(phy, params);
5820de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5821de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* forced speed requested? */
5822de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (vars->line_speed != SPEED_AUTO_NEG ||
5823de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    (SINGLE_MEDIA_DIRECT(params) &&
5824cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		     params->loopback_mode == LOOPBACK_EXT)) {
5825de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
5826de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5827de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* disable autoneg */
5828de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_set_autoneg(phy, params, vars, 0);
5829de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5830de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* program speed and duplex */
5831de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_program_serdes(phy, params, vars);
5832de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5833de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else { /* AN_mode */
5834de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "not SGMII, AN\n");
5835de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5836de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* AN enabled */
58379045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			bnx2x_set_brcm_cl37_advertisement(phy, params);
5838de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5839de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* program duplex & pause advertisement (for aneg) */
58409045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			bnx2x_set_ieee_aneg_advertisement(phy, params,
58419045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner							  vars->ieee_fc);
5842de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5843de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* enable autoneg */
5844de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_set_autoneg(phy, params, vars, enable_cl73);
5845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5846de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* enable and restart AN */
5847de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_restart_autoneg(phy, params, enable_cl73);
5848de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
5849de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5850de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* SGMII mode */
5851de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "SGMII\n");
5852de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5853de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_initialize_sgmii_process(phy, params, vars);
5854de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
5855de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
5856de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5857ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosnerstatic int bnx2x_prepare_xgxs(struct bnx2x_phy *phy,
5858ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner			  struct link_params *params,
5859ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner			  struct link_vars *vars)
5860b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
5861fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc;
5862ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	vars->phy_flags |= PHY_XGXS_FLAG;
5863b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	if ((phy->req_line_speed &&
5864b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	     ((phy->req_line_speed == SPEED_100) ||
5865b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	      (phy->req_line_speed == SPEED_10))) ||
5866b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	    (!phy->req_line_speed &&
5867b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	     (phy->speed_cap_mask >=
5868b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	      PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
5869b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	     (phy->speed_cap_mask <
5870ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
5871ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	    (phy->type == PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT_SD))
5872b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner		vars->phy_flags |= PHY_SGMII_FLAG;
5873b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	else
5874b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner		vars->phy_flags &= ~PHY_SGMII_FLAG;
5875b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
5876b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
5877ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	bnx2x_set_aer_mmd(params, phy);
5878ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)
5879ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner		bnx2x_set_master_ln(params, phy);
5880b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
5881b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	rc = bnx2x_reset_unicore(params, phy, 0);
5882b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	/* reset the SerDes and wait for reset bit return low */
5883b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	if (rc != 0)
5884b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner		return rc;
5885b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
5886ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	bnx2x_set_aer_mmd(params, phy);
5887b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	/* setting the masterLn_def again after the reset */
5888ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
5889ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner		bnx2x_set_master_ln(params, phy);
5890ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner		bnx2x_set_swap_lanes(params, phy);
5891ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	}
5892b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
5893b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	return rc;
5894b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
5895c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner
5896de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u16 bnx2x_wait_reset_complete(struct bnx2x *bp,
58976d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner				     struct bnx2x_phy *phy,
58986d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner				     struct link_params *params)
5899ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
5900de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 cnt, ctrl;
590125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* Wait for soft reset to get cleared up to 1 sec */
5902de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (cnt = 0; cnt < 1000; cnt++) {
590352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
59046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			bnx2x_cl22_read(bp, phy,
59056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				MDIO_PMA_REG_CTRL, &ctrl);
59066583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		else
59076583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			bnx2x_cl45_read(bp, phy,
59086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				MDIO_PMA_DEVAD,
59096583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				MDIO_PMA_REG_CTRL, &ctrl);
5910de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(ctrl & (1<<15)))
5911de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
5912de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(1);
5913de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
59146d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner
59156d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	if (cnt == 1000)
59166d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner		netdev_err(bp->dev,  "Warning: PHY was not initialized,"
59176d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner				      " Port %d\n",
59186d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			 params->port);
5919de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n", ctrl, cnt);
5920de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return cnt;
5921ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
5922ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
5923de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_link_int_enable(struct link_params *params)
5924a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein{
5925de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
5926de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 mask;
5927de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
5928c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner
59292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/* Setting the status to report on link up for either XGXS or SerDes */
59303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
59313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		mask = NIG_MASK_XGXS0_LINK_STATUS;
59323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (!(SINGLE_MEDIA_DIRECT(params)))
59333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			mask |= NIG_MASK_MI_INT;
59343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else if (params->switch_cfg == SWITCH_CFG_10G) {
5935de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mask = (NIG_MASK_XGXS0_LINK10G |
5936de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			NIG_MASK_XGXS0_LINK_STATUS);
5937de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
5938de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(SINGLE_MEDIA_DIRECT(params)) &&
5939de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params->phy[INT_PHY].type !=
5940de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) {
5941de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			mask |= NIG_MASK_MI_INT;
5942de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "enabled external phy int\n");
5943de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
5944de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5945de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* SerDes */
5946de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mask = NIG_MASK_SERDES0_LINK_STATUS;
5947de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
5948de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(SINGLE_MEDIA_DIRECT(params)) &&
5949de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params->phy[INT_PHY].type !=
5950de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN) {
5951de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			mask |= NIG_MASK_MI_INT;
5952de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "enabled external phy int\n");
5953de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
5954de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
5955de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_bits_en(bp,
5956de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
5957de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      mask);
5958de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
5959de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "port %x, is_xgxs %x, int_status 0x%x\n", port,
5960de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 (params->switch_cfg == SWITCH_CFG_10G),
5961de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
5962de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
5963de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
5964de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
5965de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
5966de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
5967de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
5968de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
5969a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein}
5970a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein
5971a22f078867ef362e35c54055878168e6613ff743Yaniv Rosnerstatic void bnx2x_rearm_latch_signal(struct bnx2x *bp, u8 port,
5972a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				     u8 exp_mi_int)
5973a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein{
5974a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 latch_status = 0;
5975a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
59762cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
5977a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	 * Disable the MI INT ( external phy int ) by writing 1 to the
5978a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	 * status register. Link down indication is high-active-signal,
5979a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	 * so in this case we need to write the status to clear the XOR
5980de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
5981de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Read Latched signals */
5982de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	latch_status = REG_RD(bp,
5983a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				    NIG_REG_LATCH_STATUS_0 + port*8);
5984a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	DP(NETIF_MSG_LINK, "latch_status = 0x%x\n", latch_status);
5985de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Handle only those with latched-signal=up.*/
5986a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (exp_mi_int)
5987a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		bnx2x_bits_en(bp,
5988a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			      NIG_REG_STATUS_INTERRUPT_PORT0
5989a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			      + port*4,
5990a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			      NIG_STATUS_EMAC0_MI_INT);
5991a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	else
5992a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		bnx2x_bits_dis(bp,
5993a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			       NIG_REG_STATUS_INTERRUPT_PORT0
5994a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			       + port*4,
5995a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			       NIG_STATUS_EMAC0_MI_INT);
5996a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
5997de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (latch_status & 1) {
5998a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
5999de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* For all latched-signal=up : Re-Arm Latch signals */
6000de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		REG_WR(bp, NIG_REG_LATCH_STATUS_0 + port*8,
6001cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       (latch_status & 0xfffe) | (latch_status & 1));
6002de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6003a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	/* For all latched-signal=up,Write original_signal to status */
6004a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein}
6005a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein
6006de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_link_int_ack(struct link_params *params,
60073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       struct link_vars *vars, u8 is_10g_plus)
6008b1607af526fd408b244c7b32a0c256c1ef163a17Eilon Greenstein{
6009e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x *bp = params->bp;
6010de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
60113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 mask;
60122cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
60132cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * First reset all status we assume only one line will be
60142cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * change at a time
60152cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
6016de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
6017cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       (NIG_STATUS_XGXS0_LINK10G |
6018cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_STATUS_XGXS0_LINK_STATUS |
6019cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_STATUS_SERDES0_LINK_STATUS));
6020de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->phy_link_up) {
60213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (USES_WARPCORE(bp))
60223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			mask = NIG_STATUS_XGXS0_LINK_STATUS;
60233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else {
60243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			if (is_10g_plus)
60253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				mask = NIG_STATUS_XGXS0_LINK10G;
60263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			else if (params->switch_cfg == SWITCH_CFG_10G) {
60273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				/*
60283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 * Disable the link interrupt by writing 1 to
60293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 * the relevant lane in the status register
60303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 */
60313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				u32 ser_lane =
60323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					((params->lane_config &
6033de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
6034de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
60353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				mask = ((1 << ser_lane) <<
60363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       NIG_STATUS_XGXS0_LINK_STATUS_SIZE);
60373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			} else
60383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				mask = NIG_STATUS_SERDES0_LINK_STATUS;
6039de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
60403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Ack link up interrupt with mask 0x%x\n",
60413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       mask);
60423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_bits_en(bp,
60433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
60443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			      mask);
6045ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
6046ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
6047ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6048fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_format_ver(u32 num, u8 *str, u16 *len)
6049de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6050de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 *str_ptr = str;
6051de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 mask = 0xf0000000;
6052de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 shift = 8*4;
6053de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 digit;
6054a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u8 remove_leading_zeros = 1;
6055de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (*len < 10) {
6056de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Need more than 10chars for this format */
6057de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*str_ptr = '\0';
6058a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		(*len)--;
6059de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
6060ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
6061de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	while (shift > 0) {
6062ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6063de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		shift -= 4;
6064de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		digit = ((num & mask) >> shift);
6065a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (digit == 0 && remove_leading_zeros) {
6066a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			mask = mask >> 4;
6067a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			continue;
6068a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		} else if (digit < 0xa)
6069de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			*str_ptr = digit + '0';
6070de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
6071de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			*str_ptr = digit - 0xa + 'a';
6072a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		remove_leading_zeros = 0;
6073de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		str_ptr++;
6074a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		(*len)--;
6075de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mask = mask >> 4;
6076de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (shift == 4*4) {
6077a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			*str_ptr = '.';
6078de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			str_ptr++;
6079a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			(*len)--;
6080a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			remove_leading_zeros = 1;
6081ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
6082ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
6083de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
6084ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
6085ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6086a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
6087fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_null_format_ver(u32 spirom_ver, u8 *str, u16 *len)
6088ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
6089de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[0] = '\0';
6090de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	(*len)--;
6091de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
6092de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
6093ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6094a1e785e02bb53573443c7e58a444cef1a049f6ceMintz Yuvalint bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 *version,
6095a1e785e02bb53573443c7e58a444cef1a049f6ceMintz Yuval				 u16 len)
6096de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6097de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp;
6098de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 spirom_ver = 0;
6099fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int status = 0;
6100de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 *ver_p = version;
6101a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u16 remain_len = len;
6102de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (version == NULL || params == NULL)
6103de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
6104de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bp = params->bp;
6105ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6106de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Extract first external phy*/
6107de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	version[0] = '\0';
6108de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	spirom_ver = REG_RD(bp, params->phy[EXT_PHY1].ver_addr);
6109ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6110a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (params->phy[EXT_PHY1].format_fw_ver) {
6111de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		status |= params->phy[EXT_PHY1].format_fw_ver(spirom_ver,
6112de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner							      ver_p,
6113a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner							      &remain_len);
6114a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		ver_p += (len - remain_len);
6115a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
6116a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if ((params->num_phys == MAX_PHYS) &&
6117a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	    (params->phy[EXT_PHY2].ver_addr != 0)) {
6118cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		spirom_ver = REG_RD(bp, params->phy[EXT_PHY2].ver_addr);
6119a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (params->phy[EXT_PHY2].format_fw_ver) {
6120a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			*ver_p = '/';
6121a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			ver_p++;
6122a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			remain_len--;
6123a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			status |= params->phy[EXT_PHY2].format_fw_ver(
6124a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				spirom_ver,
6125a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				ver_p,
6126a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				&remain_len);
6127a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			ver_p = version + (len - remain_len);
6128a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
6129a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
6130a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	*ver_p = '\0';
6131de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return status;
61326bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner}
6133ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
6134de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_set_xgxs_loopback(struct bnx2x_phy *phy,
6135de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    struct link_params *params)
6136589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein{
6137de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
6138589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	struct bnx2x *bp = params->bp;
6139589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6140de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed != SPEED_1000) {
61413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u32 md_devad = 0;
6142589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6143de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
6144589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
61453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (!CHIP_IS_E3(bp)) {
61463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* change the uni_phy_addr in the nig */
61473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
61483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					       port*0x18));
6149cc1cb004dfa27c63b43941076b490045a43d5fbdEilon Greenstein
61503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
61513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       0x5);
61523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
6153589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6154de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
6155cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 5,
6156cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 (MDIO_REG_BANK_AER_BLOCK +
6157cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (MDIO_AER_BLOCK_AER_REG & 0xf)),
6158cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0x2800);
6159589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6160de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
6161cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 5,
6162cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 (MDIO_REG_BANK_CL73_IEEEB0 +
6163cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  (MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
6164cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0x6041);
6165de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(200);
6166de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* set aer mmd back */
6167ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner		bnx2x_set_aer_mmd(params, phy);
6168589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
61693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (!CHIP_IS_E3(bp)) {
61703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* and md_devad */
61713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
61723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			       md_devad);
61733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
6174de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
6175de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 mii_ctrl;
6176de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
6177de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy, 5,
6178de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				(MDIO_REG_BANK_COMBO_IEEE0 +
6179de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				(MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
6180de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&mii_ctrl);
6181de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy, 5,
6182de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 (MDIO_REG_BANK_COMBO_IEEE0 +
6183de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 (MDIO_COMBO_IEEE0_MII_CONTROL & 0xf)),
6184de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 mii_ctrl |
6185de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK);
6186de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6187589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
6188589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6189fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_set_led(struct link_params *params,
6190fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner		  struct link_vars *vars, u8 mode, u32 speed)
61914d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
6192de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
6193de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 hw_led_mode = params->hw_led_mode;
6194fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
6195fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	u8 phy_idx;
6196de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 tmp;
6197de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
6198589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	struct bnx2x *bp = params->bp;
6199de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
6200de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
6201de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 speed, hw_led_mode);
62027f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	/* In case */
62037f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	for (phy_idx = EXT_PHY1; phy_idx < MAX_PHYS; phy_idx++) {
62047f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if (params->phy[phy_idx].set_link_led) {
62057f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			params->phy[phy_idx].set_link_led(
62067f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner				&params->phy[phy_idx], params, mode);
62077f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		}
62087f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	}
62097f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
6210de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (mode) {
62117f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_FRONT_PANEL_OFF:
6212de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case LED_MODE_OFF:
6213de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
6214de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6215cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       SHARED_HW_CFG_LED_MAC1);
6216589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6217de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
6218001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner		if (params->phy[EXT_PHY1].type ==
62199379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE)
62209379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			tmp &= ~(EMAC_LED_1000MB_OVERRIDE |
62219379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner				EMAC_LED_100MB_OVERRIDE |
62229379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner				EMAC_LED_10MB_OVERRIDE);
62239379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner		else
62249379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			tmp |= EMAC_LED_OVERRIDE;
62259379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner
62269379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner		EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp);
6227de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
6228589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6229de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case LED_MODE_OPER:
62302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
62317f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		 * For all other phys, OPER mode is same as ON, so in case
62327f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		 * link is down, do nothing
62332cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
62347f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if (!vars->link_up)
62357f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			break;
62367f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_ON:
6237e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		if (((params->phy[EXT_PHY1].type ==
6238e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) ||
6239e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner			 (params->phy[EXT_PHY1].type ==
6240e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner			  PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722)) &&
62411f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner		    CHIP_IS_E2(bp) && params->num_phys == 2) {
62422cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
62432cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * This is a work-around for E2+8727 Configurations
62442cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
62451f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner			if (mode == LED_MODE_ON ||
62461f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner				speed == SPEED_10000){
62471f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
62481f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner				REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
62491f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner
62501f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner				tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
62511f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner				EMAC_WR(bp, EMAC_REG_EMAC_LED,
62521f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner					(tmp | EMAC_LED_OVERRIDE));
6253793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				/*
6254793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				 * return here without enabling traffic
6255ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner				 * LED blink and setting rate in ON mode.
6256793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				 * In oper mode, enabling LED blink
6257793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				 * and setting rate is needed.
6258793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				 */
6259793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				if (mode == LED_MODE_ON)
6260793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner					return rc;
62611f48353a3ce7297f5150b47e21df5ec212876e5dYaniv Rosner			}
6262793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner		} else if (SINGLE_MEDIA_DIRECT(params)) {
62632cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
62642cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * This is a work-around for HW issue found when link
62652cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * is up in CL73
62662cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6267ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner			if ((!CHIP_IS_E3(bp)) ||
6268ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner			    (CHIP_IS_E3(bp) &&
6269ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner			     mode == LED_MODE_ON))
6270ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner				REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 1);
6271ab505dec96340946079d1288f49041bea9f259ffYaniv Rosner
6272793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner			if (CHIP_IS_E1x(bp) ||
6273793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner			    CHIP_IS_E2(bp) ||
6274793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner			    (mode == LED_MODE_ON))
6275793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6276793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner			else
6277793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6278793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner				       hw_led_mode);
6279001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner		} else if ((params->phy[EXT_PHY1].type ==
6280001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE) &&
62819379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			   (mode == LED_MODE_ON)) {
6282001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, 0);
6283001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner			tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
62849379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			EMAC_WR(bp, EMAC_REG_EMAC_LED, tmp |
62859379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner				EMAC_LED_OVERRIDE | EMAC_LED_1000MB_OVERRIDE);
62869379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			/* Break here; otherwise, it'll disable the
62879379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			 * intended override.
62889379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			 */
62899379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			break;
6290793bd450370bf85cd63cccaff5e2f1a62908a52fYaniv Rosner		} else
6291001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner			REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
6292001cea77b98f912050b8ea8995253fdbe7333fb6Yaniv Rosner			       hw_led_mode);
6293589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6294cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 + port*4, 0);
6295de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Set blinking rate to ~15.9Hz */
629626ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner		if (CHIP_IS_E3(bp))
629726ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
629826ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner			       LED_BLINK_RATE_VAL_E3);
629926ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner		else
630026ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
630126ffaf36c8e0a0eefb6ff031d6166b5ee82eb3deYaniv Rosner			       LED_BLINK_RATE_VAL_E1X_E2);
6302de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
6303cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       port*4, 1);
63049379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
63059379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner		EMAC_WR(bp, EMAC_REG_EMAC_LED,
63069379c9be4b20d5cb7bde577f402b749cd7d3caa2Yaniv Rosner			(tmp & (~EMAC_LED_OVERRIDE)));
6307589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6308de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (CHIP_IS_E1(bp) &&
6309de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    ((speed == SPEED_2500) ||
6310de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     (speed == SPEED_1000) ||
6311de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     (speed == SPEED_100) ||
6312de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     (speed == SPEED_10))) {
63132cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
63142cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * On Everest 1 Ax chip versions for speeds less than
63152cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * 10G LED scheme is different
63162cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6317de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
6318cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       + port*4, 1);
6319de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
6320cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       port*4, 0);
6321de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
6322cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       port*4, 1);
6323de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
6324de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
6325589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6326de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
6327de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		rc = -EINVAL;
6328de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
6329de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 mode);
6330de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
6331589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	}
6332de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return rc;
6333589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
63344d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein}
63354d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
63362cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/*
6337a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner * This function comes to reflect the actual link state read DIRECTLY from the
6338a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner * HW
6339a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner */
6340fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_test_link(struct link_params *params, struct link_vars *vars,
6341fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner		    u8 is_serdes)
63424d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
63434d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	struct bnx2x *bp = params->bp;
6344de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 gp_status = 0, phy_index = 0;
6345a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u8 ext_phy_link_up = 0, serdes_phy_type;
6346a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	struct link_vars temp_vars;
63473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x_phy *int_phy = &params->phy[INT_PHY];
63483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
63493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
63503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u16 link_up;
63513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (params->req_line_speed[LINK_CONFIG_IDX(INT_PHY)]
63523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    > SPEED_10000) {
63533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Check 20G link */
63543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
63553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					1, &link_up);
63563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
63573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					1, &link_up);
63583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			link_up &= (1<<2);
63593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		} else {
63603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Check 10G link and below*/
63613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			u8 lane = bnx2x_get_warpcore_lane(int_phy, params);
63623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			bnx2x_cl45_read(bp, int_phy, MDIO_WC_DEVAD,
63633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					MDIO_WC_REG_GP2_STATUS_GP_2_1,
63643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					&gp_status);
63653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			gp_status = ((gp_status >> 8) & 0xf) |
63663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				((gp_status >> 12) & 0xf);
63673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			link_up = gp_status & (1 << lane);
63683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
63693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (!link_up)
63703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return -ESRCH;
63713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
63723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		CL22_RD_OVER_CL45(bp, int_phy,
6373cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_REG_BANK_GP_STATUS,
6374cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  MDIO_GP_STATUS_TOP_AN_STATUS1,
6375cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  &gp_status);
6376de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* link is up only if both local phy and external phy are up */
6377a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (!(gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS))
6378a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return -ESRCH;
63793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
63803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* In XGXS loopback mode, do not check external PHY */
63813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (params->loopback_mode == LOOPBACK_XGXS)
63823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return 0;
6383a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
6384a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	switch (params->num_phys) {
6385a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case 1:
6386a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* No external PHY */
6387a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return 0;
6388a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case 2:
6389a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		ext_phy_link_up = params->phy[EXT_PHY1].read_status(
6390a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			&params->phy[EXT_PHY1],
6391a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			params, &temp_vars);
6392a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
6393a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case 3: /* Dual Media */
6394de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6395de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      phy_index++) {
6396a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			serdes_phy_type = ((params->phy[phy_index].media_type ==
6397a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					    ETH_PHY_SFP_FIBER) ||
6398a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					   (params->phy[phy_index].media_type ==
63991ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner					    ETH_PHY_XFP_FIBER) ||
64001ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner					   (params->phy[phy_index].media_type ==
64011ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner					    ETH_PHY_DA_TWINAX));
6402a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
6403a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			if (is_serdes != serdes_phy_type)
6404a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				continue;
6405a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			if (params->phy[phy_index].read_status) {
6406a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				ext_phy_link_up |=
6407de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					params->phy[phy_index].read_status(
6408de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						&params->phy[phy_index],
6409de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						params, &temp_vars);
6410a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			}
6411de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
6412a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
64134d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	}
6414a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (ext_phy_link_up)
6415a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return 0;
6416de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -ESRCH;
6417de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
64184d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6419fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_link_initialize(struct link_params *params,
6420fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				 struct link_vars *vars)
6421de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6422fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
6423de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 phy_index, non_ext_phy;
6424de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
64252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
64262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * In case of external phy existence, the line speed would be the
64272cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * line speed linked up by the external phy. In case it is direct
64282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * only, then the line_speed during initialization will be
64292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * equal to the req_line_speed
64302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
6431de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->line_speed = params->phy[INT_PHY].req_line_speed;
64324d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
64332cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
6434de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * Initialize the internal phy in case this is a direct board
6435de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * (no external phys), or this board has external phy which requires
6436de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * to first.
6437de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
64383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (!USES_WARPCORE(bp))
64393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_prepare_xgxs(&params->phy[INT_PHY], params, vars);
6440de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* init ext phy and enable link state int */
6441de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	non_ext_phy = (SINGLE_MEDIA_DIRECT(params) ||
6442de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		       (params->loopback_mode == LOOPBACK_XGXS));
64434d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6444de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (non_ext_phy ||
6445de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (params->phy[EXT_PHY1].flags & FLAGS_INIT_XGXS_FIRST) ||
6446de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (params->loopback_mode == LOOPBACK_EXT_PHY)) {
6447de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		struct bnx2x_phy *phy = &params->phy[INT_PHY];
64483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (vars->line_speed == SPEED_AUTO_NEG &&
64493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		    (CHIP_IS_E1x(bp) ||
64503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		     CHIP_IS_E2(bp)))
6451de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_set_parallel_detection(phy, params);
6452ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner			if (params->phy[INT_PHY].config_init)
6453ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner				params->phy[INT_PHY].config_init(phy,
6454ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner								 params,
6455ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner								 vars);
64564d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	}
64574d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6458de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Init external phy*/
6459fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner	if (non_ext_phy) {
6460fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner		if (params->phy[INT_PHY].supported &
6461fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner		    SUPPORTED_FIBRE)
6462fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			vars->link_status |= LINK_STATUS_SERDES_LINK;
6463fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner	} else {
6464de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6465de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      phy_index++) {
64662cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
6467a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * No need to initialize second phy in case of first
6468a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * phy only selection. In case of second phy, we do
6469a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * need to initialize the first phy, since they are
6470a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * connected.
64712cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6472fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			if (params->phy[phy_index].supported &
6473fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			    SUPPORTED_FIBRE)
6474fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner				vars->link_status |= LINK_STATUS_SERDES_LINK;
6475fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner
6476a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			if (phy_index == EXT_PHY2 &&
6477a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			    (bnx2x_phy_selection(params) ==
6478a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			     PORT_HW_CFG_PHY_SELECTION_FIRST_PHY)) {
647994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				DP(NETIF_MSG_LINK,
648094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				   "Not initializing second phy\n");
6481a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				continue;
6482a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			}
6483de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params->phy[phy_index].config_init(
6484de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&params->phy[phy_index],
6485de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				params, vars);
6486de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
6487fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner	}
6488de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Reset the interrupt indication after phy was initialized */
6489de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 +
6490de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		       params->port*4,
6491de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		       (NIG_STATUS_XGXS0_LINK10G |
6492de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			NIG_STATUS_XGXS0_LINK_STATUS |
6493de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			NIG_STATUS_SERDES0_LINK_STATUS |
6494de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			NIG_MASK_MI_INT));
6495fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner	bnx2x_update_mng(params, vars->link_status);
6496de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return rc;
6497de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
64984d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6499de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_int_link_reset(struct bnx2x_phy *phy,
6500de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_params *params)
6501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6502de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* reset the SerDes/XGXS */
6503cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	REG_WR(params->bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
6504cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (0x1ff << (params->port*16)));
6505589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
6506589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6507de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_common_ext_link_reset(struct bnx2x_phy *phy,
6508de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					struct link_params *params)
65094d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
6510de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
6511de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 gpio_port;
6512de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* HW reset */
6513f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (CHIP_IS_E2(bp))
6514f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = BP_PATH(bp);
6515f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
6516f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = params->port;
6517de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6518cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
6519cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       gpio_port);
6520de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
6521cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
6522cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       gpio_port);
6523de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "reset external PHY\n");
65244d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein}
6525589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6526fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_update_link_down(struct link_params *params,
6527fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
6528589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein{
6529589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	struct bnx2x *bp = params->bp;
6530de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
6531589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6532de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
65337f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
65343deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	vars->phy_flags &= ~PHY_PHYSICAL_LINK_FLAG;
6535de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* indicate no mac active */
6536de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->mac_type = MAC_TYPE_NONE;
6537ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
6538de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* update shared memory */
6539fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner	vars->link_status &= ~(LINK_STATUS_SPEED_AND_DUPLEX_MASK |
6540fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			       LINK_STATUS_LINK_UP |
6541de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			       LINK_STATUS_PHYSICAL_LINK_FLAG |
6542fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			       LINK_STATUS_AUTO_NEGOTIATE_COMPLETE |
6543fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			       LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK |
6544fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			       LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK |
65459e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			       LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK |
65469e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			       LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE |
65479e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			       LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE);
6548de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->line_speed = 0;
6549de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_update_mng(params, vars->link_status);
6550589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6551de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* activate nig drain */
6552de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
65534d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6554de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable emac */
65559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp))
65569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
6557de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6558de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(10);
65599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/* reset BigMac/Xmac */
65609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (CHIP_IS_E1x(bp) ||
65619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	    CHIP_IS_E2(bp)) {
65629380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_bmac_rx_disable(bp, params->port);
65639380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, GRCBASE_MISC +
65649380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		       MISC_REGISTERS_RESET_REG_2_CLEAR,
6565cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
65669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
6567ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	if (CHIP_IS_E3(bp)) {
65689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_xmac_disable(params);
6569ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		bnx2x_umac_disable(params);
6570ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	}
65719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
6572589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	return 0;
6573589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
6574de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6575fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_update_link_up(struct link_params *params,
6576fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				struct link_vars *vars,
6577fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				u8 link_10g)
6578589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein{
6579589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	struct bnx2x *bp = params->bp;
6580de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
6581fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
65824d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6583de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	vars->link_status |= (LINK_STATUS_LINK_UP |
6584de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			      LINK_STATUS_PHYSICAL_LINK_FLAG);
65853deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	vars->phy_flags |= PHY_PHYSICAL_LINK_FLAG;
65867f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
6587de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
6588de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_status |=
6589de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
6590589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6591de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
6592de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_status |=
6593de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
65949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (USES_WARPCORE(bp)) {
65953deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		if (link_10g) {
65963deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			if (bnx2x_xmac_enable(params, vars, 0) ==
65973deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			    -ESRCH) {
65983deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				DP(NETIF_MSG_LINK, "Found errors on XMAC\n");
65993deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->link_up = 0;
66003deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
66013deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->link_status &= ~LINK_STATUS_LINK_UP;
66023deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			}
66033deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		} else
66049380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_umac_enable(params, vars, 0);
66057f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		bnx2x_set_led(params, vars,
66069380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			      LED_MODE_OPER, vars->line_speed);
66079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
66089380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if ((CHIP_IS_E1x(bp) ||
66099380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	     CHIP_IS_E2(bp))) {
66109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (link_10g) {
66113deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			if (bnx2x_bmac_enable(params, vars, 0) ==
66123deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			    -ESRCH) {
66133deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				DP(NETIF_MSG_LINK, "Found errors on BMAC\n");
66143deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->link_up = 0;
66153deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
66163deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				vars->link_status &= ~LINK_STATUS_LINK_UP;
66173deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			}
6618cc1cb004dfa27c63b43941076b490045a43d5fbdEilon Greenstein
66199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_set_led(params, vars,
66209380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				      LED_MODE_OPER, SPEED_10000);
66219380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		} else {
66229380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			rc = bnx2x_emac_program(params, vars);
66239380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_emac_enable(params, vars, 0);
66249380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
66259380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			/* AN complete? */
66269380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			if ((vars->link_status &
66279380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			     LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
66289380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			    && (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
66299380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			    SINGLE_MEDIA_DIRECT(params))
66309380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				bnx2x_set_gmii_tx_driver(params);
66319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
6632de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6633cc1cb004dfa27c63b43941076b490045a43d5fbdEilon Greenstein
6634de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* PBF - link up */
66359380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (CHIP_IS_E1x(bp))
6636f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
6637f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				       vars->line_speed);
6638589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6639de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable drain */
6640de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
6641589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6642de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* update shared memory */
6643de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_update_mng(params, vars->link_status);
6644de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(20);
6645de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return rc;
6646589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
66472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/*
6648de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * The bnx2x_link_update function should be called upon link
6649de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * interrupt.
6650de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * Link is considered up as follows:
6651de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * - DIRECT_SINGLE_MEDIA - Only XGXS link (internal link) needs
6652de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner *   to be up
6653de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * - SINGLE_MEDIA - The link between the 577xx and the external
6654de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner *   phy (XGXS) need to up as well as the external link of the
6655de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner *   phy (PHY_EXT1)
6656de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner * - DUAL_MEDIA - The link between the 577xx and the first
6657de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner *   external phy needs to be up, and at least one of the 2
6658de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner *   external phy link must be up.
6659de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner */
6660fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_link_update(struct link_params *params, struct link_vars *vars)
66614d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
6662de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
6663de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct link_vars phy_vars[MAX_PHYS];
6664de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port = params->port;
66653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 link_10g_plus, phy_index;
6666fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	u8 ext_phy_link_up = 0, cur_link_up;
6667fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
6668de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 is_mi_int = 0;
6669de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 ext_phy_line_speed = 0, prev_line_speed = vars->line_speed;
6670de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 active_external_phy = INT_PHY;
66713deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
6672de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (phy_index = INT_PHY; phy_index < params->num_phys;
6673de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	      phy_index++) {
6674de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].flow_ctrl = 0;
6675de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].link_status = 0;
6676de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].line_speed = 0;
6677de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].duplex = DUPLEX_FULL;
6678de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].phy_link_up = 0;
6679de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_vars[phy_index].link_up = 0;
6680c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		phy_vars[phy_index].fault_detected = 0;
6681de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
66824d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
66833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (USES_WARPCORE(bp))
66843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_aer_mmd(params, &params->phy[INT_PHY]);
66853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
6686de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
6687de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 port, (vars->phy_flags & PHY_XGXS_FLAG),
6688de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
66894d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6690de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	is_mi_int = (u8)(REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT +
6691cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				port*0x18) > 0);
6692de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
6693de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
6694de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 is_mi_int,
6695cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
66964d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6697de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
6698de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
6699de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
67004d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6701de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable emac */
67029380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp))
67039380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
67044d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
67052cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
67062cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Step 1:
67072cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Check external link change only for external phys, and apply
67082cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * priority selection between them in case the link on both phys
67099045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	 * is up. Note that instead of the common vars, a temporary
67102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * vars argument is used since each phy may have different link/
67112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * speed/duplex result
67122cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
6713de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6714de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	      phy_index++) {
6715de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		struct bnx2x_phy *phy = &params->phy[phy_index];
6716de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!phy->read_status)
6717de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			continue;
6718de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Read link status and params of this ext phy */
6719de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		cur_link_up = phy->read_status(phy, params,
6720de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					       &phy_vars[phy_index]);
6721de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (cur_link_up) {
6722de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "phy in index %d link is up\n",
6723de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   phy_index);
6724de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else {
6725de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "phy in index %d link is down\n",
6726de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   phy_index);
6727de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			continue;
6728de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
6729e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
6730de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!ext_phy_link_up) {
6731de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			ext_phy_link_up = 1;
6732de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			active_external_phy = phy_index;
6733a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		} else {
6734a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			switch (bnx2x_phy_selection(params)) {
6735a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
6736a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
67372cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
6738a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * In this option, the first PHY makes sure to pass the
6739a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * traffic through itself only.
6740a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * Its not clear how to reset the link on the second phy
67412cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6742a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				active_external_phy = EXT_PHY1;
6743a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				break;
6744a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
67452cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
6746a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * In this option, the first PHY makes sure to pass the
6747a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * traffic through the second PHY.
67482cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6749a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				active_external_phy = EXT_PHY2;
6750a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				break;
6751a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			default:
67522cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
6753a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * Link indication on both PHYs with the following cases
6754a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * is invalid:
6755a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * - FIRST_PHY means that second phy wasn't initialized,
6756a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * hence its link is expected to be down
6757a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * - SECOND_PHY means that first phy should not be able
6758a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * to link up by itself (using configuration)
6759a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 * - DEFAULT should be overriden during initialiazation
67602cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
6761a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				DP(NETIF_MSG_LINK, "Invalid link indication"
6762a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					   "mpc=0x%x. DISABLING LINK !!!\n",
6763a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					   params->multi_phy_config);
6764a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				ext_phy_link_up = 0;
6765a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				break;
6766a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			}
6767589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein		}
6768589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	}
6769de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	prev_line_speed = vars->line_speed;
67702cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
67712cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Step 2:
67722cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Read the status of the internal phy. In case of
67732cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * DIRECT_SINGLE_MEDIA board, this link is the external link,
67742cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * otherwise this is the link between the 577xx and the first
67752cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * external phy
67762cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
6777de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (params->phy[INT_PHY].read_status)
6778de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		params->phy[INT_PHY].read_status(
6779de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&params->phy[INT_PHY],
6780de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params, vars);
67812cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
6782de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * The INT_PHY flow control reside in the vars. This include the
6783de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * case where the speed or flow control are not set to AUTO.
6784de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * Otherwise, the active external phy flow control result is set
6785de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * to the vars. The ext_phy_line_speed is needed to check if the
6786de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * speed is different between the internal phy and external phy.
6787de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * This case may be result of intermediate link speed change.
67884d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	 */
6789de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (active_external_phy > INT_PHY) {
6790de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = phy_vars[active_external_phy].flow_ctrl;
67912cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
6792de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * Link speed is taken from the XGXS. AN and FC result from
6793de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * the external phy.
67944d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		 */
6795de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_status |= phy_vars[active_external_phy].link_status;
6796a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
67972cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
6798a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * if active_external_phy is first PHY and link is up - disable
6799a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * disable TX on second external PHY
6800a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 */
6801a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (active_external_phy == EXT_PHY1) {
6802a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			if (params->phy[EXT_PHY2].phy_specific_func) {
680394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				DP(NETIF_MSG_LINK,
680494f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				   "Disabling TX on EXT_PHY2\n");
6805a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				params->phy[EXT_PHY2].phy_specific_func(
6806a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					&params->phy[EXT_PHY2],
6807a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					params, DISABLE_TX);
6808a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			}
6809a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
6810a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
6811de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		ext_phy_line_speed = phy_vars[active_external_phy].line_speed;
6812de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->duplex = phy_vars[active_external_phy].duplex;
6813de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (params->phy[active_external_phy].supported &
6814de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    SUPPORTED_FIBRE)
6815de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->link_status |= LINK_STATUS_SERDES_LINK;
6816fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner		else
6817fd36a2e69e05f42ddfe388efe14e068c0d0c6cb7Yaniv Rosner			vars->link_status &= ~LINK_STATUS_SERDES_LINK;
6818de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Active external phy selected: %x\n",
6819de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   active_external_phy);
6820de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6821a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
6822a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	for (phy_index = EXT_PHY1; phy_index < params->num_phys;
6823a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	      phy_index++) {
6824a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (params->phy[phy_index].flags &
6825a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		    FLAGS_REARM_LATCH_SIGNAL) {
6826a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			bnx2x_rearm_latch_signal(bp, port,
6827a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner						 phy_index ==
6828a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner						 active_external_phy);
6829a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			break;
6830a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
6831a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
6832de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "vars->flow_ctrl = 0x%x, vars->link_status = 0x%x,"
6833de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   " ext_phy_line_speed = %d\n", vars->flow_ctrl,
6834de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   vars->link_status, ext_phy_line_speed);
68352cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
6836de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * Upon link speed change set the NIG into drain mode. Comes to
6837de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * deals with possible FIFO glitch due to clk change when speed
6838de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * is decreased without link down indicator
6839de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
68404d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6841de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->phy_link_up) {
6842de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(SINGLE_MEDIA_DIRECT(params)) && ext_phy_link_up &&
6843de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    (ext_phy_line_speed != vars->line_speed)) {
6844de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "Internal link speed %d is"
6845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   " different than the external"
6846de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   " link speed %d\n", vars->line_speed,
6847de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   ext_phy_line_speed);
6848de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->phy_link_up = 0;
6849de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else if (prev_line_speed != vars->line_speed) {
6850cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4,
6851cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       0);
6852de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			msleep(1);
6853de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
6854de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6855e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
6856de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* anything 10 and over uses the bmac */
68573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	link_10g_plus = (vars->line_speed >= SPEED_10000);
6858589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
68593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_link_int_ack(params, vars, link_10g_plus);
6860589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
68612cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
68622cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * In case external phy link is up, and internal link is down
68632cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * (not initialized yet probably after link initialization, it
68642cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * needs to be initialized.
68652cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Note that after link down-up as result of cable plug, the xgxs
68662cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * link would probably become up again without the need
68672cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * initialize it
68682cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
6869de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (!(SINGLE_MEDIA_DIRECT(params))) {
6870de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "ext_phy_link_up = %d, int_link_up = %d,"
6871de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   " init_preceding = %d\n", ext_phy_link_up,
6872de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   vars->phy_link_up,
6873de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->phy[EXT_PHY1].flags &
6874de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   FLAGS_INIT_XGXS_FIRST);
6875de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(params->phy[EXT_PHY1].flags &
6876de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      FLAGS_INIT_XGXS_FIRST)
6877de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    && ext_phy_link_up && !vars->phy_link_up) {
6878de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->line_speed = ext_phy_line_speed;
6879de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			if (vars->line_speed < SPEED_1000)
6880de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->phy_flags |= PHY_SGMII_FLAG;
6881de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			else
6882de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->phy_flags &= ~PHY_SGMII_FLAG;
6883ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner
6884ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner			if (params->phy[INT_PHY].config_init)
6885ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner				params->phy[INT_PHY].config_init(
6886ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner					&params->phy[INT_PHY], params,
6887de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						vars);
68884d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		}
6889589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	}
68902cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
68912cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Link is up only if both local phy and external phy (in case of
68929045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	 * non-direct board) are up and no fault detected on active PHY.
68934d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	 */
6894de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->link_up = (vars->phy_link_up &&
6895de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 (ext_phy_link_up ||
6896c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			  SINGLE_MEDIA_DIRECT(params)) &&
6897c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			 (phy_vars[active_external_phy].fault_detected == 0));
6898de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
689927d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner	/* Update the PFC configuration in case it was changed */
690027d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
690127d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		vars->link_status |= LINK_STATUS_PFC_ENABLED;
690227d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner	else
690327d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
690427d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner
6905de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (vars->link_up)
69063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		rc = bnx2x_update_link_up(params, vars, link_10g_plus);
69074d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	else
6908de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		rc = bnx2x_update_link_down(params, vars);
6909589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
69104d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	return rc;
6911589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
6912589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6913de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*****************************************************************************/
6914de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			    External Phy section			     */
6915de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*****************************************************************************/
6916de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnervoid bnx2x_ext_phy_hw_reset(struct bnx2x *bp, u8 port)
6917de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6918de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6919cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
6920de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(1);
6921de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
6922cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
6923de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
6924589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6925de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_save_spirom_version(struct bnx2x *bp, u8 port,
6926de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      u32 spirom_ver, u32 ver_addr)
6927de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6928de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "FW version 0x%x:0x%x for port %d\n",
6929de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 (u16)(spirom_ver>>16), (u16)spirom_ver, port);
69304d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
6931de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (ver_addr)
6932de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		REG_WR(bp, ver_addr, spirom_ver);
6933589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
6934589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
6935de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_save_bcm_spirom_ver(struct bnx2x *bp,
6936de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      struct bnx2x_phy *phy,
6937de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      u8 port)
69386bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner{
6939de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 fw_ver1, fw_ver2;
6940de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6941de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6942cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_ROM_VER1, &fw_ver1);
6943de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
6944cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_ROM_VER2, &fw_ver2);
6945de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_spirom_version(bp, port, (u32)(fw_ver1<<16 | fw_ver2),
6946de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  phy->ver_addr);
6947ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
6948ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
6949de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_ext_phy_10G_an_resolve(struct bnx2x *bp,
6950de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       struct bnx2x_phy *phy,
6951de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       struct link_vars *vars)
6952de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6953de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val;
6954de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
6955de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD,
6956de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_REG_STATUS, &val);
6957de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
6958de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD,
6959de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_REG_STATUS, &val);
6960de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (val & (1<<5))
6961de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_status |= LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
6962de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((val & (1<<0)) == 0)
6963de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_status |= LINK_STATUS_PARALLEL_DETECTION_USED;
6964de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
6965de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6966de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
6967de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*		common BCM8073/BCM8727 PHY SECTION		  */
6968de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
6969de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8073_resolve_fc(struct bnx2x_phy *phy,
6970de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_params *params,
6971de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_vars *vars)
6972de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
6973de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
6974de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed == SPEED_10 ||
6975de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    phy->req_line_speed == SPEED_100) {
6976de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = phy->req_flow_ctrl;
6977de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return;
6978de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
6979de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6980de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_ext_phy_resolve_fc(phy, params, vars) &&
6981de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE)) {
6982de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 pause_result;
6983de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 ld_pause;		/* local */
6984de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 lp_pause;		/* link partner */
6985de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
6986de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_DEVAD,
6987de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_REG_CL37_FC_LD, &ld_pause);
6988de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6989de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
6990de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_DEVAD,
6991de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_REG_CL37_FC_LP, &lp_pause);
6992de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		pause_result = (ld_pause &
6993de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
6994de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		pause_result |= (lp_pause &
6995de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
6996de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
6997de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_pause_resolve(vars, pause_result);
6998de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x\n",
6999de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   pause_result);
7000de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7001de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7002fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8073_8727_external_rom_boot(struct bnx2x *bp,
7003fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     struct bnx2x_phy *phy,
7004fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     u8 port)
7005de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
70065c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	u32 count = 0;
70075c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	u16 fw_ver1, fw_msgout;
7008fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
70095c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
7010de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Boot port from external ROM  */
7011de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* EDC grst */
7012de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7013cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7014cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
7015cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 0x0001);
7016de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7017de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* ucode reboot and rst */
7018de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7019cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7020cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
7021cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 0x008c);
7022de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7023de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7024cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7025cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
7026de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7027de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Reset internal microprocessor */
7028de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7029cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7030cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
7031cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
7032de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7033de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Release srst bit */
7034de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7035cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7036cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
7037cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
7038de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
70395c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	/* Delay 100ms per the PHY specifications */
70405c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	msleep(100);
70415c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
70425c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	/* 8073 sometimes taking longer to download */
70435c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	do {
70445c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		count++;
70455c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		if (count > 300) {
70465c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner			DP(NETIF_MSG_LINK,
70475c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				 "bnx2x_8073_8727_external_rom_boot port %x:"
70485c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				 "Download failed. fw version = 0x%x\n",
70495c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				 port, fw_ver1);
70505c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner			rc = -EINVAL;
70515c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner			break;
70525c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		}
70535c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
70545c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		bnx2x_cl45_read(bp, phy,
70555c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				MDIO_PMA_DEVAD,
70565c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				MDIO_PMA_REG_ROM_VER1, &fw_ver1);
70575c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		bnx2x_cl45_read(bp, phy,
70585c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				MDIO_PMA_DEVAD,
70595c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner				MDIO_PMA_REG_M8051_MSGOUT_REG, &fw_msgout);
70605c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
70615c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		msleep(1);
70625c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	} while (fw_ver1 == 0 || fw_ver1 == 0x4321 ||
70635c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner			((fw_msgout & 0xff) != 0x03 && (phy->type ==
70645c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)));
7065de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7066de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Clear ser_boot_ctl bit */
7067de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7068cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7069cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
7070de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_bcm_spirom_ver(bp, phy, port);
70715c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
70725c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	DP(NETIF_MSG_LINK,
70735c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		 "bnx2x_8073_8727_external_rom_boot port %x:"
70745c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		 "Download complete. fw version = 0x%x\n",
70755c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		 port, fw_ver1);
70765c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner
70775c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	return rc;
7078de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7079de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7080de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
7081de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			BCM8073 PHY SECTION			  */
7082de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
7083fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8073_is_snr_needed(struct bnx2x *bp, struct bnx2x_phy *phy)
7084de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7085de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* This is only required for 8073A1, version 102 only */
7086de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val;
7087de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7088de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Read 8073 HW revision*/
7089de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7090cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
7091cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_8073_CHIP_REV, &val);
7092de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7093de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (val != 1) {
7094de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* No need to workaround in 8073 A1 */
7095de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
7096de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7097de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7098de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7099cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
7100cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_ROM_VER2, &val);
7101de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7102de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* SNR should be applied only for version 0x102 */
7103de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (val != 0x102)
7104de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
7105de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7106de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 1;
7107de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7108de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7109fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8073_xaui_wa(struct bnx2x *bp, struct bnx2x_phy *phy)
7110de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7111de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val, cnt, cnt1 ;
7112de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7113de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7114cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
7115cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_8073_CHIP_REV, &val);
7116de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7117de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (val > 0) {
7118de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* No need to workaround in 8073 A1 */
7119de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
7120de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7121de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* XAUI workaround in 8073 A0: */
7122de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
71232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
71242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * After loading the boot ROM and restarting Autoneg, poll
71252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Dev1, Reg $C820:
71262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
7127de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7128de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (cnt = 0; cnt < 1000; cnt++) {
7129de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7130cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7131cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7132cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				&val);
71332cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		  /*
71342cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		   * If bit [14] = 0 or bit [13] = 0, continue on with
71352cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		   * system initialization (XAUI work-around not required, as
71362cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		   * these bits indicate 2.5G or 1G link up).
71372cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		   */
7138de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (!(val & (1<<14)) || !(val & (1<<13))) {
7139de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
7140de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
7141de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else if (!(val & (1<<15))) {
71422cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			DP(NETIF_MSG_LINK, "bit 15 went off\n");
71432cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
71442cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * If bit 15 is 0, then poll Dev1, Reg $C841 until it's
71452cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * MSB (bit15) goes to 1 (indicating that the XAUI
71462cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * workaround has completed), then continue on with
71472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * system initialization.
71482cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
7149de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			for (cnt1 = 0; cnt1 < 1000; cnt1++) {
7150de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				bnx2x_cl45_read(bp, phy,
7151de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_PMA_DEVAD,
7152de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_PMA_REG_8073_XAUI_WA, &val);
7153de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				if (val & (1<<15)) {
7154de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					DP(NETIF_MSG_LINK,
7155de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  "XAUI workaround has completed\n");
7156de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					return 0;
7157de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 }
7158de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 msleep(3);
7159de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			}
7160de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
7161de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
7162de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(3);
7163de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7164de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
7165de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -EINVAL;
7166de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7167de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7168de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_807x_force_10G(struct bnx2x *bp, struct bnx2x_phy *phy)
7169de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7170de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Force KR or KX */
7171de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7172de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
7173de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7174de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0x000b);
7175de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7176de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0000);
7177de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7178de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
7179de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7180de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
71816bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosnerstatic void bnx2x_8073_set_pause_cl37(struct link_params *params,
7182e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				      struct bnx2x_phy *phy,
7183e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				      struct link_vars *vars)
7184ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
71856bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	u16 cl37_val;
7186e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x *bp = params->bp;
7187e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_cl45_read(bp, phy,
718862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &cl37_val);
71896bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
71906bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
71916bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
7192e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
71936bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	if ((vars->ieee_fc &
71946bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
71956bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
71966bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
71976bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
71986bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	if ((vars->ieee_fc &
71996bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
72006bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
72016bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
72026bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
72036bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	if ((vars->ieee_fc &
72046bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
72056bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
72066bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
72076bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
72086bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	DP(NETIF_MSG_LINK,
72096bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
72106bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
7211e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_cl45_write(bp, phy,
721262b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, cl37_val);
72136bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	msleep(500);
7214ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
7215ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7216fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8073_config_init(struct bnx2x_phy *phy,
7217fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
7218fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
7219ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
7220e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x *bp = params->bp;
7221de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val = 0, tmp1;
7222de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 gpio_port;
7223de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Init 8073\n");
7224e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
7225f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (CHIP_IS_E2(bp))
7226f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = BP_PATH(bp);
7227f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
7228f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = params->port;
7229de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Restore normal power mode*/
7230de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7231cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7232e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
7233de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
7234cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, gpio_port);
7235ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7236de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* enable LASI */
7237de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
723860d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL, (1<<2));
7239de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
724060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,  0x0004);
7241c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein
7242de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_8073_set_pause_cl37(params, phy, vars);
724357963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7244e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	bnx2x_cl45_read(bp, phy,
7245de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
72462f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein
7247de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
724860d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
72492f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein
7250de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1): 0x%x\n", tmp1);
7251a1e4be39dc5a8d83102b835a3ee049f2a6057be9Yaniv Rosner
725274d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner	/* Swap polarity if required - Must be done only in non-1G mode */
725374d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner	if (params->lane_config & PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
725474d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		/* Configure the 8073 to swap _P and _N of the KR lines */
725574d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		DP(NETIF_MSG_LINK, "Swapping polarity for the 8073\n");
725674d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		/* 10G Rx/Tx and 1G Tx signal polarity swap */
725774d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		bnx2x_cl45_read(bp, phy,
725874d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				MDIO_PMA_DEVAD,
725974d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL, &val);
726074d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		bnx2x_cl45_write(bp, phy,
726174d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				 MDIO_PMA_DEVAD,
726274d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				 MDIO_PMA_REG_8073_OPT_DIGITAL_CTRL,
726374d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				 (val | (3<<9)));
726474d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner	}
726574d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner
726674d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner
7267de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Enable CL37 BAM */
7268121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner	if (REG_RD(bp, params->shmem_base +
7269121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner			 offsetof(struct shmem_region, dev_info.
7270121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner				  port_hw_config[params->port].default_cfg)) &
7271121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner	    PORT_HW_CFG_ENABLE_BAM_ON_KR_ENABLED) {
727257963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7273121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner		bnx2x_cl45_read(bp, phy,
7274121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner				MDIO_AN_DEVAD,
7275121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner				MDIO_AN_REG_8073_BAM, &val);
7276121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner		bnx2x_cl45_write(bp, phy,
7277121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner				 MDIO_AN_DEVAD,
7278121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner				 MDIO_AN_REG_8073_BAM, val | 1);
7279121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner		DP(NETIF_MSG_LINK, "Enable CL37 BAM on KR\n");
7280121839beac03a127148605931598cd36e1cbeab7Yaniv Rosner	}
7281de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (params->loopback_mode == LOOPBACK_EXT) {
7282de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_807x_force_10G(bp, phy);
7283de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Forced speed 10G on 807X\n");
7284de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
7285de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
7286de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
7287de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_BCM_CTRL, 0x0002);
7288de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7289de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed != SPEED_AUTO_NEG) {
7290de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->req_line_speed == SPEED_10000) {
7291de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val = (1<<7);
7292de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else if (phy->req_line_speed ==  SPEED_2500) {
7293de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val = (1<<5);
72942cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
72952cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * Note that 2.5G works only when used with 1G
729625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi			 * advertisement
72972cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
7298de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else
7299de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val = (1<<5);
7300de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
7301de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		val = 0;
7302de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->speed_cap_mask &
7303de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
7304de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val |= (1<<7);
730557963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
730625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/* Note that 2.5G works only when used with 1G advertisement */
7307de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->speed_cap_mask &
7308de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
7309de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
7310de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val |= (1<<5);
7311de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "807x autoneg val = 0x%x\n", val);
7312de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
731357963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7314de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV, val);
7315de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, &tmp1);
731657963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7317de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (((phy->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
7318de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     (phy->req_line_speed == SPEED_AUTO_NEG)) ||
7319de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (phy->req_line_speed == SPEED_2500)) {
7320de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 phy_ver;
7321de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Allow 2.5G for A1 and above */
7322de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7323de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_CHIP_REV,
7324de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&phy_ver);
7325de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Add 2.5G\n");
7326de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy_ver > 0)
7327de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			tmp1 |= 1;
7328de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
7329de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			tmp1 &= 0xfffe;
7330de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
7331de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Disable 2.5G\n");
7332de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		tmp1 &= 0xfffe;
7333de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
733457963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7335de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_8073_2_5G, tmp1);
7336de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Add support for CL37 (passive mode) II */
733757963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7338de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, &tmp1);
7339de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD,
7340de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 (tmp1 | ((phy->req_duplex == DUPLEX_FULL) ?
7341de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  0x20 : 0x40)));
734257963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7343de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Add support for CL37 (passive mode) III */
7344de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
734557963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
73462cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
73472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The SNR will improve about 2db by changing BW and FEE main
73482cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * tap. Rest commands are executed after link is up
73492cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Change FFE main cursor to 5 in EDC register
73502cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
7351de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_8073_is_snr_needed(bp, phy))
7352de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
7353de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_EDC_FFE_MAIN,
7354de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0xFB0C);
735557963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7356de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Enable FEC (Forware Error Correction) Request in the AN */
7357de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, &tmp1);
7358de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	tmp1 |= (1<<15);
7359de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_ADV2, tmp1);
736057963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7361de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_set_pause(params, phy, vars);
736257963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
7363de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Restart autoneg */
7364de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(500);
7365de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
7366de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "807x Autoneg Restart: Advertise 1G=%x, 10G=%x\n",
7367de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   ((val & (1<<5)) > 0), ((val & (1<<7)) > 0));
7368de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
7369b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
7370ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7371de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8073_read_status(struct bnx2x_phy *phy,
7372b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_params *params,
7373b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_vars *vars)
7374b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7375b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
7376de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up = 0;
7377de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val1, val2;
7378de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 link_status = 0;
7379de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 an1000_status = 0;
7380a35da8dbf1ff403633bb6256fba691b224f17f61Eilon Greenstein
7381de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
738260d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
7383b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7384de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8703 LASI status 0x%x\n", val1);
7385ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7386de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* clear the interrupt LASI status register */
7387de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7388de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7389de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7390de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val1);
7391de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n", val2, val1);
7392de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Clear MSG-OUT */
7393de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7394de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
7395de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7396de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check the LASI */
7397de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
739860d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
7399de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7400de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
7401de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7402de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check the link status */
7403de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7404de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &val2);
7405de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
7406de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7407de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7408de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7409de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7410de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7411de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	link_up = ((val1 & 4) == 4);
7412de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
7413de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7414de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up &&
7415de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     ((phy->req_line_speed != SPEED_10000))) {
7416de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_8073_xaui_wa(bp, phy) != 0)
7417de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
741862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
7419de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7420de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
7421de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7422de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &an1000_status);
742362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7424de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check the link status on 1.1.2 */
7425de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7426de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
7427de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7428de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
7429de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
7430de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   "an_link_status=0x%x\n", val2, val1, an1000_status);
743162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7432de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	link_up = (((val1 & 4) == 4) || (an1000_status & (1<<1)));
7433de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up && bnx2x_8073_is_snr_needed(bp, phy)) {
74342cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
74352cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * The SNR will improve about 2dbby changing the BW and FEE main
74362cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * tap. The 1st write to change FFE main tap is set before
74372cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * restart AN. Change PLL Bandwidth in EDC register
74382cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
743962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_cl45_write(bp, phy,
7440de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PLL_BANDWIDTH,
7441de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x26BC);
744262b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7443de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Change CDR Bandwidth in EDC register */
744462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_cl45_write(bp, phy,
7445de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CDR_BANDWIDTH,
7446de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x0333);
7447de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7448de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7449de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_8073_SPEED_LINK_STATUS,
7450de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&link_status);
745162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7452de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Bits 0..2 --> speed detected, bits 13..15--> link is down */
7453de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
7454de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
7455de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_10000;
7456de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
7457de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
7458de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else if ((link_status & (1<<1)) && (!(link_status & (1<<14)))) {
7459de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
7460de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_2500;
7461de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link up in 2.5G\n",
7462de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
7463de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
7464de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
7465de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_1000;
7466de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
7467de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
7468de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
7469de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 0;
7470de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link is down\n",
7471de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
747262b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
7473de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7474de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up) {
747574d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		/* Swap polarity if required */
747674d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		if (params->lane_config &
747774d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		    PORT_HW_CFG_SWAP_PHY_POLARITY_ENABLED) {
747874d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner			/* Configure the 8073 to swap P and N of the KR lines */
747974d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner			bnx2x_cl45_read(bp, phy,
748074d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					MDIO_XS_DEVAD,
748174d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					MDIO_XS_REG_8073_RX_CTRL_PCIE, &val1);
74822cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/*
74832cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * Set bit 3 to invert Rx in 1G mode and clear this bit
74842cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 * when it`s in 10G mode.
74852cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			 */
748674d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner			if (vars->line_speed == SPEED_1000) {
748774d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				DP(NETIF_MSG_LINK, "Swapping 1G polarity for"
748874d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					      "the 8073\n");
748974d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				val1 |= (1<<3);
749074d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner			} else
749174d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner				val1 &= ~(1<<3);
749274d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner
749374d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner			bnx2x_cl45_write(bp, phy,
749474d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					 MDIO_XS_DEVAD,
749574d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					 MDIO_XS_REG_8073_RX_CTRL_PCIE,
749674d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner					 val1);
749774d7a11979e39adc1fc4d7a77afe83aa12a0f2b1Yaniv Rosner		}
7498de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
7499de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_8073_resolve_fc(phy, params, vars);
7500791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		vars->duplex = DUPLEX_FULL;
7501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
75029e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
75039e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
75049e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
75059e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_LP_AUTO_NEG2, &val1);
75069e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
75079e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val1 & (1<<5))
75089e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
75099e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
75109e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val1 & (1<<7))
75119e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
75129e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
75139e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval	}
75149e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
7515de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return link_up;
7516b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
7517b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7518de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8073_link_reset(struct bnx2x_phy *phy,
7519de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_params *params)
7520de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7521de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
7522de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 gpio_port;
7523f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (CHIP_IS_E2(bp))
7524f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = BP_PATH(bp);
7525f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
7526f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		gpio_port = params->port;
7527de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Setting 8073 port %d into low power mode\n",
7528de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	   gpio_port);
7529de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7530cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW,
7531cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       gpio_port);
7532de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7533de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
7534de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
7535de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			BCM8705 PHY SECTION			  */
7536de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
7537fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8705_config_init(struct bnx2x_phy *phy,
7538fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
7539fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
7540b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7541b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
7542de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "init 8705\n");
7543b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	/* Restore normal power mode*/
7544b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
7545cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
7546de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* HW reset */
7547de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_hw_reset(bp, params->port);
7548de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
75496d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
7550b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7551de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7552de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_MISC_CTRL, 0x8288);
7553de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7554de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, 0x7fbf);
7555de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7556de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CMU_PLL_BYPASS, 0x0100);
7557de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7558de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_CNTL, 0x1);
7559de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* BCM8705 doesn't have microcode, hence the 0 */
7560de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_spirom_version(bp, params->port, params->shmem_base, 0);
7561de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
7562de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
75634d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7564de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
7565de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_params *params,
7566de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_vars *vars)
7567de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7568de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up = 0;
7569de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val1, rx_sd;
7570de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
7571de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "read status 8705\n");
7572de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7573de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7574de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
757562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7576de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7577de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      MDIO_WIS_DEVAD, MDIO_WIS_REG_LASI_STATUS, &val1);
7578de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
757962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7580de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7581de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
7582c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein
7583de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7584de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      MDIO_PMA_DEVAD, 0xc809, &val1);
7585de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7586de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      MDIO_PMA_DEVAD, 0xc809, &val1);
7587c2c8b03e200bdda3ba23d27f5c33bac784dced01Eilon Greenstein
7588de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8705 1.c809 val=0x%x\n", val1);
7589de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	link_up = ((rx_sd & 0x1) && (val1 & (1<<9)) && ((val1 & (1<<8)) == 0));
7590de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up) {
7591de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_10000;
7592de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
759362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
7594de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return link_up;
7595de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
7596d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
7597de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
7598de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			SFP+ module Section			  */
7599de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
760085242eea68f5039458afad0e4030828496bb4034Yaniv Rosnerstatic void bnx2x_set_disable_pmd_transmit(struct link_params *params,
760185242eea68f5039458afad0e4030828496bb4034Yaniv Rosner					   struct bnx2x_phy *phy,
760285242eea68f5039458afad0e4030828496bb4034Yaniv Rosner					   u8 pmd_dis)
760385242eea68f5039458afad0e4030828496bb4034Yaniv Rosner{
760485242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	struct bnx2x *bp = params->bp;
760585242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	/*
760685242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	 * Disable transmitter only for bootcodes which can enable it afterwards
760785242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	 * (for D3 link)
760885242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	 */
760985242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	if (pmd_dis) {
761085242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		if (params->feature_config_flags &
761185242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		     FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED)
761285242eea68f5039458afad0e4030828496bb4034Yaniv Rosner			DP(NETIF_MSG_LINK, "Disabling PMD transmitter\n");
761385242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		else {
761485242eea68f5039458afad0e4030828496bb4034Yaniv Rosner			DP(NETIF_MSG_LINK, "NOT disabling PMD transmitter\n");
761585242eea68f5039458afad0e4030828496bb4034Yaniv Rosner			return;
761685242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		}
761785242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	} else
761885242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		DP(NETIF_MSG_LINK, "Enabling PMD transmitter\n");
761985242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	bnx2x_cl45_write(bp, phy,
762085242eea68f5039458afad0e4030828496bb4034Yaniv Rosner			 MDIO_PMA_DEVAD,
762185242eea68f5039458afad0e4030828496bb4034Yaniv Rosner			 MDIO_PMA_REG_TX_DISABLE, pmd_dis);
762285242eea68f5039458afad0e4030828496bb4034Yaniv Rosner}
762385242eea68f5039458afad0e4030828496bb4034Yaniv Rosner
7624a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosnerstatic u8 bnx2x_get_gpio_port(struct link_params *params)
7625a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner{
7626a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u8 gpio_port;
7627a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 swap_val, swap_override;
7628a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	struct bnx2x *bp = params->bp;
7629a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	if (CHIP_IS_E2(bp))
7630a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		gpio_port = BP_PATH(bp);
7631a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	else
7632a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		gpio_port = params->port;
7633a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
7634a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
7635a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	return gpio_port ^ (swap_val && swap_override);
7636a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner}
76373c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
76383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_sfp_e1e2_set_transmitter(struct link_params *params,
76393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   struct bnx2x_phy *phy,
76403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   u8 tx_en)
7641de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
7642de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val;
7643a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u8 port = params->port;
7644a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	struct bnx2x *bp = params->bp;
7645a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 tx_en_mode;
7646d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
7647de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
7648a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	tx_en_mode = REG_RD(bp, params->shmem_base +
7649a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			    offsetof(struct shmem_region,
7650a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				     dev_info.port_hw_config[port].sfp_ctrl)) &
7651a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		PORT_HW_CFG_TX_LASER_MASK;
7652a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
7653a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			   "mode = %x\n", tx_en, port, tx_en_mode);
7654a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	switch (tx_en_mode) {
7655a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_TX_LASER_MDIO:
7656d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
7657a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_read(bp, phy,
7658a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				MDIO_PMA_DEVAD,
7659a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				MDIO_PMA_REG_PHY_IDENTIFIER,
7660a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				&val);
7661b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7662a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		if (tx_en)
7663a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			val &= ~(1<<15);
7664a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		else
7665a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			val |= (1<<15);
7666a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
7667a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_write(bp, phy,
7668a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				 MDIO_PMA_DEVAD,
7669a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				 MDIO_PMA_REG_PHY_IDENTIFIER,
7670a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				 val);
7671a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	break;
7672a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_TX_LASER_GPIO0:
7673a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_TX_LASER_GPIO1:
7674a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_TX_LASER_GPIO2:
7675a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_TX_LASER_GPIO3:
7676a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	{
7677a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		u16 gpio_pin;
7678a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		u8 gpio_port, gpio_mode;
7679a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		if (tx_en)
7680a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
7681a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		else
7682a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
7683a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
7684a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
7685a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		gpio_port = bnx2x_get_gpio_port(params);
7686a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
7687a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
7688a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
7689a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	default:
7690a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
7691a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
7692a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
7693b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
7694b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
76953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_sfp_set_transmitter(struct link_params *params,
76963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      struct bnx2x_phy *phy,
76973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      u8 tx_en)
76983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
76993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
77003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting SFP+ transmitter to %d\n", tx_en);
77013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp))
77023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_sfp_e3_set_transmitter(params, phy, tx_en);
77033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
77043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_sfp_e1e2_set_transmitter(params, phy, tx_en);
77053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
77063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
7707fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7708fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     struct link_params *params,
7709fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     u16 addr, u8 byte_cnt, u8 *o_buf)
7710b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7711b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
7712de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val = 0;
7713de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 i;
7714de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (byte_cnt > 16) {
771594f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
771694f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "Reading from eeprom is limited to 0xf\n");
7717de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
7718de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7719de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set the read command byte count */
772062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7721de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7722cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 (byte_cnt | 0xa000));
7723ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7724de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set the read command address */
7725de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
7726de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7727cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 addr);
7728ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7729de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Activate read command */
773062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7731de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7732cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 0x2c0f);
7733ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7734de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Wait up to 500us for command complete status */
7735de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < 100; i++) {
7736de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7737cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7738cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7739de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7740de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7741de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
7742de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		udelay(5);
774362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
774462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7745de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7746de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7747de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK,
7748de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7749de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
7750de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
775162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
7752e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
7753de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Read the buffer */
7754de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < byte_cnt; i++) {
775562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_cl45_read(bp, phy,
7756cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7757cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_8726_TWO_WIRE_DATA_BUF + i, &val);
7758de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		o_buf[i] = (u8)(val & MDIO_PMA_REG_8726_TWO_WIRE_DATA_MASK);
775962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
77606bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
7761de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < 100; i++) {
7762de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7763cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7764cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7765de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7766de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
77676f38ad93e4882e84c1cc113736db7dc9252dcf11Joe Perches			return 0;
7768de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(1);
7769de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7770de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -EINVAL;
7771b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
77724d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
77733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic int bnx2x_warpcore_read_sfp_module_eeprom(struct bnx2x_phy *phy,
77743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						 struct link_params *params,
77753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						 u16 addr, u8 byte_cnt,
77763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner						 u8 *o_buf)
77773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
77783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	int rc = 0;
77793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 i, j = 0, cnt = 0;
77803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 data_array[4];
77813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 addr32;
77823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
77833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/*DP(NETIF_MSG_LINK, "bnx2x_direct_read_sfp_module_eeprom:"
77843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					" addr %d, cnt %d\n",
77853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					addr, byte_cnt);*/
77863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (byte_cnt > 16) {
778794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
778894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "Reading from eeprom is limited to 16 bytes\n");
77893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return -EINVAL;
77903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
77913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
77923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* 4 byte aligned address */
77933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	addr32 = addr & (~0x3);
77943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	do {
77953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		rc = bnx2x_bsc_read(params, phy, 0xa0, addr32, 0, byte_cnt,
77963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				    data_array);
77973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} while ((rc != 0) && (++cnt < I2C_WA_RETRY_CNT));
77983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
77993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (rc == 0) {
78003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		for (i = (addr - addr32); i < byte_cnt + (addr - addr32); i++) {
78013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			o_buf[j] = *((u8 *)data_array + i);
78023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			j++;
78033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
78043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
78053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
78063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	return rc;
78073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
78083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
7809fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8727_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7810fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     struct link_params *params,
7811fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					     u16 addr, u8 byte_cnt, u8 *o_buf)
7812b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7813b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
7814de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val, i;
7815ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7816de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (byte_cnt > 16) {
781794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
781894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "Reading from eeprom is limited to 0xf\n");
7819de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
7820de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
78214d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7822de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Need to read from 1.8000 to clear it */
7823de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
7824cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
7825cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7826cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			&val);
78274d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7828de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set the read command byte count */
782962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7830cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7831cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_SFP_TWO_WIRE_BYTE_CNT,
7832cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 ((byte_cnt < 2) ? 2 : byte_cnt));
7833ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
7834de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set the read command address */
783562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7836cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7837cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_SFP_TWO_WIRE_MEM_ADDR,
7838cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 addr);
7839de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set the destination address */
784062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7841cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7842cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 0x8004,
7843cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF);
784462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Activate read command */
784662b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_write(bp, phy,
7847cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
7848cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_SFP_TWO_WIRE_CTRL,
7849cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 0x8002);
78502cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
78512cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Wait appropriate time for two-wire command to finish before
78522cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * polling the status register
78532cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
7854de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(1);
78554d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7856de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Wait up to 500us for command complete status */
7857de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < 100; i++) {
785862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_cl45_read(bp, phy,
7859cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7860cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7861de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7862de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE)
7863de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
7864de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		udelay(5);
786562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
78664d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7867de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) !=
7868de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_COMPLETE) {
7869de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK,
7870de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 "Got bad status 0x%x when reading from SFP+ EEPROM\n",
7871de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 (val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK));
787265a001bad18eb80f6f953e5e0601132f09bfe197Yaniv Rosner		return -EFAULT;
7873de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
787462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7875de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Read the buffer */
7876de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < byte_cnt; i++) {
7877de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7878cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7879cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_8727_TWO_WIRE_DATA_BUF + i, &val);
7880de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		o_buf[i] = (u8)(val & MDIO_PMA_REG_8727_TWO_WIRE_DATA_MASK);
7881de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
78824d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
7883de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < 100; i++) {
7884de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
7885cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
7886cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_SFP_TWO_WIRE_CTRL, &val);
7887de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & MDIO_PMA_REG_SFP_TWO_WIRE_CTRL_STATUS_MASK) ==
7888de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    MDIO_PMA_REG_SFP_TWO_WIRE_STATUS_IDLE)
78896f38ad93e4882e84c1cc113736db7dc9252dcf11Joe Perches			return 0;
7890de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(1);
789162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
789262b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
7893de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -EINVAL;
7894b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
7895b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7896fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_read_sfp_module_eeprom(struct bnx2x_phy *phy,
7897fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				 struct link_params *params, u16 addr,
7898fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				 u8 byte_cnt, u8 *o_buf)
7899b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7900fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = -EINVAL;
7901e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	switch (phy->type) {
7902e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
7903e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		rc = bnx2x_8726_read_sfp_module_eeprom(phy, params, addr,
7904e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner						       byte_cnt, o_buf);
7905e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	break;
7906e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
7907e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
7908e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		rc = bnx2x_8727_read_sfp_module_eeprom(phy, params, addr,
7909e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner						       byte_cnt, o_buf);
7910e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	break;
79113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
79123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		rc = bnx2x_warpcore_read_sfp_module_eeprom(phy, params, addr,
79133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner							   byte_cnt, o_buf);
79143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	break;
7915e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	}
7916e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	return rc;
7917b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
7918b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
7919fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_get_edc_mode(struct bnx2x_phy *phy,
7920fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      struct link_params *params,
7921fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      u16 *edc_mode)
7922b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
7923b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
79241ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	u32 sync_offset = 0, phy_idx, media_types;
7925de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 val, check_limiting_mode = 0;
7926de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	*edc_mode = EDC_MODE_LIMITING;
792762b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
79281ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	phy->media_type = ETH_PHY_UNSPECIFIED;
7929de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* First check for copper cable */
7930de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_read_sfp_module_eeprom(phy,
7931de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 params,
7932de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 SFP_EEPROM_CON_TYPE_ADDR,
7933de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 1,
7934de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 &val) != 0) {
7935de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Failed to read from SFP+ module EEPROM\n");
7936de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
7937de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
7938a1e4be39dc5a8d83102b835a3ee049f2a6057be9Yaniv Rosner
7939de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (val) {
7940de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case SFP_EEPROM_CON_TYPE_VAL_COPPER:
7941de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	{
7942de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u8 copper_module_type;
79431ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		phy->media_type = ETH_PHY_DA_TWINAX;
79442cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
79452cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Check if its active cable (includes SFP+ module)
79462cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * of passive cable
79472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
7948de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_read_sfp_module_eeprom(phy,
7949de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					       params,
7950de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					       SFP_EEPROM_FC_TX_TECH_ADDR,
7951de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					       1,
79529045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner					       &copper_module_type) != 0) {
7953de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK,
7954de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				"Failed to read copper-cable-type"
7955de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				" from SFP+ EEPROM\n");
7956de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return -EINVAL;
7957de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
79584f60dab113230943fb1bc7969053d9a1b6578339Yaniv Rosner
7959de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (copper_module_type &
7960de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE) {
7961de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "Active Copper cable detected\n");
7962de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			check_limiting_mode = 1;
7963de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else if (copper_module_type &
7964de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE) {
796594f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				DP(NETIF_MSG_LINK,
796694f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches				   "Passive Copper cable detected\n");
7967de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				*edc_mode =
7968de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      EDC_MODE_PASSIVE_DAC;
7969de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else {
797094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
797194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Unknown copper-cable-type 0x%x !!!\n",
797294f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   copper_module_type);
7973de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return -EINVAL;
7974de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
7975de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
797662b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
7977de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case SFP_EEPROM_CON_TYPE_VAL_LC:
79781ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		phy->media_type = ETH_PHY_SFP_FIBER;
7979de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Optic module detected\n");
7980de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		check_limiting_mode = 1;
7981de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
7982de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
7983de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Unable to determine module type 0x%x !!!\n",
7984de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 val);
7985de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
798662b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
79871ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	sync_offset = params->shmem_base +
79881ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		offsetof(struct shmem_region,
79891ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			 dev_info.port_hw_config[params->port].media_type);
79901ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	media_types = REG_RD(bp, sync_offset);
79911ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	/* Update media type for non-PMF sync */
79921ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
79931ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		if (&(params->phy[phy_idx]) == phy) {
79941ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			media_types &= ~(PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
79951ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
79961ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			media_types |= ((phy->media_type &
79971ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
79981ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT * phy_idx));
79991ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			break;
80001ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		}
80011ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	}
80021ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	REG_WR(bp, sync_offset, media_types);
8003de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (check_limiting_mode) {
8004de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u8 options[SFP_EEPROM_OPTIONS_SIZE];
8005de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_read_sfp_module_eeprom(phy,
8006de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						 params,
8007de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						 SFP_EEPROM_OPTIONS_ADDR,
8008de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						 SFP_EEPROM_OPTIONS_SIZE,
8009de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						 options) != 0) {
801094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
801194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Failed to read Option field from module EEPROM\n");
8012de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return -EINVAL;
8013de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
8014de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((options[0] & SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK))
8015de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			*edc_mode = EDC_MODE_LINEAR;
8016de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
8017de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			*edc_mode = EDC_MODE_LIMITING;
801862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
8019de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "EDC mode is set to 0x%x\n", *edc_mode);
802062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	return 0;
8021b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
80222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner/*
80232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * This function read the relevant field from the module (SFP+), and verify it
80242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner * is compliant with this board
80252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner */
8026fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_verify_sfp_module(struct bnx2x_phy *phy,
8027fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				   struct link_params *params)
8028b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8029b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
8030a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 val, cmd;
8031a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 fw_resp, fw_cmd_param;
8032de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	char vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE+1];
8033de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	char vendor_pn[SFP_EEPROM_PART_NO_SIZE+1];
8034a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	phy->flags &= ~FLAGS_SFP_NOT_APPROVED;
8035de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val = REG_RD(bp, params->shmem_base +
8036de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 offsetof(struct shmem_region, dev_info.
8037de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  port_feature_config[params->port].config));
8038de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8039de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_NO_ENFORCEMENT) {
8040de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "NOT enforcing module verification\n");
8041de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
8042de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8043ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8044a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (params->feature_config_flags &
8045a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	    FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY) {
8046a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* Use specific phy request */
8047a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		cmd = DRV_MSG_CODE_VRFY_SPECIFIC_PHY_OPT_MDL;
8048a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	} else if (params->feature_config_flags &
8049a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		   FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY) {
8050a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* Use first phy request only in case of non-dual media*/
8051a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (DUAL_MEDIA(params)) {
805294f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
805394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "FW does not support OPT MDL verification\n");
8054a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			return -EINVAL;
8055a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
8056a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		cmd = DRV_MSG_CODE_VRFY_FIRST_PHY_OPT_MDL;
8057a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	} else {
8058a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* No support in OPT MDL detection */
805994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
806094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "FW does not support OPT MDL verification\n");
8061de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
8062de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8063523224a3b3cd407ce4e6731a087194e13a90db18Dmitry Kravkov
8064a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	fw_cmd_param = FW_PARAM_SET(phy->addr, phy->type, phy->mdio_ctrl);
8065a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	fw_resp = bnx2x_fw_command(bp, cmd, fw_cmd_param);
8066de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (fw_resp == FW_MSG_CODE_VRFY_OPT_MDL_SUCCESS) {
8067de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Approved module\n");
8068de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
8069de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8070b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
8071de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* format the warning message */
8072de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_read_sfp_module_eeprom(phy,
8073de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 params,
8074cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 SFP_EEPROM_VENDOR_NAME_ADDR,
8075cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 SFP_EEPROM_VENDOR_NAME_SIZE,
8076cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 (u8 *)vendor_name))
8077de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vendor_name[0] = '\0';
8078de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	else
8079de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vendor_name[SFP_EEPROM_VENDOR_NAME_SIZE] = '\0';
8080de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_read_sfp_module_eeprom(phy,
8081de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 params,
8082cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 SFP_EEPROM_PART_NO_ADDR,
8083cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 SFP_EEPROM_PART_NO_SIZE,
8084cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 (u8 *)vendor_pn))
8085de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vendor_pn[0] = '\0';
8086de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	else
8087de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vendor_pn[SFP_EEPROM_PART_NO_SIZE] = '\0';
8088de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
80896d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	netdev_err(bp->dev,  "Warning: Unqualified SFP+ module detected,"
80906d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			      " Port %d from %s part number %s\n",
80916d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			 params->port, vendor_name, vendor_pn);
809259a2e53b826103be8c22d9820355320b749b38efYaniv Rosner	if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
809359a2e53b826103be8c22d9820355320b749b38efYaniv Rosner	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_WARNING_MSG)
809459a2e53b826103be8c22d9820355320b749b38efYaniv Rosner		phy->flags |= FLAGS_SFP_NOT_APPROVED;
8095de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -EINVAL;
8096b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
80977aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
8098fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_wait_for_sfp_module_initialized(struct bnx2x_phy *phy,
8099fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner						 struct link_params *params)
81007aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
81014d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
8102de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 val;
81034d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	struct bnx2x *bp = params->bp;
8104de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 timeout;
81052cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
81062cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Initialization time after hot-plug may take up to 300ms for
81072cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * some phys type ( e.g. JDSU )
81082cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
81092cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner
8110de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (timeout = 0; timeout < 60; timeout++) {
8111de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_read_sfp_module_eeprom(phy, params, 1, 1, &val)
8112de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    == 0) {
811394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
811494f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "SFP+ module initialization took %d ms\n",
811594f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   timeout * 5);
8116de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
8117de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
8118de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(5);
8119de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8120de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return -EINVAL;
8121de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
81224d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8123de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8727_power_module(struct bnx2x *bp,
8124de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    struct bnx2x_phy *phy,
8125de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    u8 is_power_up) {
8126de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Make sure GPIOs are not using for LED mode */
8127de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val;
8128de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/*
81292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * In the GPIO register, bit 4 is use to determine if the GPIOs are
8130de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * operating as INPUT or as OUTPUT. Bit 1 is for input, and 0 for
8131de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * output
81323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	 * Bits 0-1 determine the GPIOs value for OUTPUT in case bit 4 val is 0
81333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	 * Bits 8-9 determine the GPIOs value for INPUT in case bit 4 val is 1
8134de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * where the 1st bit is the over-current(only input), and 2nd bit is
8135de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * for power( only output )
81362cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 *
8137de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * In case of NOC feature is disabled and power is up, set GPIO control
8138de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 *  as input to enable listening of over-current indication
8139de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
8140de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->flags & FLAGS_NOC)
8141de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return;
814227d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner	if (is_power_up)
8143de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		val = (1<<4);
8144de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	else
8145de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/*
8146de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * Set GPIO control to OUTPUT, and set the power bit
8147de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * to according to the is_power_up
8148de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 */
814927d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner		val = (1<<1);
81504d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8151de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8152de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
8153de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_REG_8727_GPIO_CTRL,
8154de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 val);
8155de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
81564d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8157fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8726_set_limiting_mode(struct bnx2x *bp,
8158fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					struct bnx2x_phy *phy,
8159fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					u16 edc_mode)
8160de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
8161de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 cur_limiting_mode;
81624d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8163de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
8164cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
8165cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_ROM_VER2,
8166cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			&cur_limiting_mode);
8167de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Current Limiting mode is 0x%x\n",
8168de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 cur_limiting_mode);
8169de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8170de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (edc_mode == EDC_MODE_LIMITING) {
8171cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		DP(NETIF_MSG_LINK, "Setting LIMITING MODE\n");
8172e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, phy,
817362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner				 MDIO_PMA_DEVAD,
8174de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_REG_ROM_VER2,
8175de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 EDC_MODE_LIMITING);
8176de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* LRM mode ( default )*/
81774d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8178de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting LRM MODE\n");
81794d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
81802cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
81812cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Changing to LRM mode takes quite few seconds. So do it only
81822cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * if current mode is limiting (default is LRM)
81832cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
8184de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (cur_limiting_mode != EDC_MODE_LIMITING)
8185de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
81864d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8187de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8188cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
8189cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_LRM_MODE,
8190cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0);
8191de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8192cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
8193cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_ROM_VER2,
8194cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0x128);
8195de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8196cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
8197cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_MISC_CTRL0,
8198cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0x4008);
8199de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8200cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
8201cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_LRM_MODE,
8202cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 0xaaaa);
82034d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	}
8204de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
82054d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein}
82064d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8207fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8727_set_limiting_mode(struct bnx2x *bp,
8208fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					struct bnx2x_phy *phy,
8209fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner					u16 edc_mode)
8210ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
8211de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 phy_identifier;
8212de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 rom_ver2_val;
821362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_read(bp, phy,
8214cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
8215cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_PHY_IDENTIFIER,
8216cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			&phy_identifier);
8217ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8218de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8219cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8220cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_PHY_IDENTIFIER,
8221cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 (phy_identifier & ~(1<<9)));
8222ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
822362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_read(bp, phy,
8224cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
8225cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_ROM_VER2,
8226cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			&rom_ver2_val);
8227de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Keep the MSB 8-bits, and set the LSB 8-bits with the edc_mode */
8228de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8229cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8230cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_ROM_VER2,
8231cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 (rom_ver2_val & 0xff00) | (edc_mode & 0x00ff));
82324d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8233de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8234cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8235cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_PHY_IDENTIFIER,
8236cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 (phy_identifier | (1<<9)));
82374d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8238de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
8239b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
8240ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8241a22f078867ef362e35c54055878168e6613ff743Yaniv Rosnerstatic void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
8242a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				     struct link_params *params,
8243a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				     u32 action)
8244a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner{
8245a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	struct bnx2x *bp = params->bp;
8246a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
8247a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	switch (action) {
8248a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case DISABLE_TX:
8249a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_sfp_set_transmitter(params, phy, 0);
8250a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
8251a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case ENABLE_TX:
8252a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
8253a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			bnx2x_sfp_set_transmitter(params, phy, 1);
8254a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
8255a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	default:
8256a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
8257a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		   action);
8258a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return;
8259a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
8260a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner}
8261a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
82623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_e1e2_module_fault_led(struct link_params *params,
8263a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner					   u8 gpio_mode)
8264a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner{
8265a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	struct bnx2x *bp = params->bp;
8266a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8267a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
8268a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			    offsetof(struct shmem_region,
8269a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			dev_info.port_hw_config[params->port].sfp_ctrl)) &
8270a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		PORT_HW_CFG_FAULT_MODULE_LED_MASK;
8271a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	switch (fault_led_gpio) {
8272a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
8273a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		return;
8274a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
8275a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
8276a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
8277a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
8278a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	{
8279a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		u8 gpio_port = bnx2x_get_gpio_port(params);
8280a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		u16 gpio_pin = fault_led_gpio -
8281a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
8282a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		DP(NETIF_MSG_LINK, "Set fault module-detected led "
8283a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				   "pin %x port %x mode %x\n",
8284a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			       gpio_pin, gpio_port, gpio_mode);
8285a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
8286a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
8287a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	break;
8288a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	default:
8289a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
8290a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			       fault_led_gpio);
8291a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
8292a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner}
8293a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
82943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_e3_module_fault_led(struct link_params *params,
82953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					  u8 gpio_mode)
82963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
82973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 pin_cfg;
82983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 port = params->port;
82993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
83003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	pin_cfg = (REG_RD(bp, params->shmem_base +
83013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 offsetof(struct shmem_region,
83023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  dev_info.port_hw_config[port].e3_sfp_ctrl)) &
83033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		PORT_HW_CFG_E3_FAULT_MDL_LED_MASK) >>
83043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		PORT_HW_CFG_E3_FAULT_MDL_LED_SHIFT;
83053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting Fault LED to %d using pin cfg %d\n",
83063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       gpio_mode, pin_cfg);
83073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_cfg_pin(bp, pin_cfg, gpio_mode);
83083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
83093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
83103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_set_sfp_module_fault_led(struct link_params *params,
83113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   u8 gpio_mode)
83123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
83133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
83143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting SFP+ module fault LED to %d\n", gpio_mode);
83153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
83163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*
83173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * Low ==> if SFP+ module is supported otherwise
83183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * High ==> if SFP+ module is not on the approved vendor list
83193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 */
83203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_e3_module_fault_led(params, gpio_mode);
83213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else
83223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_e1e2_module_fault_led(params, gpio_mode);
83233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
83243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
83253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_power_module(struct link_params *params,
83263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					struct bnx2x_phy *phy,
83273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					u8 power)
83283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
83293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 pin_cfg;
83303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
83313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
83323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	pin_cfg = (REG_RD(bp, params->shmem_base +
83333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			  offsetof(struct shmem_region,
83343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			dev_info.port_hw_config[params->port].e3_sfp_ctrl)) &
83353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			PORT_HW_CFG_E3_PWR_DIS_MASK) >>
83363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			PORT_HW_CFG_E3_PWR_DIS_SHIFT;
8337985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
8338985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	if (pin_cfg == PIN_CFG_NA)
8339985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner		return;
83403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, "Setting SFP+ module power to %d using pin cfg %d\n",
83413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		       power, pin_cfg);
83423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/*
83433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	 * Low ==> corresponding SFP+ module is powered
83443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	 * high ==> the SFP+ module is powered down
83453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	 */
83463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_set_cfg_pin(bp, pin_cfg, power ^ 1);
83473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
83483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
8349985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosnerstatic void bnx2x_warpcore_hw_reset(struct bnx2x_phy *phy,
8350985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				    struct link_params *params)
8351985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner{
8352b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	struct bnx2x *bp = params->bp;
8353985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	bnx2x_warpcore_power_module(params, phy, 0);
8354b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	/* Put Warpcore in low power mode */
8355b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	REG_WR(bp, MISC_REG_WC0_RESET, 0x0c0e);
8356b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner
8357b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	/* Put LCPLL in low power mode */
8358b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	REG_WR(bp, MISC_REG_LCPLL_E40_PWRDWN, 1);
8359b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_ANA, 0);
8360b76070b4058c318dde17a495b2e2d83c456f5fa9Yaniv Rosner	REG_WR(bp, MISC_REG_LCPLL_E40_RESETB_DIG, 0);
8361985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner}
8362985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
8363e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosnerstatic void bnx2x_power_sfp_module(struct link_params *params,
8364e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner				   struct bnx2x_phy *phy,
8365e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner				   u8 power)
8366e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner{
8367e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	struct bnx2x *bp = params->bp;
8368e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	DP(NETIF_MSG_LINK, "Setting SFP+ power to %x\n", power);
8369e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner
8370e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	switch (phy->type) {
8371e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8372e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8373e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		bnx2x_8727_power_module(params->bp, phy, power);
8374e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		break;
83753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
83763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_warpcore_power_module(params, phy, power);
83773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		break;
83783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	default:
83793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		break;
83803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
83813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner}
83823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic void bnx2x_warpcore_set_limiting_mode(struct link_params *params,
83833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					     struct bnx2x_phy *phy,
83843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					     u16 edc_mode)
83853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner{
83863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 val = 0;
83873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u16 mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
83883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x *bp = params->bp;
83893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
83903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 lane = bnx2x_get_warpcore_lane(phy, params);
83913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* This is a global register which controls all lanes */
83923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
83933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
83943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val &= ~(0xf << (lane << 2));
83953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
83963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	switch (edc_mode) {
83973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case EDC_MODE_LINEAR:
83983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case EDC_MODE_LIMITING:
83993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_DEFAULT;
84003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		break;
84013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case EDC_MODE_PASSIVE_DAC:
84023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		mode = MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE_SFP_DAC;
84033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		break;
8404e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	default:
8405e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		break;
8406e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	}
84073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
84083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	val |= (mode << (lane << 2));
84093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_WC_DEVAD,
84103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			 MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, val);
84113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* A must read */
84123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
84133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			MDIO_WC_REG_UC_INFO_B1_FIRMWARE_MODE, &val);
84143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
841519af03a3c8cb1e07e31c070dfde9fac2e5e7796cYaniv Rosner	/* Restart microcode to re-read the new mode */
841619af03a3c8cb1e07e31c070dfde9fac2e5e7796cYaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 1);
841719af03a3c8cb1e07e31c070dfde9fac2e5e7796cYaniv Rosner	bnx2x_warpcore_reset_lane(bp, phy, 0);
84183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
8419e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner}
8420e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner
8421e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosnerstatic void bnx2x_set_limiting_mode(struct link_params *params,
8422e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner				    struct bnx2x_phy *phy,
8423e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner				    u16 edc_mode)
8424e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner{
8425e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	switch (phy->type) {
8426e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
8427e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		bnx2x_8726_set_limiting_mode(params->bp, phy, edc_mode);
8428e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		break;
8429e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
8430e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
8431e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		bnx2x_8727_set_limiting_mode(params->bp, phy, edc_mode);
8432e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		break;
84333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
84343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_warpcore_set_limiting_mode(params, phy, edc_mode);
84353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		break;
8436e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	}
8437e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner}
8438e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner
8439fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
8440fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			       struct link_params *params)
8441b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8442b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
8443de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 edc_mode;
8444fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
8445ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8446de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 val = REG_RD(bp, params->shmem_base +
8447de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			     offsetof(struct shmem_region, dev_info.
8448de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				     port_feature_config[params->port].config));
844962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8450de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "SFP+ module plugged in/out detected on port %d\n",
8451de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 params->port);
8452e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	/* Power up module */
8453e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	bnx2x_power_sfp_module(params, phy, 1);
8454de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (bnx2x_get_edc_mode(phy, params, &edc_mode) != 0) {
8455de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Failed to get valid module type\n");
8456de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
8457cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	} else if (bnx2x_verify_sfp_module(phy, params) != 0) {
8458de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* check SFP+ module compatibility */
8459de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Module verification failed!!\n");
8460de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		rc = -EINVAL;
8461de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Turn on fault module-detected led */
8462a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_set_sfp_module_fault_led(params,
8463a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner					       MISC_REGISTERS_GPIO_HIGH);
8464a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8465e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		/* Check if need to power down the SFP+ module */
8466e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8467e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN) {
8468de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "Shutdown SFP+ module!!\n");
8469e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner			bnx2x_power_sfp_module(params, phy, 0);
8470de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return rc;
8471de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
8472de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
8473de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Turn off fault module-detected led */
8474a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
847562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
8476b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
84772cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
84782cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Check and set limiting mode / LRM mode on 8726. On 8727 it
84792cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * is done automatically
84802cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
8481e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	bnx2x_set_limiting_mode(params, phy, edc_mode);
8482e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner
8483de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/*
8484de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * Enable transmit for this module if the module is approved, or
8485de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * if unapproved modules should also enable the Tx laser
8486de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
8487de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (rc == 0 ||
8488de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
8489de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
8490a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_sfp_set_transmitter(params, phy, 1);
8491de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	else
8492a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_sfp_set_transmitter(params, phy, 0);
8493b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
8494de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return rc;
8495de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
8496de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8497de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnervoid bnx2x_handle_module_detect_int(struct link_params *params)
8498b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8499b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
85003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	struct bnx2x_phy *phy;
8501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 gpio_val;
85023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 gpio_num, gpio_port;
85033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp))
85043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		phy = &params->phy[INT_PHY];
85053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	else
85063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		phy = &params->phy[EXT_PHY1];
85073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
85083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (bnx2x_get_mod_abs_int_cfg(bp, params->chip_id, params->shmem_base,
85093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				      params->port, &gpio_num, &gpio_port) ==
85103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	    -EINVAL) {
85113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		DP(NETIF_MSG_LINK, "Failed to get MOD_ABS interrupt config\n");
85123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		return;
85133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
85144d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
8515de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set valid module led off */
8516a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
85174d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
85182cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/* Get current gpio val reflecting module plugged in / out*/
85193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	gpio_val = bnx2x_get_gpio(bp, gpio_num, gpio_port);
852062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8521de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Call the handling function in case module is detected */
8522de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (gpio_val == 0) {
8523e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner		bnx2x_power_sfp_module(params, phy, 1);
85243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_gpio_int(bp, gpio_num,
8525de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   MISC_REGISTERS_GPIO_INT_OUTPUT_CLR,
85263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				   gpio_port);
8527de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
8528de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_sfp_module_detection(phy, params);
8529de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
8530de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
8531de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
8532de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u32 val = REG_RD(bp, params->shmem_base +
8533cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 offsetof(struct shmem_region, dev_info.
8534cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					  port_feature_config[params->port].
8535cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					  config));
85363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		bnx2x_set_gpio_int(bp, gpio_num,
8537de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   MISC_REGISTERS_GPIO_INT_OUTPUT_SET,
85383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				   gpio_port);
85392cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
85402cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Module was plugged out.
85412cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Disable transmit for this module
85422cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
85431ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		phy->media_type = ETH_PHY_NOT_PRESENT;
8544de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		if (((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
8545de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		     PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) ||
8546de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		    CHIP_IS_E3(bp))
8547a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			bnx2x_sfp_set_transmitter(params, phy, 0);
854862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
8549de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
855062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8551de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8552c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner/*		Used by 8706 and 8727                             */
8553c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner/******************************************************************/
8554c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosnerstatic void bnx2x_sfp_mask_fault(struct bnx2x *bp,
8555c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner				 struct bnx2x_phy *phy,
8556c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner				 u16 alarm_status_offset,
8557c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner				 u16 alarm_ctrl_offset)
8558c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner{
8559c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	u16 alarm_status, val;
8560c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	bnx2x_cl45_read(bp, phy,
8561c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			MDIO_PMA_DEVAD, alarm_status_offset,
8562c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			&alarm_status);
8563c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	bnx2x_cl45_read(bp, phy,
8564c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			MDIO_PMA_DEVAD, alarm_status_offset,
8565c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			&alarm_status);
8566c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	/* Mask or enable the fault event. */
8567c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, &val);
8568c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	if (alarm_status & (1<<0))
8569c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		val &= ~(1<<0);
8570c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	else
8571c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		val |= (1<<0);
8572c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, alarm_ctrl_offset, val);
8573c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner}
8574c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner/******************************************************************/
8575de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*		common BCM8706/BCM8726 PHY SECTION		  */
8576de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8577de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8706_8726_read_status(struct bnx2x_phy *phy,
8578de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      struct link_params *params,
8579de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      struct link_vars *vars)
8580de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
8581de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up = 0;
8582de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val1, val2, rx_sd, pcs_status;
8583de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
8584de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "XGXS 8706/8726\n");
8585de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Clear RX Alarm*/
858662b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_read(bp, phy,
858760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &val2);
8588c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
858960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner	bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
859060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			     MDIO_PMA_LASI_TXCTRL);
8591c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
8592de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* clear LASI indication*/
8593de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
859460d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
8595de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
859660d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
8597de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8706/8726 LASI status 0x%x--> 0x%x\n", val1, val2);
859862b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
859962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	bnx2x_cl45_read(bp, phy,
8600de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_RX_SD, &rx_sd);
8601de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
8602de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PCS_DEVAD, MDIO_PCS_REG_STATUS, &pcs_status);
8603de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
8604de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
8605de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
8606de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_LINK_STATUS, &val2);
860762b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8608de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8706/8726 rx_sd 0x%x pcs_status 0x%x 1Gbps"
8609de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			" link_status 0x%x\n", rx_sd, pcs_status, val2);
86102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
86112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * link is up if both bit 0 of pmd_rx_sd and bit 0 of pcs_status
86122cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * are set, or if the autoneg bit 1 is set
8613de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
8614de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	link_up = ((rx_sd & pcs_status & 0x1) || (val2 & (1<<1)));
8615de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up) {
8616de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (val2 & (1<<1))
8617de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->line_speed = SPEED_1000;
8618de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
8619de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->line_speed = SPEED_10000;
862062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
8621791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		vars->duplex = DUPLEX_FULL;
8622de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8623c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
8624c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	/* Capture 10G link fault. Read twice to clear stale value. */
8625c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	if (vars->line_speed == SPEED_10000) {
8626c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
862760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			    MDIO_PMA_LASI_TXSTAT, &val1);
8628c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
862960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			    MDIO_PMA_LASI_TXSTAT, &val1);
8630c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		if (val1 & (1<<0))
8631c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			vars->fault_detected = 1;
8632c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	}
8633c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
863462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	return link_up;
8635b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
863662b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8637de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8638de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			BCM8706 PHY SECTION			  */
8639de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8640de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
8641b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_params *params,
8642b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_vars *vars)
8643b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8644a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 tx_en_mode;
8645a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u16 cnt, val, tmp1;
8646b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
86473deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
8648de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
8649cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
8650de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* HW reset */
8651de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_hw_reset(bp, params->port);
8652de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0xa040);
86536d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
8654ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8655de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Wait until fw is loaded */
8656de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (cnt = 0; cnt < 100; cnt++) {
8657de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
8658de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_ROM_VER1, &val);
8659de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (val)
8660de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
8661de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(10);
8662de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8663de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "XGXS 8706 is initialized after %d ms\n", cnt);
8664de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((params->feature_config_flags &
8665de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
8666de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u8 i;
8667de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 reg;
8668de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		for (i = 0; i < 4; i++) {
8669de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			reg = MDIO_XS_8706_REG_BANK_RX0 +
8670de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				i*(MDIO_XS_8706_REG_BANK_RX1 -
8671de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   MDIO_XS_8706_REG_BANK_RX0);
8672de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_XS_DEVAD, reg, &val);
8673de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* Clear first 3 bits of the control */
8674de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val &= ~0x7;
8675de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* Set control bits according to configuration */
8676de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val |= (phy->rx_preemphasis[i] & 0x7);
8677de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "Setting RX Equalizer to BCM8706"
8678de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   " reg 0x%x <-- val 0x%x\n", reg, val);
8679de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_write(bp, phy, MDIO_XS_DEVAD, reg, val);
8680de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
8681de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8682de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Force speed */
8683de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed == SPEED_10000) {
8684de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
8685ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8686de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8687de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD,
8688de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_REG_DIGITAL_CTRL, 0x400);
8689de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
869060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
8691c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner				 0);
8692c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		/* Arm LASI for link and Tx fault. */
8693c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		bnx2x_cl45_write(bp, phy,
869460d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 3);
8695de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
869625985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/* Force 1Gbps using autoneg with 1G advertisement */
86976bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
8698de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Allow CL37 through CL73 */
8699de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
8700de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8701de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
87026bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
870325985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/* Enable Full-Duplex advertisement on CL37 */
8704de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8705de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LP, 0x0020);
8706de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enable CL37 AN */
8707de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8708de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8709de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* 1G support */
8710de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8711de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, (1<<5));
87126bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
8713de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enable clause 73 AN */
8714de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8715de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
8716de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
871760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8718de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x0400);
8719de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
872060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
8721de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x0004);
8722de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8723de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8724a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8725a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	/*
8726a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
8727a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * power mode, if TX Laser is disabled
8728a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 */
8729a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8730a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	tx_en_mode = REG_RD(bp, params->shmem_base +
8731a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			    offsetof(struct shmem_region,
8732a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				dev_info.port_hw_config[params->port].sfp_ctrl))
8733a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			& PORT_HW_CFG_TX_LASER_MASK;
8734a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8735a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
8736a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
8737a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_read(bp, phy,
8738a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
8739a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		tmp1 |= 0x1;
8740a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_write(bp, phy,
8741a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
8742a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
8743a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
8744de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
8745de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
8746ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8747fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8706_read_status(struct bnx2x_phy *phy,
8748fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
8749fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
8750de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
8751de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return bnx2x_8706_8726_read_status(phy, params, vars);
8752de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
87536bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
8754de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8755de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			BCM8726 PHY SECTION			  */
8756de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8757de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8726_config_loopback(struct bnx2x_phy *phy,
8758de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       struct link_params *params)
8759de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
8760de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
8761de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "PMA/PMD ext_phy_loopback: 8726\n");
8762de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0001);
8763de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
876462b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8765de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8726_external_rom_boot(struct bnx2x_phy *phy,
8766de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 struct link_params *params)
8767de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
8768de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
8769de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Need to wait 100ms after reset */
8770de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(100);
877162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8772de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Micro controller re-boot */
8773de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8774de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x018B);
877562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8776de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set soft reset */
8777de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8778cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8779cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
8780cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
878162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8782de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8783cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8784cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_MISC_CTRL1, 0x0001);
87856bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
8786de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8787cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8788cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL,
8789cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
8790de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8791de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* wait for 150ms for microcode load */
8792de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(150);
8793de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8794de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Disable serial boot control, tristates pins SS_N, SCK, MOSI, MISO */
8795de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8796cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_DEVAD,
8797cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 MDIO_PMA_REG_MISC_CTRL1, 0x0000);
8798de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8799de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(200);
8800de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
8801b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
8802b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
8803de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8726_read_status(struct bnx2x_phy *phy,
8804b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_params *params,
8805b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				 struct link_vars *vars)
8806b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8807b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
8808de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val1;
8809de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up = bnx2x_8706_8726_read_status(phy, params, vars);
881062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	if (link_up) {
881162b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner		bnx2x_cl45_read(bp, phy,
8812de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
8813de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&val1);
8814de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (val1 & (1<<15)) {
8815de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "Tx is disabled\n");
8816de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			link_up = 0;
8817de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			vars->line_speed = 0;
8818de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
881962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	}
882062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	return link_up;
8821b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
8822b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
8823de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8824fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8726_config_init(struct bnx2x_phy *phy,
8825fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
8826fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
8827b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
8828b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
8829de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
883062b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8831de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
88326d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
883362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8834de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_8726_external_rom_boot(phy, params);
883562b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
88362cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
88372cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Need to call module detected on initialization since the module
88382cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * detection triggered by actual module insertion might occur before
88392cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * driver is loaded, and when driver is loaded, it reset all
88402cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * registers, including the transmitter
88412cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
8842de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_sfp_module_detection(phy, params);
884362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8844de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed == SPEED_1000) {
8845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 1G force\n");
8846de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8847de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
8848de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8849de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
8850de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
885160d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x5);
8852de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
885360d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8854de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x400);
8855de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
8856de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   (phy->speed_cap_mask &
8857de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      PORT_HW_CFG_SPEED_CAPABILITY_D0_1G) &&
8858de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   ((phy->speed_cap_mask &
8859de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
8860de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
8861de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
8862de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Set Flow control */
8863de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_set_pause(params, phy, vars);
8864de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8865de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_ADV, 0x20);
8866de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8867de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_CL73, 0x040c);
8868de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8869de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_FC_LD, 0x0020);
8870de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8871de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1000);
8872de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8873de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x1200);
88742cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
88752cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Enable RX-ALARM control to receive interrupt for 1G speed
88762cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * change
88772cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
8878de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
887960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x4);
8880de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
888160d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
8882de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x400);
888362b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
8884de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* Default 10G. Set only LASI control */
8885de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
888660d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 1);
88877aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner	}
88887aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
8889de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set TX PreEmphasis if needed */
8890de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((params->feature_config_flags &
8891de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
889294f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
889394f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
8894de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 phy->tx_preemphasis[0],
8895de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 phy->tx_preemphasis[1]);
8896de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8897de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD,
8898de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_REG_8726_TX_CTRL1,
8899de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 phy->tx_preemphasis[0]);
8900c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner
8901de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
8902de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD,
8903de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_REG_8726_TX_CTRL2,
8904de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 phy->tx_preemphasis[1]);
8905de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
8906ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
8907de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
8908ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
8909ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
8910ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
8911de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8726_link_reset(struct bnx2x_phy *phy,
8912de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_params *params)
89132f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein{
8914de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
8915de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "bnx2x_8726_link_reset port %d\n", params->port);
8916de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set serial boot control for external load */
8917de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
8918de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
8919de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_REG_GEN_CTRL, 0x0001);
8920de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
8921de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
8922de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
8923de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			BCM8727 PHY SECTION			  */
8924de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
89257f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
89267f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosnerstatic void bnx2x_8727_set_link_led(struct bnx2x_phy *phy,
89277f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner				    struct link_params *params, u8 mode)
89287f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner{
89297f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	struct bnx2x *bp = params->bp;
89307f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	u16 led_mode_bitmask = 0;
89317f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	u16 gpio_pins_bitmask = 0;
89327f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	u16 val;
89337f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	/* Only NOC flavor requires to set the LED specifically */
89347f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	if (!(phy->flags & FLAGS_NOC))
89357f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		return;
89367f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	switch (mode) {
89377f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_FRONT_PANEL_OFF:
89387f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OFF:
89397f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		led_mode_bitmask = 0;
89407f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		gpio_pins_bitmask = 0x03;
89417f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
89427f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_ON:
89437f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		led_mode_bitmask = 0;
89447f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		gpio_pins_bitmask = 0x02;
89457f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
89467f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OPER:
89477f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		led_mode_bitmask = 0x60;
89487f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		gpio_pins_bitmask = 0x11;
89497f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
89507f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	}
89517f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_cl45_read(bp, phy,
89527f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			MDIO_PMA_DEVAD,
89537f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			MDIO_PMA_REG_8727_PCS_OPT_CTRL,
89547f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			&val);
89557f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	val &= 0xff8f;
89567f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	val |= led_mode_bitmask;
89577f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_cl45_write(bp, phy,
89587f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_DEVAD,
89597f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_REG_8727_PCS_OPT_CTRL,
89607f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 val);
89617f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_cl45_read(bp, phy,
89627f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			MDIO_PMA_DEVAD,
89637f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			MDIO_PMA_REG_8727_GPIO_CTRL,
89647f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			&val);
89657f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	val &= 0xffe0;
89667f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	val |= gpio_pins_bitmask;
89677f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_cl45_write(bp, phy,
89687f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_DEVAD,
89697f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_REG_8727_GPIO_CTRL,
89707f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 val);
89717f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner}
8972de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8727_hw_reset(struct bnx2x_phy *phy,
8973de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				struct link_params *params) {
8974de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 swap_val, swap_override;
8975de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 port;
89762cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
8977de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * The PHY reset is controlled by GPIO 1. Fake the port number
8978de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * to cancel the swap done in set_gpio()
89792f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein	 */
8980de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
8981de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
8982de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
8983de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	port = (swap_val && swap_override) ^ 1;
8984de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
8985cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
89862f9044603c8b9ead9eb4d88e360093b44d362b58Eilon Greenstein}
8987e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
8988fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8727_config_init(struct bnx2x_phy *phy,
8989fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
8990fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
8991ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
8992a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 tx_en_mode;
8993a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u16 tmp1, val, mod_abs, tmp2;
8994de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 rx_alarm_ctrl_val;
8995de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 lasi_ctrl_val;
8996ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
8997de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Enable PMD link, MOD_ABS_FLT, and 1G link alarm */
8998ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
89996d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
9000de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	rx_alarm_ctrl_val = (1<<2) | (1<<5) ;
9001c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	/* Should be 0x6 to enable XS on Tx side. */
9002c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	lasi_ctrl_val = 0x0006;
9003ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9004de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Initializing BCM8727\n");
9005de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* enable LASI */
9006de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
900760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9008de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 rx_alarm_ctrl_val);
9009c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	bnx2x_cl45_write(bp, phy,
901060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_TXCTRL,
9011c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			 0);
9012de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
901360d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, lasi_ctrl_val);
9014ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
90152cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
90162cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Initially configure MOD_ABS to interrupt when module is
90172cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * presence( bit 8)
90182cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
9019de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9020de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
90212cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
90222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Set EDC off by setting OPTXLOS signal input to low (bit 9).
90232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * When the EDC is off it locks onto a reference clock and avoids
90242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * becoming 'lost'
90252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
90267f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	mod_abs &= ~(1<<8);
90277f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	if (!(phy->flags & FLAGS_NOC))
90287f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		mod_abs &= ~(1<<9);
9029de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9030de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9031ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9032ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
903385242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	/* Enable/Disable PHY transmitter output */
903485242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	bnx2x_set_disable_pmd_transmit(params, phy, 0);
903585242eea68f5039458afad0e4030828496bb4034Yaniv Rosner
9036de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Make MOD_ABS give interrupt on change */
9037de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL,
9038de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&val);
9039de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val |= (1<<12);
90407f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	if (phy->flags & FLAGS_NOC)
90417f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		val |= (3<<5);
9042b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
90432cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
90447f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	 * Set 8727 GPIOs to input to allow reading from the 8727 GPIO0
90457f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	 * status which reflect SFP+ module over-current
90467f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	 */
90477f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	if (!(phy->flags & FLAGS_NOC))
90487f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		val &= 0xff8f; /* Reset bits 4-6 */
9049de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9050de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_PCS_OPT_CTRL, val);
9051ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9052de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_8727_power_module(bp, phy, 1);
9053de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9054de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9055de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &tmp1);
9056de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9057de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
905860d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT, &tmp1);
9059de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9060de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set option 1G speed */
9061de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_line_speed == SPEED_1000) {
9062de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 1G force\n");
9063de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9064de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x40);
9065de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9066de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, 0xD);
9067de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
9068de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2, &tmp1);
9069de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "1.7 = 0x%x\n", tmp1);
90702cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
9071a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * Power down the XAUI until link is up in case of dual-media
9072a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * and 1G
9073a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 */
9074a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (DUAL_MEDIA(params)) {
9075a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			bnx2x_cl45_read(bp, phy,
9076a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					MDIO_PMA_DEVAD,
9077a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					MDIO_PMA_REG_8727_PCS_GP, &val);
9078a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			val |= (3<<10);
9079a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			bnx2x_cl45_write(bp, phy,
9080a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					 MDIO_PMA_DEVAD,
9081a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					 MDIO_PMA_REG_8727_PCS_GP, val);
9082a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
9083de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
9084de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   ((phy->speed_cap_mask &
9085de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) &&
9086de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   ((phy->speed_cap_mask &
9087de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      PORT_HW_CFG_SPEED_CAPABILITY_D0_10G) !=
9088de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) {
9089de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9090de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 1G clause37\n");
9091de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9092de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL, 0);
9093de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9094de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x1300);
9095de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
90962cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
9097de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * Since the 8727 has only single reset pin, need to set the 10G
9098de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * registers although it is default
9099de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 */
9100de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9101de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_8727_MISC_CTRL,
9102de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x0020);
9103de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9104de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_CL37_AN, 0x0100);
9105de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9106de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x2040);
9107de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9108de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_10G_CTRL2,
9109de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 0x0008);
9110ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
9111ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
91122cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
91132cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Set 2-wire transfer rate of SFP+ module EEPROM
9114de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * to 100Khz since some DACs(direct attached cables) do
9115de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * not work at 400Khz.
9116de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
9117de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9118de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TWO_WIRE_SLAVE_ADDR,
9119de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 0xa001);
9120b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9121de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Set TX PreEmphasis if needed */
9122de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((params->feature_config_flags &
9123de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED)) {
9124de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting TX_CTRL1 0x%x, TX_CTRL2 0x%x\n",
9125de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   phy->tx_preemphasis[0],
9126de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   phy->tx_preemphasis[1]);
9127de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9128de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL1,
9129de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 phy->tx_preemphasis[0]);
9130ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9131de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9132de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_TX_CTRL2,
9133de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 phy->tx_preemphasis[1]);
9134de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9135ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9136a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	/*
9137a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * If TX Laser is controlled by GPIO_0, do not let PHY go into low
9138a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * power mode, if TX Laser is disabled
9139a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 */
9140a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	tx_en_mode = REG_RD(bp, params->shmem_base +
9141a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			    offsetof(struct shmem_region,
9142a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				dev_info.port_hw_config[params->port].sfp_ctrl))
9143a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			& PORT_HW_CFG_TX_LASER_MASK;
9144a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
9145a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
9146a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
9147a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
9148a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_read(bp, phy,
9149a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
9150a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		tmp2 |= 0x1000;
9151a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		tmp2 &= 0xFFEF;
9152a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		bnx2x_cl45_write(bp, phy,
9153a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
915459a2e53b826103be8c22d9820355320b749b38efYaniv Rosner		bnx2x_cl45_read(bp, phy,
915559a2e53b826103be8c22d9820355320b749b38efYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
915659a2e53b826103be8c22d9820355320b749b38efYaniv Rosner				&tmp2);
915759a2e53b826103be8c22d9820355320b749b38efYaniv Rosner		bnx2x_cl45_write(bp, phy,
915859a2e53b826103be8c22d9820355320b749b38efYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_PHY_IDENTIFIER,
915959a2e53b826103be8c22d9820355320b749b38efYaniv Rosner				 (tmp2 & 0x7fff));
9160a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
9161a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
9162de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
9163ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
9164ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9165de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
9166de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      struct link_params *params)
9167ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9168ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
9169de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 mod_abs, rx_alarm_status;
9170de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 val = REG_RD(bp, params->shmem_base +
9171de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			     offsetof(struct shmem_region, dev_info.
9172de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      port_feature_config[params->port].
9173de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				      config));
9174de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9175cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
9176cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_PHY_IDENTIFIER, &mod_abs);
9177de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (mod_abs & (1<<8)) {
9178ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9179de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Module is absent */
918094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
918194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "MOD_ABS indication show module is absent\n");
91821ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		phy->media_type = ETH_PHY_NOT_PRESENT;
91832cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
91842cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * 1. Set mod_abs to detect next module
91852cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 *    presence event
91862cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * 2. Set EDC off by setting OPTXLOS signal input to low
91872cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 *    (bit 9).
91882cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 *    When the EDC is off it locks onto a reference clock and
91892cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 *    avoids becoming 'lost'.
91902cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
91917f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		mod_abs &= ~(1<<8);
91927f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if (!(phy->flags & FLAGS_NOC))
91937f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			mod_abs &= ~(1<<9);
9194de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9195cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
9196cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9197ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
91982cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
91992cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Clear RX alarm since it stays up as long as
92002cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * the mod_abs wasn't changed
92012cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
9202de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
9203cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
920460d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9205ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9206de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
9207de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Module is present */
920894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
920994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "MOD_ABS indication show module is present\n");
92102cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
92112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * First disable transmitter, and if the module is ok, the
92122cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * module_detection will enable it
92132cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * 1. Set mod_abs to detect next module absent event ( bit 8)
92142cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * 2. Restore the default polarity of the OPRXLOS signal and
92152cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * this signal will then correctly indicate the presence or
92162cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * absence of the Rx signal. (bit 9)
92172cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
92187f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		mod_abs |= (1<<8);
92197f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if (!(phy->flags & FLAGS_NOC))
92207f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			mod_abs |= (1<<9);
9221e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, phy,
9222de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD,
9223de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_REG_PHY_IDENTIFIER, mod_abs);
9224ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
92252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
92262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * Clear RX alarm since it stays up as long as the mod_abs
92272cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * wasn't changed. This is need to be done before calling the
92282cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * module detection, otherwise it will clear* the link update
92292cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * alarm
92302cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
9231de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
9232de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD,
923360d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9234ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9235ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9236de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
9237de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
9238a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner			bnx2x_sfp_set_transmitter(params, phy, 0);
9239de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9240de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
9241de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_sfp_module_detection(phy, params);
9242de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		else
9243de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "SFP+ module is not initialized\n");
9244ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
9245de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9246de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS 0x%x\n",
92472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		   rx_alarm_status);
92482cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/* No need to check link status in case of module plugged in/out */
9249ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
9250ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9251de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_8727_read_status(struct bnx2x_phy *phy,
9252de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_params *params,
9253de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_vars *vars)
9254de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9255ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9256ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
925727d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner	u8 link_up = 0, oc_port = params->port;
9258de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 link_status = 0;
9259a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u16 rx_alarm_status, lasi_ctrl, val1;
9260a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9261a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	/* If PHY is not initialized, do not check link status */
9262a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	bnx2x_cl45_read(bp, phy,
926360d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL,
9264a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			&lasi_ctrl);
9265a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (!lasi_ctrl)
9266a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return 0;
9267a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
92689045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	/* Check the LASI on Rx */
9269de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
927060d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXSTAT,
9271de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&rx_alarm_status);
9272de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->line_speed = 0;
9273de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8727 RX_ALARM_STATUS  0x%x\n", rx_alarm_status);
9274de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
927560d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner	bnx2x_sfp_mask_fault(bp, phy, MDIO_PMA_LASI_TXSTAT,
927660d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			     MDIO_PMA_LASI_TXCTRL);
9277c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
9278de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
927960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
9280de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9281de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "8727 LASI status 0x%x\n", val1);
9282de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9283de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Clear MSG-OUT */
9284de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9285de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_M8051_MSGOUT_REG, &val1);
9286de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
92872cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
9288de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * If a module is present and there is need to check
9289de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * for over current
9290de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
9291de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (!(phy->flags & FLAGS_NOC) && !(rx_alarm_status & (1<<5))) {
9292de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Check over-current using 8727 GPIO0 input*/
9293de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
9294de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_GPIO_CTRL,
9295de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&val1);
9296de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9297de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val1 & (1<<8)) == 0) {
929827d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner			if (!CHIP_IS_E1x(bp))
929927d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner				oc_port = BP_PATH(bp) + (params->port << 1);
930094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
930194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "8727 Power fault has been detected on port %d\n",
930294f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   oc_port);
93032f751a805e35dcf687473c27282a6602577df541Yaniv Rosner			netdev_err(bp->dev, "Error: Power fault on Port %d has "
93042f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "been detected and the power to "
93052f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "that SFP+ module has been removed "
93062f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "to prevent failure of the card. "
93072f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "Please remove the SFP+ module and "
93082f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "restart the system to clear this "
93092f751a805e35dcf687473c27282a6602577df541Yaniv Rosner					    "error.\n",
931027d024321cf4fc0a96c41c3b0f3c123796734a63Yaniv Rosner			 oc_port);
93112cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			/* Disable all RX_ALARMs except for mod_abs */
9312de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_write(bp, phy,
9313de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 MDIO_PMA_DEVAD,
931460d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner					 MDIO_PMA_LASI_RXCTRL, (1<<5));
9315de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9316de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_read(bp, phy,
9317de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_PMA_DEVAD,
9318de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_PMA_REG_PHY_IDENTIFIER, &val1);
9319de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* Wait for module_absent_event */
9320de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			val1 |= (1<<8);
9321de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_write(bp, phy,
9322de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 MDIO_PMA_DEVAD,
9323de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					 MDIO_PMA_REG_PHY_IDENTIFIER, val1);
9324de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* Clear RX alarm */
9325de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_read(bp, phy,
9326de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_PMA_DEVAD,
932760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				MDIO_PMA_LASI_RXSTAT, &rx_alarm_status);
9328de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return 0;
9329de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
9330de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} /* Over current check */
9331de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9332de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* When module absent bit is set, check module */
9333de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (rx_alarm_status & (1<<5)) {
9334de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_8727_handle_mod_abs(phy, params);
9335de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enable all mod_abs and link detection bits */
9336de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
933760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_LASI_RXCTRL,
9338de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 ((1<<5) | (1<<2)));
9339de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
934059a2e53b826103be8c22d9820355320b749b38efYaniv Rosner
934159a2e53b826103be8c22d9820355320b749b38efYaniv Rosner	if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) {
934259a2e53b826103be8c22d9820355320b749b38efYaniv Rosner		DP(NETIF_MSG_LINK, "Enabling 8727 TX laser\n");
934359a2e53b826103be8c22d9820355320b749b38efYaniv Rosner		bnx2x_sfp_set_transmitter(params, phy, 1);
934459a2e53b826103be8c22d9820355320b749b38efYaniv Rosner	} else {
9345de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Tx is disabled\n");
9346de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
9347de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9348de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9349de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9350de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD,
9351de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_REG_8073_SPEED_LINK_STATUS, &link_status);
9352de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
93532cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
93542cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Bits 0..2 --> speed detected,
93552cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Bits 13..15--> link is down
93562cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
9357de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if ((link_status & (1<<2)) && (!(link_status & (1<<15)))) {
9358de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
9359de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_10000;
93602cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link up in 10G\n",
93612cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			   params->port);
9362de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else if ((link_status & (1<<0)) && (!(link_status & (1<<13)))) {
9363de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
9364de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_1000;
9365de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link up in 1G\n",
9366de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
9367de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else {
9368de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 0;
9369de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "port %x: External link is down\n",
9370de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   params->port);
9371de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9372c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
9373c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	/* Capture 10G link fault. */
9374c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	if (vars->line_speed == SPEED_10000) {
9375c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
937660d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			    MDIO_PMA_LASI_TXSTAT, &val1);
9377c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
9378c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD,
937960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			    MDIO_PMA_LASI_TXSTAT, &val1);
9380c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
9381c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		if (val1 & (1<<0)) {
9382c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner			vars->fault_detected = 1;
9383c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner		}
9384c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner	}
9385c688fe2fc0cab3a5d266f7f6fcb21f14e4ac39baYaniv Rosner
9386791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner	if (link_up) {
9387de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
9388791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		vars->duplex = DUPLEX_FULL;
9389791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		DP(NETIF_MSG_LINK, "duplex = 0x%x\n", vars->duplex);
9390791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner	}
9391a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9392a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if ((DUAL_MEDIA(params)) &&
9393a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	    (phy->req_line_speed == SPEED_1000)) {
9394a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		bnx2x_cl45_read(bp, phy,
9395a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				MDIO_PMA_DEVAD,
9396a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				MDIO_PMA_REG_8727_PCS_GP, &val1);
93972cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
9398a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * In case of dual-media board and 1G, power up the XAUI side,
9399a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 * otherwise power it down. For 10G it is done automatically
9400a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 */
9401a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (link_up)
9402a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			val1 &= ~(3<<10);
9403a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		else
9404a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			val1 |= (3<<10);
9405a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		bnx2x_cl45_write(bp, phy,
9406a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				 MDIO_PMA_DEVAD,
9407a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				 MDIO_PMA_REG_8727_PCS_GP, val1);
9408a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
9409de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return link_up;
9410b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
9411ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9412de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
9413de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  struct link_params *params)
9414b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
9415b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
941685242eea68f5039458afad0e4030828496bb4034Yaniv Rosner
941785242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	/* Enable/Disable PHY transmitter output */
941885242eea68f5039458afad0e4030828496bb4034Yaniv Rosner	bnx2x_set_disable_pmd_transmit(params, phy, 1);
941985242eea68f5039458afad0e4030828496bb4034Yaniv Rosner
9420de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Disable Transmitter */
9421a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	bnx2x_sfp_set_transmitter(params, phy, 0);
9422a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	/* Clear LASI */
942360d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0);
9424a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9425ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
9426c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner
9427de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
9428de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*		BCM8481/BCM84823/BCM84833 PHY SECTION	          */
9429de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
9430de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_save_848xx_spirom_version(struct bnx2x_phy *phy,
943111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner					    struct bnx2x *bp,
943211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner					    u8 port)
9433ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9434bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u16 val, fw_ver1, fw_ver2, cnt;
9435ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
943611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
943711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD, 0x400f, &fw_ver1);
94388267bbb01f005fa8d0c8d046ecc24ae0b52e4d70Yaniv Rosner		bnx2x_save_spirom_version(bp, port, fw_ver1 & 0xfff,
943911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				phy->ver_addr);
944011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	} else {
944111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* For 32-bit registers in 848xx, access via MDIO2ARM i/f. */
944211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* (1) set reg 0xc200_0014(SPI_BRIDGE_CTRL_2) to 0x03000000 */
944311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0014);
944411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
944511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81B, 0x0000);
944611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81C, 0x0300);
944711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x0009);
944811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner
944911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		for (cnt = 0; cnt < 100; cnt++) {
945011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
945111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			if (val & 1)
945211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				break;
945311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			udelay(5);
945411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		}
945511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		if (cnt == 100) {
945611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			DP(NETIF_MSG_LINK, "Unable to read 848xx "
945711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner					"phy fw version(1)\n");
945811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			bnx2x_save_spirom_version(bp, port, 0,
945911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner						  phy->ver_addr);
946011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			return;
946111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		}
9462c87bca1eaa493779392378b69fe646644580942aYaniv Rosner
9463ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
946411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* 2) read register 0xc200_0000 (SPI_FW_STATUS) */
946511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA819, 0x0000);
946611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA81A, 0xc200);
946711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, 0xA817, 0x000A);
946811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		for (cnt = 0; cnt < 100; cnt++) {
946911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA818, &val);
947011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			if (val & 1)
947111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				break;
947211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			udelay(5);
947311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		}
947411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		if (cnt == 100) {
947511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			DP(NETIF_MSG_LINK, "Unable to read 848xx phy fw "
947611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner					"version(2)\n");
947711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			bnx2x_save_spirom_version(bp, port, 0,
947811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner						  phy->ver_addr);
947911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			return;
948011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		}
9481ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
948211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* lower 16 bits of the register SPI_FW_STATUS */
948311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81B, &fw_ver1);
948411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* upper 16 bits of register SPI_FW_STATUS */
948511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_PMA_DEVAD, 0xA81C, &fw_ver2);
9486ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
948711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_save_spirom_version(bp, port, (fw_ver2<<16) | fw_ver1,
9488de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					  phy->ver_addr);
9489ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
9490ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9491de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
9492de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_848xx_set_led(struct bnx2x *bp,
9493de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				struct bnx2x_phy *phy)
9494ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9495521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u16 val, offset;
94967846e471b5b5cac5e09c8e6ebeb67e18279db8e3Yaniv Rosner
9497de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* PHYC_CTL_LED_CTL */
9498de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9499de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD,
9500bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			MDIO_PMA_REG_8481_LINK_SIGNAL, &val);
9501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val &= 0xFE00;
9502de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val |= 0x0092;
9503345b5d52b93113d3ce82f97c2a783319fbf0fdfdEilon Greenstein
9504de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9505de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
9506bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			 MDIO_PMA_REG_8481_LINK_SIGNAL, val);
9507ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9508de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9509de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
9510bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			 MDIO_PMA_REG_8481_LED1_MASK,
9511de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 0x80);
9512ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9513de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9514de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
9515bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			 MDIO_PMA_REG_8481_LED2_MASK,
9516de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 0x18);
9517ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9518f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner	/* Select activity source by Tx and Rx, as suggested by PHY AE */
9519de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9520de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD,
9521bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			 MDIO_PMA_REG_8481_LED3_MASK,
9522f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner			 0x0006);
9523f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner
9524f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner	/* Select the closest activity blink rate to that in 10/100/1000 */
9525f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner	bnx2x_cl45_write(bp, phy,
9526f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner			MDIO_PMA_DEVAD,
9527bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			MDIO_PMA_REG_8481_LED3_BLINK,
9528f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner			0);
9529f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner
9530521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Configure the blink rate to ~15.9 Hz */
9531521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	bnx2x_cl45_write(bp, phy,
9532f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner			MDIO_PMA_DEVAD,
9533521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_PMA_REG_84823_CTL_SLOW_CLK_CNT_HIGH,
9534521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_PMA_REG_84823_BLINK_RATE_VAL_15P9HZ);
9535f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner
9536521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833)
9537521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		offset = MDIO_PMA_REG_84833_CTL_LED_CTL_1;
9538521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	else
9539521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		offset = MDIO_PMA_REG_84823_CTL_LED_CTL_1;
9540521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9541521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	bnx2x_cl45_read(bp, phy,
9542521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_PMA_DEVAD, offset, &val);
9543521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	val |= MDIO_PMA_REG_84823_LED3_STRETCH_EN; /* stretch_en for LED3*/
9544f25b3c8b5f696cf74adfb37c9d9982c72f4106c9Yaniv Rosner	bnx2x_cl45_write(bp, phy,
9545521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			 MDIO_PMA_DEVAD, offset, val);
9546ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9547de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* 'Interrupt Mask' */
9548de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9549de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD,
9550de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 0xFFFB, 0xFFFD);
9551ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner}
9552ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9553fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_848xx_cmn_config_init(struct bnx2x_phy *phy,
9554fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				       struct link_params *params,
9555fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				       struct link_vars *vars)
9556ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9557c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner	struct bnx2x *bp = params->bp;
9558521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u16 autoneg_val, an_1000_val, an_10_100_val, an_10g_val;
9559bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
9560817a8aa8cfa1ebfb7bf27afb53ebb1ec3d49b564Mintz Yuval	if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
956111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* Save spirom version */
956211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_save_848xx_spirom_version(phy, bp, params->port);
956311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
95642cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
95652cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * This phy uses the NIG latch mechanism since link indication
95662cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * arrives through its LED4 and not via its LASI signal, so we
95672cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * get steady signal instead of clear on read
95682cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
9569de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_bits_en(bp, NIG_REG_LATCH_BC_0 + params->port*4,
9570de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      1 << NIG_LATCH_BC_ENABLE_MI_INT);
9571ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9572de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9573de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 0x0000);
9574ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9575de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_848xx_set_led(bp, phy);
9576ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9577de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* set 1000 speed advertisement */
9578de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9579de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9580de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&an_1000_val);
958157963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
9582de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_set_pause(params, phy, vars);
9583de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9584de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD,
9585de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_REG_8481_LEGACY_AN_ADV,
9586de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&an_10_100_val);
9587de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
9588de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_MII_CTRL,
9589de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&autoneg_val);
9590de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Disable forced speed */
9591de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
9592de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8));
9593ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9594de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9595de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     (phy->speed_cap_mask &
9596de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
9597de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (phy->req_line_speed == SPEED_1000)) {
9598de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		an_1000_val |= (1<<8);
9599de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
9600de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
9601de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			an_1000_val |= (1<<9);
9602de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 1G\n");
9603de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else
9604de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		an_1000_val &= ~((1<<8) | (1<<9));
9605ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9606de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9607de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_1000T_CTRL,
9608de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 an_1000_val);
9609ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
96100520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	/* set 100 speed advertisement */
961175318327802235ecd7e90b0760cceb994bf975caYaniv Rosner	if ((phy->req_line_speed == SPEED_AUTO_NEG) &&
9612de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     (phy->speed_cap_mask &
96130520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	      (PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
961475318327802235ecd7e90b0760cceb994bf975caYaniv Rosner	       PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF))) {
9615de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		an_10_100_val |= (1<<7);
9616de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enable autoneg and restart autoneg for legacy speeds */
9617de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
9618b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9619de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
9620de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			an_10_100_val |= (1<<8);
9621de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 100M\n");
9622de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9623de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* set 10 speed advertisement */
9624de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
96250520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	     (phy->speed_cap_mask &
96260520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	      (PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
96270520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	       PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)) &&
96280520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	     (phy->supported &
96290520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	      (SUPPORTED_10baseT_Half |
96300520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	       SUPPORTED_10baseT_Full)))) {
9631de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		an_10_100_val |= (1<<5);
9632de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
9633de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
9634de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			an_10_100_val |= (1<<6);
9635de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 10M\n");
9636de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9637b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9638de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Only 10/100 are allowed to work in FORCE mode */
96390520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	if ((phy->req_line_speed == SPEED_100) &&
96400520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	    (phy->supported &
96410520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	     (SUPPORTED_100baseT_Half |
96420520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	      SUPPORTED_100baseT_Full))) {
9643de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		autoneg_val |= (1<<13);
9644de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enabled AUTO-MDIX when autoneg is disabled */
9645de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9646de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9647de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 (1<<15 | 1<<9 | 7<<0));
9648521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		/* The PHY needs this set even for forced link. */
9649521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		an_10_100_val |= (1<<8) | (1<<7);
9650de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 100M force\n");
9651de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
96520520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	if ((phy->req_line_speed == SPEED_10) &&
96530520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	    (phy->supported &
96540520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	     (SUPPORTED_10baseT_Half |
96550520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	      SUPPORTED_10baseT_Full))) {
9656de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enabled AUTO-MDIX when autoneg is disabled */
9657de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9658de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD, MDIO_AN_REG_8481_AUX_CTRL,
9659de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 (1<<15 | 1<<9 | 7<<0));
9660de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Setting 10M force\n");
9661de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
9662b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9663de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
9664de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_8481_LEGACY_AN_ADV,
9665de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 an_10_100_val);
9666b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9667de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy->req_duplex == DUPLEX_FULL)
9668de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		autoneg_val |= (1<<8);
9669b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9670fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	/*
9671fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	 * Always write this if this is not 84833.
9672fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	 * For 84833, write it only when it's a forced speed.
9673fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	 */
9674fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	if ((phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) ||
9675fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner		((autoneg_val & (1<<12)) == 0))
9676fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner		bnx2x_cl45_write(bp, phy,
9677de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD,
9678de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_REG_8481_LEGACY_MII_CTRL, autoneg_val);
9679b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9680de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
9681de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	    (phy->speed_cap_mask &
9682de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	     PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)) ||
9683de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		(phy->req_line_speed == SPEED_10000)) {
96849045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			DP(NETIF_MSG_LINK, "Advertising 10G\n");
96859045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			/* Restart autoneg for 10G*/
9686de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
9687521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			bnx2x_cl45_read(bp, phy,
9688521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					MDIO_AN_DEVAD,
9689521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9690521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					&an_10g_val);
96919045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			bnx2x_cl45_write(bp, phy,
9692521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					 MDIO_AN_DEVAD,
9693521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9694521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					 an_10g_val | 0x1000);
9695521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			bnx2x_cl45_write(bp, phy,
9696521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL,
9697521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner					 0x3200);
9698fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner	} else
9699de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
9700de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD,
9701de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_REG_8481_10GBASE_T_AN_CTRL,
9702de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 1);
9703fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner
9704de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
9705b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
9706b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9707fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8481_config_init(struct bnx2x_phy *phy,
9708fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
9709fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
9710ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
9711ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
9712de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Restore normal power mode*/
9713de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
9714cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
9715b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
9716de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* HW reset */
9717de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_hw_reset(bp, params->port);
97186d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
9719ab6ad5a4875e99dffe957a411fe890402a91f67fEilon Greenstein
9720de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
9721de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return bnx2x_848xx_cmn_config_init(phy, params, vars);
9722de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
9723ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
9724521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner#define PHY84833_CMDHDLR_WAIT 300
9725521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner#define PHY84833_CMDHDLR_MAX_ARGS 5
9726521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosnerstatic int bnx2x_84833_cmd_hdlr(struct bnx2x_phy *phy,
9727bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner				   struct link_params *params,
9728521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		   u16 fw_cmd,
9729521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		   u16 cmd_args[])
9730bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner{
9731bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u32 idx;
9732bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u16 val;
9733bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	struct bnx2x *bp = params->bp;
9734bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	/* Write CMD_OPEN_OVERRIDE to STATUS reg */
9735bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9736521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_84833_CMD_HDLR_STATUS,
9737521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			PHY84833_STATUS_CMD_OPEN_OVERRIDE);
9738521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9739bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9740521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_84833_CMD_HDLR_STATUS, &val);
9741521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		if (val == PHY84833_STATUS_CMD_OPEN_FOR_CMDS)
9742bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			break;
9743bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		msleep(1);
9744bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	}
9745521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if (idx >= PHY84833_CMDHDLR_WAIT) {
9746521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		DP(NETIF_MSG_LINK, "FW cmd: FW not ready.\n");
9747bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		return -EINVAL;
9748bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	}
9749bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
9750521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Prepare argument(s) and issue command */
9751521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
9752521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9753521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_84833_CMD_HDLR_DATA1 + idx,
9754521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				cmd_args[idx]);
9755521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	}
9756bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9757521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_84833_CMD_HDLR_COMMAND, fw_cmd);
9758521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	for (idx = 0; idx < PHY84833_CMDHDLR_WAIT; idx++) {
9759bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9760521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_84833_CMD_HDLR_STATUS, &val);
9761521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		if ((val == PHY84833_STATUS_CMD_COMPLETE_PASS) ||
9762521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			(val == PHY84833_STATUS_CMD_COMPLETE_ERROR))
9763bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			break;
9764bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		msleep(1);
9765bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	}
9766521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if ((idx >= PHY84833_CMDHDLR_WAIT) ||
9767521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		(val == PHY84833_STATUS_CMD_COMPLETE_ERROR)) {
9768521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		DP(NETIF_MSG_LINK, "FW cmd failed.\n");
9769bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		return -EINVAL;
9770bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	}
9771521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Gather returning data */
9772521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	for (idx = 0; idx < PHY84833_CMDHDLR_MAX_ARGS; idx++) {
9773521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9774521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_84833_CMD_HDLR_DATA1 + idx,
9775521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				&cmd_args[idx]);
9776521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	}
9777bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9778521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			MDIO_84833_CMD_HDLR_STATUS,
9779521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			PHY84833_STATUS_CMD_CLEAR_COMPLETE);
9780bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	return 0;
9781bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner}
9782bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
97830d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner
9784521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosnerstatic int bnx2x_84833_pair_swap_cfg(struct bnx2x_phy *phy,
9785521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				   struct link_params *params,
9786521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				   struct link_vars *vars)
9787521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner{
9788521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u32 pair_swap;
9789521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u16 data[PHY84833_CMDHDLR_MAX_ARGS];
9790521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	int status;
9791521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	struct bnx2x *bp = params->bp;
9792521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9793521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Check for configuration. */
9794521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	pair_swap = REG_RD(bp, params->shmem_base +
9795521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			   offsetof(struct shmem_region,
9796521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner			dev_info.port_hw_config[params->port].xgbt_phy_cfg)) &
9797521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		PORT_HW_CFG_RJ45_PAIR_SWAP_MASK;
9798521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9799521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if (pair_swap == 0)
9800521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		return 0;
9801521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9802521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Only the second argument is used for this command */
9803521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	data[1] = (u16)pair_swap;
9804521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9805521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	status = bnx2x_84833_cmd_hdlr(phy, params,
9806521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		PHY84833_CMD_SET_PAIR_SWAP, data);
9807521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	if (status == 0)
9808521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		DP(NETIF_MSG_LINK, "Pairswap OK, val=0x%x\n", data[1]);
9809521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9810521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	return status;
9811521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner}
9812521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9813985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosnerstatic u8 bnx2x_84833_get_reset_gpios(struct bnx2x *bp,
9814985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				      u32 shmem_base_path[],
9815985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				      u32 chip_id)
98160d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner{
98170d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	u32 reset_pin[2];
98180d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	u32 idx;
98190d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	u8 reset_gpios;
98200d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	if (CHIP_IS_E3(bp)) {
98210d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		/* Assume that these will be GPIOs, not EPIOs. */
98220d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		for (idx = 0; idx < 2; idx++) {
98230d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			/* Map config param to register bit. */
98240d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
98250d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				offsetof(struct shmem_region,
98260d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				dev_info.port_hw_config[0].e3_cmn_pin_cfg));
98270d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] = (reset_pin[idx] &
98280d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				PORT_HW_CFG_E3_PHY_RESET_MASK) >>
98290d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				PORT_HW_CFG_E3_PHY_RESET_SHIFT;
98300d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] -= PIN_CFG_GPIO0_P0;
98310d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] = (1 << reset_pin[idx]);
98320d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		}
98330d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
98340d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	} else {
98350d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		/* E2, look from diff place of shmem. */
98360d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		for (idx = 0; idx < 2; idx++) {
98370d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] = REG_RD(bp, shmem_base_path[idx] +
98380d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				offsetof(struct shmem_region,
98390d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				dev_info.port_hw_config[0].default_cfg));
98400d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] &= PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK;
98410d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] -= PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0;
98420d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] >>= PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT;
98430d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			reset_pin[idx] = (1 << reset_pin[idx]);
98440d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		}
98450d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		reset_gpios = (u8)(reset_pin[0] | reset_pin[1]);
98460d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	}
98470d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner
9848985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	return reset_gpios;
9849985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner}
9850985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9851985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosnerstatic int bnx2x_84833_hw_reset_phy(struct bnx2x_phy *phy,
9852985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				struct link_params *params)
9853985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner{
9854985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	struct bnx2x *bp = params->bp;
9855985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	u8 reset_gpios;
9856985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	u32 other_shmem_base_addr = REG_RD(bp, params->shmem2_base +
9857985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				offsetof(struct shmem2_region,
9858985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner				other_shmem_base_addr));
9859985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9860985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	u32 shmem_base_path[2];
986199bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner
986299bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner	/* Work around for 84833 LED failure inside RESET status */
986399bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
986499bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner		MDIO_AN_REG_8481_LEGACY_MII_CTRL,
986599bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner		MDIO_AN_REG_8481_MII_CTRL_FORCE_1G);
986699bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_AN_DEVAD,
986799bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner		MDIO_AN_REG_8481_1G_100T_EXT_CTRL,
986899bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner		MIDO_AN_REG_8481_EXT_CTRL_FORCE_LEDS_OFF);
986999bf7f34368aac9b54dfa8801ae490a2326704f9Yaniv Rosner
9870985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	shmem_base_path[0] = params->shmem_base;
9871985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	shmem_base_path[1] = other_shmem_base_addr;
9872985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9873985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path,
9874985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner						  params->chip_id);
9875985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9876985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
9877985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	udelay(10);
9878985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	DP(NETIF_MSG_LINK, "84833 hw reset on pin values 0x%x\n",
9879985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner		reset_gpios);
9880985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9881985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	return 0;
9882985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner}
9883985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
9884a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner#define PHY84833_CONSTANT_LATENCY 1193
9885fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_848x3_config_init(struct bnx2x_phy *phy,
9886fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				   struct link_params *params,
9887fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				   struct link_vars *vars)
9888de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
9889de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
98906a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner	u8 port, initialize = 1;
9891bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u16 val;
9892521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u32 actual_phy_selection, cms_enable;
9893521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u16 cmd_args[PHY84833_CMDHDLR_MAX_ARGS];
9894fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
98957f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
9896de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(1);
9897bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
9898bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	if (!(CHIP_IS_E1(bp)))
98996a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner		port = BP_PATH(bp);
99006a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner	else
99016a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner		port = params->port;
9902bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
9903bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9904bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
9905bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
9906bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			       port);
9907bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	} else {
9908985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner		/* MDIO reset */
9909bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		bnx2x_cl45_write(bp, phy,
9910bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner				MDIO_PMA_DEVAD,
9911bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner				MDIO_PMA_REG_CTRL, 0x8000);
9912521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	}
9913521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9914521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
9915521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
9916521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	/* Wait for GPHY to come out of reset */
9917521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	msleep(50);
991811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (phy->type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
9919521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		/*
9920521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		 * BCM84823 requires that XGXS links up first @ 10G for normal
9921521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		 * behavior.
9922521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		 */
9923521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		u16 temp;
9924521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		temp = vars->line_speed;
9925521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		vars->line_speed = SPEED_10000;
9926521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		bnx2x_set_autoneg(&params->phy[INT_PHY], params, vars, 0);
9927521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		bnx2x_program_serdes(&params->phy[INT_PHY], params, vars);
9928521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		vars->line_speed = temp;
9929521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	}
9930a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9931a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
9932bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			MDIO_CTL_REG_84823_MEDIA, &val);
9933a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
9934a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 MDIO_CTL_REG_84823_MEDIA_LINE_MASK |
9935a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN |
9936a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 MDIO_CTL_REG_84823_MEDIA_PRIORITY_MASK |
9937a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		 MDIO_CTL_REG_84823_MEDIA_FIBER_1G);
99380d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner
99390d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	if (CHIP_IS_E3(bp)) {
99400d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		val &= ~(MDIO_CTL_REG_84823_MEDIA_MAC_MASK |
99410d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			 MDIO_CTL_REG_84823_MEDIA_LINE_MASK);
99420d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	} else {
99430d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		val |= (MDIO_CTL_REG_84823_CTRL_MAC_XFI |
99440d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner			MDIO_CTL_REG_84823_MEDIA_LINE_XAUI_L);
99450d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	}
9946a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9947a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	actual_phy_selection = bnx2x_phy_selection(params);
9948a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9949a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	switch (actual_phy_selection) {
9950a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT:
995125985edcedea6396277003854657b5f3cb31a628Lucas De Marchi		/* Do nothing. Essentially this is like the priority copper */
9952a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
9953a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
9954a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_COPPER;
9955a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
9956a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
9957a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		val |= MDIO_CTL_REG_84823_MEDIA_PRIORITY_FIBER;
9958a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
9959a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
9960a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* Do nothing here. The first PHY won't be initialized at all */
9961a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
9962a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
9963a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		val |= MDIO_CTL_REG_84823_MEDIA_COPPER_CORE_DOWN;
9964a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		initialize = 0;
9965a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
9966a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
9967a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (params->phy[EXT_PHY2].req_line_speed == SPEED_1000)
9968a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		val |= MDIO_CTL_REG_84823_MEDIA_FIBER_1G;
9969a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
9970a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
9971bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			 MDIO_CTL_REG_84823_MEDIA, val);
9972a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	DP(NETIF_MSG_LINK, "Multi_phy config = 0x%x, Media control = 0x%x\n",
9973a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		   params->multi_phy_config, val);
9974a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
997511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
997611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_84833_pair_swap_cfg(phy, params, vars);
9977a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner
9978096b9527db77defb2501509f2517d2ab24300d9cYaniv Rosner		/* Keep AutogrEEEn disabled. */
9979096b9527db77defb2501509f2517d2ab24300d9cYaniv Rosner		cmd_args[0] = 0x0;
998011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		cmd_args[1] = 0x0;
998111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		cmd_args[2] = PHY84833_CONSTANT_LATENCY + 1;
998211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		cmd_args[3] = PHY84833_CONSTANT_LATENCY;
998311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		rc = bnx2x_84833_cmd_hdlr(phy, params,
998411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			PHY84833_CMD_SET_EEE_MODE, cmd_args);
998511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		if (rc != 0)
998611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			DP(NETIF_MSG_LINK, "Cfg AutogrEEEn failed.\n");
998711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
9988a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (initialize)
9989a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		rc = bnx2x_848xx_cmn_config_init(phy, params, vars);
9990a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	else
999111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_save_848xx_spirom_version(phy, bp, params->port);
9992a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	/* 84833 PHY has a better feature and doesn't need to support this. */
9993a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
9994a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		cms_enable = REG_RD(bp, params->shmem_base +
99951bef68e3f5d25e17adc5232dc0ad7c0ea0188374Yaniv Rosner			offsetof(struct shmem_region,
99961bef68e3f5d25e17adc5232dc0ad7c0ea0188374Yaniv Rosner			dev_info.port_hw_config[params->port].default_cfg)) &
99971bef68e3f5d25e17adc5232dc0ad7c0ea0188374Yaniv Rosner			PORT_HW_CFG_ENABLE_CMS_MASK;
99981bef68e3f5d25e17adc5232dc0ad7c0ea0188374Yaniv Rosner
9999a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_CTL_DEVAD,
10000a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				MDIO_CTL_REG_84823_USER_CTRL_REG, &val);
10001a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		if (cms_enable)
10002a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			val |= MDIO_CTL_REG_84823_USER_CTRL_CMS;
10003a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		else
10004a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			val &= ~MDIO_CTL_REG_84823_USER_CTRL_CMS;
10005a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl45_write(bp, phy, MDIO_CTL_DEVAD,
10006a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_CTL_REG_84823_USER_CTRL_REG, val);
10007a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	}
100081bef68e3f5d25e17adc5232dc0ad7c0ea0188374Yaniv Rosner
1000911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) {
1001011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		/* Bring PHY out of super isolate mode as the final step. */
1001111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_read(bp, phy,
1001211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				MDIO_CTL_DEVAD,
1001311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
1001411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		val &= ~MDIO_84833_SUPER_ISOLATE;
1001511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_write(bp, phy,
1001611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				MDIO_CTL_DEVAD,
1001711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
1001811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
10019a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	return rc;
10020de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
10021ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10022de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_848xx_read_status(struct bnx2x_phy *phy,
10023cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  struct link_params *params,
10024cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				  struct link_vars *vars)
10025de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
10026de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
10027bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u16 val, val1, val2;
10028de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up = 0;
10029ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10030c87bca1eaa493779392378b69fe646644580942aYaniv Rosner
10031de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check 10G-BaseT link status */
10032de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check PMD signal ok */
10033de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10034de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, 0xFFFA, &val1);
10035de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10036bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_8481_PMD_SIGNAL,
10037de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&val2);
10038de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "BCM848xx: PMD_SIGNAL 1.a811 = 0x%x\n", val2);
10039ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10040de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Check link 10G */
10041de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (val2 & (1<<11)) {
10042ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		vars->line_speed = SPEED_10000;
10043791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		vars->duplex = DUPLEX_FULL;
10044de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = 1;
10045de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10046de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	} else { /* Check Legacy speed link */
10047de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		u16 legacy_status, legacy_speed;
10048ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10049de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Enable expansion register 0x42 (Operation mode status) */
10050de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
10051de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_DEVAD,
10052de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_AN_REG_8481_EXPANSION_REG_ACCESS, 0xf42);
10053ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10054de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Get legacy speed operation status */
10055de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
10056de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_DEVAD,
10057de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_REG_8481_EXPANSION_REG_RD_RW,
10058de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&legacy_status);
10059ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1006094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK, "Legacy speed status = 0x%x\n",
1006194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   legacy_status);
10062de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		link_up = ((legacy_status & (1<<11)) == (1<<11));
10063de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (link_up) {
10064de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			legacy_speed = (legacy_status & (3<<9));
10065de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			if (legacy_speed == (0<<9))
10066de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_10;
10067de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			else if (legacy_speed == (1<<9))
10068de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_100;
10069de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			else if (legacy_speed == (2<<9))
10070de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = SPEED_1000;
10071de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			else /* Should not happen */
10072de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->line_speed = 0;
10073ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10074de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			if (legacy_status & (1<<8))
10075de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_FULL;
10076de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			else
10077de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->duplex = DUPLEX_HALF;
10078ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
1007994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			DP(NETIF_MSG_LINK,
1008094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   "Link is up in %dMbps, is_duplex_full= %d\n",
1008194f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   vars->line_speed,
1008294f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches			   (vars->duplex == DUPLEX_FULL));
10083de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* Check legacy speed AN resolution */
10084de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_read(bp, phy,
10085de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_AN_DEVAD,
10086de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_AN_REG_8481_LEGACY_MII_STATUS,
10087de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					&val);
10088de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			if (val & (1<<5))
10089de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->link_status |=
10090de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
10091de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			bnx2x_cl45_read(bp, phy,
10092de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_AN_DEVAD,
10093de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					MDIO_AN_REG_8481_LEGACY_AN_EXPANSION,
10094de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					&val);
10095de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			if ((val & (1<<0)) == 0)
10096de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				vars->link_status |=
10097de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					LINK_STATUS_PARALLEL_DETECTION_USED;
10098ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner		}
10099ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	}
10100de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up) {
10101de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "BCM84823: link speed is %d\n",
10102de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   vars->line_speed);
10103de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
101049e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
101059e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* Read LP advertised speeds */
101069e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
101079e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_CL37_FC_LP, &val);
101089e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<5))
101099e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101109e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
101119e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<6))
101129e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101139e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
101149e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<7))
101159e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101169e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
101179e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<8))
101189e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101199e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
101209e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<9))
101219e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101229e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
101239e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
101249e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
101259e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_1000T_STATUS, &val);
101269e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
101279e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<10))
101289e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101299e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
101309e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<11))
101319e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101329e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
101339e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
101349e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		bnx2x_cl45_read(bp, phy, MDIO_AN_DEVAD,
101359e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				MDIO_AN_REG_MASTER_STATUS, &val);
101369e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
101379e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val & (1<<11))
101389e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
101399e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10140de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
10141589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
10142de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return link_up;
10143b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
10144b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
10145fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner
10146fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_848xx_format_ver(u32 raw_ver, u8 *str, u16 *len)
10147b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
10148fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int status = 0;
10149de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 spirom_ver;
10150de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	spirom_ver = ((raw_ver & 0xF80) >> 7) << 16 | (raw_ver & 0x7F);
10151de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	status = bnx2x_format_ver(spirom_ver, str, len);
10152de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return status;
10153b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
10154de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
10155de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_8481_hw_reset(struct bnx2x_phy *phy,
10156de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				struct link_params *params)
10157b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
10158de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10159cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 0);
10160de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10161cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, 1);
10162b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
10163de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
10164b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic void bnx2x_8481_link_reset(struct bnx2x_phy *phy,
10165b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner					struct link_params *params)
10166b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
10167b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	bnx2x_cl45_write(params->bp, phy,
10168b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, 0x0000);
10169b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	bnx2x_cl45_write(params->bp, phy,
10170b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1);
10171b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
10172b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
10173b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic void bnx2x_848x3_link_reset(struct bnx2x_phy *phy,
10174b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner				   struct link_params *params)
10175b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
10176b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
101776a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner	u8 port;
101780d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	u16 val16;
10179bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
10180f93fb01628c00d1f26e8b45d2f10b8feb650dd4bYaniv Rosner	if (!(CHIP_IS_E1x(bp)))
101816a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner		port = BP_PATH(bp);
101826a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner	else
101836a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner		port = params->port;
10184bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
10185bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823) {
10186bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_3,
10187bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			       MISC_REGISTERS_GPIO_OUTPUT_LOW,
10188bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner			       port);
10189bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	} else {
101900d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		bnx2x_cl45_read(bp, phy,
101910d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				MDIO_CTL_DEVAD,
1019211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val16);
1019311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		val16 |= MDIO_84833_SUPER_ISOLATE;
10194fd38f73eb936f9d9f28e4f7ff598cc0780e09424Yaniv Rosner		bnx2x_cl45_write(bp, phy,
1019511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				 MDIO_CTL_DEVAD,
1019611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val16);
10197bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	}
10198b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
10199b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
102007f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosnerstatic void bnx2x_848xx_set_link_led(struct bnx2x_phy *phy,
102017f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner				     struct link_params *params, u8 mode)
102027f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner{
102037f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	struct bnx2x *bp = params->bp;
102047f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	u16 val;
10205bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	u8 port;
10206bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner
10207f93fb01628c00d1f26e8b45d2f10b8feb650dd4bYaniv Rosner	if (!(CHIP_IS_E1x(bp)))
10208bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		port = BP_PATH(bp);
10209bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner	else
10210bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		port = params->port;
102117f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102127f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	switch (mode) {
102137f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OFF:
102147f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
10215bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OFF\n", port);
102167f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102177f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
102187f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		    SHARED_HW_CFG_LED_EXTPHY1) {
102197f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102207f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set LED masks */
102217f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102227f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
102237f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LED1_MASK,
102247f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					0x0);
102257f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102267f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102277f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
102287f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LED2_MASK,
102297f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					0x0);
102307f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102317f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102327f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
102337f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LED3_MASK,
102347f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					0x0);
102357f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102367f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102377f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
102387f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LED5_MASK,
102397f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					0x0);
102407f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102417f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		} else {
102427f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102437f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_DEVAD,
102447f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
102457f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 0x0);
102467f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		}
102477f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
102487f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_FRONT_PANEL_OFF:
102497f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102507f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE FRONT PANEL OFF\n",
10251bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		   port);
102527f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102537f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
102547f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		    SHARED_HW_CFG_LED_EXTPHY1) {
102557f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102567f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set LED masks */
102577f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10258cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10259cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
10260cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x0);
102617f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102627f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10263cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10264cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED2_MASK,
10265cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x0);
102667f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102677f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10268cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10269cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED3_MASK,
10270cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x0);
102717f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102727f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10273cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10274cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED5_MASK,
10275cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x20);
102767f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102777f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		} else {
102787f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
102797f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_DEVAD,
102807f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
102817f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 0x0);
102827f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		}
102837f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
102847f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_ON:
102857f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
10286bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE ON\n", port);
102877f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102887f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
102897f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		    SHARED_HW_CFG_LED_EXTPHY1) {
102907f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set control reg */
102917f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_read(bp, phy,
102927f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
102937f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LINK_SIGNAL,
102947f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					&val);
102957f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			val &= 0x8000;
102967f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			val |= 0x2492;
102977f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
102987f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10299cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10300cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LINK_SIGNAL,
10301cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 val);
103027f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103037f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set LED masks */
103047f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10305cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10306cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
10307cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x0);
103087f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103097f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10310cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10311cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED2_MASK,
10312cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x20);
103137f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103147f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10315cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10316cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED3_MASK,
10317cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x20);
103187f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103197f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10320cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10321cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED5_MASK,
10322cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x0);
103237f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		} else {
103247f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10325cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10326cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
10327cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x20);
103287f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		}
103297f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
103307f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103317f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OPER:
103327f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
10333bac27bd941454aaf40f7876ce3b487e303c4953dYaniv Rosner		DP(NETIF_MSG_LINK, "Port 0x%x: LED MODE OPER\n", port);
103347f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103357f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		if ((params->hw_led_mode << SHARED_HW_CFG_LED_MODE_SHIFT) ==
103367f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		    SHARED_HW_CFG_LED_EXTPHY1) {
103377f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103387f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set control reg */
103397f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_read(bp, phy,
103407f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_DEVAD,
103417f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					MDIO_PMA_REG_8481_LINK_SIGNAL,
103427f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					&val);
103437f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103447f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			if (!((val &
10345cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_MASK)
10346cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  >> MDIO_PMA_REG_8481_LINK_SIGNAL_LED4_ENABLE_SHIFT)) {
103472cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner				DP(NETIF_MSG_LINK, "Setting LINK_SIGNAL\n");
103487f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner				bnx2x_cl45_write(bp, phy,
103497f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner						 MDIO_PMA_DEVAD,
103507f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner						 MDIO_PMA_REG_8481_LINK_SIGNAL,
103517f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner						 0xa492);
103527f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			}
103537f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103547f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			/* Set LED masks */
103557f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10356cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10357cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
10358cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x10);
103597f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103607f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10361cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10362cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED2_MASK,
10363cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x80);
103647f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103657f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10366cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10367cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED3_MASK,
10368cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x98);
103697f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103707f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
10371cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_DEVAD,
10372cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 MDIO_PMA_REG_8481_LED5_MASK,
10373cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					 0x40);
103747f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
103757f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		} else {
103767f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			bnx2x_cl45_write(bp, phy,
103777f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_DEVAD,
103787f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 MDIO_PMA_REG_8481_LED1_MASK,
103797f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner					 0x80);
1038053eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner
1038153eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner			/* Tell LED3 to blink on source */
1038253eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner			bnx2x_cl45_read(bp, phy,
1038353eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					MDIO_PMA_DEVAD,
1038453eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					MDIO_PMA_REG_8481_LINK_SIGNAL,
1038553eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					&val);
1038653eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner			val &= ~(7<<6);
1038753eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner			val |= (1<<6); /* A83B[8:6]= 1 */
1038853eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner			bnx2x_cl45_write(bp, phy,
1038953eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					 MDIO_PMA_DEVAD,
1039053eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					 MDIO_PMA_REG_8481_LINK_SIGNAL,
1039153eda06def26862c0a3c57348c71a240429fbaacYaniv Rosner					 val);
103927f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		}
103937f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
103947f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	}
103950d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner
103960d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	/*
103970d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	 * This is a workaround for E3+84833 until autoneg
103980d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	 * restart is fixed in f/w
103990d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	 */
104000d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	if (CHIP_IS_E3(bp)) {
104010d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		bnx2x_cl45_read(bp, phy, MDIO_WC_DEVAD,
104020d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner				MDIO_WC_REG_GP2_STATUS_GP_2_1, &val);
104030d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	}
104047f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner}
104050d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner
10406de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
1040752c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner/*			54618SE PHY SECTION			  */
104086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner/******************************************************************/
1040952c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosnerstatic int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
104106583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner					       struct link_params *params,
104116583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner					       struct link_vars *vars)
104126583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
104136583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	struct bnx2x *bp = params->bp;
104146583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u8 port;
104156583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u16 autoneg_val, an_1000_val, an_10_100_val, fc_val, temp;
104166583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u32 cfg_pin;
104176583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1041852c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	DP(NETIF_MSG_LINK, "54618SE cfg init\n");
104196583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	usleep_range(1000, 1000);
104206583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104212f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	/*
104222f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * This works with E3 only, no need to check the chip
104232f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 * before determining the port.
104242f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	 */
104256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	port = params->port;
104266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	cfg_pin = (REG_RD(bp, params->shmem_base +
104286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			offsetof(struct shmem_region,
104296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
104306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
104316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
104326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Drive pin high to bring the GPHY out of reset. */
104346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_set_cfg_pin(bp, cfg_pin, 1);
104356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104366583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* wait for GPHY to reset */
104376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	msleep(50);
104386583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104396583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* reset phy */
104406583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104416583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			 MDIO_PMA_REG_CTRL, 0x8000);
104426583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
104436583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104446583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/*wait for GPHY to reset */
104456583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	msleep(50);
104466583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104476583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Configure LED4: set to INTR (0x6). */
104486583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Accessing shadow register 0xe. */
104496583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104506583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104516583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW_LED_SEL2);
104526583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
104536583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104546583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&temp);
104556583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	temp &= ~(0xf << 4);
104566583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	temp |= (0x6 << 4);
104576583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104586583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104596583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
104606583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Configure INTR based on link status change. */
104616583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104626583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_INTR_MASK,
104636583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			~MDIO_REG_INTR_MASK_LINK_STATUS);
104646583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104656583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Flip the signal detect polarity (set 0x1c.0x1e[8]). */
104666583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104676583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104686583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW_AUTO_DET_MED);
104696583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
104706583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104716583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&temp);
104726583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	temp |= MDIO_REG_GPHY_SHADOW_INVERT_FIB_SD;
104736583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
104746583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW,
104756583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
104766583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104776583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Set up fc */
104786583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
104796583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_calc_ieee_aneg_adv(phy, params, &vars->ieee_fc);
104806583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	fc_val = 0;
104816583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
104826583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC)
104836583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		fc_val |= MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
104846583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104856583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if ((vars->ieee_fc & MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
104866583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH)
104876583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		fc_val |= MDIO_AN_REG_ADV_PAUSE_PAUSE;
104886583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104896583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* read all advertisement */
104906583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
104916583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x09,
104926583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&an_1000_val);
104936583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104946583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
104956583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x04,
104966583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&an_10_100_val);
104976583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
104986583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
104996583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_PMA_REG_CTRL,
105006583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&autoneg_val);
105016583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105026583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Disable forced speed */
105036583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	autoneg_val &= ~((1<<6) | (1<<8) | (1<<9) | (1<<12) | (1<<13));
105046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	an_10_100_val &= ~((1<<5) | (1<<6) | (1<<7) | (1<<8) | (1<<10) |
105056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   (1<<11));
105066583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105076583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
105086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(phy->speed_cap_mask &
105096583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)) ||
105106583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(phy->req_line_speed == SPEED_1000)) {
105116583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		an_1000_val |= (1<<8);
105126583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
105136583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
105146583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			an_1000_val |= (1<<9);
105156583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 1G\n");
105166583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	} else
105176583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		an_1000_val &= ~((1<<8) | (1<<9));
105186583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105196583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
105206583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x09,
105216583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			an_1000_val);
105226583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
105236583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x09,
105246583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&an_1000_val);
105256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set 100 speed advertisement */
105276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
105286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(phy->speed_cap_mask &
105296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_FULL |
105306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_SPEED_CAPABILITY_D0_100M_HALF)))) {
105316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		an_10_100_val |= (1<<7);
105326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		/* Enable autoneg and restart autoneg for legacy speeds */
105336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
105346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
105366583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			an_10_100_val |= (1<<8);
105376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 100M\n");
105386583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
105396583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105406583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set 10 speed advertisement */
105416583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (((phy->req_line_speed == SPEED_AUTO_NEG) &&
105426583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(phy->speed_cap_mask &
105436583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			(PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL |
105446583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_HALF)))) {
105456583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		an_10_100_val |= (1<<5);
105466583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		autoneg_val |= (1<<9 | 1<<12);
105476583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (phy->req_duplex == DUPLEX_FULL)
105486583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			an_10_100_val |= (1<<6);
105496583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "Advertising 10M\n");
105506583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
105516583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105526583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Only 10/100 are allowed to work in FORCE mode */
105536583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (phy->req_line_speed == SPEED_100) {
105546583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		autoneg_val |= (1<<13);
105556583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		/* Enabled AUTO-MDIX when autoneg is disabled */
105566583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		bnx2x_cl22_write(bp, phy,
105576583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				0x18,
105586583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				(1<<15 | 1<<9 | 7<<0));
105596583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "Setting 100M force\n");
105606583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
105616583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (phy->req_line_speed == SPEED_10) {
105626583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		/* Enabled AUTO-MDIX when autoneg is disabled */
105636583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		bnx2x_cl22_write(bp, phy,
105646583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				0x18,
105656583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				(1<<15 | 1<<9 | 7<<0));
105666583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		DP(NETIF_MSG_LINK, "Setting 10M force\n");
105676583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
105686583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
10569a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	/* Check if we should turn on Auto-GrEEEn */
10570a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &temp);
10571a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	if (temp == MDIO_REG_GPHY_ID_54618SE) {
10572a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		if (params->feature_config_flags &
10573a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		    FEATURE_CONFIG_AUTOGREEEN_ENABLED) {
10574a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			temp = 6;
10575a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			DP(NETIF_MSG_LINK, "Enabling Auto-GrEEEn\n");
10576a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		} else {
10577a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			temp = 0;
10578a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner			DP(NETIF_MSG_LINK, "Disabling Auto-GrEEEn\n");
10579a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		}
10580a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl22_write(bp, phy,
10581a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_REG_GPHY_CL45_ADDR_REG, MDIO_AN_DEVAD);
10582a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl22_write(bp, phy,
10583a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_REG_GPHY_CL45_DATA_REG,
10584a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_REG_GPHY_EEE_ADV);
10585a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl22_write(bp, phy,
10586a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_REG_GPHY_CL45_ADDR_REG,
10587a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 (0x1 << 14) | MDIO_AN_DEVAD);
10588a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner		bnx2x_cl22_write(bp, phy,
10589a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 MDIO_REG_GPHY_CL45_DATA_REG,
10590a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner				 temp);
10591a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner	}
10592a89a1d4a738668ccb2270ac218cddd30f0bef2a0Yaniv Rosner
105936583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
105946583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x04,
105956583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			an_10_100_val | fc_val);
105966583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
105976583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (phy->req_duplex == DUPLEX_FULL)
105986583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		autoneg_val |= (1<<8);
105996583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106006583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy,
106016583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_PMA_REG_CTRL, autoneg_val);
106026583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106036583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	return 0;
106046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
106056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106061d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner
106071d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosnerstatic void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
106081d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner				       struct link_params *params, u8 mode)
106091d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner{
106101d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	struct bnx2x *bp = params->bp;
106111d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	u16 temp;
106121d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner
106131d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	bnx2x_cl22_write(bp, phy,
106141d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		MDIO_REG_GPHY_SHADOW,
106151d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		MDIO_REG_GPHY_SHADOW_LED_SEL1);
106161d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	bnx2x_cl22_read(bp, phy,
106171d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		MDIO_REG_GPHY_SHADOW,
106181d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		&temp);
106191d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	temp &= 0xff00;
106201d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner
106211d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
106221d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	switch (mode) {
106231d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	case LED_MODE_FRONT_PANEL_OFF:
106241d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	case LED_MODE_OFF:
106251d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		temp |= 0x00ee;
106261d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		break;
106271d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	case LED_MODE_OPER:
106281d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		temp |= 0x0001;
106291d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		break;
106301d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	case LED_MODE_ON:
106311d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		temp |= 0x00ff;
106321d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		break;
106331d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	default:
106341d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		break;
106351d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	}
106361d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	bnx2x_cl22_write(bp, phy,
106371d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		MDIO_REG_GPHY_SHADOW,
106381d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner		MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
106391d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	return;
106401d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner}
106411d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner
106421d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner
1064352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosnerstatic void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
1064452c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				     struct link_params *params)
106456583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
106466583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	struct bnx2x *bp = params->bp;
106476583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u32 cfg_pin;
106486583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u8 port;
106496583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
10650d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	/*
10651d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 * In case of no EPIO routed to reset the GPHY, put it
10652d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 * in low power mode.
10653d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 */
10654d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	bnx2x_cl22_write(bp, phy, MDIO_PMA_REG_CTRL, 0x800);
10655d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	/*
10656d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 * This works with E3 only, no need to check the chip
10657d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 * before determining the port.
10658d2059a061164120a1e44a0ca46fe08044d6d7c2dYaniv Rosner	 */
106596583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	port = params->port;
106606583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	cfg_pin = (REG_RD(bp, params->shmem_base +
106616583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			offsetof(struct shmem_region,
106626583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			dev_info.port_hw_config[port].e3_cmn_pin_cfg)) &
106636583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_E3_PHY_RESET_MASK) >>
106646583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			PORT_HW_CFG_E3_PHY_RESET_SHIFT;
106656583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106666583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Drive pin low to put GPHY in reset. */
106676583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_set_cfg_pin(bp, cfg_pin, 0);
106686583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
106696583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1067052c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosnerstatic u8 bnx2x_54618se_read_status(struct bnx2x_phy *phy,
1067152c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				    struct link_params *params,
1067252c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				    struct link_vars *vars)
106736583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
106746583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	struct bnx2x *bp = params->bp;
106756583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u16 val;
106766583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u8 link_up = 0;
106776583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u16 legacy_status, legacy_speed;
106786583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106796583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Get speed operation status */
106806583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
106816583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			0x19,
106826583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&legacy_status);
1068352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	DP(NETIF_MSG_LINK, "54618SE read_status: 0x%x\n", legacy_status);
106846583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106856583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Read status to clear the PHY interrupt. */
106866583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy,
106876583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			MDIO_REG_INTR_STATUS,
106886583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			&val);
106896583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106906583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	link_up = ((legacy_status & (1<<2)) == (1<<2));
106916583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
106926583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	if (link_up) {
106936583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		legacy_speed = (legacy_status & (7<<8));
106946583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (legacy_speed == (7<<8)) {
106956583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_1000;
106966583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_FULL;
106976583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		} else if (legacy_speed == (6<<8)) {
106986583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_1000;
106996583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_HALF;
107006583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		} else if (legacy_speed == (5<<8)) {
107016583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_100;
107026583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_FULL;
107036583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		}
107046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		/* Omitting 100Base-T4 for now */
107056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		else if (legacy_speed == (3<<8)) {
107066583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_100;
107076583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_HALF;
107086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		} else if (legacy_speed == (2<<8)) {
107096583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_10;
107106583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_FULL;
107116583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		} else if (legacy_speed == (1<<8)) {
107126583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = SPEED_10;
107136583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->duplex = DUPLEX_HALF;
107146583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		} else /* Should not happen */
107156583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->line_speed = 0;
107166583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1071794f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		DP(NETIF_MSG_LINK,
1071894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   "Link is up in %dMbps, is_duplex_full= %d\n",
1071994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   vars->line_speed,
1072094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches		   (vars->duplex == DUPLEX_FULL));
107216583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
107226583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		/* Check legacy speed AN resolution */
107236583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		bnx2x_cl22_read(bp, phy,
107246583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				0x01,
107256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				&val);
107266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if (val & (1<<5))
107276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->link_status |=
107286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
107296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		bnx2x_cl22_read(bp, phy,
107306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				0x06,
107316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				&val);
107326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		if ((val & (1<<0)) == 0)
107336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			vars->link_status |=
107346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner				LINK_STATUS_PARALLEL_DETECTION_USED;
107356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1073652c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		DP(NETIF_MSG_LINK, "BCM54618SE: link speed is %d\n",
107376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   vars->line_speed);
1073852c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner
1073952c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		/* Report whether EEE is resolved. */
1074052c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		bnx2x_cl22_read(bp, phy, MDIO_REG_GPHY_PHYID_LSB, &val);
1074152c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		if (val == MDIO_REG_GPHY_ID_54618SE) {
1074252c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner			if (vars->link_status &
1074352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner			    LINK_STATUS_AUTO_NEGOTIATE_COMPLETE)
1074452c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				val = 0;
1074552c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner			else {
1074652c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				bnx2x_cl22_write(bp, phy,
1074752c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_REG_GPHY_CL45_ADDR_REG,
1074852c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_AN_DEVAD);
1074952c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				bnx2x_cl22_write(bp, phy,
1075052c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_REG_GPHY_CL45_DATA_REG,
1075152c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_REG_GPHY_EEE_RESOLVED);
1075252c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				bnx2x_cl22_write(bp, phy,
1075352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_REG_GPHY_CL45_ADDR_REG,
1075452c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					(0x1 << 14) | MDIO_AN_DEVAD);
1075552c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner				bnx2x_cl22_read(bp, phy,
1075652c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					MDIO_REG_GPHY_CL45_DATA_REG,
1075752c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					&val);
1075852c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner			}
1075952c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner			DP(NETIF_MSG_LINK, "EEE resolution: 0x%x\n", val);
1076052c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		}
1076152c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner
107626583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
107639e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
107649e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (vars->link_status & LINK_STATUS_AUTO_NEGOTIATE_COMPLETE) {
107659e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			/* report LP advertised speeds */
107669e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			bnx2x_cl22_read(bp, phy, 0x5, &val);
107679e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
107689e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<5))
107699e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107709e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_10THD_CAPABLE;
107719e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<6))
107729e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107739e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_10TFD_CAPABLE;
107749e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<7))
107759e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107769e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_100TXHD_CAPABLE;
107779e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<8))
107789e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107799e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_100TXFD_CAPABLE;
107809e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<9))
107819e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107829e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_100T4_CAPABLE;
107839e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
107849e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			bnx2x_cl22_read(bp, phy, 0xa, &val);
107859e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<10))
107869e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107879e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_1000THD_CAPABLE;
107889e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			if (val & (1<<11))
107899e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				vars->link_status |=
107909e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				  LINK_STATUS_LINK_PARTNER_1000TFD_CAPABLE;
107919e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		}
107926583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	}
107936583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	return link_up;
107946583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
107956583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1079652c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosnerstatic void bnx2x_54618se_config_loopback(struct bnx2x_phy *phy,
1079752c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner					  struct link_params *params)
107986583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner{
107996583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	struct bnx2x *bp = params->bp;
108006583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u16 val;
108016583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
108026583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
1080352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	DP(NETIF_MSG_LINK, "2PMA/PMD ext_phy_loopback: 54618se\n");
108046583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108056583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Enable master/slave manual mmode and set to master */
108066583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* mii write 9 [bits set 11 12] */
108076583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy, 0x09, 3<<11);
108086583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108096583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* forced 1G and disable autoneg */
108106583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set val [mii read 0] */
108116583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set val [expr $val & [bits clear 6 12 13]] */
108126583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set val [expr $val | [bits set 6 8]] */
108136583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* mii write 0 $val */
108146583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy, 0x00, &val);
108156583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	val &= ~((1<<6) | (1<<12) | (1<<13));
108166583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	val |= (1<<6) | (1<<8);
108176583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy, 0x00, val);
108186583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108196583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* Set external loopback and Tx using 6dB coding */
108206583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* mii write 0x18 7 */
108216583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* set val [mii read 0x18] */
108226583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* mii write 0x18 [expr $val | [bits set 10 15]] */
108236583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy, 0x18, 7);
108246583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_read(bp, phy, 0x18, &val);
108256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	bnx2x_cl22_write(bp, phy, 0x18, val | (1<<10) | (1<<15));
108266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* This register opens the gate for the UMAC despite its name */
108286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
108296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/*
108316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	 * Maximum Frame Length (RW). Defines a 14-Bit maximum frame
108326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	 * length used by the MAC receive logic to check frames.
108336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	 */
108346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	REG_WR(bp, umac_base + UMAC_REG_MAXFR, 0x2710);
108356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner}
108366583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner
108376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner/******************************************************************/
10838de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			SFX7101 PHY SECTION			  */
10839de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
10840de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_7101_config_loopback(struct bnx2x_phy *phy,
10841de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       struct link_params *params)
10842b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
10843b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
10844de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* SFX7101_XGXS_TEST1 */
10845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
10846de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_XS_DEVAD, MDIO_XS_SFX7101_XGXS_TEST1, 0x100);
10847589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein}
10848589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein
10849fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_7101_config_init(struct bnx2x_phy *phy,
10850fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_params *params,
10851fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct link_vars *vars)
10852ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner{
10853de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 fw_ver1, fw_ver2, val;
10854ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner	struct bnx2x *bp = params->bp;
10855de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Setting the SFX7101 LASI indication\n");
10856ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10857de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Restore normal power mode*/
10858de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
10859cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
10860de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* HW reset */
10861de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_hw_reset(bp, params->port);
108626d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	bnx2x_wait_reset_complete(bp, phy, params);
10863ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10864de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
1086560d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_LASI_CTRL, 0x1);
10866de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Setting the SFX7101 LED to blink on traffic\n");
10867de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
10868de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_PMA_DEVAD, MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
10869ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10870de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_ext_phy_set_pause(params, phy, vars);
10871de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Restart autoneg */
10872de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10873de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, &val);
10874de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val |= 0x200;
10875de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_write(bp, phy,
10876de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			 MDIO_AN_DEVAD, MDIO_AN_REG_CTRL, val);
10877ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10878de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Save spirom version */
10879de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10880de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER1, &fw_ver1);
10881ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10882de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10883de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2, &fw_ver2);
10884de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_save_spirom_version(bp, params->port,
10885de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				  (u32)(fw_ver1<<16 | fw_ver2), phy->ver_addr);
10886de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
10887de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
10888ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10889de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u8 bnx2x_7101_read_status(struct bnx2x_phy *phy,
10890de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_params *params,
10891de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 struct link_vars *vars)
1089257963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner{
1089357963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner	struct bnx2x *bp = params->bp;
10894de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u8 link_up;
10895de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val1, val2;
10896de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
1089760d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val2);
10898de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
1089960d2fe0312b3301fb5a65e9ed0b44465c8237055Yaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_LASI_STAT, &val1);
10900de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "10G-base-T LASI status 0x%x->0x%x\n",
10901de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   val2, val1);
10902de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10903de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val2);
10904de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10905de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			MDIO_PMA_DEVAD, MDIO_PMA_REG_STATUS, &val1);
10906de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "10G-base-T PMA status 0x%x->0x%x\n",
10907de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   val2, val1);
10908de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	link_up = ((val1 & 4) == 4);
109092cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/* if link is up print the AN outcome of the SFX7101 PHY */
10910de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (link_up) {
10911de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
10912de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				MDIO_AN_DEVAD, MDIO_AN_REG_MASTER_STATUS,
10913de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&val2);
10914de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_10000;
10915791f18c0da3ad540806122e173d6b730d7d7f60bYaniv Rosner		vars->duplex = DUPLEX_FULL;
10916de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "SFX7101 AN status 0x%x->Master=%x\n",
10917de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   val2, (val2 & (1<<14)));
10918de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_10G_an_resolve(bp, phy, vars);
10919de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_ext_phy_resolve_fc(phy, params, vars);
109209e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval
109219e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		/* read LP advertised speeds */
109229e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval		if (val2 & (1<<11))
109239e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval			vars->link_status |=
109249e7e8399c5d3c4dfaf84324a4a6b07a701d3e482Mintz Yuval				LINK_STATUS_LINK_PARTNER_10GXFD_CAPABLE;
10925de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
10926de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return link_up;
10927de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
109286c55c3cdc86881383075a933594748b30dd0054bEilon Greenstein
10929fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_7101_format_ver(u32 spirom_ver, u8 *str, u16 *len)
10930de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
10931de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (*len < 5)
10932de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
10933de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[0] = (spirom_ver & 0xFF);
10934de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[1] = (spirom_ver & 0xFF00) >> 8;
10935de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[2] = (spirom_ver & 0xFF0000) >> 16;
10936de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[3] = (spirom_ver & 0xFF000000) >> 24;
10937de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	str[4] = '\0';
10938de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	*len -= 5;
1093957963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner	return 0;
1094057963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner}
1094157963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
10942de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnervoid bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, struct bnx2x_phy *phy)
1094357963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner{
10944de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u16 val, cnt;
109457aa0711f32bf911add9e2ced165f8006864f973eYaniv Rosner
10946de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_cl45_read(bp, phy,
10947cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_DEVAD,
10948cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			MDIO_PMA_REG_7101_RESET, &val);
1094957963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner
10950de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (cnt = 0; cnt < 10; cnt++) {
10951de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(50);
10952de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Writes a self-clearing reset */
10953de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, phy,
10954cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
10955cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_7101_RESET,
10956cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 (val | (1<<15)));
10957de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Wait for clear */
10958de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_read(bp, phy,
10959cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
10960cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_7101_RESET, &val);
109610c786f0246951fdd9b206249aab9601fb788f9e4Yaniv Rosner
10962de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if ((val & (1<<15)) == 0)
10963de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
1096457963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner	}
1096557963ed94c27e94a7533434da5943195ea072a35Yaniv Rosner}
10966ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
10967de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_7101_hw_reset(struct bnx2x_phy *phy,
10968de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				struct link_params *params) {
10969de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Low power mode is controlled by GPIO 2 */
10970de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_2,
10971cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10972de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* The PHY reset is controlled by GPIO 1 */
10973de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_set_gpio(params->bp, MISC_REGISTERS_GPIO_1,
10974cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       MISC_REGISTERS_GPIO_OUTPUT_LOW, params->port);
10975de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
10976ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
109777f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosnerstatic void bnx2x_7101_set_link_led(struct bnx2x_phy *phy,
109787f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner				    struct link_params *params, u8 mode)
109797f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner{
109807f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	u16 val = 0;
109817f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	struct bnx2x *bp = params->bp;
109827f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	switch (mode) {
109837f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_FRONT_PANEL_OFF:
109847f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OFF:
109857f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		val = 2;
109867f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
109877f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_ON:
109887f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		val = 1;
109897f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
109907f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	case LED_MODE_OPER:
109917f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		val = 0;
109927f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner		break;
109937f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	}
109947f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_cl45_write(bp, phy,
109957f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_DEVAD,
109967f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 MDIO_PMA_REG_7107_LINK_LED_CNTL,
109977f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner			 val);
109987f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner}
109997f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
11000de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
11001de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*			STATIC PHY DECLARATION			  */
11002de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/******************************************************************/
11003ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
11004de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic struct bnx2x_phy phy_null = {
11005de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN,
11006de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.addr		= 0,
11007de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.def_md_devad	= 0,
110089045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= FLAGS_INIT_XGXS_FIRST,
11009de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11010de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11011de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.mdio_ctrl	= 0,
11012de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.supported	= 0,
11013de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.media_type	= ETH_PHY_NOT_PRESENT,
11014de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.ver_addr	= 0,
11015cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_flow_ctrl	= 0,
11016cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_line_speed	= 0,
11017cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.speed_cap_mask	= 0,
11018de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_duplex	= 0,
11019de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rsrv		= 0,
11020de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.config_init	= (config_init_t)NULL,
11021de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.read_status	= (read_status_t)NULL,
11022de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.link_reset	= (link_reset_t)NULL,
11023de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11024de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.format_fw_ver	= (format_fw_ver_t)NULL,
11025de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11026a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11027a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11028de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner};
11029ea4e040abc72f2dbbfdd8d04e271a18593ba72c7Yaniv Rosner
11030de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic struct bnx2x_phy phy_serdes = {
11031de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.type		= PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT,
11032de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.addr		= 0xff,
11033de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.def_md_devad	= 0,
110349045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= 0,
11035de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11036de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11037de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.mdio_ctrl	= 0,
11038de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
11039de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_10baseT_Full |
11040de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_100baseT_Half |
11041de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_100baseT_Full |
11042de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_1000baseT_Full |
11043de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_2500baseX_Full |
11044de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_TP |
11045de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Autoneg |
11046de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Pause |
11047de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Asym_Pause),
110481ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	.media_type	= ETH_PHY_BASE_T,
11049de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.ver_addr	= 0,
11050de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_flow_ctrl	= 0,
11051cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_line_speed	= 0,
11052cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.speed_cap_mask	= 0,
11053de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_duplex	= 0,
11054de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rsrv		= 0,
11055ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	.config_init	= (config_init_t)bnx2x_xgxs_config_init,
11056de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.read_status	= (read_status_t)bnx2x_link_settings_status,
11057de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.link_reset	= (link_reset_t)bnx2x_int_link_reset,
11058de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11059de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.format_fw_ver	= (format_fw_ver_t)NULL,
11060de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11061a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11062a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11063de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner};
11064b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11065b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_xgxs = {
11066b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
11067b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11068b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
110699045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= 0,
11070b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11071b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11072b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11073b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
11074b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_10baseT_Full |
11075b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_100baseT_Half |
11076b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_100baseT_Full |
11077b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11078b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_2500baseX_Full |
11079b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_10000baseT_Full |
11080b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11081b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Autoneg |
11082b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11083b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
110841ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	.media_type	= ETH_PHY_CX4,
11085b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11086b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11087cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_line_speed	= 0,
11088cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.speed_cap_mask	= 0,
11089b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11090b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11091ec146a6f019923819f5ca381980248b6d154ca1aYaniv Rosner	.config_init	= (config_init_t)bnx2x_xgxs_config_init,
11092b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_link_settings_status,
11093b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_int_link_reset,
11094b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)bnx2x_set_xgxs_loopback,
11095b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)NULL,
11096b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11097a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11098a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11099b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
111003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosnerstatic struct bnx2x_phy phy_warpcore = {
111013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT,
111023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.addr		= 0xff,
111033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.def_md_devad	= 0,
111040582242049c67d59c3a95cd1cba8995fa955c858Yaniv Rosner	.flags		= FLAGS_HW_LOCK_REQUIRED,
111053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
111063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
111073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.mdio_ctrl	= 0,
111083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
111093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_10baseT_Full |
111103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_100baseT_Half |
111113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_100baseT_Full |
111123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_1000baseT_Full |
111133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_10000baseT_Full |
111143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_20000baseKR2_Full |
111153c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_20000baseMLD2_Full |
111163c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_FIBRE |
111173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_Autoneg |
111183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_Pause |
111193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			     SUPPORTED_Asym_Pause),
111203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.media_type	= ETH_PHY_UNSPECIFIED,
111213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.ver_addr	= 0,
111223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.req_flow_ctrl	= 0,
111233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.req_line_speed	= 0,
111243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.speed_cap_mask	= 0,
111253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* req_duplex = */0,
111263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	/* rsrv = */0,
111273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.config_init	= (config_init_t)bnx2x_warpcore_config_init,
111283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.read_status	= (read_status_t)bnx2x_warpcore_read_status,
111293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_warpcore_link_reset,
111303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.config_loopback = (config_loopback_t)bnx2x_set_warpcore_loopback,
111313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)NULL,
11132985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	.hw_reset	= (hw_reset_t)bnx2x_warpcore_hw_reset,
111333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
111343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
111353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner};
111363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
11137b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11138b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_7101 = {
11139b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
11140b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11141b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
111429045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= FLAGS_FAN_FAILURE_DET_REQ,
11143b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11144b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11145b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11146b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11147b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_TP |
11148b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Autoneg |
11149b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11150b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
11151b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.media_type	= ETH_PHY_BASE_T,
11152b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11153b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11154cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_line_speed	= 0,
11155cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.speed_cap_mask	= 0,
11156b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11157b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11158b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_7101_config_init,
11159b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_7101_read_status,
11160b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
11161b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)bnx2x_7101_config_loopback,
11162b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_7101_format_ver,
11163b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)bnx2x_7101_hw_reset,
111647f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_7101_set_link_led,
11165a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11166b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11167b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8073 = {
11168b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
11169b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11170b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
111719045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= FLAGS_HW_LOCK_REQUIRED,
11172b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11173b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11174b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11175b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11176b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_2500baseX_Full |
11177b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11178b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11179b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Autoneg |
11180b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11181b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
111821ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	.media_type	= ETH_PHY_KR,
11183b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11184cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_flow_ctrl	= 0,
11185cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.req_line_speed	= 0,
11186cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	.speed_cap_mask	= 0,
11187b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11188b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
1118962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8073_config_init,
11190b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_8073_read_status,
11191b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_8073_link_reset,
11192b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11193b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
11194b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11195a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11196a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11197b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11198b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8705 = {
11199b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705,
11200b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11201b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
112029045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.flags		= FLAGS_INIT_XGXS_FIRST,
11203b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11204b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11205b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11206b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11207b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11208b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11209b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
11210b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.media_type	= ETH_PHY_XFP_FIBER,
11211b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11212b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11213b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_line_speed	= 0,
11214b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.speed_cap_mask	= 0,
11215b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11216b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11217b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8705_config_init,
11218b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_8705_read_status,
11219b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
11220b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11221b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_null_format_ver,
11222b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11223a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11224a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11225b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11226b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8706 = {
11227b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706,
11228b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11229b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
112300582242049c67d59c3a95cd1cba8995fa955c858Yaniv Rosner	.flags		= FLAGS_INIT_XGXS_FIRST,
11231b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11232b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11233b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11234b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11235b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11236b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11237b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11238b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
11239b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.media_type	= ETH_PHY_SFP_FIBER,
11240b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11241b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11242b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_line_speed	= 0,
11243b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.speed_cap_mask	= 0,
11244b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11245b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11246b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8706_config_init,
11247b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_8706_read_status,
11248b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_common_ext_link_reset,
11249b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11250b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
11251b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11252a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11253a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11254b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11255b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11256b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8726 = {
11257b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726,
11258b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
112599045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.def_md_devad	= 0,
11260b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.flags		= (FLAGS_HW_LOCK_REQUIRED |
112610582242049c67d59c3a95cd1cba8995fa955c858Yaniv Rosner			   FLAGS_INIT_XGXS_FIRST),
11262b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11263b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11264b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11265b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11266b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11267b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Autoneg |
11268b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11269b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11270b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
112711ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	.media_type	= ETH_PHY_NOT_PRESENT,
11272b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11273b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11274b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_line_speed	= 0,
11275b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.speed_cap_mask	= 0,
11276b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11277b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11278b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8726_config_init,
11279b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_8726_read_status,
11280b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_8726_link_reset,
11281b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)bnx2x_8726_config_loopback,
11282b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
11283b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
11284a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.set_link_led	= (set_link_led_t)NULL,
11285a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11286b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11287b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11288b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8727 = {
11289b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727,
11290b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
11291b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.def_md_devad	= 0,
112920582242049c67d59c3a95cd1cba8995fa955c858Yaniv Rosner	.flags		= FLAGS_FAN_FAILURE_DET_REQ,
11293b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11294b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11295b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11296b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10000baseT_Full |
11297b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11298b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_FIBRE |
11299b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11300b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
113011ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	.media_type	= ETH_PHY_NOT_PRESENT,
11302b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11303b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11304b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_line_speed	= 0,
11305b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.speed_cap_mask	= 0,
11306b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11307b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11308b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8727_config_init,
11309b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_8727_read_status,
11310b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_8727_link_reset,
11311b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11312b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_format_ver,
11313b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)bnx2x_8727_hw_reset,
113147f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_8727_set_link_led,
11315a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)bnx2x_8727_specific_func
11316b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11317b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosnerstatic struct bnx2x_phy phy_8481 = {
11318b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481,
11319b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.addr		= 0xff,
113209045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.def_md_devad	= 0,
11321a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
11322a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			  FLAGS_REARM_LATCH_SIGNAL,
11323b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11324b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11325b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.mdio_ctrl	= 0,
11326b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
11327b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_10baseT_Full |
11328b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_100baseT_Half |
11329b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_100baseT_Full |
11330b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_1000baseT_Full |
11331b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_10000baseT_Full |
11332b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_TP |
11333b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Autoneg |
11334b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Pause |
11335b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner			   SUPPORTED_Asym_Pause),
11336b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.media_type	= ETH_PHY_BASE_T,
11337b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.ver_addr	= 0,
11338b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_flow_ctrl	= 0,
11339b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_line_speed	= 0,
11340b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.speed_cap_mask	= 0,
11341b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.req_duplex	= 0,
11342b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.rsrv		= 0,
11343b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_init	= (config_init_t)bnx2x_8481_config_init,
11344b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.read_status	= (read_status_t)bnx2x_848xx_read_status,
11345b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_8481_link_reset,
11346b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11347b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
11348b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	.hw_reset	= (hw_reset_t)bnx2x_8481_hw_reset,
113497f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
11350a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11351b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner};
11352b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11353de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic struct bnx2x_phy phy_84823 = {
11354de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823,
11355de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.addr		= 0xff,
113569045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.def_md_devad	= 0,
11357a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
11358a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			  FLAGS_REARM_LATCH_SIGNAL,
11359de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11360de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11361de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.mdio_ctrl	= 0,
11362de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
11363de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_10baseT_Full |
11364de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_100baseT_Half |
11365de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_100baseT_Full |
11366de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_1000baseT_Full |
11367de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_10000baseT_Full |
11368de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_TP |
11369de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Autoneg |
11370de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Pause |
11371de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			   SUPPORTED_Asym_Pause),
11372de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.media_type	= ETH_PHY_BASE_T,
11373de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.ver_addr	= 0,
11374de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_flow_ctrl	= 0,
11375de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_line_speed	= 0,
11376de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.speed_cap_mask	= 0,
11377de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.req_duplex	= 0,
11378de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.rsrv		= 0,
11379de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.config_init	= (config_init_t)bnx2x_848x3_config_init,
11380de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.read_status	= (read_status_t)bnx2x_848xx_read_status,
11381de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.link_reset	= (link_reset_t)bnx2x_848x3_link_reset,
11382de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11383de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
11384de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
113857f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
11386a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11387de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner};
11388de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11389c87bca1eaa493779392378b69fe646644580942aYaniv Rosnerstatic struct bnx2x_phy phy_84833 = {
11390c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833,
11391c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.addr		= 0xff,
113929045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	.def_md_devad	= 0,
11393c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.flags		= FLAGS_FAN_FAILURE_DET_REQ |
11394c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			    FLAGS_REARM_LATCH_SIGNAL,
11395c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11396c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
11397c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.mdio_ctrl	= 0,
113980520e63acb387a265c2a6abbf51c44c67149cf37Yaniv Rosner	.supported	= (SUPPORTED_100baseT_Half |
11399c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_100baseT_Full |
11400c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_1000baseT_Full |
11401c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_10000baseT_Full |
11402c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_TP |
11403c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_Autoneg |
11404c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_Pause |
11405c87bca1eaa493779392378b69fe646644580942aYaniv Rosner			   SUPPORTED_Asym_Pause),
11406c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.media_type	= ETH_PHY_BASE_T,
11407c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.ver_addr	= 0,
11408c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.req_flow_ctrl	= 0,
11409c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.req_line_speed	= 0,
11410c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.speed_cap_mask	= 0,
11411c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.req_duplex	= 0,
11412c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.rsrv		= 0,
11413c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.config_init	= (config_init_t)bnx2x_848x3_config_init,
11414c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.read_status	= (read_status_t)bnx2x_848xx_read_status,
11415c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.link_reset	= (link_reset_t)bnx2x_848x3_link_reset,
11416c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.config_loopback = (config_loopback_t)NULL,
11417c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.format_fw_ver	= (format_fw_ver_t)bnx2x_848xx_format_ver,
11418985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	.hw_reset	= (hw_reset_t)bnx2x_84833_hw_reset_phy,
11419c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_848xx_set_link_led,
11420c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
11421c87bca1eaa493779392378b69fe646644580942aYaniv Rosner};
11422c87bca1eaa493779392378b69fe646644580942aYaniv Rosner
1142352c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosnerstatic struct bnx2x_phy phy_54618se = {
1142452c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	.type		= PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE,
114256583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.addr		= 0xff,
114266583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.def_md_devad	= 0,
114276583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.flags		= FLAGS_INIT_XGXS_FIRST,
114286583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.rx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
114296583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.tx_preemphasis	= {0xffff, 0xffff, 0xffff, 0xffff},
114306583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.mdio_ctrl	= 0,
114316583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.supported	= (SUPPORTED_10baseT_Half |
114326583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_10baseT_Full |
114336583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_100baseT_Half |
114346583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_100baseT_Full |
114356583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_1000baseT_Full |
114366583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_TP |
114376583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_Autoneg |
114386583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_Pause |
114396583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner			   SUPPORTED_Asym_Pause),
114406583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.media_type	= ETH_PHY_BASE_T,
114416583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.ver_addr	= 0,
114426583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.req_flow_ctrl	= 0,
114436583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.req_line_speed	= 0,
114446583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.speed_cap_mask	= 0,
114456583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* req_duplex = */0,
114466583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	/* rsrv = */0,
1144752c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	.config_init	= (config_init_t)bnx2x_54618se_config_init,
1144852c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	.read_status	= (read_status_t)bnx2x_54618se_read_status,
1144952c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	.link_reset	= (link_reset_t)bnx2x_54618se_link_reset,
1145052c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	.config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
114516583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.format_fw_ver	= (format_fw_ver_t)NULL,
114526583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.hw_reset	= (hw_reset_t)NULL,
114531d125bd52e1e1b9810a2d5a32a76147912fa4133Yaniv Rosner	.set_link_led	= (set_link_led_t)bnx2x_5461x_set_link_led,
114546583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner	.phy_specific_func = (phy_specific_func_t)NULL
114556583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner};
11456de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*****************************************************************/
11457de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*                                                               */
11458de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/* Populate the phy according. Main function: bnx2x_populate_phy   */
11459de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*                                                               */
11460de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*****************************************************************/
11461de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11462de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_populate_preemphasis(struct bnx2x *bp, u32 shmem_base,
11463de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				     struct bnx2x_phy *phy, u8 port,
11464de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				     u8 phy_index)
11465de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11466de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Get the 4 lanes xgxs config rx and tx */
11467de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 rx = 0, tx = 0, i;
11468de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (i = 0; i < 2; i++) {
114692cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
11470de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * INT_PHY and EXT_PHY1 share the same value location in the
11471de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * shmem. When num_phys is greater than 1, than this value
11472de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 * applies only to EXT_PHY1
11473de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		 */
11474a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (phy_index == INT_PHY || phy_index == EXT_PHY1) {
11475a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			rx = REG_RD(bp, shmem_base +
11476a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				    offsetof(struct shmem_region,
11477cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  dev_info.port_hw_config[port].xgxs_config_rx[i<<1]));
11478a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11479a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			tx = REG_RD(bp, shmem_base +
11480a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				    offsetof(struct shmem_region,
11481cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			  dev_info.port_hw_config[port].xgxs_config_tx[i<<1]));
11482a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		} else {
11483a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			rx = REG_RD(bp, shmem_base +
11484a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				    offsetof(struct shmem_region,
11485cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11486de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11487a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			tx = REG_RD(bp, shmem_base +
11488a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				    offsetof(struct shmem_region,
11489cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			 dev_info.port_hw_config[port].xgxs_config2_rx[i<<1]));
11490a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
11491de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11492de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->rx_preemphasis[i << 1] = ((rx>>16) & 0xffff);
11493de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->rx_preemphasis[(i << 1) + 1] = (rx & 0xffff);
11494de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11495de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->tx_preemphasis[i << 1] = ((tx>>16) & 0xffff);
11496de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->tx_preemphasis[(i << 1) + 1] = (tx & 0xffff);
11497de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11498de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11499de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11500de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic u32 bnx2x_get_ext_phy_config(struct bnx2x *bp, u32 shmem_base,
11501de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				    u8 phy_index, u8 port)
11502de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11503de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 ext_phy_config = 0;
11504de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (phy_index) {
11505de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case EXT_PHY1:
11506de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		ext_phy_config = REG_RD(bp, shmem_base +
11507de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					      offsetof(struct shmem_region,
11508de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			dev_info.port_hw_config[port].external_phy_config));
11509de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11510a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case EXT_PHY2:
11511a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		ext_phy_config = REG_RD(bp, shmem_base +
11512a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner					      offsetof(struct shmem_region,
11513a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			dev_info.port_hw_config[port].external_phy_config2));
11514a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
11515de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
11516de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		DP(NETIF_MSG_LINK, "Invalid phy_index %d\n", phy_index);
11517de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
11518de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11519de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11520de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return ext_phy_config;
11521de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11522fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_populate_int_phy(struct bnx2x *bp, u32 shmem_base, u8 port,
11523fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct bnx2x_phy *phy)
11524de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11525de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 phy_addr;
11526de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 chip_id;
11527de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 switch_cfg = (REG_RD(bp, shmem_base +
11528de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       offsetof(struct shmem_region,
11529de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			dev_info.port_feature_config[port].link_config)) &
11530de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			  PORT_FEATURE_CONNECTED_SWITCH_MASK);
11531ec15b898a4a812e89a63b8e52bc11d4e84d74db1Yaniv Rosner	chip_id = (REG_RD(bp, MISC_REG_CHIP_NUM) << 16) |
11532ec15b898a4a812e89a63b8e52bc11d4e84d74db1Yaniv Rosner		((REG_RD(bp, MISC_REG_CHIP_REV) & 0xf) << 12);
11533ec15b898a4a812e89a63b8e52bc11d4e84d74db1Yaniv Rosner
115343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	DP(NETIF_MSG_LINK, ":chip_id = 0x%x\n", chip_id);
115353c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (USES_WARPCORE(bp)) {
115363c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		u32 serdes_net_if;
11537de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy_addr = REG_RD(bp,
115383c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				  MISC_REG_WC0_CTRL_PHY_ADDR);
115393c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		*phy = phy_warpcore;
115403c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (REG_RD(bp, MISC_REG_PORT4MODE_EN_OVWR) == 0x3)
115413c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->flags |= FLAGS_4_PORT_MODE;
115423c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else
115433c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->flags &= ~FLAGS_4_PORT_MODE;
115443c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			/* Check Dual mode */
115453c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		serdes_net_if = (REG_RD(bp, shmem_base +
115463c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					offsetof(struct shmem_region, dev_info.
115473c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					port_hw_config[port].default_cfg)) &
115483c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				 PORT_HW_CFG_NET_SERDES_IF_MASK);
115493c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*
115503c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * Set the appropriate supported and flags indications per
115513c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * interface type of the chip
115523c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 */
115533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		switch (serdes_net_if) {
115543c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_SGMII:
115553c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->supported &= (SUPPORTED_10baseT_Half |
115563c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_10baseT_Full |
115573c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_100baseT_Half |
115583c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_100baseT_Full |
115593c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_1000baseT_Full |
115603c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_FIBRE |
115613c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Autoneg |
115623c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Pause |
115633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Asym_Pause);
115643c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_BASE_T;
115653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
115663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_XFI:
115673c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_XFP_FIBER;
115683c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
115693c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_SFI:
115703c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->supported &= (SUPPORTED_1000baseT_Full |
115713c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_10000baseT_Full |
115723c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_FIBRE |
115733c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Pause |
115743c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Asym_Pause);
115753c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_SFP_FIBER;
115763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
115773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_KR:
115783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_KR;
115793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->supported &= (SUPPORTED_1000baseT_Full |
115803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_10000baseT_Full |
115813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_FIBRE |
115823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Autoneg |
115833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Pause |
115843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Asym_Pause);
115853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
115863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_DXGXS:
115873c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_KR;
115883c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->flags |= FLAGS_WC_DUAL_MODE;
115893c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->supported &= (SUPPORTED_20000baseMLD2_Full |
115903c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_FIBRE |
115913c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Pause |
115923c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Asym_Pause);
115933c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
115943c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case PORT_HW_CFG_NET_SERDES_IF_KR2:
115953c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->media_type = ETH_PHY_KR;
115963c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->flags |= FLAGS_WC_DUAL_MODE;
115973c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->supported &= (SUPPORTED_20000baseKR2_Full |
115983c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_FIBRE |
115993c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Pause |
116003c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					   SUPPORTED_Asym_Pause);
116013c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
116023c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		default:
116033c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "Unknown WC interface type 0x%x\n",
116043c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner				       serdes_net_if);
116053c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
116063c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
116073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner
116083c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/*
116093c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * Enable MDC/MDIO work-around for E3 A0 since free running MDC
116103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * was not set as expected. For B0, ECO will be enabled so there
116113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 * won't be an issue there
116123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		 */
116133c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_REV(bp) == CHIP_REV_Ax)
116143c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy->flags |= FLAGS_MDC_MDIO_WA;
11615157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner		else
11616157fa283a7cb5bc6a55dd4e0daf6eeef66adf354Yaniv Rosner			phy->flags |= FLAGS_MDC_MDIO_WA_B0;
116173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
116183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		switch (switch_cfg) {
116193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case SWITCH_CFG_1G:
116203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy_addr = REG_RD(bp,
116213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					  NIG_REG_SERDES0_CTRL_PHY_ADDR +
116223c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					  port * 0x10);
116233c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			*phy = phy_serdes;
116243c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
116253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		case SWITCH_CFG_10G:
116263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			phy_addr = REG_RD(bp,
116273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					  NIG_REG_XGXS0_CTRL_PHY_ADDR +
116283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					  port * 0x18);
116293c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			*phy = phy_xgxs;
116303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			break;
116313c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		default:
116323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
116333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return -EINVAL;
116343c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		}
11635de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11636de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->addr = (u8)phy_addr;
11637de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->mdio_ctrl = bnx2x_get_emac_base(bp,
11638de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					    SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH,
11639de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					    port);
11640f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	if (CHIP_IS_E2(bp))
11641f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		phy->def_md_devad = E2_DEFAULT_PHY_DEV_ADDR;
11642f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	else
11643f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		phy->def_md_devad = DEFAULT_PHY_DEV_ADDR;
11644de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11645de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Internal phy port=%d, addr=0x%x, mdio_ctl=0x%x\n",
11646de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   port, phy->addr, phy->mdio_ctrl);
11647de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11648de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_populate_preemphasis(bp, shmem_base, phy, port, INT_PHY);
11649de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
11650de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11651de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11652fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_populate_ext_phy(struct bnx2x *bp,
11653fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  u8 phy_index,
11654fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  u32 shmem_base,
11655fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  u32 shmem2_base,
11656fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  u8 port,
11657fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				  struct bnx2x_phy *phy)
11658de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11659de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 ext_phy_config, phy_type, config2;
11660de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH;
11661de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	ext_phy_config = bnx2x_get_ext_phy_config(bp, shmem_base,
11662de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						  phy_index, port);
11663de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
11664de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Select the phy type */
11665de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (phy_type) {
11666de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
11667de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED;
11668de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8073;
11669de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11670de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
11671de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8705;
11672de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11673de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
11674de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8706;
11675de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11676de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
11677de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11678de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8726;
11679de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11680de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
11681de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* BCM8727_NOC => BCM8727 no over current */
11682de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11683de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8727;
11684de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->flags |= FLAGS_NOC;
11685de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11686e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
11687de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
11688de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		mdc_mdio_access = SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1;
11689de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8727;
11690de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11691de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8481:
11692de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_8481;
11693de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11694de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84823:
11695de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_84823;
11696de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11697c87bca1eaa493779392378b69fe646644580942aYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
11698c87bca1eaa493779392378b69fe646644580942aYaniv Rosner		*phy = phy_84833;
11699c87bca1eaa493779392378b69fe646644580942aYaniv Rosner		break;
117003756a89f3d039d8a6aa2556f8d57d4b2ec25d5ddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54616:
1170152c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM54618SE:
1170252c4d6c4b543574930667bfc2a4aed8af0713519Yaniv Rosner		*phy = phy_54618se;
117036583e33baefbe4dea04999ec91be1a1371cd1528Yaniv Rosner		break;
11704de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
11705de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_7101;
11706de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11707de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
11708de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_null;
11709de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return -EINVAL;
11710de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
11711de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		*phy = phy_null;
117126db5193b29642ab18e6343c8fcbc3417d6e80983Yaniv Rosner		/* In case external PHY wasn't found */
117136db5193b29642ab18e6343c8fcbc3417d6e80983Yaniv Rosner		if ((phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
117146db5193b29642ab18e6343c8fcbc3417d6e80983Yaniv Rosner		    (phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN))
117156db5193b29642ab18e6343c8fcbc3417d6e80983Yaniv Rosner			return -EINVAL;
11716de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return 0;
11717de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11718de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11719de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->addr = XGXS_EXT_PHY_ADDR(ext_phy_config);
11720de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_populate_preemphasis(bp, shmem_base, phy, port, phy_index);
11721de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
117222cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
117232cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * The shmem address of the phy version is located on different
117242cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * structures. In case this structure is too old, do not set
117252cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * the address
117262cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
11727de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	config2 = REG_RD(bp, shmem_base + offsetof(struct shmem_region,
11728de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					dev_info.shared_hw_config.config2));
11729a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (phy_index == EXT_PHY1) {
11730a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		phy->ver_addr = shmem_base + offsetof(struct shmem_region,
11731a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				port_mb[port].ext_phy_fw_version);
11732de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11733cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		/* Check specific mdc mdio settings */
11734cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK)
11735cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			mdc_mdio_access = config2 &
11736cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			SHARED_HW_CFG_MDC_MDIO_ACCESS1_MASK;
11737a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	} else {
11738a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		u32 size = REG_RD(bp, shmem2_base);
11739de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11740a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (size >
11741a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		    offsetof(struct shmem2_region, ext_phy_fw_version2)) {
11742a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			phy->ver_addr = shmem2_base +
11743a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			    offsetof(struct shmem2_region,
11744a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				     ext_phy_fw_version2[port]);
11745a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
11746a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		/* Check specific mdc mdio settings */
11747a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (config2 & SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK)
11748a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			mdc_mdio_access = (config2 &
11749a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			SHARED_HW_CFG_MDC_MDIO_ACCESS2_MASK) >>
11750a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			(SHARED_HW_CFG_MDC_MDIO_ACCESS2_SHIFT -
11751a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			 SHARED_HW_CFG_MDC_MDIO_ACCESS1_SHIFT);
11752a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
11753de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->mdio_ctrl = bnx2x_get_emac_base(bp, mdc_mdio_access, port);
11754de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
1175575318327802235ecd7e90b0760cceb994bf975caYaniv Rosner	if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833) &&
1175675318327802235ecd7e90b0760cceb994bf975caYaniv Rosner	    (phy->ver_addr)) {
1175775318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		/*
1175875318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		 * Remove 100Mb link supported for BCM84833 when phy fw
1175975318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		 * version lower than or equal to 1.39
1176075318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		 */
1176175318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		u32 raw_ver = REG_RD(bp, phy->ver_addr);
1176275318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		if (((raw_ver & 0x7F) <= 39) &&
1176375318327802235ecd7e90b0760cceb994bf975caYaniv Rosner		    (((raw_ver & 0xF80) >> 7) <= 1))
1176475318327802235ecd7e90b0760cceb994bf975caYaniv Rosner			phy->supported &= ~(SUPPORTED_100baseT_Half |
1176575318327802235ecd7e90b0760cceb994bf975caYaniv Rosner					    SUPPORTED_100baseT_Full);
1176675318327802235ecd7e90b0760cceb994bf975caYaniv Rosner	}
1176775318327802235ecd7e90b0760cceb994bf975caYaniv Rosner
117682cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
11769de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * In case mdc/mdio_access of the external phy is different than the
11770de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * mdc/mdio access of the XGXS, a HW lock must be taken in each access
11771de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * to prevent one port interfere with another port's CL45 operations.
11772de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
11773de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (mdc_mdio_access != SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH)
11774de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->flags |= FLAGS_HW_LOCK_REQUIRED;
11775de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "phy_type 0x%x port %d found in index %d\n",
11776de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   phy_type, port, phy_index);
11777de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "             addr=0x%x, mdio_ctl=0x%x\n",
11778de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		   phy->addr, phy->mdio_ctrl);
11779de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
11780de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11781de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11782fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_populate_phy(struct bnx2x *bp, u8 phy_index, u32 shmem_base,
11783fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			      u32 shmem2_base, u8 port, struct bnx2x_phy *phy)
11784de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11785fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int status = 0;
11786de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->type = PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN;
11787de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (phy_index == INT_PHY)
11788de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		return bnx2x_populate_int_phy(bp, shmem_base, port, phy);
11789a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	status = bnx2x_populate_ext_phy(bp, phy_index, shmem_base, shmem2_base,
11790de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					port, phy);
11791de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return status;
11792de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11793de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11794de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosnerstatic void bnx2x_phy_def_cfg(struct link_params *params,
11795de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			      struct bnx2x_phy *phy,
11796a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			      u8 phy_index)
11797de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11798de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
11799de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 link_config;
11800de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Populate the default phy configuration for MF mode */
11801a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (phy_index == EXT_PHY2) {
11802a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		link_config = REG_RD(bp, params->shmem_base +
11803cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				     offsetof(struct shmem_region, dev_info.
11804a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			port_feature_config[params->port].link_config2));
11805a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11806cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					     offsetof(struct shmem_region,
11807cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner						      dev_info.
11808a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			port_hw_config[params->port].speed_capability_mask2));
11809a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	} else {
11810a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		link_config = REG_RD(bp, params->shmem_base +
11811cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				     offsetof(struct shmem_region, dev_info.
11812a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				port_feature_config[params->port].link_config));
11813a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		phy->speed_cap_mask = REG_RD(bp, params->shmem_base +
11814cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner					     offsetof(struct shmem_region,
11815cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner						      dev_info.
11816cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			port_hw_config[params->port].speed_capability_mask));
11817a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
1181894f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches	DP(NETIF_MSG_LINK,
1181994f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches	   "Default config phy idx %x cfg 0x%x speed_cap_mask 0x%x\n",
1182094f05b0f60de32e6efa19310bd142f1519e2abdbJoe Perches	   phy_index, link_config, phy->speed_cap_mask);
11821de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11822de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	phy->req_duplex = DUPLEX_FULL;
11823de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (link_config  & PORT_FEATURE_LINK_SPEED_MASK) {
11824de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_10M_HALF:
11825de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_duplex = DUPLEX_HALF;
11826de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_10M_FULL:
11827de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_10;
11828de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11829de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_100M_HALF:
11830de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_duplex = DUPLEX_HALF;
11831de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_100M_FULL:
11832de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_100;
11833de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11834de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_1G:
11835de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_1000;
11836de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11837de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_2_5G:
11838de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_2500;
11839de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11840de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_LINK_SPEED_10G_CX4:
11841de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_10000;
11842de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11843de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
11844de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_line_speed = SPEED_AUTO_NEG;
11845de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11846de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11847de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11848de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	switch (link_config  & PORT_FEATURE_FLOW_CONTROL_MASK) {
11849de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_FLOW_CONTROL_AUTO:
11850de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_AUTO;
11851de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11852de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_FLOW_CONTROL_TX:
11853de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_TX;
11854de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11855de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_FLOW_CONTROL_RX:
11856de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_RX;
11857de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11858de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	case PORT_FEATURE_FLOW_CONTROL_BOTH:
11859de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
11860de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11861de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	default:
11862de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy->req_flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11863de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		break;
11864de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11865de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11866de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11867a22f078867ef362e35c54055878168e6613ff743Yaniv Rosneru32 bnx2x_phy_selection(struct link_params *params)
11868a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner{
11869a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 phy_config_swapped, prio_cfg;
11870a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 return_cfg = PORT_HW_CFG_PHY_SELECTION_HARDWARE_DEFAULT;
11871a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11872a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	phy_config_swapped = params->multi_phy_config &
11873a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11874a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11875a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	prio_cfg = params->multi_phy_config &
11876a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			PORT_HW_CFG_PHY_SELECTION_MASK;
11877a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11878a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	if (phy_config_swapped) {
11879a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		switch (prio_cfg) {
11880a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY:
11881a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY;
11882a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     break;
11883a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY_PRIORITY:
11884a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY_PRIORITY;
11885a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     break;
11886a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		case PORT_HW_CFG_PHY_SELECTION_SECOND_PHY:
11887a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     return_cfg = PORT_HW_CFG_PHY_SELECTION_FIRST_PHY;
11888a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     break;
11889a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		case PORT_HW_CFG_PHY_SELECTION_FIRST_PHY:
11890a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     return_cfg = PORT_HW_CFG_PHY_SELECTION_SECOND_PHY;
11891a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		     break;
11892a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
11893a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	} else
11894a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		return_cfg = prio_cfg;
11895a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11896a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	return return_cfg;
11897a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner}
11898a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11899a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
11900fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_phy_probe(struct link_params *params)
11901de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
119022f751a805e35dcf687473c27282a6602577df541Yaniv Rosner	u8 phy_index, actual_phy_idx;
119031ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner	u32 phy_config_swapped, sync_offset, media_types;
11904de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
11905de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x_phy *phy;
11906de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	params->num_phys = 0;
11907de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Begin phy probe\n");
11908a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	phy_config_swapped = params->multi_phy_config &
11909a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		PORT_HW_CFG_PHY_SWAPPED_ENABLED;
11910de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11911de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
11912de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	      phy_index++) {
11913de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		actual_phy_idx = phy_index;
11914a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (phy_config_swapped) {
11915a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			if (phy_index == EXT_PHY1)
11916a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				actual_phy_idx = EXT_PHY2;
11917a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			else if (phy_index == EXT_PHY2)
11918a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				actual_phy_idx = EXT_PHY1;
11919a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		}
11920a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		DP(NETIF_MSG_LINK, "phy_config_swapped %x, phy_index %x,"
11921a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			       " actual_phy_idx %x\n", phy_config_swapped,
11922a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			   phy_index, actual_phy_idx);
11923de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		phy = &params->phy[actual_phy_idx];
11924de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, params->shmem_base,
11925a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner				       params->shmem2_base, params->port,
11926de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       phy) != 0) {
11927de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params->num_phys = 0;
11928de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "phy probe failed in phy index %d\n",
11929de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				   phy_index);
11930de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			for (phy_index = INT_PHY;
11931de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			      phy_index < MAX_PHYS;
11932de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			      phy_index++)
11933de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				*phy = phy_null;
11934de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return -EINVAL;
11935de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
11936de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)
11937de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			break;
11938de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
119391ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		sync_offset = params->shmem_base +
119401ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			offsetof(struct shmem_region,
119411ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			dev_info.port_hw_config[params->port].media_type);
119421ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		media_types = REG_RD(bp, sync_offset);
119431ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner
119441ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		/*
119451ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		 * Update media type for non-PMF sync only for the first time
119461ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		 * In case the media type changes afterwards, it will be updated
119471ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		 * using the update_status function
119481ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		 */
119491ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		if ((media_types & (PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK <<
119501ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				    (PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
119511ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				     actual_phy_idx))) == 0) {
119521ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner			media_types |= ((phy->media_type &
119531ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner					PORT_HW_CFG_MEDIA_TYPE_PHY0_MASK) <<
119541ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				(PORT_HW_CFG_MEDIA_TYPE_PHY1_SHIFT *
119551ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner				 actual_phy_idx));
119561ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		}
119571ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner		REG_WR(bp, sync_offset, media_types);
119581ac9e4286dc9e64dd2d937df7f8660bb5f260792Yaniv Rosner
11959a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		bnx2x_phy_def_cfg(params, phy, phy_index);
11960de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		params->num_phys++;
11961de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
11962de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
11963de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "End phy probe. #phys found %x\n", params->num_phys);
11964de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
11965de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
11966de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
119679045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnervoid bnx2x_init_bmac_loopback(struct link_params *params,
119689045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			      struct link_vars *vars)
11969de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
11970de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x *bp = params->bp;
11971de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_up = 1;
11972de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_10000;
11973de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->duplex = DUPLEX_FULL;
11974de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11975de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->mac_type = MAC_TYPE_BMAC;
11976b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11977de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->phy_flags = PHY_XGXS_FLAG;
11978b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11979de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_xgxs_deassert(params);
11980b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11981de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* set bmac loopback */
11982de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_bmac_enable(params, vars, 1);
11983b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11984cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
119859045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
11986b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
119879045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnervoid bnx2x_init_emac_loopback(struct link_params *params,
119889045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			      struct link_vars *vars)
119899045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
119909045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
11991de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_up = 1;
11992de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->line_speed = SPEED_1000;
11993de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->duplex = DUPLEX_FULL;
11994de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
11995de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->mac_type = MAC_TYPE_EMAC;
11996b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
11997de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->phy_flags = PHY_XGXS_FLAG;
11998e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
11999de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_xgxs_deassert(params);
12000de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* set bmac loopback */
12001de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_emac_enable(params, vars, 1);
12002de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_emac_program(params, vars);
12003cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
120049045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
12005b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
120069380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnervoid bnx2x_init_xmac_loopback(struct link_params *params,
120079380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			      struct link_vars *vars)
120089380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
120099380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
120109380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->link_up = 1;
120119380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!params->req_line_speed[0])
120129380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		vars->line_speed = SPEED_10000;
120139380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	else
120149380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		vars->line_speed = params->req_line_speed[0];
120159380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->duplex = DUPLEX_FULL;
120169380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
120179380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->mac_type = MAC_TYPE_XMAC;
120189380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->phy_flags = PHY_XGXS_FLAG;
120199380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	/*
120209380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * Set WC to loopback mode since link is required to provide clock
120219380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 * to the XMAC in 20G mode
120229380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	 */
12023afad009ad76ece72a3c9629bbc08f14459b9bba7Yaniv Rosner	bnx2x_set_aer_mmd(params, &params->phy[0]);
12024afad009ad76ece72a3c9629bbc08f14459b9bba7Yaniv Rosner	bnx2x_warpcore_reset_lane(bp, &params->phy[0], 0);
12025afad009ad76ece72a3c9629bbc08f14459b9bba7Yaniv Rosner	params->phy[INT_PHY].config_loopback(
120263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			&params->phy[INT_PHY],
120273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			params);
12028afad009ad76ece72a3c9629bbc08f14459b9bba7Yaniv Rosner
120299380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_xmac_enable(params, vars, 1);
120309380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
120319380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
120329380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
120339380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosnervoid bnx2x_init_umac_loopback(struct link_params *params,
120349380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			      struct link_vars *vars)
120359380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner{
120369380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	struct bnx2x *bp = params->bp;
120379380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->link_up = 1;
120389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->line_speed = SPEED_1000;
120399380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->duplex = DUPLEX_FULL;
120409380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
120419380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->mac_type = MAC_TYPE_UMAC;
120429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	vars->phy_flags = PHY_XGXS_FLAG;
120439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	bnx2x_umac_enable(params, vars, 1);
120449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
120459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
120469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner}
120479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner
120489045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnervoid bnx2x_init_xgxs_loopback(struct link_params *params,
120499045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			      struct link_vars *vars)
120509045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
120519045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
12052de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->link_up = 1;
12053de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
12054a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		vars->duplex = DUPLEX_FULL;
120559045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if (params->req_line_speed[0] == SPEED_1000)
12056a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			vars->line_speed = SPEED_1000;
120579045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	else
12058a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			vars->line_speed = SPEED_10000;
1205962b29a5dd0930e0c956b6740f32d5b3bbaf20136Yaniv Rosner
120609380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!USES_WARPCORE(bp))
120619380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_xgxs_deassert(params);
120629045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_link_initialize(params, vars);
120639045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
120649045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if (params->req_line_speed[0] == SPEED_1000) {
120659380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (USES_WARPCORE(bp))
120669380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_umac_enable(params, vars, 0);
120679380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		else {
120689380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_emac_program(params, vars);
120699380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_emac_enable(params, vars, 0);
120709380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
120719380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	} else {
120729380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (USES_WARPCORE(bp))
120739380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_xmac_enable(params, vars, 0);
120749380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		else
120759380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			bnx2x_bmac_enable(params, vars, 0);
120769380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
120779045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
12078de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		if (params->loopback_mode == LOOPBACK_XGXS) {
12079de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* set 10G XGXS loopback */
12080de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			params->phy[INT_PHY].config_loopback(
12081de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				&params->phy[INT_PHY],
12082de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				params);
12083c18aa15d08a2d1a5c7624a21747b1b03c2c1dcfdYaniv Rosner
12084de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		} else {
12085de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			/* set external phy loopback */
12086de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			u8 phy_index;
12087de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			for (phy_index = EXT_PHY1;
12088de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			      phy_index < params->num_phys; phy_index++) {
12089de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				if (params->phy[phy_index].config_loopback)
12090de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					params->phy[phy_index].config_loopback(
12091de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						&params->phy[phy_index],
12092de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner						params);
12093de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			}
12094de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
12095cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + params->port*4, 0);
12096de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
120979045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_set_led(params, vars, LED_MODE_OPER, vars->line_speed);
120989045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner}
120999045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
121009045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosnerint bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
121019045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner{
121029045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	struct bnx2x *bp = params->bp;
121039045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "Phy Initialization started\n");
121049045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "(1) req_speed %d, req_flowctrl %d\n",
121059045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		   params->req_line_speed[0], params->req_flow_ctrl[0]);
121069045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "(2) req_speed %d, req_flowctrl %d\n",
121079045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		   params->req_line_speed[1], params->req_flow_ctrl[1]);
121089045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->link_status = 0;
121099045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->phy_link_up = 0;
121109045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->link_up = 0;
121119045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->line_speed = 0;
121129045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->duplex = DUPLEX_FULL;
121139045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
121149045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->mac_type = MAC_TYPE_NONE;
121159045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	vars->phy_flags = 0;
121169045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
121179045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	/* disable attentions */
121189045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
121199045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		       (NIG_MASK_XGXS0_LINK_STATUS |
121209045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			NIG_MASK_XGXS0_LINK10G |
121219045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			NIG_MASK_SERDES0_LINK_STATUS |
121229045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner			NIG_MASK_MI_INT));
121239045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
121249045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	bnx2x_emac_init(params, vars);
121259045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
1212627d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner	if (params->feature_config_flags & FEATURE_CONFIG_PFC_ENABLED)
1212727d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner		vars->link_status |= LINK_STATUS_PFC_ENABLED;
1212827d9129f5ae830cc031a898e0c220e1cdda69b34Yaniv Rosner
121299045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	if (params->num_phys == 0) {
121309045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		DP(NETIF_MSG_LINK, "No phy found for initialization !!\n");
121319045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		return -EINVAL;
121329045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	}
121339045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	set_phy_vars(params, vars);
121349045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner
121359045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	DP(NETIF_MSG_LINK, "Num of phys on board: %d\n", params->num_phys);
121369045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	switch (params->loopback_mode) {
121379045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case LOOPBACK_BMAC:
121389045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		bnx2x_init_bmac_loopback(params, vars);
121399045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
121409045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case LOOPBACK_EMAC:
121419045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		bnx2x_init_emac_loopback(params, vars);
121429045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
121439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case LOOPBACK_XMAC:
121449380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_init_xmac_loopback(params, vars);
121459380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
121469380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	case LOOPBACK_UMAC:
121479380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_init_umac_loopback(params, vars);
121489380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		break;
121499045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case LOOPBACK_XGXS:
121509045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	case LOOPBACK_EXT_PHY:
121519045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		bnx2x_init_xgxs_loopback(params, vars);
121529045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
121539045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner	default:
121549380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		if (!CHIP_IS_E3(bp)) {
121559380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			if (params->switch_cfg == SWITCH_CFG_10G)
121569380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				bnx2x_xgxs_deassert(params);
121579380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner			else
121589380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner				bnx2x_serdes_deassert(bp, params->port);
121599380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		}
12160de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_link_initialize(params, vars);
12161de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		msleep(30);
12162de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_link_int_enable(params);
121639045f6b44a01737a84c5bb79f580dccce6806d80Yaniv Rosner		break;
12164de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
12165e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	return 0;
12166e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner}
12167fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner
12168fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_link_reset(struct link_params *params, struct link_vars *vars,
12169fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner		     u8 reset_ext_phy)
12170b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner{
12171b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	struct bnx2x *bp = params->bp;
12172cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner	u8 phy_index, port = params->port, clear_latch_ind = 0;
12173de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	DP(NETIF_MSG_LINK, "Resetting the link of port %d\n", port);
12174de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable attentions */
12175de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->link_status = 0;
12176de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_update_mng(params, vars->link_status);
12177de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
12178cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner		       (NIG_MASK_XGXS0_LINK_STATUS |
12179cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_MASK_XGXS0_LINK10G |
12180cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_MASK_SERDES0_LINK_STATUS |
12181cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			NIG_MASK_MI_INT));
12182b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12183de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* activate nig drain */
12184de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
12185b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12186de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable nig egress interface */
121879380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp)) {
121889380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
121899380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
121909380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
12191b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12192de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Stop BigMac rx */
121939380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp))
121949380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_bmac_rx_disable(bp, port);
12195ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	else {
121969380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		bnx2x_xmac_disable(params);
12197ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		bnx2x_umac_disable(params);
12198ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	}
12199de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable emac */
122009380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp))
122019380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
12202b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12203de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(10);
1220425985edcedea6396277003854657b5f3cb31a628Lucas De Marchi	/* The PHY reset is controlled by GPIO 1
12205de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 * Hold it as vars low
12206de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 */
12207de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	 /* clear link led */
12208ca7b91bbd1f150216e6354cc20818aa993f331f2Yaniv Rosner	bnx2x_set_mdio_clk(bp, params->chip_id, port);
122097f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner	bnx2x_set_led(params, vars, LED_MODE_OFF, 0);
122107f02c4ad2182ee7820edecbaf6c510728ee8bbb3Yaniv Rosner
12211de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (reset_ext_phy) {
12212de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		for (phy_index = EXT_PHY1; phy_index < params->num_phys;
12213de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		      phy_index++) {
1221428f4881cbf9ce285edfc245a8990af36d21c062fYaniv Rosner			if (params->phy[phy_index].link_reset) {
1221528f4881cbf9ce285edfc245a8990af36d21c062fYaniv Rosner				bnx2x_set_aer_mmd(params,
1221628f4881cbf9ce285edfc245a8990af36d21c062fYaniv Rosner						  &params->phy[phy_index]);
12217de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				params->phy[phy_index].link_reset(
12218de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					&params->phy[phy_index],
12219de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner					params);
1222028f4881cbf9ce285edfc245a8990af36d21c062fYaniv Rosner			}
12221cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner			if (params->phy[phy_index].flags &
12222cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner			    FLAGS_REARM_LATCH_SIGNAL)
12223cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner				clear_latch_ind = 1;
12224b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner		}
12225b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	}
12226b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12227cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner	if (clear_latch_ind) {
12228cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner		/* Clear latching indication */
12229cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner		bnx2x_rearm_latch_signal(bp, port, 0);
12230cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner		bnx2x_bits_dis(bp, NIG_REG_LATCH_BC_0 + port*4,
12231cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner			       1 << NIG_LATCH_BC_ENABLE_MI_INT);
12232cf1d972cb6393b9b042289739111773226861d6cYaniv Rosner	}
12233de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	if (params->phy[INT_PHY].link_reset)
12234de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		params->phy[INT_PHY].link_reset(
12235de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			&params->phy[INT_PHY], params);
12236b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12237de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* disable nig ingress interface */
122389380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	if (!CHIP_IS_E3(bp)) {
12239ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		/* reset BigMac */
12240ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
12241ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
122429380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
122439380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner		REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
12244ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner	} else {
12245ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		u32 xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12246ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		bnx2x_set_xumac_nig(params, 0, 0);
12247ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12248ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner		    MISC_REGISTERS_RESET_REG_2_XMAC)
12249ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner			REG_WR(bp, xmac_base + XMAC_REG_CTRL,
12250ce7c048928473220394bb126b08596e92e998a36Yaniv Rosner			       XMAC_CTRL_REG_SOFT_RESET);
122519380bb9e88831bd3d85636b3e4fec30e330d5266Yaniv Rosner	}
12252de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	vars->link_up = 0;
122533c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	vars->phy_flags = 0;
12254b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner	return 0;
12255b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner}
12256b7737c9be9d3e894d1a4375c52f5f47789475f26Yaniv Rosner
12257de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/****************************************************************************/
12258de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/*				Common function				    */
12259de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner/****************************************************************************/
12260fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8073_common_init_phy(struct bnx2x *bp,
12261fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem_base_path[],
12262fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem2_base_path[], u8 phy_index,
12263fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 chip_id)
122646bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner{
12265e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x_phy phy[PORT_MAX];
12266e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x_phy *phy_blk[PORT_MAX];
122676bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	u16 val;
12268c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	s8 port = 0;
12269f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	s8 port_of_path = 0;
12270c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	u32 swap_val, swap_override;
12271c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	swap_val = REG_RD(bp,  NIG_REG_PORT_SWAP);
12272c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	swap_override = REG_RD(bp,  NIG_REG_STRAP_OVERRIDE);
12273c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	port ^= (swap_val && swap_override);
12274c8e64df48a814be1e7066f07b4f709ff63727abfYaniv Rosner	bnx2x_ext_phy_hw_reset(bp, port);
122756bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	/* PART1 - Reset both phys */
122766bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12277f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		u32 shmem_base, shmem2_base;
12278f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		/* In E2, same phy is using for port0 of the two paths */
122793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_IS_E1x(bp)) {
12280f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem_base = shmem_base_path[0];
12281f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem2_base = shmem2_base_path[0];
12282f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			port_of_path = port;
122833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		} else {
122843c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem_base = shmem_base_path[port];
122853c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem2_base = shmem2_base_path[port];
122863c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_of_path = 0;
12287f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		}
12288f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
122896bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Extract the ext phy address for the port */
12290a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12291f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				       port_of_path, &phy[port]) !=
12292e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		    0) {
12293e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			DP(NETIF_MSG_LINK, "populate_phy failed\n");
12294e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			return -EINVAL;
12295e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		}
122966bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* disable attentions */
122976a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
122986a71bbe04c9ee9a6e892e584a09615c1dbf35edcYaniv Rosner			       port_of_path*4,
12299cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       (NIG_MASK_XGXS0_LINK_STATUS |
12300cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				NIG_MASK_XGXS0_LINK10G |
12301cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				NIG_MASK_SERDES0_LINK_STATUS |
12302cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				NIG_MASK_MI_INT));
123036bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123046bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Need to take the phy out of low power mode in order
123056bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner			to write to access its registers */
123066bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12307cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12308cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       port);
123096bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123106bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Reset the phy */
12311e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, &phy[port],
12312cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
12313cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_CTRL,
12314cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 1<<15);
123156bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
123166bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123176bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	/* Add delay of 150ms after reset */
123186bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	msleep(150);
123196bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
12320e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	if (phy[PORT_0].addr & 0x1) {
12321e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_0] = &(phy[PORT_1]);
12322e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_1] = &(phy[PORT_0]);
12323e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	} else {
12324e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_0] = &(phy[PORT_0]);
12325e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_1] = &(phy[PORT_1]);
12326e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	}
12327e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner
123286bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	/* PART2 - Download firmware to both phys */
123296bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
123303c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_IS_E1x(bp))
12331f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			port_of_path = port;
123323c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else
123333c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_of_path = 0;
123346bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
12335f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12336f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			   phy_blk[port]->addr);
123375c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
123385c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner						      port_of_path))
123396bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner			return -EINVAL;
123406bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123416bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Only set bit 10 = 1 (Tx power down) */
12342e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_read(bp, phy_blk[port],
12343cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
12344cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_TX_POWER_DOWN, &val);
123456bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123466bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Phase1 of TX_POWER_DOWN reset */
12347e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, phy_blk[port],
12348cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
12349cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_TX_POWER_DOWN,
12350cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 (val | 1<<10));
123516bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
123526bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123532cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	/*
123542cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * Toggle Transmitter: Power down and then up with 600ms delay
123552cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 * between
123562cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner	 */
123576bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	msleep(600);
123586bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123596bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
123606bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12361f53722514242da8346cbed2223bcea9eed744ebdEilon Greenstein		/* Phase2 of POWER_DOWN_RESET */
123626bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Release bit 10 (Release Tx power down) */
12363e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_read(bp, phy_blk[port],
12364cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
12365cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_TX_POWER_DOWN, &val);
123666bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
12367e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, phy_blk[port],
12368cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
12369cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
123706bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		msleep(15);
123716bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123726bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* Read modify write the SPI-ROM version select register */
12373e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_read(bp, phy_blk[port],
12374cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_DEVAD,
12375cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				MDIO_PMA_REG_EDC_FFE_MAIN, &val);
12376e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, phy_blk[port],
12377cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD,
12378cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
123796bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
123806bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		/* set GPIO2 back to LOW */
123816bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
12382cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
123836bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
123846bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	return 0;
123856bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner}
12386fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8726_common_init_phy(struct bnx2x *bp,
12387fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem_base_path[],
12388fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem2_base_path[], u8 phy_index,
12389fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 chip_id)
12390de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner{
12391de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	u32 val;
12392de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	s8 port;
12393de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	struct bnx2x_phy phy;
12394de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Use port1 because of the static port-swap */
12395de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	/* Enable the module detection interrupt */
12396de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
12397de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	val |= ((1<<MISC_REGISTERS_GPIO_3)|
12398de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		(1<<(MISC_REGISTERS_GPIO_3 + MISC_REGISTERS_GPIO_PORT_SHIFT)));
12399de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
12400de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
12401650154bfd1ef3119e7c79f35447f0e11a5e4f7c6Yaniv Rosner	bnx2x_ext_phy_hw_reset(bp, 0);
12402de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	msleep(5);
12403de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	for (port = 0; port < PORT_MAX; port++) {
12404f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		u32 shmem_base, shmem2_base;
12405f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
12406f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		/* In E2, same phy is using for port0 of the two paths */
124073c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_IS_E1x(bp)) {
12408f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem_base = shmem_base_path[0];
12409f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem2_base = shmem2_base_path[0];
124103c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		} else {
124113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem_base = shmem_base_path[port];
124123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem2_base = shmem2_base_path[port];
12413f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		}
12414de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Extract the ext phy address for the port */
12415a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12416de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				       port, &phy) !=
12417de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		    0) {
12418de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			DP(NETIF_MSG_LINK, "populate phy failed\n");
12419de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner			return -EINVAL;
12420de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		}
12421de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
12422de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Reset phy*/
12423de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_cl45_write(bp, &phy,
12424de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_GEN_CTRL, 0x0001);
12425de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
12426de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
12427de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		/* Set fault module detected LED on */
12428de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
12429cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       MISC_REGISTERS_GPIO_HIGH,
12430cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner			       port);
12431de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	}
12432de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner
12433de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner	return 0;
12434de6eae1f42eae736548f293570fd867bd37c3bddYaniv Rosner}
12435a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosnerstatic void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
12436a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner					 u8 *io_gpio, u8 *io_port)
12437a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner{
12438a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
12439a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	u32 phy_gpio_reset = REG_RD(bp, shmem_base +
12440a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner					  offsetof(struct shmem_region,
12441a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				dev_info.port_hw_config[PORT_0].default_cfg));
12442a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	switch (phy_gpio_reset) {
12443a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
12444a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 0;
12445a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 0;
12446a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12447a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
12448a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 1;
12449a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 0;
12450a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12451a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
12452a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 2;
12453a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 0;
12454a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12455a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
12456a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 3;
12457a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 0;
12458a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12459a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
12460a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 0;
12461a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 1;
12462a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12463a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
12464a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 1;
12465a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 1;
12466a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12467a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
12468a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 2;
12469a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 1;
12470a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12471a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
12472a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_gpio = 3;
12473a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		*io_port = 1;
12474a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12475a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	default:
12476a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		/* Don't override the io_gpio and io_port */
12477a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		break;
12478a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	}
12479a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner}
12480fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner
12481fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_8727_common_init_phy(struct bnx2x *bp,
12482fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem_base_path[],
12483fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 shmem2_base_path[], u8 phy_index,
12484fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				      u32 chip_id)
124854d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein{
12486a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	s8 port, reset_gpio;
124874d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	u32 swap_val, swap_override;
12488e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x_phy phy[PORT_MAX];
12489e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	struct bnx2x_phy *phy_blk[PORT_MAX];
12490f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov	s8 port_of_path;
12491cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
12492cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
124934d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
12494a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	reset_gpio = MISC_REGISTERS_GPIO_1;
12495a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	port = 1;
124964d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
12497a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	/*
12498a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * Retrieve the reset gpio/port which control the reset.
12499a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 * Default is GPIO1, PORT1
12500a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	 */
12501a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
12502a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner				     (u8 *)&reset_gpio, (u8 *)&port);
12503a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
12504a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	/* Calculate the port based on port swap */
12505a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	port ^= (swap_val && swap_override);
12506a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner
12507a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	/* Initiate PHY reset*/
12508a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
12509a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		       port);
12510a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	msleep(1);
12511a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner	bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
12512a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner		       port);
12513a8db5b4cbde619246cd3db9a59dac5d0757aff36Yaniv Rosner
12514a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	msleep(5);
12515bc7f0a053021491e292fc00810c4f2a8524453ddEilon Greenstein
125164d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	/* PART1 - Reset both phys */
12517a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
12518f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		u32 shmem_base, shmem2_base;
12519f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
12520f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		/* In E2, same phy is using for port0 of the two paths */
125213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_IS_E1x(bp)) {
12522f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem_base = shmem_base_path[0];
12523f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			shmem2_base = shmem2_base_path[0];
12524f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			port_of_path = port;
125253c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		} else {
125263c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem_base = shmem_base_path[port];
125273c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			shmem2_base = shmem2_base_path[port];
125283c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_of_path = 0;
12529f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		}
12530f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov
125314d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		/* Extract the ext phy address for the port */
12532a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12533f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				       port_of_path, &phy[port]) !=
12534e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner				       0) {
12535e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			DP(NETIF_MSG_LINK, "populate phy failed\n");
12536e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner			return -EINVAL;
12537e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		}
125384d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		/* disable attentions */
12539f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 +
12540f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			       port_of_path*4,
12541f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			       (NIG_MASK_XGXS0_LINK_STATUS |
12542f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				NIG_MASK_XGXS0_LINK10G |
12543f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				NIG_MASK_SERDES0_LINK_STATUS |
12544f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov				NIG_MASK_MI_INT));
125454d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
125464d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
125474d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		/* Reset the phy */
12548e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		bnx2x_cl45_write(bp, &phy[port],
12549cd88ccee1da3626d1c40dfcff8617b2c83271365Yaniv Rosner				 MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
125504d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	}
125514d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
125524d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	/* Add delay of 150ms after reset */
125534d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	msleep(150);
12554e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	if (phy[PORT_0].addr & 0x1) {
12555e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_0] = &(phy[PORT_1]);
12556e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_1] = &(phy[PORT_0]);
12557e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	} else {
12558e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_0] = &(phy[PORT_0]);
12559e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner		phy_blk[PORT_1] = &(phy[PORT_1]);
12560e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	}
125614d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	/* PART2 - Download firmware to both phys */
12562e10bc84d0e96adff7569161e7d825074a119be36Yaniv Rosner	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
125633c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (CHIP_IS_E1x(bp))
12564f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			port_of_path = port;
125653c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		else
125663c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			port_of_path = 0;
12567f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		DP(NETIF_MSG_LINK, "Loading spirom for phy address 0x%x\n",
12568f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov			   phy_blk[port]->addr);
125695c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner		if (bnx2x_8073_8727_external_rom_boot(bp, phy_blk[port],
125705c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner						      port_of_path))
125714d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein			return -EINVAL;
1257285242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		/* Disable PHY transmitter output */
1257385242eea68f5039458afad0e4030828496bb4034Yaniv Rosner		bnx2x_cl45_write(bp, phy_blk[port],
1257485242eea68f5039458afad0e4030828496bb4034Yaniv Rosner				 MDIO_PMA_DEVAD,
1257585242eea68f5039458afad0e4030828496bb4034Yaniv Rosner				 MDIO_PMA_REG_TX_DISABLE, 1);
125764d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
125775c99274b0177cd614455c277b1a4d4410d9cb702Yaniv Rosner	}
125784d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	return 0;
125794d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein}
125804d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
12581521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosnerstatic int bnx2x_84833_common_init_phy(struct bnx2x *bp,
12582521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						u32 shmem_base_path[],
12583521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						u32 shmem2_base_path[],
12584521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						u8 phy_index,
12585521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						u32 chip_id)
12586521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner{
12587521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	u8 reset_gpios;
12588521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	reset_gpios = bnx2x_84833_get_reset_gpios(bp, shmem_base_path, chip_id);
12589521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_LOW);
12590521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	udelay(10);
12591521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	bnx2x_set_mult_gpio(bp, reset_gpios, MISC_REGISTERS_GPIO_OUTPUT_HIGH);
12592521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	DP(NETIF_MSG_LINK, "84833 reset pulse on pin values 0x%x\n",
12593521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		reset_gpios);
1259411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	return 0;
1259511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner}
12596521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
1259711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosnerstatic int bnx2x_84833_pre_init_phy(struct bnx2x *bp,
1259811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner					       struct bnx2x_phy *phy)
1259911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner{
1260011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	u16 val, cnt;
1260111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	/* Wait for FW completing its initialization. */
1260211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	for (cnt = 0; cnt < 1500; cnt++) {
1260311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		bnx2x_cl45_read(bp, phy,
12604521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_PMA_DEVAD,
12605521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner				MDIO_PMA_REG_CTRL, &val);
1260611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		if (!(val & (1<<15)))
1260711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			break;
1260811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		msleep(1);
1260911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
1261011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (cnt >= 1500) {
1261111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		DP(NETIF_MSG_LINK, "84833 reset timeout\n");
1261211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		return -EINVAL;
12613521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	}
12614521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
1261511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	/* Put the port in super isolate mode. */
1261611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	bnx2x_cl45_read(bp, phy,
1261711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			MDIO_CTL_DEVAD,
1261811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			MDIO_84833_TOP_CFG_XGPHY_STRAP1, &val);
1261911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	val |= MDIO_84833_SUPER_ISOLATE;
1262011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	bnx2x_cl45_write(bp, phy,
1262111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			 MDIO_CTL_DEVAD,
1262211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			 MDIO_84833_TOP_CFG_XGPHY_STRAP1, val);
1262311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner
1262411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	/* Save spirom version */
1262511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	bnx2x_save_848xx_spirom_version(phy, bp, PORT_0);
12626521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner	return 0;
12627521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner}
12628521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
1262911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosnerint bnx2x_pre_init_phy(struct bnx2x *bp,
1263011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				  u32 shmem_base,
1263111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				  u32 shmem2_base,
1263211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner				  u32 chip_id)
1263311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner{
1263411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	int rc = 0;
1263511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	struct bnx2x_phy phy;
1263611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
1263711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	if (bnx2x_populate_phy(bp, EXT_PHY1, shmem_base, shmem2_base,
1263811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner			       PORT_0, &phy)) {
1263911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		DP(NETIF_MSG_LINK, "populate_phy failed\n");
1264011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		return -EINVAL;
1264111b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
1264211b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	switch (phy.type) {
1264311b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
1264411b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		rc = bnx2x_84833_pre_init_phy(bp, &phy);
1264511b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		break;
1264611b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	default:
1264711b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner		break;
1264811b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	}
1264911b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner	return rc;
1265011b2ec6b739ee90211dc6f6942e2ba3a141434a8Yaniv Rosner}
12651521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner
12652fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerstatic int bnx2x_ext_phy_common_init(struct bnx2x *bp, u32 shmem_base_path[],
12653fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				     u32 shmem2_base_path[], u8 phy_index,
12654fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner				     u32 ext_phy_type, u32 chip_id)
126556bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner{
12656fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
126576bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
126586bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	switch (ext_phy_type) {
126596bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
12660f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc = bnx2x_8073_common_init_phy(bp, shmem_base_path,
12661f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						shmem2_base_path,
12662f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						phy_index, chip_id);
126636bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		break;
12664e4d78f120c039bbd18ae449a6b2af3df83ca02bfYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8722:
126654d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727:
126664d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727_NOC:
12667f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc = bnx2x_8727_common_init_phy(bp, shmem_base_path,
12668f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						shmem2_base_path,
12669f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						phy_index, chip_id);
126704d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein		break;
126714d295db0efd2ccf06edb7a45ad885b40c56b7161Eilon Greenstein
12672589abe3a0f594a7707a15674ca9e80370c972832Eilon Greenstein	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726:
126732cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		/*
126742cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * GPIO1 affects both ports, so there's need to pull
126752cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 * it for single port alone
126762cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner		 */
12677f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc = bnx2x_8726_common_init_phy(bp, shmem_base_path,
12678f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						shmem2_base_path,
12679f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						phy_index, chip_id);
12680a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		break;
126810d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM84833:
126820d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		/*
126830d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		 * GPIO3's are linked, and so both need to be toggled
126840d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		 * to obtain required 2us pulse.
126850d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		 */
12686521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner		rc = bnx2x_84833_common_init_phy(bp, shmem_base_path,
12687521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						shmem2_base_path,
12688521683da84b824d36b6388d2e7ea96c81eafc699Yaniv Rosner						phy_index, chip_id);
126890d40f0d425ec632956547bd8efd8965e5945e1dcYaniv Rosner		break;
12690a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
12691a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		rc = -EINVAL;
126924f60dab113230943fb1bc7969053d9a1b6578339Yaniv Rosner		break;
126936bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	default:
126946bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		DP(NETIF_MSG_LINK,
126952cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			   "ext_phy 0x%x common init not required\n",
126962cf7acf98ef8327588e49bf74b7653ca4a063f09Yaniv Rosner			   ext_phy_type);
126976bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner		break;
126986bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	}
126996bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
127006d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner	if (rc != 0)
127016d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner		netdev_err(bp->dev,  "Warning: PHY was not initialized,"
127026d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner				      " Port %d\n",
127036d870c391ec0e4da4fd75df7e6aca7252162c408Yaniv Rosner			 0);
127046bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner	return rc;
127056bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner}
127066bbca910e621d82b3ca93a99af9b59eb1ff3cbcdYaniv Rosner
12707fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosnerint bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base_path[],
12708fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner			  u32 shmem2_base_path[], u32 chip_id)
12709a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner{
12710fcf5b650832996bd857bb8f0b0b42097218f7fb8Yaniv Rosner	int rc = 0;
127113c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u32 phy_ver, val;
127123c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	u8 phy_index = 0;
12713a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	u32 ext_phy_type, ext_phy_config;
12714a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	bnx2x_set_mdio_clk(bp, chip_id, PORT_0);
12715a198c142aacf82acad29e1752191bda8b451a0c7Yaniv Rosner	bnx2x_set_mdio_clk(bp, chip_id, PORT_1);
12716a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	DP(NETIF_MSG_LINK, "Begin common phy init\n");
127173c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
127183c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		/* Enable EPIO */
127193c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		val = REG_RD(bp, MISC_REG_GEN_PURP_HWG);
127203c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		REG_WR(bp, MISC_REG_GEN_PURP_HWG, val | 1);
127213c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	}
12722b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner	/* Check if common init was already done */
12723b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner	phy_ver = REG_RD(bp, shmem_base_path[0] +
12724b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner			 offsetof(struct shmem_region,
12725b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner				  port_mb[PORT_0].ext_phy_fw_version));
12726b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner	if (phy_ver) {
12727b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner		DP(NETIF_MSG_LINK, "Not doing common init; phy ver is 0x%x\n",
12728b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner			       phy_ver);
12729b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner		return 0;
12730b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner	}
12731b21a3424877a4d5ca91a6d446ed581a2bd03160cYaniv Rosner
12732a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	/* Read the ext_phy_type for arbitrary port(0) */
12733a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12734a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	      phy_index++) {
12735a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		ext_phy_config = bnx2x_get_ext_phy_config(bp,
12736f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov							  shmem_base_path[0],
12737a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner							  phy_index, 0);
12738a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
12739f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov		rc |= bnx2x_ext_phy_common_init(bp, shmem_base_path,
12740f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						shmem2_base_path,
12741f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						phy_index, ext_phy_type,
12742f2e0899f0f275cc3f5e9c9726178d7d0ac19b2dbDmitry Kravkov						chip_id);
12743a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	}
12744a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner	return rc;
12745a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner}
12746d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
127473deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnerstatic void bnx2x_check_over_curr(struct link_params *params,
127483deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				  struct link_vars *vars)
127493deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
127503deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	struct bnx2x *bp = params->bp;
127513deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 cfg_pin;
127523deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u8 port = params->port;
127533deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 pin_val;
127543deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127553deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	cfg_pin = (REG_RD(bp, params->shmem_base +
127563deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			  offsetof(struct shmem_region,
127573deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			       dev_info.port_hw_config[port].e3_cmn_pin_cfg1)) &
127583deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		   PORT_HW_CFG_E3_OVER_CURRENT_MASK) >>
127593deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		PORT_HW_CFG_E3_OVER_CURRENT_SHIFT;
127603deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127613deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Ignore check if no external input PIN available */
127623deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (bnx2x_get_cfg_pin(bp, cfg_pin, &pin_val) != 0)
127633deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		return;
127643deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127653deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (!pin_val) {
127663deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		if ((vars->phy_flags & PHY_OVER_CURRENT_FLAG) == 0) {
127673deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			netdev_err(bp->dev, "Error:  Power fault on Port %d has"
127683deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    " been detected and the power to "
127693deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    "that SFP+ module has been removed"
127703deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    " to prevent failure of the card."
127713deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    " Please remove the SFP+ module and"
127723deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    " restart the system to clear this"
127733deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner					    " error.\n",
127743deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			 params->port);
127753deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			vars->phy_flags |= PHY_OVER_CURRENT_FLAG;
127763deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		}
127773deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	} else
127783deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->phy_flags &= ~PHY_OVER_CURRENT_FLAG;
127793deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
127803deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127813deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnerstatic void bnx2x_analyze_link_error(struct link_params *params,
127823deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				     struct link_vars *vars, u32 lss_status)
127833deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
127843deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	struct bnx2x *bp = params->bp;
127853deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Compare new value with previous value */
127863deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u8 led_mode;
127873deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 half_open_conn = (vars->phy_flags & PHY_HALF_OPEN_CONN_FLAG) > 0;
127883deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127893deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if ((lss_status ^ half_open_conn) == 0)
127903deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		return;
127913deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127923deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* If values differ */
127933deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	DP(NETIF_MSG_LINK, "Link changed:%x %x->%x\n", vars->link_up,
127943deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		       half_open_conn, lss_status);
127953deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
127963deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/*
127973deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	 * a. Update shmem->link_status accordingly
127983deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	 * b. Update link_vars->link_up
127993deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	 */
128003deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if (lss_status) {
12801de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		DP(NETIF_MSG_LINK, "Remote Fault detected !!!\n");
128023deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->link_status &= ~LINK_STATUS_LINK_UP;
128033deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->link_up = 0;
128043deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->phy_flags |= PHY_HALF_OPEN_CONN_FLAG;
128053deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		/*
128063deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		 * Set LED mode to off since the PHY doesn't know about these
128073deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		 * errors
128083deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		 */
128093deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		led_mode = LED_MODE_OFF;
128103deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	} else {
12811de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		DP(NETIF_MSG_LINK, "Remote Fault cleared\n");
128123deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->link_status |= LINK_STATUS_LINK_UP;
128133deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->link_up = 1;
128143deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		vars->phy_flags &= ~PHY_HALF_OPEN_CONN_FLAG;
128153deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		led_mode = LED_MODE_OPER;
128163deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	}
128173deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Update the LED according to the link state */
128183deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	bnx2x_set_led(params, vars, led_mode, SPEED_10000);
128193deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
128203deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* Update link status in the shared memory */
128213deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	bnx2x_update_mng(params, vars->link_status);
128223deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
128233deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* C. Trigger General Attention */
128243deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	vars->periodic_flags |= PERIODIC_FLAGS_LINK_EVENT;
128253deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	bnx2x_notify_link_changed(bp);
128263deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
128273deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
12828de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner/******************************************************************************
12829de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner* Description:
12830de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*	This function checks for half opened connection change indication.
12831de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*	When such change occurs, it calls the bnx2x_analyze_link_error
12832de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*	to check if Remote Fault is set or cleared. Reception of remote fault
12833de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*	status message in the MAC indicates that the peer's MAC has detected
12834de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*	a fault, for example, due to break in the TX side of fiber.
12835de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner*
12836de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner******************************************************************************/
128373deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnerstatic void bnx2x_check_half_open_conn(struct link_params *params,
128383deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner				       struct link_vars *vars)
128393deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
128403deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	struct bnx2x *bp = params->bp;
128413deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 lss_status = 0;
128423deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	u32 mac_base;
128433deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	/* In case link status is physically up @ 10G do */
128443deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	if ((vars->phy_flags & PHY_PHYSICAL_LINK_FLAG) == 0)
128453deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		return;
128463deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
12847de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	if (CHIP_IS_E3(bp) &&
128483deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	    (REG_RD(bp, MISC_REG_RESET_REG_2) &
12849de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	      (MISC_REGISTERS_RESET_REG_2_XMAC))) {
12850de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		/* Check E3 XMAC */
12851de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		/*
12852de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		 * Note that link speed cannot be queried here, since it may be
12853de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		 * zero while link is down. In case UMAC is active, LSS will
12854de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		 * simply not be set
12855de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		 */
12856de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		mac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
12857de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner
12858de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		/* Clear stick bits (Requires rising edge) */
12859de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
12860de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		REG_WR(bp, mac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
12861de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
12862de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
12863de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		if (REG_RD(bp, mac_base + XMAC_REG_RX_LSS_STATUS))
12864de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			lss_status = 1;
12865de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner
12866de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		bnx2x_analyze_link_error(params, vars, lss_status);
12867de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	} else if (REG_RD(bp, MISC_REG_RESET_REG_2) &
12868de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port)) {
128693deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		/* Check E1X / E2 BMAC */
128703deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		u32 lss_status_reg;
128713deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		u32 wb_data[2];
128723deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		mac_base = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
128733deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			NIG_REG_INGRESS_BMAC0_MEM;
128743deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		/*  Read BIGMAC_REGISTER_RX_LSS_STATUS */
128753deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		if (CHIP_IS_E2(bp))
128763deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			lss_status_reg = BIGMAC2_REGISTER_RX_LSS_STAT;
128773deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		else
128783deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner			lss_status_reg = BIGMAC_REGISTER_RX_LSS_STATUS;
128793deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
128803deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		REG_RD_DMAE(bp, mac_base + lss_status_reg, wb_data, 2);
128813deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		lss_status = (wb_data[0] > 0);
128823deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
128833deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		bnx2x_analyze_link_error(params, vars, lss_status);
128843deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	}
128853deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
128863deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
128873deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosnervoid bnx2x_period_func(struct link_params *params, struct link_vars *vars)
128883deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner{
128893deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner	struct bnx2x *bp = params->bp;
12890de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	u16 phy_idx;
12891de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	for (phy_idx = INT_PHY; phy_idx < MAX_PHYS; phy_idx++) {
12892de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		if (params->phy[phy_idx].flags & FLAGS_TX_ERROR_CHECK) {
12893de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			bnx2x_set_aer_mmd(params, &params->phy[phy_idx]);
12894de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			bnx2x_check_half_open_conn(params, vars);
12895de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner			break;
12896de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner		}
12897de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner	}
12898de6f3377d2da3b384ca3d716ffb8687ad175788aYaniv Rosner
12899a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	if (CHIP_IS_E3(bp)) {
12900a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		struct bnx2x_phy *phy = &params->phy[INT_PHY];
12901a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		bnx2x_set_aer_mmd(params, phy);
129023deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner		bnx2x_check_over_curr(params, vars);
12903a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner		bnx2x_warpcore_config_runtime(phy, params, vars);
12904a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner	}
12905a9077bfd0b3fdcd1051cc3d09bf8c28f9d4d506aYaniv Rosner
129063deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner}
129073deb8167ea66974b0bc8c13c8ee0beafc02a73a1Yaniv Rosner
12908a22f078867ef362e35c54055878168e6613ff743Yaniv Rosneru8 bnx2x_hw_lock_required(struct bnx2x *bp, u32 shmem_base, u32 shmem2_base)
12909d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner{
12910d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	u8 phy_index;
12911d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	struct bnx2x_phy phy;
12912d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12913d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	      phy_index++) {
12914a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12915d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner				       0, &phy) != 0) {
12916d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			DP(NETIF_MSG_LINK, "populate phy failed\n");
12917d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			return 0;
12918d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		}
12919d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
12920d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		if (phy.flags & FLAGS_HW_LOCK_REQUIRED)
12921d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			return 1;
12922d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	}
12923d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	return 0;
12924d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner}
12925d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
12926d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosneru8 bnx2x_fan_failure_det_req(struct bnx2x *bp,
12927d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			     u32 shmem_base,
12928a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner			     u32 shmem2_base,
12929d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			     u8 port)
12930d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner{
12931d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	u8 phy_index, fan_failure_det_req = 0;
12932d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	struct bnx2x_phy phy;
12933d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12934d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	      phy_index++) {
12935a22f078867ef362e35c54055878168e6613ff743Yaniv Rosner		if (bnx2x_populate_phy(bp, phy_index, shmem_base, shmem2_base,
12936d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner				       port, &phy)
12937d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		    != 0) {
12938d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			DP(NETIF_MSG_LINK, "populate phy failed\n");
12939d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			return 0;
12940d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		}
12941d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		fan_failure_det_req |= (phy.flags &
12942d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner					FLAGS_FAN_FAILURE_DET_REQ);
12943d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	}
12944d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	return fan_failure_det_req;
12945d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner}
12946d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner
12947d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosnervoid bnx2x_hw_reset_phy(struct link_params *params)
12948d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner{
12949d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	u8 phy_index;
12950985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	struct bnx2x *bp = params->bp;
12951985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	bnx2x_update_mng(params, 0);
12952985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
12953985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner		       (NIG_MASK_XGXS0_LINK_STATUS |
12954985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner			NIG_MASK_XGXS0_LINK10G |
12955985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner			NIG_MASK_SERDES0_LINK_STATUS |
12956985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner			NIG_MASK_MI_INT));
12957985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner
12958985848f80ffc61a29d9a72fec46ddce3c9643636Yaniv Rosner	for (phy_index = INT_PHY; phy_index < MAX_PHYS;
12959d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	      phy_index++) {
12960d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		if (params->phy[phy_index].hw_reset) {
12961d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			params->phy[phy_index].hw_reset(
12962d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner				&params->phy[phy_index],
12963d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner				params);
12964d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner			params->phy[phy_index] = phy_null;
12965d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner		}
12966d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner	}
12967d90d96baf0cc044bcdedc9ee9e925b5937865673Yaniv Rosner}
12968020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
12969020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosnervoid bnx2x_init_mod_abs_int(struct bnx2x *bp, struct link_vars *vars,
12970020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			    u32 chip_id, u32 shmem_base, u32 shmem2_base,
12971020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			    u8 port)
12972020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner{
12973020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	u8 gpio_num = 0xff, gpio_port = 0xff, phy_index;
12974020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	u32 val;
12975020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	u32 offset, aeu_mask, swap_val, swap_override, sync_offset;
129763c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	if (CHIP_IS_E3(bp)) {
129773c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner		if (bnx2x_get_mod_abs_int_cfg(bp, chip_id,
129783c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					      shmem_base,
129793c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					      port,
129803c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					      &gpio_num,
129813c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner					      &gpio_port) != 0)
129823c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner			return;
129833c9ada227c56c6f41e24b01d183b00b007c7ac93Yaniv Rosner	} else {
12984020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		struct bnx2x_phy phy;
12985020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		for (phy_index = EXT_PHY1; phy_index < MAX_PHYS;
12986020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		      phy_index++) {
12987020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			if (bnx2x_populate_phy(bp, phy_index, shmem_base,
12988020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner					       shmem2_base, port, &phy)
12989020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			    != 0) {
12990020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				DP(NETIF_MSG_LINK, "populate phy failed\n");
12991020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				return;
12992020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			}
12993020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			if (phy.type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8726) {
12994020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				gpio_num = MISC_REGISTERS_GPIO_3;
12995020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				gpio_port = port;
12996020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner				break;
12997020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			}
12998020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		}
12999020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	}
13000020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13001020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	if (gpio_num == 0xff)
13002020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		return;
13003020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13004020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	/* Set GPIO3 to trigger SFP+ module insertion/removal */
13005020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	bnx2x_set_gpio(bp, gpio_num, MISC_REGISTERS_GPIO_INPUT_HI_Z, gpio_port);
13006020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13007020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
13008020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
13009020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	gpio_port ^= (swap_val && swap_override);
13010020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13011020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	vars->aeu_int_mask = AEU_INPUTS_ATTN_BITS_GPIO0_FUNCTION_0 <<
13012020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		(gpio_num + (gpio_port << 2));
13013020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13014020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	sync_offset = shmem_base +
13015020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		offsetof(struct shmem_region,
13016020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner			 dev_info.port_hw_config[port].aeu_int_mask);
13017020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	REG_WR(bp, sync_offset, vars->aeu_int_mask);
13018020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13019020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	DP(NETIF_MSG_LINK, "Setting MOD_ABS (GPIO%d_P%d) AEU to 0x%x\n",
13020020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		       gpio_num, gpio_port, vars->aeu_int_mask);
13021020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13022020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	if (port == 0)
13023020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		offset = MISC_REG_AEU_ENABLE1_FUNC_0_OUT_0;
13024020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	else
13025020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner		offset = MISC_REG_AEU_ENABLE1_FUNC_1_OUT_0;
13026020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13027020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	/* Open appropriate AEU for interrupts */
13028020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	aeu_mask = REG_RD(bp, offset);
13029020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	aeu_mask |= vars->aeu_int_mask;
13030020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	REG_WR(bp, offset, aeu_mask);
13031020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner
13032020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	/* Enable the GPIO to trigger interrupt */
13033020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	val = REG_RD(bp, MISC_REG_GPIO_EVENT_EN);
13034020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	val |= 1 << (gpio_num + (gpio_port << 2));
13035020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner	REG_WR(bp, MISC_REG_GPIO_EVENT_EN, val);
13036020c7e3f3cd38d41104c7f55d3d5732c5ac939beYaniv Rosner}
13037