qed: Add support for Energy efficient ethernet.
The patch adds required driver support for reading/configuring the Energy Efficient Ethernet (EEE) parameters. Signed-off-by: Sudarsana Reddy Kalluru <sudarsana.kalluru@cavium.com> Signed-off-by: Yuval Mintz <yuval.mintz@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
3f2a2b8b7a
Коммит
645874e580
|
@ -1684,6 +1684,8 @@ int qed_hw_init(struct qed_dev *cdev, struct qed_hw_init_params *p_params)
|
||||||
"Load request was sent. Load code: 0x%x\n",
|
"Load request was sent. Load code: 0x%x\n",
|
||||||
load_code);
|
load_code);
|
||||||
|
|
||||||
|
qed_mcp_set_capabilities(p_hwfn, p_hwfn->p_main_ptt);
|
||||||
|
|
||||||
qed_reset_mb_shadow(p_hwfn, p_hwfn->p_main_ptt);
|
qed_reset_mb_shadow(p_hwfn, p_hwfn->p_main_ptt);
|
||||||
|
|
||||||
p_hwfn->first_on_engine = (load_code ==
|
p_hwfn->first_on_engine = (load_code ==
|
||||||
|
@ -2472,6 +2474,7 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
{
|
{
|
||||||
u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities;
|
u32 port_cfg_addr, link_temp, nvm_cfg_addr, device_capabilities;
|
||||||
u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg;
|
u32 nvm_cfg1_offset, mf_mode, addr, generic_cont0, core_cfg;
|
||||||
|
struct qed_mcp_link_capabilities *p_caps;
|
||||||
struct qed_mcp_link_params *link;
|
struct qed_mcp_link_params *link;
|
||||||
|
|
||||||
/* Read global nvm_cfg address */
|
/* Read global nvm_cfg address */
|
||||||
|
@ -2534,6 +2537,7 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
|
|
||||||
/* Read default link configuration */
|
/* Read default link configuration */
|
||||||
link = &p_hwfn->mcp_info->link_input;
|
link = &p_hwfn->mcp_info->link_input;
|
||||||
|
p_caps = &p_hwfn->mcp_info->link_capabilities;
|
||||||
port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
|
port_cfg_addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
|
||||||
offsetof(struct nvm_cfg1, port[MFW_PORT(p_hwfn)]);
|
offsetof(struct nvm_cfg1, port[MFW_PORT(p_hwfn)]);
|
||||||
link_temp = qed_rd(p_hwfn, p_ptt,
|
link_temp = qed_rd(p_hwfn, p_ptt,
|
||||||
|
@ -2588,10 +2592,45 @@ static int qed_hw_get_nvm_info(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX);
|
NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX);
|
||||||
link->loopback_mode = 0;
|
link->loopback_mode = 0;
|
||||||
|
|
||||||
DP_VERBOSE(p_hwfn, NETIF_MSG_LINK,
|
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE) {
|
||||||
"Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x\n",
|
link_temp = qed_rd(p_hwfn, p_ptt, port_cfg_addr +
|
||||||
link->speed.forced_speed, link->speed.advertised_speeds,
|
offsetof(struct nvm_cfg1_port, ext_phy));
|
||||||
link->speed.autoneg, link->pause.autoneg);
|
link_temp &= NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK;
|
||||||
|
link_temp >>= NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_OFFSET;
|
||||||
|
p_caps->default_eee = QED_MCP_EEE_ENABLED;
|
||||||
|
link->eee.enable = true;
|
||||||
|
switch (link_temp) {
|
||||||
|
case NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_DISABLED:
|
||||||
|
p_caps->default_eee = QED_MCP_EEE_DISABLED;
|
||||||
|
link->eee.enable = false;
|
||||||
|
break;
|
||||||
|
case NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_BALANCED:
|
||||||
|
p_caps->eee_lpi_timer = EEE_TX_TIMER_USEC_BALANCED_TIME;
|
||||||
|
break;
|
||||||
|
case NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_AGGRESSIVE:
|
||||||
|
p_caps->eee_lpi_timer =
|
||||||
|
EEE_TX_TIMER_USEC_AGGRESSIVE_TIME;
|
||||||
|
break;
|
||||||
|
case NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_LOW_LATENCY:
|
||||||
|
p_caps->eee_lpi_timer = EEE_TX_TIMER_USEC_LATENCY_TIME;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
link->eee.tx_lpi_timer = p_caps->eee_lpi_timer;
|
||||||
|
link->eee.tx_lpi_enable = link->eee.enable;
|
||||||
|
link->eee.adv_caps = QED_EEE_1G_ADV | QED_EEE_10G_ADV;
|
||||||
|
} else {
|
||||||
|
p_caps->default_eee = QED_MCP_EEE_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
DP_VERBOSE(p_hwfn,
|
||||||
|
NETIF_MSG_LINK,
|
||||||
|
"Read default link: Speed 0x%08x, Adv. Speed 0x%08x, AN: 0x%02x, PAUSE AN: 0x%02x EEE: %02x [%08x usec]\n",
|
||||||
|
link->speed.forced_speed,
|
||||||
|
link->speed.advertised_speeds,
|
||||||
|
link->speed.autoneg,
|
||||||
|
link->pause.autoneg,
|
||||||
|
p_caps->default_eee, p_caps->eee_lpi_timer);
|
||||||
|
|
||||||
/* Read Multi-function information from shmem */
|
/* Read Multi-function information from shmem */
|
||||||
addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
|
addr = MCP_REG_SCRATCH + nvm_cfg1_offset +
|
||||||
|
@ -2751,6 +2790,27 @@ static void qed_hw_info_port_num(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
qed_hw_info_port_num_ah(p_hwfn, p_ptt);
|
qed_hw_info_port_num_ah(p_hwfn, p_ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qed_get_eee_caps(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
|
{
|
||||||
|
struct qed_mcp_link_capabilities *p_caps;
|
||||||
|
u32 eee_status;
|
||||||
|
|
||||||
|
p_caps = &p_hwfn->mcp_info->link_capabilities;
|
||||||
|
if (p_caps->default_eee == QED_MCP_EEE_UNSUPPORTED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p_caps->eee_speed_caps = 0;
|
||||||
|
eee_status = qed_rd(p_hwfn, p_ptt, p_hwfn->mcp_info->port_addr +
|
||||||
|
offsetof(struct public_port, eee_status));
|
||||||
|
eee_status = (eee_status & EEE_SUPPORTED_SPEED_MASK) >>
|
||||||
|
EEE_SUPPORTED_SPEED_OFFSET;
|
||||||
|
|
||||||
|
if (eee_status & EEE_1G_SUPPORTED)
|
||||||
|
p_caps->eee_speed_caps |= QED_EEE_1G_ADV;
|
||||||
|
if (eee_status & EEE_10G_ADV)
|
||||||
|
p_caps->eee_speed_caps |= QED_EEE_10G_ADV;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qed_get_hw_info(struct qed_hwfn *p_hwfn,
|
qed_get_hw_info(struct qed_hwfn *p_hwfn,
|
||||||
struct qed_ptt *p_ptt,
|
struct qed_ptt *p_ptt,
|
||||||
|
@ -2767,6 +2827,8 @@ qed_get_hw_info(struct qed_hwfn *p_hwfn,
|
||||||
|
|
||||||
qed_hw_info_port_num(p_hwfn, p_ptt);
|
qed_hw_info_port_num(p_hwfn, p_ptt);
|
||||||
|
|
||||||
|
qed_mcp_get_capabilities(p_hwfn, p_ptt);
|
||||||
|
|
||||||
qed_hw_get_nvm_info(p_hwfn, p_ptt);
|
qed_hw_get_nvm_info(p_hwfn, p_ptt);
|
||||||
|
|
||||||
rc = qed_int_igu_read_cam(p_hwfn, p_ptt);
|
rc = qed_int_igu_read_cam(p_hwfn, p_ptt);
|
||||||
|
@ -2785,6 +2847,8 @@ qed_get_hw_info(struct qed_hwfn *p_hwfn,
|
||||||
p_hwfn->mcp_info->func_info.ovlan;
|
p_hwfn->mcp_info->func_info.ovlan;
|
||||||
|
|
||||||
qed_mcp_cmd_port_init(p_hwfn, p_ptt);
|
qed_mcp_cmd_port_init(p_hwfn, p_ptt);
|
||||||
|
|
||||||
|
qed_get_eee_caps(p_hwfn, p_ptt);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qed_mcp_is_init(p_hwfn)) {
|
if (qed_mcp_is_init(p_hwfn)) {
|
||||||
|
|
|
@ -10825,6 +10825,17 @@ struct eth_phy_cfg {
|
||||||
#define ETH_LOOPBACK_EXT (3)
|
#define ETH_LOOPBACK_EXT (3)
|
||||||
#define ETH_LOOPBACK_MAC (4)
|
#define ETH_LOOPBACK_MAC (4)
|
||||||
|
|
||||||
|
u32 eee_cfg;
|
||||||
|
#define EEE_CFG_EEE_ENABLED BIT(0)
|
||||||
|
#define EEE_CFG_TX_LPI BIT(1)
|
||||||
|
#define EEE_CFG_ADV_SPEED_1G BIT(2)
|
||||||
|
#define EEE_CFG_ADV_SPEED_10G BIT(3)
|
||||||
|
#define EEE_TX_TIMER_USEC_MASK (0xfffffff0)
|
||||||
|
#define EEE_TX_TIMER_USEC_OFFSET 4
|
||||||
|
#define EEE_TX_TIMER_USEC_BALANCED_TIME (0xa00)
|
||||||
|
#define EEE_TX_TIMER_USEC_AGGRESSIVE_TIME (0x100)
|
||||||
|
#define EEE_TX_TIMER_USEC_LATENCY_TIME (0x6000)
|
||||||
|
|
||||||
u32 feature_config_flags;
|
u32 feature_config_flags;
|
||||||
#define ETH_EEE_MODE_ADV_LPI (1 << 0)
|
#define ETH_EEE_MODE_ADV_LPI (1 << 0)
|
||||||
};
|
};
|
||||||
|
@ -11242,6 +11253,25 @@ struct public_port {
|
||||||
u32 wol_pkt_len;
|
u32 wol_pkt_len;
|
||||||
u32 wol_pkt_details;
|
u32 wol_pkt_details;
|
||||||
struct dcb_dscp_map dcb_dscp_map;
|
struct dcb_dscp_map dcb_dscp_map;
|
||||||
|
|
||||||
|
u32 eee_status;
|
||||||
|
#define EEE_ACTIVE_BIT BIT(0)
|
||||||
|
#define EEE_LD_ADV_STATUS_MASK 0x000000f0
|
||||||
|
#define EEE_LD_ADV_STATUS_OFFSET 4
|
||||||
|
#define EEE_1G_ADV BIT(1)
|
||||||
|
#define EEE_10G_ADV BIT(2)
|
||||||
|
#define EEE_LP_ADV_STATUS_MASK 0x00000f00
|
||||||
|
#define EEE_LP_ADV_STATUS_OFFSET 8
|
||||||
|
#define EEE_SUPPORTED_SPEED_MASK 0x0000f000
|
||||||
|
#define EEE_SUPPORTED_SPEED_OFFSET 12
|
||||||
|
#define EEE_1G_SUPPORTED BIT(1)
|
||||||
|
#define EEE_10G_SUPPORTED BIT(2)
|
||||||
|
|
||||||
|
u32 eee_remote;
|
||||||
|
#define EEE_REMOTE_TW_TX_MASK 0x0000ffff
|
||||||
|
#define EEE_REMOTE_TW_TX_OFFSET 0
|
||||||
|
#define EEE_REMOTE_TW_RX_MASK 0xffff0000
|
||||||
|
#define EEE_REMOTE_TW_RX_OFFSET 16
|
||||||
};
|
};
|
||||||
|
|
||||||
struct public_func {
|
struct public_func {
|
||||||
|
@ -11570,6 +11600,9 @@ struct public_drv_mb {
|
||||||
#define DRV_MSG_CODE_GET_PF_RDMA_PROTOCOL 0x002b0000
|
#define DRV_MSG_CODE_GET_PF_RDMA_PROTOCOL 0x002b0000
|
||||||
#define DRV_MSG_CODE_OS_WOL 0x002e0000
|
#define DRV_MSG_CODE_OS_WOL 0x002e0000
|
||||||
|
|
||||||
|
#define DRV_MSG_CODE_FEATURE_SUPPORT 0x00300000
|
||||||
|
#define DRV_MSG_CODE_GET_MFW_FEATURE_SUPPORT 0x00310000
|
||||||
|
|
||||||
#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
|
#define DRV_MSG_SEQ_NUMBER_MASK 0x0000ffff
|
||||||
|
|
||||||
u32 drv_mb_param;
|
u32 drv_mb_param;
|
||||||
|
@ -11653,6 +11686,10 @@ struct public_drv_mb {
|
||||||
#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
|
#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_SHIFT 8
|
||||||
#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000FF00
|
#define DRV_MB_PARAM_BIST_TEST_IMAGE_INDEX_MASK 0x0000FF00
|
||||||
|
|
||||||
|
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_MASK 0x0000FFFF
|
||||||
|
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_OFFSET 0
|
||||||
|
#define DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE 0x00000002
|
||||||
|
|
||||||
u32 fw_mb_header;
|
u32 fw_mb_header;
|
||||||
#define FW_MSG_CODE_MASK 0xffff0000
|
#define FW_MSG_CODE_MASK 0xffff0000
|
||||||
#define FW_MSG_CODE_UNSUPPORTED 0x00000000
|
#define FW_MSG_CODE_UNSUPPORTED 0x00000000
|
||||||
|
@ -11696,6 +11733,9 @@ struct public_drv_mb {
|
||||||
#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2
|
#define FW_MB_PARAM_GET_PF_RDMA_IWARP 0x2
|
||||||
#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3
|
#define FW_MB_PARAM_GET_PF_RDMA_BOTH 0x3
|
||||||
|
|
||||||
|
/* get MFW feature support response */
|
||||||
|
#define FW_MB_PARAM_FEATURE_SUPPORT_EEE 0x00000002
|
||||||
|
|
||||||
#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)
|
#define FW_MB_PARAM_LOAD_DONE_DID_EFUSE_ERROR (1 << 0)
|
||||||
|
|
||||||
u32 drv_pulse_mb;
|
u32 drv_pulse_mb;
|
||||||
|
@ -11891,7 +11931,16 @@ struct nvm_cfg1_port {
|
||||||
#define NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX 0x4
|
#define NVM_CFG1_PORT_DRV_FLOW_CONTROL_TX 0x4
|
||||||
u32 phy_cfg;
|
u32 phy_cfg;
|
||||||
u32 mgmt_traffic;
|
u32 mgmt_traffic;
|
||||||
|
|
||||||
u32 ext_phy;
|
u32 ext_phy;
|
||||||
|
/* EEE power saving mode */
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_MASK 0x00FF0000
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_OFFSET 16
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_DISABLED 0x0
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_BALANCED 0x1
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_AGGRESSIVE 0x2
|
||||||
|
#define NVM_CFG1_PORT_EEE_POWER_SAVING_MODE_LOW_LATENCY 0x3
|
||||||
|
|
||||||
u32 mba_cfg1;
|
u32 mba_cfg1;
|
||||||
u32 mba_cfg2;
|
u32 mba_cfg2;
|
||||||
u32 vf_cfg;
|
u32 vf_cfg;
|
||||||
|
|
|
@ -1297,6 +1297,10 @@ static int qed_set_link(struct qed_dev *cdev, struct qed_link_params *params)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (params->override_flags & QED_LINK_OVERRIDE_EEE_CONFIG)
|
||||||
|
memcpy(&link_params->eee, ¶ms->eee,
|
||||||
|
sizeof(link_params->eee));
|
||||||
|
|
||||||
rc = qed_mcp_set_link(hwfn, ptt, params->link_up);
|
rc = qed_mcp_set_link(hwfn, ptt, params->link_up);
|
||||||
|
|
||||||
qed_ptt_release(hwfn, ptt);
|
qed_ptt_release(hwfn, ptt);
|
||||||
|
@ -1483,6 +1487,21 @@ static void qed_fill_link(struct qed_hwfn *hwfn,
|
||||||
if (link.partner_adv_pause == QED_LINK_PARTNER_ASYMMETRIC_PAUSE ||
|
if (link.partner_adv_pause == QED_LINK_PARTNER_ASYMMETRIC_PAUSE ||
|
||||||
link.partner_adv_pause == QED_LINK_PARTNER_BOTH_PAUSE)
|
link.partner_adv_pause == QED_LINK_PARTNER_BOTH_PAUSE)
|
||||||
if_link->lp_caps |= QED_LM_Asym_Pause_BIT;
|
if_link->lp_caps |= QED_LM_Asym_Pause_BIT;
|
||||||
|
|
||||||
|
if (link_caps.default_eee == QED_MCP_EEE_UNSUPPORTED) {
|
||||||
|
if_link->eee_supported = false;
|
||||||
|
} else {
|
||||||
|
if_link->eee_supported = true;
|
||||||
|
if_link->eee_active = link.eee_active;
|
||||||
|
if_link->sup_caps = link_caps.eee_speed_caps;
|
||||||
|
/* MFW clears adv_caps on eee disable; use configured value */
|
||||||
|
if_link->eee.adv_caps = link.eee_adv_caps ? link.eee_adv_caps :
|
||||||
|
params.eee.adv_caps;
|
||||||
|
if_link->eee.lp_adv_caps = link.eee_lp_adv_caps;
|
||||||
|
if_link->eee.enable = params.eee.enable;
|
||||||
|
if_link->eee.tx_lpi_enable = params.eee.tx_lpi_enable;
|
||||||
|
if_link->eee.tx_lpi_timer = params.eee.tx_lpi_timer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void qed_get_current_link(struct qed_dev *cdev,
|
static void qed_get_current_link(struct qed_dev *cdev,
|
||||||
|
|
|
@ -1097,6 +1097,31 @@ static void qed_mcp_handle_transceiver_change(struct qed_hwfn *p_hwfn,
|
||||||
DP_NOTICE(p_hwfn, "Transceiver is unplugged.\n");
|
DP_NOTICE(p_hwfn, "Transceiver is unplugged.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void qed_mcp_read_eee_config(struct qed_hwfn *p_hwfn,
|
||||||
|
struct qed_ptt *p_ptt,
|
||||||
|
struct qed_mcp_link_state *p_link)
|
||||||
|
{
|
||||||
|
u32 eee_status, val;
|
||||||
|
|
||||||
|
p_link->eee_adv_caps = 0;
|
||||||
|
p_link->eee_lp_adv_caps = 0;
|
||||||
|
eee_status = qed_rd(p_hwfn,
|
||||||
|
p_ptt,
|
||||||
|
p_hwfn->mcp_info->port_addr +
|
||||||
|
offsetof(struct public_port, eee_status));
|
||||||
|
p_link->eee_active = !!(eee_status & EEE_ACTIVE_BIT);
|
||||||
|
val = (eee_status & EEE_LD_ADV_STATUS_MASK) >> EEE_LD_ADV_STATUS_OFFSET;
|
||||||
|
if (val & EEE_1G_ADV)
|
||||||
|
p_link->eee_adv_caps |= QED_EEE_1G_ADV;
|
||||||
|
if (val & EEE_10G_ADV)
|
||||||
|
p_link->eee_adv_caps |= QED_EEE_10G_ADV;
|
||||||
|
val = (eee_status & EEE_LP_ADV_STATUS_MASK) >> EEE_LP_ADV_STATUS_OFFSET;
|
||||||
|
if (val & EEE_1G_ADV)
|
||||||
|
p_link->eee_lp_adv_caps |= QED_EEE_1G_ADV;
|
||||||
|
if (val & EEE_10G_ADV)
|
||||||
|
p_link->eee_lp_adv_caps |= QED_EEE_10G_ADV;
|
||||||
|
}
|
||||||
|
|
||||||
static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
|
static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
|
||||||
struct qed_ptt *p_ptt, bool b_reset)
|
struct qed_ptt *p_ptt, bool b_reset)
|
||||||
{
|
{
|
||||||
|
@ -1228,6 +1253,9 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn,
|
||||||
|
|
||||||
p_link->sfp_tx_fault = !!(status & LINK_STATUS_SFP_TX_FAULT);
|
p_link->sfp_tx_fault = !!(status & LINK_STATUS_SFP_TX_FAULT);
|
||||||
|
|
||||||
|
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE)
|
||||||
|
qed_mcp_read_eee_config(p_hwfn, p_ptt, p_link);
|
||||||
|
|
||||||
qed_link_update(p_hwfn);
|
qed_link_update(p_hwfn);
|
||||||
out:
|
out:
|
||||||
spin_unlock_bh(&p_hwfn->mcp_info->link_lock);
|
spin_unlock_bh(&p_hwfn->mcp_info->link_lock);
|
||||||
|
@ -1251,6 +1279,19 @@ int qed_mcp_set_link(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, bool b_up)
|
||||||
phy_cfg.pause |= (params->pause.forced_tx) ? ETH_PAUSE_TX : 0;
|
phy_cfg.pause |= (params->pause.forced_tx) ? ETH_PAUSE_TX : 0;
|
||||||
phy_cfg.adv_speed = params->speed.advertised_speeds;
|
phy_cfg.adv_speed = params->speed.advertised_speeds;
|
||||||
phy_cfg.loopback_mode = params->loopback_mode;
|
phy_cfg.loopback_mode = params->loopback_mode;
|
||||||
|
if (p_hwfn->mcp_info->capabilities & FW_MB_PARAM_FEATURE_SUPPORT_EEE) {
|
||||||
|
if (params->eee.enable)
|
||||||
|
phy_cfg.eee_cfg |= EEE_CFG_EEE_ENABLED;
|
||||||
|
if (params->eee.tx_lpi_enable)
|
||||||
|
phy_cfg.eee_cfg |= EEE_CFG_TX_LPI;
|
||||||
|
if (params->eee.adv_caps & QED_EEE_1G_ADV)
|
||||||
|
phy_cfg.eee_cfg |= EEE_CFG_ADV_SPEED_1G;
|
||||||
|
if (params->eee.adv_caps & QED_EEE_10G_ADV)
|
||||||
|
phy_cfg.eee_cfg |= EEE_CFG_ADV_SPEED_10G;
|
||||||
|
phy_cfg.eee_cfg |= (params->eee.tx_lpi_timer <<
|
||||||
|
EEE_TX_TIMER_USEC_OFFSET) &
|
||||||
|
EEE_TX_TIMER_USEC_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
p_hwfn->b_drv_link_init = b_up;
|
p_hwfn->b_drv_link_init = b_up;
|
||||||
|
|
||||||
|
@ -2822,3 +2863,28 @@ void qed_mcp_resc_lock_default_init(struct qed_resc_lock_params *p_lock,
|
||||||
p_unlock->resource = resource;
|
p_unlock->resource = resource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qed_mcp_get_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
|
{
|
||||||
|
u32 mcp_resp;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
rc = qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_GET_MFW_FEATURE_SUPPORT,
|
||||||
|
0, &mcp_resp, &p_hwfn->mcp_info->capabilities);
|
||||||
|
if (!rc)
|
||||||
|
DP_VERBOSE(p_hwfn, (QED_MSG_SP | NETIF_MSG_PROBE),
|
||||||
|
"MFW supported features: %08x\n",
|
||||||
|
p_hwfn->mcp_info->capabilities);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt)
|
||||||
|
{
|
||||||
|
u32 mcp_resp, mcp_param, features;
|
||||||
|
|
||||||
|
features = DRV_MB_PARAM_FEATURE_SUPPORT_PORT_EEE;
|
||||||
|
|
||||||
|
return qed_mcp_cmd(p_hwfn, p_ptt, DRV_MSG_CODE_FEATURE_SUPPORT,
|
||||||
|
features, &mcp_resp, &mcp_param);
|
||||||
|
}
|
||||||
|
|
|
@ -53,15 +53,25 @@ struct qed_mcp_link_pause_params {
|
||||||
bool forced_tx;
|
bool forced_tx;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum qed_mcp_eee_mode {
|
||||||
|
QED_MCP_EEE_DISABLED,
|
||||||
|
QED_MCP_EEE_ENABLED,
|
||||||
|
QED_MCP_EEE_UNSUPPORTED
|
||||||
|
};
|
||||||
|
|
||||||
struct qed_mcp_link_params {
|
struct qed_mcp_link_params {
|
||||||
struct qed_mcp_link_speed_params speed;
|
struct qed_mcp_link_speed_params speed;
|
||||||
struct qed_mcp_link_pause_params pause;
|
struct qed_mcp_link_pause_params pause;
|
||||||
u32 loopback_mode;
|
u32 loopback_mode;
|
||||||
|
struct qed_link_eee_params eee;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_mcp_link_capabilities {
|
struct qed_mcp_link_capabilities {
|
||||||
u32 speed_capabilities;
|
u32 speed_capabilities;
|
||||||
bool default_speed_autoneg;
|
bool default_speed_autoneg;
|
||||||
|
enum qed_mcp_eee_mode default_eee;
|
||||||
|
u32 eee_lpi_timer;
|
||||||
|
u8 eee_speed_caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_mcp_link_state {
|
struct qed_mcp_link_state {
|
||||||
|
@ -102,6 +112,9 @@ struct qed_mcp_link_state {
|
||||||
u8 partner_adv_pause;
|
u8 partner_adv_pause;
|
||||||
|
|
||||||
bool sfp_tx_fault;
|
bool sfp_tx_fault;
|
||||||
|
bool eee_active;
|
||||||
|
u8 eee_adv_caps;
|
||||||
|
u8 eee_lp_adv_caps;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_mcp_function_info {
|
struct qed_mcp_function_info {
|
||||||
|
@ -546,6 +559,9 @@ struct qed_mcp_info {
|
||||||
u8 *mfw_mb_shadow;
|
u8 *mfw_mb_shadow;
|
||||||
u16 mfw_mb_length;
|
u16 mfw_mb_length;
|
||||||
u32 mcp_hist;
|
u32 mcp_hist;
|
||||||
|
|
||||||
|
/* Capabilties negotiated with the MFW */
|
||||||
|
u32 capabilities;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_mcp_mb_params {
|
struct qed_mcp_mb_params {
|
||||||
|
@ -925,5 +941,20 @@ void qed_mcp_resc_lock_default_init(struct qed_resc_lock_params *p_lock,
|
||||||
struct qed_resc_unlock_params *p_unlock,
|
struct qed_resc_unlock_params *p_unlock,
|
||||||
enum qed_resc_lock
|
enum qed_resc_lock
|
||||||
resource, bool b_is_permanent);
|
resource, bool b_is_permanent);
|
||||||
|
/**
|
||||||
|
* @brief Learn of supported MFW features; To be done during early init
|
||||||
|
*
|
||||||
|
* @param p_hwfn
|
||||||
|
* @param p_ptt
|
||||||
|
*/
|
||||||
|
int qed_mcp_get_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Inform MFW of set of features supported by driver. Should be done
|
||||||
|
* inside the content of the LOAD_REQ.
|
||||||
|
*
|
||||||
|
* @param p_hwfn
|
||||||
|
* @param p_ptt
|
||||||
|
*/
|
||||||
|
int qed_mcp_set_capabilities(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -161,6 +161,18 @@ enum qed_nvm_images {
|
||||||
QED_NVM_IMAGE_FCOE_CFG,
|
QED_NVM_IMAGE_FCOE_CFG,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct qed_link_eee_params {
|
||||||
|
u32 tx_lpi_timer;
|
||||||
|
#define QED_EEE_1G_ADV BIT(0)
|
||||||
|
#define QED_EEE_10G_ADV BIT(1)
|
||||||
|
|
||||||
|
/* Capabilities are represented using QED_EEE_*_ADV values */
|
||||||
|
u8 adv_caps;
|
||||||
|
u8 lp_adv_caps;
|
||||||
|
bool enable;
|
||||||
|
bool tx_lpi_enable;
|
||||||
|
};
|
||||||
|
|
||||||
enum qed_led_mode {
|
enum qed_led_mode {
|
||||||
QED_LED_MODE_OFF,
|
QED_LED_MODE_OFF,
|
||||||
QED_LED_MODE_ON,
|
QED_LED_MODE_ON,
|
||||||
|
@ -408,6 +420,7 @@ struct qed_link_params {
|
||||||
#define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED BIT(2)
|
#define QED_LINK_OVERRIDE_SPEED_FORCED_SPEED BIT(2)
|
||||||
#define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3)
|
#define QED_LINK_OVERRIDE_PAUSE_CONFIG BIT(3)
|
||||||
#define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4)
|
#define QED_LINK_OVERRIDE_LOOPBACK_MODE BIT(4)
|
||||||
|
#define QED_LINK_OVERRIDE_EEE_CONFIG BIT(5)
|
||||||
u32 override_flags;
|
u32 override_flags;
|
||||||
bool autoneg;
|
bool autoneg;
|
||||||
u32 adv_speeds;
|
u32 adv_speeds;
|
||||||
|
@ -422,6 +435,7 @@ struct qed_link_params {
|
||||||
#define QED_LINK_LOOPBACK_EXT BIT(3)
|
#define QED_LINK_LOOPBACK_EXT BIT(3)
|
||||||
#define QED_LINK_LOOPBACK_MAC BIT(4)
|
#define QED_LINK_LOOPBACK_MAC BIT(4)
|
||||||
u32 loopback_mode;
|
u32 loopback_mode;
|
||||||
|
struct qed_link_eee_params eee;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_link_output {
|
struct qed_link_output {
|
||||||
|
@ -437,6 +451,12 @@ struct qed_link_output {
|
||||||
u8 port; /* In PORT defs */
|
u8 port; /* In PORT defs */
|
||||||
bool autoneg;
|
bool autoneg;
|
||||||
u32 pause_config;
|
u32 pause_config;
|
||||||
|
|
||||||
|
/* EEE - capability & param */
|
||||||
|
bool eee_supported;
|
||||||
|
bool eee_active;
|
||||||
|
u8 sup_caps;
|
||||||
|
struct qed_link_eee_params eee;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qed_probe_params {
|
struct qed_probe_params {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче