/* Set one of the t_flags bits in the TCB. */ static int set_tcb_tflag(struct adapter *adap, struct filter_entry *f, unsigned int ftid, unsigned int bit_pos, unsigned int val, int no_reply) { return set_tcb_field(adap, f, ftid, TCB_T_FLAGS_W, 1ULL << bit_pos, (unsigned long long)val << bit_pos, no_reply); }
static int configure_filter_tcb(struct adapter *adap, unsigned int tid, struct filter_entry *f) { if (f->fs.hitcnts) set_tcb_field(adap, f, tid, TCB_TIMESTAMP_W, TCB_TIMESTAMP_V(TCB_TIMESTAMP_M) | TCB_RTT_TS_RECENT_AGE_V(TCB_RTT_TS_RECENT_AGE_M), TCB_TIMESTAMP_V(0ULL) | TCB_RTT_TS_RECENT_AGE_V(0ULL), 1); if (f->fs.newdmac) set_tcb_tflag(adap, f, tid, TF_CCTRL_ECE_S, 1, 1); if (f->fs.newvlan == VLAN_INSERT || f->fs.newvlan == VLAN_REWRITE) set_tcb_tflag(adap, f, tid, TF_CCTRL_RFR_S, 1, 1); if (f->fs.newsmac) configure_filter_smac(adap, f); if (f->fs.nat_mode) { switch (f->fs.nat_mode) { case NAT_MODE_DIP: set_nat_params(adap, f, tid, true, false, false, false); break; case NAT_MODE_DIP_DP: set_nat_params(adap, f, tid, true, false, true, false); break; case NAT_MODE_DIP_DP_SIP: set_nat_params(adap, f, tid, true, true, true, false); break; case NAT_MODE_DIP_DP_SP: set_nat_params(adap, f, tid, true, false, true, true); break; case NAT_MODE_SIP_SP: set_nat_params(adap, f, tid, false, true, false, true); break; case NAT_MODE_DIP_SIP_SP: set_nat_params(adap, f, tid, true, true, false, true); break; case NAT_MODE_ALL: set_nat_params(adap, f, tid, true, true, true, true); break; default: pr_err("%s: Invalid NAT mode: %d\n", __func__, f->fs.nat_mode); return -EINVAL; } } return 0; }
static int configure_filter_smac(struct adapter *adap, struct filter_entry *f) { int err; /* do a set-tcb for smac-sel and CWR bit.. */ err = set_tcb_tflag(adap, f, f->tid, TF_CCTRL_CWR_S, 1, 1); if (err) goto smac_err; err = set_tcb_field(adap, f, f->tid, TCB_SMAC_SEL_W, TCB_SMAC_SEL_V(TCB_SMAC_SEL_M), TCB_SMAC_SEL_V(f->smt->idx), 1); if (!err) return 0; smac_err: dev_err(adap->pdev_dev, "filter %u smac config failed with error %u\n", f->tid, err); return err; }
static void set_nat_params(struct adapter *adap, struct filter_entry *f, unsigned int tid, bool dip, bool sip, bool dp, bool sp) { if (dip) { if (f->fs.type) { set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W, WORD_MASK, f->fs.nat_lip[15] | f->fs.nat_lip[14] << 8 | f->fs.nat_lip[13] << 16 | f->fs.nat_lip[12] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 1, WORD_MASK, f->fs.nat_lip[11] | f->fs.nat_lip[10] << 8 | f->fs.nat_lip[9] << 16 | f->fs.nat_lip[8] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 2, WORD_MASK, f->fs.nat_lip[7] | f->fs.nat_lip[6] << 8 | f->fs.nat_lip[5] << 16 | f->fs.nat_lip[4] << 24, 1); set_tcb_field(adap, f, tid, TCB_SND_UNA_RAW_W + 3, WORD_MASK, f->fs.nat_lip[3] | f->fs.nat_lip[2] << 8 | f->fs.nat_lip[1] << 16 | f->fs.nat_lip[0] << 24, 1); } else { set_tcb_field(adap, f, tid, TCB_RX_FRAG3_LEN_RAW_W, WORD_MASK, f->fs.nat_lip[3] | f->fs.nat_lip[2] << 8 | f->fs.nat_lip[1] << 16 | f->fs.nat_lip[0] << 24, 1); } } if (sip) { if (f->fs.type) { set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W, WORD_MASK, f->fs.nat_fip[15] | f->fs.nat_fip[14] << 8 | f->fs.nat_fip[13] << 16 | f->fs.nat_fip[12] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 1, WORD_MASK, f->fs.nat_fip[11] | f->fs.nat_fip[10] << 8 | f->fs.nat_fip[9] << 16 | f->fs.nat_fip[8] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 2, WORD_MASK, f->fs.nat_fip[7] | f->fs.nat_fip[6] << 8 | f->fs.nat_fip[5] << 16 | f->fs.nat_fip[4] << 24, 1); set_tcb_field(adap, f, tid, TCB_RX_FRAG2_PTR_RAW_W + 3, WORD_MASK, f->fs.nat_fip[3] | f->fs.nat_fip[2] << 8 | f->fs.nat_fip[1] << 16 | f->fs.nat_fip[0] << 24, 1); } else { set_tcb_field(adap, f, tid, TCB_RX_FRAG3_START_IDX_OFFSET_RAW_W, WORD_MASK, f->fs.nat_fip[3] | f->fs.nat_fip[2] << 8 | f->fs.nat_fip[1] << 16 | f->fs.nat_fip[0] << 24, 1); } } set_tcb_field(adap, f, tid, TCB_PDU_HDR_LEN_W, WORD_MASK, (dp ? f->fs.nat_lport : 0) | (sp ? f->fs.nat_fport << 16 : 0), 1); }
/** * Set one of the t_flags bits in the TCB. */ static void set_tcb_tflag(struct adapter *adap, unsigned int ftid, unsigned int bit_pos, unsigned int val, int no_reply) { set_tcb_field(adap, ftid, W_TCB_T_FLAGS, 1ULL << bit_pos, (unsigned long long)val << bit_pos, no_reply); }