Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ixl/if_ixl.c
Show First 20 Lines • Show All 192 Lines • ▼ Show 20 Lines | |||||
static int ixl_adminq_err_to_errno(enum i40e_admin_queue_err err); | 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 int ixl_init_iov(device_t dev, uint16_t num_vfs, const nvlist_t*); | ||||
static void ixl_uninit_iov(device_t dev); | static void ixl_uninit_iov(device_t dev); | ||||
static int ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t*); | static int ixl_add_vf(device_t dev, uint16_t vfnum, const nvlist_t*); | ||||
static void ixl_handle_vf_msg(struct ixl_pf *, | static void ixl_handle_vf_msg(struct ixl_pf *, | ||||
struct i40e_arq_event_info *); | struct i40e_arq_event_info *); | ||||
static void ixl_handle_vflr(void *arg, int pending); | |||||
static void ixl_reset_vf(struct ixl_pf *pf, struct ixl_vf *vf); | static void ixl_reset_vf(struct ixl_pf *pf, struct ixl_vf *vf); | ||||
static void ixl_reinit_vf(struct ixl_pf *pf, struct ixl_vf *vf); | static void ixl_reinit_vf(struct ixl_pf *pf, struct ixl_vf *vf); | ||||
#endif | #endif | ||||
/********************************************************************* | /********************************************************************* | ||||
* FreeBSD Device Interface Entry Points | * FreeBSD Device Interface Entry Points | ||||
*********************************************************************/ | *********************************************************************/ | ||||
▲ Show 20 Lines • Show All 1,075 Lines • ▼ Show 20 Lines | ixl_intr(void *arg) | ||||
icr0 = rd32(hw, I40E_PFINT_ICR0); | icr0 = rd32(hw, I40E_PFINT_ICR0); | ||||
reg = rd32(hw, I40E_PFINT_DYN_CTL0); | reg = rd32(hw, I40E_PFINT_DYN_CTL0); | ||||
reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; | reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; | ||||
wr32(hw, I40E_PFINT_DYN_CTL0, reg); | wr32(hw, I40E_PFINT_DYN_CTL0, reg); | ||||
mask = rd32(hw, I40E_PFINT_ICR0_ENA); | mask = rd32(hw, I40E_PFINT_ICR0_ENA); | ||||
#ifdef PCI_IOV | |||||
if (icr0 & I40E_PFINT_ICR0_VFLR_MASK) | |||||
taskqueue_enqueue(pf->tq, &pf->vflr_task); | |||||
#endif | |||||
if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { | if (icr0 & I40E_PFINT_ICR0_ADMINQ_MASK) { | ||||
taskqueue_enqueue(pf->tq, &pf->adminq); | taskqueue_enqueue(pf->tq, &pf->adminq); | ||||
return; | return; | ||||
} | } | ||||
more_rx = ixl_rxeof(que, IXL_RX_LIMIT); | more_rx = ixl_rxeof(que, IXL_RX_LIMIT); | ||||
IXL_TX_LOCK(txr); | IXL_TX_LOCK(txr); | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | ixl_msix_adminq(void *arg) | ||||
if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) | if (reg & I40E_PFINT_ICR0_ADMINQ_MASK) | ||||
mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK; | mask &= ~I40E_PFINT_ICR0_ENA_ADMINQ_MASK; | ||||
if (reg & I40E_PFINT_ICR0_MAL_DETECT_MASK) { | if (reg & I40E_PFINT_ICR0_MAL_DETECT_MASK) { | ||||
ixl_handle_mdd_event(pf); | ixl_handle_mdd_event(pf); | ||||
mask &= ~I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK; | mask &= ~I40E_PFINT_ICR0_ENA_MAL_DETECT_MASK; | ||||
} | } | ||||
if (reg & I40E_PFINT_ICR0_VFLR_MASK) | #ifdef PCI_IOV | ||||
if (reg & I40E_PFINT_ICR0_VFLR_MASK) { | |||||
mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; | mask &= ~I40E_PFINT_ICR0_ENA_VFLR_MASK; | ||||
taskqueue_enqueue(pf->tq, &pf->vflr_task); | |||||
} | |||||
#endif | |||||
reg = rd32(hw, I40E_PFINT_DYN_CTL0); | reg = rd32(hw, I40E_PFINT_DYN_CTL0); | ||||
reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; | reg = reg | I40E_PFINT_DYN_CTL0_CLEARPBA_MASK; | ||||
wr32(hw, I40E_PFINT_DYN_CTL0, reg); | wr32(hw, I40E_PFINT_DYN_CTL0, reg); | ||||
taskqueue_enqueue(pf->tq, &pf->adminq); | taskqueue_enqueue(pf->tq, &pf->adminq); | ||||
return; | return; | ||||
} | } | ||||
▲ Show 20 Lines • Show All 503 Lines • ▼ Show 20 Lines | ixl_assign_vsi_legacy(struct ixl_pf *pf) | ||||
bus_describe_intr(dev, pf->res, pf->tag, "irq0"); | bus_describe_intr(dev, pf->res, pf->tag, "irq0"); | ||||
TASK_INIT(&que->tx_task, 0, ixl_deferred_mq_start, que); | TASK_INIT(&que->tx_task, 0, ixl_deferred_mq_start, que); | ||||
TASK_INIT(&que->task, 0, ixl_handle_que, que); | TASK_INIT(&que->task, 0, ixl_handle_que, que); | ||||
que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT, | que->tq = taskqueue_create_fast("ixl_que", M_NOWAIT, | ||||
taskqueue_thread_enqueue, &que->tq); | taskqueue_thread_enqueue, &que->tq); | ||||
taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", | taskqueue_start_threads(&que->tq, 1, PI_NET, "%s que", | ||||
device_get_nameunit(dev)); | device_get_nameunit(dev)); | ||||
TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); | TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); | ||||
#ifdef PCI_IOV | |||||
TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf); | |||||
#endif | |||||
pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, | pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, | ||||
taskqueue_thread_enqueue, &pf->tq); | taskqueue_thread_enqueue, &pf->tq); | ||||
taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", | taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", | ||||
device_get_nameunit(dev)); | device_get_nameunit(dev)); | ||||
return (0); | return (0); | ||||
} | } | ||||
Show All 29 Lines | if (error) { | ||||
pf->res = NULL; | pf->res = NULL; | ||||
device_printf(dev, "Failed to register Admin que handler"); | device_printf(dev, "Failed to register Admin que handler"); | ||||
return (error); | return (error); | ||||
} | } | ||||
bus_describe_intr(dev, pf->res, pf->tag, "aq"); | bus_describe_intr(dev, pf->res, pf->tag, "aq"); | ||||
pf->admvec = vector; | pf->admvec = vector; | ||||
/* Tasklet for Admin Queue */ | /* Tasklet for Admin Queue */ | ||||
TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); | TASK_INIT(&pf->adminq, 0, ixl_do_adminq, pf); | ||||
#ifdef PCI_IOV | |||||
TASK_INIT(&pf->vflr_task, 0, ixl_handle_vflr, pf); | |||||
#endif | |||||
pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, | pf->tq = taskqueue_create_fast("ixl_adm", M_NOWAIT, | ||||
taskqueue_thread_enqueue, &pf->tq); | taskqueue_thread_enqueue, &pf->tq); | ||||
taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", | taskqueue_start_threads(&pf->tq, 1, PI_NET, "%s adminq", | ||||
device_get_nameunit(pf->dev)); | device_get_nameunit(pf->dev)); | ||||
++vector; | ++vector; | ||||
/* Now set up the stations */ | /* Now set up the stations */ | ||||
for (int i = 0; i < ifx->vsi.num_queues; i++, vector++, que++) { | for (int i = 0; i < ifx->vsi.num_queues; i++, vector++, que++) { | ||||
▲ Show 20 Lines • Show All 2,227 Lines • ▼ Show 20 Lines | if (ret) | ||||
break; | break; | ||||
opcode = LE16_TO_CPU(event.desc.opcode); | opcode = LE16_TO_CPU(event.desc.opcode); | ||||
switch (opcode) { | switch (opcode) { | ||||
case i40e_aqc_opc_get_link_status: | case i40e_aqc_opc_get_link_status: | ||||
ifx->link_up = ixl_config_link(hw); | ifx->link_up = ixl_config_link(hw); | ||||
ixl_update_link_status(pf); | ixl_update_link_status(pf); | ||||
break; | break; | ||||
case i40e_aqc_opc_send_msg_to_pf: | case i40e_aqc_opc_send_msg_to_pf: | ||||
#ifdef PCI_IOV | |||||
ixl_handle_vf_msg(pf, &event); | ixl_handle_vf_msg(pf, &event); | ||||
#endif | |||||
break; | break; | ||||
case i40e_aqc_opc_event_lan_overflow: | case i40e_aqc_opc_event_lan_overflow: | ||||
break; | break; | ||||
default: | default: | ||||
#ifdef IXL_DEBUG | #ifdef IXL_DEBUG | ||||
printf("AdminQ unknown event %x\n", opcode); | printf("AdminQ unknown event %x\n", opcode); | ||||
#endif | #endif | ||||
break; | break; | ||||
▲ Show 20 Lines • Show All 2,167 Lines • ▼ Show 20 Lines | case I40E_VIRTCHNL_OP_CONFIG_PROMISCUOUS_MODE: | ||||
break; | break; | ||||
case I40E_VIRTCHNL_OP_GET_STATS: | case I40E_VIRTCHNL_OP_GET_STATS: | ||||
ixl_vf_get_stats_msg(pf, vf, msg, msg_size); | ixl_vf_get_stats_msg(pf, vf, msg, msg_size); | ||||
break; | break; | ||||
default: | default: | ||||
i40e_send_vf_nack(pf, vf, opcode, I40E_ERR_NOT_IMPLEMENTED); | i40e_send_vf_nack(pf, vf, opcode, I40E_ERR_NOT_IMPLEMENTED); | ||||
break; | break; | ||||
} | } | ||||
} | |||||
/* Handle any VFs that have reset themselves via a Function Level Reset(FLR). */ | |||||
static void | |||||
ixl_handle_vflr(void *arg, int pending) | |||||
{ | |||||
struct ixl_pf *pf; | |||||
struct i40e_hw *hw; | |||||
uint16_t global_vf_num; | |||||
uint32_t vflrstat_index, vflrstat_mask, vflrstat, icr0; | |||||
int i; | |||||
pf = arg; | |||||
hw = &pf->hw; | |||||
IXL_PF_LOCK(pf); | |||||
for (i = 0; i < pf->num_vfs; i++) { | |||||
global_vf_num = hw->func_caps.vf_base_id + i; | |||||
vflrstat_index = IXL_GLGEN_VFLRSTAT_INDEX(global_vf_num); | |||||
vflrstat_mask = IXL_GLGEN_VFLRSTAT_MASK(global_vf_num); | |||||
vflrstat = rd32(hw, I40E_GLGEN_VFLRSTAT(vflrstat_index)); | |||||
if (vflrstat & vflrstat_mask) { | |||||
wr32(hw, I40E_GLGEN_VFLRSTAT(vflrstat_index), | |||||
vflrstat_mask); | |||||
ixl_reinit_vf(pf, &pf->vfs[i]); | |||||
} | |||||
} | |||||
icr0 = rd32(hw, I40E_PFINT_ICR0_ENA); | |||||
icr0 |= I40E_PFINT_ICR0_ENA_VFLR_MASK; | |||||
wr32(hw, I40E_PFINT_ICR0_ENA, icr0); | |||||
ixl_flush(hw); | |||||
IXL_PF_UNLOCK(pf); | |||||
} | } | ||||
static int | static int | ||||
ixl_adminq_err_to_errno(enum i40e_admin_queue_err err) | ixl_adminq_err_to_errno(enum i40e_admin_queue_err err) | ||||
{ | { | ||||
switch (err) { | switch (err) { | ||||
case I40E_AQ_RC_EPERM: | case I40E_AQ_RC_EPERM: | ||||
▲ Show 20 Lines • Show All 146 Lines • Show Last 20 Lines |