Page MenuHomeFreeBSD

D1641.id3461.diff
No OneTemporary

D1641.id3461.diff

Index: sys/dev/ixl/if_ixl.c
===================================================================
--- sys/dev/ixl/if_ixl.c
+++ sys/dev/ixl/if_ixl.c
@@ -111,6 +111,7 @@
static void ixl_set_queue_rx_itr(struct ixl_queue *);
static void ixl_set_queue_tx_itr(struct ixl_queue *);
static int ixl_set_advertised_speeds(struct ixl_pf *, int);
+static int ixl_get_seids(struct ixl_pf *pf);
static int ixl_enable_rings(struct ixl_vsi *);
static int ixl_disable_rings(struct ixl_vsi *);
@@ -187,6 +188,13 @@
static int ixl_sysctl_dump_txd(SYSCTL_HANDLER_ARGS);
#endif
+#ifdef PCI_IOV
+static int ixl_adminq_err_to_errno(enum i40e_admin_queue_err err);
+
+static int ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t*);
+static void ixl_uninit_iov(device_t dev);
+#endif
+
/*********************************************************************
* FreeBSD Device Interface Entry Points
*********************************************************************/
@@ -197,6 +205,10 @@
DEVMETHOD(device_attach, ixl_attach),
DEVMETHOD(device_detach, ixl_detach),
DEVMETHOD(device_shutdown, ixl_shutdown),
+#ifdef PCI_IOV
+ DEVMETHOD(pci_init_iov, ixl_init_iov),
+ DEVMETHOD(pci_uninit_iov, ixl_uninit_iov),
+#endif
{0, 0}
};
@@ -283,6 +295,7 @@
TUNABLE_INT("hw.ixl.atr_rate", &ixl_atr_rate);
#endif
+static MALLOC_DEFINE(M_IXL, "ixl", "ixl driver allocations");
static uint8_t ixl_bcast_addr[ETHER_ADDR_LEN] =
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
@@ -658,6 +671,16 @@
goto err_late;
}
+ /*
+ * Fetch the Switch Element IDs (SEIDs) for the physical port and for
+ * the PF's VSI. We'll need these values when enabling SR-IOV.
+ */
+ if (ixl_get_seids(pf) != 0) {
+ device_printf(dev, "Fetching SEIDs failed!\n");
+ error = EIO;
+ goto err_late;
+ }
+
/* Get the bus configuration and set the shared code */
bus = ixl_get_bus_info(hw, dev);
i40e_set_pci_config_data(hw, bus);
@@ -2481,43 +2504,73 @@
return (check);
}
-/*********************************************************************
- *
- * Initialize this VSI
- *
- **********************************************************************/
static int
-ixl_setup_vsi(struct ixl_ifx *ifx)
+ixl_get_seids(struct ixl_pf *pf)
{
- struct i40e_hw *hw = ifx->hw;
- device_t dev = ifx->dev;
+ struct ixl_vsi *vsi;
+ struct i40e_hw *hw;
+ device_t dev;
struct i40e_aqc_get_switch_config_resp *sw_config;
- struct i40e_vsi_context ctxt;
u8 aq_buf[I40E_AQ_LARGE_BUF];
- int ret = I40E_SUCCESS;
+ int ret;
u16 next = 0;
+#ifdef IXL_DEBUG
+ int i;
+#endif
+
+ vsi = &pf->vsi;
+ hw = &pf->hw;
+ dev = pf->dev;
sw_config = (struct i40e_aqc_get_switch_config_resp *)aq_buf;
ret = i40e_aq_get_switch_config(hw, sw_config,
sizeof(aq_buf), &next, NULL);
if (ret) {
- device_printf(dev,"aq_get_switch_config failed!!\n");
+ device_printf(dev,"aq_get_switch_config failed (ret=%d)!!\n",
+ ret);
return (ret);
}
#ifdef IXL_DEBUG
- printf("Switch config: header reported: %d in structure, %d total\n",
+ device_printf(dev, "Switch config: header reported: %d in structure, %d total\n",
sw_config->header.num_reported, sw_config->header.num_total);
- printf("type=%d seid=%d uplink=%d downlink=%d\n",
- sw_config->element[0].element_type,
- sw_config->element[0].seid,
- sw_config->element[0].uplink_seid,
- sw_config->element[0].downlink_seid);
+ for (i = 0; i < sw_config->header.num_reported; i++) {
+ device_printf(dev, "%d: type=%d seid=%d uplink=%d downlink=%d\n", i,
+ sw_config->element[i].element_type,
+ sw_config->element[i].seid,
+ sw_config->element[i].uplink_seid,
+ sw_config->element[i].downlink_seid);
+ }
#endif
/* Save off this important value */
- ifx->vsi.seid = sw_config->element[0].seid;
+ vsi->uplink_seid = sw_config->element[0].uplink_seid;
+ vsi->downlink_seid = sw_config->element[0].downlink_seid;
+ vsi->seid = sw_config->element[0].seid;
+
+ vsi->first_queue = 0;
+
+ return (0);
+}
+
+/*********************************************************************
+ *
+ * Initialize this VSI
+ *
+ **********************************************************************/
+static int
+ixl_setup_vsi(struct ixl_vsi *vsi)
+{
+ struct ixl_pf *pf;
+ struct i40e_hw *hw = vsi->hw;
+ device_t dev = vsi->dev;
+ struct i40e_vsi_context ctxt;
+ int ret = I40E_SUCCESS;
+
+ pf = vsi->back;
memset(&ctxt, 0, sizeof(ctxt));
ctxt.seid = ifx->vsi.seid;
+ if (pf->veb_seid != 0)
+ ctxt.uplink_seid = pf->veb_seid;
ctxt.pf_num = hw->pf_id;
ret = i40e_aq_get_vsi_params(hw, &ctxt, NULL);
if (ret) {
@@ -2559,6 +2612,8 @@
ifx->vsi.hw_filters_add = 0;
ifx->vsi.hw_filters_del = 0;
+ ctxt.flags = htole16(I40E_AQ_VSI_TYPE_PF);
+
ret = i40e_aq_update_vsi_params(hw, &ctxt, NULL);
if (ret)
device_printf(dev,"update vsi params failed %x!!\n",
@@ -5047,3 +5102,127 @@
}
#endif /* IXL_DEBUG_SYSCTL */
+#ifdef PCI_IOV
+static int
+ixl_adminq_err_to_errno(enum i40e_admin_queue_err err)
+{
+
+ switch (err) {
+ case I40E_AQ_RC_EPERM:
+ return (EPERM);
+ case I40E_AQ_RC_ENOENT:
+ return (ENOENT);
+ case I40E_AQ_RC_ESRCH:
+ return (ESRCH);
+ case I40E_AQ_RC_EINTR:
+ return (EINTR);
+ case I40E_AQ_RC_EIO:
+ return (EIO);
+ case I40E_AQ_RC_ENXIO:
+ return (ENXIO);
+ case I40E_AQ_RC_E2BIG:
+ return (E2BIG);
+ case I40E_AQ_RC_EAGAIN:
+ return (EAGAIN);
+ case I40E_AQ_RC_ENOMEM:
+ return (ENOMEM);
+ case I40E_AQ_RC_EACCES:
+ return (EACCES);
+ case I40E_AQ_RC_EFAULT:
+ return (EFAULT);
+ case I40E_AQ_RC_EBUSY:
+ return (EBUSY);
+ case I40E_AQ_RC_EEXIST:
+ return (EEXIST);
+ case I40E_AQ_RC_EINVAL:
+ return (EINVAL);
+ case I40E_AQ_RC_ENOTTY:
+ return (ENOTTY);
+ case I40E_AQ_RC_ENOSPC:
+ return (ENOSPC);
+ case I40E_AQ_RC_ENOSYS:
+ return (ENOSYS);
+ case I40E_AQ_RC_ERANGE:
+ return (ERANGE);
+ case I40E_AQ_RC_EFLUSHED:
+ return (EINVAL); /* No exact equivalent in errno.h */
+ case I40E_AQ_RC_BAD_ADDR:
+ return (EFAULT);
+ case I40E_AQ_RC_EMODE:
+ return (EPERM);
+ case I40E_AQ_RC_EFBIG:
+ return (EFBIG);
+ default:
+ return (EINVAL);
+ }
+}
+
+static int
+ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t *params)
+{
+ struct ixl_pf *pf;
+ struct i40e_hw *hw;
+ struct ixl_vsi *pf_vsi;
+ enum i40e_status_code ret;
+ int error;
+
+ pf = device_get_softc(dev);
+ hw = &pf->hw;
+ pf_vsi = &pf->vsi;
+
+ IXL_PF_LOCK(pf);
+ pf->vfs = malloc(sizeof(struct ixl_vf) * num_vfs, M_IXL, M_NOWAIT |
+ M_ZERO);
+
+ if (pf->vfs == NULL) {
+ error = ENOMEM;
+ goto fail;
+ }
+
+ ret = i40e_aq_add_veb(hw, pf_vsi->uplink_seid, pf_vsi->seid,
+ 1, FALSE, FALSE, &pf->veb_seid, NULL);
+ if (ret != I40E_SUCCESS) {
+ error = ixl_adminq_err_to_errno(hw->aq.asq_last_status);
+ device_printf(dev, "add_veb failed; code=%d error=%d", ret,
+ error);
+ goto fail;
+ }
+
+ pf->num_vfs = num_vfs;
+ IXL_PF_UNLOCK(pf);
+ return (0);
+
+fail:
+ free(pf->vfs, M_IXL);
+ pf->vfs = NULL;
+ IXL_PF_UNLOCK(pf);
+ return (error);
+}
+
+static void
+ixl_uninit_iov(device_t dev)
+{
+ struct ixl_pf *pf;
+ struct i40e_hw *hw;
+ int i;
+
+ pf = device_get_softc(dev);
+ hw = &pf->hw;
+
+ IXL_PF_LOCK(pf);
+ for (i = 0; i < pf->num_vfs; i++) {
+ if (pf->vfs[i].vsi.seid != 0)
+ i40e_aq_delete_element(hw, pf->vfs[i].vsi.seid, NULL);
+ }
+
+ if (pf->veb_seid != 0) {
+ i40e_aq_delete_element(hw, pf->veb_seid, NULL);
+ pf->veb_seid = 0;
+ }
+
+ free(pf->vfs, M_IXL);
+ pf->vfs = NULL;
+ pf->num_vfs = 0;
+ IXL_PF_UNLOCK(pf);
+}
+#endif /* PCI_IOV */
Index: sys/dev/ixl/ixl.h
===================================================================
--- sys/dev/ixl/ixl.h
+++ sys/dev/ixl/ixl.h
@@ -46,6 +46,7 @@
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/module.h>
+#include <sys/nv.h>
#include <sys/sockio.h>
#include <sys/eventhandler.h>
Index: sys/dev/ixl/ixl_pf.h
===================================================================
--- sys/dev/ixl/ixl_pf.h
+++ sys/dev/ixl/ixl_pf.h
@@ -36,6 +36,12 @@
#ifndef _IXL_PF_H_
#define _IXL_PF_H_
+#define VF_FLAG_ENABLED 0x01
+
+struct ixl_vf {
+ uint16_t vf_num;
+};
+
/* Physical controller structure */
struct ixl_pf {
struct i40e_hw hw;
@@ -84,6 +90,11 @@
struct i40e_hw_port_stats stats;
struct i40e_hw_port_stats stats_offsets;
bool stat_offsets_loaded;
+
+ struct ixl_vf *vfs;
+ int num_vfs;
+
+ uint16_t veb_seid;
};

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 16, 3:38 AM (5 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31527232
Default Alt Text
D1641.id3461.diff (8 KB)

Event Timeline