aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ixl/ixlvc.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ixl/ixlvc.c')
-rw-r--r--sys/dev/ixl/ixlvc.c150
1 files changed, 128 insertions, 22 deletions
diff --git a/sys/dev/ixl/ixlvc.c b/sys/dev/ixl/ixlvc.c
index 6a367eab3a6d..155f0ab46ae6 100644
--- a/sys/dev/ixl/ixlvc.c
+++ b/sys/dev/ixl/ixlvc.c
@@ -69,8 +69,10 @@ static int ixl_vc_validate_vf_msg(struct ixlv_sc *sc, u32 v_opcode,
valid_len = sizeof(struct i40e_virtchnl_version_info);
break;
case I40E_VIRTCHNL_OP_RESET_VF:
+ valid_len = 0;
+ break;
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES:
- // TODO: valid length in api v1.0 is 0, v1.1 is 4
+ /* Valid length in api v1.0 is 0, v1.1 is 4 */
valid_len = 4;
break;
case I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE:
@@ -218,7 +220,7 @@ ixlv_verify_api_ver(struct ixlv_sc *sc)
i40e_status err;
int retries = 0;
- event.buf_len = IXL_AQ_BUFSZ;
+ event.buf_len = IXL_AQ_BUF_SZ;
event.msg_buf = malloc(event.buf_len, M_DEVBUF, M_NOWAIT);
if (!event.msg_buf) {
err = ENOMEM;
@@ -230,7 +232,7 @@ ixlv_verify_api_ver(struct ixlv_sc *sc)
goto out_alloc;
/* Initial delay here is necessary */
- i40e_msec_delay(100);
+ i40e_msec_pause(100);
err = i40e_clean_arq_element(hw, &event, NULL);
if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK)
continue;
@@ -288,7 +290,7 @@ ixlv_send_vf_config_msg(struct ixlv_sc *sc)
u32 caps;
caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 |
- I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
+ I40E_VIRTCHNL_VF_OFFLOAD_RSS_PF |
I40E_VIRTCHNL_VF_OFFLOAD_VLAN;
if (sc->pf_version == I40E_VIRTCHNL_VERSION_MINOR_NO_VF_CAPS)
@@ -331,7 +333,7 @@ ixlv_get_vf_config(struct ixlv_sc *sc)
err = i40e_clean_arq_element(hw, &event, NULL);
if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) {
if (++retries <= IXLV_AQ_MAX_ERR)
- i40e_msec_delay(10);
+ i40e_msec_pause(10);
} else if ((enum i40e_virtchnl_ops)le32toh(event.desc.cookie_high) !=
I40E_VIRTCHNL_OP_GET_VF_RESOURCES) {
DDPRINTF(dev, "Received a response from PF,"
@@ -498,7 +500,7 @@ ixlv_map_queues(struct ixlv_sc *sc)
vm->vecmap[i].txq_map = (1 << que->me);
vm->vecmap[i].rxq_map = (1 << que->me);
vm->vecmap[i].rxitr_idx = 0;
- vm->vecmap[i].txitr_idx = 0;
+ vm->vecmap[i].txitr_idx = 1;
}
/* Misc vector last - this is only for AdminQ messages */
@@ -570,13 +572,6 @@ ixlv_add_vlans(struct ixlv_sc *sc)
if (i == cnt)
break;
}
- // ERJ: Should this be taken out?
- if (i == 0) { /* Should not happen... */
- device_printf(dev, "%s: i == 0?\n", __func__);
- ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_ADD_VLAN_FILTER,
- I40E_SUCCESS);
- return;
- }
ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_ADD_VLAN, (u8 *)v, len);
free(v, M_DEVBUF);
@@ -640,13 +635,6 @@ ixlv_del_vlans(struct ixlv_sc *sc)
if (i == cnt)
break;
}
- // ERJ: Take this out?
- if (i == 0) { /* Should not happen... */
- device_printf(dev, "%s: i == 0?\n", __func__);
- ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_DEL_VLAN_FILTER,
- I40E_SUCCESS);
- return;
- }
ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_DEL_VLAN, (u8 *)v, len);
free(v, M_DEVBUF);
@@ -842,6 +830,100 @@ ixlv_update_stats_counters(struct ixlv_sc *sc, struct i40e_eth_stats *es)
vsi->eth_stats = *es;
}
+void
+ixlv_config_rss_key(struct ixlv_sc *sc)
+{
+ struct i40e_virtchnl_rss_key *rss_key_msg;
+ int msg_len, key_length;
+ u8 rss_seed[IXL_RSS_KEY_SIZE];
+#ifdef RSS
+ u32 rss_hash_config;
+#endif
+
+#ifdef RSS
+ /* Fetch the configured RSS key */
+ rss_getkey(&rss_seed);
+#else
+ ixl_get_default_rss_key((u32 *)rss_seed);
+#endif
+
+ /* Send the fetched key */
+ key_length = IXL_RSS_KEY_SIZE;
+ msg_len = sizeof(struct i40e_virtchnl_rss_key) + (sizeof(u8) * key_length) - 1;
+ rss_key_msg = malloc(msg_len, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (rss_key_msg == NULL) {
+ device_printf(sc->dev, "Unable to allocate msg memory for RSS key msg.\n");
+ return;
+ }
+
+ rss_key_msg->vsi_id = sc->vsi_res->vsi_id;
+ rss_key_msg->key_len = key_length;
+ bcopy(rss_seed, &rss_key_msg->key[0], key_length);
+
+ DDPRINTF(sc->dev, "config_rss: vsi_id %d, key_len %d",
+ rss_key_msg->vsi_id, rss_key_msg->key_len);
+
+ ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_CONFIG_RSS_KEY,
+ (u8 *)rss_key_msg, msg_len);
+
+ free(rss_key_msg, M_DEVBUF);
+}
+
+void
+ixlv_set_rss_hena(struct ixlv_sc *sc)
+{
+ struct i40e_virtchnl_rss_hena hena;
+
+ hena.hena = IXL_DEFAULT_RSS_HENA;
+
+ ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_SET_RSS_HENA,
+ (u8 *)&hena, sizeof(hena));
+}
+
+void
+ixlv_config_rss_lut(struct ixlv_sc *sc)
+{
+ struct i40e_virtchnl_rss_lut *rss_lut_msg;
+ int msg_len;
+ u16 lut_length;
+ u32 lut;
+ int i, que_id;
+
+ lut_length = IXL_RSS_VSI_LUT_SIZE;
+ msg_len = sizeof(struct i40e_virtchnl_rss_lut) + (lut_length * sizeof(u8)) - 1;
+ rss_lut_msg = malloc(msg_len, M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (rss_lut_msg == NULL) {
+ device_printf(sc->dev, "Unable to allocate msg memory for RSS lut msg.\n");
+ return;
+ }
+
+ rss_lut_msg->vsi_id = sc->vsi_res->vsi_id;
+ /* Each LUT entry is a max of 1 byte, so this is easy */
+ rss_lut_msg->lut_entries = lut_length;
+
+ /* Populate the LUT with max no. of queues in round robin fashion */
+ for (i = 0; i < lut_length; i++) {
+#ifdef RSS
+ /*
+ * Fetch the RSS bucket id for the given indirection entry.
+ * Cap it at the number of configured buckets (which is
+ * num_queues.)
+ */
+ que_id = rss_get_indirection_to_bucket(i);
+ que_id = que_id % sc->vsi.num_queues;
+#else
+ que_id = i % sc->vsi.num_queues;
+#endif
+ lut = que_id & IXL_RSS_VSI_LUT_ENTRY_MASK;
+ rss_lut_msg->lut[i] = lut;
+ }
+
+ ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_CONFIG_RSS_LUT,
+ (u8 *)rss_lut_msg, msg_len);
+
+ free(rss_lut_msg, M_DEVBUF);
+}
+
/*
** ixlv_vc_completion
**
@@ -940,7 +1022,7 @@ ixlv_vc_completion(struct ixlv_sc *sc,
ixlv_enable_intr(vsi);
/* And inform the stack we're ready */
vsi->ifp->if_drv_flags |= IFF_DRV_RUNNING;
- vsi->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+ /* TODO: Clear a state flag, so we know we're ready to run init again */
}
break;
case I40E_VIRTCHNL_OP_DISABLE_QUEUES:
@@ -950,7 +1032,7 @@ ixlv_vc_completion(struct ixlv_sc *sc,
/* Turn off all interrupts */
ixlv_disable_intr(vsi);
/* Tell the stack that the interface is no longer active */
- vsi->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+ vsi->ifp->if_drv_flags &= ~(IFF_DRV_RUNNING);
}
break;
case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES:
@@ -961,6 +1043,18 @@ ixlv_vc_completion(struct ixlv_sc *sc,
ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_MAP_VECTORS,
v_retval);
break;
+ case I40E_VIRTCHNL_OP_CONFIG_RSS_KEY:
+ ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_CONFIG_RSS_KEY,
+ v_retval);
+ break;
+ case I40E_VIRTCHNL_OP_SET_RSS_HENA:
+ ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_SET_RSS_HENA,
+ v_retval);
+ break;
+ case I40E_VIRTCHNL_OP_CONFIG_RSS_LUT:
+ ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_CONFIG_RSS_LUT,
+ v_retval);
+ break;
default:
#ifdef IXL_DEBUG
device_printf(dev,
@@ -1008,6 +1102,18 @@ ixl_vc_send_cmd(struct ixlv_sc *sc, uint32_t request)
case IXLV_FLAG_AQ_ENABLE_QUEUES:
ixlv_enable_queues(sc);
break;
+
+ case IXLV_FLAG_AQ_CONFIG_RSS_KEY:
+ ixlv_config_rss_key(sc);
+ break;
+
+ case IXLV_FLAG_AQ_SET_RSS_HENA:
+ ixlv_set_rss_hena(sc);
+ break;
+
+ case IXLV_FLAG_AQ_CONFIG_RSS_LUT:
+ ixlv_config_rss_lut(sc);
+ break;
}
}