Changeset View
Changeset View
Standalone View
Standalone View
sys/dev/ice/ice_lib.c
- This file is larger than 256 KB, so syntax highlighting is disabled by default.
/* SPDX-License-Identifier: BSD-3-Clause */ | /* SPDX-License-Identifier: BSD-3-Clause */ | ||||
/* Copyright (c) 2022, Intel Corporation | /* Copyright (c) 2023, Intel Corporation | ||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions are met: | * modification, are permitted provided that the following conditions are met: | ||||
* | * | ||||
* 1. Redistributions of source code must retain the above copyright notice, | * 1. Redistributions of source code must retain the above copyright notice, | ||||
* this list of conditions and the following disclaimer. | * this list of conditions and the following disclaimer. | ||||
* | * | ||||
▲ Show 20 Lines • Show All 564 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
ice_setup_vsi_qmap(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx) | ice_setup_vsi_qmap(struct ice_vsi *vsi, struct ice_vsi_ctx *ctx) | ||||
{ | { | ||||
int pow = 0; | int pow = 0; | ||||
u16 qmap; | u16 qmap; | ||||
MPASS(vsi->rx_qmap != NULL); | MPASS(vsi->rx_qmap != NULL); | ||||
/* TODO: | switch (vsi->qmap_type) { | ||||
* Handle scattered queues (for VFs) | case ICE_RESMGR_ALLOC_CONTIGUOUS: | ||||
*/ | |||||
if (vsi->qmap_type != ICE_RESMGR_ALLOC_CONTIGUOUS) | |||||
return (EOPNOTSUPP); | |||||
ctx->info.mapping_flags |= CPU_TO_LE16(ICE_AQ_VSI_Q_MAP_CONTIG); | ctx->info.mapping_flags |= CPU_TO_LE16(ICE_AQ_VSI_Q_MAP_CONTIG); | ||||
ctx->info.q_mapping[0] = CPU_TO_LE16(vsi->rx_qmap[0]); | ctx->info.q_mapping[0] = CPU_TO_LE16(vsi->rx_qmap[0]); | ||||
ctx->info.q_mapping[1] = CPU_TO_LE16(vsi->num_rx_queues); | ctx->info.q_mapping[1] = CPU_TO_LE16(vsi->num_rx_queues); | ||||
break; | |||||
case ICE_RESMGR_ALLOC_SCATTERED: | |||||
ctx->info.mapping_flags |= CPU_TO_LE16(ICE_AQ_VSI_Q_MAP_NONCONTIG); | |||||
for (int i = 0; i < vsi->num_rx_queues; i++) | |||||
ctx->info.q_mapping[i] = CPU_TO_LE16(vsi->rx_qmap[i]); | |||||
break; | |||||
default: | |||||
return (EOPNOTSUPP); | |||||
} | |||||
/* Calculate the next power-of-2 of number of queues */ | /* Calculate the next power-of-2 of number of queues */ | ||||
if (vsi->num_rx_queues) | if (vsi->num_rx_queues) | ||||
pow = flsl(vsi->num_rx_queues - 1); | pow = flsl(vsi->num_rx_queues - 1); | ||||
/* Assign all the queues to traffic class zero */ | /* Assign all the queues to traffic class zero */ | ||||
qmap = (pow << ICE_AQ_VSI_TC_Q_NUM_S) & ICE_AQ_VSI_TC_Q_NUM_M; | qmap = (pow << ICE_AQ_VSI_TC_Q_NUM_S) & ICE_AQ_VSI_TC_Q_NUM_M; | ||||
ctx->info.tc_mapping[0] = CPU_TO_LE16(qmap); | ctx->info.tc_mapping[0] = CPU_TO_LE16(qmap); | ||||
▲ Show 20 Lines • Show All 612 Lines • ▼ Show 20 Lines | ice_add_media_types(struct ice_softc *sc, struct ifmedia *media) | ||||
/* Use autoselect media by default */ | /* Use autoselect media by default */ | ||||
ifmedia_add(media, IFM_ETHER | IFM_AUTO, 0, NULL); | ifmedia_add(media, IFM_ETHER | IFM_AUTO, 0, NULL); | ||||
ifmedia_set(media, IFM_ETHER | IFM_AUTO); | ifmedia_set(media, IFM_ETHER | IFM_AUTO); | ||||
return (ICE_SUCCESS); | return (ICE_SUCCESS); | ||||
} | } | ||||
/** | /** | ||||
* ice_configure_rxq_interrupts - Configure HW Rx queues for MSI-X interrupts | * ice_configure_rxq_interrupt - Configure HW Rx queue for an MSI-X interrupt | ||||
* @hw: ice hw structure | |||||
* @rxqid: Rx queue index in PF space | |||||
* @vector: MSI-X vector index in PF/VF space | |||||
* @itr_idx: ITR index to use for interrupt | |||||
* | |||||
* @remark ice_flush() may need to be called after this | |||||
*/ | |||||
void | |||||
ice_configure_rxq_interrupt(struct ice_hw *hw, u16 rxqid, u16 vector, u8 itr_idx) | |||||
{ | |||||
u32 val; | |||||
MPASS(itr_idx <= ICE_ITR_NONE); | |||||
val = (QINT_RQCTL_CAUSE_ENA_M | | |||||
(itr_idx << QINT_RQCTL_ITR_INDX_S) | | |||||
(vector << QINT_RQCTL_MSIX_INDX_S)); | |||||
wr32(hw, QINT_RQCTL(rxqid), val); | |||||
} | |||||
/** | |||||
* ice_configure_all_rxq_interrupts - Configure HW Rx queues for MSI-X interrupts | |||||
* @vsi: the VSI to configure | * @vsi: the VSI to configure | ||||
* | * | ||||
* Called when setting up MSI-X interrupts to configure the Rx hardware queues. | * Called when setting up MSI-X interrupts to configure the Rx hardware queues. | ||||
*/ | */ | ||||
void | void | ||||
ice_configure_rxq_interrupts(struct ice_vsi *vsi) | ice_configure_all_rxq_interrupts(struct ice_vsi *vsi) | ||||
{ | { | ||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
int i; | int i; | ||||
for (i = 0; i < vsi->num_rx_queues; i++) { | for (i = 0; i < vsi->num_rx_queues; i++) { | ||||
struct ice_rx_queue *rxq = &vsi->rx_queues[i]; | struct ice_rx_queue *rxq = &vsi->rx_queues[i]; | ||||
u32 val; | |||||
val = (QINT_RQCTL_CAUSE_ENA_M | | ice_configure_rxq_interrupt(hw, vsi->rx_qmap[rxq->me], | ||||
(ICE_RX_ITR << QINT_RQCTL_ITR_INDX_S) | | rxq->irqv->me, ICE_RX_ITR); | ||||
(rxq->irqv->me << QINT_RQCTL_MSIX_INDX_S)); | |||||
wr32(hw, QINT_RQCTL(vsi->rx_qmap[rxq->me]), val); | |||||
} | } | ||||
ice_flush(hw); | ice_flush(hw); | ||||
} | } | ||||
/** | /** | ||||
* ice_configure_txq_interrupts - Configure HW Tx queues for MSI-X interrupts | * ice_configure_txq_interrupt - Configure HW Tx queue for an MSI-X interrupt | ||||
* @hw: ice hw structure | |||||
* @txqid: Tx queue index in PF space | |||||
* @vector: MSI-X vector index in PF/VF space | |||||
* @itr_idx: ITR index to use for interrupt | |||||
* | |||||
* @remark ice_flush() may need to be called after this | |||||
*/ | |||||
void | |||||
ice_configure_txq_interrupt(struct ice_hw *hw, u16 txqid, u16 vector, u8 itr_idx) | |||||
{ | |||||
u32 val; | |||||
MPASS(itr_idx <= ICE_ITR_NONE); | |||||
val = (QINT_TQCTL_CAUSE_ENA_M | | |||||
(itr_idx << QINT_TQCTL_ITR_INDX_S) | | |||||
(vector << QINT_TQCTL_MSIX_INDX_S)); | |||||
wr32(hw, QINT_TQCTL(txqid), val); | |||||
} | |||||
/** | |||||
* ice_configure_all_txq_interrupts - Configure HW Tx queues for MSI-X interrupts | |||||
* @vsi: the VSI to configure | * @vsi: the VSI to configure | ||||
* | * | ||||
* Called when setting up MSI-X interrupts to configure the Tx hardware queues. | * Called when setting up MSI-X interrupts to configure the Tx hardware queues. | ||||
*/ | */ | ||||
void | void | ||||
ice_configure_txq_interrupts(struct ice_vsi *vsi) | ice_configure_all_txq_interrupts(struct ice_vsi *vsi) | ||||
{ | { | ||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
int i; | int i; | ||||
for (i = 0; i < vsi->num_tx_queues; i++) { | for (i = 0; i < vsi->num_tx_queues; i++) { | ||||
struct ice_tx_queue *txq = &vsi->tx_queues[i]; | struct ice_tx_queue *txq = &vsi->tx_queues[i]; | ||||
u32 val; | |||||
val = (QINT_TQCTL_CAUSE_ENA_M | | ice_configure_txq_interrupt(hw, vsi->tx_qmap[txq->me], | ||||
(ICE_TX_ITR << QINT_TQCTL_ITR_INDX_S) | | txq->irqv->me, ICE_TX_ITR); | ||||
(txq->irqv->me << QINT_TQCTL_MSIX_INDX_S)); | |||||
wr32(hw, QINT_TQCTL(vsi->tx_qmap[txq->me]), val); | |||||
} | } | ||||
ice_flush(hw); | ice_flush(hw); | ||||
} | } | ||||
/** | /** | ||||
* ice_flush_rxq_interrupts - Unconfigure Hw Rx queues MSI-X interrupt cause | * ice_flush_rxq_interrupts - Unconfigure Hw Rx queues MSI-X interrupt cause | ||||
* @vsi: the VSI to configure | * @vsi: the VSI to configure | ||||
* | * | ||||
* Unset the CAUSE_ENA flag of the TQCTL register for each queue, then trigger | * Unset the CAUSE_ENA flag of the TQCTL register for each queue, then trigger | ||||
* a software interrupt on that cause. This is required as part of the Rx | * a software interrupt on that cause. This is required as part of the Rx | ||||
* queue disable logic to dissociate the Rx queue from the interrupt. | * queue disable logic to dissociate the Rx queue from the interrupt. | ||||
* | * | ||||
* Note: this function must be called prior to disabling Rx queues with | * Note: this function must be called prior to disabling Rx queues with | ||||
* ice_control_rx_queues, otherwise the Rx queue may not be disabled properly. | * ice_control_all_rx_queues, otherwise the Rx queue may not be disabled properly. | ||||
*/ | */ | ||||
void | void | ||||
ice_flush_rxq_interrupts(struct ice_vsi *vsi) | ice_flush_rxq_interrupts(struct ice_vsi *vsi) | ||||
{ | { | ||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
int i; | int i; | ||||
for (i = 0; i < vsi->num_rx_queues; i++) { | for (i = 0; i < vsi->num_rx_queues; i++) { | ||||
▲ Show 20 Lines • Show All 119 Lines • ▼ Show 20 Lines | ice_setup_tx_ctx(struct ice_tx_queue *txq, struct ice_tlan_ctx *tlan_ctx, u16 pf_q) | ||||
/* number of descriptors in the queue */ | /* number of descriptors in the queue */ | ||||
tlan_ctx->qlen = txq->desc_count; | tlan_ctx->qlen = txq->desc_count; | ||||
/* set the transmit queue base address, defined in 128 byte units */ | /* set the transmit queue base address, defined in 128 byte units */ | ||||
tlan_ctx->base = txq->tx_paddr >> 7; | tlan_ctx->base = txq->tx_paddr >> 7; | ||||
tlan_ctx->pf_num = hw->pf_id; | tlan_ctx->pf_num = hw->pf_id; | ||||
/* For now, we only have code supporting PF VSIs */ | |||||
switch (vsi->type) { | switch (vsi->type) { | ||||
case ICE_VSI_PF: | case ICE_VSI_PF: | ||||
tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_PF; | tlan_ctx->vmvf_type = ICE_TLAN_CTX_VMVF_TYPE_PF; | ||||
break; | break; | ||||
default: | default: | ||||
return (ENODEV); | return (ENODEV); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 218 Lines • ▼ Show 20 Lines | for (i = 0; i < ICE_Q_WAIT_RETRY_LIMIT; i++) { | ||||
/* wait a few microseconds before we check again */ | /* wait a few microseconds before we check again */ | ||||
DELAY(10); | DELAY(10); | ||||
} | } | ||||
return (ETIMEDOUT); | return (ETIMEDOUT); | ||||
} | } | ||||
/** | /** | ||||
* ice_control_rx_queues - Configure hardware to start or stop the Rx queues | * ice_control_rx_queue - Configure hardware to start or stop an Rx queue | ||||
* @vsi: VSI to enable/disable queues | * @vsi: VSI containing queue to enable/disable | ||||
* @enable: true to enable queues, false to disable | * @qidx: Queue index in VSI space | ||||
* @enable: true to enable queue, false to disable | |||||
* | * | ||||
* Control the Rx queues through the QRX_CTRL register, enabling or disabling | * Control the Rx queue through the QRX_CTRL register, enabling or disabling | ||||
* them. Wait for the appropriate time to ensure that the queues have actually | * it. Wait for the appropriate time to ensure that the queue has actually | ||||
* reached the expected state. | * reached the expected state. | ||||
*/ | */ | ||||
int | int | ||||
ice_control_rx_queues(struct ice_vsi *vsi, bool enable) | ice_control_rx_queue(struct ice_vsi *vsi, u16 qidx, bool enable) | ||||
{ | { | ||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
device_t dev = vsi->sc->dev; | device_t dev = vsi->sc->dev; | ||||
u32 qrx_ctrl = 0; | u32 qrx_ctrl = 0; | ||||
int i, err; | int err; | ||||
/* TODO: amortize waits by changing all queues up front and then | struct ice_rx_queue *rxq = &vsi->rx_queues[qidx]; | ||||
* checking their status afterwards. This will become more necessary | |||||
* when we have a large number of queues. | |||||
*/ | |||||
for (i = 0; i < vsi->num_rx_queues; i++) { | |||||
struct ice_rx_queue *rxq = &vsi->rx_queues[i]; | |||||
int pf_q = vsi->rx_qmap[rxq->me]; | int pf_q = vsi->rx_qmap[rxq->me]; | ||||
err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl); | err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl); | ||||
if (err) { | if (err) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"Rx queue %d is not ready\n", | "Rx queue %d is not ready\n", | ||||
pf_q); | pf_q); | ||||
return err; | return err; | ||||
} | } | ||||
/* Skip if the queue is already in correct state */ | /* Skip if the queue is already in correct state */ | ||||
if (enable == !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M)) | if (enable == !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M)) | ||||
continue; | return (0); | ||||
if (enable) | if (enable) | ||||
qrx_ctrl |= QRX_CTRL_QENA_REQ_M; | qrx_ctrl |= QRX_CTRL_QENA_REQ_M; | ||||
else | else | ||||
qrx_ctrl &= ~QRX_CTRL_QENA_REQ_M; | qrx_ctrl &= ~QRX_CTRL_QENA_REQ_M; | ||||
wr32(hw, QRX_CTRL(pf_q), qrx_ctrl); | wr32(hw, QRX_CTRL(pf_q), qrx_ctrl); | ||||
/* wait for the queue to finalize the request */ | /* wait for the queue to finalize the request */ | ||||
err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl); | err = ice_is_rxq_ready(hw, pf_q, &qrx_ctrl); | ||||
if (err) { | if (err) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"Rx queue %d %sable timeout\n", | "Rx queue %d %sable timeout\n", | ||||
pf_q, (enable ? "en" : "dis")); | pf_q, (enable ? "en" : "dis")); | ||||
return err; | return err; | ||||
} | } | ||||
/* this should never happen */ | /* this should never happen */ | ||||
if (enable != !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M)) { | if (enable != !!(qrx_ctrl & QRX_CTRL_QENA_STAT_M)) { | ||||
device_printf(dev, | device_printf(dev, | ||||
"Rx queue %d invalid state\n", | "Rx queue %d invalid state\n", | ||||
pf_q); | pf_q); | ||||
return (EDOOFUS); | return (EDOOFUS); | ||||
} | } | ||||
return (0); | |||||
} | } | ||||
/** | |||||
* ice_control_all_rx_queues - Configure hardware to start or stop the Rx queues | |||||
* @vsi: VSI to enable/disable queues | |||||
* @enable: true to enable queues, false to disable | |||||
* | |||||
* Control the Rx queues through the QRX_CTRL register, enabling or disabling | |||||
* them. Wait for the appropriate time to ensure that the queues have actually | |||||
* reached the expected state. | |||||
*/ | |||||
int | |||||
ice_control_all_rx_queues(struct ice_vsi *vsi, bool enable) | |||||
{ | |||||
int i, err; | |||||
/* TODO: amortize waits by changing all queues up front and then | |||||
* checking their status afterwards. This will become more necessary | |||||
* when we have a large number of queues. | |||||
*/ | |||||
for (i = 0; i < vsi->num_rx_queues; i++) { | |||||
err = ice_control_rx_queue(vsi, i, enable); | |||||
if (err) | |||||
break; | |||||
} | |||||
return (0); | return (0); | ||||
} | } | ||||
/** | /** | ||||
* ice_add_mac_to_list - Add MAC filter to a MAC filter list | * ice_add_mac_to_list - Add MAC filter to a MAC filter list | ||||
* @vsi: the VSI to forward to | * @vsi: the VSI to forward to | ||||
* @list: list which contains MAC filter entries | * @list: list which contains MAC filter entries | ||||
* @addr: the MAC address to be added | * @addr: the MAC address to be added | ||||
▲ Show 20 Lines • Show All 3,021 Lines • ▼ Show 20 Lines | ice_add_sysctls_mac_pfc_one_stat(struct sysctl_ctx_list *ctx, | ||||
struct sbuf *namebuf, *descbuf; | struct sbuf *namebuf, *descbuf; | ||||
node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, node_name, CTLFLAG_RD, | node = SYSCTL_ADD_NODE(ctx, parent_list, OID_AUTO, node_name, CTLFLAG_RD, | ||||
NULL, descr); | NULL, descr); | ||||
node_list = SYSCTL_CHILDREN(node); | node_list = SYSCTL_CHILDREN(node); | ||||
namebuf = sbuf_new_auto(); | namebuf = sbuf_new_auto(); | ||||
descbuf = sbuf_new_auto(); | descbuf = sbuf_new_auto(); | ||||
for (int i = 0; i < ICE_MAX_DCB_TCS; i++) { | for (int i = 0; i < ICE_MAX_TRAFFIC_CLASS; i++) { | ||||
sbuf_clear(namebuf); | sbuf_clear(namebuf); | ||||
sbuf_clear(descbuf); | sbuf_clear(descbuf); | ||||
sbuf_printf(namebuf, "%d", i); | sbuf_printf(namebuf, "%d", i); | ||||
sbuf_printf(descbuf, "%s for TC %d", descr, i); | sbuf_printf(descbuf, "%s for TC %d", descr, i); | ||||
sbuf_finish(namebuf); | sbuf_finish(namebuf); | ||||
sbuf_finish(descbuf); | sbuf_finish(descbuf); | ||||
▲ Show 20 Lines • Show All 372 Lines • ▼ Show 20 Lines | |||||
free_filter_lists: | free_filter_lists: | ||||
ice_free_fltr_list(&data.add_list); | ice_free_fltr_list(&data.add_list); | ||||
ice_free_fltr_list(&remove_list); | ice_free_fltr_list(&remove_list); | ||||
return (err); | return (err); | ||||
} | } | ||||
/** | /** | ||||
* ice_add_vlan_hw_filter - Add a VLAN filter for a given VSI | * ice_add_vlan_hw_filters - Add multiple VLAN filters for a given VSI | ||||
* @vsi: The VSI to add the filter for | * @vsi: The VSI to add the filter for | ||||
* @vid: VLAN to add | * @vid: array of VLAN ids to add | ||||
* @length: length of vid array | |||||
* | * | ||||
* Programs a HW filter so that the given VSI will receive the specified VLAN. | * Programs HW filters so that the given VSI will receive the specified VLANs. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_add_vlan_hw_filter(struct ice_vsi *vsi, u16 vid) | ice_add_vlan_hw_filters(struct ice_vsi *vsi, u16 *vid, u16 length) | ||||
{ | { | ||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
struct ice_list_head vlan_list; | struct ice_list_head vlan_list; | ||||
struct ice_fltr_list_entry vlan_entry; | struct ice_fltr_list_entry *vlan_entries; | ||||
enum ice_status status; | |||||
MPASS(length > 0); | |||||
INIT_LIST_HEAD(&vlan_list); | INIT_LIST_HEAD(&vlan_list); | ||||
memset(&vlan_entry, 0, sizeof(vlan_entry)); | |||||
vlan_entry.fltr_info.lkup_type = ICE_SW_LKUP_VLAN; | vlan_entries = (struct ice_fltr_list_entry *) | ||||
vlan_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; | malloc(sizeof(*vlan_entries) * length, M_ICE, M_NOWAIT | M_ZERO); | ||||
vlan_entry.fltr_info.flag = ICE_FLTR_TX; | if (!vlan_entries) | ||||
vlan_entry.fltr_info.src_id = ICE_SRC_ID_VSI; | return (ICE_ERR_NO_MEMORY); | ||||
vlan_entry.fltr_info.vsi_handle = vsi->idx; | |||||
vlan_entry.fltr_info.l_data.vlan.vlan_id = vid; | |||||
LIST_ADD(&vlan_entry.list_entry, &vlan_list); | for (u16 i = 0; i < length; i++) { | ||||
vlan_entries[i].fltr_info.lkup_type = ICE_SW_LKUP_VLAN; | |||||
vlan_entries[i].fltr_info.fltr_act = ICE_FWD_TO_VSI; | |||||
vlan_entries[i].fltr_info.flag = ICE_FLTR_TX; | |||||
vlan_entries[i].fltr_info.src_id = ICE_SRC_ID_VSI; | |||||
vlan_entries[i].fltr_info.vsi_handle = vsi->idx; | |||||
vlan_entries[i].fltr_info.l_data.vlan.vlan_id = vid[i]; | |||||
return ice_add_vlan(hw, &vlan_list); | LIST_ADD(&vlan_entries[i].list_entry, &vlan_list); | ||||
} | } | ||||
status = ice_add_vlan(hw, &vlan_list); | |||||
if (!status) | |||||
goto done; | |||||
device_printf(vsi->sc->dev, "Failed to add VLAN filters:\n"); | |||||
for (u16 i = 0; i < length; i++) { | |||||
device_printf(vsi->sc->dev, | |||||
"- vlan %d, status %d\n", | |||||
vlan_entries[i].fltr_info.l_data.vlan.vlan_id, | |||||
vlan_entries[i].status); | |||||
} | |||||
done: | |||||
free(vlan_entries, M_ICE); | |||||
return (status); | |||||
} | |||||
/** | /** | ||||
* ice_remove_vlan_hw_filter - Remove a VLAN filter for a given VSI | * ice_add_vlan_hw_filter - Add a VLAN filter for a given VSI | ||||
* @vsi: The VSI to add the filter for | * @vsi: The VSI to add the filter for | ||||
* @vid: VLAN to remove | * @vid: VLAN to add | ||||
* | * | ||||
* Removes a previously programmed HW filter for the specified VSI. | * Programs a HW filter so that the given VSI will receive the specified VLAN. | ||||
*/ | */ | ||||
enum ice_status | enum ice_status | ||||
ice_remove_vlan_hw_filter(struct ice_vsi *vsi, u16 vid) | ice_add_vlan_hw_filter(struct ice_vsi *vsi, u16 vid) | ||||
{ | { | ||||
return ice_add_vlan_hw_filters(vsi, &vid, 1); | |||||
} | |||||
/** | |||||
* ice_remove_vlan_hw_filters - Remove multiple VLAN filters for a given VSI | |||||
* @vsi: The VSI to remove the filters from | |||||
* @vid: array of VLAN ids to remove | |||||
* @length: length of vid array | |||||
* | |||||
* Removes previously programmed HW filters for the specified VSI. | |||||
*/ | |||||
enum ice_status | |||||
ice_remove_vlan_hw_filters(struct ice_vsi *vsi, u16 *vid, u16 length) | |||||
{ | |||||
struct ice_hw *hw = &vsi->sc->hw; | struct ice_hw *hw = &vsi->sc->hw; | ||||
struct ice_list_head vlan_list; | struct ice_list_head vlan_list; | ||||
struct ice_fltr_list_entry vlan_entry; | struct ice_fltr_list_entry *vlan_entries; | ||||
enum ice_status status; | |||||
MPASS(length > 0); | |||||
INIT_LIST_HEAD(&vlan_list); | INIT_LIST_HEAD(&vlan_list); | ||||
memset(&vlan_entry, 0, sizeof(vlan_entry)); | |||||
vlan_entry.fltr_info.lkup_type = ICE_SW_LKUP_VLAN; | vlan_entries = (struct ice_fltr_list_entry *) | ||||
vlan_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; | malloc(sizeof(*vlan_entries) * length, M_ICE, M_NOWAIT | M_ZERO); | ||||
vlan_entry.fltr_info.flag = ICE_FLTR_TX; | if (!vlan_entries) | ||||
vlan_entry.fltr_info.src_id = ICE_SRC_ID_VSI; | return (ICE_ERR_NO_MEMORY); | ||||
vlan_entry.fltr_info.vsi_handle = vsi->idx; | |||||
vlan_entry.fltr_info.l_data.vlan.vlan_id = vid; | |||||
LIST_ADD(&vlan_entry.list_entry, &vlan_list); | for (u16 i = 0; i < length; i++) { | ||||
vlan_entries[i].fltr_info.lkup_type = ICE_SW_LKUP_VLAN; | |||||
vlan_entries[i].fltr_info.fltr_act = ICE_FWD_TO_VSI; | |||||
vlan_entries[i].fltr_info.flag = ICE_FLTR_TX; | |||||
vlan_entries[i].fltr_info.src_id = ICE_SRC_ID_VSI; | |||||
vlan_entries[i].fltr_info.vsi_handle = vsi->idx; | |||||
vlan_entries[i].fltr_info.l_data.vlan.vlan_id = vid[i]; | |||||
return ice_remove_vlan(hw, &vlan_list); | LIST_ADD(&vlan_entries[i].list_entry, &vlan_list); | ||||
} | } | ||||
status = ice_remove_vlan(hw, &vlan_list); | |||||
if (!status) | |||||
goto done; | |||||
device_printf(vsi->sc->dev, "Failed to remove VLAN filters:\n"); | |||||
for (u16 i = 0; i < length; i++) { | |||||
device_printf(vsi->sc->dev, | |||||
"- vlan %d, status %d\n", | |||||
vlan_entries[i].fltr_info.l_data.vlan.vlan_id, | |||||
vlan_entries[i].status); | |||||
} | |||||
done: | |||||
free(vlan_entries, M_ICE); | |||||
return (status); | |||||
} | |||||
/** | |||||
* ice_remove_vlan_hw_filter - Remove a VLAN filter for a given VSI | |||||
* @vsi: The VSI to remove the filter from | |||||
* @vid: VLAN to remove | |||||
* | |||||
* Removes a previously programmed HW filter for the specified VSI. | |||||
*/ | |||||
enum ice_status | |||||
ice_remove_vlan_hw_filter(struct ice_vsi *vsi, u16 vid) | |||||
{ | |||||
return ice_remove_vlan_hw_filters(vsi, &vid, 1); | |||||
} | |||||
#define ICE_SYSCTL_HELP_RX_ITR \ | #define ICE_SYSCTL_HELP_RX_ITR \ | ||||
"\nControl Rx interrupt throttle rate." \ | "\nControl Rx interrupt throttle rate." \ | ||||
"\n\t0-8160 - sets interrupt rate in usecs" \ | "\n\t0-8160 - sets interrupt rate in usecs" \ | ||||
"\n\t -1 - reset the Rx itr to default" | "\n\t -1 - reset the Rx itr to default" | ||||
/** | /** | ||||
* ice_sysctl_rx_itr - Display or change the Rx ITR for a VSI | * ice_sysctl_rx_itr - Display or change the Rx ITR for a VSI | ||||
* @oidp: sysctl oid structure | * @oidp: sysctl oid structure | ||||
▲ Show 20 Lines • Show All 2,996 Lines • ▼ Show 20 Lines | ice_stop_pf_vsi(struct ice_softc *sc) | ||||
ice_flush_txq_interrupts(&sc->pf_vsi); | ice_flush_txq_interrupts(&sc->pf_vsi); | ||||
ice_flush_rxq_interrupts(&sc->pf_vsi); | ice_flush_rxq_interrupts(&sc->pf_vsi); | ||||
if (!ice_testandclear_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED)) | if (!ice_testandclear_state(&sc->state, ICE_STATE_DRIVER_INITIALIZED)) | ||||
return; | return; | ||||
/* Disable the Tx and Rx queues */ | /* Disable the Tx and Rx queues */ | ||||
ice_vsi_disable_tx(&sc->pf_vsi); | ice_vsi_disable_tx(&sc->pf_vsi); | ||||
ice_control_rx_queues(&sc->pf_vsi, false); | ice_control_all_rx_queues(&sc->pf_vsi, false); | ||||
} | } | ||||
/** | /** | ||||
* ice_vsi_setup_q_map - Setup a VSI queue map | * ice_vsi_setup_q_map - Setup a VSI queue map | ||||
* @vsi: the VSI being configured | * @vsi: the VSI being configured | ||||
* @ctxt: VSI context structure | * @ctxt: VSI context structure | ||||
*/ | */ | ||||
static void | static void | ||||
▲ Show 20 Lines • Show All 2,549 Lines • Show Last 20 Lines |