diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/sge.c | 30 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 51 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4/t4_regs.h | 10 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/sge.c | 31 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/t4vf_common.h | 1 | ||||
-rw-r--r-- | drivers/net/ethernet/chelsio/cxgb4vf/t4vf_hw.c | 23 |
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) | |||
2914 | int t4_sge_init(struct adapter *adap) | 2914 | int 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 | */ |
135 | struct sge_params { | 135 | struct 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); |