svn commit: r252705 - in head/sys/dev/cxgbe: . common tom

Navdeep Parhar np at FreeBSD.org
Thu Jul 4 17:55:54 UTC 2013


Author: np
Date: Thu Jul  4 17:55:52 2013
New Revision: 252705
URL: http://svnweb.freebsd.org/changeset/base/252705

Log:
  - 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

Modified:
  head/sys/dev/cxgbe/adapter.h
  head/sys/dev/cxgbe/common/common.h
  head/sys/dev/cxgbe/common/t4_hw.c
  head/sys/dev/cxgbe/common/t4_regs_values.h
  head/sys/dev/cxgbe/t4_main.c
  head/sys/dev/cxgbe/t4_sge.c
  head/sys/dev/cxgbe/tom/t4_connect.c
  head/sys/dev/cxgbe/tom/t4_tom.c
  head/sys/dev/cxgbe/tom/t4_tom.h

Modified: head/sys/dev/cxgbe/adapter.h
==============================================================================
--- head/sys/dev/cxgbe/adapter.h	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/adapter.h	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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 *) */

Modified: head/sys/dev/cxgbe/common/common.h
==============================================================================
--- head/sys/dev/cxgbe/common/common.h	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/common/common.h	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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 *ad
 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);

Modified: head/sys/dev/cxgbe/common/t4_hw.c
==============================================================================
--- head/sys/dev/cxgbe/common/t4_hw.c	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/common/t4_hw.c	Thu Jul  4 17:55:52 2013	(r252705)
@@ -5521,6 +5521,91 @@ int __devinit t4_prep_adapter(struct ada
 	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];

Modified: head/sys/dev/cxgbe/common/t4_regs_values.h
==============================================================================
--- head/sys/dev/cxgbe/common/t4_regs_values.h	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/common/t4_regs_values.h	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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__ */

Modified: head/sys/dev/cxgbe/t4_main.c
==============================================================================
--- head/sys/dev/cxgbe/t4_main.c	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/t4_main.c	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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, uint
 	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
 	}
 
 	/* 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;
 	}

Modified: head/sys/dev/cxgbe/t4_sge.c
==============================================================================
--- head/sys/dev/cxgbe/t4_sge.c	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/t4_sge.c	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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);
 }
 

Modified: head/sys/dev/cxgbe/tom/t4_connect.c
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_connect.c	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/tom/t4_connect.c	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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 so
 		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 so
 		cpl->opt0 = calc_opt0(so, pi, toep->l2te, mtu_idx, rscale,
 		    toep->rx_credits, toep->ulp_mode);
 		cpl->opt2 = calc_opt2a(so, toep);
+	} else {
+		struct cpl_act_open_req *cpl = wrtod(wr);
+
 		if (is_t4(sc)) {
-			cpl->params = select_ntuple(pi, toep->l2te,
-			    sc->filter_mode);
+			INIT_TP_WR(cpl, 0);
+			cpl->params = select_ntuple(pi, toep->l2te);
 		} else {
-			struct cpl_t5_act_open_req6 *c5 = (void *)cpl;
+			struct cpl_t5_act_open_req *c5 = (void *)cpl;
 
+			INIT_TP_WR(c5, 0);
 			c5->rsvd = 0;
-			c5->params = select_ntuple(pi, toep->l2te,
-			    sc->filter_mode);
+			c5->params = select_ntuple(pi, toep->l2te);
 		}
-	} else {
-		struct cpl_act_open_req *cpl = wrtod(wr);
-
-		INIT_TP_WR(cpl, 0);
 		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 so
 		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__,

Modified: head/sys/dev/cxgbe/tom/t4_tom.c
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_tom.c	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/tom/t4_tom.c	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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
 	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;
+
+	/*
+	 * 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 (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;
-        }
+	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(pi->adapter))
-		return (htobe32(ntuple));
+	if (is_t4(sc))
+		return (htobe32((uint32_t)ntuple));
 	else
 		return (htobe64(V_FILTER_TUPLE(ntuple)));
 }

Modified: head/sys/dev/cxgbe/tom/t4_tom.h
==============================================================================
--- head/sys/dev/cxgbe/tom/t4_tom.h	Thu Jul  4 17:54:46 2013	(r252704)
+++ head/sys/dev/cxgbe/tom/t4_tom.h	Thu Jul  4 17:55:52 2013	(r252705)
@@ -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 *);


More information about the svn-src-all mailing list