aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);