Skip to content

Commit 53f0eb6

Browse files
jjagielskkuba-moo
authored andcommitted
ixgbevf: fix getting link speed data for E610 devices
E610 adapters no longer use the VFLINKS register to read PF's link speed and linkup state. As a result VF driver cannot get actual link state and it incorrectly reports 10G which is the default option. It leads to a situation where even 1G adapters print 10G as actual link speed. The same happens when PF driver set speed different than 10G. Add new mailbox operation to let the VF driver request a PF driver to provide actual link data. Update the mailbox api to v1.6. Incorporate both ways of getting link status within the legacy ixgbe_check_mac_link_vf() function. Fixes: 4c44b45 ("ixgbevf: Add support for Intel(R) E610 device") Co-developed-by: Andrzej Wilczynski <andrzejx.wilczynski@intel.com> Signed-off-by: Andrzej Wilczynski <andrzejx.wilczynski@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Cc: stable@vger.kernel.org Signed-off-by: Jedrzej Jagielski <jedrzej.jagielski@intel.com> Tested-by: Rafal Romanowski <rafal.romanowski@intel.com> Signed-off-by: Jacob Keller <jacob.e.keller@intel.com> Link: https://patch.msgid.link/20251009-jk-iwl-net-2025-10-01-v3-2-ef32a425b92a@intel.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent a3f8c0a commit 53f0eb6

File tree

4 files changed

+116
-32
lines changed

4 files changed

+116
-32
lines changed

drivers/net/ethernet/intel/ixgbevf/defines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
/* Link speed */
3030
typedef u32 ixgbe_link_speed;
31+
#define IXGBE_LINK_SPEED_UNKNOWN 0
3132
#define IXGBE_LINK_SPEED_1GB_FULL 0x0020
3233
#define IXGBE_LINK_SPEED_10GB_FULL 0x0080
3334
#define IXGBE_LINK_SPEED_100_FULL 0x0008

drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2275,6 +2275,7 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
22752275
{
22762276
struct ixgbe_hw *hw = &adapter->hw;
22772277
static const int api[] = {
2278+
ixgbe_mbox_api_16,
22782279
ixgbe_mbox_api_15,
22792280
ixgbe_mbox_api_14,
22802281
ixgbe_mbox_api_13,
@@ -2294,7 +2295,8 @@ static void ixgbevf_negotiate_api(struct ixgbevf_adapter *adapter)
22942295
idx++;
22952296
}
22962297

2297-
if (hw->api_version >= ixgbe_mbox_api_15) {
2298+
/* Following is not supported by API 1.6, it is specific for 1.5 */
2299+
if (hw->api_version == ixgbe_mbox_api_15) {
22982300
hw->mbx.ops.init_params(hw);
22992301
memcpy(&hw->mbx.ops, &ixgbevf_mbx_ops,
23002302
sizeof(struct ixgbe_mbx_operations));
@@ -2651,6 +2653,7 @@ static void ixgbevf_set_num_queues(struct ixgbevf_adapter *adapter)
26512653
case ixgbe_mbox_api_13:
26522654
case ixgbe_mbox_api_14:
26532655
case ixgbe_mbox_api_15:
2656+
case ixgbe_mbox_api_16:
26542657
if (adapter->xdp_prog &&
26552658
hw->mac.max_tx_queues == rss)
26562659
rss = rss > 3 ? 2 : 1;
@@ -4645,6 +4648,7 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
46454648
case ixgbe_mbox_api_13:
46464649
case ixgbe_mbox_api_14:
46474650
case ixgbe_mbox_api_15:
4651+
case ixgbe_mbox_api_16:
46484652
netdev->max_mtu = IXGBE_MAX_JUMBO_FRAME_SIZE -
46494653
(ETH_HLEN + ETH_FCS_LEN);
46504654
break;

drivers/net/ethernet/intel/ixgbevf/mbx.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ enum ixgbe_pfvf_api_rev {
6666
ixgbe_mbox_api_13, /* API version 1.3, linux/freebsd VF driver */
6767
ixgbe_mbox_api_14, /* API version 1.4, linux/freebsd VF driver */
6868
ixgbe_mbox_api_15, /* API version 1.5, linux/freebsd VF driver */
69+
ixgbe_mbox_api_16, /* API version 1.6, linux/freebsd VF driver */
6970
/* This value should always be last */
7071
ixgbe_mbox_api_unknown, /* indicates that API version is not known */
7172
};
@@ -102,6 +103,9 @@ enum ixgbe_pfvf_api_rev {
102103

103104
#define IXGBE_VF_GET_LINK_STATE 0x10 /* get vf link state */
104105

106+
/* mailbox API, version 1.6 VF requests */
107+
#define IXGBE_VF_GET_PF_LINK_STATE 0x11 /* request PF to send link info */
108+
105109
/* length of permanent address message returned from PF */
106110
#define IXGBE_VF_PERMADDR_MSG_LEN 4
107111
/* word in permanent address message with the current multicast type */

drivers/net/ethernet/intel/ixgbevf/vf.c

Lines changed: 106 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,7 @@ int ixgbevf_get_reta_locked(struct ixgbe_hw *hw, u32 *reta, int num_rx_queues)
313313
* is not supported for this device type.
314314
*/
315315
switch (hw->api_version) {
316+
case ixgbe_mbox_api_16:
316317
case ixgbe_mbox_api_15:
317318
case ixgbe_mbox_api_14:
318319
case ixgbe_mbox_api_13:
@@ -382,6 +383,7 @@ int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key)
382383
* or if the operation is not supported for this device type.
383384
*/
384385
switch (hw->api_version) {
386+
case ixgbe_mbox_api_16:
385387
case ixgbe_mbox_api_15:
386388
case ixgbe_mbox_api_14:
387389
case ixgbe_mbox_api_13:
@@ -552,6 +554,7 @@ static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
552554
case ixgbe_mbox_api_13:
553555
case ixgbe_mbox_api_14:
554556
case ixgbe_mbox_api_15:
557+
case ixgbe_mbox_api_16:
555558
break;
556559
default:
557560
return -EOPNOTSUPP;
@@ -624,6 +627,48 @@ static s32 ixgbevf_hv_get_link_state_vf(struct ixgbe_hw *hw, bool *link_state)
624627
return -EOPNOTSUPP;
625628
}
626629

630+
/**
631+
* ixgbevf_get_pf_link_state - Get PF's link status
632+
* @hw: pointer to the HW structure
633+
* @speed: link speed
634+
* @link_up: indicate if link is up/down
635+
*
636+
* Ask PF to provide link_up state and speed of the link.
637+
*
638+
* Return: IXGBE_ERR_MBX in the case of mailbox error,
639+
* -EOPNOTSUPP if the op is not supported or 0 on success.
640+
*/
641+
static int ixgbevf_get_pf_link_state(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
642+
bool *link_up)
643+
{
644+
u32 msgbuf[3] = {};
645+
int err;
646+
647+
switch (hw->api_version) {
648+
case ixgbe_mbox_api_16:
649+
break;
650+
default:
651+
return -EOPNOTSUPP;
652+
}
653+
654+
msgbuf[0] = IXGBE_VF_GET_PF_LINK_STATE;
655+
656+
err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf,
657+
ARRAY_SIZE(msgbuf));
658+
if (err || (msgbuf[0] & IXGBE_VT_MSGTYPE_FAILURE)) {
659+
err = IXGBE_ERR_MBX;
660+
*speed = IXGBE_LINK_SPEED_UNKNOWN;
661+
/* No need to set @link_up to false as it will be done by
662+
* ixgbe_check_mac_link_vf().
663+
*/
664+
} else {
665+
*speed = msgbuf[1];
666+
*link_up = msgbuf[2];
667+
}
668+
669+
return err;
670+
}
671+
627672
/**
628673
* ixgbevf_set_vfta_vf - Set/Unset VLAN filter table address
629674
* @hw: pointer to the HW structure
@@ -658,6 +703,58 @@ static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
658703
return err;
659704
}
660705

706+
/**
707+
* ixgbe_read_vflinks - Read VFLINKS register
708+
* @hw: pointer to the HW structure
709+
* @speed: link speed
710+
* @link_up: indicate if link is up/down
711+
*
712+
* Get linkup status and link speed from the VFLINKS register.
713+
*/
714+
static void ixgbe_read_vflinks(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
715+
bool *link_up)
716+
{
717+
u32 vflinks = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
718+
719+
/* if link status is down no point in checking to see if PF is up */
720+
if (!(vflinks & IXGBE_LINKS_UP)) {
721+
*link_up = false;
722+
return;
723+
}
724+
725+
/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
726+
* before the link status is correct
727+
*/
728+
if (hw->mac.type == ixgbe_mac_82599_vf) {
729+
for (int i = 0; i < 5; i++) {
730+
udelay(100);
731+
vflinks = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
732+
733+
if (!(vflinks & IXGBE_LINKS_UP)) {
734+
*link_up = false;
735+
return;
736+
}
737+
}
738+
}
739+
740+
/* We reached this point so there's link */
741+
*link_up = true;
742+
743+
switch (vflinks & IXGBE_LINKS_SPEED_82599) {
744+
case IXGBE_LINKS_SPEED_10G_82599:
745+
*speed = IXGBE_LINK_SPEED_10GB_FULL;
746+
break;
747+
case IXGBE_LINKS_SPEED_1G_82599:
748+
*speed = IXGBE_LINK_SPEED_1GB_FULL;
749+
break;
750+
case IXGBE_LINKS_SPEED_100_82599:
751+
*speed = IXGBE_LINK_SPEED_100_FULL;
752+
break;
753+
default:
754+
*speed = IXGBE_LINK_SPEED_UNKNOWN;
755+
}
756+
}
757+
661758
/**
662759
* ixgbevf_hv_set_vfta_vf - * Hyper-V variant - just a stub.
663760
* @hw: unused
@@ -705,7 +802,6 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
705802
struct ixgbe_mbx_info *mbx = &hw->mbx;
706803
struct ixgbe_mac_info *mac = &hw->mac;
707804
s32 ret_val = 0;
708-
u32 links_reg;
709805
u32 in_msg = 0;
710806

711807
/* If we were hit with a reset drop the link */
@@ -715,36 +811,14 @@ static s32 ixgbevf_check_mac_link_vf(struct ixgbe_hw *hw,
715811
if (!mac->get_link_status)
716812
goto out;
717813

718-
/* if link status is down no point in checking to see if pf is up */
719-
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
720-
if (!(links_reg & IXGBE_LINKS_UP))
721-
goto out;
722-
723-
/* for SFP+ modules and DA cables on 82599 it can take up to 500usecs
724-
* before the link status is correct
725-
*/
726-
if (mac->type == ixgbe_mac_82599_vf) {
727-
int i;
728-
729-
for (i = 0; i < 5; i++) {
730-
udelay(100);
731-
links_reg = IXGBE_READ_REG(hw, IXGBE_VFLINKS);
732-
733-
if (!(links_reg & IXGBE_LINKS_UP))
734-
goto out;
735-
}
736-
}
737-
738-
switch (links_reg & IXGBE_LINKS_SPEED_82599) {
739-
case IXGBE_LINKS_SPEED_10G_82599:
740-
*speed = IXGBE_LINK_SPEED_10GB_FULL;
741-
break;
742-
case IXGBE_LINKS_SPEED_1G_82599:
743-
*speed = IXGBE_LINK_SPEED_1GB_FULL;
744-
break;
745-
case IXGBE_LINKS_SPEED_100_82599:
746-
*speed = IXGBE_LINK_SPEED_100_FULL;
747-
break;
814+
if (hw->mac.type == ixgbe_mac_e610_vf) {
815+
ret_val = ixgbevf_get_pf_link_state(hw, speed, link_up);
816+
if (ret_val)
817+
goto out;
818+
} else {
819+
ixgbe_read_vflinks(hw, speed, link_up);
820+
if (*link_up == false)
821+
goto out;
748822
}
749823

750824
/* if the read failed it could just be a mailbox collision, best wait
@@ -951,6 +1025,7 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
9511025
case ixgbe_mbox_api_13:
9521026
case ixgbe_mbox_api_14:
9531027
case ixgbe_mbox_api_15:
1028+
case ixgbe_mbox_api_16:
9541029
break;
9551030
default:
9561031
return 0;

0 commit comments

Comments
 (0)