aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHariprasad Shenai <hariprasad@chelsio.com>2014-11-07 06:36:30 -0500
committerDavid S. Miller <davem@davemloft.net>2014-11-10 14:15:03 -0500
commitce8f407a3cc7fc58804b9135e7c8780f0f8c2a8d (patch)
treeadaef931f4064d2969ca78d987dccace85607d3a
parent65f6ecc93e7cca888a96a68cf6b5292dff1982b6 (diff)
cxgb4/cxgb4vf: For T5 use Packing and Padding Boundaries for SGE DMA transfers
T5 introduces the ability to have separate Packing and Padding Boundaries for SGE DMA transfers from the chip to Host Memory. This change set takes advantage of that to set up a smaller Padding Boundary to conserve PCI Link and Memory Bandwidth with T5. Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/sge.c30
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_hw.c51
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4/t4_regs.h10
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/sge.c31
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h1
-rw-r--r--drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c23
6 files changed, 135 insertions, 11 deletions
diff --git a/drivers/net/ethernet/chelsio/cxgb4/sge.c b/drivers/net/ethernet/chelsio/cxgb4/sge.c
index 5e1b314e11af..39f2b13e66c7 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/sge.c
@@ -2914,7 +2914,8 @@ static int t4_sge_init_hard(struct adapter *adap)
2914int t4_sge_init(struct adapter *adap) 2914int t4_sge_init(struct adapter *adap)
2915{ 2915{
2916 struct sge *s = &adap->sge; 2916 struct sge *s = &adap->sge;
2917 u32 sge_control, sge_conm_ctrl; 2917 u32 sge_control, sge_control2, sge_conm_ctrl;
2918 unsigned int ingpadboundary, ingpackboundary;
2918 int ret, egress_threshold; 2919 int ret, egress_threshold;
2919 2920
2920 /* 2921 /*
@@ -2924,8 +2925,31 @@ int t4_sge_init(struct adapter *adap)
2924 sge_control = t4_read_reg(adap, SGE_CONTROL); 2925 sge_control = t4_read_reg(adap, SGE_CONTROL);
2925 s->pktshift = PKTSHIFT_GET(sge_control); 2926 s->pktshift = PKTSHIFT_GET(sge_control);
2926 s->stat_len = (sge_control & EGRSTATUSPAGESIZE_MASK) ? 128 : 64; 2927 s->stat_len = (sge_control & EGRSTATUSPAGESIZE_MASK) ? 128 : 64;
2927 s->fl_align = 1 << (INGPADBOUNDARY_GET(sge_control) + 2928
2928 X_INGPADBOUNDARY_SHIFT); 2929 /* T4 uses a single control field to specify both the PCIe Padding and
2930 * Packing Boundary. T5 introduced the ability to specify these
2931 * separately. The actual Ingress Packet Data alignment boundary
2932 * within Packed Buffer Mode is the maximum of these two
2933 * specifications.
2934 */
2935 ingpadboundary = 1 << (INGPADBOUNDARY_GET(sge_control) +
2936 X_INGPADBOUNDARY_SHIFT);
2937 if (is_t4(adap->params.chip)) {
2938 s->fl_align = ingpadboundary;
2939 } else {
2940 /* T5 has a different interpretation of one of the PCIe Packing
2941 * Boundary values.
2942 */
2943 sge_control2 = t4_read_reg(adap, SGE_CONTROL2_A);
2944 ingpackboundary = INGPACKBOUNDARY_G(sge_control2);
2945 if (ingpackboundary == INGPACKBOUNDARY_16B_X)
2946 ingpackboundary = 16;
2947 else
2948 ingpackboundary = 1 << (ingpackboundary +
2949 INGPACKBOUNDARY_SHIFT_X);
2950
2951 s->fl_align = max(ingpadboundary, ingpackboundary);
2952 }
2929 2953
2930 if (adap->flags & USING_SOFT_PARAMS) 2954 if (adap->flags & USING_SOFT_PARAMS)
2931 ret = t4_sge_init_soft(adap); 2955 ret = t4_sge_init_soft(adap);
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index a9d9d74e4f09..163a2a14948c 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -3129,12 +3129,51 @@ int t4_fixup_host_params(struct adapter *adap, unsigned int page_size,
3129 HOSTPAGESIZEPF6(sge_hps) | 3129 HOSTPAGESIZEPF6(sge_hps) |
3130 HOSTPAGESIZEPF7(sge_hps)); 3130 HOSTPAGESIZEPF7(sge_hps));
3131 3131
3132 t4_set_reg_field(adap, SGE_CONTROL, 3132 if (is_t4(adap->params.chip)) {
3133 INGPADBOUNDARY_MASK | 3133 t4_set_reg_field(adap, SGE_CONTROL,
3134 EGRSTATUSPAGESIZE_MASK, 3134 INGPADBOUNDARY_MASK |
3135 INGPADBOUNDARY(fl_align_log - 5) | 3135 EGRSTATUSPAGESIZE_MASK,
3136 EGRSTATUSPAGESIZE(stat_len != 64)); 3136 INGPADBOUNDARY(fl_align_log - 5) |
3137 3137 EGRSTATUSPAGESIZE(stat_len != 64));
3138 } else {
3139 /* T5 introduced the separation of the Free List Padding and
3140 * Packing Boundaries. Thus, we can select a smaller Padding
3141 * Boundary to avoid uselessly chewing up PCIe Link and Memory
3142 * Bandwidth, and use a Packing Boundary which is large enough
3143 * to avoid false sharing between CPUs, etc.
3144 *
3145 * For the PCI Link, the smaller the Padding Boundary the
3146 * better. For the Memory Controller, a smaller Padding
3147 * Boundary is better until we cross under the Memory Line
3148 * Size (the minimum unit of transfer to/from Memory). If we
3149 * have a Padding Boundary which is smaller than the Memory
3150 * Line Size, that'll involve a Read-Modify-Write cycle on the
3151 * Memory Controller which is never good. For T5 the smallest
3152 * Padding Boundary which we can select is 32 bytes which is
3153 * larger than any known Memory Controller Line Size so we'll
3154 * use that.
3155 *
3156 * T5 has a different interpretation of the "0" value for the
3157 * Packing Boundary. This corresponds to 16 bytes instead of
3158 * the expected 32 bytes. We never have a Packing Boundary
3159 * less than 32 bytes so we can't use that special value but
3160 * on the other hand, if we wanted 32 bytes, the best we can
3161 * really do is 64 bytes.
3162 */
3163 if (fl_align <= 32) {
3164 fl_align = 64;
3165 fl_align_log = 6;
3166 }
3167 t4_set_reg_field(adap, SGE_CONTROL,
3168 INGPADBOUNDARY_MASK |
3169 EGRSTATUSPAGESIZE_MASK,
3170 INGPADBOUNDARY(INGPCIEBOUNDARY_32B_X) |
3171 EGRSTATUSPAGESIZE(stat_len != 64));
3172 t4_set_reg_field(adap, SGE_CONTROL2_A,
3173 INGPACKBOUNDARY_V(INGPACKBOUNDARY_M),
3174 INGPACKBOUNDARY_V(fl_align_log -
3175 INGPACKBOUNDARY_SHIFT_X));
3176 }
3138 /* 3177 /*
3139 * Adjust various SGE Free List Host Buffer Sizes. 3178 * Adjust various SGE Free List Host Buffer Sizes.
3140 * 3179 *
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
index a1024db5dc13..8d2de1006b08 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
@@ -95,6 +95,7 @@
95#define X_INGPADBOUNDARY_SHIFT 5 95#define X_INGPADBOUNDARY_SHIFT 5
96 96
97#define SGE_CONTROL 0x1008 97#define SGE_CONTROL 0x1008
98#define SGE_CONTROL2_A 0x1124
98#define DCASYSTYPE 0x00080000U 99#define DCASYSTYPE 0x00080000U
99#define RXPKTCPLMODE_MASK 0x00040000U 100#define RXPKTCPLMODE_MASK 0x00040000U
100#define RXPKTCPLMODE_SHIFT 18 101#define RXPKTCPLMODE_SHIFT 18
@@ -106,6 +107,7 @@
106#define PKTSHIFT_SHIFT 10 107#define PKTSHIFT_SHIFT 10
107#define PKTSHIFT(x) ((x) << PKTSHIFT_SHIFT) 108#define PKTSHIFT(x) ((x) << PKTSHIFT_SHIFT)
108#define PKTSHIFT_GET(x) (((x) & PKTSHIFT_MASK) >> PKTSHIFT_SHIFT) 109#define PKTSHIFT_GET(x) (((x) & PKTSHIFT_MASK) >> PKTSHIFT_SHIFT)
110#define INGPCIEBOUNDARY_32B_X 0
109#define INGPCIEBOUNDARY_MASK 0x00000380U 111#define INGPCIEBOUNDARY_MASK 0x00000380U
110#define INGPCIEBOUNDARY_SHIFT 7 112#define INGPCIEBOUNDARY_SHIFT 7
111#define INGPCIEBOUNDARY(x) ((x) << INGPCIEBOUNDARY_SHIFT) 113#define INGPCIEBOUNDARY(x) ((x) << INGPCIEBOUNDARY_SHIFT)
@@ -114,6 +116,14 @@
114#define INGPADBOUNDARY(x) ((x) << INGPADBOUNDARY_SHIFT) 116#define INGPADBOUNDARY(x) ((x) << INGPADBOUNDARY_SHIFT)
115#define INGPADBOUNDARY_GET(x) (((x) & INGPADBOUNDARY_MASK) \ 117#define INGPADBOUNDARY_GET(x) (((x) & INGPADBOUNDARY_MASK) \
116 >> INGPADBOUNDARY_SHIFT) 118 >> INGPADBOUNDARY_SHIFT)
119#define INGPACKBOUNDARY_16B_X 0
120#define INGPACKBOUNDARY_SHIFT_X 5
121
122#define INGPACKBOUNDARY_S 16
123#define INGPACKBOUNDARY_M 0x7U
124#define INGPACKBOUNDARY_V(x) ((x) << INGPACKBOUNDARY_S)
125#define INGPACKBOUNDARY_G(x) (((x) >> INGPACKBOUNDARY_S) \
126 & INGPACKBOUNDARY_M)
117#define EGRPCIEBOUNDARY_MASK 0x0000000eU 127#define EGRPCIEBOUNDARY_MASK 0x0000000eU
118#define EGRPCIEBOUNDARY_SHIFT 1 128#define EGRPCIEBOUNDARY_SHIFT 1
119#define EGRPCIEBOUNDARY(x) ((x) << EGRPCIEBOUNDARY_SHIFT) 129#define EGRPCIEBOUNDARY(x) ((x) << EGRPCIEBOUNDARY_SHIFT)
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
index a18830d8aa6d..cd5b7896cb67 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/sge.c
@@ -2436,6 +2436,7 @@ int t4vf_sge_init(struct adapter *adapter)
2436 u32 fl0 = sge_params->sge_fl_buffer_size[0]; 2436 u32 fl0 = sge_params->sge_fl_buffer_size[0];
2437 u32 fl1 = sge_params->sge_fl_buffer_size[1]; 2437 u32 fl1 = sge_params->sge_fl_buffer_size[1];
2438 struct sge *s = &adapter->sge; 2438 struct sge *s = &adapter->sge;
2439 unsigned int ingpadboundary, ingpackboundary;
2439 2440
2440 /* 2441 /*
2441 * Start by vetting the basic SGE parameters which have been set up by 2442 * Start by vetting the basic SGE parameters which have been set up by
@@ -2460,8 +2461,34 @@ int t4vf_sge_init(struct adapter *adapter)
2460 s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_MASK) 2461 s->stat_len = ((sge_params->sge_control & EGRSTATUSPAGESIZE_MASK)
2461 ? 128 : 64); 2462 ? 128 : 64);
2462 s->pktshift = PKTSHIFT_GET(sge_params->sge_control); 2463 s->pktshift = PKTSHIFT_GET(sge_params->sge_control);
2463 s->fl_align = 1 << (INGPADBOUNDARY_GET(sge_params->sge_control) + 2464
2464 SGE_INGPADBOUNDARY_SHIFT); 2465 /* T4 uses a single control field to specify both the PCIe Padding and
2466 * Packing Boundary. T5 introduced the ability to specify these
2467 * separately. The actual Ingress Packet Data alignment boundary
2468 * within Packed Buffer Mode is the maximum of these two
2469 * specifications. (Note that it makes no real practical sense to
2470 * have the Pading Boudary be larger than the Packing Boundary but you
2471 * could set the chip up that way and, in fact, legacy T4 code would
2472 * end doing this because it would initialize the Padding Boundary and
2473 * leave the Packing Boundary initialized to 0 (16 bytes).)
2474 */
2475 ingpadboundary = 1 << (INGPADBOUNDARY_GET(sge_params->sge_control) +
2476 X_INGPADBOUNDARY_SHIFT);
2477 if (is_t4(adapter->params.chip)) {
2478 s->fl_align = ingpadboundary;
2479 } else {
2480 /* T5 has a different interpretation of one of the PCIe Packing
2481 * Boundary values.
2482 */
2483 ingpackboundary = INGPACKBOUNDARY_G(sge_params->sge_control2);
2484 if (ingpackboundary == INGPACKBOUNDARY_16B_X)
2485 ingpackboundary = 16;
2486 else
2487 ingpackboundary = 1 << (ingpackboundary +
2488 INGPACKBOUNDARY_SHIFT_X);
2489
2490 s->fl_align = max(ingpadboundary, ingpackboundary);
2491 }
2465 2492
2466 /* 2493 /*
2467 * Set up tasklet timers. 2494 * Set up tasklet timers.
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
index 95df61dcb4ce..b5c301d9565e 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h
@@ -134,6 +134,7 @@ struct dev_params {
134 */ 134 */
135struct sge_params { 135struct sge_params {
136 u32 sge_control; /* padding, boundaries, lengths, etc. */ 136 u32 sge_control; /* padding, boundaries, lengths, etc. */
137 u32 sge_control2; /* T5: more of the same */
137 u32 sge_host_page_size; /* RDMA page sizes */ 138 u32 sge_host_page_size; /* RDMA page sizes */
138 u32 sge_queues_per_page; /* RDMA queues/page */ 139 u32 sge_queues_per_page; /* RDMA queues/page */
139 u32 sge_user_mode_limits; /* limits for BAR2 user mode accesses */ 140 u32 sge_user_mode_limits; /* limits for BAR2 user mode accesses */
diff --git a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
index e984fdc48ba2..dc30d2852850 100644
--- a/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c
@@ -468,6 +468,29 @@ int t4vf_get_sge_params(struct adapter *adapter)
468 sge_params->sge_timer_value_2_and_3 = vals[5]; 468 sge_params->sge_timer_value_2_and_3 = vals[5];
469 sge_params->sge_timer_value_4_and_5 = vals[6]; 469 sge_params->sge_timer_value_4_and_5 = vals[6];
470 470
471 /* T4 uses a single control field to specify both the PCIe Padding and
472 * Packing Boundary. T5 introduced the ability to specify these
473 * separately with the Padding Boundary in SGE_CONTROL and and Packing
474 * Boundary in SGE_CONTROL2. So for T5 and later we need to grab
475 * SGE_CONTROL in order to determine how ingress packet data will be
476 * laid out in Packed Buffer Mode. Unfortunately, older versions of
477 * the firmware won't let us retrieve SGE_CONTROL2 so if we get a
478 * failure grabbing it we throw an error since we can't figure out the
479 * right value.
480 */
481 if (!is_t4(adapter->params.chip)) {
482 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
483 FW_PARAMS_PARAM_XYZ(SGE_CONTROL2_A));
484 v = t4vf_query_params(adapter, 1, params, vals);
485 if (v != FW_SUCCESS) {
486 dev_err(adapter->pdev_dev,
487 "Unable to get SGE Control2; "
488 "probably old firmware.\n");
489 return v;
490 }
491 sge_params->sge_control2 = vals[0];
492 }
493
471 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) | 494 params[0] = (FW_PARAMS_MNEM(FW_PARAMS_MNEM_REG) |
472 FW_PARAMS_PARAM_XYZ(SGE_INGRESS_RX_THRESHOLD)); 495 FW_PARAMS_PARAM_XYZ(SGE_INGRESS_RX_THRESHOLD));
473 v = t4vf_query_params(adapter, 1, params, vals); 496 v = t4vf_query_params(adapter, 1, params, vals);