mirror of
https://github.com/opnsense/src.git
synced 2026-06-08 16:22:46 -04:00
- Read all TP parameters in one place.
- Read the filter mode, calculate various shifts, and use them properly during active open (in select_ntuple). MFC after: 1 day
This commit is contained in:
parent
6f7e608220
commit
c337fa30af
9 changed files with 205 additions and 66 deletions
|
|
@ -562,7 +562,6 @@ struct adapter {
|
|||
struct taskqueue *tq[NCHAN]; /* taskqueues that flush data out */
|
||||
struct port_info *port[MAX_NPORTS];
|
||||
uint8_t chan_map[NCHAN];
|
||||
uint32_t filter_mode;
|
||||
|
||||
#ifdef TCP_OFFLOAD
|
||||
void *tom_softc; /* (struct tom_data *) */
|
||||
|
|
|
|||
|
|
@ -219,6 +219,12 @@ struct tp_params {
|
|||
unsigned int dack_re; /* DACK timer resolution */
|
||||
unsigned int la_mask; /* what events are recorded by TP LA */
|
||||
unsigned short tx_modq[NCHAN]; /* channel to modulation queue map */
|
||||
uint32_t vlan_pri_map;
|
||||
uint32_t ingress_config;
|
||||
int8_t vlan_shift;
|
||||
int8_t vnic_shift;
|
||||
int8_t port_shift;
|
||||
int8_t protocol_shift;
|
||||
};
|
||||
|
||||
struct vpd_params {
|
||||
|
|
@ -421,6 +427,8 @@ int t4_get_tp_version(struct adapter *adapter, u32 *vers);
|
|||
int t4_check_fw_version(struct adapter *adapter);
|
||||
int t4_init_hw(struct adapter *adapter, u32 fw_params);
|
||||
int t4_prep_adapter(struct adapter *adapter);
|
||||
int t4_init_tp_params(struct adapter *adap);
|
||||
int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
|
||||
int t4_port_init(struct port_info *p, int mbox, int pf, int vf);
|
||||
int t4_reinit_adapter(struct adapter *adap);
|
||||
void t4_fatal_err(struct adapter *adapter);
|
||||
|
|
|
|||
|
|
@ -5521,6 +5521,91 @@ int __devinit t4_prep_adapter(struct adapter *adapter)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_init_tp_params - initialize adap->params.tp
|
||||
* @adap: the adapter
|
||||
*
|
||||
* Initialize various fields of the adapter's TP Parameters structure.
|
||||
*/
|
||||
int __devinit t4_init_tp_params(struct adapter *adap)
|
||||
{
|
||||
int chan;
|
||||
u32 v;
|
||||
|
||||
v = t4_read_reg(adap, A_TP_TIMER_RESOLUTION);
|
||||
adap->params.tp.tre = G_TIMERRESOLUTION(v);
|
||||
adap->params.tp.dack_re = G_DELAYEDACKRESOLUTION(v);
|
||||
|
||||
/* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
|
||||
for (chan = 0; chan < NCHAN; chan++)
|
||||
adap->params.tp.tx_modq[chan] = chan;
|
||||
|
||||
/*
|
||||
* Cache the adapter's Compressed Filter Mode and global Incress
|
||||
* Configuration.
|
||||
*/
|
||||
t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
|
||||
&adap->params.tp.vlan_pri_map, 1,
|
||||
A_TP_VLAN_PRI_MAP);
|
||||
t4_read_indirect(adap, A_TP_PIO_ADDR, A_TP_PIO_DATA,
|
||||
&adap->params.tp.ingress_config, 1,
|
||||
A_TP_INGRESS_CONFIG);
|
||||
|
||||
/*
|
||||
* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
|
||||
* shift positions of several elements of the Compressed Filter Tuple
|
||||
* for this adapter which we need frequently ...
|
||||
*/
|
||||
adap->params.tp.vlan_shift = t4_filter_field_shift(adap, F_VLAN);
|
||||
adap->params.tp.vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID);
|
||||
adap->params.tp.port_shift = t4_filter_field_shift(adap, F_PORT);
|
||||
adap->params.tp.protocol_shift = t4_filter_field_shift(adap, F_PROTOCOL);
|
||||
|
||||
/*
|
||||
* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
|
||||
* represents the presense of an Outer VLAN instead of a VNIC ID.
|
||||
*/
|
||||
if ((adap->params.tp.ingress_config & F_VNIC) == 0)
|
||||
adap->params.tp.vnic_shift = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* t4_filter_field_shift - calculate filter field shift
|
||||
* @adap: the adapter
|
||||
* @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits)
|
||||
*
|
||||
* Return the shift position of a filter field within the Compressed
|
||||
* Filter Tuple. The filter field is specified via its selection bit
|
||||
* within TP_VLAN_PRI_MAL (filter mode). E.g. F_VLAN.
|
||||
*/
|
||||
int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
|
||||
{
|
||||
unsigned int filter_mode = adap->params.tp.vlan_pri_map;
|
||||
unsigned int sel;
|
||||
int field_shift;
|
||||
|
||||
if ((filter_mode & filter_sel) == 0)
|
||||
return -1;
|
||||
|
||||
for (sel = 1, field_shift = 0; sel < filter_sel; sel <<= 1) {
|
||||
switch (filter_mode & sel) {
|
||||
case F_FCOE: field_shift += W_FT_FCOE; break;
|
||||
case F_PORT: field_shift += W_FT_PORT; break;
|
||||
case F_VNIC_ID: field_shift += W_FT_VNIC_ID; break;
|
||||
case F_VLAN: field_shift += W_FT_VLAN; break;
|
||||
case F_TOS: field_shift += W_FT_TOS; break;
|
||||
case F_PROTOCOL: field_shift += W_FT_PROTOCOL; break;
|
||||
case F_ETHERTYPE: field_shift += W_FT_ETHERTYPE; break;
|
||||
case F_MACMATCH: field_shift += W_FT_MACMATCH; break;
|
||||
case F_MPSHITTYPE: field_shift += W_FT_MPSHITTYPE; break;
|
||||
case F_FRAGMENTATION: field_shift += W_FT_FRAGMENTATION; break;
|
||||
}
|
||||
}
|
||||
return field_shift;
|
||||
}
|
||||
|
||||
int __devinit t4_port_init(struct port_info *p, int mbox, int pf, int vf)
|
||||
{
|
||||
u8 addr[6];
|
||||
|
|
|
|||
|
|
@ -189,4 +189,57 @@
|
|||
#define X_MBOWNER_FW 1
|
||||
#define X_MBOWNER_PL 2
|
||||
|
||||
/*
|
||||
* PCI-E definitions.
|
||||
* ==================
|
||||
*/
|
||||
|
||||
#define X_WINDOW_SHIFT 10
|
||||
#define X_PCIEOFST_SHIFT 10
|
||||
|
||||
/*
|
||||
* TP definitions.
|
||||
* ===============
|
||||
*/
|
||||
|
||||
/*
|
||||
* TP_VLAN_PRI_MAP controls which subset of fields will be present in the
|
||||
* Compressed Filter Tuple for LE filters. Each bit set in TP_VLAN_PRI_MAP
|
||||
* selects for a particular field being present. These fields, when present
|
||||
* in the Compressed Filter Tuple, have the following widths in bits.
|
||||
*/
|
||||
#define W_FT_FCOE 1
|
||||
#define W_FT_PORT 3
|
||||
#define W_FT_VNIC_ID 17
|
||||
#define W_FT_VLAN 17
|
||||
#define W_FT_TOS 8
|
||||
#define W_FT_PROTOCOL 8
|
||||
#define W_FT_ETHERTYPE 16
|
||||
#define W_FT_MACMATCH 9
|
||||
#define W_FT_MPSHITTYPE 3
|
||||
#define W_FT_FRAGMENTATION 1
|
||||
|
||||
/*
|
||||
* Some of the Compressed Filter Tuple fields have internal structure. These
|
||||
* bit shifts/masks describe those structures. All shifts are relative to the
|
||||
* base position of the fields within the Compressed Filter Tuple
|
||||
*/
|
||||
#define S_FT_VLAN_VLD 16
|
||||
#define V_FT_VLAN_VLD(x) ((x) << S_FT_VLAN_VLD)
|
||||
#define F_FT_VLAN_VLD V_FT_VLAN_VLD(1U)
|
||||
|
||||
#define S_FT_VNID_ID_VF 0
|
||||
#define M_FT_VNID_ID_VF 0x7fU
|
||||
#define V_FT_VNID_ID_VF(x) ((x) << S_FT_VNID_ID_VF)
|
||||
#define G_FT_VNID_ID_VF(x) (((x) >> S_FT_VNID_ID_VF) & M_FT_VNID_ID_VF)
|
||||
|
||||
#define S_FT_VNID_ID_PF 7
|
||||
#define M_FT_VNID_ID_PF 0x7U
|
||||
#define V_FT_VNID_ID_PF(x) ((x) << S_FT_VNID_ID_PF)
|
||||
#define G_FT_VNID_ID_PF(x) (((x) >> S_FT_VNID_ID_PF) & M_FT_VNID_ID_PF)
|
||||
|
||||
#define S_FT_VNID_ID_VLD 16
|
||||
#define V_FT_VNID_ID_VLD(x) ((x) << S_FT_VNID_ID_VLD)
|
||||
#define F_FT_VNID_ID_VLD(x) V_FT_VNID_ID_VLD(1U)
|
||||
|
||||
#endif /* __T4_REGS_VALUES_H__ */
|
||||
|
|
|
|||
|
|
@ -633,9 +633,6 @@ t4_attach(device_t dev)
|
|||
if (rc != 0)
|
||||
goto done; /* error message displayed already */
|
||||
|
||||
for (i = 0; i < NCHAN; i++)
|
||||
sc->params.tp.tx_modq[i] = i;
|
||||
|
||||
rc = t4_create_dma_tag(sc);
|
||||
if (rc != 0)
|
||||
goto done; /* error message displayed already */
|
||||
|
|
@ -2089,6 +2086,7 @@ prep_firmware(struct adapter *sc)
|
|||
G_FW_HDR_FW_VER_MINOR(sc->params.fw_vers),
|
||||
G_FW_HDR_FW_VER_MICRO(sc->params.fw_vers),
|
||||
G_FW_HDR_FW_VER_BUILD(sc->params.fw_vers));
|
||||
t4_get_tp_version(sc, &sc->params.tp_vers);
|
||||
|
||||
/* Reset device */
|
||||
if (need_fw_reset &&
|
||||
|
|
@ -6522,13 +6520,14 @@ get_filter_mode(struct adapter *sc, uint32_t *mode)
|
|||
t4_read_indirect(sc, A_TP_PIO_ADDR, A_TP_PIO_DATA, &fconf, 1,
|
||||
A_TP_VLAN_PRI_MAP);
|
||||
|
||||
if (sc->filter_mode != fconf) {
|
||||
if (sc->params.tp.vlan_pri_map != fconf) {
|
||||
log(LOG_WARNING, "%s: cached filter mode out of sync %x %x.\n",
|
||||
device_get_nameunit(sc->dev), sc->filter_mode, fconf);
|
||||
sc->filter_mode = fconf;
|
||||
device_get_nameunit(sc->dev), sc->params.tp.vlan_pri_map,
|
||||
fconf);
|
||||
sc->params.tp.vlan_pri_map = fconf;
|
||||
}
|
||||
|
||||
*mode = fconf_to_mode(sc->filter_mode);
|
||||
*mode = fconf_to_mode(sc->params.tp.vlan_pri_map);
|
||||
|
||||
end_synchronized_op(sc, LOCK_HELD);
|
||||
return (0);
|
||||
|
|
@ -6661,7 +6660,8 @@ set_filter(struct adapter *sc, struct t4_filter *t)
|
|||
}
|
||||
|
||||
/* Validate against the global filter mode */
|
||||
if ((sc->filter_mode | fspec_to_fconf(&t->fs)) != sc->filter_mode) {
|
||||
if ((sc->params.tp.vlan_pri_map | fspec_to_fconf(&t->fs)) !=
|
||||
sc->params.tp.vlan_pri_map) {
|
||||
rc = E2BIG;
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -474,16 +474,11 @@ t4_read_chip_settings(struct adapter *sc)
|
|||
s->s_qpp = r & M_QUEUESPERPAGEPF0;
|
||||
}
|
||||
|
||||
r = t4_read_reg(sc, A_TP_TIMER_RESOLUTION);
|
||||
sc->params.tp.tre = G_TIMERRESOLUTION(r);
|
||||
sc->params.tp.dack_re = G_DELAYEDACKRESOLUTION(r);
|
||||
t4_init_tp_params(sc);
|
||||
|
||||
t4_read_mtu_tbl(sc, sc->params.mtus, NULL);
|
||||
t4_load_mtus(sc, sc->params.mtus, sc->params.a_wnd, sc->params.b_wnd);
|
||||
|
||||
t4_read_indirect(sc, A_TP_PIO_ADDR, A_TP_PIO_DATA, &sc->filter_mode, 1,
|
||||
A_TP_VLAN_PRI_MAP);
|
||||
|
||||
return (rc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include "common/common.h"
|
||||
#include "common/t4_msg.h"
|
||||
#include "common/t4_regs.h"
|
||||
#include "common/t4_regs_values.h"
|
||||
#include "tom/t4_tom_l2t.h"
|
||||
#include "tom/t4_tom.h"
|
||||
|
||||
|
|
@ -384,10 +385,18 @@ t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt,
|
|||
if (toep->ce == NULL)
|
||||
DONT_OFFLOAD_ACTIVE_OPEN(ENOENT);
|
||||
|
||||
INIT_TP_WR(cpl, 0);
|
||||
if (is_t4(sc)) {
|
||||
INIT_TP_WR(cpl, 0);
|
||||
cpl->params = select_ntuple(pi, toep->l2te);
|
||||
} else {
|
||||
struct cpl_t5_act_open_req6 *c5 = (void *)cpl;
|
||||
|
||||
INIT_TP_WR(c5, 0);
|
||||
c5->rsvd = 0;
|
||||
c5->params = select_ntuple(pi, toep->l2te);
|
||||
}
|
||||
OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ6,
|
||||
qid_atid));
|
||||
|
||||
cpl->local_port = inp->inp_lport;
|
||||
cpl->local_ip_hi = *(uint64_t *)&inp->in6p_laddr.s6_addr[0];
|
||||
cpl->local_ip_lo = *(uint64_t *)&inp->in6p_laddr.s6_addr[8];
|
||||
|
|
@ -397,20 +406,19 @@ t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt,
|
|||
cpl->opt0 = calc_opt0(so, pi, toep->l2te, mtu_idx, rscale,
|
||||
toep->rx_credits, toep->ulp_mode);
|
||||
cpl->opt2 = calc_opt2a(so, toep);
|
||||
if (is_t4(sc)) {
|
||||
cpl->params = select_ntuple(pi, toep->l2te,
|
||||
sc->filter_mode);
|
||||
} else {
|
||||
struct cpl_t5_act_open_req6 *c5 = (void *)cpl;
|
||||
|
||||
c5->rsvd = 0;
|
||||
c5->params = select_ntuple(pi, toep->l2te,
|
||||
sc->filter_mode);
|
||||
}
|
||||
} else {
|
||||
struct cpl_act_open_req *cpl = wrtod(wr);
|
||||
|
||||
INIT_TP_WR(cpl, 0);
|
||||
if (is_t4(sc)) {
|
||||
INIT_TP_WR(cpl, 0);
|
||||
cpl->params = select_ntuple(pi, toep->l2te);
|
||||
} else {
|
||||
struct cpl_t5_act_open_req *c5 = (void *)cpl;
|
||||
|
||||
INIT_TP_WR(c5, 0);
|
||||
c5->rsvd = 0;
|
||||
c5->params = select_ntuple(pi, toep->l2te);
|
||||
}
|
||||
OPCODE_TID(cpl) = htobe32(MK_OPCODE_TID(CPL_ACT_OPEN_REQ,
|
||||
qid_atid));
|
||||
inp_4tuple_get(inp, &cpl->local_ip, &cpl->local_port,
|
||||
|
|
@ -418,16 +426,6 @@ t4_connect(struct toedev *tod, struct socket *so, struct rtentry *rt,
|
|||
cpl->opt0 = calc_opt0(so, pi, toep->l2te, mtu_idx, rscale,
|
||||
toep->rx_credits, toep->ulp_mode);
|
||||
cpl->opt2 = calc_opt2a(so, toep);
|
||||
if (is_t4(sc)) {
|
||||
cpl->params = select_ntuple(pi, toep->l2te,
|
||||
sc->filter_mode);
|
||||
} else {
|
||||
struct cpl_t5_act_open_req6 *c5 = (void *)cpl;
|
||||
|
||||
c5->rsvd = 0;
|
||||
c5->params = select_ntuple(pi, toep->l2te,
|
||||
sc->filter_mode);
|
||||
}
|
||||
}
|
||||
|
||||
CTR5(KTR_CXGBE, "%s: atid %u (%s), toep %p, inp %p", __func__,
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ __FBSDID("$FreeBSD$");
|
|||
#include "common/common.h"
|
||||
#include "common/t4_msg.h"
|
||||
#include "common/t4_regs.h"
|
||||
#include "common/t4_regs_values.h"
|
||||
#include "tom/t4_tom_l2t.h"
|
||||
#include "tom/t4_tom.h"
|
||||
|
||||
|
|
@ -513,38 +514,38 @@ calc_opt0(struct socket *so, struct port_info *pi, struct l2t_entry *e,
|
|||
return htobe64(opt0);
|
||||
}
|
||||
|
||||
#define FILTER_SEL_WIDTH_P_FC (3 + 1)
|
||||
#define FILTER_SEL_WIDTH_VIN_P_FC (6 + 7 + FILTER_SEL_WIDTH_P_FC)
|
||||
#define FILTER_SEL_WIDTH_TAG_P_FC (3 + FILTER_SEL_WIDTH_VIN_P_FC)
|
||||
#define FILTER_SEL_WIDTH_VLD_TAG_P_FC (1 + FILTER_SEL_WIDTH_TAG_P_FC)
|
||||
#define VLAN_NONE 0xfff
|
||||
#define FILTER_SEL_VLAN_NONE 0xffff
|
||||
|
||||
uint64_t
|
||||
select_ntuple(struct port_info *pi, struct l2t_entry *e, uint32_t filter_mode)
|
||||
select_ntuple(struct port_info *pi, struct l2t_entry *e)
|
||||
{
|
||||
struct adapter *sc = pi->adapter;
|
||||
struct tp_params *tp = &sc->params.tp;
|
||||
uint16_t viid = pi->viid;
|
||||
uint32_t ntuple = 0;
|
||||
uint64_t ntuple = 0;
|
||||
|
||||
if (filter_mode == HW_TPL_FR_MT_PR_IV_P_FC) {
|
||||
if (e->vlan == VLAN_NONE)
|
||||
ntuple |= FILTER_SEL_VLAN_NONE << FILTER_SEL_WIDTH_P_FC;
|
||||
else {
|
||||
ntuple |= e->vlan << FILTER_SEL_WIDTH_P_FC;
|
||||
ntuple |= 1 << FILTER_SEL_WIDTH_VLD_TAG_P_FC;
|
||||
}
|
||||
ntuple |= e->lport << S_PORT;
|
||||
ntuple |= IPPROTO_TCP << FILTER_SEL_WIDTH_VLD_TAG_P_FC;
|
||||
} else if (filter_mode == HW_TPL_FR_MT_PR_OV_P_FC) {
|
||||
ntuple |= G_FW_VIID_VIN(viid) << FILTER_SEL_WIDTH_P_FC;
|
||||
ntuple |= G_FW_VIID_PFN(viid) << FILTER_SEL_WIDTH_VIN_P_FC;
|
||||
ntuple |= G_FW_VIID_VIVLD(viid) << FILTER_SEL_WIDTH_TAG_P_FC;
|
||||
ntuple |= e->lport << S_PORT;
|
||||
ntuple |= IPPROTO_TCP << FILTER_SEL_WIDTH_VLD_TAG_P_FC;
|
||||
}
|
||||
/*
|
||||
* Initialize each of the fields which we care about which are present
|
||||
* in the Compressed Filter Tuple.
|
||||
*/
|
||||
if (tp->vlan_shift >= 0 && e->vlan != CPL_L2T_VLAN_NONE)
|
||||
ntuple |= (uint64_t)(F_FT_VLAN_VLD | e->vlan) << tp->vlan_shift;
|
||||
|
||||
if (is_t4(pi->adapter))
|
||||
return (htobe32(ntuple));
|
||||
if (tp->port_shift >= 0)
|
||||
ntuple |= (uint64_t)e->lport << tp->port_shift;
|
||||
|
||||
if (tp->protocol_shift >= 0)
|
||||
ntuple |= (uint64_t)IPPROTO_TCP << tp->protocol_shift;
|
||||
|
||||
if (tp->vnic_shift >= 0) {
|
||||
uint32_t vf = G_FW_VIID_VIN(viid);
|
||||
uint32_t pf = G_FW_VIID_PFN(viid);
|
||||
uint32_t vld = G_FW_VIID_VIVLD(viid);
|
||||
|
||||
ntuple |= (uint64_t)(V_FT_VNID_ID_VF(vf) | V_FT_VNID_ID_PF(pf) |
|
||||
V_FT_VNID_ID_VLD(vld)) << tp->vnic_shift;
|
||||
}
|
||||
|
||||
if (is_t4(sc))
|
||||
return (htobe32((uint32_t)ntuple));
|
||||
else
|
||||
return (htobe64(V_FILTER_TUPLE(ntuple)));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -234,7 +234,7 @@ u_long select_rcv_wnd(struct socket *);
|
|||
int select_rcv_wscale(void);
|
||||
uint64_t calc_opt0(struct socket *, struct port_info *, struct l2t_entry *,
|
||||
int, int, int, int);
|
||||
uint64_t select_ntuple(struct port_info *, struct l2t_entry *, uint32_t);
|
||||
uint64_t select_ntuple(struct port_info *, struct l2t_entry *);
|
||||
void set_tcpddp_ulp_mode(struct toepcb *);
|
||||
int negative_advice(int);
|
||||
struct clip_entry *hold_lip(struct tom_data *, struct in6_addr *);
|
||||
|
|
|
|||
Loading…
Reference in a new issue