Changeset View
Changeset View
Standalone View
Standalone View
stable/10/sys/dev/ixl/if_ixlv.c
Show First 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | |||||
#ifdef RSS | #ifdef RSS | ||||
#include <net/rss_config.h> | #include <net/rss_config.h> | ||||
#endif | #endif | ||||
/********************************************************************* | /********************************************************************* | ||||
* Driver version | * Driver version | ||||
*********************************************************************/ | *********************************************************************/ | ||||
char ixlv_driver_version[] = "1.2.6"; | char ixlv_driver_version[] = "1.2.11-k"; | ||||
/********************************************************************* | /********************************************************************* | ||||
* PCI Device ID Table | * PCI Device ID Table | ||||
* | * | ||||
* Used by probe to select devices to load on | * Used by probe to select devices to load on | ||||
* Last field stores an index into ixlv_strings | * Last field stores an index into ixlv_strings | ||||
* Last entry must be all 0s | * Last entry must be all 0s | ||||
* | * | ||||
▲ Show 20 Lines • Show All 175 Lines • ▼ Show 20 Lines | |||||
ixlv_probe(device_t dev) | ixlv_probe(device_t dev) | ||||
{ | { | ||||
ixl_vendor_info_t *ent; | ixl_vendor_info_t *ent; | ||||
u16 pci_vendor_id, pci_device_id; | u16 pci_vendor_id, pci_device_id; | ||||
u16 pci_subvendor_id, pci_subdevice_id; | u16 pci_subvendor_id, pci_subdevice_id; | ||||
char device_name[256]; | char device_name[256]; | ||||
#if 0 | |||||
INIT_DEBUGOUT("ixlv_probe: begin"); | INIT_DEBUGOUT("ixlv_probe: begin"); | ||||
#endif | |||||
pci_vendor_id = pci_get_vendor(dev); | pci_vendor_id = pci_get_vendor(dev); | ||||
if (pci_vendor_id != I40E_INTEL_VENDOR_ID) | if (pci_vendor_id != I40E_INTEL_VENDOR_ID) | ||||
return (ENXIO); | return (ENXIO); | ||||
pci_device_id = pci_get_device(dev); | pci_device_id = pci_get_device(dev); | ||||
pci_subvendor_id = pci_get_subvendor(dev); | pci_subvendor_id = pci_get_subvendor(dev); | ||||
pci_subdevice_id = pci_get_subdevice(dev); | pci_subdevice_id = pci_get_subdevice(dev); | ||||
▲ Show 20 Lines • Show All 89 Lines • ▼ Show 20 Lines | ixlv_attach(device_t dev) | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "%s: Error setting up PF comms, %d\n", | device_printf(dev, "%s: Error setting up PF comms, %d\n", | ||||
__func__, error); | __func__, error); | ||||
goto err_pci_res; | goto err_pci_res; | ||||
} | } | ||||
INIT_DBG_DEV(dev, "PF API version verified"); | INIT_DBG_DEV(dev, "PF API version verified"); | ||||
/* TODO: Figure out why MDD events occur when this reset is removed. */ | |||||
/* Need API version before sending reset message */ | /* Need API version before sending reset message */ | ||||
error = ixlv_reset(sc); | error = ixlv_reset(sc); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "VF reset failed; reload the driver\n"); | device_printf(dev, "VF reset failed; reload the driver\n"); | ||||
goto err_aq; | goto err_aq; | ||||
} | } | ||||
INIT_DBG_DEV(dev, "VF reset complete"); | INIT_DBG_DEV(dev, "VF reset complete"); | ||||
Show All 10 Lines | ixlv_attach(device_t dev) | ||||
INIT_DBG_DEV(dev, "VSIs %d, Queues %d, Max Vectors %d, Max MTU %d", | INIT_DBG_DEV(dev, "VSIs %d, Queues %d, Max Vectors %d, Max MTU %d", | ||||
sc->vf_res->num_vsis, | sc->vf_res->num_vsis, | ||||
sc->vf_res->num_queue_pairs, | sc->vf_res->num_queue_pairs, | ||||
sc->vf_res->max_vectors, | sc->vf_res->max_vectors, | ||||
sc->vf_res->max_mtu); | sc->vf_res->max_mtu); | ||||
INIT_DBG_DEV(dev, "Offload flags: %#010x", | INIT_DBG_DEV(dev, "Offload flags: %#010x", | ||||
sc->vf_res->vf_offload_flags); | sc->vf_res->vf_offload_flags); | ||||
// TODO: Move this into ixlv_vf_config? | |||||
/* got VF config message back from PF, now we can parse it */ | /* got VF config message back from PF, now we can parse it */ | ||||
for (int i = 0; i < sc->vf_res->num_vsis; i++) { | for (int i = 0; i < sc->vf_res->num_vsis; i++) { | ||||
if (sc->vf_res->vsi_res[i].vsi_type == I40E_VSI_SRIOV) | if (sc->vf_res->vsi_res[i].vsi_type == I40E_VSI_SRIOV) | ||||
sc->vsi_res = &sc->vf_res->vsi_res[i]; | sc->vsi_res = &sc->vf_res->vsi_res[i]; | ||||
} | } | ||||
if (!sc->vsi_res) { | if (!sc->vsi_res) { | ||||
device_printf(dev, "%s: no LAN VSI found\n", __func__); | device_printf(dev, "%s: no LAN VSI found\n", __func__); | ||||
error = EIO; | error = EIO; | ||||
▲ Show 20 Lines • Show All 280 Lines • ▼ Show 20 Lines | #endif | ||||
case SIOCSIFMTU: | case SIOCSIFMTU: | ||||
IOCTL_DBG_IF2(ifp, "SIOCSIFMTU (Set Interface MTU)"); | IOCTL_DBG_IF2(ifp, "SIOCSIFMTU (Set Interface MTU)"); | ||||
mtx_lock(&sc->mtx); | mtx_lock(&sc->mtx); | ||||
if (ifr->ifr_mtu > IXL_MAX_FRAME - | if (ifr->ifr_mtu > IXL_MAX_FRAME - | ||||
ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN) { | ETHER_HDR_LEN - ETHER_CRC_LEN - ETHER_VLAN_ENCAP_LEN) { | ||||
error = EINVAL; | error = EINVAL; | ||||
IOCTL_DBG_IF(ifp, "mtu too large"); | IOCTL_DBG_IF(ifp, "mtu too large"); | ||||
} else { | } else { | ||||
IOCTL_DBG_IF2(ifp, "mtu: %lu -> %d", ifp->if_mtu, ifr->ifr_mtu); | IOCTL_DBG_IF2(ifp, "mtu: %lu -> %d", (u_long)ifp->if_mtu, ifr->ifr_mtu); | ||||
// ERJ: Interestingly enough, these types don't match | // ERJ: Interestingly enough, these types don't match | ||||
ifp->if_mtu = (u_long)ifr->ifr_mtu; | ifp->if_mtu = (u_long)ifr->ifr_mtu; | ||||
vsi->max_frame_size = | vsi->max_frame_size = | ||||
ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN | ifp->if_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN | ||||
+ ETHER_VLAN_ENCAP_LEN; | + ETHER_VLAN_ENCAP_LEN; | ||||
if (ifp->if_drv_flags & IFF_DRV_RUNNING) | if (ifp->if_drv_flags & IFF_DRV_RUNNING) | ||||
ixlv_init_locked(sc); | ixlv_init_locked(sc); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 255 Lines • ▼ Show 20 Lines | ixlv_init(void *arg) | ||||
int retries = 0; | int retries = 0; | ||||
mtx_lock(&sc->mtx); | mtx_lock(&sc->mtx); | ||||
ixlv_init_locked(sc); | ixlv_init_locked(sc); | ||||
mtx_unlock(&sc->mtx); | mtx_unlock(&sc->mtx); | ||||
/* Wait for init_locked to finish */ | /* Wait for init_locked to finish */ | ||||
while (!(vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) | while (!(vsi->ifp->if_drv_flags & IFF_DRV_RUNNING) | ||||
&& ++retries < 100) { | && ++retries < IXLV_AQ_MAX_ERR) { | ||||
i40e_msec_delay(10); | i40e_msec_delay(25); | ||||
} | } | ||||
if (retries >= IXLV_AQ_MAX_ERR) | if (retries >= IXLV_AQ_MAX_ERR) | ||||
if_printf(vsi->ifp, | if_printf(vsi->ifp, | ||||
"Init failed to complete in alloted time!\n"); | "Init failed to complete in allotted time!\n"); | ||||
} | } | ||||
/* | /* | ||||
* ixlv_attach() helper function; gathers information about | * ixlv_attach() helper function; gathers information about | ||||
* the (virtual) hardware for use elsewhere in the driver. | * the (virtual) hardware for use elsewhere in the driver. | ||||
*/ | */ | ||||
static void | static void | ||||
ixlv_init_hw(struct ixlv_sc *sc) | ixlv_init_hw(struct ixlv_sc *sc) | ||||
Show All 39 Lines | for (int i = 0; i < IXLV_AQ_MAX_ERR; i++) { | ||||
error = i40e_init_adminq(hw); | error = i40e_init_adminq(hw); | ||||
if (error) { | if (error) { | ||||
device_printf(dev, "%s: init_adminq failed: %d\n", | device_printf(dev, "%s: init_adminq failed: %d\n", | ||||
__func__, error); | __func__, error); | ||||
ret_error = 1; | ret_error = 1; | ||||
continue; | continue; | ||||
} | } | ||||
INIT_DBG_DEV(dev, "Initialized Admin Queue, attempt %d", i+1); | INIT_DBG_DEV(dev, "Initialized Admin Queue; starting" | ||||
" send_api_ver attempt %d", i+1); | |||||
retry_send: | retry_send: | ||||
/* Send VF's API version */ | /* Send VF's API version */ | ||||
error = ixlv_send_api_ver(sc); | error = ixlv_send_api_ver(sc); | ||||
if (error) { | if (error) { | ||||
i40e_shutdown_adminq(hw); | i40e_shutdown_adminq(hw); | ||||
ret_error = 2; | ret_error = 2; | ||||
device_printf(dev, "%s: unable to send api" | device_printf(dev, "%s: unable to send api" | ||||
▲ Show 20 Lines • Show All 102 Lines • ▼ Show 20 Lines | retry_config: | ||||
/* Check for VF config response */ | /* Check for VF config response */ | ||||
error = ixlv_get_vf_config(sc); | error = ixlv_get_vf_config(sc); | ||||
if (error == ETIMEDOUT) { | if (error == ETIMEDOUT) { | ||||
/* The 1st time we timeout, send the configuration message again */ | /* The 1st time we timeout, send the configuration message again */ | ||||
if (!retried) { | if (!retried) { | ||||
retried++; | retried++; | ||||
goto retry_config; | goto retry_config; | ||||
} | } | ||||
device_printf(dev, | |||||
"%s: ixlv_get_vf_config() timed out waiting for a response\n", | |||||
__func__); | |||||
} | } | ||||
if (error) { | if (error) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"%s: Unable to get VF configuration from PF after %d tries!\n", | "%s: Unable to get VF configuration from PF after %d tries!\n", | ||||
__func__, retried + 1); | __func__, retried + 1); | ||||
ret_error = 4; | ret_error = 4; | ||||
} | } | ||||
goto done; | goto done; | ||||
▲ Show 20 Lines • Show All 1,453 Lines • ▼ Show 20 Lines | set_hena = | ||||
((u64)1 << I40E_FILTER_PCTYPE_L2_PAYLOAD); | ((u64)1 << I40E_FILTER_PCTYPE_L2_PAYLOAD); | ||||
#endif | #endif | ||||
hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) | | hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) | | ||||
((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32); | ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32); | ||||
hena |= set_hena; | hena |= set_hena; | ||||
wr32(hw, I40E_VFQF_HENA(0), (u32)hena); | wr32(hw, I40E_VFQF_HENA(0), (u32)hena); | ||||
wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32)); | wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32)); | ||||
// TODO: Fix -- only 3,7,11,15 are filled out, instead of all 16 registers | |||||
/* Populate the LUT with max no. of queues in round robin fashion */ | /* Populate the LUT with max no. of queues in round robin fashion */ | ||||
for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++, j++) { | for (i = 0, j = 0; i <= I40E_VFQF_HLUT_MAX_INDEX; i++, j++) { | ||||
if (j == vsi->num_queues) | if (j == vsi->num_queues) | ||||
j = 0; | j = 0; | ||||
#ifdef RSS | #ifdef RSS | ||||
/* | /* | ||||
* Fetch the RSS bucket id for the given indirection entry. | * Fetch the RSS bucket id for the given indirection entry. | ||||
* Cap it at the number of configured buckets (which is | * Cap it at the number of configured buckets (which is | ||||
▲ Show 20 Lines • Show All 222 Lines • ▼ Show 20 Lines | struct ixl_sysctl_info ctls[] = | ||||
"Multicast Packets Transmitted"}, | "Multicast Packets Transmitted"}, | ||||
{&es->tx_broadcast, "bcast_pkts_txd", | {&es->tx_broadcast, "bcast_pkts_txd", | ||||
"Broadcast Packets Transmitted"}, | "Broadcast Packets Transmitted"}, | ||||
{&es->tx_errors, "tx_errors", "TX packet errors"}, | {&es->tx_errors, "tx_errors", "TX packet errors"}, | ||||
// end | // end | ||||
{0,0,0} | {0,0,0} | ||||
}; | }; | ||||
struct ixl_sysctl_info *entry = ctls; | struct ixl_sysctl_info *entry = ctls; | ||||
while (entry->stat != 0) | while (entry->stat != NULL) | ||||
{ | { | ||||
SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, entry->name, | SYSCTL_ADD_QUAD(ctx, child, OID_AUTO, entry->name, | ||||
CTLFLAG_RD, entry->stat, | CTLFLAG_RD, entry->stat, | ||||
entry->description); | entry->description); | ||||
entry++; | entry++; | ||||
} | } | ||||
/* Queue sysctls */ | /* Queue sysctls */ | ||||
▲ Show 20 Lines • Show All 129 Lines • Show Last 20 Lines |