Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/ixlvc.c
Show First 20 Lines • Show All 64 Lines • ▼ Show 20 Lines | static int ixl_vc_validate_vf_msg(struct ixlv_sc *sc, u32 v_opcode, | ||||
/* Validate message length. */ | /* Validate message length. */ | ||||
switch (v_opcode) { | switch (v_opcode) { | ||||
case I40E_VIRTCHNL_OP_VERSION: | case I40E_VIRTCHNL_OP_VERSION: | ||||
valid_len = sizeof(struct i40e_virtchnl_version_info); | valid_len = sizeof(struct i40e_virtchnl_version_info); | ||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_RESET_VF: | case I40E_VIRTCHNL_OP_RESET_VF: | ||||
case I40E_VIRTCHNL_OP_GET_VF_RESOURCES: | case I40E_VIRTCHNL_OP_GET_VF_RESOURCES: | ||||
valid_len = 0; | // TODO: valid length in api v1.0 is 0, v1.1 is 4 | ||||
valid_len = 4; | |||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE: | case I40E_VIRTCHNL_OP_CONFIG_TX_QUEUE: | ||||
valid_len = sizeof(struct i40e_virtchnl_txq_info); | valid_len = sizeof(struct i40e_virtchnl_txq_info); | ||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_CONFIG_RX_QUEUE: | case I40E_VIRTCHNL_OP_CONFIG_RX_QUEUE: | ||||
valid_len = sizeof(struct i40e_virtchnl_rxq_info); | valid_len = sizeof(struct i40e_virtchnl_rxq_info); | ||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: | case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: | ||||
▲ Show 20 Lines • Show All 126 Lines • ▼ Show 20 Lines | |||||
** they do not, or I40E_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty. | ** they do not, or I40E_ERR_ADMIN_QUEUE_NO_WORK if the admin queue is empty. | ||||
*/ | */ | ||||
int | int | ||||
ixlv_verify_api_ver(struct ixlv_sc *sc) | ixlv_verify_api_ver(struct ixlv_sc *sc) | ||||
{ | { | ||||
struct i40e_virtchnl_version_info *pf_vvi; | struct i40e_virtchnl_version_info *pf_vvi; | ||||
struct i40e_hw *hw = &sc->hw; | struct i40e_hw *hw = &sc->hw; | ||||
struct i40e_arq_event_info event; | struct i40e_arq_event_info event; | ||||
device_t dev = sc->dev; | |||||
i40e_status err; | i40e_status err; | ||||
int retries = 0; | int retries = 0; | ||||
event.buf_len = IXL_AQ_BUFSZ; | event.buf_len = IXL_AQ_BUFSZ; | ||||
event.msg_buf = malloc(event.buf_len, M_DEVBUF, M_NOWAIT); | event.msg_buf = malloc(event.buf_len, M_DEVBUF, M_NOWAIT); | ||||
if (!event.msg_buf) { | if (!event.msg_buf) { | ||||
err = ENOMEM; | err = ENOMEM; | ||||
goto out; | goto out; | ||||
} | } | ||||
do { | for (;;) { | ||||
if (++retries > IXLV_AQ_MAX_ERR) | if (++retries > IXLV_AQ_MAX_ERR) | ||||
goto out_alloc; | goto out_alloc; | ||||
/* NOTE: initial delay is necessary */ | /* Initial delay here is necessary */ | ||||
i40e_msec_delay(100); | i40e_msec_delay(100); | ||||
err = i40e_clean_arq_element(hw, &event, NULL); | err = i40e_clean_arq_element(hw, &event, NULL); | ||||
} while (err == I40E_ERR_ADMIN_QUEUE_NO_WORK); | if (err == I40E_ERR_ADMIN_QUEUE_NO_WORK) | ||||
if (err) | continue; | ||||
goto out_alloc; | else if (err) { | ||||
err = (i40e_status)le32toh(event.desc.cookie_low); | |||||
if (err) { | |||||
err = EIO; | err = EIO; | ||||
goto out_alloc; | goto out_alloc; | ||||
} | } | ||||
if ((enum i40e_virtchnl_ops)le32toh(event.desc.cookie_high) != | if ((enum i40e_virtchnl_ops)le32toh(event.desc.cookie_high) != | ||||
I40E_VIRTCHNL_OP_VERSION) { | I40E_VIRTCHNL_OP_VERSION) { | ||||
DDPRINTF(sc->dev, "Received unexpected op response: %d\n", | DDPRINTF(dev, "Received unexpected op response: %d\n", | ||||
le32toh(event.desc.cookie_high)); | le32toh(event.desc.cookie_high)); | ||||
/* Don't stop looking for expected response */ | |||||
continue; | |||||
} | |||||
err = (i40e_status)le32toh(event.desc.cookie_low); | |||||
if (err) { | |||||
err = EIO; | err = EIO; | ||||
goto out_alloc; | goto out_alloc; | ||||
} else | |||||
break; | |||||
} | } | ||||
pf_vvi = (struct i40e_virtchnl_version_info *)event.msg_buf; | pf_vvi = (struct i40e_virtchnl_version_info *)event.msg_buf; | ||||
if ((pf_vvi->major > I40E_VIRTCHNL_VERSION_MAJOR) || | if ((pf_vvi->major > I40E_VIRTCHNL_VERSION_MAJOR) || | ||||
((pf_vvi->major == I40E_VIRTCHNL_VERSION_MAJOR) && | ((pf_vvi->major == I40E_VIRTCHNL_VERSION_MAJOR) && | ||||
(pf_vvi->minor > I40E_VIRTCHNL_VERSION_MINOR))) | (pf_vvi->minor > I40E_VIRTCHNL_VERSION_MINOR))) { | ||||
device_printf(dev, "Critical PF/VF API version mismatch!\n"); | |||||
err = EIO; | err = EIO; | ||||
else | } else | ||||
sc->pf_version = pf_vvi->minor; | sc->pf_version = pf_vvi->minor; | ||||
/* Log PF/VF api versions */ | |||||
device_printf(dev, "PF API %d.%d / VF API %d.%d\n", | |||||
pf_vvi->major, pf_vvi->minor, | |||||
I40E_VIRTCHNL_VERSION_MAJOR, I40E_VIRTCHNL_VERSION_MINOR); | |||||
out_alloc: | out_alloc: | ||||
free(event.msg_buf, M_DEVBUF); | free(event.msg_buf, M_DEVBUF); | ||||
out: | out: | ||||
return err; | return (err); | ||||
} | } | ||||
/* | /* | ||||
** ixlv_send_vf_config_msg | ** ixlv_send_vf_config_msg | ||||
** | ** | ||||
** Send VF configuration request admin queue message to the PF. The reply | ** Send VF configuration request admin queue message to the PF. The reply | ||||
** is not checked in this function. Returns 0 if the message was | ** is not checked in this function. Returns 0 if the message was | ||||
** successfully sent, or one of the I40E_ADMIN_QUEUE_ERROR_ statuses if not. | ** successfully sent, or one of the I40E_ADMIN_QUEUE_ERROR_ statuses if not. | ||||
*/ | */ | ||||
int | int | ||||
ixlv_send_vf_config_msg(struct ixlv_sc *sc) | ixlv_send_vf_config_msg(struct ixlv_sc *sc) | ||||
{ | { | ||||
u32 caps; | u32 caps; | ||||
caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 | | caps = I40E_VIRTCHNL_VF_OFFLOAD_L2 | | ||||
I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ | | |||||
I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG | | I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG | | ||||
I40E_VIRTCHNL_VF_OFFLOAD_VLAN; | I40E_VIRTCHNL_VF_OFFLOAD_VLAN; | ||||
if (sc->pf_version) | if (sc->pf_version == I40E_VIRTCHNL_VERSION_MINOR_NO_VF_CAPS) | ||||
return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES, | return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES, | ||||
(u8 *)&caps, sizeof(caps)); | NULL, 0); | ||||
else | else | ||||
return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES, | return ixlv_send_pf_msg(sc, I40E_VIRTCHNL_OP_GET_VF_RESOURCES, | ||||
NULL, 0); | (u8 *)&caps, sizeof(caps)); | ||||
} | } | ||||
/* | /* | ||||
** ixlv_get_vf_config | ** ixlv_get_vf_config | ||||
** | ** | ||||
** Get VF configuration from PF and populate hw structure. Must be called after | ** Get VF configuration from PF and populate hw structure. Must be called after | ||||
** admin queue is initialized. Busy waits until response is received from PF, | ** admin queue is initialized. Busy waits until response is received from PF, | ||||
** with maximum timeout. Response from PF is returned in the buffer for further | ** with maximum timeout. Response from PF is returned in the buffer for further | ||||
▲ Show 20 Lines • Show All 564 Lines • ▼ Show 20 Lines | #endif | ||||
vpe->event_data.link_event.link_status; | vpe->event_data.link_event.link_status; | ||||
sc->link_speed = | sc->link_speed = | ||||
vpe->event_data.link_event.link_speed; | vpe->event_data.link_event.link_speed; | ||||
ixlv_update_link_status(sc); | ixlv_update_link_status(sc); | ||||
break; | break; | ||||
case I40E_VIRTCHNL_EVENT_RESET_IMPENDING: | case I40E_VIRTCHNL_EVENT_RESET_IMPENDING: | ||||
device_printf(dev, "PF initiated reset!\n"); | device_printf(dev, "PF initiated reset!\n"); | ||||
sc->init_state = IXLV_RESET_PENDING; | sc->init_state = IXLV_RESET_PENDING; | ||||
ixlv_init(sc); | mtx_unlock(&sc->mtx); | ||||
ixlv_init(vsi); | |||||
mtx_lock(&sc->mtx); | |||||
break; | break; | ||||
default: | default: | ||||
device_printf(dev, "%s: Unknown event %d from AQ\n", | device_printf(dev, "%s: Unknown event %d from AQ\n", | ||||
__func__, vpe->event); | __func__, vpe->event); | ||||
break; | break; | ||||
} | } | ||||
return; | return; | ||||
▲ Show 20 Lines • Show All 66 Lines • ▼ Show 20 Lines | case I40E_VIRTCHNL_OP_CONFIG_VSI_QUEUES: | ||||
ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_CONFIGURE_QUEUES, | ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_CONFIGURE_QUEUES, | ||||
v_retval); | v_retval); | ||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP: | case I40E_VIRTCHNL_OP_CONFIG_IRQ_MAP: | ||||
ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_MAP_VECTORS, | ixl_vc_process_resp(&sc->vc_mgr, IXLV_FLAG_AQ_MAP_VECTORS, | ||||
v_retval); | v_retval); | ||||
break; | break; | ||||
default: | default: | ||||
#ifdef IXL_DEBUG | |||||
device_printf(dev, | device_printf(dev, | ||||
"%s: Received unexpected message %d from PF.\n", | "%s: Received unexpected message %d from PF.\n", | ||||
__func__, v_opcode); | __func__, v_opcode); | ||||
#endif | |||||
break; | break; | ||||
} | } | ||||
return; | return; | ||||
} | } | ||||
static void | static void | ||||
ixl_vc_send_cmd(struct ixlv_sc *sc, uint32_t request) | ixl_vc_send_cmd(struct ixlv_sc *sc, uint32_t request) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 172 Lines • Show Last 20 Lines |