cxgb4: Pass in a Congestion Channel Map to t4_sge_alloc_rxq()
authorHariprasad Shenai <hariprasad@chelsio.com>
Tue, 5 May 2015 09:29:53 +0000 (14:59 +0530)
committerDavid S. Miller <davem@davemloft.net>
Tue, 5 May 2015 23:31:49 +0000 (19:31 -0400)
Passes a Congestion Channel Map to t4_sge_alloc_rxq()
for the Ethernet RX Queues based on the MPS Buffer Group Map
of the TX Channel rather than just the TX Channel Map.
Also, in t4_sge_alloc_rxq() for T5, setting up the
Congestion Manager values of the new RX Ethernet Queue is
done by firmware now.

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/chelsio/cxgb4/sge.c
drivers/net/ethernet/chelsio/cxgb4/t4_values.h
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h

index 6397d6ccad1c9dda9488b2c068677b76901c20f7..a9002b1a8ea91f1c3dcc6ac02838f26c9d871baa 100644 (file)
@@ -2551,6 +2551,41 @@ int t4_sge_alloc_rxq(struct adapter *adap, struct sge_rspq *iq, bool fwevtq,
                                             &fl->bar2_qid);
                refill_fl(adap, fl, fl_cap(fl), GFP_KERNEL);
        }
+
+       /* For T5 and later we attempt to set up the Congestion Manager values
+        * of the new RX Ethernet Queue.  This should really be handled by
+        * firmware because it's more complex than any host driver wants to
+        * get involved with and it's different per chip and this is almost
+        * certainly wrong.  Firmware would be wrong as well, but it would be
+        * a lot easier to fix in one place ...  For now we do something very
+        * simple (and hopefully less wrong).
+        */
+       if (!is_t4(adap->params.chip) && cong >= 0) {
+               u32 param, val;
+               int i;
+
+               param = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DMAQ) |
+                        FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DMAQ_CONM_CTXT) |
+                        FW_PARAMS_PARAM_YZ_V(iq->cntxt_id));
+               if (cong == 0) {
+                       val = CONMCTXT_CNGTPMODE_V(CONMCTXT_CNGTPMODE_QUEUE_X);
+               } else {
+                       val =
+                           CONMCTXT_CNGTPMODE_V(CONMCTXT_CNGTPMODE_CHANNEL_X);
+                       for (i = 0; i < 4; i++) {
+                               if (cong & (1 << i))
+                                       val |=
+                                            CONMCTXT_CNGCHMAP_V(1 << (i << 2));
+                       }
+               }
+               ret = t4_set_params(adap, adap->mbox, adap->fn, 0, 1,
+                                   &param, &val);
+               if (ret)
+                       dev_warn(adap->pdev_dev, "Failed to set Congestion"
+                                " Manager Context for Ingress Queue %d: %d\n",
+                                iq->cntxt_id, -ret);
+       }
+
        return 0;
 
 fl_nomem:
index 19b2dcf6acdebbd841c3869e3340de17c750a505..c4d9952f814bef05a29a4db8cf5f189e7261853f 100644 (file)
 #define SGE_TIMERREGS                  6
 #define TIMERREG_COUNTER0_X            0
 
+/* Congestion Manager Definitions.
+ */
+#define CONMCTXT_CNGTPMODE_S           19
+#define CONMCTXT_CNGTPMODE_V(x)                ((x) << CONMCTXT_CNGTPMODE_S)
+#define CONMCTXT_CNGCHMAP_S            0
+#define CONMCTXT_CNGCHMAP_V(x)         ((x) << CONMCTXT_CNGCHMAP_S)
+#define CONMCTXT_CNGTPMODE_CHANNEL_X   2
+#define CONMCTXT_CNGTPMODE_QUEUE_X     1
+
 /* T5 and later support a new BAR2-based doorbell mechanism for Egress Queues.
  * The User Doorbells are each 128 bytes in length with a Simple Doorbell at
  * offsets 8x and a Write Combining single 64-byte Egress Queue Unit
index e34efb7a858f3260a9fb85a01a2dff295c93a82c..d75fca7695eb7d9734a2bc37f65b7aca117fb17b 100644 (file)
@@ -1123,6 +1123,7 @@ enum fw_params_param_dmaq {
        FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11,
        FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12,
        FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH = 0x13,
+       FW_PARAMS_PARAM_DMAQ_CONM_CTXT = 0x20,
 };
 
 enum fw_params_param_dev_diag {