Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F152466814
D1641.id3461.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D1641.id3461.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D1641: Implement PCI SR-IOV initialization methods
Attached
Detach File
Event Timeline
Log In to Comment