1 #ifdef __LINUX
2 #include <linux/kernel.h>
3 #include <linux/types.h>
4 #include <asm/byteorder.h>
5 #endif
6 #ifdef USER_LINUX
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <sys/types.h>
10 #include <sys/socket.h>
11 #include <netinet/in.h>
12 #include <arpa/inet.h>
13 #include <sys/ioctl.h>
14 #include <net/if.h>
15 #include <linux/sockios.h>
16 #include <string.h>
17 #include <malloc.h>
18 #endif
19 #ifdef __FreeBSD__
20 #include <sys/types.h>
21 #endif
22 #include "bcmtype.h"
23 #ifdef EDEBUG
24 #include "edebug_types.h"
25 #endif
26 #include "clc.h"
27 #include "grc_addr.h"
28 #include "bigmac_addresses.h"
29 #include "emac_reg_driver.h"
30 #include "misc_bits.h"
31 #include "57712_reg.h"
32 #include "clc_reg.h"
33 #include "dev_info.h"
34 #include "license.h"
35 #include "shmem.h"
36 #include "aeu_inputs.h"
37 
38 typedef elink_status_t (*read_sfp_module_eeprom_func_p)(struct elink_phy *phy,
39 					     struct elink_params *params,
40 					     u8 dev_addr, u16 addr, u8 byte_cnt,
41 					     u8 *o_buf, u8);
42 /********************************************************/
43 #define ELINK_ETH_HLEN			14
44 /* L2 header size + 2*VLANs (8 bytes) + LLC SNAP (8 bytes) */
45 #define ELINK_ETH_OVREHEAD			(ELINK_ETH_HLEN + 8 + 8)
46 #define ELINK_ETH_MIN_PACKET_SIZE		60
47 #define ELINK_ETH_MAX_PACKET_SIZE		1500
48 #define ELINK_ETH_MAX_JUMBO_PACKET_SIZE	9600
49 #define ELINK_MDIO_ACCESS_TIMEOUT		1000
50 #define WC_LANE_MAX			4
51 #define I2C_SWITCH_WIDTH		2
52 #define I2C_BSC0			0
53 #define I2C_BSC1			1
54 #define I2C_WA_RETRY_CNT		3
55 #define I2C_WA_PWR_ITER			(I2C_WA_RETRY_CNT - 1)
56 #define MCPR_IMC_COMMAND_READ_OP	1
57 #define MCPR_IMC_COMMAND_WRITE_OP	2
58 
59 /* LED Blink rate that will achieve ~15.9Hz */
60 #define LED_BLINK_RATE_VAL_E3		354
61 #define LED_BLINK_RATE_VAL_E1X_E2	480
62 /***********************************************************/
63 /*			  Macros			   */
64 /***********************************************************/
65 #define MSLEEP(cb, ms)			elink_cb_udelay(cb, 1000*ms)
66 #define USLEEP(cb, us)			elink_cb_udelay(cb, us)
67 #define REG_RD(cb, reg)			elink_cb_reg_read(cb, reg)
68 #define REG_WR(cb, reg, val)		elink_cb_reg_write(cb, reg, val)
69 #define EMAC_RD(cb, reg)		REG_RD(cb, emac_base + reg)
70 #define EMAC_WR(cb, reg, val)		REG_WR(cb, emac_base + reg, val)
71 #define REG_WR_DMAE(cb, offset, wb_data, len) \
72 	elink_cb_reg_wb_write(cb, offset, wb_data, len)
73 #define REG_RD_DMAE(cb, offset, wb_data, len) \
74 	elink_cb_reg_wb_read(cb, offset, wb_data, len)
75 #define PATH_ID(cb) elink_cb_path_id(cb)
76 
77 #define ELINK_SET_GPIO			elink_cb_gpio_write
78 #define ELINK_SET_MULT_GPIO		elink_cb_gpio_mult_write
79 #define ELINK_GET_GPIO			elink_cb_gpio_read
80 #define ELINK_SET_GPIO_INT		elink_cb_gpio_int_write
81 
82 #ifndef OFFSETOF
83 #define OFFSETOF(_s, _m)	((u32) ((u8 *)(&((_s *) 0)->_m) - \
84 					(u8 *)((u8 *) 0)))
85 #endif
86 
87 #define CHIP_REV_SHIFT              12
88 #define CHIP_REV_MASK               (0xF<<CHIP_REV_SHIFT)
89 #define CHIP_REV(_chip_id)          ((_chip_id) & CHIP_REV_MASK)
90 
91 #define CHIP_REV_Ax                 (0x0<<CHIP_REV_SHIFT)
92 #define CHIP_REV_Bx                 (0x1<<CHIP_REV_SHIFT)
93 #define CHIP_REV_IS_SLOW(_chip_id) \
94 		(CHIP_REV(_chip_id) > 0x00005000)
95 #define CHIP_REV_IS_FPGA(_chip_id) \
96 		(CHIP_REV_IS_SLOW(_chip_id)&& \
97 		(CHIP_REV(_chip_id) & 0x00001000))
98 #define CHIP_REV_IS_EMUL(_chip_id) \
99 		(CHIP_REV_IS_SLOW(_chip_id)&& \
100 		!(CHIP_REV(_chip_id) & 0x00001000))
101 
102 #define CHIP_NUM(_chip_id)	(_chip_id >> 16)
103 #define CHIP_NUM_57710		0x164e
104 #define CHIP_NUM_57711		0x164f
105 #define CHIP_NUM_57711E		0x1650
106 #define CHIP_NUM_57712		0x1662
107 #define CHIP_NUM_57712E		0x1663
108 #define CHIP_NUM_57713		0x1651
109 #define CHIP_NUM_57713E		0x1652
110 #define CHIP_NUM_57840_OBSOLETE 0x168d
111 #define CHIP_NUM_57840_4_10	0x16a1
112 #define CHIP_NUM_57840_2_20	0x16a2
113 #define CHIP_NUM_57810		0x168e
114 #define CHIP_NUM_57800		0x168a
115 #define CHIP_NUM_57811		0x163d
116 #define CHIP_NUM_57811_MF   0x163e
117 #define CHIP_IS_E1(_chip_id)	(CHIP_NUM(_chip_id) == \
118 	CHIP_NUM_57710)
119 #define CHIP_IS_E1X(_chip_id)	((CHIP_NUM(_chip_id) == \
120 				  CHIP_NUM_57710) || \
121 				 (CHIP_NUM(_chip_id) == \
122 				  CHIP_NUM_57711) || \
123 				 (CHIP_NUM(_chip_id) == \
124 				  CHIP_NUM_57711E))
125 
126 #define CHIP_IS_E2(_chip_id)	((CHIP_NUM(_chip_id) == \
127 					  CHIP_NUM_57712) || \
128 					 (CHIP_NUM(_chip_id) == \
129 					  CHIP_NUM_57712E) || \
130 					 (CHIP_NUM(_chip_id) == \
131 					  CHIP_NUM_57713) || \
132 					 (CHIP_NUM(_chip_id) == \
133 					  CHIP_NUM_57713E))
134 
135 #define CHIP_IS_57711(_chip_id)	(CHIP_NUM(_chip_id) == \
136 					 CHIP_NUM_57711)
137 #define CHIP_IS_57711E(_chip_id)	(CHIP_NUM(_chip_id) == \
138 					 CHIP_NUM_57711E)
139 #define DO_CHIP_IS_E3(_chip_family)	((_chip_family == 0x1630) || \
140 					 (_chip_family == 0x1680) || \
141 					 (_chip_family == 0x16a0))
142 #define CHIP_IS_E3(_chip_id)	(DO_CHIP_IS_E3(((CHIP_NUM(_chip_id)) & 0xfff0)))
143 
144 
145 /* For EMUL: Ax=0xE, Bx=0xC, Cx=0xA. For FPGA: Ax=0xF, Bx=0xD,
146  * Cx=0xB.
147  */
148 #define CHIP_REV_SIM(_p)            (((0xF - (CHIP_REV(_p) >> CHIP_REV_SHIFT)) \
149 				      >>1) << CHIP_REV_SHIFT)
150 
151 #define CHIP_IS_E3B0(_p)            (CHIP_IS_E3(_p) && \
152 				     ((CHIP_REV(_p) == CHIP_REV_Bx) || \
153 				      (CHIP_REV_SIM(_p) == CHIP_REV_Bx)))
154 
155 #define CHIP_IS_E3A0(_p)            (CHIP_IS_E3(_p) && \
156 				     ((CHIP_REV(_p) == CHIP_REV_Ax) || \
157 				      (CHIP_REV_SIM(_p) == CHIP_REV_Ax)))
158 
159 #define ELINK_USES_WARPCORE(_chip_id)   (CHIP_IS_E3(_chip_id))
160 
161 #define SHMEM2_RD(cb, shmem2_base, _field) \
162 				      REG_RD(cb, shmem2_base + \
163 					      OFFSETOF(struct shmem2_region, \
164 						      _field))
165 
166 #define SHMEM2_HAS(cb, shmem2_base, field) (shmem2_base && \
167 					 (SHMEM2_RD(cb, shmem2_base, size) > \
168 					 OFFSETOF(struct shmem2_region, field)))
169 #ifndef NULL
170 #define NULL    ((void *) 0)
171 #endif
172 
173 /***********************************************************/
174 /*			Shortcut definitions		   */
175 /***********************************************************/
176 
177 #define ELINK_NIG_LATCH_BC_ENABLE_MI_INT 0
178 
179 #define ELINK_NIG_STATUS_EMAC0_MI_INT \
180 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_EMAC0_MISC_MI_INT
181 #define ELINK_NIG_STATUS_XGXS0_LINK10G \
182 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK10G
183 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS \
184 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS
185 #define ELINK_NIG_STATUS_XGXS0_LINK_STATUS_SIZE \
186 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_XGXS0_LINK_STATUS_SIZE
187 #define ELINK_NIG_STATUS_SERDES0_LINK_STATUS \
188 		NIG_STATUS_INTERRUPT_PORT0_REG_STATUS_SERDES0_LINK_STATUS
189 #define ELINK_NIG_MASK_MI_INT \
190 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_EMAC0_MISC_MI_INT
191 #define ELINK_NIG_MASK_XGXS0_LINK10G \
192 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK10G
193 #define ELINK_NIG_MASK_XGXS0_LINK_STATUS \
194 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_XGXS0_LINK_STATUS
195 #define ELINK_NIG_MASK_SERDES0_LINK_STATUS \
196 		NIG_MASK_INTERRUPT_PORT0_REG_MASK_SERDES0_LINK_STATUS
197 
198 #define ELINK_MDIO_AN_CL73_OR_37_COMPLETE \
199 		(MDIO_GP_STATUS_TOP_AN_STATUS1_CL73_AUTONEG_COMPLETE | \
200 		 MDIO_GP_STATUS_TOP_AN_STATUS1_CL37_AUTONEG_COMPLETE)
201 
202 #define ELINK_XGXS_RESET_BITS \
203 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_RSTB_HW |   \
204 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_IDDQ |      \
205 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN |    \
206 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_PWRDWN_SD | \
207 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_XGXS0_TXD_FIFO_RSTB)
208 
209 #define ELINK_SERDES_RESET_BITS \
210 	(MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_RSTB_HW | \
211 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_IDDQ |    \
212 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN |  \
213 	 MISC_REGISTERS_RESET_REG_3_MISC_NIG_MUX_SERDES0_PWRDWN_SD)
214 
215 #define ELINK_AUTONEG_CL37		SHARED_HW_CFG_AN_ENABLE_CL37
216 #define ELINK_AUTONEG_CL73		SHARED_HW_CFG_AN_ENABLE_CL73
217 #define ELINK_AUTONEG_BAM		SHARED_HW_CFG_AN_ENABLE_BAM
218 #define ELINK_AUTONEG_PARALLEL \
219 				SHARED_HW_CFG_AN_ENABLE_PARALLEL_DETECTION
220 #define ELINK_AUTONEG_SGMII_FIBER_AUTODET \
221 				SHARED_HW_CFG_AN_EN_SGMII_FIBER_AUTO_DETECT
222 #define ELINK_AUTONEG_REMOTE_PHY	SHARED_HW_CFG_AN_ENABLE_REMOTE_PHY
223 
224 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_TXSIDE \
225 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_TXSIDE
226 #define ELINK_GP_STATUS_PAUSE_RSOLUTION_RXSIDE \
227 			MDIO_GP_STATUS_TOP_AN_STATUS1_PAUSE_RSOLUTION_RXSIDE
228 #define ELINK_GP_STATUS_SPEED_MASK \
229 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_MASK
230 #define ELINK_GP_STATUS_10M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10M
231 #define ELINK_GP_STATUS_100M	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_100M
232 #define ELINK_GP_STATUS_1G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G
233 #define ELINK_GP_STATUS_2_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_2_5G
234 #define ELINK_GP_STATUS_5G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_5G
235 #define ELINK_GP_STATUS_6G	MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_6G
236 #define ELINK_GP_STATUS_10G_HIG \
237 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_HIG
238 #define ELINK_GP_STATUS_10G_CX4 \
239 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_CX4
240 #define ELINK_GP_STATUS_1G_KX MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_1G_KX
241 #define ELINK_GP_STATUS_10G_KX4 \
242 			MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KX4
243 #define	ELINK_GP_STATUS_10G_KR MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_KR
244 #define	ELINK_GP_STATUS_10G_XFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_XFI
245 #define	ELINK_GP_STATUS_20G_DXGXS MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_DXGXS
246 #define	ELINK_GP_STATUS_10G_SFI   MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_10G_SFI
247 #define	ELINK_GP_STATUS_20G_KR2 MDIO_GP_STATUS_TOP_AN_STATUS1_ACTUAL_SPEED_20G_KR2
248 #define ELINK_LINK_10THD		LINK_STATUS_SPEED_AND_DUPLEX_10THD
249 #define ELINK_LINK_10TFD		LINK_STATUS_SPEED_AND_DUPLEX_10TFD
250 #define ELINK_LINK_100TXHD		LINK_STATUS_SPEED_AND_DUPLEX_100TXHD
251 #define ELINK_LINK_100T4		LINK_STATUS_SPEED_AND_DUPLEX_100T4
252 #define ELINK_LINK_100TXFD		LINK_STATUS_SPEED_AND_DUPLEX_100TXFD
253 #define ELINK_LINK_1000THD		LINK_STATUS_SPEED_AND_DUPLEX_1000THD
254 #define ELINK_LINK_1000TFD		LINK_STATUS_SPEED_AND_DUPLEX_1000TFD
255 #define ELINK_LINK_1000XFD		LINK_STATUS_SPEED_AND_DUPLEX_1000XFD
256 #define ELINK_LINK_2500THD		LINK_STATUS_SPEED_AND_DUPLEX_2500THD
257 #define ELINK_LINK_2500TFD		LINK_STATUS_SPEED_AND_DUPLEX_2500TFD
258 #define ELINK_LINK_2500XFD		LINK_STATUS_SPEED_AND_DUPLEX_2500XFD
259 #define ELINK_LINK_10GTFD		LINK_STATUS_SPEED_AND_DUPLEX_10GTFD
260 #define ELINK_LINK_10GXFD		LINK_STATUS_SPEED_AND_DUPLEX_10GXFD
261 #define ELINK_LINK_20GTFD		LINK_STATUS_SPEED_AND_DUPLEX_20GTFD
262 #define ELINK_LINK_20GXFD		LINK_STATUS_SPEED_AND_DUPLEX_20GXFD
263 
264 #define ELINK_LINK_UPDATE_MASK \
265 			(LINK_STATUS_SPEED_AND_DUPLEX_MASK | \
266 			 LINK_STATUS_LINK_UP | \
267 			 LINK_STATUS_PHYSICAL_LINK_FLAG | \
268 			 LINK_STATUS_AUTO_NEGOTIATE_COMPLETE | \
269 			 LINK_STATUS_RX_FLOW_CONTROL_FLAG_MASK | \
270 			 LINK_STATUS_TX_FLOW_CONTROL_FLAG_MASK | \
271 			 LINK_STATUS_PARALLEL_DETECTION_FLAG_MASK | \
272 			 LINK_STATUS_LINK_PARTNER_SYMMETRIC_PAUSE | \
273 			 LINK_STATUS_LINK_PARTNER_ASYMMETRIC_PAUSE)
274 
275 #define ELINK_SFP_EEPROM_CON_TYPE_ADDR		0x2
276 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_UNKNOWN	0x0
277 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_LC	0x7
278 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_COPPER	0x21
279 	#define ELINK_SFP_EEPROM_CON_TYPE_VAL_RJ45	0x22
280 
281 
282 #define ELINK_SFP_EEPROM_10G_COMP_CODE_ADDR		0x3
283 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_SR_MASK	(1<<4)
284 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LR_MASK	(1<<5)
285 	#define ELINK_SFP_EEPROM_10G_COMP_CODE_LRM_MASK	(1<<6)
286 
287 #define ELINK_SFP_EEPROM_1G_COMP_CODE_ADDR		0x6
288 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_SX	(1<<0)
289 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_LX	(1<<1)
290 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_CX	(1<<2)
291 	#define ELINK_SFP_EEPROM_1G_COMP_CODE_BASE_T	(1<<3)
292 
293 #define ELINK_SFP_EEPROM_FC_TX_TECH_ADDR		0x8
294 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_PASSIVE 0x4
295 	#define ELINK_SFP_EEPROM_FC_TX_TECH_BITMASK_COPPER_ACTIVE  0x8
296 
297 #define ELINK_SFP_EEPROM_OPTIONS_ADDR			0x40
298 	#define ELINK_SFP_EEPROM_OPTIONS_LINEAR_RX_OUT_MASK 0x1
299 #define ELINK_SFP_EEPROM_OPTIONS_SIZE			2
300 
301 #define ELINK_EDC_MODE_LINEAR				0x0022
302 #define ELINK_EDC_MODE_LIMITING				0x0044
303 #define ELINK_EDC_MODE_PASSIVE_DAC			0x0055
304 #define ELINK_EDC_MODE_ACTIVE_DAC			0x0066
305 
306 /* ETS defines*/
307 #define DCBX_INVALID_COS					(0xFF)
308 
309 #define ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND		(0x5000)
310 #define ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT		(0x5000)
311 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS		(1360)
312 #define ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS			(2720)
313 #define ELINK_ETS_E3B0_PBF_MIN_W_VAL				(10000)
314 
315 #define ELINK_MAX_PACKET_SIZE					(9700)
316 #ifdef INCLUDE_WARPCORE_UC_LOAD
317 #define ELINK_WC_UC_TIMEOUT					1000
318 #define ELINK_WC_RDY_TIMEOUT_MSEC           100
319 #endif
320 #define MAX_KR_LINK_RETRY				4
321 
322 /**********************************************************/
323 /*                     INTERFACE                          */
324 /**********************************************************/
325 
326 #define CL22_WR_OVER_CL45(_cb, _phy, _bank, _addr, _val) \
327 	elink_cl45_write(_cb, _phy, \
328 		(_phy)->def_md_devad, \
329 		(_bank + (_addr & 0xf)), \
330 		_val)
331 
332 #define CL22_RD_OVER_CL45(_cb, _phy, _bank, _addr, _val) \
333 	elink_cl45_read(_cb, _phy, \
334 		(_phy)->def_md_devad, \
335 		(_bank + (_addr & 0xf)), \
336 		_val)
337 
338 #ifdef BNX2X_ADD /* BNX2X_ADD */
339 static int elink_check_half_open_conn(struct elink_params *params,
340 				      struct elink_vars *vars, u8 notify);
341 static int elink_sfp_module_detection(struct elink_phy *phy,
342 				      struct elink_params *params);
343 #endif
344 
elink_bits_en(struct elink_dev * cb,u32 reg,u32 bits)345 static u32 elink_bits_en(struct elink_dev *cb, u32 reg, u32 bits)
346 {
347 	u32 val = REG_RD(cb, reg);
348 
349 	val |= bits;
350 	REG_WR(cb, reg, val);
351 	return val;
352 }
353 
elink_bits_dis(struct elink_dev * cb,u32 reg,u32 bits)354 static u32 elink_bits_dis(struct elink_dev *cb, u32 reg, u32 bits)
355 {
356 	u32 val = REG_RD(cb, reg);
357 
358 	val &= ~bits;
359 	REG_WR(cb, reg, val);
360 	return val;
361 }
362 
363 /*
364  * elink_check_lfa - This function checks if link reinitialization is required,
365  *                   or link flap can be avoided.
366  *
367  * @params:	link parameters
368  * Returns 0 if Link Flap Avoidance conditions are met otherwise, the failed
369  *         condition code.
370  */
371 #ifndef EXCLUDE_NON_COMMON_INIT
elink_check_lfa(struct elink_params * params)372 static int elink_check_lfa(struct elink_params *params)
373 {
374 	u32 link_status, cfg_idx, lfa_mask, cfg_size;
375 	u32 cur_speed_cap_mask, cur_req_fc_auto_adv, additional_config;
376 	u32 saved_val, req_val, eee_status;
377 	struct elink_dev *cb = params->cb;
378 
379 	additional_config =
380 		REG_RD(cb, params->lfa_base +
381 			   OFFSETOF(struct shmem_lfa, additional_config));
382 
383 	/* NOTE: must be first condition checked -
384 	* to verify DCC bit is cleared in any case!
385 	*/
386 	if (additional_config & NO_LFA_DUE_TO_DCC_MASK) {
387 		ELINK_DEBUG_P0(cb, "No LFA due to DCC flap after clp exit\n");
388 		REG_WR(cb, params->lfa_base +
389 			   OFFSETOF(struct shmem_lfa, additional_config),
390 		       additional_config & ~NO_LFA_DUE_TO_DCC_MASK);
391 		return LFA_DCC_LFA_DISABLED;
392 	}
393 
394 	/* Verify that link is up */
395 	link_status = REG_RD(cb, params->shmem_base +
396 			     OFFSETOF(struct shmem_region,
397 				      port_mb[params->port].link_status));
398 	if (!(link_status & LINK_STATUS_LINK_UP))
399 		return LFA_LINK_DOWN;
400 
401 	/* if loaded after BOOT from SAN, don't flap the link in any case and
402 	 * rely on link set by preboot driver
403 	 */
404 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_BOOT_FROM_SAN)
405 		return 0;
406 
407 	/* Verify that loopback mode is not set */
408 	if (params->loopback_mode)
409 		return LFA_LOOPBACK_ENABLED;
410 
411 	/* Verify that MFW supports LFA */
412 	if (!params->lfa_base)
413 		return LFA_MFW_IS_TOO_OLD;
414 
415 	if (params->num_phys == 3) {
416 		cfg_size = 2;
417 		lfa_mask = 0xffffffff;
418 	} else {
419 		cfg_size = 1;
420 		lfa_mask = 0xffff;
421 	}
422 
423 	/* Compare Duplex */
424 	saved_val = REG_RD(cb, params->lfa_base +
425 			   OFFSETOF(struct shmem_lfa, req_duplex));
426 	req_val = params->req_duplex[0] | (params->req_duplex[1] << 16);
427 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
428 		ELINK_DEBUG_P2(cb, "Duplex mismatch %x vs. %x\n",
429 			       (saved_val & lfa_mask), (req_val & lfa_mask));
430 		return LFA_DUPLEX_MISMATCH;
431 	}
432 	/* Compare Flow Control */
433 	saved_val = REG_RD(cb, params->lfa_base +
434 			   OFFSETOF(struct shmem_lfa, req_flow_ctrl));
435 	req_val = params->req_flow_ctrl[0] | (params->req_flow_ctrl[1] << 16);
436 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
437 		ELINK_DEBUG_P2(cb, "Flow control mismatch %x vs. %x\n",
438 			       (saved_val & lfa_mask), (req_val & lfa_mask));
439 		return LFA_FLOW_CTRL_MISMATCH;
440 	}
441 	/* Compare Link Speed */
442 	saved_val = REG_RD(cb, params->lfa_base +
443 			   OFFSETOF(struct shmem_lfa, req_line_speed));
444 	req_val = params->req_line_speed[0] | (params->req_line_speed[1] << 16);
445 	if ((saved_val & lfa_mask) != (req_val & lfa_mask)) {
446 		ELINK_DEBUG_P2(cb, "Link speed mismatch %x vs. %x\n",
447 			       (saved_val & lfa_mask), (req_val & lfa_mask));
448 		return LFA_LINK_SPEED_MISMATCH;
449 	}
450 
451 	for (cfg_idx = 0; cfg_idx < cfg_size; cfg_idx++) {
452 		cur_speed_cap_mask = REG_RD(cb, params->lfa_base +
453 					    OFFSETOF(struct shmem_lfa,
454 						     speed_cap_mask[cfg_idx]));
455 
456 		if (cur_speed_cap_mask != params->speed_cap_mask[cfg_idx]) {
457 			ELINK_DEBUG_P2(cb, "Speed Cap mismatch %x vs. %x\n",
458 				       cur_speed_cap_mask,
459 				       params->speed_cap_mask[cfg_idx]);
460 			return LFA_SPEED_CAP_MISMATCH;
461 		}
462 	}
463 
464 	cur_req_fc_auto_adv =
465 		REG_RD(cb, params->lfa_base +
466 		       OFFSETOF(struct shmem_lfa, additional_config)) &
467 		REQ_FC_AUTO_ADV_MASK;
468 
469 	if ((u16)cur_req_fc_auto_adv != params->req_fc_auto_adv) {
470 		ELINK_DEBUG_P2(cb, "Flow Ctrl AN mismatch %x vs. %x\n",
471 			       cur_req_fc_auto_adv, params->req_fc_auto_adv);
472 		return LFA_FLOW_CTRL_MISMATCH;
473 	}
474 
475 	eee_status = REG_RD(cb, params->shmem2_base +
476 			    OFFSETOF(struct shmem2_region,
477 				     eee_status[params->port]));
478 
479 	if (((eee_status & SHMEM_EEE_LPI_REQUESTED_BIT) ^
480 	     (params->eee_mode & ELINK_EEE_MODE_ENABLE_LPI)) ||
481 	    ((eee_status & SHMEM_EEE_REQUESTED_BIT) ^
482 	     (params->eee_mode & ELINK_EEE_MODE_ADV_LPI))) {
483 		ELINK_DEBUG_P2(cb, "EEE mismatch %x vs. %x\n", params->eee_mode,
484 			       eee_status);
485 		return LFA_EEE_MISMATCH;
486 	}
487 
488 	/* LFA conditions are met */
489 	return 0;
490 }
491 #endif
492 /******************************************************************/
493 /*			EPIO/GPIO section			  */
494 /******************************************************************/
495 #if (!defined EXCLUDE_WARPCORE)
elink_get_epio(struct elink_dev * cb,u32 epio_pin,u32 * en)496 static void elink_get_epio(struct elink_dev *cb, u32 epio_pin, u32 *en)
497 {
498 	u32 epio_mask, gp_oenable;
499 	*en = 0;
500 	/* Sanity check */
501 	if (epio_pin > 31) {
502 		ELINK_DEBUG_P1(cb, "Invalid EPIO pin %d to get\n", epio_pin);
503 		return;
504 	}
505 
506 	epio_mask = 1 << epio_pin;
507 	/* Set this EPIO to output */
508 	gp_oenable = REG_RD(cb, MCP_REG_MCPR_GP_OENABLE);
509 	REG_WR(cb, MCP_REG_MCPR_GP_OENABLE, gp_oenable & ~epio_mask);
510 
511 	*en = (REG_RD(cb, MCP_REG_MCPR_GP_INPUTS) & epio_mask) >> epio_pin;
512 }
elink_set_epio(struct elink_dev * cb,u32 epio_pin,u32 en)513 static void elink_set_epio(struct elink_dev *cb, u32 epio_pin, u32 en)
514 {
515 	u32 epio_mask, gp_output, gp_oenable;
516 
517 	/* Sanity check */
518 	if (epio_pin > 31) {
519 		ELINK_DEBUG_P1(cb, "Invalid EPIO pin %d to set\n", epio_pin);
520 		return;
521 	}
522 	ELINK_DEBUG_P2(cb, "Setting EPIO pin %d to %d\n", epio_pin, en);
523 	epio_mask = 1 << epio_pin;
524 	/* Set this EPIO to output */
525 	gp_output = REG_RD(cb, MCP_REG_MCPR_GP_OUTPUTS);
526 	if (en)
527 		gp_output |= epio_mask;
528 	else
529 		gp_output &= ~epio_mask;
530 
531 	REG_WR(cb, MCP_REG_MCPR_GP_OUTPUTS, gp_output);
532 
533 	/* Set the value for this EPIO */
534 	gp_oenable = REG_RD(cb, MCP_REG_MCPR_GP_OENABLE);
535 	REG_WR(cb, MCP_REG_MCPR_GP_OENABLE, gp_oenable | epio_mask);
536 }
537 
elink_set_cfg_pin(struct elink_dev * cb,u32 pin_cfg,u32 val)538 static void elink_set_cfg_pin(struct elink_dev *cb, u32 pin_cfg, u32 val)
539 {
540 	if (pin_cfg == PIN_CFG_NA)
541 		return;
542 	if (pin_cfg >= PIN_CFG_EPIO0) {
543 		elink_set_epio(cb, pin_cfg - PIN_CFG_EPIO0, val);
544 	} else {
545 		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
546 		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
547 		ELINK_SET_GPIO(cb, gpio_num, (u8)val, gpio_port);
548 	}
549 }
550 
elink_get_cfg_pin(struct elink_dev * cb,u32 pin_cfg,u32 * val)551 static u32 elink_get_cfg_pin(struct elink_dev *cb, u32 pin_cfg, u32 *val)
552 {
553 	if (pin_cfg == PIN_CFG_NA)
554 		return ELINK_STATUS_ERROR;
555 	if (pin_cfg >= PIN_CFG_EPIO0) {
556 		elink_get_epio(cb, pin_cfg - PIN_CFG_EPIO0, val);
557 	} else {
558 		u8 gpio_num = (pin_cfg - PIN_CFG_GPIO0_P0) & 0x3;
559 		u8 gpio_port = (pin_cfg - PIN_CFG_GPIO0_P0) >> 2;
560 		*val = ELINK_GET_GPIO(cb, gpio_num, gpio_port);
561 	}
562 	return ELINK_STATUS_OK;
563 
564 }
565 #endif /* (!defined EXCLUDE_WARPCORE) */
566 /******************************************************************/
567 /*				ETS section			  */
568 /******************************************************************/
569 #ifdef ELINK_ENHANCEMENTS
elink_ets_e2e3a0_disabled(struct elink_params * params)570 static void elink_ets_e2e3a0_disabled(struct elink_params *params)
571 {
572 	/* ETS disabled configuration*/
573 	struct elink_dev *cb = params->cb;
574 
575 	ELINK_DEBUG_P0(cb, "ETS E2E3 disabled configuration\n");
576 
577 	/* mapping between entry  priority to client number (0,1,2 -debug and
578 	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
579 	 * 3bits client num.
580 	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
581 	 * cos1-100     cos0-011     dbg1-010     dbg0-001     MCP-000
582 	 */
583 
584 	REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, 0x4688);
585 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
586 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
587 	 * COS0 entry, 4 - COS1 entry.
588 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
589 	 * bit4   bit3	  bit2   bit1	  bit0
590 	 * MCP and debug are strict
591 	 */
592 
593 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
594 	/* defines which entries (clients) are subjected to WFQ arbitration */
595 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
596 	/* For strict priority entries defines the number of consecutive
597 	 * slots for the highest priority.
598 	 */
599 	REG_WR(cb, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
600 	/* mapping between the CREDIT_WEIGHT registers and actual client
601 	 * numbers
602 	 */
603 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0);
604 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0);
605 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0);
606 
607 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, 0);
608 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, 0);
609 	REG_WR(cb, PBF_REG_HIGH_PRIORITY_COS_NUM, 0);
610 	/* ETS mode disable */
611 	REG_WR(cb, PBF_REG_ETS_ENABLED, 0);
612 	/* If ETS mode is enabled (there is no strict priority) defines a WFQ
613 	 * weight for COS0/COS1.
614 	 */
615 	REG_WR(cb, PBF_REG_COS0_WEIGHT, 0x2710);
616 	REG_WR(cb, PBF_REG_COS1_WEIGHT, 0x2710);
617 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter */
618 	REG_WR(cb, PBF_REG_COS0_UPPER_BOUND, 0x989680);
619 	REG_WR(cb, PBF_REG_COS1_UPPER_BOUND, 0x989680);
620 	/* Defines the number of consecutive slots for the strict priority */
621 	REG_WR(cb, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
622 }
623 /******************************************************************************
624 * Description:
625 *	Getting min_w_val will be set according to line speed .
626 *.
627 ******************************************************************************/
elink_ets_get_min_w_val_nig(const struct elink_vars * vars)628 static u32 elink_ets_get_min_w_val_nig(const struct elink_vars *vars)
629 {
630 	u32 min_w_val = 0;
631 	/* Calculate min_w_val.*/
632 	if (vars->link_up) {
633 		if (vars->line_speed == ELINK_SPEED_20000)
634 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
635 		else
636 			min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_UP_TO_10GBPS;
637 	} else
638 		min_w_val = ELINK_ETS_E3B0_NIG_MIN_W_VAL_20GBPS;
639 	/* If the link isn't up (static configuration for example ) The
640 	 * link will be according to 20GBPS.
641 	 */
642 	return min_w_val;
643 }
644 /******************************************************************************
645 * Description:
646 *	Getting credit upper bound form min_w_val.
647 *.
648 ******************************************************************************/
elink_ets_get_credit_upper_bound(const u32 min_w_val)649 static u32 elink_ets_get_credit_upper_bound(const u32 min_w_val)
650 {
651 	const u32 credit_upper_bound = (u32)ELINK_MAXVAL((150 * min_w_val),
652 						ELINK_MAX_PACKET_SIZE);
653 	return credit_upper_bound;
654 }
655 /******************************************************************************
656 * Description:
657 *	Set credit upper bound for NIG.
658 *.
659 ******************************************************************************/
elink_ets_e3b0_set_credit_upper_bound_nig(const struct elink_params * params,const u32 min_w_val)660 static void elink_ets_e3b0_set_credit_upper_bound_nig(
661 	const struct elink_params *params,
662 	const u32 min_w_val)
663 {
664 	struct elink_dev *cb = params->cb;
665 	const u8 port = params->port;
666 	const u32 credit_upper_bound =
667 	    elink_ets_get_credit_upper_bound(min_w_val);
668 
669 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_0 :
670 		NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0, credit_upper_bound);
671 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_1 :
672 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1, credit_upper_bound);
673 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_2 :
674 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_2, credit_upper_bound);
675 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_3 :
676 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_3, credit_upper_bound);
677 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_4 :
678 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_4, credit_upper_bound);
679 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_UPPER_BOUND_5 :
680 		   NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_5, credit_upper_bound);
681 
682 	if (!port) {
683 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_6,
684 			credit_upper_bound);
685 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_7,
686 			credit_upper_bound);
687 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_8,
688 			credit_upper_bound);
689 	}
690 }
691 /******************************************************************************
692 * Description:
693 *	Will return the NIG ETS registers to init values.Except
694 *	credit_upper_bound.
695 *	That isn't used in this configuration (No WFQ is enabled) and will be
696 *	configured acording to spec
697 *.
698 ******************************************************************************/
elink_ets_e3b0_nig_disabled(const struct elink_params * params,const struct elink_vars * vars)699 static void elink_ets_e3b0_nig_disabled(const struct elink_params *params,
700 					const struct elink_vars *vars)
701 {
702 	struct elink_dev *cb = params->cb;
703 	const u8 port = params->port;
704 	const u32 min_w_val = elink_ets_get_min_w_val_nig(vars);
705 	/* Mapping between entry  priority to client number (0,1,2 -debug and
706 	 * management clients, 3 - COS0 client, 4 - COS1, ... 8 -
707 	 * COS5)(HIGHEST) 4bits client num.TODO_ETS - Should be done by
708 	 * reset value or init tool
709 	 */
710 	if (port) {
711 		REG_WR(cb, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB, 0x543210);
712 		REG_WR(cb, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_MSB, 0x0);
713 	} else {
714 		REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB, 0x76543210);
715 		REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB, 0x8);
716 	}
717 	/* For strict priority entries defines the number of consecutive
718 	 * slots for the highest priority.
719 	 */
720 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS :
721 		   NIG_REG_P1_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
722 	/* Mapping between the CREDIT_WEIGHT registers and actual client
723 	 * numbers
724 	 */
725 	if (port) {
726 		/*Port 1 has 6 COS*/
727 		REG_WR(cb, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_LSB, 0x210543);
728 		REG_WR(cb, NIG_REG_P1_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x0);
729 	} else {
730 		/*Port 0 has 9 COS*/
731 		REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_LSB,
732 		       0x43210876);
733 		REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP2_MSB, 0x5);
734 	}
735 
736 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
737 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 -
738 	 * COS0 entry, 4 - COS1 entry.
739 	 * COS1 | COS0 | DEBUG1 | DEBUG0 | MGMT
740 	 * bit4   bit3	  bit2   bit1	  bit0
741 	 * MCP and debug are strict
742 	 */
743 	if (port)
744 		REG_WR(cb, NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT, 0x3f);
745 	else
746 		REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1ff);
747 	/* defines which entries (clients) are subjected to WFQ arbitration */
748 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
749 		   NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0);
750 
751 	/* Please notice the register address are note continuous and a
752 	 * for here is note appropriate.In 2 port mode port0 only COS0-5
753 	 * can be used. DEBUG1,DEBUG1,MGMT are never used for WFQ* In 4
754 	 * port mode port1 only COS0-2 can be used. DEBUG1,DEBUG1,MGMT
755 	 * are never used for WFQ
756 	 */
757 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
758 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, 0x0);
759 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
760 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, 0x0);
761 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
762 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2, 0x0);
763 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_3 :
764 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3, 0x0);
765 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_4 :
766 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4, 0x0);
767 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_5 :
768 		   NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5, 0x0);
769 	if (!port) {
770 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_6, 0x0);
771 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_7, 0x0);
772 		REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_8, 0x0);
773 	}
774 
775 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val);
776 }
777 /******************************************************************************
778 * Description:
779 *	Set credit upper bound for PBF.
780 *.
781 ******************************************************************************/
elink_ets_e3b0_set_credit_upper_bound_pbf(const struct elink_params * params,const u32 min_w_val)782 static void elink_ets_e3b0_set_credit_upper_bound_pbf(
783 	const struct elink_params *params,
784 	const u32 min_w_val)
785 {
786 	struct elink_dev *cb = params->cb;
787 	const u32 credit_upper_bound =
788 	    elink_ets_get_credit_upper_bound(min_w_val);
789 	const u8 port = params->port;
790 	u32 base_upper_bound = 0;
791 	u8 max_cos = 0;
792 	u8 i = 0;
793 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.In 4
794 	 * port mode port1 has COS0-2 that can be used for WFQ.
795 	 */
796 	if (!port) {
797 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P0;
798 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
799 	} else {
800 		base_upper_bound = PBF_REG_COS0_UPPER_BOUND_P1;
801 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
802 	}
803 
804 	for (i = 0; i < max_cos; i++)
805 		REG_WR(cb, base_upper_bound + (i << 2), credit_upper_bound);
806 }
807 
808 /******************************************************************************
809 * Description:
810 *	Will return the PBF ETS registers to init values.Except
811 *	credit_upper_bound.
812 *	That isn't used in this configuration (No WFQ is enabled) and will be
813 *	configured acording to spec
814 *.
815 ******************************************************************************/
elink_ets_e3b0_pbf_disabled(const struct elink_params * params)816 static void elink_ets_e3b0_pbf_disabled(const struct elink_params *params)
817 {
818 	struct elink_dev *cb = params->cb;
819 	const u8 port = params->port;
820 	const u32 min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
821 	u8 i = 0;
822 	u32 base_weight = 0;
823 	u8 max_cos = 0;
824 
825 	/* Mapping between entry  priority to client number 0 - COS0
826 	 * client, 2 - COS1, ... 5 - COS5)(HIGHEST) 4bits client num.
827 	 * TODO_ETS - Should be done by reset value or init tool
828 	 */
829 	if (port)
830 		/*  0x688 (|011|0 10|00 1|000) */
831 		REG_WR(cb, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , 0x688);
832 	else
833 		/*  (10 1|100 |011|0 10|00 1|000) */
834 		REG_WR(cb, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , 0x2C688);
835 
836 	/* TODO_ETS - Should be done by reset value or init tool */
837 	if (port)
838 		/* 0x688 (|011|0 10|00 1|000)*/
839 		REG_WR(cb, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P1, 0x688);
840 	else
841 	/* 0x2C688 (10 1|100 |011|0 10|00 1|000) */
842 	REG_WR(cb, PBF_REG_ETS_ARB_CLIENT_CREDIT_MAP_P0, 0x2C688);
843 
844 	REG_WR(cb, (port) ? PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P1 :
845 		   PBF_REG_ETS_ARB_NUM_STRICT_ARB_SLOTS_P0 , 0x100);
846 
847 
848 	REG_WR(cb, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
849 		   PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , 0);
850 
851 	REG_WR(cb, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
852 		   PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0 , 0);
853 	/* In 2 port mode port0 has COS0-5 that can be used for WFQ.
854 	 * In 4 port mode port1 has COS0-2 that can be used for WFQ.
855 	 */
856 	if (!port) {
857 		base_weight = PBF_REG_COS0_WEIGHT_P0;
858 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
859 	} else {
860 		base_weight = PBF_REG_COS0_WEIGHT_P1;
861 		max_cos = ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1;
862 	}
863 
864 	for (i = 0; i < max_cos; i++)
865 		REG_WR(cb, base_weight + (0x4 * i), 0);
866 
867 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
868 }
869 /******************************************************************************
870 * Description:
871 *	E3B0 disable will return basicly the values to init values.
872 *.
873 ******************************************************************************/
elink_ets_e3b0_disabled(const struct elink_params * params,const struct elink_vars * vars)874 static elink_status_t elink_ets_e3b0_disabled(const struct elink_params *params,
875 				   const struct elink_vars *vars)
876 {
877 	struct elink_dev *cb = params->cb;
878 
879 	if (!CHIP_IS_E3B0(params->chip_id)) {
880 		ELINK_DEBUG_P0(cb,
881 		   "elink_ets_e3b0_disabled the chip isn't E3B0\n");
882 		return ELINK_STATUS_ERROR;
883 	}
884 
885 	elink_ets_e3b0_nig_disabled(params, vars);
886 
887 	elink_ets_e3b0_pbf_disabled(params);
888 
889 	return ELINK_STATUS_OK;
890 }
891 
892 /******************************************************************************
893 * Description:
894 *	Disable will return basicly the values to init values.
895 *
896 ******************************************************************************/
elink_ets_disabled(struct elink_params * params,struct elink_vars * vars)897 elink_status_t elink_ets_disabled(struct elink_params *params,
898 		      struct elink_vars *vars)
899 {
900 	struct elink_dev *cb = params->cb;
901 	elink_status_t elink_status = ELINK_STATUS_OK;
902 
903 	if ((CHIP_IS_E2(params->chip_id)) || (CHIP_IS_E3A0(params->chip_id)))
904 		elink_ets_e2e3a0_disabled(params);
905 	else if (CHIP_IS_E3B0(params->chip_id))
906 		elink_status = elink_ets_e3b0_disabled(params, vars);
907 	else {
908 		ELINK_DEBUG_P0(cb, "elink_ets_disabled - chip not supported\n");
909 		return ELINK_STATUS_ERROR;
910 	}
911 
912 	return elink_status;
913 }
914 
915 /******************************************************************************
916 * Description
917 *	Set the COS mappimg to SP and BW until this point all the COS are not
918 *	set as SP or BW.
919 ******************************************************************************/
elink_ets_e3b0_cli_map(const struct elink_params * params,const struct elink_ets_params * ets_params,const u8 cos_sp_bitmap,const u8 cos_bw_bitmap)920 static elink_status_t elink_ets_e3b0_cli_map(const struct elink_params *params,
921 				  const struct elink_ets_params *ets_params,
922 				  const u8 cos_sp_bitmap,
923 				  const u8 cos_bw_bitmap)
924 {
925 	struct elink_dev *cb = params->cb;
926 	const u8 port = params->port;
927 	const u8 nig_cli_sp_bitmap = 0x7 | (cos_sp_bitmap << 3);
928 	const u8 pbf_cli_sp_bitmap = cos_sp_bitmap;
929 	const u8 nig_cli_subject2wfq_bitmap = cos_bw_bitmap << 3;
930 	const u8 pbf_cli_subject2wfq_bitmap = cos_bw_bitmap;
931 
932 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_STRICT :
933 	       NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, nig_cli_sp_bitmap);
934 
935 	REG_WR(cb, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P1 :
936 	       PBF_REG_ETS_ARB_CLIENT_IS_STRICT_P0 , pbf_cli_sp_bitmap);
937 
938 	REG_WR(cb, (port) ? NIG_REG_P1_TX_ARB_CLIENT_IS_SUBJECT2WFQ :
939 	       NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ,
940 	       nig_cli_subject2wfq_bitmap);
941 
942 	REG_WR(cb, (port) ? PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P1 :
943 	       PBF_REG_ETS_ARB_CLIENT_IS_SUBJECT2WFQ_P0,
944 	       pbf_cli_subject2wfq_bitmap);
945 
946 	return ELINK_STATUS_OK;
947 }
948 
949 /******************************************************************************
950 * Description:
951 *	This function is needed because NIG ARB_CREDIT_WEIGHT_X are
952 *	not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
953 ******************************************************************************/
elink_ets_e3b0_set_cos_bw(struct elink_dev * cb,const u8 cos_entry,const u32 min_w_val_nig,const u32 min_w_val_pbf,const u16 total_bw,const u8 bw,const u8 port)954 static elink_status_t elink_ets_e3b0_set_cos_bw(struct elink_dev *cb,
955 				     const u8 cos_entry,
956 				     const u32 min_w_val_nig,
957 				     const u32 min_w_val_pbf,
958 				     const u16 total_bw,
959 				     const u8 bw,
960 				     const u8 port)
961 {
962 	u32 nig_reg_adress_crd_weight = 0;
963 	u32 pbf_reg_adress_crd_weight = 0;
964 	/* Calculate and set BW for this COS - use 1 instead of 0 for BW */
965 	const u32 cos_bw_nig = ((bw ? bw : 1) * min_w_val_nig) / total_bw;
966 	const u32 cos_bw_pbf = ((bw ? bw : 1) * min_w_val_pbf) / total_bw;
967 
968 	switch (cos_entry) {
969 	case 0:
970 	    nig_reg_adress_crd_weight =
971 		 (port) ? NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_0 :
972 		     NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0;
973 	     pbf_reg_adress_crd_weight = (port) ?
974 		 PBF_REG_COS0_WEIGHT_P1 : PBF_REG_COS0_WEIGHT_P0;
975 	     break;
976 	case 1:
977 	     nig_reg_adress_crd_weight = (port) ?
978 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_1 :
979 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1;
980 	     pbf_reg_adress_crd_weight = (port) ?
981 		 PBF_REG_COS1_WEIGHT_P1 : PBF_REG_COS1_WEIGHT_P0;
982 	     break;
983 	case 2:
984 	     nig_reg_adress_crd_weight = (port) ?
985 		 NIG_REG_P1_TX_ARB_CREDIT_WEIGHT_2 :
986 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_2;
987 
988 		 pbf_reg_adress_crd_weight = (port) ?
989 		     PBF_REG_COS2_WEIGHT_P1 : PBF_REG_COS2_WEIGHT_P0;
990 	     break;
991 	case 3:
992 	    if (port)
993 			return ELINK_STATUS_ERROR;
994 	     nig_reg_adress_crd_weight =
995 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_3;
996 	     pbf_reg_adress_crd_weight =
997 		 PBF_REG_COS3_WEIGHT_P0;
998 	     break;
999 	case 4:
1000 	    if (port)
1001 		return ELINK_STATUS_ERROR;
1002 	     nig_reg_adress_crd_weight =
1003 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_4;
1004 	     pbf_reg_adress_crd_weight = PBF_REG_COS4_WEIGHT_P0;
1005 	     break;
1006 	case 5:
1007 	    if (port)
1008 		return ELINK_STATUS_ERROR;
1009 	     nig_reg_adress_crd_weight =
1010 		 NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_5;
1011 	     pbf_reg_adress_crd_weight = PBF_REG_COS5_WEIGHT_P0;
1012 	     break;
1013 	}
1014 
1015 	REG_WR(cb, nig_reg_adress_crd_weight, cos_bw_nig);
1016 
1017 	REG_WR(cb, pbf_reg_adress_crd_weight, cos_bw_pbf);
1018 
1019 	return ELINK_STATUS_OK;
1020 }
1021 /******************************************************************************
1022 * Description:
1023 *	Calculate the total BW.A value of 0 isn't legal.
1024 *
1025 ******************************************************************************/
elink_ets_e3b0_get_total_bw(const struct elink_params * params,struct elink_ets_params * ets_params,u16 * total_bw)1026 static elink_status_t elink_ets_e3b0_get_total_bw(
1027 	const struct elink_params *params,
1028 	struct elink_ets_params *ets_params,
1029 	u16 *total_bw)
1030 {
1031 	struct elink_dev *cb = params->cb;
1032 	u8 cos_idx = 0;
1033 	u8 is_bw_cos_exist = 0;
1034 
1035 	*total_bw = 0 ;
1036 	/* Calculate total BW requested */
1037 	for (cos_idx = 0; cos_idx < ets_params->num_of_cos; cos_idx++) {
1038 		if (ets_params->cos[cos_idx].state == elink_cos_state_bw) {
1039 			is_bw_cos_exist = 1;
1040 			if (!ets_params->cos[cos_idx].params.bw_params.bw) {
1041 				ELINK_DEBUG_P0(cb, "elink_ets_E3B0_config BW"
1042 						   "was set to 0\n");
1043 				/* This is to prevent a state when ramrods
1044 				 * can't be sent
1045 				 */
1046 				ets_params->cos[cos_idx].params.bw_params.bw
1047 					 = 1;
1048 			}
1049 			*total_bw +=
1050 				ets_params->cos[cos_idx].params.bw_params.bw;
1051 		}
1052 	}
1053 
1054 	/* Check total BW is valid */
1055 	if ((is_bw_cos_exist == 1) && (*total_bw != 100)) {
1056 		if (*total_bw == 0) {
1057 			ELINK_DEBUG_P0(cb,
1058 			   "elink_ets_E3B0_config total BW shouldn't be 0\n");
1059 			return ELINK_STATUS_ERROR;
1060 		}
1061 		ELINK_DEBUG_P0(cb,
1062 		   "elink_ets_E3B0_config total BW should be 100\n");
1063 		/* We can handle a case whre the BW isn't 100 this can happen
1064 		 * if the TC are joined.
1065 		 */
1066 	}
1067 	return ELINK_STATUS_OK;
1068 }
1069 
1070 /******************************************************************************
1071 * Description:
1072 *	Invalidate all the sp_pri_to_cos.
1073 *
1074 ******************************************************************************/
elink_ets_e3b0_sp_pri_to_cos_init(u8 * sp_pri_to_cos)1075 static void elink_ets_e3b0_sp_pri_to_cos_init(u8 *sp_pri_to_cos)
1076 {
1077 	u8 pri = 0;
1078 	for (pri = 0; pri < ELINK_DCBX_MAX_NUM_COS; pri++)
1079 		sp_pri_to_cos[pri] = DCBX_INVALID_COS;
1080 }
1081 /******************************************************************************
1082 * Description:
1083 *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1084 *	according to sp_pri_to_cos.
1085 *
1086 ******************************************************************************/
elink_ets_e3b0_sp_pri_to_cos_set(const struct elink_params * params,u8 * sp_pri_to_cos,const u8 pri,const u8 cos_entry)1087 static elink_status_t elink_ets_e3b0_sp_pri_to_cos_set(const struct elink_params *params,
1088 					    u8 *sp_pri_to_cos, const u8 pri,
1089 					    const u8 cos_entry)
1090 {
1091 	struct elink_dev *cb = params->cb;
1092 	const u8 port = params->port;
1093 	const u8 max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1094 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1095 
1096 	if (pri >= max_num_of_cos) {
1097 		ELINK_DEBUG_P0(cb, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1098 		   "parameter Illegal strict priority\n");
1099 	    return ELINK_STATUS_ERROR;
1100 	}
1101 
1102 	if (sp_pri_to_cos[pri] != DCBX_INVALID_COS) {
1103 		ELINK_DEBUG_P0(cb, "elink_ets_e3b0_sp_pri_to_cos_set invalid "
1104 				   "parameter There can't be two COS's with "
1105 				   "the same strict pri\n");
1106 		return ELINK_STATUS_ERROR;
1107 	}
1108 
1109 	sp_pri_to_cos[pri] = cos_entry;
1110 	return ELINK_STATUS_OK;
1111 
1112 }
1113 
1114 /******************************************************************************
1115 * Description:
1116 *	Returns the correct value according to COS and priority in
1117 *	the sp_pri_cli register.
1118 *
1119 ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg(const u8 cos,const u8 cos_offset,const u8 pri_set,const u8 pri_offset,const u8 entry_size)1120 static u64 elink_e3b0_sp_get_pri_cli_reg(const u8 cos, const u8 cos_offset,
1121 					 const u8 pri_set,
1122 					 const u8 pri_offset,
1123 					 const u8 entry_size)
1124 {
1125 	u64 pri_cli_nig = 0;
1126 	pri_cli_nig = ((u64)(cos + cos_offset)) << (entry_size *
1127 						    (pri_set + pri_offset));
1128 
1129 	return pri_cli_nig;
1130 }
1131 /******************************************************************************
1132 * Description:
1133 *	Returns the correct value according to COS and priority in the
1134 *	sp_pri_cli register for NIG.
1135 *
1136 ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg_nig(const u8 cos,const u8 pri_set)1137 static u64 elink_e3b0_sp_get_pri_cli_reg_nig(const u8 cos, const u8 pri_set)
1138 {
1139 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1140 	const u8 nig_cos_offset = 3;
1141 	const u8 nig_pri_offset = 3;
1142 
1143 	return elink_e3b0_sp_get_pri_cli_reg(cos, nig_cos_offset, pri_set,
1144 		nig_pri_offset, 4);
1145 
1146 }
1147 /******************************************************************************
1148 * Description:
1149 *	Returns the correct value according to COS and priority in the
1150 *	sp_pri_cli register for PBF.
1151 *
1152 ******************************************************************************/
elink_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos,const u8 pri_set)1153 static u64 elink_e3b0_sp_get_pri_cli_reg_pbf(const u8 cos, const u8 pri_set)
1154 {
1155 	const u8 pbf_cos_offset = 0;
1156 	const u8 pbf_pri_offset = 0;
1157 
1158 	return elink_e3b0_sp_get_pri_cli_reg(cos, pbf_cos_offset, pri_set,
1159 		pbf_pri_offset, 3);
1160 
1161 }
1162 
1163 /******************************************************************************
1164 * Description:
1165 *	Calculate and set the SP (ARB_PRIORITY_CLIENT) NIG and PBF registers
1166 *	according to sp_pri_to_cos.(which COS has higher priority)
1167 *
1168 ******************************************************************************/
elink_ets_e3b0_sp_set_pri_cli_reg(const struct elink_params * params,u8 * sp_pri_to_cos)1169 static elink_status_t elink_ets_e3b0_sp_set_pri_cli_reg(const struct elink_params *params,
1170 					     u8 *sp_pri_to_cos)
1171 {
1172 	struct elink_dev *cb = params->cb;
1173 	u8 i = 0;
1174 	const u8 port = params->port;
1175 	/* MCP Dbg0 and dbg1 are always with higher strict pri*/
1176 	u64 pri_cli_nig = 0x210;
1177 	u32 pri_cli_pbf = 0x0;
1178 	u8 pri_set = 0;
1179 	u8 pri_bitmask = 0;
1180 	const u8 max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1181 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1182 
1183 	u8 cos_bit_to_set = (1 << max_num_of_cos) - 1;
1184 
1185 	/* Set all the strict priority first */
1186 	for (i = 0; i < max_num_of_cos; i++) {
1187 		if (sp_pri_to_cos[i] != DCBX_INVALID_COS) {
1188 			if (sp_pri_to_cos[i] >= ELINK_DCBX_MAX_NUM_COS) {
1189 				ELINK_DEBUG_P0(cb,
1190 					   "elink_ets_e3b0_sp_set_pri_cli_reg "
1191 					   "invalid cos entry\n");
1192 				return ELINK_STATUS_ERROR;
1193 			}
1194 
1195 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1196 			    sp_pri_to_cos[i], pri_set);
1197 
1198 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1199 			    sp_pri_to_cos[i], pri_set);
1200 			pri_bitmask = 1 << sp_pri_to_cos[i];
1201 			/* COS is used remove it from bitmap.*/
1202 			if (!(pri_bitmask & cos_bit_to_set)) {
1203 				ELINK_DEBUG_P0(cb,
1204 					"elink_ets_e3b0_sp_set_pri_cli_reg "
1205 					"invalid There can't be two COS's with"
1206 					" the same strict pri\n");
1207 				return ELINK_STATUS_ERROR;
1208 			}
1209 			cos_bit_to_set &= ~pri_bitmask;
1210 			pri_set++;
1211 		}
1212 	}
1213 
1214 	/* Set all the Non strict priority i= COS*/
1215 	for (i = 0; i < max_num_of_cos; i++) {
1216 		pri_bitmask = 1 << i;
1217 		/* Check if COS was already used for SP */
1218 		if (pri_bitmask & cos_bit_to_set) {
1219 			/* COS wasn't used for SP */
1220 			pri_cli_nig |= elink_e3b0_sp_get_pri_cli_reg_nig(
1221 			    i, pri_set);
1222 
1223 			pri_cli_pbf |= elink_e3b0_sp_get_pri_cli_reg_pbf(
1224 			    i, pri_set);
1225 			/* COS is used remove it from bitmap.*/
1226 			cos_bit_to_set &= ~pri_bitmask;
1227 			pri_set++;
1228 		}
1229 	}
1230 
1231 	if (pri_set != max_num_of_cos) {
1232 		ELINK_DEBUG_P0(cb, "elink_ets_e3b0_sp_set_pri_cli_reg not all "
1233 				   "entries were set\n");
1234 		return ELINK_STATUS_ERROR;
1235 	}
1236 
1237 	if (port) {
1238 		/* Only 6 usable clients*/
1239 		REG_WR(cb, NIG_REG_P1_TX_ARB_PRIORITY_CLIENT2_LSB,
1240 		       (u32)pri_cli_nig);
1241 
1242 		REG_WR(cb, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P1 , pri_cli_pbf);
1243 	} else {
1244 		/* Only 9 usable clients*/
1245 		const u32 pri_cli_nig_lsb = (u32) (pri_cli_nig);
1246 		const u32 pri_cli_nig_msb = (u32) ((pri_cli_nig >> 32) & 0xF);
1247 
1248 		REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_LSB,
1249 		       pri_cli_nig_lsb);
1250 		REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT2_MSB,
1251 		       pri_cli_nig_msb);
1252 
1253 		REG_WR(cb, PBF_REG_ETS_ARB_PRIORITY_CLIENT_P0 , pri_cli_pbf);
1254 	}
1255 	return ELINK_STATUS_OK;
1256 }
1257 
1258 /******************************************************************************
1259 * Description:
1260 *	Configure the COS to ETS according to BW and SP settings.
1261 ******************************************************************************/
elink_ets_e3b0_config(const struct elink_params * params,const struct elink_vars * vars,struct elink_ets_params * ets_params)1262 elink_status_t elink_ets_e3b0_config(const struct elink_params *params,
1263 			 const struct elink_vars *vars,
1264 			 struct elink_ets_params *ets_params)
1265 {
1266 	struct elink_dev *cb = params->cb;
1267 	elink_status_t elink_status = ELINK_STATUS_OK;
1268 	const u8 port = params->port;
1269 	u16 total_bw = 0;
1270 	const u32 min_w_val_nig = elink_ets_get_min_w_val_nig(vars);
1271 	const u32 min_w_val_pbf = ELINK_ETS_E3B0_PBF_MIN_W_VAL;
1272 	u8 cos_bw_bitmap = 0;
1273 	u8 cos_sp_bitmap = 0;
1274 	u8 sp_pri_to_cos[ELINK_DCBX_MAX_NUM_COS] = {0};
1275 	const u8 max_num_of_cos = (port) ? ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1 :
1276 		ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0;
1277 	u8 cos_entry = 0;
1278 
1279 	if (!CHIP_IS_E3B0(params->chip_id)) {
1280 		ELINK_DEBUG_P0(cb,
1281 		   "elink_ets_e3b0_disabled the chip isn't E3B0\n");
1282 		return ELINK_STATUS_ERROR;
1283 	}
1284 
1285 	if ((ets_params->num_of_cos > max_num_of_cos)) {
1286 		ELINK_DEBUG_P0(cb, "elink_ets_E3B0_config the number of COS "
1287 				   "isn't supported\n");
1288 		return ELINK_STATUS_ERROR;
1289 	}
1290 
1291 	/* Prepare sp strict priority parameters*/
1292 	elink_ets_e3b0_sp_pri_to_cos_init(sp_pri_to_cos);
1293 
1294 	/* Prepare BW parameters*/
1295 	elink_status = elink_ets_e3b0_get_total_bw(params, ets_params,
1296 						   &total_bw);
1297 	if (elink_status != ELINK_STATUS_OK) {
1298 		ELINK_DEBUG_P0(cb,
1299 		   "elink_ets_E3B0_config get_total_bw failed\n");
1300 		return ELINK_STATUS_ERROR;
1301 	}
1302 
1303 	/* Upper bound is set according to current link speed (min_w_val
1304 	 * should be the same for upper bound and COS credit val).
1305 	 */
1306 	elink_ets_e3b0_set_credit_upper_bound_nig(params, min_w_val_nig);
1307 	elink_ets_e3b0_set_credit_upper_bound_pbf(params, min_w_val_pbf);
1308 
1309 
1310 	for (cos_entry = 0; cos_entry < ets_params->num_of_cos; cos_entry++) {
1311 		if (elink_cos_state_bw == ets_params->cos[cos_entry].state) {
1312 			cos_bw_bitmap |= (1 << cos_entry);
1313 			/* The function also sets the BW in HW(not the mappin
1314 			 * yet)
1315 			 */
1316 			elink_status = elink_ets_e3b0_set_cos_bw(
1317 				cb, cos_entry, min_w_val_nig, min_w_val_pbf,
1318 				total_bw,
1319 				ets_params->cos[cos_entry].params.bw_params.bw,
1320 				 port);
1321 		} else if (elink_cos_state_strict ==
1322 			ets_params->cos[cos_entry].state){
1323 			cos_sp_bitmap |= (1 << cos_entry);
1324 
1325 			elink_status = elink_ets_e3b0_sp_pri_to_cos_set(
1326 				params,
1327 				sp_pri_to_cos,
1328 				ets_params->cos[cos_entry].params.sp_params.pri,
1329 				cos_entry);
1330 
1331 		} else {
1332 			ELINK_DEBUG_P0(cb,
1333 			   "elink_ets_e3b0_config cos state not valid\n");
1334 			return ELINK_STATUS_ERROR;
1335 		}
1336 		if (elink_status != ELINK_STATUS_OK) {
1337 			ELINK_DEBUG_P0(cb,
1338 			   "elink_ets_e3b0_config set cos bw failed\n");
1339 			return elink_status;
1340 		}
1341 	}
1342 
1343 	/* Set SP register (which COS has higher priority) */
1344 	elink_status = elink_ets_e3b0_sp_set_pri_cli_reg(params,
1345 							 sp_pri_to_cos);
1346 
1347 	if (elink_status != ELINK_STATUS_OK) {
1348 		ELINK_DEBUG_P0(cb,
1349 		   "elink_ets_E3B0_config set_pri_cli_reg failed\n");
1350 		return elink_status;
1351 	}
1352 
1353 	/* Set client mapping of BW and strict */
1354 	elink_status = elink_ets_e3b0_cli_map(params, ets_params,
1355 					      cos_sp_bitmap,
1356 					      cos_bw_bitmap);
1357 
1358 	if (elink_status != ELINK_STATUS_OK) {
1359 		ELINK_DEBUG_P0(cb, "elink_ets_E3B0_config SP failed\n");
1360 		return elink_status;
1361 	}
1362 	return ELINK_STATUS_OK;
1363 }
elink_ets_bw_limit_common(const struct elink_params * params)1364 static void elink_ets_bw_limit_common(const struct elink_params *params)
1365 {
1366 	/* ETS disabled configuration */
1367 	struct elink_dev *cb = params->cb;
1368 	ELINK_DEBUG_P0(cb, "ETS enabled BW limit configuration\n");
1369 	/* Defines which entries (clients) are subjected to WFQ arbitration
1370 	 * COS0 0x8
1371 	 * COS1 0x10
1372 	 */
1373 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_SUBJECT2WFQ, 0x18);
1374 	/* Mapping between the ARB_CREDIT_WEIGHT registers and actual
1375 	 * client numbers (WEIGHT_0 does not actually have to represent
1376 	 * client 0)
1377 	 *    PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1378 	 *  cos1-001     cos0-000     dbg1-100     dbg0-011     MCP-010
1379 	 */
1380 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_CREDIT_MAP, 0x111A);
1381 
1382 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_0,
1383 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1384 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_UPPER_BOUND_1,
1385 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1386 
1387 	/* ETS mode enabled*/
1388 	REG_WR(cb, PBF_REG_ETS_ENABLED, 1);
1389 
1390 	/* Defines the number of consecutive slots for the strict priority */
1391 	REG_WR(cb, PBF_REG_NUM_STRICT_ARB_SLOTS, 0);
1392 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1393 	 * as strict.  Bits 0,1,2 - debug and management entries, 3 - COS0
1394 	 * entry, 4 - COS1 entry.
1395 	 * COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1396 	 * bit4   bit3	  bit2     bit1	   bit0
1397 	 * MCP and debug are strict
1398 	 */
1399 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x7);
1400 
1401 	/* Upper bound that COS0_WEIGHT can reach in the WFQ arbiter.*/
1402 	REG_WR(cb, PBF_REG_COS0_UPPER_BOUND,
1403 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1404 	REG_WR(cb, PBF_REG_COS1_UPPER_BOUND,
1405 	       ELINK_ETS_BW_LIMIT_CREDIT_UPPER_BOUND);
1406 }
1407 
elink_ets_bw_limit(const struct elink_params * params,const u32 cos0_bw,const u32 cos1_bw)1408 void elink_ets_bw_limit(const struct elink_params *params, const u32 cos0_bw,
1409 			const u32 cos1_bw)
1410 {
1411 	/* ETS disabled configuration*/
1412 	struct elink_dev *cb = params->cb;
1413 	const u32 total_bw = cos0_bw + cos1_bw;
1414 	u32 cos0_credit_weight = 0;
1415 	u32 cos1_credit_weight = 0;
1416 
1417 	ELINK_DEBUG_P0(cb, "ETS enabled BW limit configuration\n");
1418 
1419 	if ((!total_bw) ||
1420 	    (!cos0_bw) ||
1421 	    (!cos1_bw)) {
1422 		ELINK_DEBUG_P0(cb, "Total BW can't be zero\n");
1423 		return;
1424 	}
1425 
1426 	cos0_credit_weight = (cos0_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
1427 		total_bw;
1428 	cos1_credit_weight = (cos1_bw * ELINK_ETS_BW_LIMIT_CREDIT_WEIGHT)/
1429 		total_bw;
1430 
1431 	elink_ets_bw_limit_common(params);
1432 
1433 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_0, cos0_credit_weight);
1434 	REG_WR(cb, NIG_REG_P0_TX_ARB_CREDIT_WEIGHT_1, cos1_credit_weight);
1435 
1436 	REG_WR(cb, PBF_REG_COS0_WEIGHT, cos0_credit_weight);
1437 	REG_WR(cb, PBF_REG_COS1_WEIGHT, cos1_credit_weight);
1438 }
1439 
elink_ets_strict(const struct elink_params * params,const u8 strict_cos)1440 elink_status_t elink_ets_strict(const struct elink_params *params, const u8 strict_cos)
1441 {
1442 	/* ETS disabled configuration*/
1443 	struct elink_dev *cb = params->cb;
1444 	u32 val	= 0;
1445 
1446 	ELINK_DEBUG_P0(cb, "ETS enabled strict configuration\n");
1447 	/* Bitmap of 5bits length. Each bit specifies whether the entry behaves
1448 	 * as strict.  Bits 0,1,2 - debug and management entries,
1449 	 * 3 - COS0 entry, 4 - COS1 entry.
1450 	 *  COS1 | COS0 | DEBUG21 | DEBUG0 | MGMT
1451 	 *  bit4   bit3	  bit2      bit1     bit0
1452 	 * MCP and debug are strict
1453 	 */
1454 	REG_WR(cb, NIG_REG_P0_TX_ARB_CLIENT_IS_STRICT, 0x1F);
1455 	/* For strict priority entries defines the number of consecutive slots
1456 	 * for the highest priority.
1457 	 */
1458 	REG_WR(cb, NIG_REG_P0_TX_ARB_NUM_STRICT_ARB_SLOTS, 0x100);
1459 	/* ETS mode disable */
1460 	REG_WR(cb, PBF_REG_ETS_ENABLED, 0);
1461 	/* Defines the number of consecutive slots for the strict priority */
1462 	REG_WR(cb, PBF_REG_NUM_STRICT_ARB_SLOTS, 0x100);
1463 
1464 	/* Defines the number of consecutive slots for the strict priority */
1465 	REG_WR(cb, PBF_REG_HIGH_PRIORITY_COS_NUM, strict_cos);
1466 
1467 	/* Mapping between entry  priority to client number (0,1,2 -debug and
1468 	 * management clients, 3 - COS0 client, 4 - COS client)(HIGHEST)
1469 	 * 3bits client num.
1470 	 *   PRI4    |    PRI3    |    PRI2    |    PRI1    |    PRI0
1471 	 * dbg0-010     dbg1-001     cos1-100     cos0-011     MCP-000
1472 	 * dbg0-010     dbg1-001     cos0-011     cos1-100     MCP-000
1473 	 */
1474 	val = (!strict_cos) ? 0x2318 : 0x22E0;
1475 	REG_WR(cb, NIG_REG_P0_TX_ARB_PRIORITY_CLIENT, val);
1476 
1477 	return ELINK_STATUS_OK;
1478 }
1479 #endif /* ELINK_ENHANCEMENTS */
1480 
1481 /******************************************************************/
1482 /*			PFC section				  */
1483 /******************************************************************/
1484 #ifndef EXCLUDE_NON_COMMON_INIT
1485 #ifndef EXCLUDE_WARPCORE
elink_update_pfc_xmac(struct elink_params * params,struct elink_vars * vars,u8 is_lb)1486 static void elink_update_pfc_xmac(struct elink_params *params,
1487 				  struct elink_vars *vars,
1488 				  u8 is_lb)
1489 {
1490 	struct elink_dev *cb = params->cb;
1491 	u32 xmac_base;
1492 	u32 pause_val, pfc0_val, pfc1_val;
1493 
1494 	/* XMAC base adrr */
1495 	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1496 
1497 	/* Initialize pause and pfc registers */
1498 	pause_val = 0x18000;
1499 	pfc0_val = 0xFFFF8000;
1500 	pfc1_val = 0x2;
1501 
1502 	/* No PFC support */
1503 	if (!(params->feature_config_flags &
1504 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
1505 
1506 		/* RX flow control - Process pause frame in receive direction
1507 		 */
1508 		if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
1509 			pause_val |= XMAC_PAUSE_CTRL_REG_RX_PAUSE_EN;
1510 
1511 		/* TX flow control - Send pause packet when buffer is full */
1512 		if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
1513 			pause_val |= XMAC_PAUSE_CTRL_REG_TX_PAUSE_EN;
1514 	} else {/* PFC support */
1515 		pfc1_val |= XMAC_PFC_CTRL_HI_REG_PFC_REFRESH_EN |
1516 			XMAC_PFC_CTRL_HI_REG_PFC_STATS_EN |
1517 			XMAC_PFC_CTRL_HI_REG_RX_PFC_EN |
1518 			XMAC_PFC_CTRL_HI_REG_TX_PFC_EN |
1519 			XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1520 		/* Write pause and PFC registers */
1521 		REG_WR(cb, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1522 		REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1523 		REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1524 		pfc1_val &= ~XMAC_PFC_CTRL_HI_REG_FORCE_PFC_XON;
1525 
1526 	}
1527 
1528 	/* Write pause and PFC registers */
1529 	REG_WR(cb, xmac_base + XMAC_REG_PAUSE_CTRL, pause_val);
1530 	REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL, pfc0_val);
1531 	REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL_HI, pfc1_val);
1532 
1533 
1534 	/* Set MAC address for source TX Pause/PFC frames */
1535 	REG_WR(cb, xmac_base + XMAC_REG_CTRL_SA_LO,
1536 	       ((params->mac_addr[2] << 24) |
1537 		(params->mac_addr[3] << 16) |
1538 		(params->mac_addr[4] << 8) |
1539 		(params->mac_addr[5])));
1540 	REG_WR(cb, xmac_base + XMAC_REG_CTRL_SA_HI,
1541 	       ((params->mac_addr[0] << 8) |
1542 		(params->mac_addr[1])));
1543 
1544 	USLEEP(cb, 30);
1545 }
1546 
1547 #endif // EXCLUDE_WARPCORE
1548 #endif // #ifndef EXCLUDE_NON_COMMON_INIT
1549 #ifdef ELINK_ENHANCEMENTS
1550 #ifndef BNX2X_UPSTREAM /* ! BNX2X_UPSTREAM */
elink_emac_get_pfc_stat(struct elink_params * params,u32 pfc_frames_sent[2],u32 pfc_frames_received[2])1551 static void elink_emac_get_pfc_stat(struct elink_params *params,
1552 				    u32 pfc_frames_sent[2],
1553 				    u32 pfc_frames_received[2])
1554 {
1555 	/* Read pfc statistic */
1556 	struct elink_dev *cb = params->cb;
1557 	u32 emac_base = params->port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1558 	u32 val_xon = 0;
1559 	u32 val_xoff = 0;
1560 
1561 	ELINK_DEBUG_P0(cb, "pfc statistic read from EMAC\n");
1562 
1563 	/* PFC received frames */
1564 	val_xoff = REG_RD(cb, emac_base +
1565 				EMAC_REG_RX_PFC_STATS_XOFF_RCVD);
1566 	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_RCVD_COUNT;
1567 	val_xon = REG_RD(cb, emac_base + EMAC_REG_RX_PFC_STATS_XON_RCVD);
1568 	val_xon &= EMAC_REG_RX_PFC_STATS_XON_RCVD_COUNT;
1569 
1570 	pfc_frames_received[0] = val_xon + val_xoff;
1571 
1572 	/* PFC received sent */
1573 	val_xoff = REG_RD(cb, emac_base +
1574 				EMAC_REG_RX_PFC_STATS_XOFF_SENT);
1575 	val_xoff &= EMAC_REG_RX_PFC_STATS_XOFF_SENT_COUNT;
1576 	val_xon = REG_RD(cb, emac_base + EMAC_REG_RX_PFC_STATS_XON_SENT);
1577 	val_xon &= EMAC_REG_RX_PFC_STATS_XON_SENT_COUNT;
1578 
1579 	pfc_frames_sent[0] = val_xon + val_xoff;
1580 }
1581 
1582 /* Read pfc statistic*/
elink_pfc_statistic(struct elink_params * params,struct elink_vars * vars,u32 pfc_frames_sent[2],u32 pfc_frames_received[2])1583 void elink_pfc_statistic(struct elink_params *params, struct elink_vars *vars,
1584 			 u32 pfc_frames_sent[2],
1585 			 u32 pfc_frames_received[2])
1586 {
1587 	/* Read pfc statistic */
1588 	struct elink_dev *cb = params->cb;
1589 
1590 	ELINK_DEBUG_P0(cb, "pfc statistic\n");
1591 
1592 	if (!vars->link_up)
1593 		return;
1594 
1595 	if (vars->mac_type == ELINK_MAC_TYPE_EMAC) {
1596 		ELINK_DEBUG_P0(cb, "About to read PFC stats from EMAC\n");
1597 		elink_emac_get_pfc_stat(params, pfc_frames_sent,
1598 					pfc_frames_received);
1599 	}
1600 }
1601 #endif /* ! BNX2X_UPSTREAM */
1602 #endif /* ELINK_ENHANCEMENTS */
1603 /******************************************************************/
1604 /*			MAC/PBF section				  */
1605 /******************************************************************/
elink_set_mdio_clk(struct elink_dev * cb,u32 chip_id,u32 emac_base)1606 static void elink_set_mdio_clk(struct elink_dev *cb, u32 chip_id,
1607 			       u32 emac_base)
1608 {
1609 	u32 new_mode, cur_mode;
1610 	u32 clc_cnt;
1611 	/* Set clause 45 mode, slow down the MDIO clock to 2.5MHz
1612 	 * (a value of 49==0x31) and make sure that the AUTO poll is off
1613 	 */
1614 	cur_mode = REG_RD(cb, emac_base + EMAC_REG_EMAC_MDIO_MODE);
1615 
1616 	if (ELINK_USES_WARPCORE(chip_id))
1617 		clc_cnt = 74L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1618 	else
1619 		clc_cnt = 49L << EMAC_MDIO_MODE_CLOCK_CNT_BITSHIFT;
1620 
1621 	if (((cur_mode & EMAC_MDIO_MODE_CLOCK_CNT) == clc_cnt) &&
1622 	    (cur_mode & (EMAC_MDIO_MODE_CLAUSE_45)))
1623 		return;
1624 
1625 	new_mode = cur_mode &
1626 		~(EMAC_MDIO_MODE_AUTO_POLL | EMAC_MDIO_MODE_CLOCK_CNT);
1627 	new_mode |= clc_cnt;
1628 	new_mode |= (EMAC_MDIO_MODE_CLAUSE_45);
1629 
1630 	ELINK_DEBUG_P2(cb, "Changing emac_mode from 0x%x to 0x%x\n",
1631 	   cur_mode, new_mode);
1632 	REG_WR(cb, emac_base + EMAC_REG_EMAC_MDIO_MODE, new_mode);
1633 	USLEEP(cb, 40);
1634 }
1635 
1636 #ifndef EXCLUDE_WARPCORE
elink_is_4_port_mode(struct elink_dev * cb)1637 static u8 elink_is_4_port_mode(struct elink_dev *cb)
1638 {
1639 	u32 port4mode_ovwr_val;
1640 	/* Check 4-port override enabled */
1641 	port4mode_ovwr_val = REG_RD(cb, MISC_REG_PORT4MODE_EN_OVWR);
1642 	if (port4mode_ovwr_val & (1<<0)) {
1643 		/* Return 4-port mode override value */
1644 		return ((port4mode_ovwr_val & (1<<1)) == (1<<1));
1645 	}
1646 	/* Return 4-port mode from input pin */
1647 	return (u8)REG_RD(cb, MISC_REG_PORT4MODE_EN);
1648 }
1649 #endif
1650 
1651 #ifndef EXCLUDE_NON_COMMON_INIT
elink_set_mdio_emac_per_phy(struct elink_dev * cb,struct elink_params * params)1652 static void elink_set_mdio_emac_per_phy(struct elink_dev *cb,
1653 					struct elink_params *params)
1654 {
1655 	u8 phy_index;
1656 
1657 	/* Set mdio clock per phy */
1658 	for (phy_index = ELINK_INT_PHY; phy_index < params->num_phys;
1659 	      phy_index++)
1660 		elink_set_mdio_clk(cb, params->chip_id,
1661 				   params->phy[phy_index].mdio_ctrl);
1662 }
1663 
elink_emac_init(struct elink_params * params,struct elink_vars * vars)1664 static void elink_emac_init(struct elink_params *params,
1665 			    struct elink_vars *vars)
1666 {
1667 	/* reset and unreset the emac core */
1668 	struct elink_dev *cb = params->cb;
1669 	u8 port = params->port;
1670 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
1671 	u32 val;
1672 	u16 timeout;
1673 
1674 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1675 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1676 	USLEEP(cb, 5);
1677 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1678 	       (MISC_REGISTERS_RESET_REG_2_RST_EMAC0_HARD_CORE << port));
1679 
1680 	/* init emac - use read-modify-write */
1681 	/* self clear reset */
1682 	val = REG_RD(cb, emac_base + EMAC_REG_EMAC_MODE);
1683 	EMAC_WR(cb, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_RESET));
1684 
1685 	timeout = 200;
1686 	do {
1687 		val = REG_RD(cb, emac_base + EMAC_REG_EMAC_MODE);
1688 		ELINK_DEBUG_P1(cb, "EMAC reset reg is %u\n", val);
1689 		if (!timeout) {
1690 			ELINK_DEBUG_P0(cb, "EMAC timeout!\n");
1691 			return;
1692 		}
1693 		timeout--;
1694 	} while (val & EMAC_MODE_RESET);
1695 
1696 	elink_set_mdio_emac_per_phy(cb, params);
1697 	/* Set mac address */
1698 	val = ((params->mac_addr[0] << 8) |
1699 		params->mac_addr[1]);
1700 	EMAC_WR(cb, EMAC_REG_EMAC_MAC_MATCH, val);
1701 
1702 	val = ((params->mac_addr[2] << 24) |
1703 	       (params->mac_addr[3] << 16) |
1704 	       (params->mac_addr[4] << 8) |
1705 		params->mac_addr[5]);
1706 	EMAC_WR(cb, EMAC_REG_EMAC_MAC_MATCH + 4, val);
1707 }
1708 
1709 #ifndef EXCLUDE_WARPCORE
elink_set_xumac_nig(struct elink_params * params,u16 tx_pause_en,u8 enable)1710 static void elink_set_xumac_nig(struct elink_params *params,
1711 				u16 tx_pause_en,
1712 				u8 enable)
1713 {
1714 	struct elink_dev *cb = params->cb;
1715 
1716 	REG_WR(cb, params->port ? NIG_REG_P1_MAC_IN_EN : NIG_REG_P0_MAC_IN_EN,
1717 	       enable);
1718 	REG_WR(cb, params->port ? NIG_REG_P1_MAC_OUT_EN : NIG_REG_P0_MAC_OUT_EN,
1719 	       enable);
1720 	REG_WR(cb, params->port ? NIG_REG_P1_MAC_PAUSE_OUT_EN :
1721 	       NIG_REG_P0_MAC_PAUSE_OUT_EN, tx_pause_en);
1722 }
1723 
elink_set_umac_rxtx(struct elink_params * params,u8 en)1724 static void elink_set_umac_rxtx(struct elink_params *params, u8 en)
1725 {
1726 	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1727 	u32 val;
1728 	struct elink_dev *cb = params->cb;
1729 	if (!(REG_RD(cb, MISC_REG_RESET_REG_2) &
1730 		   (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port)))
1731 		return;
1732 	val = REG_RD(cb, umac_base + UMAC_REG_COMMAND_CONFIG);
1733 	if (en)
1734 		val |= (UMAC_COMMAND_CONFIG_REG_TX_ENA |
1735 			UMAC_COMMAND_CONFIG_REG_RX_ENA);
1736 	else
1737 		val &= ~(UMAC_COMMAND_CONFIG_REG_TX_ENA |
1738 			 UMAC_COMMAND_CONFIG_REG_RX_ENA);
1739 	/* Disable RX and TX */
1740 	REG_WR(cb, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1741 }
1742 
elink_umac_enable(struct elink_params * params,struct elink_vars * vars,u8 lb)1743 static void elink_umac_enable(struct elink_params *params,
1744 			    struct elink_vars *vars, u8 lb)
1745 {
1746 	u32 val;
1747 	u32 umac_base = params->port ? GRCBASE_UMAC1 : GRCBASE_UMAC0;
1748 	struct elink_dev *cb = params->cb;
1749 	/* Reset UMAC */
1750 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1751 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1752 	MSLEEP(cb, 1);
1753 
1754 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1755 	       (MISC_REGISTERS_RESET_REG_2_UMAC0 << params->port));
1756 
1757 	ELINK_DEBUG_P0(cb, "enabling UMAC\n");
1758 
1759 	/* This register opens the gate for the UMAC despite its name */
1760 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 1);
1761 
1762 	val = UMAC_COMMAND_CONFIG_REG_PROMIS_EN |
1763 		UMAC_COMMAND_CONFIG_REG_PAD_EN |
1764 		UMAC_COMMAND_CONFIG_REG_SW_RESET |
1765 		UMAC_COMMAND_CONFIG_REG_NO_LGTH_CHECK;
1766 	switch (vars->line_speed) {
1767 	case ELINK_SPEED_10:
1768 		val |= (0<<2);
1769 		break;
1770 	case ELINK_SPEED_100:
1771 		val |= (1<<2);
1772 		break;
1773 	case ELINK_SPEED_1000:
1774 		val |= (2<<2);
1775 		break;
1776 	case ELINK_SPEED_2500:
1777 		val |= (3<<2);
1778 		break;
1779 	default:
1780 		ELINK_DEBUG_P1(cb, "Invalid speed for UMAC %d\n",
1781 			       vars->line_speed);
1782 		break;
1783 	}
1784 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
1785 		val |= UMAC_COMMAND_CONFIG_REG_IGNORE_TX_PAUSE;
1786 
1787 	if (!(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
1788 		val |= UMAC_COMMAND_CONFIG_REG_PAUSE_IGNORE;
1789 
1790 	if (vars->duplex == DUPLEX_HALF)
1791 		val |= UMAC_COMMAND_CONFIG_REG_HD_ENA;
1792 
1793 	REG_WR(cb, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1794 	USLEEP(cb, 50);
1795 
1796 	/* Configure UMAC for EEE */
1797 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1798 		ELINK_DEBUG_P0(cb, "configured UMAC for EEE\n");
1799 		REG_WR(cb, umac_base + UMAC_REG_UMAC_EEE_CTRL,
1800 		       UMAC_UMAC_EEE_CTRL_REG_EEE_EN);
1801 		REG_WR(cb, umac_base + UMAC_REG_EEE_WAKE_TIMER, 0x11);
1802 	} else {
1803 		REG_WR(cb, umac_base + UMAC_REG_UMAC_EEE_CTRL, 0x0);
1804 	}
1805 
1806 	/* Set MAC address for source TX Pause/PFC frames (under SW reset) */
1807 	REG_WR(cb, umac_base + UMAC_REG_MAC_ADDR0,
1808 	       ((params->mac_addr[2] << 24) |
1809 		(params->mac_addr[3] << 16) |
1810 		(params->mac_addr[4] << 8) |
1811 		(params->mac_addr[5])));
1812 	REG_WR(cb, umac_base + UMAC_REG_MAC_ADDR1,
1813 	       ((params->mac_addr[0] << 8) |
1814 		(params->mac_addr[1])));
1815 
1816 	/* Enable RX and TX */
1817 	val &= ~UMAC_COMMAND_CONFIG_REG_PAD_EN;
1818 	val |= UMAC_COMMAND_CONFIG_REG_TX_ENA |
1819 		UMAC_COMMAND_CONFIG_REG_RX_ENA;
1820 	REG_WR(cb, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1821 	USLEEP(cb, 50);
1822 
1823 	/* Remove SW Reset */
1824 	val &= ~UMAC_COMMAND_CONFIG_REG_SW_RESET;
1825 
1826 	/* Check loopback mode */
1827 	if (lb)
1828 		val |= UMAC_COMMAND_CONFIG_REG_LOOP_ENA;
1829 	REG_WR(cb, umac_base + UMAC_REG_COMMAND_CONFIG, val);
1830 
1831 	/* Maximum Frame Length (RW). Defines a 14-Bit maximum frame
1832 	 * length used by the MAC receive logic to check frames.
1833 	 */
1834 	REG_WR(cb, umac_base + UMAC_REG_MAXFR, 0x2710);
1835 	elink_set_xumac_nig(params,
1836 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
1837 	vars->mac_type = ELINK_MAC_TYPE_UMAC;
1838 
1839 }
1840 
1841 /* Define the XMAC mode */
elink_xmac_init(struct elink_params * params,u32 max_speed)1842 static void elink_xmac_init(struct elink_params *params, u32 max_speed)
1843 {
1844 	struct elink_dev *cb = params->cb;
1845 	u32 is_port4mode = elink_is_4_port_mode(cb);
1846 
1847 	/* In 4-port mode, need to set the mode only once, so if XMAC is
1848 	 * already out of reset, it means the mode has already been set,
1849 	 * and it must not* reset the XMAC again, since it controls both
1850 	 * ports of the path
1851 	 */
1852 
1853 	if (((CHIP_NUM(params->chip_id) == CHIP_NUM_57840_4_10) ||
1854 	     (CHIP_NUM(params->chip_id) == CHIP_NUM_57840_2_20) ||
1855 	     (CHIP_NUM(params->chip_id) == CHIP_NUM_57840_OBSOLETE)) &&
1856 	    is_port4mode &&
1857 	    (REG_RD(cb, MISC_REG_RESET_REG_2) &
1858 	     MISC_REGISTERS_RESET_REG_2_XMAC)) {
1859 		ELINK_DEBUG_P0(cb,
1860 		   "XMAC already out of reset in 4-port mode\n");
1861 		return;
1862 	}
1863 
1864 	/* Hard reset */
1865 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1866 	       MISC_REGISTERS_RESET_REG_2_XMAC);
1867 	MSLEEP(cb, 1);
1868 
1869 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1870 	       MISC_REGISTERS_RESET_REG_2_XMAC);
1871 	if (is_port4mode) {
1872 		ELINK_DEBUG_P0(cb, "Init XMAC to 2 ports x 10G per path\n");
1873 
1874 		/* Set the number of ports on the system side to up to 2 */
1875 		REG_WR(cb, MISC_REG_XMAC_CORE_PORT_MODE, 1);
1876 
1877 		/* Set the number of ports on the Warp Core to 10G */
1878 		REG_WR(cb, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1879 	} else {
1880 		/* Set the number of ports on the system side to 1 */
1881 		REG_WR(cb, MISC_REG_XMAC_CORE_PORT_MODE, 0);
1882 		if (max_speed == ELINK_SPEED_10000) {
1883 			ELINK_DEBUG_P0(cb,
1884 			   "Init XMAC to 10G x 1 port per path\n");
1885 			/* Set the number of ports on the Warp Core to 10G */
1886 			REG_WR(cb, MISC_REG_XMAC_PHY_PORT_MODE, 3);
1887 		} else {
1888 			ELINK_DEBUG_P0(cb,
1889 			   "Init XMAC to 20G x 2 ports per path\n");
1890 			/* Set the number of ports on the Warp Core to 20G */
1891 			REG_WR(cb, MISC_REG_XMAC_PHY_PORT_MODE, 1);
1892 		}
1893 	}
1894 	/* Soft reset */
1895 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
1896 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1897 	MSLEEP(cb, 1);
1898 
1899 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
1900 	       MISC_REGISTERS_RESET_REG_2_XMAC_SOFT);
1901 
1902 }
1903 
elink_set_xmac_rxtx(struct elink_params * params,u8 en)1904 static void elink_set_xmac_rxtx(struct elink_params *params, u8 en)
1905 {
1906 	u8 port = params->port;
1907 	struct elink_dev *cb = params->cb;
1908 	u32 pfc_ctrl, xmac_base = (port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1909 	u32 val;
1910 
1911 	if (REG_RD(cb, MISC_REG_RESET_REG_2) &
1912 	    MISC_REGISTERS_RESET_REG_2_XMAC) {
1913 		/* Send an indication to change the state in the NIG back to XON
1914 		 * Clearing this bit enables the next set of this bit to get
1915 		 * rising edge
1916 		 */
1917 		pfc_ctrl = REG_RD(cb, xmac_base + XMAC_REG_PFC_CTRL_HI);
1918 		REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL_HI,
1919 		       (pfc_ctrl & ~(1<<1)));
1920 		REG_WR(cb, xmac_base + XMAC_REG_PFC_CTRL_HI,
1921 		       (pfc_ctrl | (1<<1)));
1922 		ELINK_DEBUG_P1(cb, "Disable XMAC on port %x\n", port);
1923 		val = REG_RD(cb, xmac_base + XMAC_REG_CTRL);
1924 		if (en)
1925 			val |= (XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1926 		else
1927 			val &= ~(XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN);
1928 		REG_WR(cb, xmac_base + XMAC_REG_CTRL, val);
1929 	}
1930 }
1931 
elink_xmac_enable(struct elink_params * params,struct elink_vars * vars,u8 lb)1932 static elink_status_t elink_xmac_enable(struct elink_params *params,
1933 			     struct elink_vars *vars, u8 lb)
1934 {
1935 	u32 val, xmac_base;
1936 	struct elink_dev *cb = params->cb;
1937 	ELINK_DEBUG_P0(cb, "enabling XMAC\n");
1938 
1939 	xmac_base = (params->port) ? GRCBASE_XMAC1 : GRCBASE_XMAC0;
1940 
1941 	elink_xmac_init(params, vars->line_speed);
1942 
1943 	/* This register determines on which events the MAC will assert
1944 	 * error on the i/f to the NIG along w/ EOP.
1945 	 */
1946 
1947 	/* This register tells the NIG whether to send traffic to UMAC
1948 	 * or XMAC
1949 	 */
1950 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_PORT + params->port*4, 0);
1951 
1952 	/* When XMAC is in XLGMII mode, disable sending idles for fault
1953 	 * detection.
1954 	 */
1955 	if (!(params->phy[ELINK_INT_PHY].flags & ELINK_FLAGS_TX_ERROR_CHECK)) {
1956 		REG_WR(cb, xmac_base + XMAC_REG_RX_LSS_CTRL,
1957 		       (XMAC_RX_LSS_CTRL_REG_LOCAL_FAULT_DISABLE |
1958 			XMAC_RX_LSS_CTRL_REG_REMOTE_FAULT_DISABLE));
1959 		REG_WR(cb, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS, 0);
1960 		REG_WR(cb, xmac_base + XMAC_REG_CLEAR_RX_LSS_STATUS,
1961 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_LOCAL_FAULT_STATUS |
1962 		       XMAC_CLEAR_RX_LSS_STATUS_REG_CLEAR_REMOTE_FAULT_STATUS);
1963 	}
1964 	/* Set Max packet size */
1965 	REG_WR(cb, xmac_base + XMAC_REG_RX_MAX_SIZE, 0x2710);
1966 
1967 	/* CRC append for Tx packets */
1968 	REG_WR(cb, xmac_base + XMAC_REG_TX_CTRL, 0xC800);
1969 
1970 	/* update PFC */
1971 	elink_update_pfc_xmac(params, vars, 0);
1972 
1973 	if (vars->eee_status & SHMEM_EEE_ADV_STATUS_MASK) {
1974 		ELINK_DEBUG_P0(cb, "Setting XMAC for EEE\n");
1975 		REG_WR(cb, xmac_base + XMAC_REG_EEE_TIMERS_HI, 0x1380008);
1976 		REG_WR(cb, xmac_base + XMAC_REG_EEE_CTRL, 0x1);
1977 	} else {
1978 		REG_WR(cb, xmac_base + XMAC_REG_EEE_CTRL, 0x0);
1979 	}
1980 
1981 	/* Enable TX and RX */
1982 	val = XMAC_CTRL_REG_TX_EN | XMAC_CTRL_REG_RX_EN;
1983 
1984 	/* Set MAC in XLGMII mode for dual-mode */
1985 	if ((vars->line_speed == ELINK_SPEED_20000) &&
1986 	    (params->phy[ELINK_INT_PHY].supported &
1987 	     ELINK_SUPPORTED_20000baseKR2_Full))
1988 		val |= XMAC_CTRL_REG_XLGMII_ALIGN_ENB;
1989 
1990 	/* Check loopback mode */
1991 	if (lb)
1992 		val |= XMAC_CTRL_REG_LINE_LOCAL_LPBK;
1993 	REG_WR(cb, xmac_base + XMAC_REG_CTRL, val);
1994 	elink_set_xumac_nig(params,
1995 			    ((vars->flow_ctrl & ELINK_FLOW_CTRL_TX) != 0), 1);
1996 
1997 	vars->mac_type = ELINK_MAC_TYPE_XMAC;
1998 
1999 	return ELINK_STATUS_OK;
2000 }
2001 #endif // EXCLUDE_WARPCORE
2002 
2003 #ifndef EXCLUDE_EMAC
elink_emac_enable(struct elink_params * params,struct elink_vars * vars,u8 lb)2004 static elink_status_t elink_emac_enable(struct elink_params *params,
2005 			     struct elink_vars *vars, u8 lb)
2006 {
2007 	struct elink_dev *cb = params->cb;
2008 	u8 port = params->port;
2009 	u32 emac_base = port ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2010 	u32 val;
2011 
2012 	ELINK_DEBUG_P0(cb, "enabling EMAC\n");
2013 
2014 	/* Disable BMAC */
2015 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2016 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2017 
2018 	/* enable emac and not bmac */
2019 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_PORT + port*4, 1);
2020 
2021 #ifdef ELINK_INCLUDE_EMUL
2022 	/* for paladium */
2023 	if (CHIP_REV_IS_EMUL(params->chip_id)) {
2024 		/* Use lane 1 (of lanes 0-3) */
2025 		REG_WR(cb, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2026 		REG_WR(cb, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2027 	}
2028 	/* for fpga */
2029 	else
2030 #endif
2031 #ifdef ELINK_INCLUDE_FPGA
2032 	if (CHIP_REV_IS_FPGA(params->chip_id)) {
2033 		/* Use lane 1 (of lanes 0-3) */
2034 		ELINK_DEBUG_P0(cb, "elink_emac_enable: Setting FPGA\n");
2035 
2036 		REG_WR(cb, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 1);
2037 		REG_WR(cb, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2038 	} else
2039 #endif
2040 	/* ASIC */
2041 	if (vars->phy_flags & PHY_XGXS_FLAG) {
2042 		u32 ser_lane = ((params->lane_config &
2043 				 PORT_HW_CFG_LANE_SWAP_CFG_MASTER_MASK) >>
2044 				PORT_HW_CFG_LANE_SWAP_CFG_MASTER_SHIFT);
2045 
2046 		ELINK_DEBUG_P0(cb, "XGXS\n");
2047 		/* select the master lanes (out of 0-3) */
2048 		REG_WR(cb, NIG_REG_XGXS_LANE_SEL_P0 + port*4, ser_lane);
2049 		/* select XGXS */
2050 		REG_WR(cb, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 1);
2051 
2052 	} else { /* SerDes */
2053 		ELINK_DEBUG_P0(cb, "SerDes\n");
2054 		/* select SerDes */
2055 		REG_WR(cb, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0);
2056 	}
2057 
2058 	elink_bits_en(cb, emac_base + EMAC_REG_EMAC_RX_MODE,
2059 		      EMAC_RX_MODE_RESET);
2060 	elink_bits_en(cb, emac_base + EMAC_REG_EMAC_TX_MODE,
2061 		      EMAC_TX_MODE_RESET);
2062 
2063 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2064 	if (CHIP_REV_IS_SLOW(params->chip_id)) {
2065 		/* config GMII mode */
2066 		val = REG_RD(cb, emac_base + EMAC_REG_EMAC_MODE);
2067 		EMAC_WR(cb, EMAC_REG_EMAC_MODE, (val | EMAC_MODE_PORT_GMII));
2068 	} else { /* ASIC */
2069 #endif /* defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)*/
2070 		/* pause enable/disable */
2071 		elink_bits_dis(cb, emac_base + EMAC_REG_EMAC_RX_MODE,
2072 			       EMAC_RX_MODE_FLOW_EN);
2073 
2074 		elink_bits_dis(cb,  emac_base + EMAC_REG_EMAC_TX_MODE,
2075 			       (EMAC_TX_MODE_EXT_PAUSE_EN |
2076 				EMAC_TX_MODE_FLOW_EN));
2077 		if (!(params->feature_config_flags &
2078 		      ELINK_FEATURE_CONFIG_PFC_ENABLED)) {
2079 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_RX)
2080 				elink_bits_en(cb, emac_base +
2081 					      EMAC_REG_EMAC_RX_MODE,
2082 					      EMAC_RX_MODE_FLOW_EN);
2083 
2084 			if (vars->flow_ctrl & ELINK_FLOW_CTRL_TX)
2085 				elink_bits_en(cb, emac_base +
2086 					      EMAC_REG_EMAC_TX_MODE,
2087 					      (EMAC_TX_MODE_EXT_PAUSE_EN |
2088 					       EMAC_TX_MODE_FLOW_EN));
2089 		} else
2090 			elink_bits_en(cb, emac_base + EMAC_REG_EMAC_TX_MODE,
2091 				      EMAC_TX_MODE_FLOW_EN);
2092 #if defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA)
2093 	}
2094 #endif /* defined(ELINK_INCLUDE_EMUL) || defined(ELINK_INCLUDE_FPGA) */
2095 
2096 	/* KEEP_VLAN_TAG, promiscuous */
2097 	val = REG_RD(cb, emac_base + EMAC_REG_EMAC_RX_MODE);
2098 	val |= EMAC_RX_MODE_KEEP_VLAN_TAG | EMAC_RX_MODE_PROMISCUOUS;
2099 
2100 	/* Setting this bit causes MAC control frames (except for pause
2101 	 * frames) to be passed on for processing. This setting has no
2102 	 * affect on the operation of the pause frames. This bit effects
2103 	 * all packets regardless of RX Parser packet sorting logic.
2104 	 * Turn the PFC off to make sure we are in Xon state before
2105 	 * enabling it.
2106 	 */
2107 	EMAC_WR(cb, EMAC_REG_RX_PFC_MODE, 0);
2108 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2109 		ELINK_DEBUG_P0(cb, "PFC is enabled\n");
2110 		/* Enable PFC again */
2111 		EMAC_WR(cb, EMAC_REG_RX_PFC_MODE,
2112 			EMAC_REG_RX_PFC_MODE_RX_EN |
2113 			EMAC_REG_RX_PFC_MODE_TX_EN |
2114 			EMAC_REG_RX_PFC_MODE_PRIORITIES);
2115 
2116 		EMAC_WR(cb, EMAC_REG_RX_PFC_PARAM,
2117 			((0x0101 <<
2118 			  EMAC_REG_RX_PFC_PARAM_OPCODE_BITSHIFT) |
2119 			 (0x00ff <<
2120 			  EMAC_REG_RX_PFC_PARAM_PRIORITY_EN_BITSHIFT)));
2121 		val |= EMAC_RX_MODE_KEEP_MAC_CONTROL;
2122 	}
2123 	EMAC_WR(cb, EMAC_REG_EMAC_RX_MODE, val);
2124 
2125 	/* Set Loopback */
2126 	val = REG_RD(cb, emac_base + EMAC_REG_EMAC_MODE);
2127 	if (lb)
2128 		val |= 0x810;
2129 	else
2130 		val &= ~0x810;
2131 	EMAC_WR(cb, EMAC_REG_EMAC_MODE, val);
2132 
2133 	/* Enable emac */
2134 	REG_WR(cb, NIG_REG_NIG_EMAC0_EN + port*4, 1);
2135 
2136 #ifndef ELINK_AUX_POWER
2137 	/* Enable emac for jumbo packets */
2138 	EMAC_WR(cb, EMAC_REG_EMAC_RX_MTU_SIZE,
2139 		(EMAC_RX_MTU_SIZE_JUMBO_ENA |
2140 		 (ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD)));
2141 #endif
2142 
2143 	/* Strip CRC */
2144 	REG_WR(cb, NIG_REG_NIG_INGRESS_EMAC0_NO_CRC + port*4, 0x1);
2145 
2146 	/* Disable the NIG in/out to the bmac */
2147 	REG_WR(cb, NIG_REG_BMAC0_IN_EN + port*4, 0x0);
2148 	REG_WR(cb, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, 0x0);
2149 	REG_WR(cb, NIG_REG_BMAC0_OUT_EN + port*4, 0x0);
2150 
2151 	/* Enable the NIG in/out to the emac */
2152 	REG_WR(cb, NIG_REG_EMAC0_IN_EN + port*4, 0x1);
2153 	val = 0;
2154 	if ((params->feature_config_flags &
2155 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2156 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2157 		val = 1;
2158 
2159 	REG_WR(cb, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, val);
2160 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x1);
2161 
2162 #ifdef ELINK_INCLUDE_EMUL
2163 	if (CHIP_REV_IS_EMUL(params->chip_id)) {
2164 		/* Take the BigMac out of reset */
2165 		REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2166 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2167 
2168 		/* Enable access for bmac registers */
2169 		REG_WR(cb, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2170 	} else
2171 #endif /* ELINK_INCLUDE_EMUL */
2172 	REG_WR(cb, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x0);
2173 
2174 	vars->mac_type = ELINK_MAC_TYPE_EMAC;
2175 	return ELINK_STATUS_OK;
2176 }
2177 
2178 #endif //EXCLUDE_EMAC
2179 #ifndef EXCLUDE_BMAC1
elink_update_pfc_bmac1(struct elink_params * params,struct elink_vars * vars)2180 static void elink_update_pfc_bmac1(struct elink_params *params,
2181 				   struct elink_vars *vars)
2182 {
2183 	u32 wb_data[2];
2184 	struct elink_dev *cb = params->cb;
2185 	u32 bmac_addr =  params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2186 		NIG_REG_INGRESS_BMAC0_MEM;
2187 
2188 	u32 val = 0x14;
2189 	if ((!(params->feature_config_flags &
2190 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2191 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2192 		/* Enable BigMAC to react on received Pause packets */
2193 		val |= (1<<5);
2194 	wb_data[0] = val;
2195 	wb_data[1] = 0;
2196 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_RX_CONTROL, wb_data, 2);
2197 
2198 	/* TX control */
2199 	val = 0xc0;
2200 	if (!(params->feature_config_flags &
2201 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2202 		(vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2203 		val |= 0x800000;
2204 	wb_data[0] = val;
2205 	wb_data[1] = 0;
2206 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_TX_CONTROL, wb_data, 2);
2207 }
2208 #endif // EXCLUDE_BMAC1
2209 
2210 #ifndef EXCLUDE_BMAC2
elink_update_pfc_bmac2(struct elink_params * params,struct elink_vars * vars,u8 is_lb)2211 static void elink_update_pfc_bmac2(struct elink_params *params,
2212 				   struct elink_vars *vars,
2213 				   u8 is_lb)
2214 {
2215 	/* Set rx control: Strip CRC and enable BigMAC to relay
2216 	 * control packets to the system as well
2217 	 */
2218 	u32 wb_data[2];
2219 	struct elink_dev *cb = params->cb;
2220 	u32 bmac_addr = params->port ? NIG_REG_INGRESS_BMAC1_MEM :
2221 		NIG_REG_INGRESS_BMAC0_MEM;
2222 	u32 val = 0x14;
2223 
2224 	if ((!(params->feature_config_flags &
2225 	      ELINK_FEATURE_CONFIG_PFC_ENABLED)) &&
2226 		(vars->flow_ctrl & ELINK_FLOW_CTRL_RX))
2227 		/* Enable BigMAC to react on received Pause packets */
2228 		val |= (1<<5);
2229 	wb_data[0] = val;
2230 	wb_data[1] = 0;
2231 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_RX_CONTROL, wb_data, 2);
2232 	USLEEP(cb, 30);
2233 
2234 	/* Tx control */
2235 	val = 0xc0;
2236 	if (!(params->feature_config_flags &
2237 				ELINK_FEATURE_CONFIG_PFC_ENABLED) &&
2238 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2239 		val |= 0x800000;
2240 	wb_data[0] = val;
2241 	wb_data[1] = 0;
2242 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_TX_CONTROL, wb_data, 2);
2243 
2244 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED) {
2245 		ELINK_DEBUG_P0(cb, "PFC is enabled\n");
2246 		/* Enable PFC RX & TX & STATS and set 8 COS  */
2247 		wb_data[0] = 0x0;
2248 		wb_data[0] |= (1<<0);  /* RX */
2249 		wb_data[0] |= (1<<1);  /* TX */
2250 		wb_data[0] |= (1<<2);  /* Force initial Xon */
2251 		wb_data[0] |= (1<<3);  /* 8 cos */
2252 		wb_data[0] |= (1<<5);  /* STATS */
2253 		wb_data[1] = 0;
2254 		REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL,
2255 			    wb_data, 2);
2256 		/* Clear the force Xon */
2257 		wb_data[0] &= ~(1<<2);
2258 	} else {
2259 		ELINK_DEBUG_P0(cb, "PFC is disabled\n");
2260 		/* Disable PFC RX & TX & STATS and set 8 COS */
2261 		wb_data[0] = 0x8;
2262 		wb_data[1] = 0;
2263 	}
2264 
2265 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_PFC_CONTROL, wb_data, 2);
2266 
2267 	/* Set Time (based unit is 512 bit time) between automatic
2268 	 * re-sending of PP packets amd enable automatic re-send of
2269 	 * Per-Priroity Packet as long as pp_gen is asserted and
2270 	 * pp_disable is low.
2271 	 */
2272 	val = 0x8000;
2273 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2274 		val |= (1<<16); /* enable automatic re-send */
2275 
2276 	wb_data[0] = val;
2277 	wb_data[1] = 0;
2278 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_TX_PAUSE_CONTROL,
2279 		    wb_data, 2);
2280 
2281 	/* mac control */
2282 	val = 0x3; /* Enable RX and TX */
2283 	if (is_lb) {
2284 		val |= 0x4; /* Local loopback */
2285 		ELINK_DEBUG_P0(cb, "enable bmac loopback\n");
2286 	}
2287 	/* When PFC enabled, Pass pause frames towards the NIG. */
2288 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2289 		val |= ((1<<6)|(1<<5));
2290 
2291 	wb_data[0] = val;
2292 	wb_data[1] = 0;
2293 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2294 }
2295 #endif // EXCLUDE_BMAC2
2296 #endif // EXCLUDE_NON_COMMON_INIT
2297 #ifdef ELINK_ENHANCEMENTS
2298 
2299 /******************************************************************************
2300 * Description:
2301 *  This function is needed because NIG ARB_CREDIT_WEIGHT_X are
2302 *  not continues and ARB_CREDIT_WEIGHT_0 + offset is suitable.
2303 ******************************************************************************/
elink_pfc_nig_rx_priority_mask(struct elink_dev * cb,u8 cos_entry,u32 priority_mask,u8 port)2304 static elink_status_t elink_pfc_nig_rx_priority_mask(struct elink_dev *cb,
2305 					   u8 cos_entry,
2306 					   u32 priority_mask, u8 port)
2307 {
2308 	u32 nig_reg_rx_priority_mask_add = 0;
2309 
2310 	switch (cos_entry) {
2311 	case 0:
2312 	     nig_reg_rx_priority_mask_add = (port) ?
2313 		 NIG_REG_P1_RX_COS0_PRIORITY_MASK :
2314 		 NIG_REG_P0_RX_COS0_PRIORITY_MASK;
2315 	     break;
2316 	case 1:
2317 	    nig_reg_rx_priority_mask_add = (port) ?
2318 		NIG_REG_P1_RX_COS1_PRIORITY_MASK :
2319 		NIG_REG_P0_RX_COS1_PRIORITY_MASK;
2320 	    break;
2321 	case 2:
2322 	    nig_reg_rx_priority_mask_add = (port) ?
2323 		NIG_REG_P1_RX_COS2_PRIORITY_MASK :
2324 		NIG_REG_P0_RX_COS2_PRIORITY_MASK;
2325 	    break;
2326 	case 3:
2327 	    if (port)
2328 		return ELINK_STATUS_ERROR;
2329 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS3_PRIORITY_MASK;
2330 	    break;
2331 	case 4:
2332 	    if (port)
2333 		return ELINK_STATUS_ERROR;
2334 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS4_PRIORITY_MASK;
2335 	    break;
2336 	case 5:
2337 	    if (port)
2338 		return ELINK_STATUS_ERROR;
2339 	    nig_reg_rx_priority_mask_add = NIG_REG_P0_RX_COS5_PRIORITY_MASK;
2340 	    break;
2341 	}
2342 
2343 	REG_WR(cb, nig_reg_rx_priority_mask_add, priority_mask);
2344 
2345 	return ELINK_STATUS_OK;
2346 }
2347 #endif // ELINK_ENHANCEMENTS
2348 #ifndef EXCLUDE_NON_COMMON_INIT
elink_update_mng(struct elink_params * params,u32 link_status)2349 static void elink_update_mng(struct elink_params *params, u32 link_status)
2350 {
2351 	struct elink_dev *cb = params->cb;
2352 
2353 	REG_WR(cb, params->shmem_base +
2354 	       OFFSETOF(struct shmem_region,
2355 			port_mb[params->port].link_status), link_status);
2356 }
2357 
2358 #ifdef ELINK_ENHANCEMENTS
elink_update_pfc_nig(struct elink_params * params,struct elink_vars * vars,struct elink_nig_brb_pfc_port_params * nig_params)2359 static void elink_update_pfc_nig(struct elink_params *params,
2360 		struct elink_vars *vars,
2361 		struct elink_nig_brb_pfc_port_params *nig_params)
2362 {
2363 	u32 xcm_mask = 0, ppp_enable = 0, pause_enable = 0, llfc_out_en = 0;
2364 	u32 llfc_enable = 0, xcm_out_en = 0, hwpfc_enable = 0;
2365 	u32 pkt_priority_to_cos = 0;
2366 	struct elink_dev *cb = params->cb;
2367 	u8 port = params->port;
2368 
2369 	int set_pfc = params->feature_config_flags &
2370 		ELINK_FEATURE_CONFIG_PFC_ENABLED;
2371 	ELINK_DEBUG_P0(cb, "updating pfc nig parameters\n");
2372 
2373 	/* When NIG_LLH0_XCM_MASK_REG_LLHX_XCM_MASK_BCN bit is set
2374 	 * MAC control frames (that are not pause packets)
2375 	 * will be forwarded to the XCM.
2376 	 */
2377 	xcm_mask = REG_RD(cb, port ? NIG_REG_LLH1_XCM_MASK :
2378 			  NIG_REG_LLH0_XCM_MASK);
2379 	/* NIG params will override non PFC params, since it's possible to
2380 	 * do transition from PFC to SAFC
2381 	 */
2382 	if (set_pfc) {
2383 		pause_enable = 0;
2384 		llfc_out_en = 0;
2385 		llfc_enable = 0;
2386 		if (CHIP_IS_E3(params->chip_id))
2387 			ppp_enable = 0;
2388 		else
2389 			ppp_enable = 1;
2390 		xcm_mask &= ~(port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2391 				     NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2392 		xcm_out_en = 0;
2393 		hwpfc_enable = 1;
2394 	} else  {
2395 		if (nig_params) {
2396 			llfc_out_en = nig_params->llfc_out_en;
2397 			llfc_enable = nig_params->llfc_enable;
2398 			pause_enable = nig_params->pause_enable;
2399 		} else  /* Default non PFC mode - PAUSE */
2400 			pause_enable = 1;
2401 
2402 		xcm_mask |= (port ? NIG_LLH1_XCM_MASK_REG_LLH1_XCM_MASK_BCN :
2403 			NIG_LLH0_XCM_MASK_REG_LLH0_XCM_MASK_BCN);
2404 		xcm_out_en = 1;
2405 	}
2406 
2407 	if (CHIP_IS_E3(params->chip_id))
2408 		REG_WR(cb, port ? NIG_REG_BRB1_PAUSE_IN_EN :
2409 		       NIG_REG_BRB0_PAUSE_IN_EN, pause_enable);
2410 	REG_WR(cb, port ? NIG_REG_LLFC_OUT_EN_1 :
2411 	       NIG_REG_LLFC_OUT_EN_0, llfc_out_en);
2412 	REG_WR(cb, port ? NIG_REG_LLFC_ENABLE_1 :
2413 	       NIG_REG_LLFC_ENABLE_0, llfc_enable);
2414 	REG_WR(cb, port ? NIG_REG_PAUSE_ENABLE_1 :
2415 	       NIG_REG_PAUSE_ENABLE_0, pause_enable);
2416 
2417 	REG_WR(cb, port ? NIG_REG_PPP_ENABLE_1 :
2418 	       NIG_REG_PPP_ENABLE_0, ppp_enable);
2419 
2420 	REG_WR(cb, port ? NIG_REG_LLH1_XCM_MASK :
2421 	       NIG_REG_LLH0_XCM_MASK, xcm_mask);
2422 
2423 	REG_WR(cb, port ? NIG_REG_LLFC_EGRESS_SRC_ENABLE_1 :
2424 	       NIG_REG_LLFC_EGRESS_SRC_ENABLE_0, 0x7);
2425 
2426 	/* Output enable for RX_XCM # IF */
2427 	REG_WR(cb, port ? NIG_REG_XCM1_OUT_EN :
2428 	       NIG_REG_XCM0_OUT_EN, xcm_out_en);
2429 
2430 	/* HW PFC TX enable */
2431 	REG_WR(cb, port ? NIG_REG_P1_HWPFC_ENABLE :
2432 	       NIG_REG_P0_HWPFC_ENABLE, hwpfc_enable);
2433 
2434 	if (nig_params) {
2435 		u8 i = 0;
2436 		pkt_priority_to_cos = nig_params->pkt_priority_to_cos;
2437 
2438 		for (i = 0; i < nig_params->num_of_rx_cos_priority_mask; i++)
2439 			elink_pfc_nig_rx_priority_mask(cb, i,
2440 		nig_params->rx_cos_priority_mask[i], port);
2441 
2442 		REG_WR(cb, port ? NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_1 :
2443 		       NIG_REG_LLFC_HIGH_PRIORITY_CLASSES_0,
2444 		       nig_params->llfc_high_priority_classes);
2445 
2446 		REG_WR(cb, port ? NIG_REG_LLFC_LOW_PRIORITY_CLASSES_1 :
2447 		       NIG_REG_LLFC_LOW_PRIORITY_CLASSES_0,
2448 		       nig_params->llfc_low_priority_classes);
2449 	}
2450 	REG_WR(cb, port ? NIG_REG_P1_PKT_PRIORITY_TO_COS :
2451 	       NIG_REG_P0_PKT_PRIORITY_TO_COS,
2452 	       pkt_priority_to_cos);
2453 }
2454 
elink_update_pfc(struct elink_params * params,struct elink_vars * vars,struct elink_nig_brb_pfc_port_params * pfc_params)2455 elink_status_t elink_update_pfc(struct elink_params *params,
2456 		      struct elink_vars *vars,
2457 		      struct elink_nig_brb_pfc_port_params *pfc_params)
2458 {
2459 	/* The PFC and pause are orthogonal to one another, meaning when
2460 	 * PFC is enabled, the pause are disabled, and when PFC is
2461 	 * disabled, pause are set according to the pause result.
2462 	 */
2463 	u32 val;
2464 	struct elink_dev *cb = params->cb;
2465 	u8 bmac_loopback = (params->loopback_mode == ELINK_LOOPBACK_BMAC);
2466 
2467 	if (params->feature_config_flags & ELINK_FEATURE_CONFIG_PFC_ENABLED)
2468 		vars->link_status |= LINK_STATUS_PFC_ENABLED;
2469 	else
2470 		vars->link_status &= ~LINK_STATUS_PFC_ENABLED;
2471 
2472 	elink_update_mng(params, vars->link_status);
2473 
2474 	/* Update NIG params */
2475 	elink_update_pfc_nig(params, vars, pfc_params);
2476 
2477 	if (!vars->link_up)
2478 		return ELINK_STATUS_OK;
2479 
2480 	ELINK_DEBUG_P0(cb, "About to update PFC in BMAC\n");
2481 
2482 	if (CHIP_IS_E3(params->chip_id)) {
2483 		if (vars->mac_type == ELINK_MAC_TYPE_XMAC)
2484 			elink_update_pfc_xmac(params, vars, 0);
2485 	} else {
2486 		val = REG_RD(cb, MISC_REG_RESET_REG_2);
2487 		if ((val &
2488 		     (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << params->port))
2489 		    == 0) {
2490 			ELINK_DEBUG_P0(cb, "About to update PFC in EMAC\n");
2491 			elink_emac_enable(params, vars, 0);
2492 			return ELINK_STATUS_OK;
2493 		}
2494 		if (CHIP_IS_E2(params->chip_id))
2495 			elink_update_pfc_bmac2(params, vars, bmac_loopback);
2496 		else
2497 			elink_update_pfc_bmac1(params, vars);
2498 
2499 		val = 0;
2500 		if ((params->feature_config_flags &
2501 		     ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2502 		    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2503 			val = 1;
2504 		REG_WR(cb, NIG_REG_BMAC0_PAUSE_OUT_EN + params->port*4, val);
2505 	}
2506 	return ELINK_STATUS_OK;
2507 }
2508 
2509 #endif /* ELINK_ENHANCEMENTS */
2510 #ifndef EXCLUDE_BMAC1
elink_bmac1_enable(struct elink_params * params,struct elink_vars * vars,u8 is_lb)2511 static elink_status_t elink_bmac1_enable(struct elink_params *params,
2512 			      struct elink_vars *vars,
2513 			      u8 is_lb)
2514 {
2515 	struct elink_dev *cb = params->cb;
2516 	u8 port = params->port;
2517 	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2518 			       NIG_REG_INGRESS_BMAC0_MEM;
2519 	u32 wb_data[2];
2520 	u32 val;
2521 
2522 	ELINK_DEBUG_P0(cb, "Enabling BigMAC1\n");
2523 
2524 	/* XGXS control */
2525 	wb_data[0] = 0x3c;
2526 	wb_data[1] = 0;
2527 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_BMAC_XGXS_CONTROL,
2528 		    wb_data, 2);
2529 
2530 	/* TX MAC SA */
2531 	wb_data[0] = ((params->mac_addr[2] << 24) |
2532 		       (params->mac_addr[3] << 16) |
2533 		       (params->mac_addr[4] << 8) |
2534 			params->mac_addr[5]);
2535 	wb_data[1] = ((params->mac_addr[0] << 8) |
2536 			params->mac_addr[1]);
2537 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_TX_SOURCE_ADDR, wb_data, 2);
2538 
2539 	/* MAC control */
2540 	val = 0x3;
2541 	if (is_lb) {
2542 		val |= 0x4;
2543 		ELINK_DEBUG_P0(cb,  "enable bmac loopback\n");
2544 	}
2545 	wb_data[0] = val;
2546 	wb_data[1] = 0;
2547 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_BMAC_CONTROL, wb_data, 2);
2548 
2549 	/* Set rx mtu */
2550 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2551 	wb_data[1] = 0;
2552 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_RX_MAX_SIZE, wb_data, 2);
2553 
2554 	elink_update_pfc_bmac1(params, vars);
2555 
2556 	/* Set tx mtu */
2557 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2558 	wb_data[1] = 0;
2559 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_TX_MAX_SIZE, wb_data, 2);
2560 
2561 	/* Set cnt max size */
2562 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2563 	wb_data[1] = 0;
2564 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2565 
2566 	/* Configure SAFC */
2567 	wb_data[0] = 0x1000200;
2568 	wb_data[1] = 0;
2569 	REG_WR_DMAE(cb, bmac_addr + BIGMAC_REGISTER_RX_LLFC_MSG_FLDS,
2570 		    wb_data, 2);
2571 #ifdef ELINK_INCLUDE_EMUL
2572 	/* Fix for emulation */
2573 	if (CHIP_REV_IS_EMUL(params->chip_id)) {
2574 		wb_data[0] = 0xf000;
2575 		wb_data[1] = 0;
2576 		REG_WR_DMAE(cb,	bmac_addr + BIGMAC_REGISTER_TX_PAUSE_THRESHOLD,
2577 			    wb_data, 2);
2578 	}
2579 #endif /* ELINK_INCLUDE_EMUL */
2580 
2581 	return ELINK_STATUS_OK;
2582 }
2583 #endif /* EXCLUDE_BMAC1 */
2584 
2585 #ifndef EXCLUDE_BMAC2
elink_bmac2_enable(struct elink_params * params,struct elink_vars * vars,u8 is_lb)2586 static elink_status_t elink_bmac2_enable(struct elink_params *params,
2587 			      struct elink_vars *vars,
2588 			      u8 is_lb)
2589 {
2590 	struct elink_dev *cb = params->cb;
2591 	u8 port = params->port;
2592 	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2593 			       NIG_REG_INGRESS_BMAC0_MEM;
2594 	u32 wb_data[2];
2595 
2596 	ELINK_DEBUG_P0(cb, "Enabling BigMAC2\n");
2597 
2598 	wb_data[0] = 0;
2599 	wb_data[1] = 0;
2600 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_BMAC_CONTROL, wb_data, 2);
2601 	USLEEP(cb, 30);
2602 
2603 	/* XGXS control: Reset phy HW, MDIO registers, PHY PLL and BMAC */
2604 	wb_data[0] = 0x3c;
2605 	wb_data[1] = 0;
2606 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_BMAC_XGXS_CONTROL,
2607 		    wb_data, 2);
2608 
2609 	USLEEP(cb, 30);
2610 
2611 	/* TX MAC SA */
2612 	wb_data[0] = ((params->mac_addr[2] << 24) |
2613 		       (params->mac_addr[3] << 16) |
2614 		       (params->mac_addr[4] << 8) |
2615 			params->mac_addr[5]);
2616 	wb_data[1] = ((params->mac_addr[0] << 8) |
2617 			params->mac_addr[1]);
2618 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_TX_SOURCE_ADDR,
2619 		    wb_data, 2);
2620 
2621 	USLEEP(cb, 30);
2622 
2623 	/* Configure SAFC */
2624 	wb_data[0] = 0x1000200;
2625 	wb_data[1] = 0;
2626 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_RX_LLFC_MSG_FLDS,
2627 		    wb_data, 2);
2628 	USLEEP(cb, 30);
2629 
2630 	/* Set RX MTU */
2631 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2632 	wb_data[1] = 0;
2633 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_RX_MAX_SIZE, wb_data, 2);
2634 	USLEEP(cb, 30);
2635 
2636 	/* Set TX MTU */
2637 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD;
2638 	wb_data[1] = 0;
2639 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_TX_MAX_SIZE, wb_data, 2);
2640 	USLEEP(cb, 30);
2641 	/* Set cnt max size */
2642 	wb_data[0] = ELINK_ETH_MAX_JUMBO_PACKET_SIZE + ELINK_ETH_OVREHEAD - 2;
2643 	wb_data[1] = 0;
2644 	REG_WR_DMAE(cb, bmac_addr + BIGMAC2_REGISTER_CNT_MAX_SIZE, wb_data, 2);
2645 	USLEEP(cb, 30);
2646 	elink_update_pfc_bmac2(params, vars, is_lb);
2647 
2648 	return ELINK_STATUS_OK;
2649 }
2650 #endif /* EXCLUDE_BMAC2 */
2651 
2652 #if !defined(EXCLUDE_BMAC2)
elink_bmac_enable(struct elink_params * params,struct elink_vars * vars,u8 is_lb,u8 reset_bmac)2653 static elink_status_t elink_bmac_enable(struct elink_params *params,
2654 			     struct elink_vars *vars,
2655 			     u8 is_lb, u8 reset_bmac)
2656 {
2657 	elink_status_t rc = ELINK_STATUS_OK;
2658 	u8 port = params->port;
2659 	struct elink_dev *cb = params->cb;
2660 	u32 val;
2661 	/* Reset and unreset the BigMac */
2662 	if (reset_bmac) {
2663 		REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_CLEAR,
2664 		       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2665 		MSLEEP(cb, 1);
2666 	}
2667 
2668 	REG_WR(cb, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
2669 	       (MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port));
2670 
2671 	/* Enable access for bmac registers */
2672 	REG_WR(cb, NIG_REG_BMAC0_REGS_OUT_EN + port*4, 0x1);
2673 
2674 	/* Enable BMAC according to BMAC type*/
2675 #ifdef ELINK_ENHANCEMENTS
2676 	if (CHIP_IS_E2(params->chip_id))
2677 #endif
2678 #ifndef EXCLUDE_BMAC2
2679 		rc = elink_bmac2_enable(params, vars, is_lb);
2680 #endif
2681 #ifdef ELINK_ENHANCEMENTS
2682 	else
2683 #endif
2684 #ifndef EXCLUDE_BMAC1
2685 		rc = elink_bmac1_enable(params, vars, is_lb);
2686 #endif
2687 	REG_WR(cb, NIG_REG_XGXS_SERDES0_MODE_SEL + port*4, 0x1);
2688 	REG_WR(cb, NIG_REG_XGXS_LANE_SEL_P0 + port*4, 0x0);
2689 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_PORT + port*4, 0x0);
2690 	val = 0;
2691 	if ((params->feature_config_flags &
2692 	      ELINK_FEATURE_CONFIG_PFC_ENABLED) ||
2693 	    (vars->flow_ctrl & ELINK_FLOW_CTRL_TX))
2694 		val = 1;
2695 	REG_WR(cb, NIG_REG_BMAC0_PAUSE_OUT_EN + port*4, val);
2696 	REG_WR(cb, NIG_REG_EGRESS_EMAC0_OUT_EN + port*4, 0x0);
2697 	REG_WR(cb, NIG_REG_EMAC0_IN_EN + port*4, 0x0);
2698 	REG_WR(cb, NIG_REG_EMAC0_PAUSE_OUT_EN + port*4, 0x0);
2699 	REG_WR(cb, NIG_REG_BMAC0_IN_EN + port*4, 0x1);
2700 	REG_WR(cb, NIG_REG_BMAC0_OUT_EN + port*4, 0x1);
2701 
2702 	vars->mac_type = ELINK_MAC_TYPE_BMAC;
2703 	return rc;
2704 }
2705 #endif /* #if !defined(EXCLUDE_BMAC2) && !defined(EXCLUDE_BMAC1) */
2706 
2707 #if !defined(EXCLUDE_BMAC2) && !defined(EXCLUDE_BMAC1)
elink_set_bmac_rx(struct elink_dev * cb,u32 chip_id,u8 port,u8 en)2708 static void elink_set_bmac_rx(struct elink_dev *cb, u32 chip_id, u8 port, u8 en)
2709 {
2710 	u32 bmac_addr = port ? NIG_REG_INGRESS_BMAC1_MEM :
2711 			NIG_REG_INGRESS_BMAC0_MEM;
2712 	u32 wb_data[2];
2713 	u32 nig_bmac_enable = REG_RD(cb, NIG_REG_BMAC0_REGS_OUT_EN + port*4);
2714 
2715 	if (CHIP_IS_E2(chip_id))
2716 		bmac_addr += BIGMAC2_REGISTER_BMAC_CONTROL;
2717 	else
2718 		bmac_addr += BIGMAC_REGISTER_BMAC_CONTROL;
2719 	/* Only if the bmac is out of reset */
2720 	if (REG_RD(cb, MISC_REG_RESET_REG_2) &
2721 			(MISC_REGISTERS_RESET_REG_2_RST_BMAC0 << port) &&
2722 	    nig_bmac_enable) {
2723 		/* Clear Rx Enable bit in BMAC_CONTROL register */
2724 		REG_RD_DMAE(cb, bmac_addr, wb_data, 2);
2725 		if (en)
2726 			wb_data[0] |= ELINK_BMAC_CONTROL_RX_ENABLE;
2727 		else
2728 			wb_data[0] &= ~ELINK_BMAC_CONTROL_RX_ENABLE;
2729 		REG_WR_DMAE(cb, bmac_addr, wb_data, 2);
2730 		MSLEEP(cb, 1);
2731 	}
2732 }
2733 #endif /* !defined(EXCLUDE_BMAC2) && !defined(EXCLUDE_BMAC1) */
2734 #endif // EXCLUDE_NON_COMMON_INIT
2735 
2736 #ifndef ELINK_AUX_POWER
elink_pbf_update(struct elink_params * params,u32 flow_ctrl,u32 line_speed)2737 static elink_status_t elink_pbf_update(struct elink_params *params, u32 flow_ctrl,
2738 			    u32 line_speed)
2739 {
2740 	struct elink_dev *cb = params->cb;
2741 	u8 port = params->port;
2742 	u32 init_crd, crd;
2743 	u32 count = 1000;
2744 
2745 	/* Disable port */
2746 	REG_WR(cb, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x1);
2747 
2748 	/* Wait for init credit */
2749 	init_crd = REG_RD(cb, PBF_REG_P0_INIT_CRD + port*4);
2750 	crd = REG_RD(cb, PBF_REG_P0_CREDIT + port*8);
2751 	ELINK_DEBUG_P2(cb, "init_crd 0x%x  crd 0x%x\n", init_crd, crd);
2752 
2753 	while ((init_crd != crd) && count) {
2754 		MSLEEP(cb, 5);
2755 		crd = REG_RD(cb, PBF_REG_P0_CREDIT + port*8);
2756 		count--;
2757 	}
2758 	crd = REG_RD(cb, PBF_REG_P0_CREDIT + port*8);
2759 	if (init_crd != crd) {
2760 		ELINK_DEBUG_P2(cb, "BUG! init_crd 0x%x != crd 0x%x\n",
2761 			  init_crd, crd);
2762 		return ELINK_STATUS_ERROR;
2763 	}
2764 
2765 	if (flow_ctrl & ELINK_FLOW_CTRL_RX ||
2766 	    line_speed == ELINK_SPEED_10 ||
2767 	    line_speed == ELINK_SPEED_100 ||
2768 	    line_speed == ELINK_SPEED_1000 ||
2769 	    line_speed == ELINK_SPEED_2500) {
2770 		REG_WR(cb, PBF_REG_P0_PAUSE_ENABLE + port*4, 1);
2771 		/* Update threshold */
2772 		REG_WR(cb, PBF_REG_P0_ARB_THRSH + port*4, 0);
2773 		/* Update init credit */
2774 		init_crd = 778;		/* (800-18-4) */
2775 
2776 	} else {
2777 		u32 thresh = (ELINK_ETH_MAX_JUMBO_PACKET_SIZE +
2778 			      ELINK_ETH_OVREHEAD)/16;
2779 		REG_WR(cb, PBF_REG_P0_PAUSE_ENABLE + port*4, 0);
2780 		/* Update threshold */
2781 		REG_WR(cb, PBF_REG_P0_ARB_THRSH + port*4, thresh);
2782 		/* Update init credit */
2783 		switch (line_speed) {
2784 		case ELINK_SPEED_10000:
2785 			init_crd = thresh + 553 - 22;
2786 			break;
2787 		default:
2788 			ELINK_DEBUG_P1(cb, "Invalid line_speed 0x%x\n",
2789 				  line_speed);
2790 			return ELINK_STATUS_ERROR;
2791 		}
2792 	}
2793 	REG_WR(cb, PBF_REG_P0_INIT_CRD + port*4, init_crd);
2794 	ELINK_DEBUG_P2(cb, "PBF updated to speed %d credit %d\n",
2795 		 line_speed, init_crd);
2796 
2797 	/* Probe the credit changes */
2798 	REG_WR(cb, PBF_REG_INIT_P0 + port*4, 0x1);
2799 	MSLEEP(cb, 5);
2800 	REG_WR(cb, PBF_REG_INIT_P0 + port*4, 0x0);
2801 
2802 	/* Enable port */
2803 	REG_WR(cb, PBF_REG_DISABLE_NEW_TASK_PROC_P0 + port*4, 0x0);
2804 	return ELINK_STATUS_OK;
2805 }
2806 #endif /* ELINK_AUX_POWER */
2807 
2808 #ifndef EXCLUDE_COMMON_INIT
2809 /**
2810  * elink_get_emac_base - retrive emac base address
2811  *
2812  * @bp:			driver handle
2813  * @mdc_mdio_access:	access type
2814  * @port:		port id
2815  *
2816  * This function selects the MDC/MDIO access (through emac0 or
2817  * emac1) depend on the mdc_mdio_access, port, port swapped. Each
2818  * phy has a default access mode, which could also be overridden
2819  * by nvram configuration. This parameter, whether this is the
2820  * default phy configuration, or the nvram overrun
2821  * configuration, is passed here as mdc_mdio_access and selects
2822  * the emac_base for the CL45 read/writes operations
2823  */
elink_get_emac_base(struct elink_dev * cb,u32 mdc_mdio_access,u8 port)2824 static u32 elink_get_emac_base(struct elink_dev *cb,
2825 			       u32 mdc_mdio_access, u8 port)
2826 {
2827 	u32 emac_base = 0;
2828 	switch (mdc_mdio_access) {
2829 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_PHY_TYPE:
2830 		break;
2831 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC0:
2832 		if (REG_RD(cb, NIG_REG_PORT_SWAP))
2833 			emac_base = GRCBASE_EMAC1;
2834 		else
2835 			emac_base = GRCBASE_EMAC0;
2836 		break;
2837 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_EMAC1:
2838 		if (REG_RD(cb, NIG_REG_PORT_SWAP))
2839 			emac_base = GRCBASE_EMAC0;
2840 		else
2841 			emac_base = GRCBASE_EMAC1;
2842 		break;
2843 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_BOTH:
2844 		emac_base = (port) ? GRCBASE_EMAC1 : GRCBASE_EMAC0;
2845 		break;
2846 	case SHARED_HW_CFG_MDC_MDIO_ACCESS1_SWAPPED:
2847 		emac_base = (port) ? GRCBASE_EMAC0 : GRCBASE_EMAC1;
2848 		break;
2849 	default:
2850 		break;
2851 	}
2852 	return emac_base;
2853 
2854 }
2855 #endif /* EXCLUDE_COMMON_INIT */
2856 
2857 /******************************************************************/
2858 /*			CL22 access functions			  */
2859 /******************************************************************/
2860 #ifndef EXCLUDE_NON_COMMON_INIT
2861 #ifndef EXCLUDE_BCM54618SE
elink_cl22_write(struct elink_dev * cb,struct elink_phy * phy,u16 reg,u16 val)2862 static elink_status_t elink_cl22_write(struct elink_dev *cb,
2863 				       struct elink_phy *phy,
2864 				       u16 reg, u16 val)
2865 {
2866 	u32 tmp, mode;
2867 	u8 i;
2868 	elink_status_t rc = ELINK_STATUS_OK;
2869 	/* Switch to CL22 */
2870 	mode = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2871 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2872 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2873 
2874 	/* Address */
2875 	tmp = ((phy->addr << 21) | (reg << 16) | val |
2876 	       EMAC_MDIO_COMM_COMMAND_WRITE_22 |
2877 	       EMAC_MDIO_COMM_START_BUSY);
2878 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
2879 
2880 	for (i = 0; i < 50; i++) {
2881 		USLEEP(cb, 10);
2882 
2883 		tmp = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2884 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
2885 			USLEEP(cb, 5);
2886 			break;
2887 		}
2888 	}
2889 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
2890 		ELINK_DEBUG_P0(cb, "write phy register failed\n");
2891 		rc = ELINK_STATUS_TIMEOUT;
2892 	}
2893 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2894 	return rc;
2895 }
2896 
elink_cl22_read(struct elink_dev * cb,struct elink_phy * phy,u16 reg,u16 * ret_val)2897 static elink_status_t elink_cl22_read(struct elink_dev *cb,
2898 				      struct elink_phy *phy,
2899 				      u16 reg, u16 *ret_val)
2900 {
2901 	u32 val, mode;
2902 	u16 i;
2903 	elink_status_t rc = ELINK_STATUS_OK;
2904 
2905 	/* Switch to CL22 */
2906 	mode = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE);
2907 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE,
2908 	       mode & ~EMAC_MDIO_MODE_CLAUSE_45);
2909 
2910 	/* Address */
2911 	val = ((phy->addr << 21) | (reg << 16) |
2912 	       EMAC_MDIO_COMM_COMMAND_READ_22 |
2913 	       EMAC_MDIO_COMM_START_BUSY);
2914 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2915 
2916 	for (i = 0; i < 50; i++) {
2917 		USLEEP(cb, 10);
2918 
2919 		val = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2920 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2921 			*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2922 			USLEEP(cb, 5);
2923 			break;
2924 		}
2925 	}
2926 	if (val & EMAC_MDIO_COMM_START_BUSY) {
2927 		ELINK_DEBUG_P0(cb, "read phy register failed\n");
2928 
2929 		*ret_val = 0;
2930 		rc = ELINK_STATUS_TIMEOUT;
2931 	}
2932 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_MODE, mode);
2933 	return rc;
2934 }
2935 #endif
2936 #endif /* EXCLUDE_NON_COMMON_INIT */
2937 
2938 /******************************************************************/
2939 /*			CL45 access functions			  */
2940 /******************************************************************/
elink_cl45_read(struct elink_dev * cb,struct elink_phy * phy,u8 devad,u16 reg,u16 * ret_val)2941 static elink_status_t elink_cl45_read(struct elink_dev *cb, struct elink_phy *phy,
2942 			   u8 devad, u16 reg, u16 *ret_val)
2943 {
2944 	u32 val;
2945 	u16 i;
2946 	elink_status_t rc = ELINK_STATUS_OK;
2947 #ifndef ELINK_AUX_POWER
2948 	u32 chip_id;
2949 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
2950 		chip_id = (REG_RD(cb, MISC_REG_CHIP_NUM) << 16) |
2951 			  ((REG_RD(cb, MISC_REG_CHIP_REV) & 0xf) << 12);
2952 		elink_set_mdio_clk(cb, chip_id, phy->mdio_ctrl);
2953 	}
2954 #endif /* ELINK_AUX_POWER */
2955 
2956 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
2957 		elink_bits_en(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
2958 			      EMAC_MDIO_STATUS_10MB);
2959 	/* Address */
2960 	val = ((phy->addr << 21) | (devad << 16) | reg |
2961 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
2962 	       EMAC_MDIO_COMM_START_BUSY);
2963 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2964 
2965 	for (i = 0; i < 50; i++) {
2966 		USLEEP(cb, 10);
2967 
2968 		val = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
2969 		if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2970 			USLEEP(cb, 5);
2971 			break;
2972 		}
2973 	}
2974 	if (val & EMAC_MDIO_COMM_START_BUSY) {
2975 		ELINK_DEBUG_P0(cb, "read phy register failed\n");
2976 		elink_cb_event_log(cb, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
2977 
2978 		*ret_val = 0;
2979 		rc = ELINK_STATUS_TIMEOUT;
2980 	} else {
2981 		/* Data */
2982 		val = ((phy->addr << 21) | (devad << 16) |
2983 		       EMAC_MDIO_COMM_COMMAND_READ_45 |
2984 		       EMAC_MDIO_COMM_START_BUSY);
2985 		REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, val);
2986 
2987 		for (i = 0; i < 50; i++) {
2988 			USLEEP(cb, 10);
2989 
2990 			val = REG_RD(cb, phy->mdio_ctrl +
2991 				     EMAC_REG_EMAC_MDIO_COMM);
2992 			if (!(val & EMAC_MDIO_COMM_START_BUSY)) {
2993 				*ret_val = (u16)(val & EMAC_MDIO_COMM_DATA);
2994 				break;
2995 			}
2996 		}
2997 		if (val & EMAC_MDIO_COMM_START_BUSY) {
2998 			ELINK_DEBUG_P0(cb, "read phy register failed\n");
2999 			elink_cb_event_log(cb, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3000 
3001 			*ret_val = 0;
3002 			rc = ELINK_STATUS_TIMEOUT;
3003 		}
3004 	}
3005 	/* Work around for E3 A0 */
3006 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3007 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3008 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3009 			u16 temp_val;
3010 			elink_cl45_read(cb, phy, devad, 0xf, &temp_val);
3011 		}
3012 	}
3013 
3014 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3015 		elink_bits_dis(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3016 			       EMAC_MDIO_STATUS_10MB);
3017 	return rc;
3018 }
3019 
elink_cl45_write(struct elink_dev * cb,struct elink_phy * phy,u8 devad,u16 reg,u16 val)3020 static elink_status_t elink_cl45_write(struct elink_dev *cb, struct elink_phy *phy,
3021 			    u8 devad, u16 reg, u16 val)
3022 {
3023 	u32 tmp;
3024 	u8 i;
3025 	elink_status_t rc = ELINK_STATUS_OK;
3026 #ifndef ELINK_AUX_POWER
3027 	u32 chip_id;
3028 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_G) {
3029 		chip_id = (REG_RD(cb, MISC_REG_CHIP_NUM) << 16) |
3030 			  ((REG_RD(cb, MISC_REG_CHIP_REV) & 0xf) << 12);
3031 		elink_set_mdio_clk(cb, chip_id, phy->mdio_ctrl);
3032 	}
3033 #endif /* ELINK_AUX_POWER */
3034 
3035 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3036 		elink_bits_en(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3037 			      EMAC_MDIO_STATUS_10MB);
3038 
3039 	/* Address */
3040 	tmp = ((phy->addr << 21) | (devad << 16) | reg |
3041 	       EMAC_MDIO_COMM_COMMAND_ADDRESS |
3042 	       EMAC_MDIO_COMM_START_BUSY);
3043 	REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3044 
3045 	for (i = 0; i < 50; i++) {
3046 		USLEEP(cb, 10);
3047 
3048 		tmp = REG_RD(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM);
3049 		if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3050 			USLEEP(cb, 5);
3051 			break;
3052 		}
3053 	}
3054 	if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3055 		ELINK_DEBUG_P0(cb, "write phy register failed\n");
3056 		elink_cb_event_log(cb, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3057 
3058 		rc = ELINK_STATUS_TIMEOUT;
3059 	} else {
3060 		/* Data */
3061 		tmp = ((phy->addr << 21) | (devad << 16) | val |
3062 		       EMAC_MDIO_COMM_COMMAND_WRITE_45 |
3063 		       EMAC_MDIO_COMM_START_BUSY);
3064 		REG_WR(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_COMM, tmp);
3065 
3066 		for (i = 0; i < 50; i++) {
3067 			USLEEP(cb, 10);
3068 
3069 			tmp = REG_RD(cb, phy->mdio_ctrl +
3070 				     EMAC_REG_EMAC_MDIO_COMM);
3071 			if (!(tmp & EMAC_MDIO_COMM_START_BUSY)) {
3072 				USLEEP(cb, 5);
3073 				break;
3074 			}
3075 		}
3076 		if (tmp & EMAC_MDIO_COMM_START_BUSY) {
3077 			ELINK_DEBUG_P0(cb, "write phy register failed\n");
3078 			elink_cb_event_log(cb, ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT); // "MDC/MDIO access timeout\n"
3079 
3080 			rc = ELINK_STATUS_TIMEOUT;
3081 		}
3082 	}
3083 	/* Work around for E3 A0 */
3084 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA) {
3085 		phy->flags ^= ELINK_FLAGS_DUMMY_READ;
3086 		if (phy->flags & ELINK_FLAGS_DUMMY_READ) {
3087 			u16 temp_val;
3088 			elink_cl45_read(cb, phy, devad, 0xf, &temp_val);
3089 		}
3090 	}
3091 	if (phy->flags & ELINK_FLAGS_MDC_MDIO_WA_B0)
3092 		elink_bits_dis(cb, phy->mdio_ctrl + EMAC_REG_EMAC_MDIO_STATUS,
3093 			       EMAC_MDIO_STATUS_10MB);
3094 	return rc;
3095 }
3096 
3097 /******************************************************************/
3098 /*			EEE section				   */
3099 /******************************************************************/
3100 #ifndef EXCLUDE_NON_COMMON_INIT
3101 #ifndef EXCLUDE_WARPCORE
elink_eee_has_cap(struct elink_params * params)3102 static u8 elink_eee_has_cap(struct elink_params *params)
3103 {
3104 	struct elink_dev *cb =