Commit 877253d2 authored by Mengyuan Lou's avatar Mengyuan Lou Committed by Jakub Kicinski
Browse files

net: ngbe: add sriov function support



Add sriov_configure for driver ops.
Add mailbox handler wx_msg_task for ngbe in
the interrupt handler.
Add the notification flow when the vfs exist.

Signed-off-by: default avatarMengyuan Lou <mengyuanlou@net-swift.com>
Link: https://patch.msgid.link/C9A0A43732966022+20250408091556.9640-6-mengyuanlou@net-swift.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 359e41f6
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -834,3 +834,34 @@ void wx_msg_task(struct wx *wx)
	}
}
EXPORT_SYMBOL(wx_msg_task);

void wx_disable_vf_rx_tx(struct wx *wx)
{
	wr32(wx, WX_TDM_VFTE_CLR(0), U32_MAX);
	wr32(wx, WX_RDM_VFRE_CLR(0), U32_MAX);
	if (wx->mac.type != wx_mac_em) {
		wr32(wx, WX_TDM_VFTE_CLR(1), U32_MAX);
		wr32(wx, WX_RDM_VFRE_CLR(1), U32_MAX);
	}
}
EXPORT_SYMBOL(wx_disable_vf_rx_tx);

void wx_ping_all_vfs_with_link_status(struct wx *wx, bool link_up)
{
	u32 msgbuf[2] = {0, 0};
	u16 i;

	if (!wx->num_vfs)
		return;
	msgbuf[0] = WX_PF_NOFITY_VF_LINK_STATUS | WX_PF_CONTROL_MSG;
	if (link_up)
		msgbuf[1] = FIELD_PREP(GENMASK(31, 1), wx->speed) | link_up;
	if (wx->notify_down)
		msgbuf[1] |= WX_PF_NOFITY_VF_NET_NOT_RUNNING;
	for (i = 0; i < wx->num_vfs; i++) {
		if (wx->vfinfo[i].clear_to_send)
			msgbuf[0] |= WX_VT_MSGTYPE_CTS;
		wx_write_mbx_pf(wx, msgbuf, 2, i);
	}
}
EXPORT_SYMBOL(wx_ping_all_vfs_with_link_status);
+2 −0
Original line number Diff line number Diff line
@@ -11,5 +11,7 @@
void wx_disable_sriov(struct wx *wx);
int wx_pci_sriov_configure(struct pci_dev *pdev, int num_vfs);
void wx_msg_task(struct wx *wx);
void wx_disable_vf_rx_tx(struct wx *wx);
void wx_ping_all_vfs_with_link_status(struct wx *wx, bool link_up);

#endif /* _WX_SRIOV_H_ */
+2 −0
Original line number Diff line number Diff line
@@ -92,6 +92,7 @@
/************************* Port Registers ************************************/
/* port cfg Registers */
#define WX_CFG_PORT_CTL              0x14400
#define WX_CFG_PORT_CTL_PFRSTD       BIT(14)
#define WX_CFG_PORT_CTL_DRV_LOAD     BIT(3)
#define WX_CFG_PORT_CTL_QINQ         BIT(2)
#define WX_CFG_PORT_CTL_D_VLAN       BIT(0) /* double vlan*/
@@ -1231,6 +1232,7 @@ struct wx {
	u8 swfw_index;

	/* PHY stuff */
	bool notify_down;
	unsigned int link;
	int speed;
	int duplex;
+84 −9
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
#include "../libwx/wx_hw.h"
#include "../libwx/wx_lib.h"
#include "../libwx/wx_ptp.h"
#include "../libwx/wx_mbx.h"
#include "../libwx/wx_sriov.h"
#include "ngbe_type.h"
#include "ngbe_mdio.h"
#include "ngbe_hw.h"
@@ -129,6 +131,10 @@ static int ngbe_sw_init(struct wx *wx)
	wx->tx_work_limit = NGBE_DEFAULT_TX_WORK;
	wx->rx_work_limit = NGBE_DEFAULT_RX_WORK;

	wx->mbx.size = WX_VXMAILBOX_SIZE;
	wx->setup_tc = ngbe_setup_tc;
	set_bit(0, &wx->fwd_bitmask);

	return 0;
}

@@ -200,12 +206,10 @@ static irqreturn_t ngbe_intr(int __always_unused irq, void *data)
	return IRQ_HANDLED;
}

static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data)
static irqreturn_t __ngbe_msix_misc(struct wx *wx, u32 eicr)
{
	struct wx *wx = data;
	u32 eicr;

	eicr = wx_misc_isb(wx, WX_ISB_MISC);
	if (eicr & NGBE_PX_MISC_IC_VF_MBOX)
		wx_msg_task(wx);

	if (unlikely(eicr & NGBE_PX_MISC_IC_TIMESYNC))
		wx_ptp_check_pps_event(wx);
@@ -217,6 +221,35 @@ static irqreturn_t ngbe_msix_other(int __always_unused irq, void *data)
	return IRQ_HANDLED;
}

static irqreturn_t ngbe_msix_misc(int __always_unused irq, void *data)
{
	struct wx *wx = data;
	u32 eicr;

	eicr = wx_misc_isb(wx, WX_ISB_MISC);

	return __ngbe_msix_misc(wx, eicr);
}

static irqreturn_t ngbe_misc_and_queue(int __always_unused irq, void *data)
{
	struct wx_q_vector *q_vector;
	struct wx *wx = data;
	u32 eicr;

	eicr = wx_misc_isb(wx, WX_ISB_MISC);
	if (!eicr) {
		/* queue */
		q_vector = wx->q_vector[0];
		napi_schedule_irqoff(&q_vector->napi);
		if (netif_running(wx->netdev))
			ngbe_irq_enable(wx, true);
		return IRQ_HANDLED;
	}

	return __ngbe_msix_misc(wx, eicr);
}

