Skip to content

Commit 1aee053

Browse files
Zaiyu Wangshemminger
authored andcommitted
net/txgbe: add PF-triggered VF link status change handling
Our Linux kernel driver add TXGBE_NOFITY_VF_LINK_STATUS field in mailbox message when pf notifying vf of LSC event since txgbe-2.0.0. So we can process VF link down/up via PF's mailbox notifications, and directly update VF link status based on PF status For legacy kernel driver compatibility, trigger link_update to check vf link status changes when receive a mailbox message without TXGBE_NOFITY_VF_LINK_STATUS filed from pf. Signed-off-by: Zaiyu Wang <[email protected]>
1 parent b6ccdb7 commit 1aee053

File tree

2 files changed

+80
-6
lines changed

2 files changed

+80
-6
lines changed

drivers/net/txgbe/base/txgbe_mbx.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ enum txgbe_pfvf_api_rev {
4949
#define TXGBE_VF_SET_MULTICAST 0x03 /* VF requests PF to set MC addr */
5050
#define TXGBE_VF_SET_VLAN 0x04 /* VF requests PF to set VLAN */
5151

52+
#define TXGBE_NOFITY_VF_LINK_STATUS 0x01 /* PF notify VF link status */
53+
5254
/* mailbox API, version 1.0 VF requests */
5355
#define TXGBE_VF_SET_LPE 0x05 /* VF requests PF to set VMOLR.LPE */
5456
#define TXGBE_VF_SET_MACVLAN 0x06 /* VF requests PF for unicast filter */

drivers/net/txgbe/txgbe_ethdev_vf.c

Lines changed: 78 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,75 @@ txgbevf_dev_allmulticast_disable(struct rte_eth_dev *dev)
13661366
return ret;
13671367
}
13681368

1369+
/**
1370+
* txgbevf_get_pf_link_status - Get pf link/speed status
1371+
* @hw: pointer to hardware structure
1372+
*
1373+
* - PF notifies status via mailbox on change
1374+
* - VF sets its link state synchronously upon mailbox interrupt,
1375+
* skipping hardware link detection.
1376+
**/
1377+
static s32 txgbevf_get_pf_link_status(struct rte_eth_dev *dev)
1378+
{
1379+
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
1380+
struct txgbe_mbx_info *mbx = &hw->mbx;
1381+
struct rte_eth_link link;
1382+
u32 link_speed = TXGBE_LINK_SPEED_UNKNOWN;
1383+
bool link_up = false;
1384+
u32 msgbuf[2];
1385+
s32 retval;
1386+
1387+
retval = mbx->read(hw, msgbuf, 2, 0);
1388+
1389+
/*
1390+
*if the read failed it could just be a mailbox collision, best wait
1391+
* until we are called again and don't report an error
1392+
*/
1393+
if (retval)
1394+
return 0;
1395+
1396+
rte_eth_linkstatus_get(dev, &link);
1397+
1398+
link_up = msgbuf[1] & TXGBE_VFSTATUS_UP;
1399+
link_speed = (msgbuf[1] & 0xFFF0) >> 1;
1400+
1401+
if (link_up == link.link_status && link_speed == link.link_speed)
1402+
return 0;
1403+
1404+
link.link_speed = link_speed;
1405+
link.link_status = link_up;
1406+
1407+
if (link_up)
1408+
link.link_duplex = RTE_ETH_LINK_FULL_DUPLEX;
1409+
else
1410+
link.link_duplex = RTE_ETH_LINK_HALF_DUPLEX;
1411+
/*
1412+
* Invoke the LSC interrupt callback to notify the upper app of a link
1413+
* status change, even though the change is detected via a mailbox interrupt
1414+
* instead of an LSC interrupt. This is because VF link status changes do
1415+
* not trigger LSC interrupts — they rely on PF notifications.
1416+
*/
1417+
rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
1418+
NULL);
1419+
return rte_eth_linkstatus_set(dev, &link);
1420+
}
1421+
1422+
static void txgbevf_check_link_for_intr(struct rte_eth_dev *dev)
1423+
{
1424+
struct rte_eth_link orig_link, new_link;
1425+
1426+
rte_eth_linkstatus_get(dev, &orig_link);
1427+
txgbevf_dev_link_update(dev, 0);
1428+
rte_eth_linkstatus_get(dev, &new_link);
1429+
1430+
PMD_DRV_LOG(INFO, "orig_link: %d, new_link: %d",
1431+
orig_link.link_status, new_link.link_status);
1432+
1433+
if (new_link.link_status != orig_link.link_status)
1434+
rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_LSC,
1435+
NULL);
1436+
}
1437+
13691438
static void txgbevf_mbx_process(struct rte_eth_dev *dev)
13701439
{
13711440
struct txgbe_hw *hw = TXGBE_DEV_HW(dev);
@@ -1375,12 +1444,15 @@ static void txgbevf_mbx_process(struct rte_eth_dev *dev)
13751444
in_msg = rd32(hw, TXGBE_VFMBX);
13761445

13771446
/* PF reset VF event */
1378-
if (in_msg == TXGBE_PF_CONTROL_MSG) {
1379-
/* dummy mbx read to ack pf */
1380-
if (txgbe_read_mbx(hw, &in_msg, 1, 0))
1381-
return;
1382-
rte_eth_dev_callback_process(dev, RTE_ETH_EVENT_INTR_RESET,
1383-
NULL);
1447+
if (in_msg & TXGBE_PF_CONTROL_MSG) {
1448+
if (in_msg & TXGBE_NOFITY_VF_LINK_STATUS) {
1449+
txgbevf_get_pf_link_status(dev);
1450+
} else {
1451+
/* dummy mbx read to ack pf */
1452+
txgbe_read_mbx(hw, &in_msg, 1, 0);
1453+
/* check link status if pf ping vf */
1454+
txgbevf_check_link_for_intr(dev);
1455+
}
13841456
}
13851457
}
13861458

0 commit comments

Comments
 (0)