ice: Check FDIR program status for AVF

Enable returning FDIR completion status by checking the
ctrl_vsi Rx queue descriptor value.

To enable returning FDIR completion status from ctrl_vsi Rx queue,
COMP_Queue and COMP_Report of FDIR filter programming descriptor
needs to be properly configured. After program request sent to ctrl_vsi
Tx queue, ctrl_vsi Rx queue interrupt will be triggered and
completion status will be returned.

Driver will first issue request in ice_vc_fdir_add_fltr(), then
pass FDIR context to the background task in interrupt service routine
ice_vc_fdir_irq_handler() and finally deal with them in
ice_flush_fdir_ctx(). ice_flush_fdir_ctx() will check the descriptor's
value, fdir context, and then send back virtual channel message to VF
by calling ice_vc_add_fdir_fltr_post(). An additional timer will be
setup in case of hardware interrupt timeout.

Signed-off-by: Yahui Cao <yahui.cao@intel.com>
Signed-off-by: Brett Creeley <brett.creeley@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Qi Zhang <qi.z.zhang@intel.com>
Tested-by: Chen Bo <BoX.C.Chen@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
This commit is contained in:
Qi Zhang
2021-03-22 11:32:12 -07:00
committed by Tony Nguyen
parent 213528fed2
commit d6218317e2
7 changed files with 541 additions and 16 deletions
+1
View File
@@ -231,6 +231,7 @@ enum ice_state {
__ICE_VF_RESETS_DISABLED, /* disable resets during ice_remove */
__ICE_LINK_DEFAULT_OVERRIDE_PENDING,
__ICE_PHY_INIT_COMPLETE,
__ICE_FD_VF_FLUSH_CTX, /* set at FD Rx IRQ or timeout */
__ICE_STATE_NBITS /* must be last */
};
@@ -384,6 +384,9 @@
#define VSIQF_FD_CNT(_VSI) (0x00464000 + ((_VSI) * 4))
#define VSIQF_FD_CNT_FD_GCNT_S 0
#define VSIQF_FD_CNT_FD_GCNT_M ICE_M(0x3FFF, 0)
#define VSIQF_FD_CNT_FD_BCNT_S 16
#define VSIQF_FD_CNT_FD_BCNT_M ICE_M(0x3FFF, 16)
#define VSIQF_FD_SIZE(_VSI) (0x00462000 + ((_VSI) * 4))
#define VSIQF_HKEY_MAX_INDEX 12
#define VSIQF_HLUT_MAX_INDEX 15
#define PFPM_APM 0x000B8080
@@ -140,6 +140,26 @@ struct ice_fltr_desc {
(0xFFFFFFFFULL << ICE_FXD_FLTR_QW1_FDID_S)
#define ICE_FXD_FLTR_QW1_FDID_ZERO 0x0ULL
/* definition for FD filter programming status descriptor WB format */
#define ICE_FXD_FLTR_WB_QW1_DD_S 0
#define ICE_FXD_FLTR_WB_QW1_DD_M (0x1ULL << ICE_FXD_FLTR_WB_QW1_DD_S)
#define ICE_FXD_FLTR_WB_QW1_DD_YES 0x1ULL
#define ICE_FXD_FLTR_WB_QW1_PROG_ID_S 1
#define ICE_FXD_FLTR_WB_QW1_PROG_ID_M \
(0x3ULL << ICE_FXD_FLTR_WB_QW1_PROG_ID_S)
#define ICE_FXD_FLTR_WB_QW1_PROG_ADD 0x0ULL
#define ICE_FXD_FLTR_WB_QW1_PROG_DEL 0x1ULL
#define ICE_FXD_FLTR_WB_QW1_FAIL_S 4
#define ICE_FXD_FLTR_WB_QW1_FAIL_M (0x1ULL << ICE_FXD_FLTR_WB_QW1_FAIL_S)
#define ICE_FXD_FLTR_WB_QW1_FAIL_YES 0x1ULL
#define ICE_FXD_FLTR_WB_QW1_FAIL_PROF_S 5
#define ICE_FXD_FLTR_WB_QW1_FAIL_PROF_M \
(0x1ULL << ICE_FXD_FLTR_WB_QW1_FAIL_PROF_S)
#define ICE_FXD_FLTR_WB_QW1_FAIL_PROF_YES 0x1ULL
struct ice_rx_ptype_decoded {
u32 ptype:10;
u32 known:1;
@@ -2071,6 +2071,7 @@ static void ice_service_task(struct work_struct *work)
ice_process_vflr_event(pf);
ice_clean_mailboxq_subtask(pf);
ice_sync_arfs_fltrs(pf);
ice_flush_fdir_ctx(pf);
/* Clear __ICE_SERVICE_SCHED flag to allow scheduling next event */
ice_service_task_complete(pf);
@@ -2082,6 +2083,7 @@ static void ice_service_task(struct work_struct *work)
test_bit(__ICE_MDD_EVENT_PENDING, pf->state) ||
test_bit(__ICE_VFLR_EVENT_PENDING, pf->state) ||
test_bit(__ICE_MAILBOXQ_EVENT_PENDING, pf->state) ||
test_bit(__ICE_FD_VF_FLUSH_CTX, pf->state) ||
test_bit(__ICE_ADMINQ_EVENT_PENDING, pf->state))
mod_timer(&pf->serv_tmr, jiffies);
}
@@ -1115,6 +1115,11 @@ int ice_clean_rx_irq(struct ice_ring *rx_ring, int budget)
dma_rmb();
if (rx_desc->wb.rxdid == FDIR_DESC_RXDID || !rx_ring->netdev) {
struct ice_vsi *ctrl_vsi = rx_ring->vsi;
if (rx_desc->wb.rxdid == FDIR_DESC_RXDID &&
ctrl_vsi->vf_id != ICE_INVAL_VFID)
ice_vc_fdir_irq_handler(ctrl_vsi, rx_desc);
ice_put_rx_buf(rx_ring, NULL, 0);
cleaned_count++;
continue;
File diff suppressed because it is too large Load Diff
@@ -5,6 +5,24 @@
#define _ICE_VIRTCHNL_FDIR_H_
struct ice_vf;
struct ice_pf;
enum ice_fdir_ctx_stat {
ICE_FDIR_CTX_READY,
ICE_FDIR_CTX_IRQ,
ICE_FDIR_CTX_TIMEOUT,
};
struct ice_vf_fdir_ctx {
struct timer_list rx_tmr;
enum virtchnl_ops v_opcode;
enum ice_fdir_ctx_stat stat;
union ice_32b_rx_flex_desc rx_desc;
#define ICE_VF_FDIR_CTX_VALID BIT(0)
u32 flags;
void *conf;
};
/* VF FDIR information structure */
struct ice_vf_fdir {
@@ -14,11 +32,24 @@ struct ice_vf_fdir {
struct idr fdir_rule_idr;
struct list_head fdir_rule_list;
spinlock_t ctx_lock; /* protects FDIR context info */
struct ice_vf_fdir_ctx ctx_irq;
struct ice_vf_fdir_ctx ctx_done;
};
#ifdef CONFIG_PCI_IOV
int ice_vc_add_fdir_fltr(struct ice_vf *vf, u8 *msg);
int ice_vc_del_fdir_fltr(struct ice_vf *vf, u8 *msg);
void ice_vf_fdir_init(struct ice_vf *vf);
void ice_vf_fdir_exit(struct ice_vf *vf);
void
ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi,
union ice_32b_rx_flex_desc *rx_desc);
void ice_flush_fdir_ctx(struct ice_pf *pf);
#else
static inline void
ice_vc_fdir_irq_handler(struct ice_vsi *ctrl_vsi, union ice_32b_rx_flex_desc *rx_desc) { }
static inline void ice_flush_fdir_ctx(struct ice_pf *pf) { }
#endif /* CONFIG_PCI_IOV */
#endif /* _ICE_VIRTCHNL_FDIR_H_ */