/**
 * ngbe_request_msix_irqs - Initialize MSI-X interrupts
 * @wx: board private structure
@@ -249,8 +282,16 @@ static int ngbe_request_msix_irqs(struct wx *wx)
		}
	}

	/* Due to hardware design, when num_vfs < 7, pf can use 0 for misc and 1
	 * for queue. But when num_vfs == 7, vector[1] is assigned to vf6.
	 * Misc and queue should reuse interrupt vector[0].
	 */
	if (wx->num_vfs == 7)
		err = request_irq(wx->msix_entry->vector,
			  ngbe_msix_other, 0, netdev->name, wx);
				  ngbe_misc_and_queue, 0, netdev->name, wx);
	else
		err = request_irq(wx->msix_entry->vector,
				  ngbe_msix_misc, 0, netdev->name, wx);

	if (err) {
		wx_err(wx, "request_irq for msix_other failed: %d\n", err);
@@ -302,6 +343,22 @@ static void ngbe_disable_device(struct wx *wx)
	struct net_device *netdev = wx->netdev;
	u32 i;

	if (wx->num_vfs) {
		/* Clear EITR Select mapping */
		wr32(wx, WX_PX_ITRSEL, 0);

		/* Mark all the VFs as inactive */
		for (i = 0; i < wx->num_vfs; i++)
			wx->vfinfo[i].clear_to_send = 0;
		wx->notify_down = true;
		/* ping all the active vfs to let them know we are going down */
		wx_ping_all_vfs_with_link_status(wx, false);
		wx->notify_down = false;

		/* Disable all VFTE/VFRE TX/RX */
		wx_disable_vf_rx_tx(wx);
	}

	/* disable all enabled rx queues */
	for (i = 0; i < wx->num_rx_queues; i++)
		/* this call also flushes the previous write */
@@ -324,12 +381,19 @@ static void ngbe_disable_device(struct wx *wx)
	wx_update_stats(wx);
}

static void ngbe_reset(struct wx *wx)
{
	wx_flush_sw_mac_table(wx);
	wx_mac_set_default_filter(wx, wx->mac.addr);
	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
		wx_ptp_reset(wx);
}

void ngbe_down(struct wx *wx)
{
	phylink_stop(wx->phylink);
	ngbe_disable_device(wx);
	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
		wx_ptp_reset(wx);
	ngbe_reset(wx);
	wx_clean_all_tx_rings(wx);
	wx_clean_all_rx_rings(wx);
}
@@ -352,6 +416,11 @@ void ngbe_up(struct wx *wx)
		ngbe_sfp_modules_txrx_powerctl(wx, true);

	phylink_start(wx->phylink);
	/* Set PF Reset Done bit so PF/VF Mail Ops can work */
	wr32m(wx, WX_CFG_PORT_CTL,
	      WX_CFG_PORT_CTL_PFRSTD, WX_CFG_PORT_CTL_PFRSTD);
	if (wx->num_vfs)
		wx_ping_all_vfs_with_link_status(wx, false);
}

/**
@@ -596,6 +665,10 @@ static int ngbe_probe(struct pci_dev *pdev,
		goto err_pci_release_regions;
	}

	/* The emerald supports up to 8 VFs per pf, but physical
	 * function also need one pool for basic networking.
	 */
	pci_sriov_set_totalvfs(pdev, NGBE_MAX_VFS_DRV_LIMIT);
	wx->driver_name = ngbe_driver_name;
	ngbe_set_ethtool_ops(netdev);
	netdev->netdev_ops = &ngbe_netdev_ops;
@@ -743,6 +816,7 @@ static void ngbe_remove(struct pci_dev *pdev)
	struct net_device *netdev;

	netdev = wx->netdev;
	wx_disable_sriov(wx);
	unregister_netdev(netdev);
	phylink_destroy(wx->phylink);
	pci_release_selected_regions(pdev,
@@ -802,6 +876,7 @@ static struct pci_driver ngbe_driver = {
	.suspend  = ngbe_suspend,
	.resume   = ngbe_resume,
	.shutdown = ngbe_shutdown,
	.sriov_configure = wx_pci_sriov_configure,
};

module_pci_driver(ngbe_driver);
+5 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#include "../libwx/wx_type.h"
#include "../libwx/wx_ptp.h"
#include "../libwx/wx_hw.h"
#include "../libwx/wx_sriov.h"
#include "ngbe_type.h"
#include "ngbe_mdio.h"

@@ -70,6 +71,8 @@ static void ngbe_mac_link_down(struct phylink_config *config,
	wx->speed = SPEED_UNKNOWN;
	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
		wx_ptp_reset_cyclecounter(wx);
	/* ping all the active vfs to let them know we are going down */
	wx_ping_all_vfs_with_link_status(wx, false);
}

static void ngbe_mac_link_up(struct phylink_config *config,
@@ -114,6 +117,8 @@ static void ngbe_mac_link_up(struct phylink_config *config,
	wx->last_rx_ptp_check = jiffies;
	if (test_bit(WX_STATE_PTP_RUNNING, wx->state))
		wx_ptp_reset_cyclecounter(wx);
	/* ping all the active vfs to let them know we are going up */
	wx_ping_all_vfs_with_link_status(wx, true);
}

static const struct phylink_mac_ops ngbe_mac_ops = {
Loading