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