1255736Sdavidch/*-
2296071Sdavidcs * Copyright (c) 2007-2017 QLogic Corporation. All rights reserved.
3255736Sdavidch *
4255736Sdavidch * Redistribution and use in source and binary forms, with or without
5255736Sdavidch * modification, are permitted provided that the following conditions
6255736Sdavidch * are met:
7255736Sdavidch *
8255736Sdavidch * 1. Redistributions of source code must retain the above copyright
9255736Sdavidch *    notice, this list of conditions and the following disclaimer.
10255736Sdavidch * 2. Redistributions in binary form must reproduce the above copyright
11255736Sdavidch *    notice, this list of conditions and the following disclaimer in the
12255736Sdavidch *    documentation and/or other materials provided with the distribution.
13255736Sdavidch *
14296071Sdavidcs * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15255736Sdavidch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16255736Sdavidch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17255736Sdavidch * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
18255736Sdavidch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19255736Sdavidch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20255736Sdavidch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21255736Sdavidch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22255736Sdavidch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23255736Sdavidch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24255736Sdavidch * THE POSSIBILITY OF SUCH DAMAGE.
25255736Sdavidch */
26255736Sdavidch
27255736Sdavidch#include <sys/cdefs.h>
28255736Sdavidch__FBSDID("$FreeBSD$");
29255736Sdavidch
30255736Sdavidch#ifndef ELINK_H
31255736Sdavidch#define ELINK_H
32255736Sdavidch
33255736Sdavidch#define ELINK_DEBUG
34255736Sdavidch
35255736Sdavidch
36255736Sdavidch
37255736Sdavidch
38255736Sdavidch
39255736Sdavidch
40255736Sdavidch/***********************************************************/
41255736Sdavidch/*                  CLC Call backs functions               */
42255736Sdavidch/***********************************************************/
43255736Sdavidch/* CLC device structure */
44255736Sdavidchstruct bxe_softc;
45255736Sdavidch
46255736Sdavidchextern uint32_t elink_cb_reg_read(struct bxe_softc *sc, uint32_t reg_addr);
47255736Sdavidchextern void elink_cb_reg_write(struct bxe_softc *sc, uint32_t reg_addr, uint32_t val);
48255736Sdavidch/* wb_write - pointer to 2 32 bits vars to be passed to the DMAE*/
49255736Sdavidchextern void elink_cb_reg_wb_write(struct bxe_softc *sc, uint32_t offset,
50255736Sdavidch				uint32_t *wb_write, uint16_t len);
51255736Sdavidchextern void elink_cb_reg_wb_read(struct bxe_softc *sc, uint32_t offset,
52255736Sdavidch			       uint32_t *wb_write, uint16_t len);
53255736Sdavidch
54255736Sdavidch/* mode - 0( LOW ) /1(HIGH)*/
55255736Sdavidchextern uint8_t elink_cb_gpio_write(struct bxe_softc *sc,
56255736Sdavidch			    uint16_t gpio_num,
57255736Sdavidch			    uint8_t mode, uint8_t port);
58255736Sdavidchextern uint8_t elink_cb_gpio_mult_write(struct bxe_softc *sc,
59255736Sdavidch			    uint8_t pins,
60255736Sdavidch			    uint8_t mode);
61255736Sdavidch
62255736Sdavidchextern uint32_t elink_cb_gpio_read(struct bxe_softc *sc, uint16_t gpio_num, uint8_t port);
63255736Sdavidchextern uint8_t elink_cb_gpio_int_write(struct bxe_softc *sc,
64255736Sdavidch				uint16_t gpio_num,
65255736Sdavidch				uint8_t mode, uint8_t port);
66255736Sdavidch
67255736Sdavidchextern uint32_t elink_cb_fw_command(struct bxe_softc *sc, uint32_t command, uint32_t param);
68255736Sdavidch
69255736Sdavidch/* Delay */
70255736Sdavidchextern void elink_cb_udelay(struct bxe_softc *sc, uint32_t microsecond);
71255736Sdavidch
72255736Sdavidch/* This function is called every 1024 bytes downloading of phy firmware.
73255736SdavidchDriver can use it to print to screen indication for download progress */
74255736Sdavidchextern void elink_cb_download_progress(struct bxe_softc *sc, uint32_t cur, uint32_t total);
75255736Sdavidch
76255736Sdavidch/* Each log type has its own parameters */
77255736Sdavidchtypedef enum elink_log_id {
78255736Sdavidch	ELINK_LOG_ID_UNQUAL_IO_MODULE	= 0, /* uint8_t port, const char* vendor_name, const char* vendor_pn */
79255736Sdavidch	ELINK_LOG_ID_OVER_CURRENT	= 1, /* uint8_t port */
80255736Sdavidch	ELINK_LOG_ID_PHY_UNINITIALIZED	= 2, /* uint8_t port */
81255736Sdavidch	ELINK_LOG_ID_MDIO_ACCESS_TIMEOUT= 3, /* No params */
82255736Sdavidch	ELINK_LOG_ID_NON_10G_MODULE	= 4, /* uint8_t port */
83255736Sdavidch}elink_log_id_t;
84255736Sdavidch
85255736Sdavidchtypedef enum elink_status {
86255736Sdavidch	ELINK_STATUS_OK = 0,
87255736Sdavidch	ELINK_STATUS_ERROR,
88255736Sdavidch	ELINK_STATUS_TIMEOUT,
89255736Sdavidch	ELINK_STATUS_NO_LINK,
90255736Sdavidch	ELINK_STATUS_INVALID_IMAGE,
91255736Sdavidch	ELINK_OP_NOT_SUPPORTED = 122
92255736Sdavidch} elink_status_t;
93255736Sdavidchextern void elink_cb_event_log(struct bxe_softc *sc, const elink_log_id_t log_id, ...);
94255736Sdavidchextern void elink_cb_load_warpcore_microcode(void);
95255736Sdavidch
96255736Sdavidchextern uint8_t elink_cb_path_id(struct bxe_softc *sc);
97255736Sdavidch
98255736Sdavidchextern void elink_cb_notify_link_changed(struct bxe_softc *sc);
99255736Sdavidch
100255736Sdavidch#define ELINK_EVENT_LOG_LEVEL_ERROR 	1
101255736Sdavidch#define ELINK_EVENT_LOG_LEVEL_WARNING 	2
102255736Sdavidch#define ELINK_EVENT_ID_SFP_UNQUALIFIED_MODULE 	1
103255736Sdavidch#define ELINK_EVENT_ID_SFP_POWER_FAULT 		2
104255736Sdavidch
105255736Sdavidch#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
106255736Sdavidch/* Debug prints */
107255736Sdavidch#ifdef ELINK_DEBUG
108255736Sdavidch
109255736Sdavidchextern void elink_cb_dbg(struct bxe_softc *sc,  char *fmt);
110255736Sdavidchextern void elink_cb_dbg1(struct bxe_softc *sc,  char *fmt, uint32_t arg1);
111255736Sdavidchextern void elink_cb_dbg2(struct bxe_softc *sc,  char *fmt, uint32_t arg1, uint32_t arg2);
112255736Sdavidchextern void elink_cb_dbg3(struct bxe_softc *sc,  char *fmt, uint32_t arg1, uint32_t arg2,
113255736Sdavidch			  uint32_t arg3);
114255736Sdavidch
115255736Sdavidch#define ELINK_DEBUG_P0(sc, fmt) 		elink_cb_dbg(sc, fmt)
116255736Sdavidch#define ELINK_DEBUG_P1(sc, fmt, arg1) 		elink_cb_dbg1(sc, fmt, arg1)
117255736Sdavidch#define ELINK_DEBUG_P2(sc, fmt, arg1, arg2)	elink_cb_dbg2(sc, fmt, arg1, arg2)
118255736Sdavidch#define ELINK_DEBUG_P3(sc, fmt, arg1, arg2, arg3) \
119255736Sdavidch					elink_cb_dbg3(sc, fmt, arg1, arg2, arg3)
120255736Sdavidch#else
121255736Sdavidch#define ELINK_DEBUG_P0(sc, fmt)
122255736Sdavidch#define ELINK_DEBUG_P1(sc, fmt, arg1)
123255736Sdavidch#define ELINK_DEBUG_P2(sc, fmt, arg1, arg2)
124255736Sdavidch#define ELINK_DEBUG_P3(sc, fmt, arg1, arg2, arg3)
125255736Sdavidch#endif
126255736Sdavidch
127255736Sdavidch/***********************************************************/
128255736Sdavidch/*                         Defines                         */
129255736Sdavidch/***********************************************************/
130255736Sdavidch#define ELINK_DEFAULT_PHY_DEV_ADDR	3
131255736Sdavidch#define ELINK_E2_DEFAULT_PHY_DEV_ADDR	5
132255736Sdavidch
133255736Sdavidch
134255736Sdavidch#define DUPLEX_FULL			1
135255736Sdavidch#define DUPLEX_HALF			2
136255736Sdavidch
137255736Sdavidch#define ELINK_FLOW_CTRL_AUTO		PORT_FEATURE_FLOW_CONTROL_AUTO
138255736Sdavidch#define ELINK_FLOW_CTRL_TX		PORT_FEATURE_FLOW_CONTROL_TX
139255736Sdavidch#define ELINK_FLOW_CTRL_RX		PORT_FEATURE_FLOW_CONTROL_RX
140255736Sdavidch#define ELINK_FLOW_CTRL_BOTH		PORT_FEATURE_FLOW_CONTROL_BOTH
141255736Sdavidch#define ELINK_FLOW_CTRL_NONE		PORT_FEATURE_FLOW_CONTROL_NONE
142255736Sdavidch
143255736Sdavidch#define ELINK_NET_SERDES_IF_XFI		1
144255736Sdavidch#define ELINK_NET_SERDES_IF_SFI		2
145255736Sdavidch#define ELINK_NET_SERDES_IF_KR		3
146255736Sdavidch#define ELINK_NET_SERDES_IF_DXGXS	4
147255736Sdavidch
148255736Sdavidch#define ELINK_SPEED_AUTO_NEG		0
149255736Sdavidch#define ELINK_SPEED_10			10
150255736Sdavidch#define ELINK_SPEED_100			100
151255736Sdavidch#define ELINK_SPEED_1000		1000
152255736Sdavidch#define ELINK_SPEED_2500		2500
153255736Sdavidch#define ELINK_SPEED_10000		10000
154255736Sdavidch#define ELINK_SPEED_20000		20000
155255736Sdavidch
156255736Sdavidch#define ELINK_I2C_DEV_ADDR_A0			0xa0
157255736Sdavidch#define ELINK_I2C_DEV_ADDR_A2			0xa2
158255736Sdavidch
159255736Sdavidch#define ELINK_SFP_EEPROM_PAGE_SIZE			16
160255736Sdavidch#define ELINK_SFP_EEPROM_VENDOR_NAME_ADDR		0x14
161255736Sdavidch#define ELINK_SFP_EEPROM_VENDOR_NAME_SIZE		16
162255736Sdavidch#define ELINK_SFP_EEPROM_VENDOR_OUI_ADDR		0x25
163255736Sdavidch#define ELINK_SFP_EEPROM_VENDOR_OUI_SIZE		3
164255736Sdavidch#define ELINK_SFP_EEPROM_PART_NO_ADDR			0x28
165255736Sdavidch#define ELINK_SFP_EEPROM_PART_NO_SIZE			16
166255736Sdavidch#define ELINK_SFP_EEPROM_REVISION_ADDR		0x38
167255736Sdavidch#define ELINK_SFP_EEPROM_REVISION_SIZE		4
168255736Sdavidch#define ELINK_SFP_EEPROM_SERIAL_ADDR			0x44
169255736Sdavidch#define ELINK_SFP_EEPROM_SERIAL_SIZE			16
170255736Sdavidch#define ELINK_SFP_EEPROM_DATE_ADDR			0x54 /* ASCII YYMMDD */
171255736Sdavidch#define ELINK_SFP_EEPROM_DATE_SIZE			6
172255736Sdavidch#define ELINK_SFP_EEPROM_DIAG_TYPE_ADDR			0x5c
173255736Sdavidch#define ELINK_SFP_EEPROM_DIAG_TYPE_SIZE			1
174255736Sdavidch#define ELINK_SFP_EEPROM_DIAG_ADDR_CHANGE_REQ		(1<<2)
175255736Sdavidch#define ELINK_SFP_EEPROM_SFF_8472_COMP_ADDR		0x5e
176255736Sdavidch#define ELINK_SFP_EEPROM_SFF_8472_COMP_SIZE		1
177296071Sdavidcs#define ELINK_SFP_EEPROM_VENDOR_SPECIFIC_ADDR	0x60
178296071Sdavidcs#define ELINK_SFP_EEPROM_VENDOR_SPECIFIC_SIZE	16
179255736Sdavidch
180296071Sdavidcs
181255736Sdavidch#define ELINK_SFP_EEPROM_A2_CHECKSUM_RANGE		0x5e
182255736Sdavidch#define ELINK_SFP_EEPROM_A2_CC_DMI_ADDR			0x5f
183255736Sdavidch
184255736Sdavidch#define ELINK_PWR_FLT_ERR_MSG_LEN			250
185255736Sdavidch
186255736Sdavidch#define ELINK_XGXS_EXT_PHY_TYPE(ext_phy_config) \
187255736Sdavidch		((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK)
188255736Sdavidch#define ELINK_XGXS_EXT_PHY_ADDR(ext_phy_config) \
189255736Sdavidch		(((ext_phy_config) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK) >> \
190255736Sdavidch		 PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT)
191255736Sdavidch#define ELINK_SERDES_EXT_PHY_TYPE(ext_phy_config) \
192255736Sdavidch		((ext_phy_config) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK)
193255736Sdavidch
194255736Sdavidch/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */
195255736Sdavidch#define ELINK_SINGLE_MEDIA_DIRECT(params)	(params->num_phys == 1)
196255736Sdavidch/* Single Media board contains single external phy */
197255736Sdavidch#define ELINK_SINGLE_MEDIA(params)		(params->num_phys == 2)
198255736Sdavidch/* Dual Media board contains two external phy with different media */
199255736Sdavidch#define ELINK_DUAL_MEDIA(params)		(params->num_phys == 3)
200255736Sdavidch
201255736Sdavidch#define ELINK_FW_PARAM_PHY_ADDR_MASK		0x000000FF
202255736Sdavidch#define ELINK_FW_PARAM_PHY_TYPE_MASK		0x0000FF00
203255736Sdavidch#define ELINK_FW_PARAM_MDIO_CTRL_MASK		0xFFFF0000
204255736Sdavidch#define ELINK_FW_PARAM_MDIO_CTRL_OFFSET		16
205255736Sdavidch#define ELINK_FW_PARAM_PHY_ADDR(fw_param) (fw_param & \
206255736Sdavidch					   ELINK_FW_PARAM_PHY_ADDR_MASK)
207255736Sdavidch#define ELINK_FW_PARAM_PHY_TYPE(fw_param) (fw_param & \
208255736Sdavidch					   ELINK_FW_PARAM_PHY_TYPE_MASK)
209255736Sdavidch#define ELINK_FW_PARAM_MDIO_CTRL(fw_param) ((fw_param & \
210255736Sdavidch					    ELINK_FW_PARAM_MDIO_CTRL_MASK) >> \
211255736Sdavidch					    ELINK_FW_PARAM_MDIO_CTRL_OFFSET)
212255736Sdavidch#define ELINK_FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
213255736Sdavidch	(phy_addr | phy_type | mdio_access << ELINK_FW_PARAM_MDIO_CTRL_OFFSET)
214255736Sdavidch
215255736Sdavidch
216255736Sdavidch#define ELINK_PFC_BRB_FULL_LB_XOFF_THRESHOLD				170
217255736Sdavidch#define ELINK_PFC_BRB_FULL_LB_XON_THRESHOLD				250
218255736Sdavidch
219255736Sdavidch#define ELINK_MAXVAL(a, b) (((a) > (b)) ? (a) : (b))
220255736Sdavidch
221255736Sdavidch#define ELINK_BMAC_CONTROL_RX_ENABLE		2
222255736Sdavidch/***********************************************************/
223255736Sdavidch/*                         Structs                         */
224255736Sdavidch/***********************************************************/
225255736Sdavidch#define ELINK_INT_PHY		0
226255736Sdavidch#define ELINK_EXT_PHY1	1
227255736Sdavidch#define ELINK_EXT_PHY2	2
228255736Sdavidch#define ELINK_MAX_PHYS	3
229255736Sdavidch
230255736Sdavidch/* Same configuration is shared between the XGXS and the first external phy */
231255736Sdavidch#define ELINK_LINK_CONFIG_SIZE (ELINK_MAX_PHYS - 1)
232255736Sdavidch#define ELINK_LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == ELINK_INT_PHY) ? \
233255736Sdavidch					 0 : (_phy_idx - 1))
234255736Sdavidch/***********************************************************/
235255736Sdavidch/*                      elink_phy struct                   */
236255736Sdavidch/*  Defines the required arguments and function per phy    */
237255736Sdavidch/***********************************************************/
238255736Sdavidchstruct elink_vars;
239255736Sdavidchstruct elink_params;
240255736Sdavidchstruct elink_phy;
241255736Sdavidch
242255736Sdavidchtypedef uint8_t (*config_init_t)(struct elink_phy *phy, struct elink_params *params,
243255736Sdavidch			    struct elink_vars *vars);
244255736Sdavidchtypedef uint8_t (*read_status_t)(struct elink_phy *phy, struct elink_params *params,
245255736Sdavidch			    struct elink_vars *vars);
246255736Sdavidchtypedef void (*link_reset_t)(struct elink_phy *phy,
247255736Sdavidch			     struct elink_params *params);
248255736Sdavidchtypedef void (*config_loopback_t)(struct elink_phy *phy,
249255736Sdavidch				  struct elink_params *params);
250255736Sdavidchtypedef uint8_t (*format_fw_ver_t)(uint32_t raw, uint8_t *str, uint16_t *len);
251255736Sdavidchtypedef void (*hw_reset_t)(struct elink_phy *phy, struct elink_params *params);
252255736Sdavidchtypedef void (*set_link_led_t)(struct elink_phy *phy,
253255736Sdavidch			       struct elink_params *params, uint8_t mode);
254255736Sdavidchtypedef void (*phy_specific_func_t)(struct elink_phy *phy,
255255736Sdavidch				    struct elink_params *params, uint32_t action);
256255736Sdavidchstruct elink_reg_set {
257255736Sdavidch	uint8_t  devad;
258255736Sdavidch	uint16_t reg;
259255736Sdavidch	uint16_t val;
260255736Sdavidch};
261255736Sdavidch
262255736Sdavidchstruct elink_phy {
263255736Sdavidch	uint32_t type;
264255736Sdavidch
265255736Sdavidch	/* Loaded during init */
266255736Sdavidch	uint8_t addr;
267255736Sdavidch	uint8_t def_md_devad;
268255736Sdavidch	uint16_t flags;
269255736Sdavidch	/* No Over-Current detection */
270255736Sdavidch#define ELINK_FLAGS_NOC			(1<<1)
271255736Sdavidch	/* Fan failure detection required */
272255736Sdavidch#define ELINK_FLAGS_FAN_FAILURE_DET_REQ	(1<<2)
273255736Sdavidch	/* Initialize first the XGXS and only then the phy itself */
274255736Sdavidch#define ELINK_FLAGS_INIT_XGXS_FIRST		(1<<3)
275255736Sdavidch#define ELINK_FLAGS_WC_DUAL_MODE		(1<<4)
276255736Sdavidch#define ELINK_FLAGS_4_PORT_MODE		(1<<5)
277255736Sdavidch#define ELINK_FLAGS_REARM_LATCH_SIGNAL		(1<<6)
278255736Sdavidch#define ELINK_FLAGS_SFP_NOT_APPROVED		(1<<7)
279255736Sdavidch#define ELINK_FLAGS_MDC_MDIO_WA		(1<<8)
280255736Sdavidch#define ELINK_FLAGS_DUMMY_READ			(1<<9)
281255736Sdavidch#define ELINK_FLAGS_MDC_MDIO_WA_B0		(1<<10)
282255736Sdavidch#define ELINK_FLAGS_SFP_MODULE_PLUGGED_IN_WC	(1<<11)
283255736Sdavidch#define ELINK_FLAGS_TX_ERROR_CHECK		(1<<12)
284255736Sdavidch#define ELINK_FLAGS_EEE			(1<<13)
285255736Sdavidch#define ELINK_FLAGS_TEMPERATURE		(1<<14)
286255736Sdavidch#define ELINK_FLAGS_MDC_MDIO_WA_G		(1<<15)
287255736Sdavidch
288255736Sdavidch	/* preemphasis values for the rx side */
289255736Sdavidch	uint16_t rx_preemphasis[4];
290255736Sdavidch
291255736Sdavidch	/* preemphasis values for the tx side */
292255736Sdavidch	uint16_t tx_preemphasis[4];
293255736Sdavidch
294255736Sdavidch	/* EMAC address for access MDIO */
295255736Sdavidch	uint32_t mdio_ctrl;
296255736Sdavidch
297255736Sdavidch	uint32_t supported;
298255736Sdavidch#define ELINK_SUPPORTED_10baseT_Half		(1<<0)
299255736Sdavidch#define ELINK_SUPPORTED_10baseT_Full		(1<<1)
300255736Sdavidch#define ELINK_SUPPORTED_100baseT_Half		(1<<2)
301255736Sdavidch#define ELINK_SUPPORTED_100baseT_Full 		(1<<3)
302255736Sdavidch#define ELINK_SUPPORTED_1000baseT_Full 	(1<<4)
303255736Sdavidch#define ELINK_SUPPORTED_2500baseX_Full 	(1<<5)
304255736Sdavidch#define ELINK_SUPPORTED_10000baseT_Full 	(1<<6)
305255736Sdavidch#define ELINK_SUPPORTED_TP 			(1<<7)
306255736Sdavidch#define ELINK_SUPPORTED_FIBRE 			(1<<8)
307255736Sdavidch#define ELINK_SUPPORTED_Autoneg 		(1<<9)
308255736Sdavidch#define ELINK_SUPPORTED_Pause 			(1<<10)
309255736Sdavidch#define ELINK_SUPPORTED_Asym_Pause		(1<<11)
310296071Sdavidcs#define ELINK_SUPPORTED_1000baseKX_Full		(1<<17)
311296071Sdavidcs#define ELINK_SUPPORTED_10000baseKR_Full	(1<<19)
312255736Sdavidch#define ELINK_SUPPORTED_20000baseMLD2_Full	(1<<21)
313255736Sdavidch#define ELINK_SUPPORTED_20000baseKR2_Full	(1<<22)
314255736Sdavidch
315255736Sdavidch	uint32_t media_type;
316255736Sdavidch#define	ELINK_ETH_PHY_UNSPECIFIED	0x0
317255736Sdavidch#define	ELINK_ETH_PHY_SFPP_10G_FIBER	0x1
318255736Sdavidch#define	ELINK_ETH_PHY_XFP_FIBER		0x2
319255736Sdavidch#define	ELINK_ETH_PHY_DA_TWINAX		0x3
320255736Sdavidch#define	ELINK_ETH_PHY_BASE_T		0x4
321255736Sdavidch#define ELINK_ETH_PHY_SFP_1G_FIBER	0x5
322255736Sdavidch#define	ELINK_ETH_PHY_KR		0xf0
323255736Sdavidch#define	ELINK_ETH_PHY_CX4		0xf1
324255736Sdavidch#define	ELINK_ETH_PHY_NOT_PRESENT	0xff
325255736Sdavidch
326255736Sdavidch	/* The address in which version is located*/
327255736Sdavidch	uint32_t ver_addr;
328255736Sdavidch
329255736Sdavidch	uint16_t req_flow_ctrl;
330255736Sdavidch
331255736Sdavidch	uint16_t req_line_speed;
332255736Sdavidch
333255736Sdavidch	uint32_t speed_cap_mask;
334255736Sdavidch
335255736Sdavidch	uint16_t req_duplex;
336255736Sdavidch	uint16_t rsrv;
337255736Sdavidch	/* Called per phy/port init, and it configures LASI, speed, autoneg,
338255736Sdavidch	 duplex, flow control negotiation, etc. */
339255736Sdavidch	config_init_t config_init;
340255736Sdavidch
341255736Sdavidch	/* Called due to interrupt. It determines the link, speed */
342255736Sdavidch	read_status_t read_status;
343255736Sdavidch
344255736Sdavidch	/* Called when driver is unloading. Should reset the phy */
345255736Sdavidch	link_reset_t link_reset;
346255736Sdavidch
347255736Sdavidch	/* Set the loopback configuration for the phy */
348255736Sdavidch	config_loopback_t config_loopback;
349255736Sdavidch
350255736Sdavidch	/* Format the given raw number into str up to len */
351255736Sdavidch	format_fw_ver_t format_fw_ver;
352255736Sdavidch
353255736Sdavidch	/* Reset the phy (both ports) */
354255736Sdavidch	hw_reset_t hw_reset;
355255736Sdavidch
356255736Sdavidch	/* Set link led mode (on/off/oper)*/
357255736Sdavidch	set_link_led_t set_link_led;
358255736Sdavidch
359255736Sdavidch	/* PHY Specific tasks */
360255736Sdavidch	phy_specific_func_t phy_specific_func;
361255736Sdavidch#define ELINK_DISABLE_TX	1
362255736Sdavidch#define ELINK_ENABLE_TX	2
363255736Sdavidch#define ELINK_PHY_INIT	3
364255736Sdavidch};
365255736Sdavidch
366255736Sdavidch/* Inputs parameters to the CLC */
367255736Sdavidchstruct elink_params {
368255736Sdavidch
369255736Sdavidch	uint8_t port;
370255736Sdavidch
371255736Sdavidch	/* Default / User Configuration */
372255736Sdavidch	uint8_t loopback_mode;
373255736Sdavidch#define ELINK_LOOPBACK_NONE		0
374255736Sdavidch#define ELINK_LOOPBACK_EMAC		1
375255736Sdavidch#define ELINK_LOOPBACK_BMAC		2
376255736Sdavidch#define ELINK_LOOPBACK_XGXS		3
377255736Sdavidch#define ELINK_LOOPBACK_EXT_PHY		4
378255736Sdavidch#define ELINK_LOOPBACK_EXT		5
379255736Sdavidch#define ELINK_LOOPBACK_UMAC		6
380255736Sdavidch#define ELINK_LOOPBACK_XMAC		7
381255736Sdavidch
382255736Sdavidch	/* Device parameters */
383255736Sdavidch	uint8_t mac_addr[6];
384255736Sdavidch
385255736Sdavidch	uint16_t req_duplex[ELINK_LINK_CONFIG_SIZE];
386255736Sdavidch	uint16_t req_flow_ctrl[ELINK_LINK_CONFIG_SIZE];
387255736Sdavidch
388255736Sdavidch	uint16_t req_line_speed[ELINK_LINK_CONFIG_SIZE]; /* Also determine AutoNeg */
389255736Sdavidch
390255736Sdavidch	/* shmem parameters */
391255736Sdavidch	uint32_t shmem_base;
392255736Sdavidch	uint32_t shmem2_base;
393255736Sdavidch	uint32_t speed_cap_mask[ELINK_LINK_CONFIG_SIZE];
394255736Sdavidch	uint32_t switch_cfg;
395255736Sdavidch#define ELINK_SWITCH_CFG_1G		PORT_FEATURE_CON_SWITCH_1G_SWITCH
396255736Sdavidch#define ELINK_SWITCH_CFG_10G		PORT_FEATURE_CON_SWITCH_10G_SWITCH
397255736Sdavidch#define ELINK_SWITCH_CFG_AUTO_DETECT	PORT_FEATURE_CON_SWITCH_AUTO_DETECT
398255736Sdavidch
399255736Sdavidch	uint32_t lane_config;
400255736Sdavidch
401255736Sdavidch	/* Phy register parameter */
402255736Sdavidch	uint32_t chip_id;
403255736Sdavidch
404255736Sdavidch	/* features */
405255736Sdavidch	uint32_t feature_config_flags;
406255736Sdavidch#define ELINK_FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED	(1<<0)
407255736Sdavidch#define ELINK_FEATURE_CONFIG_PFC_ENABLED			(1<<1)
408255736Sdavidch#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY		(1<<2)
409255736Sdavidch#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY	(1<<3)
410255736Sdavidch#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_EMAC			(1<<4)
411255736Sdavidch#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_BMAC			(1<<5)
412255736Sdavidch#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_UMAC			(1<<6)
413255736Sdavidch#define ELINK_FEATURE_CONFIG_EMUL_DISABLE_XMAC			(1<<7)
414255736Sdavidch#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_AFEX			(1<<8)
415255736Sdavidch#define ELINK_FEATURE_CONFIG_AUTOGREEEN_ENABLED		(1<<9)
416255736Sdavidch#define ELINK_FEATURE_CONFIG_BC_SUPPORTS_SFP_TX_DISABLED	(1<<10)
417255736Sdavidch#define ELINK_FEATURE_CONFIG_DISABLE_REMOTE_FAULT_DET		(1<<11)
418255736Sdavidch#define ELINK_FEATURE_CONFIG_IEEE_PHY_TEST			(1<<12)
419255736Sdavidch#define ELINK_FEATURE_CONFIG_MT_SUPPORT			(1<<13)
420255736Sdavidch#define ELINK_FEATURE_CONFIG_BOOT_FROM_SAN			(1<<14)
421296071Sdavidcs#define ELINK_FEATURE_CONFIG_DISABLE_PD				(1<<15)
422255736Sdavidch
423255736Sdavidch	/* Will be populated during common init */
424255736Sdavidch	struct elink_phy phy[ELINK_MAX_PHYS];
425255736Sdavidch
426255736Sdavidch	/* Will be populated during common init */
427255736Sdavidch	uint8_t num_phys;
428255736Sdavidch
429255736Sdavidch	uint8_t rsrv;
430255736Sdavidch
431255736Sdavidch	/* Used to configure the EEE Tx LPI timer, has several modes of
432255736Sdavidch	 * operation, according to bits 29:28 -
433255736Sdavidch	 * 2'b00: Timer will be configured by nvram, output will be the value
434255736Sdavidch	 *        from nvram.
435255736Sdavidch	 * 2'b01: Timer will be configured by nvram, output will be in
436255736Sdavidch	 *        microseconds.
437255736Sdavidch	 * 2'b10: bits 1:0 contain an nvram value which will be used instead
438255736Sdavidch	 *        of the one located in the nvram. Output will be that value.
439255736Sdavidch	 * 2'b11: bits 19:0 contain the idle timer in microseconds; output
440255736Sdavidch	 *        will be in microseconds.
441255736Sdavidch	 * Bits 31:30 should be 2'b11 in order for EEE to be enabled.
442255736Sdavidch	 */
443255736Sdavidch	uint32_t eee_mode;
444255736Sdavidch#define ELINK_EEE_MODE_NVRAM_BALANCED_TIME		(0xa00)
445255736Sdavidch#define ELINK_EEE_MODE_NVRAM_AGGRESSIVE_TIME		(0x100)
446255736Sdavidch#define ELINK_EEE_MODE_NVRAM_LATENCY_TIME		(0x6000)
447255736Sdavidch#define ELINK_EEE_MODE_NVRAM_MASK		(0x3)
448255736Sdavidch#define ELINK_EEE_MODE_TIMER_MASK		(0xfffff)
449255736Sdavidch#define ELINK_EEE_MODE_OUTPUT_TIME		(1<<28)
450255736Sdavidch#define ELINK_EEE_MODE_OVERRIDE_NVRAM		(1<<29)
451255736Sdavidch#define ELINK_EEE_MODE_ENABLE_LPI		(1<<30)
452255736Sdavidch#define ELINK_EEE_MODE_ADV_LPI			(1<<31)
453255736Sdavidch
454255736Sdavidch	uint16_t hw_led_mode; /* part of the hw_config read from the shmem */
455255736Sdavidch	uint32_t multi_phy_config;
456255736Sdavidch
457255736Sdavidch	/* Device pointer passed to all callback functions */
458255736Sdavidch	struct bxe_softc *sc;
459255736Sdavidch	uint16_t req_fc_auto_adv; /* Should be set to TX / BOTH when
460255736Sdavidch				req_flow_ctrl is set to AUTO */
461255736Sdavidch	uint16_t link_flags;
462255736Sdavidch#define ELINK_LINK_FLAGS_INT_DISABLED		(1<<0)
463255736Sdavidch#define ELINK_PHY_INITIALIZED		(1<<1)
464255736Sdavidch	uint32_t lfa_base;
465296071Sdavidcs
466296071Sdavidcs	/* The same definitions as the shmem2 parameter */
467296071Sdavidcs	uint32_t link_attr_sync;
468255736Sdavidch};
469255736Sdavidch
470255736Sdavidch/* Output parameters */
471255736Sdavidchstruct elink_vars {
472255736Sdavidch	uint8_t phy_flags;
473255736Sdavidch#define PHY_XGXS_FLAG			(1<<0)
474255736Sdavidch#define PHY_SGMII_FLAG			(1<<1)
475255736Sdavidch#define PHY_PHYSICAL_LINK_FLAG		(1<<2)
476255736Sdavidch#define PHY_HALF_OPEN_CONN_FLAG		(1<<3)
477255736Sdavidch#define PHY_OVER_CURRENT_FLAG		(1<<4)
478255736Sdavidch#define PHY_SFP_TX_FAULT_FLAG		(1<<5)
479255736Sdavidch
480255736Sdavidch	uint8_t mac_type;
481255736Sdavidch#define ELINK_MAC_TYPE_NONE		0
482255736Sdavidch#define ELINK_MAC_TYPE_EMAC		1
483255736Sdavidch#define ELINK_MAC_TYPE_BMAC		2
484255736Sdavidch#define ELINK_MAC_TYPE_UMAC		3
485255736Sdavidch#define ELINK_MAC_TYPE_XMAC		4
486255736Sdavidch
487255736Sdavidch	uint8_t phy_link_up; /* internal phy link indication */
488255736Sdavidch	uint8_t link_up;
489255736Sdavidch
490255736Sdavidch	uint16_t line_speed;
491255736Sdavidch	uint16_t duplex;
492255736Sdavidch
493255736Sdavidch	uint16_t flow_ctrl;
494255736Sdavidch	uint16_t ieee_fc;
495255736Sdavidch
496255736Sdavidch	/* The same definitions as the shmem parameter */
497255736Sdavidch	uint32_t link_status;
498255736Sdavidch	uint32_t eee_status;
499255736Sdavidch	uint8_t fault_detected;
500255736Sdavidch	uint8_t check_kr2_recovery_cnt;
501255736Sdavidch#define ELINK_CHECK_KR2_RECOVERY_CNT	5
502255736Sdavidch	uint16_t periodic_flags;
503255736Sdavidch#define ELINK_PERIODIC_FLAGS_LINK_EVENT	0x0001
504255736Sdavidch
505255736Sdavidch	uint32_t aeu_int_mask;
506255736Sdavidch	uint8_t rx_tx_asic_rst;
507255736Sdavidch	uint8_t turn_to_run_wc_rt;
508255736Sdavidch	uint16_t rsrv2;
509296071Sdavidcs
510255736Sdavidch};
511255736Sdavidch
512255736Sdavidch/***********************************************************/
513255736Sdavidch/*                         Functions                       */
514255736Sdavidch/***********************************************************/
515255736Sdavidchelink_status_t elink_phy_init(struct elink_params *params, struct elink_vars *vars);
516255736Sdavidch
517255736Sdavidch/* Reset the link. Should be called when driver or interface goes down
518255736Sdavidch   Before calling phy firmware upgrade, the reset_ext_phy should be set
519255736Sdavidch   to 0 */
520255736Sdavidchelink_status_t elink_link_reset(struct elink_params *params, struct elink_vars *vars,
521255736Sdavidch		     uint8_t reset_ext_phy);
522255736Sdavidchelink_status_t elink_lfa_reset(struct elink_params *params, struct elink_vars *vars);
523255736Sdavidch/* elink_link_update should be called upon link interrupt */
524255736Sdavidchelink_status_t elink_link_update(struct elink_params *params, struct elink_vars *vars);
525255736Sdavidch
526255736Sdavidch/* use the following phy functions to read/write from external_phy
527255736Sdavidch  In order to use it to read/write internal phy registers, use
528255736Sdavidch  ELINK_DEFAULT_PHY_DEV_ADDR as devad, and (_bank + (_addr & 0xf)) as
529255736Sdavidch  the register */
530255736Sdavidchelink_status_t elink_phy_read(struct elink_params *params, uint8_t phy_addr,
531255736Sdavidch		   uint8_t devad, uint16_t reg, uint16_t *ret_val);
532255736Sdavidch
533255736Sdavidchelink_status_t elink_phy_write(struct elink_params *params, uint8_t phy_addr,
534255736Sdavidch		    uint8_t devad, uint16_t reg, uint16_t val);
535255736Sdavidch
536255736Sdavidch/* Reads the link_status from the shmem,
537255736Sdavidch   and update the link vars accordingly */
538255736Sdavidchvoid elink_link_status_update(struct elink_params *input,
539255736Sdavidch			    struct elink_vars *output);
540255736Sdavidch/* returns string representing the fw_version of the external phy */
541255736Sdavidchelink_status_t elink_get_ext_phy_fw_version(struct elink_params *params, uint8_t *version,
542255736Sdavidch				 uint16_t len);
543255736Sdavidch
544255736Sdavidch/* Set/Unset the led
545255736Sdavidch   Basically, the CLC takes care of the led for the link, but in case one needs
546255736Sdavidch   to set/unset the led unnaturally, set the "mode" to ELINK_LED_MODE_OPER to
547255736Sdavidch   blink the led, and ELINK_LED_MODE_OFF to set the led off.*/
548255736Sdavidchelink_status_t elink_set_led(struct elink_params *params,
549255736Sdavidch		  struct elink_vars *vars, uint8_t mode, uint32_t speed);
550255736Sdavidch#define ELINK_LED_MODE_OFF			0
551255736Sdavidch#define ELINK_LED_MODE_ON			1
552255736Sdavidch#define ELINK_LED_MODE_OPER			2
553255736Sdavidch#define ELINK_LED_MODE_FRONT_PANEL_OFF	3
554255736Sdavidch
555255736Sdavidch/* elink_handle_module_detect_int should be called upon module detection
556255736Sdavidch   interrupt */
557255736Sdavidchvoid elink_handle_module_detect_int(struct elink_params *params);
558255736Sdavidch
559255736Sdavidch/* Get the actual link status. In case it returns ELINK_STATUS_OK, link is up,
560255736Sdavidch	otherwise link is down*/
561255736Sdavidchelink_status_t elink_test_link(struct elink_params *params, struct elink_vars *vars,
562255736Sdavidch		    uint8_t is_serdes);
563255736Sdavidch
564255736Sdavidch
565255736Sdavidch/* One-time initialization for external phy after power up */
566255736Sdavidchelink_status_t elink_common_init_phy(struct bxe_softc *sc, uint32_t shmem_base_path[],
567255736Sdavidch			  uint32_t shmem2_base_path[], uint32_t chip_id, uint8_t one_port_enabled);
568255736Sdavidch
569255736Sdavidch/* Reset the external PHY using GPIO */
570255736Sdavidchvoid elink_ext_phy_hw_reset(struct bxe_softc *sc, uint8_t port);
571255736Sdavidch
572255736Sdavidch/* Reset the external of SFX7101 */
573255736Sdavidchvoid elink_sfx7101_sp_sw_reset(struct bxe_softc *sc, struct elink_phy *phy);
574255736Sdavidch
575255736Sdavidch/* Read "byte_cnt" bytes from address "addr" from the SFP+ EEPROM */
576255736Sdavidchelink_status_t elink_read_sfp_module_eeprom(struct elink_phy *phy,
577255736Sdavidch				 struct elink_params *params, uint8_t dev_addr,
578255736Sdavidch				 uint16_t addr, uint16_t byte_cnt, uint8_t *o_buf);
579255736Sdavidch
580255736Sdavidchvoid elink_hw_reset_phy(struct elink_params *params);
581255736Sdavidch
582255736Sdavidch/* Check swap bit and adjust PHY order */
583255736Sdavidchuint32_t elink_phy_selection(struct elink_params *params);
584255736Sdavidch
585255736Sdavidch/* Probe the phys on board, and populate them in "params" */
586255736Sdavidchelink_status_t elink_phy_probe(struct elink_params *params);
587255736Sdavidch
588255736Sdavidch/* Checks if fan failure detection is required on one of the phys on board */
589255736Sdavidchuint8_t elink_fan_failure_det_req(struct bxe_softc *sc, uint32_t shmem_base,
590255736Sdavidch			     uint32_t shmem2_base, uint8_t port);
591255736Sdavidch
592255736Sdavidch/* Open / close the gate between the NIG and the BRB */
593255736Sdavidchvoid elink_set_rx_filter(struct elink_params *params, uint8_t en);
594255736Sdavidch
595255736Sdavidch/* DCBX structs */
596255736Sdavidch
597255736Sdavidch/* Number of maximum COS per chip */
598255736Sdavidch#define ELINK_DCBX_E2E3_MAX_NUM_COS		(2)
599255736Sdavidch#define ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0	(6)
600255736Sdavidch#define ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1	(3)
601255736Sdavidch#define ELINK_DCBX_E3B0_MAX_NUM_COS		( \
602255736Sdavidch			ELINK_MAXVAL(ELINK_DCBX_E3B0_MAX_NUM_COS_PORT0, \
603255736Sdavidch			    ELINK_DCBX_E3B0_MAX_NUM_COS_PORT1))
604255736Sdavidch
605255736Sdavidch#define ELINK_DCBX_MAX_NUM_COS			( \
606255736Sdavidch			ELINK_MAXVAL(ELINK_DCBX_E3B0_MAX_NUM_COS, \
607255736Sdavidch			    ELINK_DCBX_E2E3_MAX_NUM_COS))
608255736Sdavidch
609255736Sdavidch/* PFC port configuration params */
610255736Sdavidchstruct elink_nig_brb_pfc_port_params {
611255736Sdavidch	/* NIG */
612255736Sdavidch	uint32_t pause_enable;
613255736Sdavidch	uint32_t llfc_out_en;
614255736Sdavidch	uint32_t llfc_enable;
615255736Sdavidch	uint32_t pkt_priority_to_cos;
616255736Sdavidch	uint8_t num_of_rx_cos_priority_mask;
617255736Sdavidch	uint32_t rx_cos_priority_mask[ELINK_DCBX_MAX_NUM_COS];
618255736Sdavidch	uint32_t llfc_high_priority_classes;
619255736Sdavidch	uint32_t llfc_low_priority_classes;
620255736Sdavidch};
621255736Sdavidch
622255736Sdavidch
623255736Sdavidch/* ETS port configuration params */
624255736Sdavidchstruct elink_ets_bw_params {
625255736Sdavidch	uint8_t bw;
626255736Sdavidch};
627255736Sdavidch
628255736Sdavidchstruct elink_ets_sp_params {
629255736Sdavidch	/**
630255736Sdavidch	 * valid values are 0 - 5. 0 is highest strict priority.
631255736Sdavidch	 * There can't be two COS's with the same pri.
632255736Sdavidch	 */
633255736Sdavidch	uint8_t pri;
634255736Sdavidch};
635255736Sdavidch
636255736Sdavidchenum elink_cos_state {
637255736Sdavidch	elink_cos_state_strict = 0,
638255736Sdavidch	elink_cos_state_bw = 1,
639255736Sdavidch};
640255736Sdavidch
641255736Sdavidchstruct elink_ets_cos_params {
642255736Sdavidch	enum elink_cos_state state ;
643255736Sdavidch	union {
644255736Sdavidch		struct elink_ets_bw_params bw_params;
645255736Sdavidch		struct elink_ets_sp_params sp_params;
646255736Sdavidch	} params;
647255736Sdavidch};
648255736Sdavidch
649255736Sdavidchstruct elink_ets_params {
650255736Sdavidch	uint8_t num_of_cos; /* Number of valid COS entries*/
651255736Sdavidch	struct elink_ets_cos_params cos[ELINK_DCBX_MAX_NUM_COS];
652255736Sdavidch};
653255736Sdavidch
654255736Sdavidch/* Used to update the PFC attributes in EMAC, BMAC, NIG and BRB
655255736Sdavidch * when link is already up
656255736Sdavidch */
657255736Sdavidchelink_status_t elink_update_pfc(struct elink_params *params,
658255736Sdavidch		      struct elink_vars *vars,
659255736Sdavidch		      struct elink_nig_brb_pfc_port_params *pfc_params);
660255736Sdavidch
661255736Sdavidch
662255736Sdavidch/* Used to configure the ETS to disable */
663255736Sdavidchelink_status_t elink_ets_disabled(struct elink_params *params,
664255736Sdavidch		       struct elink_vars *vars);
665255736Sdavidch
666255736Sdavidch/* Used to configure the ETS to BW limited */
667255736Sdavidchvoid elink_ets_bw_limit(const struct elink_params *params, const uint32_t cos0_bw,
668255736Sdavidch			const uint32_t cos1_bw);
669255736Sdavidch
670255736Sdavidch/* Used to configure the ETS to strict */
671255736Sdavidchelink_status_t elink_ets_strict(const struct elink_params *params, const uint8_t strict_cos);
672255736Sdavidch
673255736Sdavidch
674255736Sdavidch/*  Configure the COS to ETS according to BW and SP settings.*/
675255736Sdavidchelink_status_t elink_ets_e3b0_config(const struct elink_params *params,
676255736Sdavidch			 const struct elink_vars *vars,
677255736Sdavidch			 struct elink_ets_params *ets_params);
678255736Sdavidch/* Read pfc statistic*/
679255736Sdavidchvoid elink_pfc_statistic(struct elink_params *params, struct elink_vars *vars,
680255736Sdavidch						 uint32_t pfc_frames_sent[2],
681255736Sdavidch						 uint32_t pfc_frames_received[2]);
682255736Sdavidchvoid elink_init_mod_abs_int(struct bxe_softc *sc, struct elink_vars *vars,
683255736Sdavidch			    uint32_t chip_id, uint32_t shmem_base, uint32_t shmem2_base,
684255736Sdavidch			    uint8_t port);
685296071Sdavidcs//elink_status_t elink_sfp_module_detection(struct elink_phy *phy,
686296071Sdavidcs//			       struct elink_params *params);
687255736Sdavidch
688255736Sdavidchvoid elink_period_func(struct elink_params *params, struct elink_vars *vars);
689255736Sdavidch
690296071Sdavidcs//elink_status_t elink_check_half_open_conn(struct elink_params *params,
691296071Sdavidcs//			            struct elink_vars *vars, uint8_t notify);
692255736Sdavidch
693255736Sdavidchvoid elink_enable_pmd_tx(struct elink_params *params);
694255736Sdavidch
695255736Sdavidch
696255736Sdavidch
697255736Sdavidch#endif /* ELINK_H */
698255736Sdavidch
699