Merge branch 'enic-sr-iov-v2-preparatory-infrastructure'
Satish Kharat says:
====================
enic: SR-IOV V2 preparatory infrastructure
This is the first of four series adding SR-IOV V2 support to the enic
driver for Cisco VIC 14xx/15xx adapters.
The existing V1 SR-IOV implementation has VFs that interact directly
with the VIC firmware, leaving the PF driver with no visibility or
control over VF behavior. V2 introduces a PF-mediated model where VFs
communicate with the PF through a mailbox over a dedicated admin
channel. This brings enic in line with the standard Linux SR-IOV
model, enabling full PF management of VFs via ip link (MAC, VLAN,
link state, spoofchk, trust, and per-VF statistics).
This preparatory series adds detection and resource helper code with
no functional change to existing driver behavior:
- Extend BAR resource discovery for admin channel resources
- Register the V2 VF PCI device ID
- Detect VF type (V1/V2/usNIC) from SR-IOV PCI capability
- Make enic_dev_enable/disable ref-counted for shared use by data
path and admin channel
- Add type-aware resource allocation for admin WQ/RQ/CQ/INTR
- Detect presence of admin channel resources at probe time
Tested on VIC 14xx and 15xx series adapters with V2 VFs under KVM
(sriov_numvfs, VF passthrough, ip link VF configuration, VF traffic).
Based in part on initial work by Christian Benvenuti.
====================
Link: https://patch.msgid.link/20260401-enic-sriov-v2-prep-v4-0-d5834b2ef1b9@cisco.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
master
commit
8b0e64d6c9
|
|
@ -225,6 +225,13 @@ struct enic_rq {
|
|||
struct page_pool *pool;
|
||||
} ____cacheline_aligned;
|
||||
|
||||
enum enic_vf_type {
|
||||
ENIC_VF_TYPE_NONE,
|
||||
ENIC_VF_TYPE_V1,
|
||||
ENIC_VF_TYPE_USNIC,
|
||||
ENIC_VF_TYPE_V2,
|
||||
};
|
||||
|
||||
/* Per-instance private data structure */
|
||||
struct enic {
|
||||
struct net_device *netdev;
|
||||
|
|
@ -252,6 +259,8 @@ struct enic {
|
|||
#ifdef CONFIG_PCI_IOV
|
||||
u16 num_vfs;
|
||||
#endif
|
||||
enum enic_vf_type vf_type;
|
||||
unsigned int enable_count;
|
||||
spinlock_t enic_api_lock;
|
||||
bool enic_api_busy;
|
||||
struct enic_port_profile *pp;
|
||||
|
|
@ -280,6 +289,13 @@ struct enic {
|
|||
u8 rss_key[ENIC_RSS_LEN];
|
||||
struct vnic_gen_stats gen_stats;
|
||||
enum ext_cq ext_cq;
|
||||
|
||||
/* Admin channel resources for SR-IOV MBOX */
|
||||
bool has_admin_channel;
|
||||
struct vnic_wq admin_wq;
|
||||
struct vnic_rq admin_rq;
|
||||
struct vnic_cq admin_cq[2];
|
||||
struct vnic_intr admin_intr;
|
||||
};
|
||||
|
||||
static inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev)
|
||||
|
|
@ -297,6 +313,8 @@ static inline struct net_device *vnic_get_netdev(struct vnic_dev *vdev)
|
|||
dev_warn(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__)
|
||||
#define vdev_info(vdev, fmt, ...) \
|
||||
dev_info(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__)
|
||||
#define vdev_dbg(vdev, fmt, ...) \
|
||||
dev_dbg(&(vdev)->pdev->dev, fmt, ##__VA_ARGS__)
|
||||
|
||||
#define vdev_neterr(vdev, fmt, ...) \
|
||||
netdev_err(vnic_get_netdev(vdev), fmt, ##__VA_ARGS__)
|
||||
|
|
|
|||
|
|
@ -131,10 +131,13 @@ int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
|
|||
|
||||
int enic_dev_enable(struct enic *enic)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
spin_lock_bh(&enic->devcmd_lock);
|
||||
err = vnic_dev_enable_wait(enic->vdev);
|
||||
if (enic->enable_count == 0)
|
||||
err = vnic_dev_enable_wait(enic->vdev);
|
||||
if (!err)
|
||||
enic->enable_count++;
|
||||
spin_unlock_bh(&enic->devcmd_lock);
|
||||
|
||||
return err;
|
||||
|
|
@ -142,10 +145,16 @@ int enic_dev_enable(struct enic *enic)
|
|||
|
||||
int enic_dev_disable(struct enic *enic)
|
||||
{
|
||||
int err;
|
||||
int err = 0;
|
||||
|
||||
spin_lock_bh(&enic->devcmd_lock);
|
||||
err = vnic_dev_disable(enic->vdev);
|
||||
if (enic->enable_count == 0) {
|
||||
spin_unlock_bh(&enic->devcmd_lock);
|
||||
return 0;
|
||||
}
|
||||
enic->enable_count--;
|
||||
if (enic->enable_count == 0)
|
||||
err = vnic_dev_disable(enic->vdev);
|
||||
spin_unlock_bh(&enic->devcmd_lock);
|
||||
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -66,12 +66,15 @@
|
|||
#define PCI_DEVICE_ID_CISCO_VIC_ENET 0x0043 /* ethernet vnic */
|
||||
#define PCI_DEVICE_ID_CISCO_VIC_ENET_DYN 0x0044 /* enet dynamic vnic */
|
||||
#define PCI_DEVICE_ID_CISCO_VIC_ENET_VF 0x0071 /* enet SRIOV VF */
|
||||
#define PCI_DEVICE_ID_CISCO_VIC_ENET_VF_V2 0x02b7 /* enet SRIOV V2 VF */
|
||||
#define PCI_DEVICE_ID_CISCO_VIC_ENET_VF_USNIC 0x00cf /* enet USNIC VF */
|
||||
|
||||
/* Supported devices */
|
||||
static const struct pci_device_id enic_id_table[] = {
|
||||
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET) },
|
||||
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_DYN) },
|
||||
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_VF) },
|
||||
{ PCI_VDEVICE(CISCO, PCI_DEVICE_ID_CISCO_VIC_ENET_VF_V2) },
|
||||
{ 0, } /* end of table */
|
||||
};
|
||||
|
||||
|
|
@ -307,7 +310,8 @@ int enic_sriov_enabled(struct enic *enic)
|
|||
|
||||
static int enic_is_sriov_vf(struct enic *enic)
|
||||
{
|
||||
return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_VF;
|
||||
return enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_VF ||
|
||||
enic->pdev->device == PCI_DEVICE_ID_CISCO_VIC_ENET_VF_V2;
|
||||
}
|
||||
|
||||
int enic_is_valid_vf(struct enic *enic, int vf)
|
||||
|
|
@ -1746,7 +1750,11 @@ static int enic_open(struct net_device *netdev)
|
|||
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
|
||||
for (i = 0; i < enic->wq_count; i++)
|
||||
napi_enable(&enic->napi[enic_cq_wq(enic, i)]);
|
||||
enic_dev_enable(enic);
|
||||
err = enic_dev_enable(enic);
|
||||
if (err) {
|
||||
netdev_err(netdev, "Failed to enable device: %d\n", err);
|
||||
goto err_out_dev_enable;
|
||||
}
|
||||
|
||||
for (i = 0; i < enic->intr_count; i++)
|
||||
vnic_intr_unmask(&enic->intr[i]);
|
||||
|
|
@ -1756,6 +1764,17 @@ static int enic_open(struct net_device *netdev)
|
|||
|
||||
return 0;
|
||||
|
||||
err_out_dev_enable:
|
||||
for (i = 0; i < enic->rq_count; i++)
|
||||
napi_disable(&enic->napi[i]);
|
||||
if (vnic_dev_get_intr_mode(enic->vdev) == VNIC_DEV_INTR_MODE_MSIX)
|
||||
for (i = 0; i < enic->wq_count; i++)
|
||||
napi_disable(&enic->napi[enic_cq_wq(enic, i)]);
|
||||
netif_tx_disable(netdev);
|
||||
if (!enic_is_dynamic(enic) && !enic_is_sriov_vf(enic))
|
||||
enic_dev_del_station_addr(enic);
|
||||
for (i = 0; i < enic->wq_count; i++)
|
||||
vnic_wq_disable(&enic->wq[i].vwq);
|
||||
err_out_free_rq:
|
||||
for (i = 0; i < enic->rq_count; i++) {
|
||||
ret = vnic_rq_disable(&enic->rq[i].vrq);
|
||||
|
|
@ -2618,6 +2637,41 @@ static void enic_iounmap(struct enic *enic)
|
|||
iounmap(enic->bar[i].vaddr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI_IOV
|
||||
static void enic_sriov_detect_vf_type(struct enic *enic)
|
||||
{
|
||||
struct pci_dev *pdev = enic->pdev;
|
||||
int pos;
|
||||
u16 vf_dev_id;
|
||||
|
||||
if (enic_is_sriov_vf(enic) || enic_is_dynamic(enic))
|
||||
return;
|
||||
|
||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_SRIOV);
|
||||
if (!pos) {
|
||||
enic->vf_type = ENIC_VF_TYPE_NONE;
|
||||
return;
|
||||
}
|
||||
|
||||
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &vf_dev_id);
|
||||
|
||||
switch (vf_dev_id) {
|
||||
case PCI_DEVICE_ID_CISCO_VIC_ENET_VF:
|
||||
enic->vf_type = ENIC_VF_TYPE_V1;
|
||||
break;
|
||||
case PCI_DEVICE_ID_CISCO_VIC_ENET_VF_USNIC:
|
||||
enic->vf_type = ENIC_VF_TYPE_USNIC;
|
||||
break;
|
||||
case PCI_DEVICE_ID_CISCO_VIC_ENET_VF_V2:
|
||||
enic->vf_type = ENIC_VF_TYPE_V2;
|
||||
break;
|
||||
default:
|
||||
enic->vf_type = ENIC_VF_TYPE_NONE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
@ -2731,6 +2785,7 @@ static int enic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
num_pps = enic->num_vfs;
|
||||
}
|
||||
}
|
||||
enic_sriov_detect_vf_type(enic);
|
||||
#endif
|
||||
|
||||
/* Allocate structure for port profiles */
|
||||
|
|
|
|||
|
|
@ -205,10 +205,18 @@ void enic_get_res_counts(struct enic *enic)
|
|||
enic->cq_count = enic->cq_avail;
|
||||
enic->intr_count = enic->intr_avail;
|
||||
|
||||
enic->has_admin_channel =
|
||||
vnic_dev_get_res_count(enic->vdev, RES_TYPE_ADMIN_WQ) >= 1 &&
|
||||
vnic_dev_get_res_count(enic->vdev, RES_TYPE_ADMIN_RQ) >= 1 &&
|
||||
vnic_dev_get_res_count(enic->vdev, RES_TYPE_ADMIN_CQ) >=
|
||||
ARRAY_SIZE(enic->admin_cq) &&
|
||||
vnic_dev_get_res_count(enic->vdev, RES_TYPE_SRIOV_INTR) >= 1;
|
||||
|
||||
dev_info(enic_get_dev(enic),
|
||||
"vNIC resources avail: wq %d rq %d cq %d intr %d\n",
|
||||
"vNIC resources avail: wq %d rq %d cq %d intr %d admin %s\n",
|
||||
enic->wq_avail, enic->rq_avail,
|
||||
enic->cq_avail, enic->intr_avail);
|
||||
enic->cq_avail, enic->intr_avail,
|
||||
enic->has_admin_channel ? "yes" : "no");
|
||||
}
|
||||
|
||||
void enic_init_vnic_resources(struct enic *enic)
|
||||
|
|
|
|||
|
|
@ -20,13 +20,14 @@ void vnic_cq_free(struct vnic_cq *cq)
|
|||
cq->ctrl = NULL;
|
||||
}
|
||||
|
||||
int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
int vnic_cq_alloc_with_type(struct vnic_dev *vdev, struct vnic_cq *cq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type)
|
||||
{
|
||||
cq->index = index;
|
||||
cq->vdev = vdev;
|
||||
|
||||
cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index);
|
||||
cq->ctrl = vnic_dev_get_res(vdev, res_type, index);
|
||||
if (!cq->ctrl) {
|
||||
vdev_err(vdev, "Failed to hook CQ[%d] resource\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -35,6 +36,13 @@ int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
|
|||
return vnic_dev_alloc_desc_ring(vdev, &cq->ring, desc_count, desc_size);
|
||||
}
|
||||
|
||||
int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
{
|
||||
return vnic_cq_alloc_with_type(vdev, cq, index, desc_count, desc_size,
|
||||
RES_TYPE_CQ);
|
||||
}
|
||||
|
||||
void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable,
|
||||
unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail,
|
||||
unsigned int cq_tail_color, unsigned int interrupt_enable,
|
||||
|
|
|
|||
|
|
@ -73,6 +73,9 @@ static inline void vnic_cq_inc_to_clean(struct vnic_cq *cq)
|
|||
void vnic_cq_free(struct vnic_cq *cq);
|
||||
int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size);
|
||||
int vnic_cq_alloc_with_type(struct vnic_dev *vdev, struct vnic_cq *cq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type);
|
||||
void vnic_cq_init(struct vnic_cq *cq, unsigned int flow_control_enable,
|
||||
unsigned int color_enable, unsigned int cq_head, unsigned int cq_tail,
|
||||
unsigned int cq_tail_color, unsigned int interrupt_enable,
|
||||
|
|
|
|||
|
|
@ -77,6 +77,9 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
|
|||
u32 count = ioread32(&r->count);
|
||||
u32 len;
|
||||
|
||||
vdev_dbg(vdev, "res type %u bar %u offset 0x%x count %u\n",
|
||||
type, bar_num, bar_offset, count);
|
||||
|
||||
r++;
|
||||
|
||||
if (bar_num >= num_bars)
|
||||
|
|
@ -90,6 +93,9 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
|
|||
case RES_TYPE_RQ:
|
||||
case RES_TYPE_CQ:
|
||||
case RES_TYPE_INTR_CTRL:
|
||||
case RES_TYPE_ADMIN_WQ:
|
||||
case RES_TYPE_ADMIN_RQ:
|
||||
case RES_TYPE_ADMIN_CQ:
|
||||
/* each count is stride bytes long */
|
||||
len = count * VNIC_RES_STRIDE;
|
||||
if (len + bar_offset > bar[bar_num].len) {
|
||||
|
|
@ -102,6 +108,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
|
|||
case RES_TYPE_INTR_PBA_LEGACY:
|
||||
case RES_TYPE_DEVCMD:
|
||||
case RES_TYPE_DEVCMD2:
|
||||
case RES_TYPE_SRIOV_INTR:
|
||||
len = count;
|
||||
break;
|
||||
default:
|
||||
|
|
@ -135,6 +142,9 @@ void __iomem *vnic_dev_get_res(struct vnic_dev *vdev, enum vnic_res_type type,
|
|||
case RES_TYPE_RQ:
|
||||
case RES_TYPE_CQ:
|
||||
case RES_TYPE_INTR_CTRL:
|
||||
case RES_TYPE_ADMIN_WQ:
|
||||
case RES_TYPE_ADMIN_RQ:
|
||||
case RES_TYPE_ADMIN_CQ:
|
||||
return (char __iomem *)vdev->res[type].vaddr +
|
||||
index * VNIC_RES_STRIDE;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -19,13 +19,13 @@ void vnic_intr_free(struct vnic_intr *intr)
|
|||
intr->ctrl = NULL;
|
||||
}
|
||||
|
||||
int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
|
||||
unsigned int index)
|
||||
int vnic_intr_alloc_with_type(struct vnic_dev *vdev, struct vnic_intr *intr,
|
||||
unsigned int index, unsigned int res_type)
|
||||
{
|
||||
intr->index = index;
|
||||
intr->vdev = vdev;
|
||||
|
||||
intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index);
|
||||
intr->ctrl = vnic_dev_get_res(vdev, res_type, index);
|
||||
if (!intr->ctrl) {
|
||||
vdev_err(vdev, "Failed to hook INTR[%d].ctrl resource\n",
|
||||
index);
|
||||
|
|
@ -35,6 +35,12 @@ int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
|
||||
unsigned int index)
|
||||
{
|
||||
return vnic_intr_alloc_with_type(vdev, intr, index, RES_TYPE_INTR_CTRL);
|
||||
}
|
||||
|
||||
void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
|
||||
unsigned int coalescing_type, unsigned int mask_on_assertion)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -89,6 +89,8 @@ static inline u32 vnic_intr_legacy_pba(u32 __iomem *legacy_pba)
|
|||
void vnic_intr_free(struct vnic_intr *intr);
|
||||
int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
|
||||
unsigned int index);
|
||||
int vnic_intr_alloc_with_type(struct vnic_dev *vdev, struct vnic_intr *intr,
|
||||
unsigned int index, unsigned int res_type);
|
||||
void vnic_intr_init(struct vnic_intr *intr, u32 coalescing_timer,
|
||||
unsigned int coalescing_type, unsigned int mask_on_assertion);
|
||||
void vnic_intr_coalescing_timer_set(struct vnic_intr *intr,
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ enum vnic_res_type {
|
|||
RES_TYPE_DEPRECATED1, /* Old version of devcmd 2 */
|
||||
RES_TYPE_DEPRECATED2, /* Old version of devcmd 2 */
|
||||
RES_TYPE_DEVCMD2, /* Device control region */
|
||||
RES_TYPE_SRIOV_INTR = 45, /* SR-IOV VF interrupt */
|
||||
RES_TYPE_ADMIN_WQ = 49, /* Admin channel WQ */
|
||||
RES_TYPE_ADMIN_RQ, /* Admin channel RQ */
|
||||
RES_TYPE_ADMIN_CQ, /* Admin channel CQ */
|
||||
|
||||
RES_TYPE_MAX, /* Count of resource types */
|
||||
};
|
||||
|
|
|
|||
|
|
@ -69,15 +69,16 @@ void vnic_rq_free(struct vnic_rq *rq)
|
|||
rq->ctrl = NULL;
|
||||
}
|
||||
|
||||
int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
int vnic_rq_alloc_with_type(struct vnic_dev *vdev, struct vnic_rq *rq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type)
|
||||
{
|
||||
int err;
|
||||
|
||||
rq->index = index;
|
||||
rq->vdev = vdev;
|
||||
|
||||
rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index);
|
||||
rq->ctrl = vnic_dev_get_res(vdev, res_type, index);
|
||||
if (!rq->ctrl) {
|
||||
vdev_err(vdev, "Failed to hook RQ[%d] resource\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -98,6 +99,13 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
{
|
||||
return vnic_rq_alloc_with_type(vdev, rq, index, desc_count, desc_size,
|
||||
RES_TYPE_RQ);
|
||||
}
|
||||
|
||||
static void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
|
||||
unsigned int fetch_index, unsigned int posted_index,
|
||||
unsigned int error_interrupt_enable,
|
||||
|
|
|
|||
|
|
@ -196,6 +196,9 @@ static inline int vnic_rq_fill(struct vnic_rq *rq,
|
|||
void vnic_rq_free(struct vnic_rq *rq);
|
||||
int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size);
|
||||
int vnic_rq_alloc_with_type(struct vnic_dev *vdev, struct vnic_rq *rq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type);
|
||||
void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
|
||||
unsigned int error_interrupt_enable,
|
||||
unsigned int error_interrupt_offset);
|
||||
|
|
|
|||
|
|
@ -72,15 +72,16 @@ void vnic_wq_free(struct vnic_wq *wq)
|
|||
wq->ctrl = NULL;
|
||||
}
|
||||
|
||||
int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
int vnic_wq_alloc_with_type(struct vnic_dev *vdev, struct vnic_wq *wq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type)
|
||||
{
|
||||
int err;
|
||||
|
||||
wq->index = index;
|
||||
wq->vdev = vdev;
|
||||
|
||||
wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index);
|
||||
wq->ctrl = vnic_dev_get_res(vdev, res_type, index);
|
||||
if (!wq->ctrl) {
|
||||
vdev_err(vdev, "Failed to hook WQ[%d] resource\n", index);
|
||||
return -EINVAL;
|
||||
|
|
@ -101,6 +102,13 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
|
|||
return 0;
|
||||
}
|
||||
|
||||
int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
{
|
||||
return vnic_wq_alloc_with_type(vdev, wq, index, desc_count, desc_size,
|
||||
RES_TYPE_WQ);
|
||||
}
|
||||
|
||||
int enic_wq_devcmd2_alloc(struct vnic_dev *vdev, struct vnic_wq *wq,
|
||||
unsigned int desc_count, unsigned int desc_size)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -165,6 +165,9 @@ static inline void vnic_wq_service(struct vnic_wq *wq,
|
|||
void vnic_wq_free(struct vnic_wq *wq);
|
||||
int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
|
||||
unsigned int desc_count, unsigned int desc_size);
|
||||
int vnic_wq_alloc_with_type(struct vnic_dev *vdev, struct vnic_wq *wq,
|
||||
unsigned int index, unsigned int desc_count,
|
||||
unsigned int desc_size, unsigned int res_type);
|
||||
void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
|
||||
unsigned int error_interrupt_enable,
|
||||
unsigned int error_interrupt_offset);
|
||||
|
|
|
|||
Loading…
Reference in New Issue