void (*free_consistent)(void *priv,
size_t size, void *vaddr,
dma_addr_t dma_handle);
+ /*
+ * Used to serialize devcmd access, currently from PF and its
+ * VF representors. When there are no representors, lock is
+ * not used.
+ */
+ int locked;
+ void (*lock)(void *priv);
+ void (*unlock)(void *priv);
+ struct vnic_dev *pf_vdev;
+ int vf_id;
};
#define VNIC_MAX_RES_HDR_SIZE \
vdev->free_consistent = free_consistent;
}
+void vnic_register_lock(struct vnic_dev *vdev, void (*lock)(void *priv),
+ void (*unlock)(void *priv))
+{
+ vdev->lock = lock;
+ vdev->unlock = unlock;
+ vdev->locked = 0;
+}
+
static int vnic_dev_discover_res(struct vnic_dev *vdev,
struct vnic_dev_bar *bar, unsigned int num_bars)
{
return err;
}
+void vnic_dev_cmd_proxy_by_index_start(struct vnic_dev *vdev, uint16_t index)
+{
+ vdev->proxy = PROXY_BY_INDEX;
+ vdev->proxy_index = index;
+}
+
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
+{
+ vdev->proxy = PROXY_NONE;
+ vdev->proxy_index = 0;
+}
+
int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
uint64_t *a0, uint64_t *a1, int wait)
{
uint64_t args[2];
+ bool vf_rep;
+ int vf_idx;
int err;
+ vf_rep = false;
+ if (vdev->pf_vdev) {
+ vf_rep = true;
+ vf_idx = vdev->vf_id;
+ /* Everything below assumes PF vdev */
+ vdev = vdev->pf_vdev;
+ }
+ if (vdev->lock)
+ vdev->lock(vdev->priv);
+ /* For VF representor, proxy devcmd to VF index */
+ if (vf_rep)
+ vnic_dev_cmd_proxy_by_index_start(vdev, vf_idx);
+
args[0] = *a0;
args[1] = *a1;
memset(vdev->args, 0, sizeof(vdev->args));
break;
}
+ if (vf_rep)
+ vnic_dev_cmd_proxy_end(vdev);
+ if (vdev->unlock)
+ vdev->unlock(vdev->priv);
if (err == 0) {
*a0 = args[0];
*a1 = args[1];
int vnic_dev_cmd_args(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
uint64_t *args, int nargs, int wait)
{
+ bool vf_rep;
+ int vf_idx;
+ int err;
+
+ vf_rep = false;
+ if (vdev->pf_vdev) {
+ vf_rep = true;
+ vf_idx = vdev->vf_id;
+ vdev = vdev->pf_vdev;
+ }
+ if (vdev->lock)
+ vdev->lock(vdev->priv);
+ if (vf_rep)
+ vnic_dev_cmd_proxy_by_index_start(vdev, vf_idx);
+
switch (vdev->proxy) {
case PROXY_BY_INDEX:
- return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd,
+ err = vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_INDEX, cmd,
args, nargs, wait);
+ break;
case PROXY_BY_BDF:
- return vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd,
+ err = vnic_dev_cmd_proxy(vdev, CMD_PROXY_BY_BDF, cmd,
args, nargs, wait);
+ break;
case PROXY_NONE:
default:
- return vnic_dev_cmd_no_proxy(vdev, cmd, args, nargs, wait);
+ err = vnic_dev_cmd_no_proxy(vdev, cmd, args, nargs, wait);
+ break;
}
+
+ if (vf_rep)
+ vnic_dev_cmd_proxy_end(vdev);
+ if (vdev->unlock)
+ vdev->unlock(vdev->priv);
+ return err;
}
int vnic_dev_fw_info(struct vnic_dev *vdev,
return vdev->notify_copy.port_speed;
}
+uint32_t vnic_dev_mtu(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.mtu;
+}
+
+uint32_t vnic_dev_uif(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.uif;
+}
+
uint32_t vnic_dev_intr_coal_timer_usec_to_hw(struct vnic_dev *vdev,
uint32_t usec)
{
return NULL;
}
+struct vnic_dev *vnic_vf_rep_register(void *priv, struct vnic_dev *pf_vdev,
+ int vf_id)
+{
+ struct vnic_dev *vdev;
+
+ vdev = (struct vnic_dev *)rte_zmalloc("enic-vf-rep-vdev",
+ sizeof(struct vnic_dev), RTE_CACHE_LINE_SIZE);
+ if (!vdev)
+ return NULL;
+ vdev->priv = priv;
+ vdev->pf_vdev = pf_vdev;
+ vdev->vf_id = vf_id;
+ vdev->alloc_consistent = pf_vdev->alloc_consistent;
+ vdev->free_consistent = pf_vdev->free_consistent;
+ return vdev;
+}
+
/*
* vnic_dev_classifier: Add/Delete classifier entries
* @vdev: vdev of the device
ret = vnic_dev_cmd(vdev, CMD_GET_SUPP_FEATURE_VER, &a0, &a1, wait);
return ret == 0 && (a1 & FEATURE_GENEVE_OPTIONS);
}
+
+uint64_t vnic_dev_capable_cq_entry_size(struct vnic_dev *vdev)
+{
+ uint64_t a0 = CMD_CQ_ENTRY_SIZE_SET;
+ uint64_t a1 = 0;
+ int wait = 1000;
+ int ret;
+
+ ret = vnic_dev_cmd(vdev, CMD_CAPABILITY, &a0, &a1, wait);
+ /* All models support 16B CQ entry by default */
+ if (!(ret == 0 && a0 == 0))
+ a1 = VNIC_RQ_CQ_ENTRY_SIZE_16_CAPABLE;
+ return a1;
+}
+
+int vnic_dev_set_cq_entry_size(struct vnic_dev *vdev, uint32_t rq_idx,
+ uint32_t size_flag)
+{
+ uint64_t a0 = rq_idx;
+ uint64_t a1 = size_flag;
+ int wait = 1000;
+
+ return vnic_dev_cmd(vdev, CMD_CQ_ENTRY_SIZE_SET, &a0, &a1, wait);
+}