ixgbe: support link speed auto-negotiation on X550em_x
Normally the auto-negotiation is supported by FW. SW need not care about that. But on x550em_x, FW doesn't support auto-neg. As the x550em_x ports are 10G, if we connect the port will a peer which is 1G, the link will always be down. We need support auto-neg by SW to avoid this link down issue. As we already have the code to handle the link speed setting, what we need is a trigger. When the advertised link speed changes, a PHY interruption will be triggered. So, we should handle this interrupt and call ixgbe_handle_lasi to set the link speed correctly. Please be aware it's working when auto-neg is on. If the auto-neg of the peer port is turned off and its speed is indicated manually, we should also set the speed of our own port manually. Signed-off-by: Wenzhuo Lu <wenzhuo.lu@intel.com> Acked-by: Shaopeng He <shaopeng.he@intel.com>
This commit is contained in:
parent
72dec9e37a
commit
6be3dfec31
@ -116,6 +116,14 @@ This section should contain new features added in this release. Sample format:
|
||||
Only x550em_x V1 was supported before. Now V2 is supported.
|
||||
A mask for V1 and V2 is defined and used to support both.
|
||||
|
||||
* **Supported link speed auto-negotiation on X550EM_X**
|
||||
|
||||
Normally the auto-negotiation is supported by FW. SW need not care about
|
||||
that. But on x550em_x, FW doesn't support auto-neg. As the ports of x550em_x
|
||||
are 10G, if we connect the port with a peer which is 1G, the link will always
|
||||
be down.
|
||||
We added the support of auto-neg by SW to avoid this link down issue.
|
||||
|
||||
* **Added sw-firmware sync on X550EM_a.**
|
||||
|
||||
Added support for sw-firmware sync for resource sharing.
|
||||
|
@ -2030,6 +2030,25 @@ ixgbe_dev_configure(struct rte_eth_dev *dev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ixgbe_dev_phy_intr_setup(struct rte_eth_dev *dev)
|
||||
{
|
||||
struct ixgbe_hw *hw =
|
||||
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
struct ixgbe_interrupt *intr =
|
||||
IXGBE_DEV_PRIVATE_TO_INTR(dev->data->dev_private);
|
||||
uint32_t gpie;
|
||||
|
||||
/* only set up it on X550EM_X */
|
||||
if (hw->mac.type == ixgbe_mac_X550EM_x) {
|
||||
gpie = IXGBE_READ_REG(hw, IXGBE_GPIE);
|
||||
gpie |= IXGBE_SDP0_GPIEN_X550EM_x;
|
||||
IXGBE_WRITE_REG(hw, IXGBE_GPIE, gpie);
|
||||
if (hw->phy.type == ixgbe_phy_x550em_ext_t)
|
||||
intr->mask |= IXGBE_EICR_GPI_SDP0_X550EM_x;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure device link speed and setup link.
|
||||
* It returns 0 on success.
|
||||
@ -2078,6 +2097,8 @@ ixgbe_dev_start(struct rte_eth_dev *dev)
|
||||
/* configure PF module if SRIOV enabled */
|
||||
ixgbe_pf_host_configure(dev);
|
||||
|
||||
ixgbe_dev_phy_intr_setup(dev);
|
||||
|
||||
/* check and configure queue intr-vector mapping */
|
||||
if ((rte_intr_cap_multiple(intr_handle) ||
|
||||
!RTE_ETH_DEV_SRIOV(dev).active) &&
|
||||
@ -3156,6 +3177,11 @@ ixgbe_dev_interrupt_get_status(struct rte_eth_dev *dev)
|
||||
if (eicr & IXGBE_EICR_MAILBOX)
|
||||
intr->flags |= IXGBE_FLAG_MAILBOX;
|
||||
|
||||
if (hw->mac.type == ixgbe_mac_X550EM_x &&
|
||||
hw->phy.type == ixgbe_phy_x550em_ext_t &&
|
||||
(eicr & IXGBE_EICR_GPI_SDP0_X550EM_x))
|
||||
intr->flags |= IXGBE_FLAG_PHY_INTERRUPT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -3211,6 +3237,8 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
|
||||
int64_t timeout;
|
||||
struct rte_eth_link link;
|
||||
int intr_enable_delay = false;
|
||||
struct ixgbe_hw *hw =
|
||||
IXGBE_DEV_PRIVATE_TO_HW(dev->data->dev_private);
|
||||
|
||||
PMD_DRV_LOG(DEBUG, "intr action type %d", intr->flags);
|
||||
|
||||
@ -3219,6 +3247,11 @@ ixgbe_dev_interrupt_action(struct rte_eth_dev *dev)
|
||||
intr->flags &= ~IXGBE_FLAG_MAILBOX;
|
||||
}
|
||||
|
||||
if (intr->flags & IXGBE_FLAG_PHY_INTERRUPT) {
|
||||
ixgbe_handle_lasi(hw);
|
||||
intr->flags &= ~IXGBE_FLAG_PHY_INTERRUPT;
|
||||
}
|
||||
|
||||
if (intr->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
|
||||
/* get the link status before link update, for predicting later */
|
||||
memset(&link, 0, sizeof(link));
|
||||
@ -3282,6 +3315,11 @@ ixgbe_dev_interrupt_delayed_handler(void *param)
|
||||
if (eicr & IXGBE_EICR_MAILBOX)
|
||||
ixgbe_pf_mbx_process(dev);
|
||||
|
||||
if (intr->flags & IXGBE_FLAG_PHY_INTERRUPT) {
|
||||
ixgbe_handle_lasi(hw);
|
||||
intr->flags &= ~IXGBE_FLAG_PHY_INTERRUPT;
|
||||
}
|
||||
|
||||
if (intr->flags & IXGBE_FLAG_NEED_LINK_UPDATE) {
|
||||
ixgbe_dev_link_update(dev, 0);
|
||||
intr->flags &= ~IXGBE_FLAG_NEED_LINK_UPDATE;
|
||||
|
@ -42,6 +42,7 @@
|
||||
/* need update link, bit flag */
|
||||
#define IXGBE_FLAG_NEED_LINK_UPDATE (uint32_t)(1 << 0)
|
||||
#define IXGBE_FLAG_MAILBOX (uint32_t)(1 << 1)
|
||||
#define IXGBE_FLAG_PHY_INTERRUPT (uint32_t)(1 << 2)
|
||||
|
||||
/*
|
||||
* Defines that were not part of ixgbe_type.h as they are not used by the
|
||||
|
Loading…
Reference in New Issue
Block a user