• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2008-2009 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 #include <linux/kernel.h>
18 #include <linux/errno.h>
19 #include <linux/pci.h>
20 #include <linux/netdevice.h>
21 #include <linux/delay.h>
22 #include <linux/ethtool.h>
23 #include <linux/mutex.h>
24 
25 #include "bnx2x_reg.h"
26 #include "bnx2x_fw_defs.h"
27 #include "bnx2x_hsi.h"
28 #include "bnx2x_link.h"
29 #include "bnx2x.h"
30 
31 /********************************************************/
32 #define SUPPORT_CL73 0 /* Currently no */
33 #define ETH_HLEN			14
34 #define ETH_OVREHEAD		(ETH_HLEN + 8)/* 8 for CRC + VLAN*/
35 #define ETH_MIN_PACKET_SIZE		60
36 #define ETH_MAX_PACKET_SIZE		1500
37 #define ETH_MAX_JUMBO_PACKET_SIZE	9600
38 #define MDIO_ACCESS_TIMEOUT		1000
39 #define BMAC_CONTROL_RX_ENABLE	2
40 
41 /***********************************************************/
42 /*			Shortcut definitions		   */
43 /***********************************************************/
44 
45 #define NIG_STATUS_XGXS0_LINK10G \
46 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
47 #define NIG_STATUS_XGXS0_LINK_STATUS \
48 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
49 #define NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
50 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
51 #define NIG_STATUS_SERDES0_LINK_STATUS \
52 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
53 #define NIG_MASK_MI_INT \
54 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
55 #define NIG_MASK_XGXS0_LINK10G \
56 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
57 #define NIG_MASK_XGXS0_LINK_STATUS \
58 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
59 #define NIG_MASK_SERDES0_LINK_STATUS \
60 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
61 
62 #define MDIO_AN_CL73_OR_37_COMPLETE \
63 		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
64 		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
65 
66 #define XGXS_RESET_BITS \
67 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
68 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
69 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
70 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
71 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
72 
73 #define SERDES_RESET_BITS \
74 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
75 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
76 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
77 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
78 
79 #define AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
80 #define AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
81 #define AUTONEG_BAM 		SHARED_HW_CFG_AN_ENABLE_BAM
82 #define AUTONEG_PARALLEL \
83 				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
84 #define AUTONEG_SGMII_FIBER_AUTODET \
85 				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
86 #define AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
87 
88 #define GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
89 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
90 #define GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
91 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
92 #define GP_STATUS_SPEED_MASK \
93 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
94 #define GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
95 #define GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
96 #define GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
97 #define GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
98 #define GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
99 #define GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
100 #define GP_STATUS_10G_HIG \
101 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
102 #define GP_STATUS_10G_CX4 \
103 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
104 #define GP_STATUS_12G_HIG \
105 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12G_HIG
106 #define GP_STATUS_12_5G MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_12_5G
107 #define GP_STATUS_13G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_13G
108 #define GP_STATUS_15G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_15G
109 #define GP_STATUS_16G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_16G
110 #define GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
111 #define GP_STATUS_10G_KX4 \
112 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
113 
114 #define LINK_10THD			LINK_STATUS_SPEED_AND_DUPLEX_10THD
115 #define LINK_10TFD			LINK_STATUS_SPEED_AND_DUPLEX_10TFD
116 #define LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
117 #define LINK_100T4			LINK_STATUS_SPEED_AND_DUPLEX_100T4
118 #define LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
119 #define LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
120 #define LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
121 #define LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
122 #define LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
123 #define LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
124 #define LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
125 #define LINK_10GTFD			LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
126 #define LINK_10GXFD			LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
127 #define LINK_12GTFD			LINK_STATUS_SPEED_AND_DUPLEX_12GTFD
128 #define LINK_12GXFD			LINK_STATUS_SPEED_AND_DUPLEX_12GXFD
129 #define LINK_12_5GTFD		LINK_STATUS_SPEED_AND_DUPLEX_12_5GTFD
130 #define LINK_12_5GXFD		LINK_STATUS_SPEED_AND_DUPLEX_12_5GXFD
131 #define LINK_13GTFD			LINK_STATUS_SPEED_AND_DUPLEX_13GTFD
132 #define LINK_13GXFD			LINK_STATUS_SPEED_AND_DUPLEX_13GXFD
133 #define LINK_15GTFD			LINK_STATUS_SPEED_AND_DUPLEX_15GTFD
134 #define LINK_15GXFD			LINK_STATUS_SPEED_AND_DUPLEX_15GXFD
135 #define LINK_16GTFD			LINK_STATUS_SPEED_AND_DUPLEX_16GTFD
136 #define LINK_16GXFD			LINK_STATUS_SPEED_AND_DUPLEX_16GXFD
137 
138 #define PHY_XGXS_FLAG			0x1
139 #define PHY_SGMII_FLAG			0x2
140 #define PHY_SERDES_FLAG			0x4
141 
142 /**********************************************************/
143 /*                     INTERFACE                          */
144 /**********************************************************/
145 #define CL45_WR_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
146 	bnx2x_cl45_write(_bp, _port, 0, _phy_addr, \
147 		DEFAULT_PHY_DEV_ADDR, \
148 		(_bank + (_addr & 0xf)), \
149 		_val)
150 
151 #define CL45_RD_OVER_CL22(_bp, _port, _phy_addr, _bank, _addr, _val) \
152 	bnx2x_cl45_read(_bp, _port, 0, _phy_addr, \
153 		DEFAULT_PHY_DEV_ADDR, \
154 		(_bank + (_addr & 0xf)), \
155 		_val)
156 
bnx2x_set_phy_mdio(struct link_params * params)157 static void bnx2x_set_phy_mdio(struct link_params *params)
158 {
159 	struct bnx2x *bp = params->bp;
160 	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_ST +
161 		   params->port*0x18, 0);
162 	REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + params->port*0x18,
163 		   DEFAULT_PHY_DEV_ADDR);
164 }
165 
bnx2x_bits_en(struct bnx2x * bp,u32 reg,u32 bits)166 static u32 bnx2x_bits_en(struct bnx2x *bp, u32 reg, u32 bits)
167 {
168 	u32 val = REG_RD(bp, reg);
169 
170 	val |= bits;
171 	REG_WR(bp, reg, val);
172 	return val;
173 }
174 
bnx2x_bits_dis(struct bnx2x * bp,u32 reg,u32 bits)175 static u32 bnx2x_bits_dis(struct bnx2x *bp, u32 reg, u32 bits)
176 {
177 	u32 val = REG_RD(bp, reg);
178 
179 	val &= ~bits;
180 	REG_WR(bp, reg, val);
181 	return val;
182 }
183 
bnx2x_emac_init(struct link_params * params,struct link_vars * vars)184 static void bnx2x_emac_init(struct link_params *params,
185 			   struct link_vars *vars)
186 {
187 	/* reset and unreset the emac core */
188 	struct bnx2x *bp = params->bp;
189 	u8 port = params->port;
190 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
191 	u32 val;
192 	u16 timeout;
193 
194 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
195 		   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
196 	udelay(5);
197 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
198 		   (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
199 
200 	/* init emac - use read-modify-write */
201 	/* self clear reset */
202 	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
203 	EMAC_WR(bp, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
204 
205 	timeout = 200;
206 	do {
207 		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
208 		DP(NETIF_MSG_LINK, "EMAC reset reg is %u\n", val);
209 		if (!timeout) {
210 			DP(NETIF_MSG_LINK, "EMAC timeout!\n");
211 			return;
212 		}
213 		timeout--;
214 	} while (val & EMAC_MODE_RESET);
215 
216 	/* Set mac address */
217 	val = ((params->mac_addr[0] << 8) |
218 		params->mac_addr[1]);
219 	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH, val);
220 
221 	val = ((params->mac_addr[2] << 24) |
222 	       (params->mac_addr[3] << 16) |
223 	       (params->mac_addr[4] << 8) |
224 		params->mac_addr[5]);
225 	EMAC_WR(bp, EMAC_REG_EMAC_MAC_MATCH + 4, val);
226 }
227 
bnx2x_emac_enable(struct link_params * params,struct link_vars * vars,u8 lb)228 static u8 bnx2x_emac_enable(struct link_params *params,
229 			  struct link_vars *vars, u8 lb)
230 {
231 	struct bnx2x *bp = params->bp;
232 	u8 port = params->port;
233 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
234 	u32 val;
235 
236 	DP(NETIF_MSG_LINK, "enabling EMAC\n");
237 
238 	/* enable emac and not bmac */
239 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
240 
241 	/* for paladium */
242 	if (CHIP_REV_IS_EMUL(bp)) {
243 		/* Use lane 1 (of lanes 0-3) */
244 		REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
245 		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
246 			    port*4, 1);
247 	}
248 	/* for fpga */
249 	else
250 
251 	if (CHIP_REV_IS_FPGA(bp)) {
252 		/* Use lane 1 (of lanes 0-3) */
253 		DP(NETIF_MSG_LINK, "bnx2x_emac_enable: Setting FPGA\n");
254 
255 		REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
256 		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4,
257 			    0);
258 	} else
259 	/* ASIC */
260 	if (vars->phy_flags & PHY_XGXS_FLAG) {
261 		u32 ser_lane = ((params->lane_config &
262 			    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
263 			    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
264 
265 		DP(NETIF_MSG_LINK, "XGXS\n");
266 		/* select the master lanes (out of 0-3) */
267 		REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 +
268 			   port*4, ser_lane);
269 		/* select XGXS */
270 		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
271 			   port*4, 1);
272 
273 	} else { /* SerDes */
274 		DP(NETIF_MSG_LINK, "SerDes\n");
275 		/* select SerDes */
276 		REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL +
277 			   port*4, 0);
278 	}
279 
280 	/* enable emac */
281 	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
282 
283 	if (CHIP_REV_IS_SLOW(bp)) {
284 		/* config GMII mode */
285 		val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
286 		EMAC_WR(bp, EMAC_REG_EMAC_MODE,
287 			    (val | EMAC_MODE_PORT_GMII));
288 	} else { /* ASIC */
289 		/* pause enable/disable */
290 		bnx2x_bits_dis(bp, emac_base + EMAC_REG_EMAC_RX_MODE,
291 			       EMAC_RX_MODE_FLOW_EN);
292 		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
293 			bnx2x_bits_en(bp, emac_base +
294 				    EMAC_REG_EMAC_RX_MODE,
295 				    EMAC_RX_MODE_FLOW_EN);
296 
297 		bnx2x_bits_dis(bp,  emac_base + EMAC_REG_EMAC_TX_MODE,
298 			     (EMAC_TX_MODE_EXT_PAUSE_EN |
299 			      EMAC_TX_MODE_FLOW_EN));
300 		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
301 			bnx2x_bits_en(bp, emac_base +
302 				    EMAC_REG_EMAC_TX_MODE,
303 				   (EMAC_TX_MODE_EXT_PAUSE_EN |
304 				    EMAC_TX_MODE_FLOW_EN));
305 	}
306 
307 	/* KEEP_VLAN_TAG, promiscuous */
308 	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_RX_MODE);
309 	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
310 	EMAC_WR(bp, EMAC_REG_EMAC_RX_MODE, val);
311 
312 	/* Set Loopback */
313 	val = REG_RD(bp, emac_base + EMAC_REG_EMAC_MODE);
314 	if (lb)
315 		val |= 0x810;
316 	else
317 		val &= ~0x810;
318 	EMAC_WR(bp, EMAC_REG_EMAC_MODE, val);
319 
320 	/* enable emac */
321 	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 1);
322 
323 	/* enable emac for jumbo packets */
324 	EMAC_WR(bp, EMAC_REG_EMAC_RX_MTU_SIZE,
325 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
326 		 (ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD)));
327 
328 	/* strip CRC */
329 	REG_WR(bp, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
330 
331 	/* disable the NIG in/out to the bmac */
332 	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
333 	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
334 	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
335 
336 	/* enable the NIG in/out to the emac */
337 	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
338 	val = 0;
339 	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
340 		val = 1;
341 
342 	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
343 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
344 
345 	if (CHIP_REV_IS_EMUL(bp)) {
346 		/* take the BigMac out of reset */
347 		REG_WR(bp,
348 			   GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
349 			   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
350 
351 		/* enable access for bmac registers */
352 		REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
353 	}
354 
355 	vars->mac_type = MAC_TYPE_EMAC;
356 	return 0;
357 }
358 
359 
360 
bnx2x_bmac_enable(struct link_params * params,struct link_vars * vars,u8 is_lb)361 static u8 bnx2x_bmac_enable(struct link_params *params, struct link_vars *vars,
362 			  u8 is_lb)
363 {
364 	struct bnx2x *bp = params->bp;
365 	u8 port = params->port;
366 	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
367 			       NIG_REG_INGRESS_BMAC0_MEM;
368 	u32 wb_data[2];
369 	u32 val;
370 
371 	DP(NETIF_MSG_LINK, "Enabling BigMAC\n");
372 	/* reset and unreset the BigMac */
373 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
374 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
375 	msleep(1);
376 
377 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
378 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
379 
380 	/* enable access for bmac registers */
381 	REG_WR(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
382 
383 	/* XGXS control */
384 	wb_data[0] = 0x3c;
385 	wb_data[1] = 0;
386 	REG_WR_DMAE(bp, bmac_addr +
387 		      BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
388 		      wb_data, 2);
389 
390 	/* tx MAC SA */
391 	wb_data[0] = ((params->mac_addr[2] << 24) |
392 		       (params->mac_addr[3] << 16) |
393 		       (params->mac_addr[4] << 8) |
394 			params->mac_addr[5]);
395 	wb_data[1] = ((params->mac_addr[0] << 8) |
396 			params->mac_addr[1]);
397 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR,
398 		    wb_data, 2);
399 
400 	/* tx control */
401 	val = 0xc0;
402 	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
403 		val |= 0x800000;
404 	wb_data[0] = val;
405 	wb_data[1] = 0;
406 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_CONTROL,
407 			wb_data, 2);
408 
409 	/* mac control */
410 	val = 0x3;
411 	if (is_lb) {
412 		val |= 0x4;
413 		DP(NETIF_MSG_LINK, "enable bmac loopback\n");
414 	}
415 	wb_data[0] = val;
416 	wb_data[1] = 0;
417 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
418 		    wb_data, 2);
419 
420 
421 	/* set rx mtu */
422 	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
423 	wb_data[1] = 0;
424 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE,
425 			wb_data, 2);
426 
427 	/* rx control set to don't strip crc */
428 	val = 0x14;
429 	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
430 		val |= 0x20;
431 	wb_data[0] = val;
432 	wb_data[1] = 0;
433 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_CONTROL,
434 			wb_data, 2);
435 
436 	/* set tx mtu */
437 	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
438 	wb_data[1] = 0;
439 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE,
440 			wb_data, 2);
441 
442 	/* set cnt max size */
443 	wb_data[0] = ETH_MAX_JUMBO_PACKET_SIZE + ETH_OVREHEAD;
444 	wb_data[1] = 0;
445 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE,
446 		    wb_data, 2);
447 
448 	/* configure safc */
449 	wb_data[0] = 0x1000200;
450 	wb_data[1] = 0;
451 	REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
452 		    wb_data, 2);
453 	/* fix for emulation */
454 	if (CHIP_REV_IS_EMUL(bp)) {
455 		wb_data[0] = 0xf000;
456 		wb_data[1] = 0;
457 		REG_WR_DMAE(bp,
458 			    bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
459 			    wb_data, 2);
460 	}
461 
462 	REG_WR(bp, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
463 	REG_WR(bp, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
464 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
465 	val = 0;
466 	if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
467 		val = 1;
468 	REG_WR(bp, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
469 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
470 	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
471 	REG_WR(bp, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
472 	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
473 	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
474 
475 	vars->mac_type = MAC_TYPE_BMAC;
476 	return 0;
477 }
478 
bnx2x_phy_deassert(struct link_params * params,u8 phy_flags)479 static void bnx2x_phy_deassert(struct link_params *params, u8 phy_flags)
480 {
481 	struct bnx2x *bp = params->bp;
482 	u32 val;
483 
484 	if (phy_flags & PHY_XGXS_FLAG) {
485 		DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:XGXS\n");
486 		val = XGXS_RESET_BITS;
487 
488 	} else { /* SerDes */
489 		DP(NETIF_MSG_LINK, "bnx2x_phy_deassert:SerDes\n");
490 		val = SERDES_RESET_BITS;
491 	}
492 
493 	val = val << (params->port*16);
494 
495 	/* reset and unreset the SerDes/XGXS */
496 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
497 		    val);
498 	udelay(500);
499 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_SET,
500 		    val);
501 	bnx2x_set_phy_mdio(params);
502 }
503 
bnx2x_link_status_update(struct link_params * params,struct link_vars * vars)504 void bnx2x_link_status_update(struct link_params *params,
505 			    struct link_vars   *vars)
506 {
507 	struct bnx2x *bp = params->bp;
508 	u8 link_10g;
509 	u8 port = params->port;
510 
511 	if (params->switch_cfg ==  SWITCH_CFG_1G)
512 		vars->phy_flags = PHY_SERDES_FLAG;
513 	else
514 		vars->phy_flags = PHY_XGXS_FLAG;
515 	vars->link_status = REG_RD(bp, params->shmem_base +
516 					  offsetof(struct shmem_region,
517 					   port_mb[port].link_status));
518 
519 	vars->link_up = (vars->link_status & LINK_STATUS_LINK_UP);
520 
521 	if (vars->link_up) {
522 		DP(NETIF_MSG_LINK, "phy link up\n");
523 
524 		vars->phy_link_up = 1;
525 		vars->duplex = DUPLEX_FULL;
526 		switch (vars->link_status &
527 					LINK_STATUS_SPEED_AND_DUPLEX_MASK) {
528 			case LINK_10THD:
529 				vars->duplex = DUPLEX_HALF;
530 				/* fall thru */
531 			case LINK_10TFD:
532 				vars->line_speed = SPEED_10;
533 				break;
534 
535 			case LINK_100TXHD:
536 				vars->duplex = DUPLEX_HALF;
537 				/* fall thru */
538 			case LINK_100T4:
539 			case LINK_100TXFD:
540 				vars->line_speed = SPEED_100;
541 				break;
542 
543 			case LINK_1000THD:
544 				vars->duplex = DUPLEX_HALF;
545 				/* fall thru */
546 			case LINK_1000TFD:
547 				vars->line_speed = SPEED_1000;
548 				break;
549 
550 			case LINK_2500THD:
551 				vars->duplex = DUPLEX_HALF;
552 				/* fall thru */
553 			case LINK_2500TFD:
554 				vars->line_speed = SPEED_2500;
555 				break;
556 
557 			case LINK_10GTFD:
558 				vars->line_speed = SPEED_10000;
559 				break;
560 
561 			case LINK_12GTFD:
562 				vars->line_speed = SPEED_12000;
563 				break;
564 
565 			case LINK_12_5GTFD:
566 				vars->line_speed = SPEED_12500;
567 				break;
568 
569 			case LINK_13GTFD:
570 				vars->line_speed = SPEED_13000;
571 				break;
572 
573 			case LINK_15GTFD:
574 				vars->line_speed = SPEED_15000;
575 				break;
576 
577 			case LINK_16GTFD:
578 				vars->line_speed = SPEED_16000;
579 				break;
580 
581 			default:
582 				break;
583 		}
584 
585 		if (vars->link_status & LINK_STATUS_TX_FLOW_CONTROL_ENABLED)
586 			vars->flow_ctrl |= BNX2X_FLOW_CTRL_TX;
587 		else
588 			vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_TX;
589 
590 		if (vars->link_status & LINK_STATUS_RX_FLOW_CONTROL_ENABLED)
591 			vars->flow_ctrl |= BNX2X_FLOW_CTRL_RX;
592 		else
593 			vars->flow_ctrl &= ~BNX2X_FLOW_CTRL_RX;
594 
595 		if (vars->phy_flags & PHY_XGXS_FLAG) {
596 			if (vars->line_speed &&
597 			    ((vars->line_speed == SPEED_10) ||
598 			     (vars->line_speed == SPEED_100))) {
599 				vars->phy_flags |= PHY_SGMII_FLAG;
600 			} else {
601 				vars->phy_flags &= ~PHY_SGMII_FLAG;
602 			}
603 		}
604 
605 		/* anything 10 and over uses the bmac */
606 		link_10g = ((vars->line_speed == SPEED_10000) ||
607 			    (vars->line_speed == SPEED_12000) ||
608 			    (vars->line_speed == SPEED_12500) ||
609 			    (vars->line_speed == SPEED_13000) ||
610 			    (vars->line_speed == SPEED_15000) ||
611 			    (vars->line_speed == SPEED_16000));
612 		if (link_10g)
613 			vars->mac_type = MAC_TYPE_BMAC;
614 		else
615 			vars->mac_type = MAC_TYPE_EMAC;
616 
617 	} else { /* link down */
618 		DP(NETIF_MSG_LINK, "phy link down\n");
619 
620 		vars->phy_link_up = 0;
621 
622 		vars->line_speed = 0;
623 		vars->duplex = DUPLEX_FULL;
624 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
625 
626 		/* indicate no mac active */
627 		vars->mac_type = MAC_TYPE_NONE;
628 	}
629 
630 	DP(NETIF_MSG_LINK, "link_status 0x%x  phy_link_up %x\n",
631 		 vars->link_status, vars->phy_link_up);
632 	DP(NETIF_MSG_LINK, "line_speed %x  duplex %x  flow_ctrl 0x%x\n",
633 		 vars->line_speed, vars->duplex, vars->flow_ctrl);
634 }
635 
bnx2x_update_mng(struct link_params * params,u32 link_status)636 static void bnx2x_update_mng(struct link_params *params, u32 link_status)
637 {
638 	struct bnx2x *bp = params->bp;
639 	REG_WR(bp, params->shmem_base +
640 		   offsetof(struct shmem_region,
641 			    port_mb[params->port].link_status),
642 			link_status);
643 }
644 
bnx2x_bmac_rx_disable(struct bnx2x * bp,u8 port)645 static void bnx2x_bmac_rx_disable(struct bnx2x *bp, u8 port)
646 {
647 	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
648 		NIG_REG_INGRESS_BMAC0_MEM;
649 	u32 wb_data[2];
650 	u32 nig_bmac_enable = REG_RD(bp, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
651 
652 	/* Only if the bmac is out of reset */
653 	if (REG_RD(bp, MISC_REG_RESET_REG_2) &
654 			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
655 	    nig_bmac_enable) {
656 
657 		/* Clear Rx Enable bit in BMAC_CONTROL register */
658 		REG_RD_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
659 			    wb_data, 2);
660 		wb_data[0] &= ~BMAC_CONTROL_RX_ENABLE;
661 		REG_WR_DMAE(bp, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL,
662 			    wb_data, 2);
663 
664 		msleep(1);
665 	}
666 }
667 
bnx2x_pbf_update(struct link_params * params,u32 flow_ctrl,u32 line_speed)668 static u8 bnx2x_pbf_update(struct link_params *params, u32 flow_ctrl,
669 			 u32 line_speed)
670 {
671 	struct bnx2x *bp = params->bp;
672 	u8 port = params->port;
673 	u32 init_crd, crd;
674 	u32 count = 1000;
675 
676 	/* disable port */
677 	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
678 
679 	/* wait for init credit */
680 	init_crd = REG_RD(bp, PBF_REG_P0_INIT_CRD + port*4);
681 	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
682 	DP(NETIF_MSG_LINK, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
683 
684 	while ((init_crd != crd) && count) {
685 		msleep(5);
686 
687 		crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
688 		count--;
689 	}
690 	crd = REG_RD(bp, PBF_REG_P0_CREDIT + port*8);
691 	if (init_crd != crd) {
692 		DP(NETIF_MSG_LINK, "BUG! init_crd 0x%x != crd 0x%x\n",
693 			  init_crd, crd);
694 		return -EINVAL;
695 	}
696 
697 	if (flow_ctrl & BNX2X_FLOW_CTRL_RX ||
698 	    line_speed == SPEED_10 ||
699 	    line_speed == SPEED_100 ||
700 	    line_speed == SPEED_1000 ||
701 	    line_speed == SPEED_2500) {
702 		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
703 		/* update threshold */
704 		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, 0);
705 		/* update init credit */
706 		init_crd = 778; 	/* (800-18-4) */
707 
708 	} else {
709 		u32 thresh = (ETH_MAX_JUMBO_PACKET_SIZE +
710 			      ETH_OVREHEAD)/16;
711 		REG_WR(bp, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
712 		/* update threshold */
713 		REG_WR(bp, PBF_REG_P0_ARB_THRSH + port*4, thresh);
714 		/* update init credit */
715 		switch (line_speed) {
716 		case SPEED_10000:
717 			init_crd = thresh + 553 - 22;
718 			break;
719 
720 		case SPEED_12000:
721 			init_crd = thresh + 664 - 22;
722 			break;
723 
724 		case SPEED_13000:
725 			init_crd = thresh + 742 - 22;
726 			break;
727 
728 		case SPEED_16000:
729 			init_crd = thresh + 778 - 22;
730 			break;
731 		default:
732 			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
733 				  line_speed);
734 			return -EINVAL;
735 			break;
736 		}
737 	}
738 	REG_WR(bp, PBF_REG_P0_INIT_CRD + port*4, init_crd);
739 	DP(NETIF_MSG_LINK, "PBF updated to speed %d credit %d\n",
740 		 line_speed, init_crd);
741 
742 	/* probe the credit changes */
743 	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x1);
744 	msleep(5);
745 	REG_WR(bp, PBF_REG_INIT_P0 + port*4, 0x0);
746 
747 	/* enable port */
748 	REG_WR(bp, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
749 	return 0;
750 }
751 
bnx2x_get_emac_base(u32 ext_phy_type,u8 port)752 static u32 bnx2x_get_emac_base(u32 ext_phy_type, u8 port)
753 {
754 	u32 emac_base;
755 	switch (ext_phy_type) {
756 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
757 		emac_base = GRCBASE_EMAC0;
758 		break;
759 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
760 		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
761 		break;
762 	default:
763 		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
764 		break;
765 	}
766 	return emac_base;
767 
768 }
769 
bnx2x_cl45_write(struct bnx2x * bp,u8 port,u32 ext_phy_type,u8 phy_addr,u8 devad,u16 reg,u16 val)770 u8 bnx2x_cl45_write(struct bnx2x *bp, u8 port, u32 ext_phy_type,
771 		  u8 phy_addr, u8 devad, u16 reg, u16 val)
772 {
773 	u32 tmp, saved_mode;
774 	u8 i, rc = 0;
775 	u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
776 
777 	/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
778 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
779 	 */
780 	saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
781 	tmp = saved_mode & ~(EMAC_MDIO_MODE_AUTO_POLL |
782 			     EMAC_MDIO_MODE_CLOCK_CNT);
783 	tmp |= (EMAC_MDIO_MODE_CLAUSE_45 |
784 		(49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
785 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, tmp);
786 	REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
787 	udelay(40);
788 
789 	/* address */
790 
791 	tmp = ((phy_addr << 21) | (devad << 16) | reg |
792 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
793 	       EMAC_MDIO_COMM_START_BUSY);
794 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
795 
796 	for (i = 0; i < 50; i++) {
797 		udelay(10);
798 
799 		tmp = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
800 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
801 			udelay(5);
802 			break;
803 		}
804 	}
805 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
806 		DP(NETIF_MSG_LINK, "write phy register failed\n");
807 		rc = -EFAULT;
808 	} else {
809 		/* data */
810 		tmp = ((phy_addr << 21) | (devad << 16) | val |
811 		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
812 		       EMAC_MDIO_COMM_START_BUSY);
813 		REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
814 
815 		for (i = 0; i < 50; i++) {
816 			udelay(10);
817 
818 			tmp = REG_RD(bp, mdio_ctrl +
819 					 EMAC_REG_EMAC_MDIO_COMM);
820 			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
821 				udelay(5);
822 				break;
823 			}
824 		}
825 		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
826 			DP(NETIF_MSG_LINK, "write phy register failed\n");
827 			rc = -EFAULT;
828 		}
829 	}
830 
831 	/* Restore the saved mode */
832 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
833 
834 	return rc;
835 }
836 
bnx2x_cl45_read(struct bnx2x * bp,u8 port,u32 ext_phy_type,u8 phy_addr,u8 devad,u16 reg,u16 * ret_val)837 u8 bnx2x_cl45_read(struct bnx2x *bp, u8 port, u32 ext_phy_type,
838 		 u8 phy_addr, u8 devad, u16 reg, u16 *ret_val)
839 {
840 	u32 val, saved_mode;
841 	u16 i;
842 	u8 rc = 0;
843 
844 	u32 mdio_ctrl = bnx2x_get_emac_base(ext_phy_type, port);
845 	/* set clause 45 mode, slow down the MDIO clock to 2.5MHz
846 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
847 	 */
848 	saved_mode = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
849 	val = saved_mode & ((EMAC_MDIO_MODE_AUTO_POLL |
850 			     EMAC_MDIO_MODE_CLOCK_CNT));
851 	val |= (EMAC_MDIO_MODE_CLAUSE_45 |
852 		(49 << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT));
853 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, val);
854 	REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
855 	udelay(40);
856 
857 	/* address */
858 	val = ((phy_addr << 21) | (devad << 16) | reg |
859 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
860 	       EMAC_MDIO_COMM_START_BUSY);
861 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
862 
863 	for (i = 0; i < 50; i++) {
864 		udelay(10);
865 
866 		val = REG_RD(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
867 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
868 			udelay(5);
869 			break;
870 		}
871 	}
872 	if (val & EMAC_MDIO_COMM_START_BUSY) {
873 		DP(NETIF_MSG_LINK, "read phy register failed\n");
874 
875 		*ret_val = 0;
876 		rc = -EFAULT;
877 
878 	} else {
879 		/* data */
880 		val = ((phy_addr << 21) | (devad << 16) |
881 		       EMAC_MDIO_COMM_COMMAND_READ_45 |
882 		       EMAC_MDIO_COMM_START_BUSY);
883 		REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
884 
885 		for (i = 0; i < 50; i++) {
886 			udelay(10);
887 
888 			val = REG_RD(bp, mdio_ctrl +
889 					  EMAC_REG_EMAC_MDIO_COMM);
890 			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
891 				*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
892 				break;
893 			}
894 		}
895 		if (val & EMAC_MDIO_COMM_START_BUSY) {
896 			DP(NETIF_MSG_LINK, "read phy register failed\n");
897 
898 			*ret_val = 0;
899 			rc = -EFAULT;
900 		}
901 	}
902 
903 	/* Restore the saved mode */
904 	REG_WR(bp, mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, saved_mode);
905 
906 	return rc;
907 }
908 
bnx2x_set_aer_mmd(struct link_params * params,struct link_vars * vars)909 static void bnx2x_set_aer_mmd(struct link_params *params,
910 			    struct link_vars   *vars)
911 {
912 	struct bnx2x *bp = params->bp;
913 	u32 ser_lane;
914 	u16 offset;
915 
916 	ser_lane = ((params->lane_config &
917 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
918 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
919 
920 	offset = (vars->phy_flags & PHY_XGXS_FLAG) ?
921 		(params->phy_addr + ser_lane) : 0;
922 
923 	CL45_WR_OVER_CL22(bp, params->port,
924 			      params->phy_addr,
925 			      MDIO_REG_BANK_AER_BLOCK,
926 			      MDIO_AER_BLOCK_AER_REG, 0x3800 + offset);
927 }
928 
bnx2x_set_master_ln(struct link_params * params)929 static void bnx2x_set_master_ln(struct link_params *params)
930 {
931 	struct bnx2x *bp = params->bp;
932 	u16 new_master_ln, ser_lane;
933 	ser_lane =  ((params->lane_config &
934 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
935 		     PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
936 
937 	/* set the master_ln for AN */
938 	CL45_RD_OVER_CL22(bp, params->port,
939 			      params->phy_addr,
940 			      MDIO_REG_BANK_XGXS_BLOCK2,
941 			      MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
942 			      &new_master_ln);
943 
944 	CL45_WR_OVER_CL22(bp, params->port,
945 			      params->phy_addr,
946 			      MDIO_REG_BANK_XGXS_BLOCK2 ,
947 			      MDIO_XGXS_BLOCK2_TEST_MODE_LANE,
948 			      (new_master_ln | ser_lane));
949 }
950 
bnx2x_reset_unicore(struct link_params * params)951 static u8 bnx2x_reset_unicore(struct link_params *params)
952 {
953 	struct bnx2x *bp = params->bp;
954 	u16 mii_control;
955 	u16 i;
956 
957 	CL45_RD_OVER_CL22(bp, params->port,
958 			      params->phy_addr,
959 			      MDIO_REG_BANK_COMBO_IEEE0,
960 			      MDIO_COMBO_IEEE0_MII_CONTROL, &mii_control);
961 
962 	/* reset the unicore */
963 	CL45_WR_OVER_CL22(bp, params->port,
964 			      params->phy_addr,
965 			      MDIO_REG_BANK_COMBO_IEEE0,
966 			      MDIO_COMBO_IEEE0_MII_CONTROL,
967 			      (mii_control |
968 			       MDIO_COMBO_IEEO_MII_CONTROL_RESET));
969 
970 	/* wait for the reset to self clear */
971 	for (i = 0; i < MDIO_ACCESS_TIMEOUT; i++) {
972 		udelay(5);
973 
974 		/* the reset erased the previous bank value */
975 		CL45_RD_OVER_CL22(bp, params->port,
976 				      params->phy_addr,
977 			      MDIO_REG_BANK_COMBO_IEEE0,
978 			      MDIO_COMBO_IEEE0_MII_CONTROL,
979 			      &mii_control);
980 
981 		if (!(mii_control & MDIO_COMBO_IEEO_MII_CONTROL_RESET)) {
982 			udelay(5);
983 			return 0;
984 		}
985 	}
986 
987 	DP(NETIF_MSG_LINK, "BUG! XGXS is still in reset!\n");
988 	return -EINVAL;
989 
990 }
991 
bnx2x_set_swap_lanes(struct link_params * params)992 static void bnx2x_set_swap_lanes(struct link_params *params)
993 {
994 	struct bnx2x *bp = params->bp;
995 	/* Each two bits represents a lane number:
996 	   No swap is 0123 => 0x1b no need to enable the swap */
997 	u16 ser_lane, rx_lane_swap, tx_lane_swap;
998 
999 	ser_lane = ((params->lane_config &
1000 			 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
1001 			PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
1002 	rx_lane_swap = ((params->lane_config &
1003 			     PORT_HW_CFG_LANE_SWAP_CFG_RX_MASK) >>
1004 			    PORT_HW_CFG_LANE_SWAP_CFG_RX_SHIFT);
1005 	tx_lane_swap = ((params->lane_config &
1006 			     PORT_HW_CFG_LANE_SWAP_CFG_TX_MASK) >>
1007 			    PORT_HW_CFG_LANE_SWAP_CFG_TX_SHIFT);
1008 
1009 	if (rx_lane_swap != 0x1b) {
1010 		CL45_WR_OVER_CL22(bp, params->port,
1011 				      params->phy_addr,
1012 				    MDIO_REG_BANK_XGXS_BLOCK2,
1013 				    MDIO_XGXS_BLOCK2_RX_LN_SWAP,
1014 				    (rx_lane_swap |
1015 				    MDIO_XGXS_BLOCK2_RX_LN_SWAP_ENABLE |
1016 				    MDIO_XGXS_BLOCK2_RX_LN_SWAP_FORCE_ENABLE));
1017 	} else {
1018 		CL45_WR_OVER_CL22(bp, params->port,
1019 				      params->phy_addr,
1020 				      MDIO_REG_BANK_XGXS_BLOCK2,
1021 				      MDIO_XGXS_BLOCK2_RX_LN_SWAP, 0);
1022 	}
1023 
1024 	if (tx_lane_swap != 0x1b) {
1025 		CL45_WR_OVER_CL22(bp, params->port,
1026 				      params->phy_addr,
1027 				      MDIO_REG_BANK_XGXS_BLOCK2,
1028 				      MDIO_XGXS_BLOCK2_TX_LN_SWAP,
1029 				      (tx_lane_swap |
1030 				       MDIO_XGXS_BLOCK2_TX_LN_SWAP_ENABLE));
1031 	} else {
1032 		CL45_WR_OVER_CL22(bp, params->port,
1033 				      params->phy_addr,
1034 				      MDIO_REG_BANK_XGXS_BLOCK2,
1035 				      MDIO_XGXS_BLOCK2_TX_LN_SWAP, 0);
1036 	}
1037 }
1038 
bnx2x_set_parallel_detection(struct link_params * params,u8 phy_flags)1039 static void bnx2x_set_parallel_detection(struct link_params *params,
1040 				       u8       	 phy_flags)
1041 {
1042 	struct bnx2x *bp = params->bp;
1043 	u16 control2;
1044 
1045 	CL45_RD_OVER_CL22(bp, params->port,
1046 			      params->phy_addr,
1047 			      MDIO_REG_BANK_SERDES_DIGITAL,
1048 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1049 			      &control2);
1050 
1051 
1052 	control2 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL2_PRL_DT_EN;
1053 
1054 
1055 	CL45_WR_OVER_CL22(bp, params->port,
1056 			      params->phy_addr,
1057 			      MDIO_REG_BANK_SERDES_DIGITAL,
1058 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL2,
1059 			      control2);
1060 
1061 	if (phy_flags & PHY_XGXS_FLAG) {
1062 		DP(NETIF_MSG_LINK, "XGXS\n");
1063 
1064 		CL45_WR_OVER_CL22(bp, params->port,
1065 				      params->phy_addr,
1066 				MDIO_REG_BANK_10G_PARALLEL_DETECT,
1067 				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK,
1068 				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_LINK_CNT);
1069 
1070 		CL45_RD_OVER_CL22(bp, params->port,
1071 				      params->phy_addr,
1072 				MDIO_REG_BANK_10G_PARALLEL_DETECT,
1073 				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1074 				&control2);
1075 
1076 
1077 		control2 |=
1078 		    MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL_PARDET10G_EN;
1079 
1080 		CL45_WR_OVER_CL22(bp, params->port,
1081 				      params->phy_addr,
1082 				MDIO_REG_BANK_10G_PARALLEL_DETECT,
1083 				MDIO_10G_PARALLEL_DETECT_PAR_DET_10G_CONTROL,
1084 				control2);
1085 
1086 		/* Disable parallel detection of HiG */
1087 		CL45_WR_OVER_CL22(bp, params->port,
1088 				      params->phy_addr,
1089 				MDIO_REG_BANK_XGXS_BLOCK2,
1090 				MDIO_XGXS_BLOCK2_UNICORE_MODE_10G,
1091 				MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_CX4_XGXS |
1092 				MDIO_XGXS_BLOCK2_UNICORE_MODE_10G_HIGIG_XGXS);
1093 	}
1094 }
1095 
bnx2x_set_autoneg(struct link_params * params,struct link_vars * vars)1096 static void bnx2x_set_autoneg(struct link_params *params,
1097 			    struct link_vars   *vars)
1098 {
1099 	struct bnx2x *bp = params->bp;
1100 	u16 reg_val;
1101 
1102 	/* CL37 Autoneg */
1103 
1104 	CL45_RD_OVER_CL22(bp, params->port,
1105 			      params->phy_addr,
1106 			      MDIO_REG_BANK_COMBO_IEEE0,
1107 			      MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1108 
1109 	/* CL37 Autoneg Enabled */
1110 	if (vars->line_speed == SPEED_AUTO_NEG)
1111 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_AN_EN;
1112 	else /* CL37 Autoneg Disabled */
1113 		reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1114 			     MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN);
1115 
1116 	CL45_WR_OVER_CL22(bp, params->port,
1117 			      params->phy_addr,
1118 			      MDIO_REG_BANK_COMBO_IEEE0,
1119 			      MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1120 
1121 	/* Enable/Disable Autodetection */
1122 
1123 	CL45_RD_OVER_CL22(bp, params->port,
1124 			      params->phy_addr,
1125 			      MDIO_REG_BANK_SERDES_DIGITAL,
1126 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, &reg_val);
1127 	reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_SIGNAL_DETECT_EN;
1128 	if (vars->line_speed == SPEED_AUTO_NEG)
1129 		reg_val |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1130 	else
1131 		reg_val &= ~MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET;
1132 
1133 	CL45_WR_OVER_CL22(bp, params->port,
1134 			      params->phy_addr,
1135 			      MDIO_REG_BANK_SERDES_DIGITAL,
1136 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1, reg_val);
1137 
1138 	/* Enable TetonII and BAM autoneg */
1139 	CL45_RD_OVER_CL22(bp, params->port,
1140 			      params->phy_addr,
1141 			      MDIO_REG_BANK_BAM_NEXT_PAGE,
1142 			      MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1143 			  &reg_val);
1144 	if (vars->line_speed == SPEED_AUTO_NEG) {
1145 		/* Enable BAM aneg Mode and TetonII aneg Mode */
1146 		reg_val |= (MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1147 			    MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1148 	} else {
1149 		/* TetonII and BAM Autoneg Disabled */
1150 		reg_val &= ~(MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_BAM_MODE |
1151 			     MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL_TETON_AN);
1152 	}
1153 	CL45_WR_OVER_CL22(bp, params->port,
1154 			      params->phy_addr,
1155 			      MDIO_REG_BANK_BAM_NEXT_PAGE,
1156 			      MDIO_BAM_NEXT_PAGE_MP5_NEXT_PAGE_CTRL,
1157 			      reg_val);
1158 
1159 	/* Enable Clause 73 Aneg */
1160 	if ((vars->line_speed == SPEED_AUTO_NEG) &&
1161 	    (SUPPORT_CL73)) {
1162 		/* Enable BAM Station Manager */
1163 
1164 		CL45_WR_OVER_CL22(bp, params->port,
1165 				      params->phy_addr,
1166 				      MDIO_REG_BANK_CL73_USERB0,
1167 				      MDIO_CL73_USERB0_CL73_BAM_CTRL1,
1168 				   (MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_EN |
1169 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_STATION_MNGR_EN |
1170 			MDIO_CL73_USERB0_CL73_BAM_CTRL1_BAM_NP_AFTER_BP_EN));
1171 
1172 		/* Merge CL73 and CL37 aneg resolution */
1173 		CL45_RD_OVER_CL22(bp, params->port,
1174 				      params->phy_addr,
1175 				      MDIO_REG_BANK_CL73_USERB0,
1176 				      MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1177 				      &reg_val);
1178 
1179 		CL45_WR_OVER_CL22(bp, params->port,
1180 				      params->phy_addr,
1181 			MDIO_REG_BANK_CL73_USERB0,
1182 			MDIO_CL73_USERB0_CL73_BAM_CTRL3,
1183 			(reg_val |
1184 			MDIO_CL73_USERB0_CL73_BAM_CTRL3_USE_CL73_HCD_MR));
1185 
1186 		/* Set the CL73 AN speed */
1187 
1188 		CL45_RD_OVER_CL22(bp, params->port,
1189 				      params->phy_addr,
1190 				      MDIO_REG_BANK_CL73_IEEEB1,
1191 				      MDIO_CL73_IEEEB1_AN_ADV2, &reg_val);
1192 		/* In the SerDes we support only the 1G.
1193 		   In the XGXS we support the 10G KX4
1194 		   but we currently do not support the KR */
1195 		if (vars->phy_flags & PHY_XGXS_FLAG) {
1196 			DP(NETIF_MSG_LINK, "XGXS\n");
1197 			/* 10G KX4 */
1198 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_10G_KX4;
1199 		} else {
1200 			DP(NETIF_MSG_LINK, "SerDes\n");
1201 			/* 1000M KX */
1202 			reg_val |= MDIO_CL73_IEEEB1_AN_ADV2_ADVR_1000M_KX;
1203 		}
1204 		CL45_WR_OVER_CL22(bp, params->port,
1205 				      params->phy_addr,
1206 				      MDIO_REG_BANK_CL73_IEEEB1,
1207 				      MDIO_CL73_IEEEB1_AN_ADV2, reg_val);
1208 
1209 		/* CL73 Autoneg Enabled */
1210 		reg_val = MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN;
1211 	} else {
1212 		/* CL73 Autoneg Disabled */
1213 		reg_val = 0;
1214 	}
1215 	CL45_WR_OVER_CL22(bp, params->port,
1216 			      params->phy_addr,
1217 			      MDIO_REG_BANK_CL73_IEEEB0,
1218 			      MDIO_CL73_IEEEB0_CL73_AN_CONTROL, reg_val);
1219 }
1220 
1221 /* program SerDes, forced speed */
bnx2x_program_serdes(struct link_params * params,struct link_vars * vars)1222 static void bnx2x_program_serdes(struct link_params *params,
1223 			       struct link_vars *vars)
1224 {
1225 	struct bnx2x *bp = params->bp;
1226 	u16 reg_val;
1227 
1228 	/* program duplex, disable autoneg */
1229 
1230 	CL45_RD_OVER_CL22(bp, params->port,
1231 			      params->phy_addr,
1232 			      MDIO_REG_BANK_COMBO_IEEE0,
1233 			      MDIO_COMBO_IEEE0_MII_CONTROL, &reg_val);
1234 	reg_val &= ~(MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX |
1235 		     MDIO_COMBO_IEEO_MII_CONTROL_AN_EN);
1236 	if (params->req_duplex == DUPLEX_FULL)
1237 		reg_val |= MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1238 	CL45_WR_OVER_CL22(bp, params->port,
1239 			      params->phy_addr,
1240 			      MDIO_REG_BANK_COMBO_IEEE0,
1241 			      MDIO_COMBO_IEEE0_MII_CONTROL, reg_val);
1242 
1243 	/* program speed
1244 	   - needed only if the speed is greater than 1G (2.5G or 10G) */
1245 	CL45_RD_OVER_CL22(bp, params->port,
1246 				      params->phy_addr,
1247 				      MDIO_REG_BANK_SERDES_DIGITAL,
1248 				      MDIO_SERDES_DIGITAL_MISC1, &reg_val);
1249 	/* clearing the speed value before setting the right speed */
1250 	DP(NETIF_MSG_LINK, "MDIO_REG_BANK_SERDES_DIGITAL = 0x%x\n", reg_val);
1251 
1252 	reg_val &= ~(MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_MASK |
1253 		     MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1254 
1255 	if (!((vars->line_speed == SPEED_1000) ||
1256 	      (vars->line_speed == SPEED_100) ||
1257 	      (vars->line_speed == SPEED_10))) {
1258 
1259 		reg_val |= (MDIO_SERDES_DIGITAL_MISC1_REFCLK_SEL_156_25M |
1260 			    MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_SEL);
1261 		if (vars->line_speed == SPEED_10000)
1262 			reg_val |=
1263 				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_10G_CX4;
1264 		if (vars->line_speed == SPEED_13000)
1265 			reg_val |=
1266 				MDIO_SERDES_DIGITAL_MISC1_FORCE_SPEED_13G;
1267 	}
1268 
1269 	CL45_WR_OVER_CL22(bp, params->port,
1270 				      params->phy_addr,
1271 				      MDIO_REG_BANK_SERDES_DIGITAL,
1272 				      MDIO_SERDES_DIGITAL_MISC1, reg_val);
1273 
1274 }
1275 
bnx2x_set_brcm_cl37_advertisment(struct link_params * params)1276 static void bnx2x_set_brcm_cl37_advertisment(struct link_params *params)
1277 {
1278 	struct bnx2x *bp = params->bp;
1279 	u16 val = 0;
1280 
1281 	/* configure the 48 bits for BAM AN */
1282 
1283 	/* set extended capabilities */
1284 	if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G)
1285 		val |= MDIO_OVER_1G_UP1_2_5G;
1286 	if (params->speed_cap_mask & PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
1287 		val |= MDIO_OVER_1G_UP1_10G;
1288 	CL45_WR_OVER_CL22(bp, params->port,
1289 			      params->phy_addr,
1290 			      MDIO_REG_BANK_OVER_1G,
1291 			      MDIO_OVER_1G_UP1, val);
1292 
1293 	CL45_WR_OVER_CL22(bp, params->port,
1294 			      params->phy_addr,
1295 			      MDIO_REG_BANK_OVER_1G,
1296 			      MDIO_OVER_1G_UP3, 0);
1297 }
1298 
bnx2x_calc_ieee_aneg_adv(struct link_params * params,u32 * ieee_fc)1299 static void bnx2x_calc_ieee_aneg_adv(struct link_params *params, u32 *ieee_fc)
1300 {
1301 	*ieee_fc = MDIO_COMBO_IEEE0_AUTO_NEG_ADV_FULL_DUPLEX;
1302 	/* resolve pause mode and advertisement
1303 	 * Please refer to Table 28B-3 of the 802.3ab-1999 spec */
1304 
1305 	switch (params->req_flow_ctrl) {
1306 	case BNX2X_FLOW_CTRL_AUTO:
1307 		if (params->req_fc_auto_adv == BNX2X_FLOW_CTRL_BOTH) {
1308 			*ieee_fc |=
1309 			     MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1310 		} else {
1311 			*ieee_fc |=
1312 		       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1313 		}
1314 		break;
1315 	case BNX2X_FLOW_CTRL_TX:
1316 		*ieee_fc |=
1317 		       MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
1318 		break;
1319 
1320 	case BNX2X_FLOW_CTRL_RX:
1321 	case BNX2X_FLOW_CTRL_BOTH:
1322 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
1323 		break;
1324 
1325 	case BNX2X_FLOW_CTRL_NONE:
1326 	default:
1327 		*ieee_fc |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_NONE;
1328 		break;
1329 	}
1330 }
1331 
bnx2x_set_ieee_aneg_advertisment(struct link_params * params,u32 ieee_fc)1332 static void bnx2x_set_ieee_aneg_advertisment(struct link_params *params,
1333 					   u32 ieee_fc)
1334 {
1335 	struct bnx2x *bp = params->bp;
1336 	/* for AN, we are always publishing full duplex */
1337 
1338 	CL45_WR_OVER_CL22(bp, params->port,
1339 			      params->phy_addr,
1340 			      MDIO_REG_BANK_COMBO_IEEE0,
1341 			      MDIO_COMBO_IEEE0_AUTO_NEG_ADV, (u16)ieee_fc);
1342 }
1343 
bnx2x_restart_autoneg(struct link_params * params)1344 static void bnx2x_restart_autoneg(struct link_params *params)
1345 {
1346 	struct bnx2x *bp = params->bp;
1347 	DP(NETIF_MSG_LINK, "bnx2x_restart_autoneg\n");
1348 	if (SUPPORT_CL73) {
1349 		/* enable and restart clause 73 aneg */
1350 		u16 an_ctrl;
1351 
1352 		CL45_RD_OVER_CL22(bp, params->port,
1353 				      params->phy_addr,
1354 				      MDIO_REG_BANK_CL73_IEEEB0,
1355 				      MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1356 				  &an_ctrl);
1357 		CL45_WR_OVER_CL22(bp, params->port,
1358 				      params->phy_addr,
1359 				MDIO_REG_BANK_CL73_IEEEB0,
1360 				MDIO_CL73_IEEEB0_CL73_AN_CONTROL,
1361 				(an_ctrl |
1362 				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_AN_EN |
1363 				MDIO_CL73_IEEEB0_CL73_AN_CONTROL_RESTART_AN));
1364 
1365 	} else {
1366 		/* Enable and restart BAM/CL37 aneg */
1367 		u16 mii_control;
1368 
1369 		CL45_RD_OVER_CL22(bp, params->port,
1370 				      params->phy_addr,
1371 				      MDIO_REG_BANK_COMBO_IEEE0,
1372 				      MDIO_COMBO_IEEE0_MII_CONTROL,
1373 				      &mii_control);
1374 		DP(NETIF_MSG_LINK,
1375 			 "bnx2x_restart_autoneg mii_control before = 0x%x\n",
1376 			 mii_control);
1377 		CL45_WR_OVER_CL22(bp, params->port,
1378 				      params->phy_addr,
1379 				      MDIO_REG_BANK_COMBO_IEEE0,
1380 				      MDIO_COMBO_IEEE0_MII_CONTROL,
1381 				      (mii_control |
1382 				MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1383 				MDIO_COMBO_IEEO_MII_CONTROL_RESTART_AN));
1384 	}
1385 }
1386 
bnx2x_initialize_sgmii_process(struct link_params * params,struct link_vars * vars)1387 static void bnx2x_initialize_sgmii_process(struct link_params *params,
1388 					 struct link_vars *vars)
1389 {
1390 	struct bnx2x *bp = params->bp;
1391 	u16 control1;
1392 
1393 	/* in SGMII mode, the unicore is always slave */
1394 
1395 	CL45_RD_OVER_CL22(bp, params->port,
1396 			      params->phy_addr,
1397 			      MDIO_REG_BANK_SERDES_DIGITAL,
1398 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1399 		      &control1);
1400 	control1 |= MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_INVERT_SIGNAL_DETECT;
1401 	/* set sgmii mode (and not fiber) */
1402 	control1 &= ~(MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_FIBER_MODE |
1403 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_AUTODET |
1404 		      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1_MSTR_MODE);
1405 	CL45_WR_OVER_CL22(bp, params->port,
1406 			      params->phy_addr,
1407 			      MDIO_REG_BANK_SERDES_DIGITAL,
1408 			      MDIO_SERDES_DIGITAL_A_1000X_CONTROL1,
1409 			      control1);
1410 
1411 	/* if forced speed */
1412 	if (!(vars->line_speed == SPEED_AUTO_NEG)) {
1413 		/* set speed, disable autoneg */
1414 		u16 mii_control;
1415 
1416 		CL45_RD_OVER_CL22(bp, params->port,
1417 				      params->phy_addr,
1418 				      MDIO_REG_BANK_COMBO_IEEE0,
1419 				      MDIO_COMBO_IEEE0_MII_CONTROL,
1420 				      &mii_control);
1421 		mii_control &= ~(MDIO_COMBO_IEEO_MII_CONTROL_AN_EN |
1422 				 MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_MASK|
1423 				 MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX);
1424 
1425 		switch (vars->line_speed) {
1426 		case SPEED_100:
1427 			mii_control |=
1428 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_100;
1429 			break;
1430 		case SPEED_1000:
1431 			mii_control |=
1432 				MDIO_COMBO_IEEO_MII_CONTROL_MAN_SGMII_SP_1000;
1433 			break;
1434 		case SPEED_10:
1435 			/* there is nothing to set for 10M */
1436 			break;
1437 		default:
1438 			/* invalid speed for SGMII */
1439 			DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n",
1440 				  vars->line_speed);
1441 			break;
1442 		}
1443 
1444 		/* setting the full duplex */
1445 		if (params->req_duplex == DUPLEX_FULL)
1446 			mii_control |=
1447 				MDIO_COMBO_IEEO_MII_CONTROL_FULL_DUPLEX;
1448 		CL45_WR_OVER_CL22(bp, params->port,
1449 				      params->phy_addr,
1450 				      MDIO_REG_BANK_COMBO_IEEE0,
1451 				      MDIO_COMBO_IEEE0_MII_CONTROL,
1452 				      mii_control);
1453 
1454 	} else { /* AN mode */
1455 		/* enable and restart AN */
1456 		bnx2x_restart_autoneg(params);
1457 	}
1458 }
1459 
1460 
1461 /*
1462  * link management
1463  */
1464 
bnx2x_pause_resolve(struct link_vars * vars,u32 pause_result)1465 static void bnx2x_pause_resolve(struct link_vars *vars, u32 pause_result)
1466 {						/*  LD	    LP	 */
1467 	switch (pause_result) { 		/* ASYM P ASYM P */
1468 	case 0xb:       			/*   1  0   1  1 */
1469 		vars->flow_ctrl = BNX2X_FLOW_CTRL_TX;
1470 		break;
1471 
1472 	case 0xe:       			/*   1  1   1  0 */
1473 		vars->flow_ctrl = BNX2X_FLOW_CTRL_RX;
1474 		break;
1475 
1476 	case 0x5:       			/*   0  1   0  1 */
1477 	case 0x7:       			/*   0  1   1  1 */
1478 	case 0xd:       			/*   1  1   0  1 */
1479 	case 0xf:       			/*   1  1   1  1 */
1480 		vars->flow_ctrl = BNX2X_FLOW_CTRL_BOTH;
1481 		break;
1482 
1483 	default:
1484 		break;
1485 	}
1486 }
1487 
bnx2x_ext_phy_resove_fc(struct link_params * params,struct link_vars * vars)1488 static u8 bnx2x_ext_phy_resove_fc(struct link_params *params,
1489 				  struct link_vars *vars)
1490 {
1491 	struct bnx2x *bp = params->bp;
1492 	u8 ext_phy_addr;
1493 	u16 ld_pause;	/* local */
1494 	u16 lp_pause;	/* link partner */
1495 	u16 an_complete; /* AN complete */
1496 	u16 pause_result;
1497 	u8 ret = 0;
1498 	u32 ext_phy_type;
1499 	u8 port = params->port;
1500 	ext_phy_addr = ((params->ext_phy_config &
1501 			 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1502 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1503 
1504 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1505 	/* read twice */
1506 
1507 	bnx2x_cl45_read(bp, port,
1508 		      ext_phy_type,
1509 		      ext_phy_addr,
1510 		      MDIO_AN_DEVAD,
1511 		      MDIO_AN_REG_STATUS, &an_complete);
1512 	bnx2x_cl45_read(bp, port,
1513 		      ext_phy_type,
1514 		      ext_phy_addr,
1515 		      MDIO_AN_DEVAD,
1516 		      MDIO_AN_REG_STATUS, &an_complete);
1517 
1518 	if (an_complete & MDIO_AN_REG_STATUS_AN_COMPLETE) {
1519 		ret = 1;
1520 		bnx2x_cl45_read(bp, port,
1521 			      ext_phy_type,
1522 			      ext_phy_addr,
1523 			      MDIO_AN_DEVAD,
1524 			      MDIO_AN_REG_ADV_PAUSE, &ld_pause);
1525 		bnx2x_cl45_read(bp, port,
1526 			      ext_phy_type,
1527 			      ext_phy_addr,
1528 			      MDIO_AN_DEVAD,
1529 			      MDIO_AN_REG_LP_AUTO_NEG, &lp_pause);
1530 		pause_result = (ld_pause &
1531 				MDIO_AN_REG_ADV_PAUSE_MASK) >> 8;
1532 		pause_result |= (lp_pause &
1533 				 MDIO_AN_REG_ADV_PAUSE_MASK) >> 10;
1534 		DP(NETIF_MSG_LINK, "Ext PHY pause result 0x%x \n",
1535 		   pause_result);
1536 		bnx2x_pause_resolve(vars, pause_result);
1537 		if (vars->flow_ctrl == BNX2X_FLOW_CTRL_NONE &&
1538 		     ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
1539 			bnx2x_cl45_read(bp, port,
1540 				      ext_phy_type,
1541 				      ext_phy_addr,
1542 				      MDIO_AN_DEVAD,
1543 				      MDIO_AN_REG_CL37_FC_LD, &ld_pause);
1544 
1545 			bnx2x_cl45_read(bp, port,
1546 				      ext_phy_type,
1547 				      ext_phy_addr,
1548 				      MDIO_AN_DEVAD,
1549 				      MDIO_AN_REG_CL37_FC_LP, &lp_pause);
1550 			pause_result = (ld_pause &
1551 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 5;
1552 			pause_result |= (lp_pause &
1553 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) >> 7;
1554 
1555 			bnx2x_pause_resolve(vars, pause_result);
1556 			DP(NETIF_MSG_LINK, "Ext PHY CL37 pause result 0x%x \n",
1557 				 pause_result);
1558 		}
1559 	}
1560 	return ret;
1561 }
1562 
1563 
bnx2x_flow_ctrl_resolve(struct link_params * params,struct link_vars * vars,u32 gp_status)1564 static void bnx2x_flow_ctrl_resolve(struct link_params *params,
1565 				  struct link_vars *vars,
1566 				  u32 gp_status)
1567 {
1568 	struct bnx2x *bp = params->bp;
1569 	u16 ld_pause;   /* local driver */
1570 	u16 lp_pause;   /* link partner */
1571 	u16 pause_result;
1572 
1573 	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1574 
1575 	/* resolve from gp_status in case of AN complete and not sgmii */
1576 	if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1577 	    (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) &&
1578 	    (!(vars->phy_flags & PHY_SGMII_FLAG)) &&
1579 	    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1580 	     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT)) {
1581 		CL45_RD_OVER_CL22(bp, params->port,
1582 				      params->phy_addr,
1583 				      MDIO_REG_BANK_COMBO_IEEE0,
1584 				      MDIO_COMBO_IEEE0_AUTO_NEG_ADV,
1585 				      &ld_pause);
1586 		CL45_RD_OVER_CL22(bp, params->port,
1587 				      params->phy_addr,
1588 			MDIO_REG_BANK_COMBO_IEEE0,
1589 			MDIO_COMBO_IEEE0_AUTO_NEG_LINK_PARTNER_ABILITY1,
1590 			&lp_pause);
1591 		pause_result = (ld_pause &
1592 				MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>5;
1593 		pause_result |= (lp_pause &
1594 				 MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_MASK)>>7;
1595 		DP(NETIF_MSG_LINK, "pause_result 0x%x\n", pause_result);
1596 		bnx2x_pause_resolve(vars, pause_result);
1597 	} else if ((params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO) &&
1598 		   (bnx2x_ext_phy_resove_fc(params, vars))) {
1599 		return;
1600 	} else {
1601 		if (params->req_flow_ctrl == BNX2X_FLOW_CTRL_AUTO)
1602 			vars->flow_ctrl = params->req_fc_auto_adv;
1603 		else
1604 			vars->flow_ctrl = params->req_flow_ctrl;
1605 	}
1606 	DP(NETIF_MSG_LINK, "flow_ctrl 0x%x\n", vars->flow_ctrl);
1607 }
1608 
1609 
bnx2x_link_settings_status(struct link_params * params,struct link_vars * vars,u32 gp_status)1610 static u8 bnx2x_link_settings_status(struct link_params *params,
1611 				      struct link_vars *vars,
1612 				      u32 gp_status)
1613 {
1614 	struct bnx2x *bp = params->bp;
1615 	u16 new_line_speed;
1616 	u8 rc = 0;
1617 	vars->link_status = 0;
1618 
1619 	if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) {
1620 		DP(NETIF_MSG_LINK, "phy link up gp_status=0x%x\n",
1621 			 gp_status);
1622 
1623 		vars->phy_link_up = 1;
1624 		vars->link_status |= LINK_STATUS_LINK_UP;
1625 
1626 		if (gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_DUPLEX_STATUS)
1627 			vars->duplex = DUPLEX_FULL;
1628 		else
1629 			vars->duplex = DUPLEX_HALF;
1630 
1631 		bnx2x_flow_ctrl_resolve(params, vars, gp_status);
1632 
1633 		switch (gp_status & GP_STATUS_SPEED_MASK) {
1634 		case GP_STATUS_10M:
1635 			new_line_speed = SPEED_10;
1636 			if (vars->duplex == DUPLEX_FULL)
1637 				vars->link_status |= LINK_10TFD;
1638 			else
1639 				vars->link_status |= LINK_10THD;
1640 			break;
1641 
1642 		case GP_STATUS_100M:
1643 			new_line_speed = SPEED_100;
1644 			if (vars->duplex == DUPLEX_FULL)
1645 				vars->link_status |= LINK_100TXFD;
1646 			else
1647 				vars->link_status |= LINK_100TXHD;
1648 			break;
1649 
1650 		case GP_STATUS_1G:
1651 		case GP_STATUS_1G_KX:
1652 			new_line_speed = SPEED_1000;
1653 			if (vars->duplex == DUPLEX_FULL)
1654 				vars->link_status |= LINK_1000TFD;
1655 			else
1656 				vars->link_status |= LINK_1000THD;
1657 			break;
1658 
1659 		case GP_STATUS_2_5G:
1660 			new_line_speed = SPEED_2500;
1661 			if (vars->duplex == DUPLEX_FULL)
1662 				vars->link_status |= LINK_2500TFD;
1663 			else
1664 				vars->link_status |= LINK_2500THD;
1665 			break;
1666 
1667 		case GP_STATUS_5G:
1668 		case GP_STATUS_6G:
1669 			DP(NETIF_MSG_LINK,
1670 				 "link speed unsupported  gp_status 0x%x\n",
1671 				  gp_status);
1672 			return -EINVAL;
1673 			break;
1674 		case GP_STATUS_10G_KX4:
1675 		case GP_STATUS_10G_HIG:
1676 		case GP_STATUS_10G_CX4:
1677 			new_line_speed = SPEED_10000;
1678 			vars->link_status |= LINK_10GTFD;
1679 			break;
1680 
1681 		case GP_STATUS_12G_HIG:
1682 			new_line_speed = SPEED_12000;
1683 			vars->link_status |= LINK_12GTFD;
1684 			break;
1685 
1686 		case GP_STATUS_12_5G:
1687 			new_line_speed = SPEED_12500;
1688 			vars->link_status |= LINK_12_5GTFD;
1689 			break;
1690 
1691 		case GP_STATUS_13G:
1692 			new_line_speed = SPEED_13000;
1693 			vars->link_status |= LINK_13GTFD;
1694 			break;
1695 
1696 		case GP_STATUS_15G:
1697 			new_line_speed = SPEED_15000;
1698 			vars->link_status |= LINK_15GTFD;
1699 			break;
1700 
1701 		case GP_STATUS_16G:
1702 			new_line_speed = SPEED_16000;
1703 			vars->link_status |= LINK_16GTFD;
1704 			break;
1705 
1706 		default:
1707 			DP(NETIF_MSG_LINK,
1708 				  "link speed unsupported gp_status 0x%x\n",
1709 				  gp_status);
1710 		return -EINVAL;
1711 			break;
1712 		}
1713 
1714 		/* Upon link speed change set the NIG into drain mode.
1715 		Comes to deals with possible FIFO glitch due to clk change
1716 		when speed is decreased without link down indicator */
1717 		if (new_line_speed != vars->line_speed) {
1718 			REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
1719 				    + params->port*4, 0);
1720 			msleep(1);
1721 		}
1722 		vars->line_speed = new_line_speed;
1723 		vars->link_status |= LINK_STATUS_SERDES_LINK;
1724 
1725 		if ((params->req_line_speed == SPEED_AUTO_NEG) &&
1726 		    ((XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1727 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
1728 		    (XGXS_EXT_PHY_TYPE(params->ext_phy_config) ==
1729 		     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705))) {
1730 			vars->autoneg = AUTO_NEG_ENABLED;
1731 
1732 			if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
1733 				vars->autoneg |= AUTO_NEG_COMPLETE;
1734 				vars->link_status |=
1735 					LINK_STATUS_AUTO_NEGOTIATE_COMPLETE;
1736 			}
1737 
1738 			vars->autoneg |= AUTO_NEG_PARALLEL_DETECTION_USED;
1739 			vars->link_status |=
1740 				LINK_STATUS_PARALLEL_DETECTION_USED;
1741 
1742 		}
1743 		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_TX)
1744 			vars->link_status |=
1745 				LINK_STATUS_TX_FLOW_CONTROL_ENABLED;
1746 
1747 		if (vars->flow_ctrl & BNX2X_FLOW_CTRL_RX)
1748 			vars->link_status |=
1749 				LINK_STATUS_RX_FLOW_CONTROL_ENABLED;
1750 
1751 	} else { /* link_down */
1752 		DP(NETIF_MSG_LINK, "phy link down\n");
1753 
1754 		vars->phy_link_up = 0;
1755 
1756 		vars->duplex = DUPLEX_FULL;
1757 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
1758 		vars->autoneg = AUTO_NEG_DISABLED;
1759 		vars->mac_type = MAC_TYPE_NONE;
1760 	}
1761 
1762 	DP(NETIF_MSG_LINK, "gp_status 0x%x  phy_link_up %x line_speed %x \n",
1763 		 gp_status, vars->phy_link_up, vars->line_speed);
1764 	DP(NETIF_MSG_LINK, "duplex %x  flow_ctrl 0x%x"
1765 		 " autoneg 0x%x\n",
1766 		 vars->duplex,
1767 		 vars->flow_ctrl, vars->autoneg);
1768 	DP(NETIF_MSG_LINK, "link_status 0x%x\n", vars->link_status);
1769 
1770 	return rc;
1771 }
1772 
bnx2x_set_sgmii_tx_driver(struct link_params * params)1773 static void bnx2x_set_sgmii_tx_driver(struct link_params *params)
1774 {
1775 	struct bnx2x *bp = params->bp;
1776 	u16 lp_up2;
1777 	u16 tx_driver;
1778 
1779 	/* read precomp */
1780 
1781 	CL45_RD_OVER_CL22(bp, params->port,
1782 			      params->phy_addr,
1783 			      MDIO_REG_BANK_OVER_1G,
1784 			      MDIO_OVER_1G_LP_UP2, &lp_up2);
1785 
1786 	CL45_RD_OVER_CL22(bp, params->port,
1787 			      params->phy_addr,
1788 			      MDIO_REG_BANK_TX0,
1789 			      MDIO_TX0_TX_DRIVER, &tx_driver);
1790 
1791 	/* bits [10:7] at lp_up2, positioned at [15:12] */
1792 	lp_up2 = (((lp_up2 & MDIO_OVER_1G_LP_UP2_PREEMPHASIS_MASK) >>
1793 		   MDIO_OVER_1G_LP_UP2_PREEMPHASIS_SHIFT) <<
1794 		  MDIO_TX0_TX_DRIVER_PREEMPHASIS_SHIFT);
1795 
1796 	if ((lp_up2 != 0) &&
1797 	    (lp_up2 != (tx_driver & MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK))) {
1798 		/* replace tx_driver bits [15:12] */
1799 		tx_driver &= ~MDIO_TX0_TX_DRIVER_PREEMPHASIS_MASK;
1800 		tx_driver |= lp_up2;
1801 		CL45_WR_OVER_CL22(bp, params->port,
1802 				      params->phy_addr,
1803 				      MDIO_REG_BANK_TX0,
1804 				      MDIO_TX0_TX_DRIVER, tx_driver);
1805 	}
1806 }
1807 
bnx2x_emac_program(struct link_params * params,u32 line_speed,u32 duplex)1808 static u8 bnx2x_emac_program(struct link_params *params,
1809 			   u32 line_speed, u32 duplex)
1810 {
1811 	struct bnx2x *bp = params->bp;
1812 	u8 port = params->port;
1813 	u16 mode = 0;
1814 
1815 	DP(NETIF_MSG_LINK, "setting link speed & duplex\n");
1816 	bnx2x_bits_dis(bp, GRCBASE_EMAC0 + port*0x400 +
1817 		     EMAC_REG_EMAC_MODE,
1818 		     (EMAC_MODE_25G_MODE |
1819 		     EMAC_MODE_PORT_MII_10M |
1820 		     EMAC_MODE_HALF_DUPLEX));
1821 	switch (line_speed) {
1822 	case SPEED_10:
1823 		mode |= EMAC_MODE_PORT_MII_10M;
1824 		break;
1825 
1826 	case SPEED_100:
1827 		mode |= EMAC_MODE_PORT_MII;
1828 		break;
1829 
1830 	case SPEED_1000:
1831 		mode |= EMAC_MODE_PORT_GMII;
1832 		break;
1833 
1834 	case SPEED_2500:
1835 		mode |= (EMAC_MODE_25G_MODE | EMAC_MODE_PORT_GMII);
1836 		break;
1837 
1838 	default:
1839 		/* 10G not valid for EMAC */
1840 		DP(NETIF_MSG_LINK, "Invalid line_speed 0x%x\n", line_speed);
1841 		return -EINVAL;
1842 	}
1843 
1844 	if (duplex == DUPLEX_HALF)
1845 		mode |= EMAC_MODE_HALF_DUPLEX;
1846 	bnx2x_bits_en(bp,
1847 		    GRCBASE_EMAC0 + port*0x400 + EMAC_REG_EMAC_MODE,
1848 		    mode);
1849 
1850 	bnx2x_set_led(bp, params->port, LED_MODE_OPER,
1851 		    line_speed, params->hw_led_mode, params->chip_id);
1852 	return 0;
1853 }
1854 
1855 /*****************************************************************************/
1856 /*      		     External Phy section       		     */
1857 /*****************************************************************************/
bnx2x_hw_reset(struct bnx2x * bp,u8 port)1858 static void bnx2x_hw_reset(struct bnx2x *bp, u8 port)
1859 {
1860 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1861 		       MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
1862 	msleep(1);
1863 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1864 		      MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
1865 }
1866 
bnx2x_ext_phy_reset(struct link_params * params,struct link_vars * vars)1867 static void bnx2x_ext_phy_reset(struct link_params *params,
1868 			      struct link_vars   *vars)
1869 {
1870 	struct bnx2x *bp = params->bp;
1871 	u32 ext_phy_type;
1872 	u8 ext_phy_addr = ((params->ext_phy_config &
1873 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1874 			   PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1875 	DP(NETIF_MSG_LINK, "Port %x: bnx2x_ext_phy_reset\n", params->port);
1876 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1877 	/* The PHY reset is controled by GPIO 1
1878 	 * Give it 1ms of reset pulse
1879 	 */
1880 	if (vars->phy_flags & PHY_XGXS_FLAG) {
1881 
1882 		switch (ext_phy_type) {
1883 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
1884 			DP(NETIF_MSG_LINK, "XGXS Direct\n");
1885 			break;
1886 
1887 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
1888 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
1889 			DP(NETIF_MSG_LINK, "XGXS 8705/8706\n");
1890 
1891 			/* Restore normal power mode*/
1892 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1893 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1894 					  params->port);
1895 
1896 			/* HW reset */
1897 			bnx2x_hw_reset(bp, params->port);
1898 
1899 			bnx2x_cl45_write(bp, params->port,
1900 				       ext_phy_type,
1901 				       ext_phy_addr,
1902 				       MDIO_PMA_DEVAD,
1903 				       MDIO_PMA_REG_CTRL, 0xa040);
1904 			break;
1905 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
1906 			/* Unset Low Power Mode and SW reset */
1907 			/* Restore normal power mode*/
1908 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1909 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1910 					  params->port);
1911 
1912 			DP(NETIF_MSG_LINK, "XGXS 8072\n");
1913 			bnx2x_cl45_write(bp, params->port,
1914 				       ext_phy_type,
1915 				       ext_phy_addr,
1916 				       MDIO_PMA_DEVAD,
1917 				       MDIO_PMA_REG_CTRL,
1918 				       1<<15);
1919 			break;
1920 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
1921 			{
1922 			u16 emac_base;
1923 			emac_base = (params->port) ? GRCBASE_EMAC0 :
1924 					GRCBASE_EMAC1;
1925 
1926 			/* Restore normal power mode*/
1927 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1928 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1929 					  params->port);
1930 
1931 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
1932 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1933 					  params->port);
1934 
1935 			DP(NETIF_MSG_LINK, "XGXS 8073\n");
1936 			}
1937 			break;
1938 
1939 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
1940 			DP(NETIF_MSG_LINK, "XGXS SFX7101\n");
1941 
1942 			/* Restore normal power mode*/
1943 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
1944 				      MISC_REGISTERS_GPIO_OUTPUT_HIGH,
1945 					  params->port);
1946 
1947 			/* HW reset */
1948 			bnx2x_hw_reset(bp, params->port);
1949 
1950 			break;
1951 
1952 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
1953 			DP(NETIF_MSG_LINK, "XGXS PHY Failure detected\n");
1954 			break;
1955 
1956 		default:
1957 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
1958 			   params->ext_phy_config);
1959 			break;
1960 		}
1961 
1962 	} else { /* SerDes */
1963 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
1964 		switch (ext_phy_type) {
1965 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
1966 			DP(NETIF_MSG_LINK, "SerDes Direct\n");
1967 			break;
1968 
1969 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
1970 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
1971 			bnx2x_hw_reset(bp, params->port);
1972 			break;
1973 
1974 		default:
1975 			DP(NETIF_MSG_LINK,
1976 				 "BAD SerDes ext_phy_config 0x%x\n",
1977 				 params->ext_phy_config);
1978 			break;
1979 		}
1980 	}
1981 }
1982 
bnx2x_bcm8072_external_rom_boot(struct link_params * params)1983 static void bnx2x_bcm8072_external_rom_boot(struct link_params *params)
1984 {
1985 	struct bnx2x *bp = params->bp;
1986 	u8 port = params->port;
1987 	u8 ext_phy_addr = ((params->ext_phy_config &
1988 			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
1989 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
1990 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
1991 	u16 fw_ver1, fw_ver2;
1992 
1993 	/* Need to wait 200ms after reset */
1994 	msleep(200);
1995 	/* Boot port from external ROM
1996 	 * Set ser_boot_ctl bit in the MISC_CTRL1 register
1997 	 */
1998 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
1999 			    MDIO_PMA_DEVAD,
2000 			    MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2001 
2002 	/* Reset internal microprocessor */
2003 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2004 			  MDIO_PMA_DEVAD,
2005 			  MDIO_PMA_REG_GEN_CTRL,
2006 			  MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2007 	/* set micro reset = 0 */
2008 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2009 			    MDIO_PMA_DEVAD,
2010 			    MDIO_PMA_REG_GEN_CTRL,
2011 			    MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2012 	/* Reset internal microprocessor */
2013 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2014 			  MDIO_PMA_DEVAD,
2015 			  MDIO_PMA_REG_GEN_CTRL,
2016 			  MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2017 	/* wait for 100ms for code download via SPI port */
2018 	msleep(100);
2019 
2020 	/* Clear ser_boot_ctl bit */
2021 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2022 			    MDIO_PMA_DEVAD,
2023 			    MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2024 	/* Wait 100ms */
2025 	msleep(100);
2026 
2027 	/* Print the PHY FW version */
2028 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2029 			    MDIO_PMA_DEVAD,
2030 			    MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2031 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2032 			    MDIO_PMA_DEVAD,
2033 			    MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2034 	DP(NETIF_MSG_LINK, "8072 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2035 }
2036 
bnx2x_8073_is_snr_needed(struct link_params * params)2037 static u8 bnx2x_8073_is_snr_needed(struct link_params *params)
2038 {
2039 	/* This is only required for 8073A1, version 102 only */
2040 
2041 	struct bnx2x *bp = params->bp;
2042 	u8 ext_phy_addr = ((params->ext_phy_config &
2043 			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2044 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2045 	u16 val;
2046 
2047 	/* Read 8073 HW revision*/
2048 	bnx2x_cl45_read(bp, params->port,
2049 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2050 		      ext_phy_addr,
2051 		      MDIO_PMA_DEVAD,
2052 		      0xc801, &val);
2053 
2054 	if (val != 1) {
2055 		/* No need to workaround in 8073 A1 */
2056 		return 0;
2057 	}
2058 
2059 	bnx2x_cl45_read(bp, params->port,
2060 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2061 		      ext_phy_addr,
2062 		      MDIO_PMA_DEVAD,
2063 		      MDIO_PMA_REG_ROM_VER2, &val);
2064 
2065 	/* SNR should be applied only for version 0x102 */
2066 	if (val != 0x102)
2067 		return 0;
2068 
2069 	return 1;
2070 }
2071 
bnx2x_bcm8073_xaui_wa(struct link_params * params)2072 static u8 bnx2x_bcm8073_xaui_wa(struct link_params *params)
2073 {
2074 	struct bnx2x *bp = params->bp;
2075 	u8 ext_phy_addr = ((params->ext_phy_config &
2076 			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2077 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2078 	u16 val, cnt, cnt1 ;
2079 
2080 	bnx2x_cl45_read(bp, params->port,
2081 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2082 		      ext_phy_addr,
2083 		      MDIO_PMA_DEVAD,
2084 		      0xc801, &val);
2085 
2086 	if (val > 0) {
2087 		/* No need to workaround in 8073 A1 */
2088 		return 0;
2089 	}
2090 	/* XAUI workaround in 8073 A0: */
2091 
2092 	/* After loading the boot ROM and restarting Autoneg,
2093 	poll Dev1, Reg $C820: */
2094 
2095 	for (cnt = 0; cnt < 1000; cnt++) {
2096 		bnx2x_cl45_read(bp, params->port,
2097 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2098 			      ext_phy_addr,
2099 			      MDIO_PMA_DEVAD,
2100 			      0xc820, &val);
2101 		  /* If bit [14] = 0 or bit [13] = 0, continue on with
2102 		   system initialization (XAUI work-around not required,
2103 		    as these bits indicate 2.5G or 1G link up). */
2104 		if (!(val & (1<<14)) || !(val & (1<<13))) {
2105 			DP(NETIF_MSG_LINK, "XAUI work-around not required\n");
2106 			return 0;
2107 		} else if (!(val & (1<<15))) {
2108 			DP(NETIF_MSG_LINK, "clc bit 15 went off\n");
2109 			 /* If bit 15 is 0, then poll Dev1, Reg $C841 until
2110 			  it's MSB (bit 15) goes to 1 (indicating that the
2111 			  XAUI workaround has completed),
2112 			  then continue on with system initialization.*/
2113 			for (cnt1 = 0; cnt1 < 1000; cnt1++) {
2114 				bnx2x_cl45_read(bp, params->port,
2115 					PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2116 					ext_phy_addr,
2117 					MDIO_PMA_DEVAD,
2118 					0xc841, &val);
2119 				if (val & (1<<15)) {
2120 					DP(NETIF_MSG_LINK,
2121 					  "XAUI workaround has completed\n");
2122 					return 0;
2123 				 }
2124 				 msleep(3);
2125 			}
2126 			break;
2127 		}
2128 		msleep(3);
2129 	}
2130 	DP(NETIF_MSG_LINK, "Warning: XAUI work-around timeout !!!\n");
2131 	return -EINVAL;
2132 
2133 }
2134 
bnx2x_bcm8073_external_rom_boot(struct bnx2x * bp,u8 port,u8 ext_phy_addr)2135 static void bnx2x_bcm8073_external_rom_boot(struct bnx2x *bp, u8 port,
2136 					  u8 ext_phy_addr)
2137 {
2138 	u16 fw_ver1, fw_ver2;
2139 	/* Boot port from external ROM  */
2140 	/* EDC grst */
2141 	bnx2x_cl45_write(bp, port,
2142 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2143 		       ext_phy_addr,
2144 		       MDIO_PMA_DEVAD,
2145 		       MDIO_PMA_REG_GEN_CTRL,
2146 		       0x0001);
2147 
2148 	/* ucode reboot and rst */
2149 	bnx2x_cl45_write(bp, port,
2150 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2151 		       ext_phy_addr,
2152 		       MDIO_PMA_DEVAD,
2153 		       MDIO_PMA_REG_GEN_CTRL,
2154 		       0x008c);
2155 
2156 	bnx2x_cl45_write(bp, port,
2157 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2158 		       ext_phy_addr,
2159 		       MDIO_PMA_DEVAD,
2160 		       MDIO_PMA_REG_MISC_CTRL1, 0x0001);
2161 
2162 	/* Reset internal microprocessor */
2163 	bnx2x_cl45_write(bp, port,
2164 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2165 		       ext_phy_addr,
2166 		       MDIO_PMA_DEVAD,
2167 		       MDIO_PMA_REG_GEN_CTRL,
2168 		       MDIO_PMA_REG_GEN_CTRL_ROM_MICRO_RESET);
2169 
2170 	/* Release srst bit */
2171 	bnx2x_cl45_write(bp, port,
2172 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2173 		       ext_phy_addr,
2174 		       MDIO_PMA_DEVAD,
2175 		       MDIO_PMA_REG_GEN_CTRL,
2176 		       MDIO_PMA_REG_GEN_CTRL_ROM_RESET_INTERNAL_MP);
2177 
2178 	/* wait for 100ms for code download via SPI port */
2179 	msleep(100);
2180 
2181 	/* Clear ser_boot_ctl bit */
2182 	bnx2x_cl45_write(bp, port,
2183 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2184 		       ext_phy_addr,
2185 		       MDIO_PMA_DEVAD,
2186 		       MDIO_PMA_REG_MISC_CTRL1, 0x0000);
2187 
2188 	bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2189 		      ext_phy_addr,
2190 		      MDIO_PMA_DEVAD,
2191 		      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
2192 	bnx2x_cl45_read(bp, port,
2193 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2194 		      ext_phy_addr,
2195 		      MDIO_PMA_DEVAD,
2196 		      MDIO_PMA_REG_ROM_VER2, &fw_ver2);
2197 	DP(NETIF_MSG_LINK, "8073 FW version 0x%x:0x%x\n", fw_ver1, fw_ver2);
2198 
2199 }
2200 
bnx2x_bcm807x_force_10G(struct link_params * params)2201 static void bnx2x_bcm807x_force_10G(struct link_params *params)
2202 {
2203 	struct bnx2x *bp = params->bp;
2204 	u8 port = params->port;
2205 	u8 ext_phy_addr = ((params->ext_phy_config &
2206 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2207 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2208 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2209 
2210 	/* Force KR or KX */
2211 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2212 		       MDIO_PMA_DEVAD,
2213 		       MDIO_PMA_REG_CTRL,
2214 		       0x2040);
2215 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2216 		       MDIO_PMA_DEVAD,
2217 		       MDIO_PMA_REG_10G_CTRL2,
2218 		       0x000b);
2219 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2220 		       MDIO_PMA_DEVAD,
2221 		       MDIO_PMA_REG_BCM_CTRL,
2222 		       0x0000);
2223 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2224 		       MDIO_AN_DEVAD,
2225 		       MDIO_AN_REG_CTRL,
2226 		       0x0000);
2227 }
bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params * params)2228 static void bnx2x_bcm8073_set_xaui_low_power_mode(struct link_params *params)
2229 {
2230 	struct bnx2x *bp = params->bp;
2231 	u8 port = params->port;
2232 	u16 val;
2233 	u8 ext_phy_addr = ((params->ext_phy_config &
2234 			     PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2235 			    PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2236 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2237 
2238 	bnx2x_cl45_read(bp, params->port,
2239 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2240 		      ext_phy_addr,
2241 		      MDIO_PMA_DEVAD,
2242 		      0xc801, &val);
2243 
2244 	if (val == 0) {
2245 		/* Mustn't set low power mode in 8073 A0 */
2246 		return;
2247 	}
2248 
2249 	/* Disable PLL sequencer (use read-modify-write to clear bit 13) */
2250 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2251 		       MDIO_XS_DEVAD,
2252 		       MDIO_XS_PLL_SEQUENCER, &val);
2253 	val &= ~(1<<13);
2254 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2255 		       MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2256 
2257 	/* PLL controls */
2258 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2259 		       MDIO_XS_DEVAD, 0x805E, 0x1077);
2260 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2261 		       MDIO_XS_DEVAD, 0x805D, 0x0000);
2262 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2263 		       MDIO_XS_DEVAD, 0x805C, 0x030B);
2264 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2265 		       MDIO_XS_DEVAD, 0x805B, 0x1240);
2266 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2267 		       MDIO_XS_DEVAD, 0x805A, 0x2490);
2268 
2269 	/* Tx Controls */
2270 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2271 		       MDIO_XS_DEVAD, 0x80A7, 0x0C74);
2272 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2273 		       MDIO_XS_DEVAD, 0x80A6, 0x9041);
2274 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2275 		       MDIO_XS_DEVAD, 0x80A5, 0x4640);
2276 
2277 	/* Rx Controls */
2278 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2279 		       MDIO_XS_DEVAD, 0x80FE, 0x01C4);
2280 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2281 		       MDIO_XS_DEVAD, 0x80FD, 0x9249);
2282 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2283 		       MDIO_XS_DEVAD, 0x80FC, 0x2015);
2284 
2285 	/* Enable PLL sequencer  (use read-modify-write to set bit 13) */
2286 	bnx2x_cl45_read(bp, port, ext_phy_type, ext_phy_addr,
2287 		       MDIO_XS_DEVAD,
2288 		       MDIO_XS_PLL_SEQUENCER, &val);
2289 	val |= (1<<13);
2290 	bnx2x_cl45_write(bp, port, ext_phy_type, ext_phy_addr,
2291 		       MDIO_XS_DEVAD, MDIO_XS_PLL_SEQUENCER, val);
2292 }
2293 
bnx2x_8073_set_pause_cl37(struct link_params * params,struct link_vars * vars)2294 static void bnx2x_8073_set_pause_cl37(struct link_params *params,
2295 				  struct link_vars *vars)
2296 {
2297 
2298 	struct bnx2x *bp = params->bp;
2299 	u16 cl37_val;
2300 	u8 ext_phy_addr = ((params->ext_phy_config &
2301 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2302 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2303 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2304 
2305 	bnx2x_cl45_read(bp, params->port,
2306 		      ext_phy_type,
2307 		      ext_phy_addr,
2308 		      MDIO_AN_DEVAD,
2309 		      MDIO_AN_REG_CL37_FC_LD, &cl37_val);
2310 
2311 	cl37_val &= ~MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2312 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2313 
2314 	if ((vars->ieee_fc &
2315 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) ==
2316 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC) {
2317 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_SYMMETRIC;
2318 	}
2319 	if ((vars->ieee_fc &
2320 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2321 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2322 		cl37_val |=  MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC;
2323 	}
2324 	if ((vars->ieee_fc &
2325 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2326 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2327 		cl37_val |= MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH;
2328 	}
2329 	DP(NETIF_MSG_LINK,
2330 		 "Ext phy AN advertize cl37 0x%x\n", cl37_val);
2331 
2332 	bnx2x_cl45_write(bp, params->port,
2333 		       ext_phy_type,
2334 		       ext_phy_addr,
2335 		       MDIO_AN_DEVAD,
2336 		       MDIO_AN_REG_CL37_FC_LD, cl37_val);
2337 	msleep(500);
2338 }
2339 
bnx2x_ext_phy_set_pause(struct link_params * params,struct link_vars * vars)2340 static void bnx2x_ext_phy_set_pause(struct link_params *params,
2341 				  struct link_vars *vars)
2342 {
2343 	struct bnx2x *bp = params->bp;
2344 	u16 val;
2345 	u8 ext_phy_addr = ((params->ext_phy_config &
2346 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2347 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2348 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2349 
2350 	/* read modify write pause advertizing */
2351 	bnx2x_cl45_read(bp, params->port,
2352 		      ext_phy_type,
2353 		      ext_phy_addr,
2354 		      MDIO_AN_DEVAD,
2355 		      MDIO_AN_REG_ADV_PAUSE, &val);
2356 
2357 	val &= ~MDIO_AN_REG_ADV_PAUSE_BOTH;
2358 
2359 	/* Please refer to Table 28B-3 of 802.3ab-1999 spec. */
2360 
2361 	if ((vars->ieee_fc &
2362 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) ==
2363 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_ASYMMETRIC) {
2364 		val |=  MDIO_AN_REG_ADV_PAUSE_ASYMMETRIC;
2365 	}
2366 	if ((vars->ieee_fc &
2367 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) ==
2368 	    MDIO_COMBO_IEEE0_AUTO_NEG_ADV_PAUSE_BOTH) {
2369 		val |=
2370 		 MDIO_AN_REG_ADV_PAUSE_PAUSE;
2371 	}
2372 	DP(NETIF_MSG_LINK,
2373 		 "Ext phy AN advertize 0x%x\n", val);
2374 	bnx2x_cl45_write(bp, params->port,
2375 		       ext_phy_type,
2376 		       ext_phy_addr,
2377 		       MDIO_AN_DEVAD,
2378 		       MDIO_AN_REG_ADV_PAUSE, val);
2379 }
2380 
2381 
bnx2x_init_internal_phy(struct link_params * params,struct link_vars * vars)2382 static void bnx2x_init_internal_phy(struct link_params *params,
2383 				struct link_vars *vars)
2384 {
2385 	struct bnx2x *bp = params->bp;
2386 	u8 port = params->port;
2387 	if (!(vars->phy_flags & PHY_SGMII_FLAG)) {
2388 		u16 bank, rx_eq;
2389 
2390 		rx_eq = ((params->serdes_config &
2391 			  PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_MASK) >>
2392 			 PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT);
2393 
2394 		DP(NETIF_MSG_LINK, "setting rx eq to 0x%x\n", rx_eq);
2395 		for (bank = MDIO_REG_BANK_RX0; bank <= MDIO_REG_BANK_RX_ALL;
2396 		      bank += (MDIO_REG_BANK_RX1-MDIO_REG_BANK_RX0)) {
2397 			CL45_WR_OVER_CL22(bp, port,
2398 					      params->phy_addr,
2399 					      bank ,
2400 					      MDIO_RX0_RX_EQ_BOOST,
2401 					      ((rx_eq &
2402 				MDIO_RX0_RX_EQ_BOOST_EQUALIZER_CTRL_MASK) |
2403 				MDIO_RX0_RX_EQ_BOOST_OFFSET_CTRL));
2404 		}
2405 
2406 		/* forced speed requested? */
2407 		if (vars->line_speed != SPEED_AUTO_NEG) {
2408 			DP(NETIF_MSG_LINK, "not SGMII, no AN\n");
2409 
2410 			/* disable autoneg */
2411 			bnx2x_set_autoneg(params, vars);
2412 
2413 			/* program speed and duplex */
2414 			bnx2x_program_serdes(params, vars);
2415 
2416 		} else { /* AN_mode */
2417 			DP(NETIF_MSG_LINK, "not SGMII, AN\n");
2418 
2419 			/* AN enabled */
2420 			bnx2x_set_brcm_cl37_advertisment(params);
2421 
2422 			/* program duplex & pause advertisement (for aneg) */
2423 			bnx2x_set_ieee_aneg_advertisment(params,
2424 						       vars->ieee_fc);
2425 
2426 			/* enable autoneg */
2427 			bnx2x_set_autoneg(params, vars);
2428 
2429 			/* enable and restart AN */
2430 			bnx2x_restart_autoneg(params);
2431 		}
2432 
2433 	} else { /* SGMII mode */
2434 		DP(NETIF_MSG_LINK, "SGMII\n");
2435 
2436 		bnx2x_initialize_sgmii_process(params, vars);
2437 	}
2438 }
2439 
bnx2x_ext_phy_init(struct link_params * params,struct link_vars * vars)2440 static u8 bnx2x_ext_phy_init(struct link_params *params, struct link_vars *vars)
2441 {
2442 	struct bnx2x *bp = params->bp;
2443 	u32 ext_phy_type;
2444 	u8 ext_phy_addr;
2445 	u16 cnt;
2446 	u16 ctrl = 0;
2447 	u16 val = 0;
2448 	u8 rc = 0;
2449 	if (vars->phy_flags & PHY_XGXS_FLAG) {
2450 		ext_phy_addr = ((params->ext_phy_config &
2451 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2452 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2453 
2454 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2455 		/* Make sure that the soft reset is off (expect for the 8072:
2456 		 * due to the lock, it will be done inside the specific
2457 		 * handling)
2458 		 */
2459 		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
2460 		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
2461 		   (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN) &&
2462 		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
2463 		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
2464 			/* Wait for soft reset to get cleared upto 1 sec */
2465 			for (cnt = 0; cnt < 1000; cnt++) {
2466 				bnx2x_cl45_read(bp, params->port,
2467 					      ext_phy_type,
2468 					      ext_phy_addr,
2469 					      MDIO_PMA_DEVAD,
2470 					      MDIO_PMA_REG_CTRL, &ctrl);
2471 				if (!(ctrl & (1<<15)))
2472 					break;
2473 				msleep(1);
2474 			}
2475 			DP(NETIF_MSG_LINK, "control reg 0x%x (after %d ms)\n",
2476 				 ctrl, cnt);
2477 		}
2478 
2479 		switch (ext_phy_type) {
2480 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2481 			break;
2482 
2483 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2484 			DP(NETIF_MSG_LINK, "XGXS 8705\n");
2485 
2486 			bnx2x_cl45_write(bp, params->port,
2487 				       ext_phy_type,
2488 				       ext_phy_addr,
2489 				       MDIO_PMA_DEVAD,
2490 				       MDIO_PMA_REG_MISC_CTRL,
2491 				       0x8288);
2492 			bnx2x_cl45_write(bp, params->port,
2493 				       ext_phy_type,
2494 				       ext_phy_addr,
2495 				       MDIO_PMA_DEVAD,
2496 				       MDIO_PMA_REG_PHY_IDENTIFIER,
2497 				       0x7fbf);
2498 			bnx2x_cl45_write(bp, params->port,
2499 				       ext_phy_type,
2500 				       ext_phy_addr,
2501 				       MDIO_PMA_DEVAD,
2502 				       MDIO_PMA_REG_CMU_PLL_BYPASS,
2503 				       0x0100);
2504 			bnx2x_cl45_write(bp, params->port,
2505 				       ext_phy_type,
2506 				       ext_phy_addr,
2507 				       MDIO_WIS_DEVAD,
2508 				       MDIO_WIS_REG_LASI_CNTL, 0x1);
2509 			break;
2510 
2511 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2512 			DP(NETIF_MSG_LINK, "XGXS 8706\n");
2513 
2514 			msleep(10);
2515 			/* Force speed */
2516 			/* First enable LASI */
2517 			bnx2x_cl45_write(bp, params->port,
2518 				       ext_phy_type,
2519 				       ext_phy_addr,
2520 				       MDIO_PMA_DEVAD,
2521 				       MDIO_PMA_REG_RX_ALARM_CTRL,
2522 				       0x0400);
2523 			bnx2x_cl45_write(bp, params->port,
2524 				       ext_phy_type,
2525 				       ext_phy_addr,
2526 				       MDIO_PMA_DEVAD,
2527 				       MDIO_PMA_REG_LASI_CTRL, 0x0004);
2528 
2529 			if (params->req_line_speed == SPEED_10000) {
2530 				DP(NETIF_MSG_LINK, "XGXS 8706 force 10Gbps\n");
2531 
2532 				bnx2x_cl45_write(bp, params->port,
2533 					       ext_phy_type,
2534 					       ext_phy_addr,
2535 					       MDIO_PMA_DEVAD,
2536 					       MDIO_PMA_REG_DIGITAL_CTRL,
2537 					       0x400);
2538 			} else {
2539 				/* Force 1Gbps using autoneg with 1G
2540 				advertisment */
2541 
2542 				/* Allow CL37 through CL73 */
2543 				DP(NETIF_MSG_LINK, "XGXS 8706 AutoNeg\n");
2544 				bnx2x_cl45_write(bp, params->port,
2545 					       ext_phy_type,
2546 					       ext_phy_addr,
2547 					       MDIO_AN_DEVAD,
2548 					       MDIO_AN_REG_CL37_CL73,
2549 					       0x040c);
2550 
2551 				/* Enable Full-Duplex advertisment on CL37 */
2552 				bnx2x_cl45_write(bp, params->port,
2553 					       ext_phy_type,
2554 					       ext_phy_addr,
2555 					       MDIO_AN_DEVAD,
2556 					       MDIO_AN_REG_CL37_FC_LP,
2557 					       0x0020);
2558 				/* Enable CL37 AN */
2559 				bnx2x_cl45_write(bp, params->port,
2560 					       ext_phy_type,
2561 					       ext_phy_addr,
2562 					       MDIO_AN_DEVAD,
2563 					       MDIO_AN_REG_CL37_AN,
2564 					       0x1000);
2565 				/* 1G support */
2566 				bnx2x_cl45_write(bp, params->port,
2567 					       ext_phy_type,
2568 					       ext_phy_addr,
2569 					       MDIO_AN_DEVAD,
2570 					       MDIO_AN_REG_ADV, (1<<5));
2571 
2572 				/* Enable clause 73 AN */
2573 				bnx2x_cl45_write(bp, params->port,
2574 					       ext_phy_type,
2575 					       ext_phy_addr,
2576 					       MDIO_AN_DEVAD,
2577 					       MDIO_AN_REG_CTRL,
2578 					       0x1200);
2579 
2580 			}
2581 
2582 			break;
2583 
2584 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2585 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2586 		{
2587 			u16 tmp1;
2588 			u16 rx_alarm_ctrl_val;
2589 			u16 lasi_ctrl_val;
2590 			if (ext_phy_type ==
2591 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2592 				rx_alarm_ctrl_val = 0x400;
2593 				lasi_ctrl_val = 0x0004;
2594 			} else {
2595 				rx_alarm_ctrl_val = (1<<2);
2596 				lasi_ctrl_val = 0x0004;
2597 			}
2598 
2599 			/* enable LASI */
2600 			bnx2x_cl45_write(bp, params->port,
2601 				   ext_phy_type,
2602 				   ext_phy_addr,
2603 				   MDIO_PMA_DEVAD,
2604 				   MDIO_PMA_REG_RX_ALARM_CTRL,
2605 				   rx_alarm_ctrl_val);
2606 
2607 			bnx2x_cl45_write(bp, params->port,
2608 				       ext_phy_type,
2609 				       ext_phy_addr,
2610 				       MDIO_PMA_DEVAD,
2611 				       MDIO_PMA_REG_LASI_CTRL,
2612 				       lasi_ctrl_val);
2613 
2614 			bnx2x_8073_set_pause_cl37(params, vars);
2615 
2616 			if (ext_phy_type ==
2617 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072){
2618 				bnx2x_bcm8072_external_rom_boot(params);
2619 			} else {
2620 
2621 				/* In case of 8073 with long xaui lines,
2622 				don't set the 8073 xaui low power*/
2623 				bnx2x_bcm8073_set_xaui_low_power_mode(params);
2624 			}
2625 
2626 			bnx2x_cl45_read(bp, params->port,
2627 				      ext_phy_type,
2628 				      ext_phy_addr,
2629 				      MDIO_PMA_DEVAD,
2630 				      0xca13,
2631 				      &tmp1);
2632 
2633 			bnx2x_cl45_read(bp, params->port,
2634 				      ext_phy_type,
2635 				      ext_phy_addr,
2636 				      MDIO_PMA_DEVAD,
2637 				      MDIO_PMA_REG_RX_ALARM, &tmp1);
2638 
2639 			DP(NETIF_MSG_LINK, "Before rom RX_ALARM(port1):"
2640 					     "0x%x\n", tmp1);
2641 
2642 			/* If this is forced speed, set to KR or KX
2643 			 * (all other are not supported)
2644 			 */
2645 			if (params->loopback_mode == LOOPBACK_EXT) {
2646 				bnx2x_bcm807x_force_10G(params);
2647 				DP(NETIF_MSG_LINK,
2648 					"Forced speed 10G on 807X\n");
2649 				break;
2650 			} else {
2651 				bnx2x_cl45_write(bp, params->port,
2652 					       ext_phy_type, ext_phy_addr,
2653 					       MDIO_PMA_DEVAD,
2654 					       MDIO_PMA_REG_BCM_CTRL,
2655 					       0x0002);
2656 			}
2657 			if (params->req_line_speed != SPEED_AUTO_NEG) {
2658 				if (params->req_line_speed == SPEED_10000) {
2659 					val = (1<<7);
2660 				} else if (params->req_line_speed ==
2661 					   SPEED_2500) {
2662 					val = (1<<5);
2663 					/* Note that 2.5G works only
2664 					when used with 1G advertisment */
2665 				} else
2666 					val = (1<<5);
2667 			} else {
2668 
2669 				val = 0;
2670 				if (params->speed_cap_mask &
2671 					PORT_HW_CFG_SPEED_CAPABILITY_D0_10G)
2672 					val |= (1<<7);
2673 
2674 				/* Note that 2.5G works only when
2675 				used with 1G advertisment */
2676 				if (params->speed_cap_mask &
2677 					(PORT_HW_CFG_SPEED_CAPABILITY_D0_1G |
2678 					 PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G))
2679 					val |= (1<<5);
2680 				DP(NETIF_MSG_LINK,
2681 					 "807x autoneg val = 0x%x\n", val);
2682 			}
2683 
2684 			bnx2x_cl45_write(bp, params->port,
2685 				       ext_phy_type,
2686 				       ext_phy_addr,
2687 				       MDIO_AN_DEVAD,
2688 				       MDIO_AN_REG_ADV, val);
2689 
2690 			if (ext_phy_type ==
2691 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2692 
2693 				bnx2x_cl45_read(bp, params->port,
2694 					      ext_phy_type,
2695 					      ext_phy_addr,
2696 					      MDIO_AN_DEVAD,
2697 					      0x8329, &tmp1);
2698 
2699 				if (((params->speed_cap_mask &
2700 				      PORT_HW_CFG_SPEED_CAPABILITY_D0_2_5G) &&
2701 				     (params->req_line_speed ==
2702 				      SPEED_AUTO_NEG)) ||
2703 				    (params->req_line_speed ==
2704 				     SPEED_2500)) {
2705 					u16 phy_ver;
2706 					/* Allow 2.5G for A1 and above */
2707 					bnx2x_cl45_read(bp, params->port,
2708 					 PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
2709 					 ext_phy_addr,
2710 					 MDIO_PMA_DEVAD,
2711 					 0xc801, &phy_ver);
2712 					DP(NETIF_MSG_LINK, "Add 2.5G\n");
2713 					if (phy_ver > 0)
2714 						tmp1 |= 1;
2715 					else
2716 						tmp1 &= 0xfffe;
2717 				} else {
2718 					DP(NETIF_MSG_LINK, "Disable 2.5G\n");
2719 					tmp1 &= 0xfffe;
2720 				}
2721 
2722 				bnx2x_cl45_write(bp, params->port,
2723 					       ext_phy_type,
2724 					       ext_phy_addr,
2725 					       MDIO_AN_DEVAD,
2726 					       0x8329, tmp1);
2727 			}
2728 
2729 			/* Add support for CL37 (passive mode) II */
2730 
2731 			bnx2x_cl45_read(bp, params->port,
2732 				       ext_phy_type,
2733 				       ext_phy_addr,
2734 				       MDIO_AN_DEVAD,
2735 				       MDIO_AN_REG_CL37_FC_LD,
2736 				       &tmp1);
2737 
2738 			bnx2x_cl45_write(bp, params->port,
2739 				       ext_phy_type,
2740 				       ext_phy_addr,
2741 				       MDIO_AN_DEVAD,
2742 				       MDIO_AN_REG_CL37_FC_LD, (tmp1 |
2743 				       ((params->req_duplex == DUPLEX_FULL) ?
2744 				       0x20 : 0x40)));
2745 
2746 			/* Add support for CL37 (passive mode) III */
2747 			bnx2x_cl45_write(bp, params->port,
2748 				       ext_phy_type,
2749 				       ext_phy_addr,
2750 				       MDIO_AN_DEVAD,
2751 				       MDIO_AN_REG_CL37_AN, 0x1000);
2752 
2753 			if (ext_phy_type ==
2754 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
2755 				/* The SNR will improve about 2db by changing
2756 				BW and FEE main tap. Rest commands are executed
2757 				after link is up*/
2758 				/*Change FFE main cursor to 5 in EDC register*/
2759 				if (bnx2x_8073_is_snr_needed(params))
2760 					bnx2x_cl45_write(bp, params->port,
2761 						    ext_phy_type,
2762 						    ext_phy_addr,
2763 						    MDIO_PMA_DEVAD,
2764 						    MDIO_PMA_REG_EDC_FFE_MAIN,
2765 						    0xFB0C);
2766 
2767 				/* Enable FEC (Forware Error Correction)
2768 				Request in the AN */
2769 				bnx2x_cl45_read(bp, params->port,
2770 					      ext_phy_type,
2771 					      ext_phy_addr,
2772 					      MDIO_AN_DEVAD,
2773 					      MDIO_AN_REG_ADV2, &tmp1);
2774 
2775 				tmp1 |= (1<<15);
2776 
2777 				bnx2x_cl45_write(bp, params->port,
2778 					       ext_phy_type,
2779 					       ext_phy_addr,
2780 					       MDIO_AN_DEVAD,
2781 					       MDIO_AN_REG_ADV2, tmp1);
2782 
2783 			}
2784 
2785 			bnx2x_ext_phy_set_pause(params, vars);
2786 
2787 			/* Restart autoneg */
2788 			msleep(500);
2789 			bnx2x_cl45_write(bp, params->port,
2790 				       ext_phy_type,
2791 				       ext_phy_addr,
2792 				       MDIO_AN_DEVAD,
2793 				       MDIO_AN_REG_CTRL, 0x1200);
2794 			DP(NETIF_MSG_LINK, "807x Autoneg Restart: "
2795 			   "Advertise 1G=%x, 10G=%x\n",
2796 			   ((val & (1<<5)) > 0),
2797 			   ((val & (1<<7)) > 0));
2798 			break;
2799 		}
2800 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
2801 			DP(NETIF_MSG_LINK,
2802 				"Setting the SFX7101 LASI indication\n");
2803 
2804 			bnx2x_cl45_write(bp, params->port,
2805 				       ext_phy_type,
2806 				       ext_phy_addr,
2807 				       MDIO_PMA_DEVAD,
2808 				       MDIO_PMA_REG_LASI_CTRL, 0x1);
2809 			DP(NETIF_MSG_LINK,
2810 			  "Setting the SFX7101 LED to blink on traffic\n");
2811 			bnx2x_cl45_write(bp, params->port,
2812 				       ext_phy_type,
2813 				       ext_phy_addr,
2814 				       MDIO_PMA_DEVAD,
2815 				       MDIO_PMA_REG_7107_LED_CNTL, (1<<3));
2816 
2817 			bnx2x_ext_phy_set_pause(params, vars);
2818 			/* Restart autoneg */
2819 			bnx2x_cl45_read(bp, params->port,
2820 				      ext_phy_type,
2821 				      ext_phy_addr,
2822 				      MDIO_AN_DEVAD,
2823 				      MDIO_AN_REG_CTRL, &val);
2824 			val |= 0x200;
2825 			bnx2x_cl45_write(bp, params->port,
2826 				       ext_phy_type,
2827 				       ext_phy_addr,
2828 				       MDIO_AN_DEVAD,
2829 				       MDIO_AN_REG_CTRL, val);
2830 			break;
2831 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
2832 			DP(NETIF_MSG_LINK,
2833 				 "XGXS PHY Failure detected 0x%x\n",
2834 				 params->ext_phy_config);
2835 			rc = -EINVAL;
2836 			break;
2837 		default:
2838 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
2839 				  params->ext_phy_config);
2840 			rc = -EINVAL;
2841 			break;
2842 		}
2843 
2844 	} else { /* SerDes */
2845 
2846 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
2847 		switch (ext_phy_type) {
2848 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
2849 			DP(NETIF_MSG_LINK, "SerDes Direct\n");
2850 			break;
2851 
2852 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
2853 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
2854 			break;
2855 
2856 		default:
2857 			DP(NETIF_MSG_LINK, "BAD SerDes ext_phy_config 0x%x\n",
2858 			   params->ext_phy_config);
2859 			break;
2860 		}
2861 	}
2862 	return rc;
2863 }
2864 
2865 
bnx2x_ext_phy_is_link_up(struct link_params * params,struct link_vars * vars)2866 static u8 bnx2x_ext_phy_is_link_up(struct link_params *params,
2867 				 struct link_vars *vars)
2868 {
2869 	struct bnx2x *bp = params->bp;
2870 	u32 ext_phy_type;
2871 	u8 ext_phy_addr;
2872 	u16 val1 = 0, val2;
2873 	u16 rx_sd, pcs_status;
2874 	u8 ext_phy_link_up = 0;
2875 	u8 port = params->port;
2876 	if (vars->phy_flags & PHY_XGXS_FLAG) {
2877 		ext_phy_addr = ((params->ext_phy_config &
2878 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
2879 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
2880 
2881 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
2882 		switch (ext_phy_type) {
2883 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
2884 			DP(NETIF_MSG_LINK, "XGXS Direct\n");
2885 			ext_phy_link_up = 1;
2886 			break;
2887 
2888 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
2889 			DP(NETIF_MSG_LINK, "XGXS 8705\n");
2890 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2891 				      ext_phy_addr,
2892 				      MDIO_WIS_DEVAD,
2893 				      MDIO_WIS_REG_LASI_STATUS, &val1);
2894 			DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2895 
2896 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2897 				      ext_phy_addr,
2898 				      MDIO_WIS_DEVAD,
2899 				      MDIO_WIS_REG_LASI_STATUS, &val1);
2900 			DP(NETIF_MSG_LINK, "8705 LASI status 0x%x\n", val1);
2901 
2902 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2903 				      ext_phy_addr,
2904 				      MDIO_PMA_DEVAD,
2905 				      MDIO_PMA_REG_RX_SD, &rx_sd);
2906 			DP(NETIF_MSG_LINK, "8705 rx_sd 0x%x\n", rx_sd);
2907 			ext_phy_link_up = (rx_sd & 0x1);
2908 			if (ext_phy_link_up)
2909 				vars->line_speed = SPEED_10000;
2910 			break;
2911 
2912 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
2913 			DP(NETIF_MSG_LINK, "XGXS 8706\n");
2914 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2915 				      ext_phy_addr,
2916 				      MDIO_PMA_DEVAD,
2917 				      MDIO_PMA_REG_LASI_STATUS, &val1);
2918 			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2919 
2920 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2921 				      ext_phy_addr,
2922 				      MDIO_PMA_DEVAD,
2923 				      MDIO_PMA_REG_LASI_STATUS, &val1);
2924 			DP(NETIF_MSG_LINK, "8706 LASI status 0x%x\n", val1);
2925 
2926 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2927 				      ext_phy_addr,
2928 				      MDIO_PMA_DEVAD,
2929 				      MDIO_PMA_REG_RX_SD, &rx_sd);
2930 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2931 				      ext_phy_addr,
2932 				      MDIO_PCS_DEVAD,
2933 				      MDIO_PCS_REG_STATUS, &pcs_status);
2934 
2935 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2936 				      ext_phy_addr,
2937 				      MDIO_AN_DEVAD,
2938 				      MDIO_AN_REG_LINK_STATUS, &val2);
2939 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2940 				      ext_phy_addr,
2941 				      MDIO_AN_DEVAD,
2942 				      MDIO_AN_REG_LINK_STATUS, &val2);
2943 
2944 			DP(NETIF_MSG_LINK, "8706 rx_sd 0x%x"
2945 			   "  pcs_status 0x%x 1Gbps link_status 0x%x\n",
2946 			   rx_sd, pcs_status, val2);
2947 			/* link is up if both bit 0 of pmd_rx_sd and
2948 			 * bit 0 of pcs_status are set, or if the autoneg bit
2949 			   1 is set
2950 			 */
2951 			ext_phy_link_up = ((rx_sd & pcs_status & 0x1) ||
2952 					   (val2 & (1<<1)));
2953 			if (ext_phy_link_up) {
2954 				if (val2 & (1<<1))
2955 					vars->line_speed = SPEED_1000;
2956 				else
2957 					vars->line_speed = SPEED_10000;
2958 			}
2959 
2960 			/* clear LASI indication*/
2961 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
2962 				      ext_phy_addr,
2963 				      MDIO_PMA_DEVAD,
2964 				      MDIO_PMA_REG_RX_ALARM, &val2);
2965 			break;
2966 
2967 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
2968 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
2969 		{
2970 			u16 link_status = 0;
2971 			u16 an1000_status = 0;
2972 			if (ext_phy_type ==
2973 			     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) {
2974 				bnx2x_cl45_read(bp, params->port,
2975 				      ext_phy_type,
2976 				      ext_phy_addr,
2977 				      MDIO_PCS_DEVAD,
2978 				      MDIO_PCS_REG_LASI_STATUS, &val1);
2979 			bnx2x_cl45_read(bp, params->port,
2980 				      ext_phy_type,
2981 				      ext_phy_addr,
2982 				      MDIO_PCS_DEVAD,
2983 				      MDIO_PCS_REG_LASI_STATUS, &val2);
2984 			DP(NETIF_MSG_LINK,
2985 				 "870x LASI status 0x%x->0x%x\n",
2986 				  val1, val2);
2987 
2988 			} else {
2989 				/* In 8073, port1 is directed through emac0 and
2990 				 * port0 is directed through emac1
2991 				 */
2992 				bnx2x_cl45_read(bp, params->port,
2993 					      ext_phy_type,
2994 					      ext_phy_addr,
2995 					      MDIO_PMA_DEVAD,
2996 					      MDIO_PMA_REG_LASI_STATUS, &val1);
2997 
2998 				DP(NETIF_MSG_LINK,
2999 					 "8703 LASI status 0x%x\n",
3000 					  val1);
3001 			}
3002 
3003 			/* clear the interrupt LASI status register */
3004 			bnx2x_cl45_read(bp, params->port,
3005 				      ext_phy_type,
3006 				      ext_phy_addr,
3007 				      MDIO_PCS_DEVAD,
3008 				      MDIO_PCS_REG_STATUS, &val2);
3009 			bnx2x_cl45_read(bp, params->port,
3010 				      ext_phy_type,
3011 				      ext_phy_addr,
3012 				      MDIO_PCS_DEVAD,
3013 				      MDIO_PCS_REG_STATUS, &val1);
3014 			DP(NETIF_MSG_LINK, "807x PCS status 0x%x->0x%x\n",
3015 			   val2, val1);
3016 			/* Clear MSG-OUT */
3017 			bnx2x_cl45_read(bp, params->port,
3018 				      ext_phy_type,
3019 				      ext_phy_addr,
3020 				      MDIO_PMA_DEVAD,
3021 				      0xca13,
3022 				      &val1);
3023 
3024 			/* Check the LASI */
3025 			bnx2x_cl45_read(bp, params->port,
3026 				      ext_phy_type,
3027 				      ext_phy_addr,
3028 				      MDIO_PMA_DEVAD,
3029 				      MDIO_PMA_REG_RX_ALARM, &val2);
3030 
3031 			DP(NETIF_MSG_LINK, "KR 0x9003 0x%x\n", val2);
3032 
3033 			/* Check the link status */
3034 			bnx2x_cl45_read(bp, params->port,
3035 				      ext_phy_type,
3036 				      ext_phy_addr,
3037 				      MDIO_PCS_DEVAD,
3038 				      MDIO_PCS_REG_STATUS, &val2);
3039 			DP(NETIF_MSG_LINK, "KR PCS status 0x%x\n", val2);
3040 
3041 			bnx2x_cl45_read(bp, params->port,
3042 				      ext_phy_type,
3043 				      ext_phy_addr,
3044 				      MDIO_PMA_DEVAD,
3045 				      MDIO_PMA_REG_STATUS, &val2);
3046 			bnx2x_cl45_read(bp, params->port,
3047 				      ext_phy_type,
3048 				      ext_phy_addr,
3049 				      MDIO_PMA_DEVAD,
3050 				      MDIO_PMA_REG_STATUS, &val1);
3051 			ext_phy_link_up = ((val1 & 4) == 4);
3052 			DP(NETIF_MSG_LINK, "PMA_REG_STATUS=0x%x\n", val1);
3053 			if (ext_phy_type ==
3054 			    PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
3055 
3056 				if (ext_phy_link_up &&
3057 				    ((params->req_line_speed !=
3058 					SPEED_10000))) {
3059 					if (bnx2x_bcm8073_xaui_wa(params)
3060 					     != 0) {
3061 						ext_phy_link_up = 0;
3062 						break;
3063 					}
3064 				}
3065 				bnx2x_cl45_read(bp, params->port,
3066 						      ext_phy_type,
3067 						      ext_phy_addr,
3068 						      MDIO_AN_DEVAD,
3069 						      0x8304,
3070 						      &an1000_status);
3071 				bnx2x_cl45_read(bp, params->port,
3072 						      ext_phy_type,
3073 						      ext_phy_addr,
3074 						      MDIO_AN_DEVAD,
3075 						      0x8304,
3076 						      &an1000_status);
3077 
3078 				/* Check the link status on 1.1.2 */
3079 				bnx2x_cl45_read(bp, params->port,
3080 					      ext_phy_type,
3081 					      ext_phy_addr,
3082 					      MDIO_PMA_DEVAD,
3083 					      MDIO_PMA_REG_STATUS, &val2);
3084 				bnx2x_cl45_read(bp, params->port,
3085 					      ext_phy_type,
3086 					      ext_phy_addr,
3087 					      MDIO_PMA_DEVAD,
3088 					      MDIO_PMA_REG_STATUS, &val1);
3089 				DP(NETIF_MSG_LINK, "KR PMA status 0x%x->0x%x,"
3090 					     "an_link_status=0x%x\n",
3091 					  val2, val1, an1000_status);
3092 
3093 					ext_phy_link_up = (((val1 & 4) == 4) ||
3094 						(an1000_status & (1<<1)));
3095 				if (ext_phy_link_up &&
3096 				    bnx2x_8073_is_snr_needed(params)) {
3097 					/* The SNR will improve about 2dbby
3098 					changing the BW and FEE main tap.*/
3099 
3100 					/* The 1st write to change FFE main
3101 					tap is set before restart AN */
3102 					/* Change PLL Bandwidth in EDC
3103 					register */
3104 					bnx2x_cl45_write(bp, port, ext_phy_type,
3105 						    ext_phy_addr,
3106 						    MDIO_PMA_DEVAD,
3107 						    MDIO_PMA_REG_PLL_BANDWIDTH,
3108 						    0x26BC);
3109 
3110 					/* Change CDR Bandwidth in EDC
3111 					register */
3112 					bnx2x_cl45_write(bp, port, ext_phy_type,
3113 						    ext_phy_addr,
3114 						    MDIO_PMA_DEVAD,
3115 						    MDIO_PMA_REG_CDR_BANDWIDTH,
3116 						    0x0333);
3117 
3118 
3119 				}
3120 				bnx2x_cl45_read(bp, params->port,
3121 						      ext_phy_type,
3122 						      ext_phy_addr,
3123 						      MDIO_PMA_DEVAD,
3124 						      0xc820,
3125 						      &link_status);
3126 
3127 				/* Bits 0..2 --> speed detected,
3128 				   bits 13..15--> link is down */
3129 				if ((link_status & (1<<2)) &&
3130 				    (!(link_status & (1<<15)))) {
3131 					ext_phy_link_up = 1;
3132 					vars->line_speed = SPEED_10000;
3133 					DP(NETIF_MSG_LINK,
3134 						 "port %x: External link"
3135 						 " up in 10G\n", params->port);
3136 				} else if ((link_status & (1<<1)) &&
3137 					   (!(link_status & (1<<14)))) {
3138 					ext_phy_link_up = 1;
3139 					vars->line_speed = SPEED_2500;
3140 					DP(NETIF_MSG_LINK,
3141 						 "port %x: External link"
3142 						 " up in 2.5G\n", params->port);
3143 				} else if ((link_status & (1<<0)) &&
3144 					   (!(link_status & (1<<13)))) {
3145 					ext_phy_link_up = 1;
3146 					vars->line_speed = SPEED_1000;
3147 					DP(NETIF_MSG_LINK,
3148 						 "port %x: External link"
3149 						 " up in 1G\n", params->port);
3150 				} else {
3151 					ext_phy_link_up = 0;
3152 					DP(NETIF_MSG_LINK,
3153 						 "port %x: External link"
3154 						 " is down\n", params->port);
3155 				}
3156 			} else {
3157 				/* See if 1G link is up for the 8072 */
3158 				bnx2x_cl45_read(bp, params->port,
3159 						      ext_phy_type,
3160 						      ext_phy_addr,
3161 						      MDIO_AN_DEVAD,
3162 						      0x8304,
3163 						      &an1000_status);
3164 				bnx2x_cl45_read(bp, params->port,
3165 						      ext_phy_type,
3166 						      ext_phy_addr,
3167 						      MDIO_AN_DEVAD,
3168 						      0x8304,
3169 						      &an1000_status);
3170 				if (an1000_status & (1<<1)) {
3171 					ext_phy_link_up = 1;
3172 					vars->line_speed = SPEED_1000;
3173 					DP(NETIF_MSG_LINK,
3174 						 "port %x: External link"
3175 						 " up in 1G\n", params->port);
3176 				} else if (ext_phy_link_up) {
3177 					ext_phy_link_up = 1;
3178 					vars->line_speed = SPEED_10000;
3179 					DP(NETIF_MSG_LINK,
3180 						 "port %x: External link"
3181 						 " up in 10G\n", params->port);
3182 				}
3183 			}
3184 
3185 
3186 			break;
3187 		}
3188 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3189 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
3190 				      ext_phy_addr,
3191 				      MDIO_PMA_DEVAD,
3192 				      MDIO_PMA_REG_LASI_STATUS, &val2);
3193 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
3194 				      ext_phy_addr,
3195 				      MDIO_PMA_DEVAD,
3196 				      MDIO_PMA_REG_LASI_STATUS, &val1);
3197 			DP(NETIF_MSG_LINK,
3198 				 "10G-base-T LASI status 0x%x->0x%x\n",
3199 				  val2, val1);
3200 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
3201 				      ext_phy_addr,
3202 				      MDIO_PMA_DEVAD,
3203 				      MDIO_PMA_REG_STATUS, &val2);
3204 			bnx2x_cl45_read(bp, params->port, ext_phy_type,
3205 				      ext_phy_addr,
3206 				      MDIO_PMA_DEVAD,
3207 				      MDIO_PMA_REG_STATUS, &val1);
3208 			DP(NETIF_MSG_LINK,
3209 				 "10G-base-T PMA status 0x%x->0x%x\n",
3210 				 val2, val1);
3211 			ext_phy_link_up = ((val1 & 4) == 4);
3212 			/* if link is up
3213 			 * print the AN outcome of the SFX7101 PHY
3214 			 */
3215 			if (ext_phy_link_up) {
3216 				bnx2x_cl45_read(bp, params->port,
3217 					      ext_phy_type,
3218 					      ext_phy_addr,
3219 					      MDIO_AN_DEVAD,
3220 					      MDIO_AN_REG_MASTER_STATUS,
3221 					      &val2);
3222 				vars->line_speed = SPEED_10000;
3223 				DP(NETIF_MSG_LINK,
3224 					 "SFX7101 AN status 0x%x->Master=%x\n",
3225 					  val2,
3226 					 (val2 & (1<<14)));
3227 			}
3228 			break;
3229 
3230 		default:
3231 			DP(NETIF_MSG_LINK, "BAD XGXS ext_phy_config 0x%x\n",
3232 			   params->ext_phy_config);
3233 			ext_phy_link_up = 0;
3234 			break;
3235 		}
3236 
3237 	} else { /* SerDes */
3238 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3239 		switch (ext_phy_type) {
3240 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT:
3241 			DP(NETIF_MSG_LINK, "SerDes Direct\n");
3242 			ext_phy_link_up = 1;
3243 			break;
3244 
3245 		case PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482:
3246 			DP(NETIF_MSG_LINK, "SerDes 5482\n");
3247 			ext_phy_link_up = 1;
3248 			break;
3249 
3250 		default:
3251 			DP(NETIF_MSG_LINK,
3252 				 "BAD SerDes ext_phy_config 0x%x\n",
3253 				 params->ext_phy_config);
3254 			ext_phy_link_up = 0;
3255 			break;
3256 		}
3257 	}
3258 
3259 	return ext_phy_link_up;
3260 }
3261 
bnx2x_link_int_enable(struct link_params * params)3262 static void bnx2x_link_int_enable(struct link_params *params)
3263 {
3264 	u8 port = params->port;
3265 	u32 ext_phy_type;
3266 	u32 mask;
3267 	struct bnx2x *bp = params->bp;
3268 	/* setting the status to report on link up
3269 	   for either XGXS or SerDes */
3270 
3271 	if (params->switch_cfg == SWITCH_CFG_10G) {
3272 		mask = (NIG_MASK_XGXS0_LINK10G |
3273 			NIG_MASK_XGXS0_LINK_STATUS);
3274 		DP(NETIF_MSG_LINK, "enabled XGXS interrupt\n");
3275 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3276 		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) &&
3277 		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE) &&
3278 		    (ext_phy_type !=
3279 				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN)) {
3280 			mask |= NIG_MASK_MI_INT;
3281 			DP(NETIF_MSG_LINK, "enabled external phy int\n");
3282 		}
3283 
3284 	} else { /* SerDes */
3285 		mask = NIG_MASK_SERDES0_LINK_STATUS;
3286 		DP(NETIF_MSG_LINK, "enabled SerDes interrupt\n");
3287 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3288 		if ((ext_phy_type !=
3289 				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
3290 		    (ext_phy_type !=
3291 				PORT_HW_CFG_SERDES_EXT_PHY_TYPE_NOT_CONN)) {
3292 			mask |= NIG_MASK_MI_INT;
3293 			DP(NETIF_MSG_LINK, "enabled external phy int\n");
3294 		}
3295 	}
3296 	bnx2x_bits_en(bp,
3297 		      NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
3298 		      mask);
3299 	DP(NETIF_MSG_LINK, "port %x, is_xgxs=%x, int_status 0x%x\n", port,
3300 		 (params->switch_cfg == SWITCH_CFG_10G),
3301 		 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
3302 
3303 	DP(NETIF_MSG_LINK, " int_mask 0x%x, MI_INT %x, SERDES_LINK %x\n",
3304 		 REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
3305 		 REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
3306 		 REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS+port*0x3c));
3307 	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
3308 	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
3309 	   REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
3310 }
3311 
3312 
3313 /*
3314  * link management
3315  */
bnx2x_link_int_ack(struct link_params * params,struct link_vars * vars,u8 is_10g)3316 static void bnx2x_link_int_ack(struct link_params *params,
3317 			     struct link_vars *vars, u8 is_10g)
3318 {
3319 	struct bnx2x *bp = params->bp;
3320 	u8 port = params->port;
3321 
3322 	/* first reset all status
3323 	 * we assume only one line will be change at a time */
3324 	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3325 		     (NIG_STATUS_XGXS0_LINK10G |
3326 		      NIG_STATUS_XGXS0_LINK_STATUS |
3327 		      NIG_STATUS_SERDES0_LINK_STATUS));
3328 	if (vars->phy_link_up) {
3329 		if (is_10g) {
3330 			/* Disable the 10G link interrupt
3331 			 * by writing 1 to the status register
3332 			 */
3333 			DP(NETIF_MSG_LINK, "10G XGXS phy link up\n");
3334 			bnx2x_bits_en(bp,
3335 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3336 				      NIG_STATUS_XGXS0_LINK10G);
3337 
3338 		} else if (params->switch_cfg == SWITCH_CFG_10G) {
3339 			/* Disable the link interrupt
3340 			 * by writing 1 to the relevant lane
3341 			 * in the status register
3342 			 */
3343 			u32 ser_lane = ((params->lane_config &
3344 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
3345 				    PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
3346 
3347 			DP(NETIF_MSG_LINK, "1G XGXS phy link up\n");
3348 			bnx2x_bits_en(bp,
3349 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3350 				      ((1 << ser_lane) <<
3351 				       NIG_STATUS_XGXS0_LINK_STATUS_SIZE));
3352 
3353 		} else { /* SerDes */
3354 			DP(NETIF_MSG_LINK, "SerDes phy link up\n");
3355 			/* Disable the link interrupt
3356 			 * by writing 1 to the status register
3357 			 */
3358 			bnx2x_bits_en(bp,
3359 				      NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3360 				      NIG_STATUS_SERDES0_LINK_STATUS);
3361 		}
3362 
3363 	} else { /* link_down */
3364 	}
3365 }
3366 
bnx2x_format_ver(u32 num,u8 * str,u16 len)3367 static u8 bnx2x_format_ver(u32 num, u8 *str, u16 len)
3368 {
3369 	u8 *str_ptr = str;
3370 	u32 mask = 0xf0000000;
3371 	u8 shift = 8*4;
3372 	u8 digit;
3373 	if (len < 10) {
3374 		/* Need more than 10chars for this format */
3375 		*str_ptr = '\0';
3376 		return -EINVAL;
3377 	}
3378 	while (shift > 0) {
3379 
3380 		shift -= 4;
3381 		digit = ((num & mask) >> shift);
3382 		if (digit < 0xa)
3383 			*str_ptr = digit + '0';
3384 		else
3385 			*str_ptr = digit - 0xa + 'a';
3386 		str_ptr++;
3387 		mask = mask >> 4;
3388 		if (shift == 4*4) {
3389 			*str_ptr = ':';
3390 			str_ptr++;
3391 		}
3392 	}
3393 	*str_ptr = '\0';
3394 	return 0;
3395 }
3396 
3397 
bnx2x_turn_on_ef(struct bnx2x * bp,u8 port,u8 ext_phy_addr,u32 ext_phy_type)3398 static void bnx2x_turn_on_ef(struct bnx2x *bp, u8 port, u8 ext_phy_addr,
3399 			   u32 ext_phy_type)
3400 {
3401 	u32 cnt = 0;
3402 	u16 ctrl = 0;
3403 	/* Enable EMAC0 in to enable MDIO */
3404 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
3405 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
3406 	msleep(5);
3407 
3408 	/* take ext phy out of reset */
3409 	bnx2x_set_gpio(bp,
3410 			  MISC_REGISTERS_GPIO_2,
3411 			  MISC_REGISTERS_GPIO_HIGH,
3412 			  port);
3413 
3414 	bnx2x_set_gpio(bp,
3415 			  MISC_REGISTERS_GPIO_1,
3416 			  MISC_REGISTERS_GPIO_HIGH,
3417 			  port);
3418 
3419 	/* wait for 5ms */
3420 	msleep(5);
3421 
3422 	for (cnt = 0; cnt < 1000; cnt++) {
3423 		msleep(1);
3424 		bnx2x_cl45_read(bp, port,
3425 			      ext_phy_type,
3426 			      ext_phy_addr,
3427 			      MDIO_PMA_DEVAD,
3428 			      MDIO_PMA_REG_CTRL,
3429 			       &ctrl);
3430 		if (!(ctrl & (1<<15))) {
3431 			DP(NETIF_MSG_LINK, "Reset completed\n\n");
3432 				break;
3433 		}
3434 	}
3435 }
3436 
bnx2x_turn_off_sf(struct bnx2x * bp,u8 port)3437 static void bnx2x_turn_off_sf(struct bnx2x *bp, u8 port)
3438 {
3439 	/* put sf to reset */
3440 	bnx2x_set_gpio(bp,
3441 			  MISC_REGISTERS_GPIO_1,
3442 			  MISC_REGISTERS_GPIO_LOW,
3443 			  port);
3444 	bnx2x_set_gpio(bp,
3445 			  MISC_REGISTERS_GPIO_2,
3446 			  MISC_REGISTERS_GPIO_LOW,
3447 			  port);
3448 }
3449 
bnx2x_get_ext_phy_fw_version(struct link_params * params,u8 driver_loaded,u8 * version,u16 len)3450 u8 bnx2x_get_ext_phy_fw_version(struct link_params *params, u8 driver_loaded,
3451 			      u8 *version, u16 len)
3452 {
3453 	struct bnx2x *bp = params->bp;
3454 	u32 ext_phy_type = 0;
3455 	u16 val = 0;
3456 	u8 ext_phy_addr = 0 ;
3457 	u8 status = 0 ;
3458 	u32 ver_num;
3459 
3460 	if (version == NULL || params == NULL)
3461 		return -EINVAL;
3462 
3463 	/* reset the returned value to zero */
3464 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3465 	ext_phy_addr = ((params->ext_phy_config &
3466 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3467 				PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3468 
3469 	switch (ext_phy_type) {
3470 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3471 
3472 		if (len < 5)
3473 			return -EINVAL;
3474 
3475 		/* Take ext phy out of reset */
3476 		if (!driver_loaded)
3477 			bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3478 				       ext_phy_type);
3479 
3480 		/*  wait for 1ms */
3481 		msleep(1);
3482 
3483 		bnx2x_cl45_read(bp, params->port,
3484 			      ext_phy_type,
3485 			      ext_phy_addr,
3486 			      MDIO_PMA_DEVAD,
3487 			      MDIO_PMA_REG_7101_VER1, &val);
3488 		version[2] = (val & 0xFF);
3489 		version[3] = ((val & 0xFF00)>>8);
3490 
3491 		bnx2x_cl45_read(bp, params->port,
3492 			      ext_phy_type,
3493 			      ext_phy_addr,
3494 			      MDIO_PMA_DEVAD, MDIO_PMA_REG_7101_VER2,
3495 			      &val);
3496 		version[0] = (val & 0xFF);
3497 		version[1] = ((val & 0xFF00)>>8);
3498 		version[4] = '\0';
3499 
3500 		if (!driver_loaded)
3501 			bnx2x_turn_off_sf(bp, params->port);
3502 		break;
3503 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3504 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
3505 	{
3506 		/* Take ext phy out of reset */
3507 		if (!driver_loaded)
3508 			bnx2x_turn_on_ef(bp, params->port, ext_phy_addr,
3509 				       ext_phy_type);
3510 
3511 		bnx2x_cl45_read(bp, params->port, ext_phy_type,
3512 			      ext_phy_addr,
3513 			      MDIO_PMA_DEVAD,
3514 			      MDIO_PMA_REG_ROM_VER1, &val);
3515 		ver_num = val<<16;
3516 		bnx2x_cl45_read(bp, params->port, ext_phy_type,
3517 			      ext_phy_addr,
3518 			      MDIO_PMA_DEVAD,
3519 			      MDIO_PMA_REG_ROM_VER2, &val);
3520 		ver_num |= val;
3521 		status = bnx2x_format_ver(ver_num, version, len);
3522 		break;
3523 	}
3524 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3525 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3526 
3527 		bnx2x_cl45_read(bp, params->port, ext_phy_type,
3528 			      ext_phy_addr,
3529 			      MDIO_PMA_DEVAD,
3530 			      MDIO_PMA_REG_ROM_VER1, &val);
3531 		ver_num = val<<16;
3532 		bnx2x_cl45_read(bp, params->port, ext_phy_type,
3533 			      ext_phy_addr,
3534 			      MDIO_PMA_DEVAD,
3535 			      MDIO_PMA_REG_ROM_VER2, &val);
3536 		ver_num |= val;
3537 		status = bnx2x_format_ver(ver_num, version, len);
3538 		break;
3539 
3540 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3541 		break;
3542 
3543 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
3544 		DP(NETIF_MSG_LINK, "bnx2x_get_ext_phy_fw_version:"
3545 				    " type is FAILURE!\n");
3546 		status = -EINVAL;
3547 		break;
3548 
3549 	default:
3550 		break;
3551 	}
3552 	return status;
3553 }
3554 
bnx2x_set_xgxs_loopback(struct link_params * params,struct link_vars * vars,u8 is_10g)3555 static void bnx2x_set_xgxs_loopback(struct link_params *params,
3556 				  struct link_vars *vars,
3557 				  u8 is_10g)
3558 {
3559 	u8 port = params->port;
3560 	struct bnx2x *bp = params->bp;
3561 
3562 	if (is_10g) {
3563 		u32 md_devad;
3564 
3565 		DP(NETIF_MSG_LINK, "XGXS 10G loopback enable\n");
3566 
3567 		/* change the uni_phy_addr in the nig */
3568 		md_devad = REG_RD(bp, (NIG_REG_XGXS0_CTRL_MD_DEVAD +
3569 					  port*0x18));
3570 
3571 		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18, 0x5);
3572 
3573 		bnx2x_cl45_write(bp, port, 0,
3574 			       params->phy_addr,
3575 			       5,
3576 			       (MDIO_REG_BANK_AER_BLOCK +
3577 				(MDIO_AER_BLOCK_AER_REG & 0xf)),
3578 			       0x2800);
3579 
3580 		bnx2x_cl45_write(bp, port, 0,
3581 			       params->phy_addr,
3582 			       5,
3583 			       (MDIO_REG_BANK_CL73_IEEEB0 +
3584 				(MDIO_CL73_IEEEB0_CL73_AN_CONTROL & 0xf)),
3585 			       0x6041);
3586 		msleep(200);
3587 		/* set aer mmd back */
3588 		bnx2x_set_aer_mmd(params, vars);
3589 
3590 		/* and md_devad */
3591 		REG_WR(bp, NIG_REG_XGXS0_CTRL_MD_DEVAD + port*0x18,
3592 			    md_devad);
3593 
3594 	} else {
3595 		u16 mii_control;
3596 
3597 		DP(NETIF_MSG_LINK, "XGXS 1G loopback enable\n");
3598 
3599 		CL45_RD_OVER_CL22(bp, port,
3600 				      params->phy_addr,
3601 				      MDIO_REG_BANK_COMBO_IEEE0,
3602 				      MDIO_COMBO_IEEE0_MII_CONTROL,
3603 				      &mii_control);
3604 
3605 		CL45_WR_OVER_CL22(bp, port,
3606 				      params->phy_addr,
3607 				      MDIO_REG_BANK_COMBO_IEEE0,
3608 				      MDIO_COMBO_IEEE0_MII_CONTROL,
3609 				      (mii_control |
3610 				       MDIO_COMBO_IEEO_MII_CONTROL_LOOPBACK));
3611 	}
3612 }
3613 
3614 
bnx2x_ext_phy_loopback(struct link_params * params)3615 static void bnx2x_ext_phy_loopback(struct link_params *params)
3616 {
3617 	struct bnx2x *bp = params->bp;
3618 	u8 ext_phy_addr;
3619 	u32 ext_phy_type;
3620 
3621 	if (params->switch_cfg == SWITCH_CFG_10G) {
3622 		ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3623 		/* CL37 Autoneg Enabled */
3624 		ext_phy_addr = ((params->ext_phy_config &
3625 					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
3626 					PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
3627 		switch (ext_phy_type) {
3628 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
3629 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
3630 			DP(NETIF_MSG_LINK,
3631 				"ext_phy_loopback: We should not get here\n");
3632 			break;
3633 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
3634 			DP(NETIF_MSG_LINK, "ext_phy_loopback: 8705\n");
3635 			break;
3636 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
3637 			DP(NETIF_MSG_LINK, "ext_phy_loopback: 8706\n");
3638 			break;
3639 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
3640 			/* SFX7101_XGXS_TEST1 */
3641 			bnx2x_cl45_write(bp, params->port, ext_phy_type,
3642 				       ext_phy_addr,
3643 				       MDIO_XS_DEVAD,
3644 				       MDIO_XS_SFX7101_XGXS_TEST1,
3645 				       0x100);
3646 			DP(NETIF_MSG_LINK,
3647 				"ext_phy_loopback: set ext phy loopback\n");
3648 			break;
3649 		case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
3650 
3651 			break;
3652 		} /* switch external PHY type */
3653 	} else {
3654 		/* serdes */
3655 		ext_phy_type = SERDES_EXT_PHY_TYPE(params->ext_phy_config);
3656 		ext_phy_addr = (params->ext_phy_config  &
3657 		PORT_HW_CFG_SERDES_EXT_PHY_ADDR_MASK)
3658 		>> PORT_HW_CFG_SERDES_EXT_PHY_ADDR_SHIFT;
3659 	}
3660 }
3661 
3662 
3663 /*
3664  *------------------------------------------------------------------------
3665  * bnx2x_override_led_value -
3666  *
3667  * Override the led value of the requsted led
3668  *
3669  *------------------------------------------------------------------------
3670  */
bnx2x_override_led_value(struct bnx2x * bp,u8 port,u32 led_idx,u32 value)3671 u8 bnx2x_override_led_value(struct bnx2x *bp, u8 port,
3672 			  u32 led_idx, u32 value)
3673 {
3674 	u32 reg_val;
3675 
3676 	/* If port 0 then use EMAC0, else use EMAC1*/
3677 	u32 emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3678 
3679 	DP(NETIF_MSG_LINK,
3680 		 "bnx2x_override_led_value() port %x led_idx %d value %d\n",
3681 		 port, led_idx, value);
3682 
3683 	switch (led_idx) {
3684 	case 0: /* 10MB led */
3685 		/* Read the current value of the LED register in
3686 		the EMAC block */
3687 		reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3688 		/* Set the OVERRIDE bit to 1 */
3689 		reg_val |= EMAC_LED_OVERRIDE;
3690 		/* If value is 1, set the 10M_OVERRIDE bit,
3691 		otherwise reset it.*/
3692 		reg_val = (value == 1) ? (reg_val | EMAC_LED_10MB_OVERRIDE) :
3693 			(reg_val & ~EMAC_LED_10MB_OVERRIDE);
3694 		REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3695 		break;
3696 	case 1: /*100MB led    */
3697 		/*Read the current value of the LED register in
3698 		the EMAC block */
3699 		reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3700 		/*  Set the OVERRIDE bit to 1 */
3701 		reg_val |= EMAC_LED_OVERRIDE;
3702 		/*  If value is 1, set the 100M_OVERRIDE bit,
3703 		otherwise reset it.*/
3704 		reg_val = (value == 1) ? (reg_val | EMAC_LED_100MB_OVERRIDE) :
3705 			(reg_val & ~EMAC_LED_100MB_OVERRIDE);
3706 		REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3707 		break;
3708 	case 2: /* 1000MB led */
3709 		/* Read the current value of the LED register in the
3710 		EMAC block */
3711 		reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3712 		/* Set the OVERRIDE bit to 1 */
3713 		reg_val |= EMAC_LED_OVERRIDE;
3714 		/* If value is 1, set the 1000M_OVERRIDE bit, otherwise
3715 		reset it. */
3716 		reg_val = (value == 1) ? (reg_val | EMAC_LED_1000MB_OVERRIDE) :
3717 			(reg_val & ~EMAC_LED_1000MB_OVERRIDE);
3718 		REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3719 		break;
3720 	case 3: /* 2500MB led */
3721 		/*  Read the current value of the LED register in the
3722 		EMAC block*/
3723 		reg_val = REG_RD(bp, emac_base + EMAC_REG_EMAC_LED);
3724 		/* Set the OVERRIDE bit to 1 */
3725 		reg_val |= EMAC_LED_OVERRIDE;
3726 		/*  If value is 1, set the 2500M_OVERRIDE bit, otherwise
3727 		reset it.*/
3728 		reg_val = (value == 1) ? (reg_val | EMAC_LED_2500MB_OVERRIDE) :
3729 			(reg_val & ~EMAC_LED_2500MB_OVERRIDE);
3730 		REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3731 		break;
3732 	case 4: /*10G led */
3733 		if (port == 0) {
3734 			REG_WR(bp, NIG_REG_LED_10G_P0,
3735 				    value);
3736 		} else {
3737 			REG_WR(bp, NIG_REG_LED_10G_P1,
3738 				    value);
3739 		}
3740 		break;
3741 	case 5: /* TRAFFIC led */
3742 		/* Find if the traffic control is via BMAC or EMAC */
3743 		if (port == 0)
3744 			reg_val = REG_RD(bp, NIG_REG_NIG_EMAC0_EN);
3745 		else
3746 			reg_val = REG_RD(bp, NIG_REG_NIG_EMAC1_EN);
3747 
3748 		/*  Override the traffic led in the EMAC:*/
3749 		if (reg_val == 1) {
3750 			/* Read the current value of the LED register in
3751 			the EMAC block */
3752 			reg_val = REG_RD(bp, emac_base +
3753 					     EMAC_REG_EMAC_LED);
3754 			/* Set the TRAFFIC_OVERRIDE bit to 1 */
3755 			reg_val |= EMAC_LED_OVERRIDE;
3756 			/* If value is 1, set the TRAFFIC bit, otherwise
3757 			reset it.*/
3758 			reg_val = (value == 1) ? (reg_val | EMAC_LED_TRAFFIC) :
3759 				(reg_val & ~EMAC_LED_TRAFFIC);
3760 			REG_WR(bp, emac_base + EMAC_REG_EMAC_LED, reg_val);
3761 		} else { /* Override the traffic led in the BMAC: */
3762 			REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3763 				   + port*4, 1);
3764 			REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 + port*4,
3765 				    value);
3766 		}
3767 		break;
3768 	default:
3769 		DP(NETIF_MSG_LINK,
3770 			 "bnx2x_override_led_value() unknown led index %d "
3771 			 "(should be 0-5)\n", led_idx);
3772 		return -EINVAL;
3773 	}
3774 
3775 	return 0;
3776 }
3777 
3778 
bnx2x_set_led(struct bnx2x * bp,u8 port,u8 mode,u32 speed,u16 hw_led_mode,u32 chip_id)3779 u8 bnx2x_set_led(struct bnx2x *bp, u8 port, u8 mode, u32 speed,
3780 	       u16 hw_led_mode, u32 chip_id)
3781 {
3782 	u8 rc = 0;
3783 	u32 tmp;
3784 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
3785 	DP(NETIF_MSG_LINK, "bnx2x_set_led: port %x, mode %d\n", port, mode);
3786 	DP(NETIF_MSG_LINK, "speed 0x%x, hw_led_mode 0x%x\n",
3787 		 speed, hw_led_mode);
3788 	switch (mode) {
3789 	case LED_MODE_OFF:
3790 		REG_WR(bp, NIG_REG_LED_10G_P0 + port*4, 0);
3791 		REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4,
3792 			   SHARED_HW_CFG_LED_MAC1);
3793 
3794 		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3795 		EMAC_WR(bp, EMAC_REG_EMAC_LED, (tmp | EMAC_LED_OVERRIDE));
3796 		break;
3797 
3798 	case LED_MODE_OPER:
3799 		REG_WR(bp, NIG_REG_LED_MODE_P0 + port*4, hw_led_mode);
3800 		REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0 +
3801 			   port*4, 0);
3802 		/* Set blinking rate to ~15.9Hz */
3803 		REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_P0 + port*4,
3804 			   LED_BLINK_RATE_VAL);
3805 		REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_RATE_ENA_P0 +
3806 			   port*4, 1);
3807 		tmp = EMAC_RD(bp, EMAC_REG_EMAC_LED);
3808 		EMAC_WR(bp, EMAC_REG_EMAC_LED,
3809 			    (tmp & (~EMAC_LED_OVERRIDE)));
3810 
3811 		if (!CHIP_IS_E1H(bp) &&
3812 		    ((speed == SPEED_2500) ||
3813 		     (speed == SPEED_1000) ||
3814 		     (speed == SPEED_100) ||
3815 		     (speed == SPEED_10))) {
3816 			/* On Everest 1 Ax chip versions for speeds less than
3817 			10G LED scheme is different */
3818 			REG_WR(bp, NIG_REG_LED_CONTROL_OVERRIDE_TRAFFIC_P0
3819 				   + port*4, 1);
3820 			REG_WR(bp, NIG_REG_LED_CONTROL_TRAFFIC_P0 +
3821 				   port*4, 0);
3822 			REG_WR(bp, NIG_REG_LED_CONTROL_BLINK_TRAFFIC_P0 +
3823 				   port*4, 1);
3824 		}
3825 		break;
3826 
3827 	default:
3828 		rc = -EINVAL;
3829 		DP(NETIF_MSG_LINK, "bnx2x_set_led: Invalid led mode %d\n",
3830 			 mode);
3831 		break;
3832 	}
3833 	return rc;
3834 
3835 }
3836 
bnx2x_test_link(struct link_params * params,struct link_vars * vars)3837 u8 bnx2x_test_link(struct link_params *params, struct link_vars *vars)
3838 {
3839 	struct bnx2x *bp = params->bp;
3840 	u16 gp_status = 0;
3841 
3842 	CL45_RD_OVER_CL22(bp, params->port,
3843 			      params->phy_addr,
3844 			      MDIO_REG_BANK_GP_STATUS,
3845 			      MDIO_GP_STATUS_TOP_AN_STATUS1,
3846 			      &gp_status);
3847 	/* link is up only if both local phy and external phy are up */
3848 	if ((gp_status & MDIO_GP_STATUS_TOP_AN_STATUS1_LINK_STATUS) &&
3849 	    bnx2x_ext_phy_is_link_up(params, vars))
3850 		return 0;
3851 
3852 	return -ESRCH;
3853 }
3854 
bnx2x_link_initialize(struct link_params * params,struct link_vars * vars)3855 static u8 bnx2x_link_initialize(struct link_params *params,
3856 			      struct link_vars *vars)
3857 {
3858 	struct bnx2x *bp = params->bp;
3859 	u8 port = params->port;
3860 	u8 rc = 0;
3861 	u8 non_ext_phy;
3862 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
3863 	/* Activate the external PHY */
3864 	bnx2x_ext_phy_reset(params, vars);
3865 
3866 	bnx2x_set_aer_mmd(params, vars);
3867 
3868 	if (vars->phy_flags & PHY_XGXS_FLAG)
3869 		bnx2x_set_master_ln(params);
3870 
3871 	rc = bnx2x_reset_unicore(params);
3872 	/* reset the SerDes and wait for reset bit return low */
3873 	if (rc != 0)
3874 		return rc;
3875 
3876 	bnx2x_set_aer_mmd(params, vars);
3877 
3878 	/* setting the masterLn_def again after the reset */
3879 	if (vars->phy_flags & PHY_XGXS_FLAG) {
3880 		bnx2x_set_master_ln(params);
3881 		bnx2x_set_swap_lanes(params);
3882 	}
3883 
3884 	if (vars->phy_flags & PHY_XGXS_FLAG) {
3885 		if ((params->req_line_speed &&
3886 		    ((params->req_line_speed == SPEED_100) ||
3887 		     (params->req_line_speed == SPEED_10))) ||
3888 		    (!params->req_line_speed &&
3889 		     (params->speed_cap_mask >=
3890 		       PORT_HW_CFG_SPEED_CAPABILITY_D0_10M_FULL) &&
3891 		     (params->speed_cap_mask <
3892 		       PORT_HW_CFG_SPEED_CAPABILITY_D0_1G)
3893 		     ))  {
3894 			vars->phy_flags |= PHY_SGMII_FLAG;
3895 		} else {
3896 			vars->phy_flags &= ~PHY_SGMII_FLAG;
3897 		}
3898 	}
3899 	/* In case of external phy existance, the line speed would be the
3900 	 line speed linked up by the external phy. In case it is direct only,
3901 	  then the line_speed during initialization will be equal to the
3902 	   req_line_speed*/
3903 	vars->line_speed = params->req_line_speed;
3904 
3905 	bnx2x_calc_ieee_aneg_adv(params, &vars->ieee_fc);
3906 
3907 	/* init ext phy and enable link state int */
3908 	non_ext_phy = ((ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) ||
3909 		       (params->loopback_mode == LOOPBACK_XGXS_10) ||
3910 		       (params->loopback_mode == LOOPBACK_EXT_PHY));
3911 
3912 	if (non_ext_phy ||
3913 	    (ext_phy_type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705)) {
3914 		if (params->req_line_speed == SPEED_AUTO_NEG)
3915 			bnx2x_set_parallel_detection(params, vars->phy_flags);
3916 		bnx2x_init_internal_phy(params, vars);
3917 	}
3918 
3919 	if (!non_ext_phy)
3920 		rc |= bnx2x_ext_phy_init(params, vars);
3921 
3922 	bnx2x_bits_dis(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4,
3923 		     (NIG_STATUS_XGXS0_LINK10G |
3924 		      NIG_STATUS_XGXS0_LINK_STATUS |
3925 		      NIG_STATUS_SERDES0_LINK_STATUS));
3926 
3927 	return rc;
3928 
3929 }
3930 
3931 
bnx2x_phy_init(struct link_params * params,struct link_vars * vars)3932 u8 bnx2x_phy_init(struct link_params *params, struct link_vars *vars)
3933 {
3934 	struct bnx2x *bp = params->bp;
3935 
3936 	u32 val;
3937 	DP(NETIF_MSG_LINK, "Phy Initialization started \n");
3938 	DP(NETIF_MSG_LINK, "req_speed = %d, req_flowctrl=%d\n",
3939 		  params->req_line_speed, params->req_flow_ctrl);
3940 	vars->link_status = 0;
3941 	vars->phy_link_up = 0;
3942 	vars->link_up = 0;
3943 	vars->line_speed = 0;
3944 	vars->duplex = DUPLEX_FULL;
3945 	vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3946 	vars->mac_type = MAC_TYPE_NONE;
3947 
3948 	if (params->switch_cfg ==  SWITCH_CFG_1G)
3949 		vars->phy_flags = PHY_SERDES_FLAG;
3950 	else
3951 		vars->phy_flags = PHY_XGXS_FLAG;
3952 
3953 
3954 	/* disable attentions */
3955 	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + params->port*4,
3956 		       (NIG_MASK_XGXS0_LINK_STATUS |
3957 			NIG_MASK_XGXS0_LINK10G |
3958 			NIG_MASK_SERDES0_LINK_STATUS |
3959 			NIG_MASK_MI_INT));
3960 
3961 	bnx2x_emac_init(params, vars);
3962 
3963 	if (CHIP_REV_IS_FPGA(bp)) {
3964 		vars->link_up = 1;
3965 		vars->line_speed = SPEED_10000;
3966 		vars->duplex = DUPLEX_FULL;
3967 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3968 		vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3969 		/* enable on E1.5 FPGA */
3970 		if (CHIP_IS_E1H(bp)) {
3971 			vars->flow_ctrl |=
3972 				(BNX2X_FLOW_CTRL_TX | BNX2X_FLOW_CTRL_RX);
3973 			vars->link_status |=
3974 					(LINK_STATUS_TX_FLOW_CONTROL_ENABLED |
3975 					 LINK_STATUS_RX_FLOW_CONTROL_ENABLED);
3976 		}
3977 
3978 		bnx2x_emac_enable(params, vars, 0);
3979 		bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
3980 		/* disable drain */
3981 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
3982 				    + params->port*4, 0);
3983 
3984 		/* update shared memory */
3985 		bnx2x_update_mng(params, vars->link_status);
3986 
3987 		return 0;
3988 
3989 	} else
3990 	if (CHIP_REV_IS_EMUL(bp)) {
3991 
3992 		vars->link_up = 1;
3993 		vars->line_speed = SPEED_10000;
3994 		vars->duplex = DUPLEX_FULL;
3995 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
3996 		vars->link_status = (LINK_STATUS_LINK_UP | LINK_10GTFD);
3997 
3998 		bnx2x_bmac_enable(params, vars, 0);
3999 
4000 		bnx2x_pbf_update(params, vars->flow_ctrl, vars->line_speed);
4001 		/* Disable drain */
4002 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE
4003 				    + params->port*4, 0);
4004 
4005 		/* update shared memory */
4006 		bnx2x_update_mng(params, vars->link_status);
4007 
4008 		return 0;
4009 
4010 	} else
4011 	if (params->loopback_mode == LOOPBACK_BMAC) {
4012 		vars->link_up = 1;
4013 		vars->line_speed = SPEED_10000;
4014 		vars->duplex = DUPLEX_FULL;
4015 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4016 		vars->mac_type = MAC_TYPE_BMAC;
4017 
4018 		vars->phy_flags = PHY_XGXS_FLAG;
4019 
4020 		bnx2x_phy_deassert(params, vars->phy_flags);
4021 		/* set bmac loopback */
4022 		bnx2x_bmac_enable(params, vars, 1);
4023 
4024 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4025 		    params->port*4, 0);
4026 	} else if (params->loopback_mode == LOOPBACK_EMAC) {
4027 		vars->link_up = 1;
4028 		vars->line_speed = SPEED_1000;
4029 		vars->duplex = DUPLEX_FULL;
4030 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4031 		vars->mac_type = MAC_TYPE_EMAC;
4032 
4033 		vars->phy_flags = PHY_XGXS_FLAG;
4034 
4035 		bnx2x_phy_deassert(params, vars->phy_flags);
4036 		/* set bmac loopback */
4037 		bnx2x_emac_enable(params, vars, 1);
4038 		bnx2x_emac_program(params, vars->line_speed,
4039 					      vars->duplex);
4040 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4041 		    params->port*4, 0);
4042 	} else if ((params->loopback_mode == LOOPBACK_XGXS_10) ||
4043 		  (params->loopback_mode == LOOPBACK_EXT_PHY)) {
4044 		vars->link_up = 1;
4045 		vars->line_speed = SPEED_10000;
4046 		vars->duplex = DUPLEX_FULL;
4047 		vars->flow_ctrl = BNX2X_FLOW_CTRL_NONE;
4048 
4049 		vars->phy_flags = PHY_XGXS_FLAG;
4050 
4051 		val = REG_RD(bp,
4052 				 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4053 				 params->port*0x18);
4054 		params->phy_addr = (u8)val;
4055 
4056 		bnx2x_phy_deassert(params, vars->phy_flags);
4057 		bnx2x_link_initialize(params, vars);
4058 
4059 		vars->mac_type = MAC_TYPE_BMAC;
4060 
4061 		bnx2x_bmac_enable(params, vars, 0);
4062 
4063 		if (params->loopback_mode == LOOPBACK_XGXS_10) {
4064 			/* set 10G XGXS loopback */
4065 			bnx2x_set_xgxs_loopback(params, vars, 1);
4066 		} else {
4067 			/* set external phy loopback */
4068 			bnx2x_ext_phy_loopback(params);
4069 		}
4070 		REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE +
4071 			    params->port*4, 0);
4072 	} else
4073 	/* No loopback */
4074 	{
4075 
4076 		bnx2x_phy_deassert(params, vars->phy_flags);
4077 		switch (params->switch_cfg) {
4078 		case SWITCH_CFG_1G:
4079 			vars->phy_flags |= PHY_SERDES_FLAG;
4080 			if ((params->ext_phy_config &
4081 			     PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK) ==
4082 			     PORT_HW_CFG_SERDES_EXT_PHY_TYPE_BCM5482) {
4083 				vars->phy_flags |=
4084 					PHY_SGMII_FLAG;
4085 			}
4086 
4087 			val = REG_RD(bp,
4088 					 NIG_REG_SERDES0_CTRL_PHY_ADDR+
4089 					 params->port*0x10);
4090 
4091 			params->phy_addr = (u8)val;
4092 
4093 			break;
4094 		case SWITCH_CFG_10G:
4095 			vars->phy_flags |= PHY_XGXS_FLAG;
4096 			val = REG_RD(bp,
4097 				 NIG_REG_XGXS0_CTRL_PHY_ADDR+
4098 				 params->port*0x18);
4099 			params->phy_addr = (u8)val;
4100 
4101 			break;
4102 		default:
4103 			DP(NETIF_MSG_LINK, "Invalid switch_cfg\n");
4104 			return -EINVAL;
4105 			break;
4106 		}
4107 
4108 		bnx2x_link_initialize(params, vars);
4109 		msleep(30);
4110 		bnx2x_link_int_enable(params);
4111 	}
4112 	return 0;
4113 }
4114 
bnx2x_link_reset(struct link_params * params,struct link_vars * vars)4115 u8 bnx2x_link_reset(struct link_params *params, struct link_vars *vars)
4116 {
4117 
4118 	struct bnx2x *bp = params->bp;
4119 	u32 ext_phy_config = params->ext_phy_config;
4120 	u16 hw_led_mode = params->hw_led_mode;
4121 	u32 chip_id = params->chip_id;
4122 	u8 port = params->port;
4123 	u32 ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4124 	/* disable attentions */
4125 
4126 	vars->link_status = 0;
4127 	bnx2x_update_mng(params, vars->link_status);
4128 	bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4129 		     (NIG_MASK_XGXS0_LINK_STATUS |
4130 		      NIG_MASK_XGXS0_LINK10G |
4131 		      NIG_MASK_SERDES0_LINK_STATUS |
4132 		      NIG_MASK_MI_INT));
4133 
4134 	/* activate nig drain */
4135 	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4136 
4137 	/* disable nig egress interface */
4138 	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4139 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4140 
4141 	/* Stop BigMac rx */
4142 	bnx2x_bmac_rx_disable(bp, port);
4143 
4144 	/* disable emac */
4145 	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4146 
4147 	msleep(10);
4148 	/* The PHY reset is controled by GPIO 1
4149 	 * Hold it as vars low
4150 	 */
4151 	 /* clear link led */
4152 	bnx2x_set_led(bp, port, LED_MODE_OFF, 0, hw_led_mode, chip_id);
4153 	if (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT) {
4154 		if ((ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072) &&
4155 		    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073)) {
4156 			/* HW reset */
4157 
4158 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
4159 					  MISC_REGISTERS_GPIO_OUTPUT_LOW,
4160 					  port);
4161 
4162 			bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4163 					  MISC_REGISTERS_GPIO_OUTPUT_LOW,
4164 					  port);
4165 
4166 			DP(NETIF_MSG_LINK, "reset external PHY\n");
4167 		} else if (ext_phy_type ==
4168 			   PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073) {
4169 				DP(NETIF_MSG_LINK, "Setting 8073 port %d into "
4170 					 "low power mode\n",
4171 					 port);
4172 				bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4173 					MISC_REGISTERS_GPIO_OUTPUT_LOW,
4174 						  port);
4175 		}
4176 	}
4177 	/* reset the SerDes/XGXS */
4178 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_3_CLEAR,
4179 	       (0x1ff << (port*16)));
4180 
4181 	/* reset BigMac */
4182 	REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
4183 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4184 
4185 	/* disable nig ingress interface */
4186 	REG_WR(bp, NIG_REG_BMAC0_IN_EN + port*4, 0);
4187 	REG_WR(bp, NIG_REG_EMAC0_IN_EN + port*4, 0);
4188 	REG_WR(bp, NIG_REG_BMAC0_OUT_EN + port*4, 0);
4189 	REG_WR(bp, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0);
4190 	vars->link_up = 0;
4191 	return 0;
4192 }
4193 
bnx2x_update_link_down(struct link_params * params,struct link_vars * vars)4194 static u8 bnx2x_update_link_down(struct link_params *params,
4195 			       struct link_vars *vars)
4196 {
4197 	struct bnx2x *bp = params->bp;
4198 	u8 port = params->port;
4199 	DP(NETIF_MSG_LINK, "Port %x: Link is down\n", port);
4200 	bnx2x_set_led(bp, port, LED_MODE_OFF,
4201 		    0, params->hw_led_mode,
4202 		    params->chip_id);
4203 
4204 	/* indicate no mac active */
4205 	vars->mac_type = MAC_TYPE_NONE;
4206 
4207 	/* update shared memory */
4208 	vars->link_status = 0;
4209 	vars->line_speed = 0;
4210 	bnx2x_update_mng(params, vars->link_status);
4211 
4212 	/* activate nig drain */
4213 	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 1);
4214 
4215 	/* disable emac */
4216 	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4217 
4218 	msleep(10);
4219 
4220 	/* reset BigMac */
4221 	bnx2x_bmac_rx_disable(bp, params->port);
4222 	REG_WR(bp, GRCBASE_MISC +
4223 		   MISC_REGISTERS_RESET_REG_2_CLEAR,
4224 		   (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
4225 	return 0;
4226 }
4227 
bnx2x_update_link_up(struct link_params * params,struct link_vars * vars,u8 link_10g,u32 gp_status)4228 static u8 bnx2x_update_link_up(struct link_params *params,
4229 			     struct link_vars *vars,
4230 			     u8 link_10g, u32 gp_status)
4231 {
4232 	struct bnx2x *bp = params->bp;
4233 	u8 port = params->port;
4234 	u8 rc = 0;
4235 	vars->link_status |= LINK_STATUS_LINK_UP;
4236 	if (link_10g) {
4237 		bnx2x_bmac_enable(params, vars, 0);
4238 		bnx2x_set_led(bp, port, LED_MODE_OPER,
4239 			    SPEED_10000, params->hw_led_mode,
4240 			    params->chip_id);
4241 
4242 	} else {
4243 		bnx2x_emac_enable(params, vars, 0);
4244 		rc = bnx2x_emac_program(params, vars->line_speed,
4245 				      vars->duplex);
4246 
4247 		/* AN complete? */
4248 		if (gp_status & MDIO_AN_CL73_OR_37_COMPLETE) {
4249 			if (!(vars->phy_flags &
4250 			      PHY_SGMII_FLAG))
4251 				bnx2x_set_sgmii_tx_driver(params);
4252 		}
4253 	}
4254 
4255 	/* PBF - link up */
4256 	rc |= bnx2x_pbf_update(params, vars->flow_ctrl,
4257 			      vars->line_speed);
4258 
4259 	/* disable drain */
4260 	REG_WR(bp, NIG_REG_EGRESS_DRAIN0_MODE + port*4, 0);
4261 
4262 	/* update shared memory */
4263 	bnx2x_update_mng(params, vars->link_status);
4264 	msleep(20);
4265 	return rc;
4266 }
4267 /* This function should called upon link interrupt */
4268 /* In case vars->link_up, driver needs to
4269 	1. Update the pbf
4270 	2. Disable drain
4271 	3. Update the shared memory
4272 	4. Indicate link up
4273 	5. Set LEDs
4274    Otherwise,
4275 	1. Update shared memory
4276 	2. Reset BigMac
4277 	3. Report link down
4278 	4. Unset LEDs
4279 */
bnx2x_link_update(struct link_params * params,struct link_vars * vars)4280 u8 bnx2x_link_update(struct link_params *params, struct link_vars *vars)
4281 {
4282 	struct bnx2x *bp = params->bp;
4283 	u8 port = params->port;
4284 	u16 gp_status;
4285 	u8 link_10g;
4286 	u8 ext_phy_link_up, rc = 0;
4287 	u32 ext_phy_type;
4288 
4289 	DP(NETIF_MSG_LINK, "port %x, XGXS?%x, int_status 0x%x\n",
4290 	 port,
4291 	(vars->phy_flags & PHY_XGXS_FLAG),
4292 	 REG_RD(bp, NIG_REG_STATUS_INTERRUPT_PORT0 + port*4));
4293 
4294 	DP(NETIF_MSG_LINK, "int_mask 0x%x MI_INT %x, SERDES_LINK %x\n",
4295 	REG_RD(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4),
4296 	REG_RD(bp, NIG_REG_EMAC0_STATUS_MISC_MI_INT + port*0x18),
4297 	REG_RD(bp, NIG_REG_SERDES0_STATUS_LINK_STATUS + port*0x3c));
4298 
4299 	DP(NETIF_MSG_LINK, " 10G %x, XGXS_LINK %x\n",
4300 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK10G + port*0x68),
4301 	  REG_RD(bp, NIG_REG_XGXS0_STATUS_LINK_STATUS + port*0x68));
4302 
4303 	/* disable emac */
4304 	REG_WR(bp, NIG_REG_NIG_EMAC0_EN + port*4, 0);
4305 
4306 	ext_phy_type = XGXS_EXT_PHY_TYPE(params->ext_phy_config);
4307 
4308 	/* Check external link change only for non-direct */
4309 	ext_phy_link_up = bnx2x_ext_phy_is_link_up(params, vars);
4310 
4311 	/* Read gp_status */
4312 	CL45_RD_OVER_CL22(bp, port, params->phy_addr,
4313 			      MDIO_REG_BANK_GP_STATUS,
4314 			      MDIO_GP_STATUS_TOP_AN_STATUS1,
4315 			      &gp_status);
4316 
4317 	rc = bnx2x_link_settings_status(params, vars, gp_status);
4318 	if (rc != 0)
4319 		return rc;
4320 
4321 	/* anything 10 and over uses the bmac */
4322 	link_10g = ((vars->line_speed == SPEED_10000) ||
4323 		    (vars->line_speed == SPEED_12000) ||
4324 		    (vars->line_speed == SPEED_12500) ||
4325 		    (vars->line_speed == SPEED_13000) ||
4326 		    (vars->line_speed == SPEED_15000) ||
4327 		    (vars->line_speed == SPEED_16000));
4328 
4329 	bnx2x_link_int_ack(params, vars, link_10g);
4330 
4331 	/* In case external phy link is up, and internal link is down
4332 	( not initialized yet probably after link initialization, it needs
4333 	to be initialized.
4334 	Note that after link down-up as result of cable plug,
4335 	the xgxs link would probably become up again without the need to
4336 	initialize it*/
4337 
4338 	if ((ext_phy_type != PORT_HW_CFG_SERDES_EXT_PHY_TYPE_DIRECT) &&
4339 	    (ext_phy_type != PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705) &&
4340 	    (ext_phy_link_up && !vars->phy_link_up))
4341 		bnx2x_init_internal_phy(params, vars);
4342 
4343 	/* link is up only if both local phy and external phy are up */
4344 	vars->link_up = (ext_phy_link_up && vars->phy_link_up);
4345 
4346 	if (vars->link_up)
4347 		rc = bnx2x_update_link_up(params, vars, link_10g, gp_status);
4348 	else
4349 		rc = bnx2x_update_link_down(params, vars);
4350 
4351 	return rc;
4352 }
4353 
bnx2x_8073_common_init_phy(struct bnx2x * bp,u32 shmem_base)4354 static u8 bnx2x_8073_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4355 {
4356 	u8 ext_phy_addr[PORT_MAX];
4357 	u16 val;
4358 	s8 port;
4359 
4360 	/* PART1 - Reset both phys */
4361 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4362 		/* Extract the ext phy address for the port */
4363 		u32 ext_phy_config = REG_RD(bp, shmem_base +
4364 					offsetof(struct shmem_region,
4365 		   dev_info.port_hw_config[port].external_phy_config));
4366 
4367 		/* disable attentions */
4368 		bnx2x_bits_dis(bp, NIG_REG_MASK_INTERRUPT_PORT0 + port*4,
4369 			     (NIG_MASK_XGXS0_LINK_STATUS |
4370 			      NIG_MASK_XGXS0_LINK10G |
4371 			      NIG_MASK_SERDES0_LINK_STATUS |
4372 			      NIG_MASK_MI_INT));
4373 
4374 		ext_phy_addr[port] =
4375 			((ext_phy_config &
4376 			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4377 			      PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4378 
4379 		/* Need to take the phy out of low power mode in order
4380 			to write to access its registers */
4381 		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4382 				  MISC_REGISTERS_GPIO_OUTPUT_HIGH, port);
4383 
4384 		/* Reset the phy */
4385 		bnx2x_cl45_write(bp, port,
4386 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4387 			       ext_phy_addr[port],
4388 			       MDIO_PMA_DEVAD,
4389 			       MDIO_PMA_REG_CTRL,
4390 			       1<<15);
4391 	}
4392 
4393 	/* Add delay of 150ms after reset */
4394 	msleep(150);
4395 
4396 	/* PART2 - Download firmware to both phys */
4397 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4398 		u16 fw_ver1;
4399 
4400 		bnx2x_bcm8073_external_rom_boot(bp, port,
4401 						      ext_phy_addr[port]);
4402 
4403 		bnx2x_cl45_read(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4404 			      ext_phy_addr[port],
4405 			      MDIO_PMA_DEVAD,
4406 			      MDIO_PMA_REG_ROM_VER1, &fw_ver1);
4407 		if (fw_ver1 == 0 || fw_ver1 == 0x4321) {
4408 			DP(NETIF_MSG_LINK,
4409 				 "bnx2x_8073_common_init_phy port %x:"
4410 				 "Download failed. fw version = 0x%x\n",
4411 				 port, fw_ver1);
4412 			return -EINVAL;
4413 		}
4414 
4415 		/* Only set bit 10 = 1 (Tx power down) */
4416 		bnx2x_cl45_read(bp, port,
4417 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4418 			      ext_phy_addr[port],
4419 			      MDIO_PMA_DEVAD,
4420 			      MDIO_PMA_REG_TX_POWER_DOWN, &val);
4421 
4422 		/* Phase1 of TX_POWER_DOWN reset */
4423 		bnx2x_cl45_write(bp, port,
4424 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4425 			       ext_phy_addr[port],
4426 			       MDIO_PMA_DEVAD,
4427 			       MDIO_PMA_REG_TX_POWER_DOWN,
4428 			       (val | 1<<10));
4429 	}
4430 
4431 	/* Toggle Transmitter: Power down and then up with 600ms
4432 	   delay between */
4433 	msleep(600);
4434 
4435 	/* PART3 - complete TX_POWER_DOWN process, and set GPIO2 back to low */
4436 	for (port = PORT_MAX - 1; port >= PORT_0; port--) {
4437 		/* Phase2 of POWER_DOWN_RESET*/
4438 		/* Release bit 10 (Release Tx power down) */
4439 		bnx2x_cl45_read(bp, port,
4440 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4441 			      ext_phy_addr[port],
4442 			      MDIO_PMA_DEVAD,
4443 			      MDIO_PMA_REG_TX_POWER_DOWN, &val);
4444 
4445 		bnx2x_cl45_write(bp, port,
4446 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4447 			       ext_phy_addr[port],
4448 			       MDIO_PMA_DEVAD,
4449 			       MDIO_PMA_REG_TX_POWER_DOWN, (val & (~(1<<10))));
4450 		msleep(15);
4451 
4452 		/* Read modify write the SPI-ROM version select register */
4453 		bnx2x_cl45_read(bp, port,
4454 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4455 			      ext_phy_addr[port],
4456 			      MDIO_PMA_DEVAD,
4457 			      MDIO_PMA_REG_EDC_FFE_MAIN, &val);
4458 		bnx2x_cl45_write(bp, port,
4459 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073,
4460 			      ext_phy_addr[port],
4461 			      MDIO_PMA_DEVAD,
4462 			      MDIO_PMA_REG_EDC_FFE_MAIN, (val | (1<<12)));
4463 
4464 		/* set GPIO2 back to LOW */
4465 		bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
4466 				  MISC_REGISTERS_GPIO_OUTPUT_LOW, port);
4467 	}
4468 	return 0;
4469 
4470 }
4471 
bnx2x_common_init_phy(struct bnx2x * bp,u32 shmem_base)4472 u8 bnx2x_common_init_phy(struct bnx2x *bp, u32 shmem_base)
4473 {
4474 	u8 rc = 0;
4475 	u32 ext_phy_type;
4476 
4477 	DP(NETIF_MSG_LINK, "bnx2x_common_init_phy\n");
4478 
4479 	/* Read the ext_phy_type for arbitrary port(0) */
4480 	ext_phy_type = XGXS_EXT_PHY_TYPE(
4481 			REG_RD(bp, shmem_base +
4482 			   offsetof(struct shmem_region,
4483 			     dev_info.port_hw_config[0].external_phy_config)));
4484 
4485 	switch (ext_phy_type) {
4486 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4487 	{
4488 		rc = bnx2x_8073_common_init_phy(bp, shmem_base);
4489 		break;
4490 	}
4491 	default:
4492 		DP(NETIF_MSG_LINK,
4493 			 "bnx2x_common_init_phy: ext_phy 0x%x not required\n",
4494 			 ext_phy_type);
4495 		break;
4496 	}
4497 
4498 	return rc;
4499 }
4500 
4501 
4502 
bnx2x_sfx7101_sp_sw_reset(struct bnx2x * bp,u8 port,u8 phy_addr)4503 static void bnx2x_sfx7101_sp_sw_reset(struct bnx2x *bp, u8 port, u8 phy_addr)
4504 {
4505 	u16 val, cnt;
4506 
4507 	bnx2x_cl45_read(bp, port,
4508 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4509 		      phy_addr,
4510 		      MDIO_PMA_DEVAD,
4511 		      MDIO_PMA_REG_7101_RESET, &val);
4512 
4513 	for (cnt = 0; cnt < 10; cnt++) {
4514 		msleep(50);
4515 		/* Writes a self-clearing reset */
4516 		bnx2x_cl45_write(bp, port,
4517 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4518 			       phy_addr,
4519 			       MDIO_PMA_DEVAD,
4520 			       MDIO_PMA_REG_7101_RESET,
4521 			       (val | (1<<15)));
4522 		/* Wait for clear */
4523 		bnx2x_cl45_read(bp, port,
4524 			      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4525 			      phy_addr,
4526 			      MDIO_PMA_DEVAD,
4527 			      MDIO_PMA_REG_7101_RESET, &val);
4528 
4529 		if ((val & (1<<15)) == 0)
4530 			break;
4531 	}
4532 }
4533 #define RESERVED_SIZE 256
4534 /* max application is 160K bytes - data at end of RAM */
4535 #define MAX_APP_SIZE (160*1024 - RESERVED_SIZE)
4536 
4537 /* Header is 14 bytes */
4538 #define HEADER_SIZE 14
4539 #define DATA_OFFSET HEADER_SIZE
4540 
4541 #define SPI_START_TRANSFER(bp, port, ext_phy_addr) \
4542 	bnx2x_cl45_write(bp, port, PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101, \
4543 			ext_phy_addr, \
4544 			MDIO_PCS_DEVAD, \
4545 			MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 1)
4546 
4547 /* Programs an image to DSP's flash via the SPI port*/
bnx2x_sfx7101_flash_download(struct bnx2x * bp,u8 port,u8 ext_phy_addr,char data[],u32 size)4548 static u8 bnx2x_sfx7101_flash_download(struct bnx2x *bp, u8 port,
4549 				     u8 ext_phy_addr,
4550 				     char data[], u32 size)
4551 {
4552 	const u16 num_trans = size/4; /* 4 bytes can be sent at a time */
4553 	/* Doesn't include last trans!*/
4554 	const u16 last_trans_size = size%4; /* Num bytes on last trans */
4555 	u16 trans_cnt, byte_cnt;
4556 	u32 data_index;
4557 	u16 tmp;
4558 	u16 code_started = 0;
4559 	u16 image_revision1, image_revision2;
4560 	u16 cnt;
4561 
4562 	DP(NETIF_MSG_LINK, "bnx2x_sfx7101_flash_download file_size=%d\n", size);
4563 	/* Going to flash*/
4564 	if ((size-HEADER_SIZE) > MAX_APP_SIZE) {
4565 		/* This very often will be the case, because the image is built
4566 		with 160Kbytes size whereas the total image size must actually
4567 		be 160Kbytes-RESERVED_SIZE */
4568 		DP(NETIF_MSG_LINK, "Warning, file size was %d bytes "
4569 			 "truncated to %d bytes\n", size, MAX_APP_SIZE);
4570 		size = MAX_APP_SIZE+HEADER_SIZE;
4571 	}
4572 	DP(NETIF_MSG_LINK, "File version is %c%c\n", data[0x14e], data[0x14f]);
4573 	DP(NETIF_MSG_LINK, "  	      %c%c\n", data[0x150], data[0x151]);
4574 	/* Put the DSP in download mode by setting FLASH_CFG[2] to 1
4575 	   and issuing a reset.*/
4576 
4577 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4578 			  MISC_REGISTERS_GPIO_HIGH, port);
4579 
4580 	bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4581 
4582 	/* wait 0.5 sec */
4583 	for (cnt = 0; cnt < 100; cnt++)
4584 		msleep(5);
4585 
4586 	/* Make sure we can access the DSP
4587 	   And it's in the correct mode (waiting for download) */
4588 
4589 	bnx2x_cl45_read(bp, port,
4590 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4591 		      ext_phy_addr,
4592 		      MDIO_PCS_DEVAD,
4593 		      MDIO_PCS_REG_7101_DSP_ACCESS, &tmp);
4594 
4595 	if (tmp != 0x000A) {
4596 		DP(NETIF_MSG_LINK, "DSP is not in waiting on download mode. "
4597 			 "Expected 0x000A, read 0x%04X\n", tmp);
4598 		DP(NETIF_MSG_LINK, "Download failed\n");
4599 		return -EINVAL;
4600 	}
4601 
4602 	/* Mux the SPI interface away from the internal processor */
4603 	bnx2x_cl45_write(bp, port,
4604 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4605 		       ext_phy_addr,
4606 		       MDIO_PCS_DEVAD,
4607 		       MDIO_PCS_REG_7101_SPI_MUX, 1);
4608 
4609 	/* Reset the SPI port */
4610 	bnx2x_cl45_write(bp, port,
4611 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4612 		       ext_phy_addr,
4613 		       MDIO_PCS_DEVAD,
4614 		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4615 	bnx2x_cl45_write(bp, port,
4616 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4617 		       ext_phy_addr,
4618 		       MDIO_PCS_DEVAD,
4619 		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR,
4620 		       (1<<MDIO_PCS_REG_7101_SPI_RESET_BIT));
4621 	bnx2x_cl45_write(bp, port,
4622 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4623 		       ext_phy_addr,
4624 		       MDIO_PCS_DEVAD,
4625 		       MDIO_PCS_REG_7101_SPI_CTRL_ADDR, 0);
4626 
4627 	/* Erase the flash */
4628 	bnx2x_cl45_write(bp, port,
4629 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4630 		       ext_phy_addr,
4631 		       MDIO_PCS_DEVAD,
4632 		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4633 		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4634 
4635 	bnx2x_cl45_write(bp, port,
4636 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4637 		       ext_phy_addr,
4638 		       MDIO_PCS_DEVAD,
4639 		       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4640 		       1);
4641 
4642 	SPI_START_TRANSFER(bp, port, ext_phy_addr);
4643 	bnx2x_cl45_write(bp, port,
4644 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4645 		       ext_phy_addr,
4646 		       MDIO_PCS_DEVAD,
4647 		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4648 		       MDIO_PCS_REG_7101_SPI_FIFO_ADDR_BULK_ERASE_CMD);
4649 
4650 	bnx2x_cl45_write(bp, port,
4651 		       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4652 		       ext_phy_addr,
4653 		       MDIO_PCS_DEVAD,
4654 		       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4655 		       1);
4656 	SPI_START_TRANSFER(bp, port, ext_phy_addr);
4657 
4658 	/* Wait 10 seconds, the maximum time for the erase to complete */
4659 	DP(NETIF_MSG_LINK, "Erasing flash, this takes 10 seconds...\n");
4660 	for (cnt = 0; cnt < 1000; cnt++)
4661 		msleep(10);
4662 
4663 	DP(NETIF_MSG_LINK, "Downloading flash, please wait...\n");
4664 	data_index = 0;
4665 	for (trans_cnt = 0; trans_cnt < num_trans; trans_cnt++) {
4666 		bnx2x_cl45_write(bp, port,
4667 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4668 			     ext_phy_addr,
4669 			     MDIO_PCS_DEVAD,
4670 			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4671 			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4672 
4673 		bnx2x_cl45_write(bp, port,
4674 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4675 			       ext_phy_addr,
4676 			       MDIO_PCS_DEVAD,
4677 			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4678 			       1);
4679 		SPI_START_TRANSFER(bp, port, ext_phy_addr);
4680 
4681 		bnx2x_cl45_write(bp, port,
4682 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4683 			       ext_phy_addr,
4684 			       MDIO_PCS_DEVAD,
4685 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4686 			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4687 
4688 		/* Bits 23-16 of address */
4689 		bnx2x_cl45_write(bp, port,
4690 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4691 			       ext_phy_addr,
4692 			       MDIO_PCS_DEVAD,
4693 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4694 			       (data_index>>16));
4695 		/* Bits 15-8 of address */
4696 		bnx2x_cl45_write(bp, port,
4697 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4698 			       ext_phy_addr,
4699 			       MDIO_PCS_DEVAD,
4700 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4701 			       (data_index>>8));
4702 
4703 		/* Bits 7-0 of address */
4704 		bnx2x_cl45_write(bp, port,
4705 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4706 			       ext_phy_addr,
4707 			       MDIO_PCS_DEVAD,
4708 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4709 			       ((u16)data_index));
4710 
4711 		byte_cnt = 0;
4712 		while (byte_cnt < 4 && data_index < size) {
4713 			bnx2x_cl45_write(bp, port,
4714 				       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4715 				       ext_phy_addr,
4716 			       MDIO_PCS_DEVAD,
4717 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4718 			       data[data_index++]);
4719 			byte_cnt++;
4720 		}
4721 
4722 		bnx2x_cl45_write(bp, port,
4723 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4724 			       ext_phy_addr,
4725 			       MDIO_PCS_DEVAD,
4726 			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4727 			       byte_cnt+4);
4728 
4729 		SPI_START_TRANSFER(bp, port, ext_phy_addr);
4730 		msleep(5); /* Wait 5 ms minimum between transs */
4731 
4732 		/* Let the user know something's going on.*/
4733 		/* a pacifier ever 4K */
4734 		if ((data_index % 1023) == 0)
4735 			DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4736 	}
4737 
4738 	DP(NETIF_MSG_LINK, "\n");
4739 	/* Transfer the last block if there is data remaining */
4740 	if (last_trans_size) {
4741 		bnx2x_cl45_write(bp, port,
4742 			PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4743 			ext_phy_addr,
4744 			MDIO_PCS_DEVAD,
4745 			MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4746 			MDIO_PCS_REG_7101_SPI_FIFO_ADDR_WRITE_ENABLE_CMD);
4747 
4748 		bnx2x_cl45_write(bp, port,
4749 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4750 			       ext_phy_addr,
4751 			       MDIO_PCS_DEVAD,
4752 			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4753 			       1);
4754 
4755 		SPI_START_TRANSFER(bp, port, ext_phy_addr);
4756 
4757 		bnx2x_cl45_write(bp, port,
4758 			     PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4759 			     ext_phy_addr,
4760 			     MDIO_PCS_DEVAD,
4761 			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4762 			     MDIO_PCS_REG_7101_SPI_FIFO_ADDR_PAGE_PROGRAM_CMD);
4763 
4764 		/* Bits 23-16 of address */
4765 		bnx2x_cl45_write(bp, port,
4766 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4767 			       ext_phy_addr,
4768 			       MDIO_PCS_DEVAD,
4769 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4770 			       (data_index>>16));
4771 		/* Bits 15-8 of address */
4772 		bnx2x_cl45_write(bp, port,
4773 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4774 			       ext_phy_addr,
4775 			       MDIO_PCS_DEVAD,
4776 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4777 			       (data_index>>8));
4778 
4779 		/* Bits 7-0 of address */
4780 		bnx2x_cl45_write(bp, port,
4781 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4782 			       ext_phy_addr,
4783 			       MDIO_PCS_DEVAD,
4784 			       MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4785 			       ((u16)data_index));
4786 
4787 		byte_cnt = 0;
4788 		while (byte_cnt < last_trans_size && data_index < size) {
4789 			/* Bits 7-0 of address */
4790 			bnx2x_cl45_write(bp, port,
4791 				PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4792 				ext_phy_addr,
4793 				MDIO_PCS_DEVAD,
4794 				MDIO_PCS_REG_7101_SPI_FIFO_ADDR,
4795 				data[data_index++]);
4796 			byte_cnt++;
4797 		}
4798 
4799 		bnx2x_cl45_write(bp, port,
4800 			       PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4801 			       ext_phy_addr,
4802 			       MDIO_PCS_DEVAD,
4803 			       MDIO_PCS_REG_7101_SPI_BYTES_TO_TRANSFER_ADDR,
4804 			       byte_cnt+4);
4805 
4806 		SPI_START_TRANSFER(bp, port, ext_phy_addr);
4807 	}
4808 
4809 	/* DSP Remove Download Mode */
4810 	bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
4811 			  MISC_REGISTERS_GPIO_LOW, port);
4812 
4813 	bnx2x_sfx7101_sp_sw_reset(bp, port, ext_phy_addr);
4814 
4815 	/* wait 0.5 sec to allow it to run */
4816 	for (cnt = 0; cnt < 100; cnt++)
4817 		msleep(5);
4818 
4819 	bnx2x_hw_reset(bp, port);
4820 
4821 	for (cnt = 0; cnt < 100; cnt++)
4822 		msleep(5);
4823 
4824 	/* Check that the code is started. In case the download
4825 	checksum failed, the code won't be started. */
4826 	bnx2x_cl45_read(bp, port,
4827 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4828 		      ext_phy_addr,
4829 		      MDIO_PCS_DEVAD,
4830 		      MDIO_PCS_REG_7101_DSP_ACCESS,
4831 		      &tmp);
4832 
4833 	code_started = (tmp & (1<<4));
4834 	if (!code_started) {
4835 		DP(NETIF_MSG_LINK, "Download failed. Please check file.\n");
4836 		return -EINVAL;
4837 	}
4838 
4839 	/* Verify that the file revision is now equal to the image
4840 	revision within the DSP */
4841 	bnx2x_cl45_read(bp, port,
4842 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4843 		      ext_phy_addr,
4844 		      MDIO_PMA_DEVAD,
4845 		      MDIO_PMA_REG_7101_VER1,
4846 		      &image_revision1);
4847 
4848 	bnx2x_cl45_read(bp, port,
4849 		      PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101,
4850 		      ext_phy_addr,
4851 		      MDIO_PMA_DEVAD,
4852 		      MDIO_PMA_REG_7101_VER2,
4853 		      &image_revision2);
4854 
4855 	if (data[0x14e] != (image_revision2&0xFF) ||
4856 	    data[0x14f] != ((image_revision2&0xFF00)>>8) ||
4857 	    data[0x150] != (image_revision1&0xFF) ||
4858 	    data[0x151] != ((image_revision1&0xFF00)>>8)) {
4859 		DP(NETIF_MSG_LINK, "Download failed.\n");
4860 		return -EINVAL;
4861 	}
4862 	DP(NETIF_MSG_LINK, "Download %d%%\n", data_index/size);
4863 	return 0;
4864 }
4865 
bnx2x_flash_download(struct bnx2x * bp,u8 port,u32 ext_phy_config,u8 driver_loaded,char data[],u32 size)4866 u8 bnx2x_flash_download(struct bnx2x *bp, u8 port, u32 ext_phy_config,
4867 		      u8 driver_loaded, char data[], u32 size)
4868 {
4869 	u8 rc = 0;
4870 	u32 ext_phy_type;
4871 	u8 ext_phy_addr;
4872 	ext_phy_addr = ((ext_phy_config &
4873 			PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >>
4874 			PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT);
4875 
4876 	ext_phy_type = XGXS_EXT_PHY_TYPE(ext_phy_config);
4877 
4878 	switch (ext_phy_type) {
4879 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8072:
4880 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8073:
4881 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8705:
4882 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8706:
4883 		DP(NETIF_MSG_LINK,
4884 			"Flash download not supported for this ext phy\n");
4885 		rc = -EINVAL;
4886 		break;
4887 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_SFX7101:
4888 		/* Take ext phy out of reset */
4889 		if (!driver_loaded)
4890 			bnx2x_turn_on_ef(bp, port, ext_phy_addr, ext_phy_type);
4891 		rc = bnx2x_sfx7101_flash_download(bp, port, ext_phy_addr,
4892 						data, size);
4893 		if (!driver_loaded)
4894 			bnx2x_turn_off_sf(bp, port);
4895 		break;
4896 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_DIRECT:
4897 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_FAILURE:
4898 	case PORT_HW_CFG_XGXS_EXT_PHY_TYPE_NOT_CONN:
4899 	default:
4900 		DP(NETIF_MSG_LINK, "Invalid ext phy type\n");
4901 		rc = -EINVAL;
4902 		break;
4903 	}
4904 	return rc;
4905 }
4906 
4907