2010-09-07 11:40:50 +00:00
/* Copyright 2008-2010 Broadcom Corporation
2008-06-23 20:27:26 -07:00
*
* Unless you and Broadcom execute a separate written software license
* agreement governing use of this software , this software is licensed to you
* under the terms of the GNU General Public License version 2 , available
* at http : //www.gnu.org/licenses/old-licenses/gpl-2.0.html (the "GPL").
*
* Notwithstanding the above , under no circumstances may you combine this
* software in any way with any other Broadcom software provided under a
* license other than the GPL , without Broadcom ' s express prior written
* consent .
*
* Written by Yaniv Rosner
*
*/
# ifndef BNX2X_LINK_H
# define BNX2X_LINK_H
/***********************************************************/
/* Defines */
/***********************************************************/
2010-10-06 03:28:26 +00:00
# define DEFAULT_PHY_DEV_ADDR 3
# define E2_DEFAULT_PHY_DEV_ADDR 5
2008-06-23 20:27:26 -07:00
2008-12-16 23:53:20 -08:00
# define BNX2X_FLOW_CTRL_AUTO PORT_FEATURE_FLOW_CONTROL_AUTO
# define BNX2X_FLOW_CTRL_TX PORT_FEATURE_FLOW_CONTROL_TX
# define BNX2X_FLOW_CTRL_RX PORT_FEATURE_FLOW_CONTROL_RX
# define BNX2X_FLOW_CTRL_BOTH PORT_FEATURE_FLOW_CONTROL_BOTH
# define BNX2X_FLOW_CTRL_NONE PORT_FEATURE_FLOW_CONTROL_NONE
2008-06-23 20:27:26 -07:00
# define SPEED_AUTO_NEG 0
# define SPEED_12000 12000
# define SPEED_12500 12500
# define SPEED_13000 13000
# define SPEED_15000 15000
# define SPEED_16000 16000
2009-07-21 05:47:47 +00:00
# define SFP_EEPROM_VENDOR_NAME_ADDR 0x14
# define SFP_EEPROM_VENDOR_NAME_SIZE 16
# define SFP_EEPROM_VENDOR_OUI_ADDR 0x25
# define SFP_EEPROM_VENDOR_OUI_SIZE 3
# define SFP_EEPROM_PART_NO_ADDR 0x28
# define SFP_EEPROM_PART_NO_SIZE 16
# define PWR_FLT_ERR_MSG_LEN 250
2010-09-07 11:40:54 +00:00
# define XGXS_EXT_PHY_TYPE(ext_phy_config) \
( ( ext_phy_config ) & PORT_HW_CFG_XGXS_EXT_PHY_TYPE_MASK )
# define XGXS_EXT_PHY_ADDR(ext_phy_config) \
( ( ( ext_phy_config ) & PORT_HW_CFG_XGXS_EXT_PHY_ADDR_MASK ) > > \
PORT_HW_CFG_XGXS_EXT_PHY_ADDR_SHIFT )
# define SERDES_EXT_PHY_TYPE(ext_phy_config) \
( ( ext_phy_config ) & PORT_HW_CFG_SERDES_EXT_PHY_TYPE_MASK )
2010-09-07 11:40:50 +00:00
/* Single Media Direct board is the plain 577xx board with CX4/RJ45 jacks */
# define SINGLE_MEDIA_DIRECT(params) (params->num_phys == 1)
/* Single Media board contains single external phy */
# define SINGLE_MEDIA(params) (params->num_phys == 2)
2010-09-07 11:41:20 +00:00
/* Dual Media board contains two external phy with different media */
# define DUAL_MEDIA(params) (params->num_phys == 3)
# define FW_PARAM_MDIO_CTRL_OFFSET 16
# define FW_PARAM_SET(phy_addr, phy_type, mdio_access) \
( phy_addr | phy_type | mdio_access < < FW_PARAM_MDIO_CTRL_OFFSET )
2008-06-23 20:27:26 -07:00
/***********************************************************/
/* Structs */
/***********************************************************/
2010-09-07 11:40:50 +00:00
# define INT_PHY 0
# define EXT_PHY1 1
2010-09-07 11:41:20 +00:00
# define EXT_PHY2 2
# define MAX_PHYS 3
2010-09-07 11:40:50 +00:00
2010-09-07 11:40:54 +00:00
/* Same configuration is shared between the XGXS and the first external phy */
# define LINK_CONFIG_SIZE (MAX_PHYS - 1)
# define LINK_CONFIG_IDX(_phy_idx) ((_phy_idx == INT_PHY) ? \
0 : ( _phy_idx - 1 ) )
2010-09-07 11:40:50 +00:00
/***********************************************************/
/* bnx2x_phy struct */
/* Defines the required arguments and function per phy */
/***********************************************************/
struct link_vars ;
struct link_params ;
struct bnx2x_phy ;
2010-09-07 11:40:54 +00:00
typedef u8 ( * config_init_t ) ( struct bnx2x_phy * phy , struct link_params * params ,
struct link_vars * vars ) ;
typedef u8 ( * read_status_t ) ( struct bnx2x_phy * phy , struct link_params * params ,
struct link_vars * vars ) ;
typedef void ( * link_reset_t ) ( struct bnx2x_phy * phy ,
struct link_params * params ) ;
typedef void ( * config_loopback_t ) ( struct bnx2x_phy * phy ,
struct link_params * params ) ;
typedef u8 ( * format_fw_ver_t ) ( u32 raw , u8 * str , u16 * len ) ;
typedef void ( * hw_reset_t ) ( struct bnx2x_phy * phy , struct link_params * params ) ;
typedef void ( * set_link_led_t ) ( struct bnx2x_phy * phy ,
struct link_params * params , u8 mode ) ;
2010-09-07 11:41:20 +00:00
typedef void ( * phy_specific_func_t ) ( struct bnx2x_phy * phy ,
struct link_params * params , u32 action ) ;
2010-09-07 11:40:54 +00:00
2010-09-07 11:40:50 +00:00
struct bnx2x_phy {
u32 type ;
/* Loaded during init */
u8 addr ;
2010-09-07 11:40:54 +00:00
u8 flags ;
/* Require HW lock */
# define FLAGS_HW_LOCK_REQUIRED (1<<0)
/* No Over-Current detection */
# define FLAGS_NOC (1<<1)
/* Fan failure detection required */
# define FLAGS_FAN_FAILURE_DET_REQ (1<<2)
/* Initialize first the XGXS and only then the phy itself */
2010-09-07 11:41:20 +00:00
# define FLAGS_INIT_XGXS_FIRST (1<<3)
# define FLAGS_REARM_LATCH_SIGNAL (1<<6)
# define FLAGS_SFP_NOT_APPROVED (1<<7)
2010-09-07 11:40:54 +00:00
u8 def_md_devad ;
u8 reserved ;
/* preemphasis values for the rx side */
u16 rx_preemphasis [ 4 ] ;
/* preemphasis values for the tx side */
u16 tx_preemphasis [ 4 ] ;
/* EMAC address for access MDIO */
2010-09-07 11:40:50 +00:00
u32 mdio_ctrl ;
2010-09-07 11:40:54 +00:00
u32 supported ;
u32 media_type ;
# define ETH_PHY_UNSPECIFIED 0x0
# define ETH_PHY_SFP_FIBER 0x1
# define ETH_PHY_XFP_FIBER 0x2
# define ETH_PHY_DA_TWINAX 0x3
# define ETH_PHY_BASE_T 0x4
# define ETH_PHY_NOT_PRESENT 0xff
/* The address in which version is located*/
u32 ver_addr ;
u16 req_flow_ctrl ;
u16 req_line_speed ;
u32 speed_cap_mask ;
u16 req_duplex ;
u16 rsrv ;
/* Called per phy/port init, and it configures LASI, speed, autoneg,
duplex , flow control negotiation , etc . */
config_init_t config_init ;
/* Called due to interrupt. It determines the link, speed */
read_status_t read_status ;
/* Called when driver is unloading. Should reset the phy */
link_reset_t link_reset ;
/* Set the loopback configuration for the phy */
config_loopback_t config_loopback ;
/* Format the given raw number into str up to len */
format_fw_ver_t format_fw_ver ;
/* Reset the phy (both ports) */
hw_reset_t hw_reset ;
/* Set link led mode (on/off/oper)*/
set_link_led_t set_link_led ;
2010-09-07 11:41:20 +00:00
/* PHY Specific tasks */
phy_specific_func_t phy_specific_func ;
# define DISABLE_TX 1
# define ENABLE_TX 2
2010-09-07 11:40:50 +00:00
} ;
2008-06-23 20:27:26 -07:00
/* Inputs parameters to the CLC */
struct link_params {
u8 port ;
/* Default / User Configuration */
u8 loopback_mode ;
# define LOOPBACK_NONE 0
# define LOOPBACK_EMAC 1
# define LOOPBACK_BMAC 2
2010-09-07 11:41:13 +00:00
# define LOOPBACK_XGXS 3
2008-06-23 20:27:26 -07:00
# define LOOPBACK_EXT_PHY 4
2008-08-13 15:57:28 -07:00
# define LOOPBACK_EXT 5
2008-06-23 20:27:26 -07:00
/* Device parameters */
u8 mac_addr [ 6 ] ;
2008-08-13 15:56:17 -07:00
2010-09-07 11:41:20 +00:00
u16 req_duplex [ LINK_CONFIG_SIZE ] ;
u16 req_flow_ctrl [ LINK_CONFIG_SIZE ] ;
u16 req_line_speed [ LINK_CONFIG_SIZE ] ; /* Also determine AutoNeg */
2008-06-23 20:27:26 -07:00
/* shmem parameters */
u32 shmem_base ;
2010-09-07 11:41:20 +00:00
u32 shmem2_base ;
u32 speed_cap_mask [ LINK_CONFIG_SIZE ] ;
2008-06-23 20:27:26 -07:00
u32 switch_cfg ;
# define SWITCH_CFG_1G PORT_FEATURE_CON_SWITCH_1G_SWITCH
# define SWITCH_CFG_10G PORT_FEATURE_CON_SWITCH_10G_SWITCH
# define SWITCH_CFG_AUTO_DETECT PORT_FEATURE_CON_SWITCH_AUTO_DETECT
u32 lane_config ;
2009-08-12 08:24:02 +00:00
2008-06-23 20:27:26 -07:00
/* Phy register parameter */
u32 chip_id ;
2009-02-12 08:36:55 +00:00
u32 feature_config_flags ;
# define FEATURE_CONFIG_OVERRIDE_PREEMPHASIS_ENABLED (1<<0)
2009-07-21 05:47:47 +00:00
# define FEATURE_CONFIG_BC_SUPPORTS_OPT_MDL_VRFY (1<<2)
2010-09-07 11:41:20 +00:00
# define FEATURE_CONFIG_BC_SUPPORTS_DUAL_PHY_OPT_MDL_VRFY (1<<3)
2010-09-07 11:40:50 +00:00
/* Will be populated during common init */
struct bnx2x_phy phy [ MAX_PHYS ] ;
/* Will be populated during common init */
u8 num_phys ;
2009-08-12 08:23:59 +00:00
2010-09-07 11:40:54 +00:00
u8 rsrv ;
u16 hw_led_mode ; /* part of the hw_config read from the shmem */
2010-09-07 11:41:20 +00:00
u32 multi_phy_config ;
2010-09-07 11:40:54 +00:00
2008-06-23 20:27:26 -07:00
/* Device pointer passed to all callback functions */
struct bnx2x * bp ;
2010-09-07 11:41:20 +00:00
u16 req_fc_auto_adv ; /* Should be set to TX / BOTH when
req_flow_ctrl is set to AUTO */
2008-06-23 20:27:26 -07:00
} ;
/* Output parameters */
struct link_vars {
2009-08-12 08:23:59 +00:00
u8 phy_flags ;
u8 mac_type ;
# define MAC_TYPE_NONE 0
# define MAC_TYPE_EMAC 1
# define MAC_TYPE_BMAC 2
2008-06-23 20:27:26 -07:00
u8 phy_link_up ; /* internal phy link indication */
u8 link_up ;
2009-08-12 08:23:59 +00:00
u16 line_speed ;
2008-06-23 20:27:26 -07:00
u16 duplex ;
2009-08-12 08:23:59 +00:00
2008-06-23 20:27:26 -07:00
u16 flow_ctrl ;
2009-08-12 08:23:59 +00:00
u16 ieee_fc ;
2008-06-23 20:27:26 -07:00
/* The same definitions as the shmem parameter */
u32 link_status ;
} ;
/***********************************************************/
/* Functions */
/***********************************************************/
u8 bnx2x_phy_init ( struct link_params * input , struct link_vars * output ) ;
2009-02-12 08:36:55 +00:00
/* Reset the link. Should be called when driver or interface goes down
Before calling phy firmware upgrade , the reset_ext_phy should be set
to 0 */
u8 bnx2x_link_reset ( struct link_params * params , struct link_vars * vars ,
u8 reset_ext_phy ) ;
2008-06-23 20:27:26 -07:00
/* bnx2x_link_update should be called upon link interrupt */
u8 bnx2x_link_update ( struct link_params * input , struct link_vars * output ) ;
2010-09-07 11:40:50 +00:00
/* use the following phy functions to read/write from external_phy
2008-06-23 20:27:26 -07:00
In order to use it to read / write internal phy registers , use
DEFAULT_PHY_DEV_ADDR as devad , and ( _bank + ( _addr & 0xf ) ) as
the register */
2010-09-07 11:40:50 +00:00
u8 bnx2x_phy_read ( struct link_params * params , u8 phy_addr ,
u8 devad , u16 reg , u16 * ret_val ) ;
2008-06-23 20:27:26 -07:00
2010-09-07 11:40:50 +00:00
u8 bnx2x_phy_write ( struct link_params * params , u8 phy_addr ,
u8 devad , u16 reg , u16 val ) ;
2008-06-23 20:27:26 -07:00
/* Reads the link_status from the shmem,
2008-08-13 15:59:08 -07:00
and update the link vars accordingly */
2008-06-23 20:27:26 -07:00
void bnx2x_link_status_update ( struct link_params * input ,
struct link_vars * output ) ;
/* returns string representing the fw_version of the external phy */
u8 bnx2x_get_ext_phy_fw_version ( struct link_params * params , u8 driver_loaded ,
u8 * version , u16 len ) ;
/* Set/Unset the led
Basically , the CLC takes care of the led for the link , but in case one needs
2008-08-13 15:59:08 -07:00
to set / unset the led unnaturally , set the " mode " to LED_MODE_OPER to
2008-06-23 20:27:26 -07:00
blink the led , and LED_MODE_OFF to set the led off . */
2010-09-07 11:41:23 +00:00
u8 bnx2x_set_led ( struct link_params * params , struct link_vars * vars ,
u8 mode , u32 speed ) ;
# define LED_MODE_OFF 0
# define LED_MODE_ON 1
# define LED_MODE_OPER 2
# define LED_MODE_FRONT_PANEL_OFF 3
2008-06-23 20:27:26 -07:00
2009-02-12 08:36:55 +00:00
/* bnx2x_handle_module_detect_int should be called upon module detection
interrupt */
void bnx2x_handle_module_detect_int ( struct link_params * params ) ;
2008-06-23 20:27:26 -07:00
/* Get the actual link status. In case it returns 0, link is up,
otherwise link is down */
2010-09-07 11:41:20 +00:00
u8 bnx2x_test_link ( struct link_params * input , struct link_vars * vars ,
u8 is_serdes ) ;
2008-06-23 20:27:26 -07:00
2008-08-13 15:57:28 -07:00
/* One-time initialization for external phy after power up */
2010-10-06 03:28:26 +00:00
u8 bnx2x_common_init_phy ( struct bnx2x * bp , u32 shmem_base_path [ ] ,
u32 shmem2_base_path [ ] , u32 chip_id ) ;
2008-06-23 20:27:26 -07:00
2009-08-12 08:23:11 +00:00
/* Reset the external PHY using GPIO */
void bnx2x_ext_phy_hw_reset ( struct bnx2x * bp , u8 port ) ;
2010-09-07 11:40:50 +00:00
/* Reset the external of SFX7101 */
void bnx2x_sfx7101_sp_sw_reset ( struct bnx2x * bp , struct bnx2x_phy * phy ) ;
2009-02-12 08:38:32 +00:00
2010-09-07 11:41:04 +00:00
void bnx2x_hw_reset_phy ( struct link_params * params ) ;
/* Checks if HW lock is required for this phy/board type */
2010-09-07 11:41:20 +00:00
u8 bnx2x_hw_lock_required ( struct bnx2x * bp , u32 shmem_base ,
u32 shmem2_base ) ;
/* Check swap bit and adjust PHY order */
u32 bnx2x_phy_selection ( struct link_params * params ) ;
2010-09-07 11:40:50 +00:00
/* Probe the phys on board, and populate them in "params" */
u8 bnx2x_phy_probe ( struct link_params * params ) ;
2010-09-07 11:41:04 +00:00
/* Checks if fan failure detection is required on one of the phys on board */
2010-09-07 11:41:20 +00:00
u8 bnx2x_fan_failure_det_req ( struct bnx2x * bp , u32 shmem_base ,
u32 shmem2_base , u8 port ) ;
2010-09-07 11:41:04 +00:00
2008-06-23 20:27:26 -07:00
# endif /* BNX2X_LINK_H */