提交 a8db5b4c 编写于 作者: Y Yaniv Rosner 提交者: David S. Miller

bnx2x: Enhance SFP+ module control

Add flexible support to control various SFP+ module features either throughout MDIO registers or GPIO pins according to NVRAM configuration
Signed-off-by: NYaniv Rosner <yanivr@broadcom.com>
Signed-off-by: NEilon Greenstein <eilong@broadcom.com>
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
上级 6d870c39
...@@ -237,8 +237,26 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ ...@@ -237,8 +237,26 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
#define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 16 #define PORT_HW_CFG_SERDES_RX_DRV_EQUALIZER_SHIFT 16
u32 Reserved0[16]; /* 0x158 */ u32 Reserved0[3]; /* 0x158 */
/* Controls the TX laser of the SFP+ module */
u32 sfp_ctrl; /* 0x164 */
#define PORT_HW_CFG_TX_LASER_MASK 0x000000FF
#define PORT_HW_CFG_TX_LASER_SHIFT 0
#define PORT_HW_CFG_TX_LASER_MDIO 0x00000000
#define PORT_HW_CFG_TX_LASER_GPIO0 0x00000001
#define PORT_HW_CFG_TX_LASER_GPIO1 0x00000002
#define PORT_HW_CFG_TX_LASER_GPIO2 0x00000003
#define PORT_HW_CFG_TX_LASER_GPIO3 0x00000004
/* Controls the fault module LED of the SFP+ */
#define PORT_HW_CFG_FAULT_MODULE_LED_MASK 0x0000FF00
#define PORT_HW_CFG_FAULT_MODULE_LED_SHIFT 8
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO0 0x00000000
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO1 0x00000100
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO2 0x00000200
#define PORT_HW_CFG_FAULT_MODULE_LED_GPIO3 0x00000300
#define PORT_HW_CFG_FAULT_MODULE_LED_DISABLED 0x00000400
u32 Reserved01[12]; /* 0x158 */
/* for external PHY, or forced mode or during AN */ /* for external PHY, or forced mode or during AN */
u16 xgxs_config_rx[4]; /* 0x198 */ u16 xgxs_config_rx[4]; /* 0x198 */
...@@ -246,6 +264,66 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */ ...@@ -246,6 +264,66 @@ struct port_hw_cfg { /* port 0: 0x12c port 1: 0x2bc */
u32 Reserved1[56]; /* 0x1A8 */ u32 Reserved1[56]; /* 0x1A8 */
u32 default_cfg; /* 0x288 */ u32 default_cfg; /* 0x288 */
#define PORT_HW_CFG_GPIO0_CONFIG_MASK 0x00000003
#define PORT_HW_CFG_GPIO0_CONFIG_SHIFT 0
#define PORT_HW_CFG_GPIO0_CONFIG_NA 0x00000000
#define PORT_HW_CFG_GPIO0_CONFIG_LOW 0x00000001
#define PORT_HW_CFG_GPIO0_CONFIG_HIGH 0x00000002
#define PORT_HW_CFG_GPIO0_CONFIG_INPUT 0x00000003
#define PORT_HW_CFG_GPIO1_CONFIG_MASK 0x0000000C
#define PORT_HW_CFG_GPIO1_CONFIG_SHIFT 2
#define PORT_HW_CFG_GPIO1_CONFIG_NA 0x00000000
#define PORT_HW_CFG_GPIO1_CONFIG_LOW 0x00000004
#define PORT_HW_CFG_GPIO1_CONFIG_HIGH 0x00000008
#define PORT_HW_CFG_GPIO1_CONFIG_INPUT 0x0000000c
#define PORT_HW_CFG_GPIO2_CONFIG_MASK 0x00000030
#define PORT_HW_CFG_GPIO2_CONFIG_SHIFT 4
#define PORT_HW_CFG_GPIO2_CONFIG_NA 0x00000000
#define PORT_HW_CFG_GPIO2_CONFIG_LOW 0x00000010
#define PORT_HW_CFG_GPIO2_CONFIG_HIGH 0x00000020
#define PORT_HW_CFG_GPIO2_CONFIG_INPUT 0x00000030
#define PORT_HW_CFG_GPIO3_CONFIG_MASK 0x000000C0
#define PORT_HW_CFG_GPIO3_CONFIG_SHIFT 6
#define PORT_HW_CFG_GPIO3_CONFIG_NA 0x00000000
#define PORT_HW_CFG_GPIO3_CONFIG_LOW 0x00000040
#define PORT_HW_CFG_GPIO3_CONFIG_HIGH 0x00000080
#define PORT_HW_CFG_GPIO3_CONFIG_INPUT 0x000000c0
/*
* When KR link is required to be set to force which is not
* KR-compliant, this parameter determine what is the trigger for it.
* When GPIO is selected, low input will force the speed. Currently
* default speed is 1G. In the future, it may be widen to select the
* forced speed in with another parameter. Note when force-1G is
* enabled, it override option 56: Link Speed option.
*/
#define PORT_HW_CFG_FORCE_KR_ENABLER_MASK 0x00000F00
#define PORT_HW_CFG_FORCE_KR_ENABLER_SHIFT 8
#define PORT_HW_CFG_FORCE_KR_ENABLER_NOT_FORCED 0x00000000
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO0_P0 0x00000100
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO1_P0 0x00000200
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO2_P0 0x00000300
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO3_P0 0x00000400
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO0_P1 0x00000500
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO1_P1 0x00000600
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO2_P1 0x00000700
#define PORT_HW_CFG_FORCE_KR_ENABLER_GPIO3_P1 0x00000800
#define PORT_HW_CFG_FORCE_KR_ENABLER_FORCED 0x00000900
/* Enable to determine with which GPIO to reset the external phy */
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_MASK 0x000F0000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_SHIFT 16
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_PHY_TYPE 0x00000000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0 0x00010000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0 0x00020000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0 0x00030000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0 0x00040000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1 0x00050000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1 0x00060000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1 0x00070000
#define PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1 0x00080000
/* Enable BAM on KR */ /* Enable BAM on KR */
#define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000 #define PORT_HW_CFG_ENABLE_BAM_ON_KR_MASK 0x00100000
#define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20 #define PORT_HW_CFG_ENABLE_BAM_ON_KR_SHIFT 20
......
...@@ -4464,30 +4464,74 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy, ...@@ -4464,30 +4464,74 @@ static u8 bnx2x_8705_read_status(struct bnx2x_phy *phy,
/******************************************************************/ /******************************************************************/
/* SFP+ module Section */ /* SFP+ module Section */
/******************************************************************/ /******************************************************************/
static void bnx2x_sfp_set_transmitter(struct bnx2x *bp, static u8 bnx2x_get_gpio_port(struct link_params *params)
{
u8 gpio_port;
u32 swap_val, swap_override;
struct bnx2x *bp = params->bp;
if (CHIP_IS_E2(bp))
gpio_port = BP_PATH(bp);
else
gpio_port = params->port;
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
return gpio_port ^ (swap_val && swap_override);
}
static void bnx2x_sfp_set_transmitter(struct link_params *params,
struct bnx2x_phy *phy, struct bnx2x_phy *phy,
u8 port,
u8 tx_en) u8 tx_en)
{ {
u16 val; u16 val;
u8 port = params->port;
struct bnx2x *bp = params->bp;
u32 tx_en_mode;
DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x\n",
tx_en, port);
/* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/ /* Disable/Enable transmitter ( TX laser of the SFP+ module.)*/
bnx2x_cl45_read(bp, phy, tx_en_mode = REG_RD(bp, params->shmem_base +
MDIO_PMA_DEVAD, offsetof(struct shmem_region,
MDIO_PMA_REG_PHY_IDENTIFIER, dev_info.port_hw_config[port].sfp_ctrl)) &
&val); PORT_HW_CFG_TX_LASER_MASK;
DP(NETIF_MSG_LINK, "Setting transmitter tx_en=%x for port %x "
"mode = %x\n", tx_en, port, tx_en_mode);
switch (tx_en_mode) {
case PORT_HW_CFG_TX_LASER_MDIO:
if (tx_en) bnx2x_cl45_read(bp, phy,
val &= ~(1<<15); MDIO_PMA_DEVAD,
else MDIO_PMA_REG_PHY_IDENTIFIER,
val |= (1<<15); &val);
bnx2x_cl45_write(bp, phy, if (tx_en)
MDIO_PMA_DEVAD, val &= ~(1<<15);
MDIO_PMA_REG_PHY_IDENTIFIER, else
val); val |= (1<<15);
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD,
MDIO_PMA_REG_PHY_IDENTIFIER,
val);
break;
case PORT_HW_CFG_TX_LASER_GPIO0:
case PORT_HW_CFG_TX_LASER_GPIO1:
case PORT_HW_CFG_TX_LASER_GPIO2:
case PORT_HW_CFG_TX_LASER_GPIO3:
{
u16 gpio_pin;
u8 gpio_port, gpio_mode;
if (tx_en)
gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_HIGH;
else
gpio_mode = MISC_REGISTERS_GPIO_OUTPUT_LOW;
gpio_pin = tx_en_mode - PORT_HW_CFG_TX_LASER_GPIO0;
gpio_port = bnx2x_get_gpio_port(params);
bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
break;
}
default:
DP(NETIF_MSG_LINK, "Invalid TX_LASER_MDIO 0x%x\n", tx_en_mode);
break;
}
} }
static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy, static u8 bnx2x_8726_read_sfp_module_eeprom(struct bnx2x_phy *phy,
...@@ -4966,11 +5010,11 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, ...@@ -4966,11 +5010,11 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
switch (action) { switch (action) {
case DISABLE_TX: case DISABLE_TX:
bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); bnx2x_sfp_set_transmitter(params, phy, 0);
break; break;
case ENABLE_TX: case ENABLE_TX:
if (!(phy->flags & FLAGS_SFP_NOT_APPROVED)) if (!(phy->flags & FLAGS_SFP_NOT_APPROVED))
bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); bnx2x_sfp_set_transmitter(params, phy, 1);
break; break;
default: default:
DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n", DP(NETIF_MSG_LINK, "Function 0x%x not supported by 8727\n",
...@@ -4979,6 +5023,38 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy, ...@@ -4979,6 +5023,38 @@ static void bnx2x_8727_specific_func(struct bnx2x_phy *phy,
} }
} }
static void bnx2x_set_sfp_module_fault_led(struct link_params *params,
u8 gpio_mode)
{
struct bnx2x *bp = params->bp;
u32 fault_led_gpio = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region,
dev_info.port_hw_config[params->port].sfp_ctrl)) &
PORT_HW_CFG_FAULT_MODULE_LED_MASK;
switch (fault_led_gpio) {
case PORT_HW_CFG_FAULT_MODULE_LED_DISABLED:
return;
case PORT_HW_CFG_FAULT_MODULE_LED_GPIO0:
case PORT_HW_CFG_FAULT_MODULE_LED_GPIO1:
case PORT_HW_CFG_FAULT_MODULE_LED_GPIO2:
case PORT_HW_CFG_FAULT_MODULE_LED_GPIO3:
{
u8 gpio_port = bnx2x_get_gpio_port(params);
u16 gpio_pin = fault_led_gpio -
PORT_HW_CFG_FAULT_MODULE_LED_GPIO0;
DP(NETIF_MSG_LINK, "Set fault module-detected led "
"pin %x port %x mode %x\n",
gpio_pin, gpio_port, gpio_mode);
bnx2x_set_gpio(bp, gpio_pin, gpio_mode, gpio_port);
}
break;
default:
DP(NETIF_MSG_LINK, "Error: Invalid fault led mode 0x%x\n",
fault_led_gpio);
}
}
static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
struct link_params *params) struct link_params *params)
{ {
...@@ -5001,9 +5077,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, ...@@ -5001,9 +5077,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
DP(NETIF_MSG_LINK, "Module verification failed!!\n"); DP(NETIF_MSG_LINK, "Module verification failed!!\n");
rc = -EINVAL; rc = -EINVAL;
/* Turn on fault module-detected led */ /* Turn on fault module-detected led */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, bnx2x_set_sfp_module_fault_led(params,
MISC_REGISTERS_GPIO_HIGH, MISC_REGISTERS_GPIO_HIGH);
params->port);
if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) && if ((phy->type == PORT_HW_CFG_XGXS_EXT_PHY_TYPE_BCM8727) &&
((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) { PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_POWER_DOWN)) {
...@@ -5014,10 +5090,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, ...@@ -5014,10 +5090,7 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
} }
} else { } else {
/* Turn off fault module-detected led */ /* Turn off fault module-detected led */
DP(NETIF_MSG_LINK, "Turn off fault module-detected led\n"); bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_LOW);
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0,
MISC_REGISTERS_GPIO_LOW,
params->port);
} }
/* power up the SFP module */ /* power up the SFP module */
...@@ -5039,9 +5112,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy, ...@@ -5039,9 +5112,9 @@ static u8 bnx2x_sfp_module_detection(struct bnx2x_phy *phy,
if (rc == 0 || if (rc == 0 ||
(val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) != (val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) !=
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
bnx2x_sfp_set_transmitter(bp, phy, params->port, 1); bnx2x_sfp_set_transmitter(params, phy, 1);
else else
bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); bnx2x_sfp_set_transmitter(params, phy, 0);
return rc; return rc;
} }
...@@ -5054,9 +5127,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) ...@@ -5054,9 +5127,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
u8 port = params->port; u8 port = params->port;
/* Set valid module led off */ /* Set valid module led off */
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_0, bnx2x_set_sfp_module_fault_led(params, MISC_REGISTERS_GPIO_HIGH);
MISC_REGISTERS_GPIO_HIGH,
params->port);
/* Get current gpio val reflecting module plugged in / out*/ /* Get current gpio val reflecting module plugged in / out*/
gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port); gpio_val = bnx2x_get_gpio(bp, MISC_REGISTERS_GPIO_3, port);
...@@ -5087,7 +5158,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params) ...@@ -5087,7 +5158,7 @@ void bnx2x_handle_module_detect_int(struct link_params *params)
*/ */
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); bnx2x_sfp_set_transmitter(params, phy, 0);
} }
} }
...@@ -5146,7 +5217,8 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, ...@@ -5146,7 +5217,8 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
struct link_vars *vars) struct link_vars *vars)
{ {
u16 cnt, val; u32 tx_en_mode;
u16 cnt, val, tmp1;
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2, bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port); MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
...@@ -5220,6 +5292,26 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy, ...@@ -5220,6 +5292,26 @@ static u8 bnx2x_8706_config_init(struct bnx2x_phy *phy,
0x0004); 0x0004);
} }
bnx2x_save_bcm_spirom_ver(bp, phy, params->port); bnx2x_save_bcm_spirom_ver(bp, phy, params->port);
/*
* If TX Laser is controlled by GPIO_0, do not let PHY go into low
* power mode, if TX Laser is disabled
*/
tx_en_mode = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region,
dev_info.port_hw_config[params->port].sfp_ctrl))
& PORT_HW_CFG_TX_LASER_MASK;
if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, &tmp1);
tmp1 |= 0x1;
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_DIGITAL_CTRL, tmp1);
}
return 0; return 0;
} }
...@@ -5308,12 +5400,6 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy, ...@@ -5308,12 +5400,6 @@ static u8 bnx2x_8726_config_init(struct bnx2x_phy *phy,
u32 val; u32 val;
u32 swap_val, swap_override, aeu_gpio_mask, offset; u32 swap_val, swap_override, aeu_gpio_mask, offset;
DP(NETIF_MSG_LINK, "Initializing BCM8726\n"); DP(NETIF_MSG_LINK, "Initializing BCM8726\n");
/* Restore normal power mode*/
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_2,
MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
bnx2x_set_gpio(bp, MISC_REGISTERS_GPIO_1,
MISC_REGISTERS_GPIO_OUTPUT_HIGH, params->port);
bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_CTRL, 1<<15);
bnx2x_wait_reset_complete(bp, phy, params); bnx2x_wait_reset_complete(bp, phy, params);
...@@ -5500,7 +5586,8 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, ...@@ -5500,7 +5586,8 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
struct link_params *params, struct link_params *params,
struct link_vars *vars) struct link_vars *vars)
{ {
u16 tmp1, val, mod_abs; u32 tx_en_mode;
u16 tmp1, val, mod_abs, tmp2;
u16 rx_alarm_ctrl_val; u16 rx_alarm_ctrl_val;
u16 lasi_ctrl_val; u16 lasi_ctrl_val;
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
...@@ -5637,6 +5724,26 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy, ...@@ -5637,6 +5724,26 @@ static u8 bnx2x_8727_config_init(struct bnx2x_phy *phy,
phy->tx_preemphasis[1]); phy->tx_preemphasis[1]);
} }
/*
* If TX Laser is controlled by GPIO_0, do not let PHY go into low
* power mode, if TX Laser is disabled
*/
tx_en_mode = REG_RD(bp, params->shmem_base +
offsetof(struct shmem_region,
dev_info.port_hw_config[params->port].sfp_ctrl))
& PORT_HW_CFG_TX_LASER_MASK;
if (tx_en_mode == PORT_HW_CFG_TX_LASER_GPIO0) {
DP(NETIF_MSG_LINK, "Enabling TXONOFF_PWRDN_DIS\n");
bnx2x_cl45_read(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, &tmp2);
tmp2 |= 0x1000;
tmp2 &= 0xFFEF;
bnx2x_cl45_write(bp, phy,
MDIO_PMA_DEVAD, MDIO_PMA_REG_8727_OPT_CFG_REG, tmp2);
}
return 0; return 0;
} }
...@@ -5713,7 +5820,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy, ...@@ -5713,7 +5820,7 @@ static void bnx2x_8727_handle_mod_abs(struct bnx2x_phy *phy,
if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) == if ((val & PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_MASK) ==
PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER) PORT_FEAT_CFG_OPT_MDL_ENFRCMNT_DISABLE_TX_LASER)
bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); bnx2x_sfp_set_transmitter(params, phy, 0);
if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0) if (bnx2x_wait_for_sfp_module_initialized(phy, params) == 0)
bnx2x_sfp_module_detection(phy, params); bnx2x_sfp_module_detection(phy, params);
...@@ -5873,7 +5980,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy, ...@@ -5873,7 +5980,7 @@ static void bnx2x_8727_link_reset(struct bnx2x_phy *phy,
{ {
struct bnx2x *bp = params->bp; struct bnx2x *bp = params->bp;
/* Disable Transmitter */ /* Disable Transmitter */
bnx2x_sfp_set_transmitter(bp, phy, params->port, 0); bnx2x_sfp_set_transmitter(params, phy, 0);
/* Clear LASI */ /* Clear LASI */
bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0); bnx2x_cl45_write(bp, phy, MDIO_PMA_DEVAD, MDIO_PMA_REG_LASI_CTRL, 0);
...@@ -7889,12 +7996,57 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp, ...@@ -7889,12 +7996,57 @@ static u8 bnx2x_8726_common_init_phy(struct bnx2x *bp,
return 0; return 0;
} }
static void bnx2x_get_ext_phy_reset_gpio(struct bnx2x *bp, u32 shmem_base,
u8 *io_gpio, u8 *io_port)
{
u32 phy_gpio_reset = REG_RD(bp, shmem_base +
offsetof(struct shmem_region,
dev_info.port_hw_config[PORT_0].default_cfg));
switch (phy_gpio_reset) {
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P0:
*io_gpio = 0;
*io_port = 0;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P0:
*io_gpio = 1;
*io_port = 0;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P0:
*io_gpio = 2;
*io_port = 0;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P0:
*io_gpio = 3;
*io_port = 0;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO0_P1:
*io_gpio = 0;
*io_port = 1;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO1_P1:
*io_gpio = 1;
*io_port = 1;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO2_P1:
*io_gpio = 2;
*io_port = 1;
break;
case PORT_HW_CFG_EXT_PHY_GPIO_RST_GPIO3_P1:
*io_gpio = 3;
*io_port = 1;
break;
default:
/* Don't override the io_gpio and io_port */
break;
}
}
static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
u32 shmem_base_path[], u32 shmem_base_path[],
u32 shmem2_base_path[], u8 phy_index, u32 shmem2_base_path[], u8 phy_index,
u32 chip_id) u32 chip_id)
{ {
s8 port; s8 port, reset_gpio;
u32 swap_val, swap_override; u32 swap_val, swap_override;
struct bnx2x_phy phy[PORT_MAX]; struct bnx2x_phy phy[PORT_MAX];
struct bnx2x_phy *phy_blk[PORT_MAX]; struct bnx2x_phy *phy_blk[PORT_MAX];
...@@ -7902,13 +8054,26 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp, ...@@ -7902,13 +8054,26 @@ static u8 bnx2x_8727_common_init_phy(struct bnx2x *bp,
swap_val = REG_RD(bp, NIG_REG_PORT_SWAP); swap_val = REG_RD(bp, NIG_REG_PORT_SWAP);
swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE); swap_override = REG_RD(bp, NIG_REG_STRAP_OVERRIDE);
reset_gpio = MISC_REGISTERS_GPIO_1;
port = 1; port = 1;
bnx2x_ext_phy_hw_reset(bp, port ^ (swap_val && swap_override)); /*
* Retrieve the reset gpio/port which control the reset.
* Default is GPIO1, PORT1
*/
bnx2x_get_ext_phy_reset_gpio(bp, shmem_base_path[0],
(u8 *)&reset_gpio, (u8 *)&port);
/* Calculate the port based on port swap */ /* Calculate the port based on port swap */
port ^= (swap_val && swap_override); port ^= (swap_val && swap_override);
/* Initiate PHY reset*/
bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_LOW,
port);
msleep(1);
bnx2x_set_gpio(bp, reset_gpio, MISC_REGISTERS_GPIO_OUTPUT_HIGH,
port);
msleep(5); msleep(5);
/* PART1 - Reset both phys */ /* PART1 - Reset both phys */
......
...@@ -6083,6 +6083,7 @@ Theotherbitsarereservedandshouldbezero*/ ...@@ -6083,6 +6083,7 @@ Theotherbitsarereservedandshouldbezero*/
#define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808 #define MDIO_PMA_REG_8727_PCS_OPT_CTRL 0xc808
#define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e #define MDIO_PMA_REG_8727_GPIO_CTRL 0xc80e
#define MDIO_PMA_REG_8727_PCS_GP 0xc842 #define MDIO_PMA_REG_8727_PCS_GP 0xc842
#define MDIO_PMA_REG_8727_OPT_CFG_REG 0xc8e4
#define MDIO_AN_REG_8727_MISC_CTRL 0x8309 #define MDIO_AN_REG_8727_MISC_CTRL 0x8309
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册