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 *);
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to