hc
2024-02-19 1c055e55a242a33e574e48be530e06770a210dcd
kernel/drivers/net/ethernet/qlogic/qed/qed_init_fw_funcs.c
....@@ -1,33 +1,7 @@
1
+// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
12 /* QLogic qed NIC Driver
23 * Copyright (c) 2015-2017 QLogic Corporation
3
- *
4
- * This software is available to you under a choice of one of two
5
- * licenses. You may choose to be licensed under the terms of the GNU
6
- * General Public License (GPL) Version 2, available from the file
7
- * COPYING in the main directory of this source tree, or the
8
- * OpenIB.org BSD license below:
9
- *
10
- * Redistribution and use in source and binary forms, with or
11
- * without modification, are permitted provided that the following
12
- * conditions are met:
13
- *
14
- * - Redistributions of source code must retain the above
15
- * copyright notice, this list of conditions and the following
16
- * disclaimer.
17
- *
18
- * - Redistributions in binary form must reproduce the above
19
- * copyright notice, this list of conditions and the following
20
- * disclaimer in the documentation and /or other materials
21
- * provided with the distribution.
22
- *
23
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
- * SOFTWARE.
4
+ * Copyright (c) 2019-2020 Marvell International Ltd.
315 */
326
337 #include <linux/types.h>
....@@ -44,9 +18,9 @@
4418 #define CDU_VALIDATION_DEFAULT_CFG 61
4519
4620 static u16 con_region_offsets[3][NUM_OF_CONNECTION_TYPES_E4] = {
47
- {400, 336, 352, 304, 304, 384, 416, 352}, /* region 3 offsets */
48
- {528, 496, 416, 448, 448, 512, 544, 480}, /* region 4 offsets */
49
- {608, 544, 496, 512, 576, 592, 624, 560} /* region 5 offsets */
21
+ {400, 336, 352, 368, 304, 384, 416, 352}, /* region 3 offsets */
22
+ {528, 496, 416, 512, 448, 512, 544, 480}, /* region 4 offsets */
23
+ {608, 544, 496, 576, 576, 592, 624, 560} /* region 5 offsets */
5024 };
5125
5226 static u16 task_region_offsets[1][NUM_OF_CONNECTION_TYPES_E4] = {
....@@ -60,6 +34,9 @@
6034 #define QM_PQ_SIZE_256B(pq_size) (pq_size ? DIV_ROUND_UP(pq_size, \
6135 0x100) - 1 : 0)
6236 #define QM_INVALID_PQ_ID 0xffff
37
+
38
+/* Max link speed (in Mbps) */
39
+#define QM_MAX_LINK_SPEED 100000
6340
6441 /* Feature enable */
6542 #define QM_BYPASS_EN 1
....@@ -128,8 +105,6 @@
128105 /* Pure LB CmdQ lines (+spare) */
129106 #define PBF_CMDQ_PURE_LB_LINES 150
130107
131
-#define PBF_CMDQ_LINES_E5_RSVD_RATIO 8
132
-
133108 #define PBF_CMDQ_LINES_RT_OFFSET(ext_voq) \
134109 (PBF_REG_YCMD_QS_NUM_LINES_VOQ0_RT_OFFSET + \
135110 (ext_voq) * (PBF_REG_YCMD_QS_NUM_LINES_VOQ1_RT_OFFSET - \
....@@ -140,6 +115,9 @@
140115 (ext_voq) * (PBF_REG_BTB_GUARANTEED_VOQ1_RT_OFFSET - \
141116 PBF_REG_BTB_GUARANTEED_VOQ0_RT_OFFSET))
142117
118
+/* Returns the VOQ line credit for the specified number of PBF command lines.
119
+ * PBF lines are specified in 256b units.
120
+ */
143121 #define QM_VOQ_LINE_CRD(pbf_cmd_lines) \
144122 ((((pbf_cmd_lines) - 4) * 2) | QM_LINE_CRD_REG_SIGN_BIT)
145123
....@@ -178,31 +156,36 @@
178156 cmd ## _ ## field, \
179157 value)
180158
181
-#define QM_INIT_TX_PQ_MAP(p_hwfn, map, chip, pq_id, rl_valid, vp_pq_id, rl_id, \
182
- ext_voq, wrr) \
183
- do { \
184
- typeof(map) __map; \
185
- memset(&__map, 0, sizeof(__map)); \
186
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _PQ_VALID, 1); \
187
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _RL_VALID, \
188
- rl_valid); \
189
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _VP_PQ_ID, \
190
- vp_pq_id); \
191
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _RL_ID, rl_id); \
192
- SET_FIELD(__map.reg, QM_RF_PQ_MAP_ ## chip ## _VOQ, ext_voq); \
193
- SET_FIELD(__map.reg, \
194
- QM_RF_PQ_MAP_ ## chip ## _WRR_WEIGHT_GROUP, wrr); \
195
- STORE_RT_REG(p_hwfn, QM_REG_TXPQMAP_RT_OFFSET + (pq_id), \
196
- *((u32 *)&__map)); \
197
- (map) = __map; \
159
+#define QM_INIT_TX_PQ_MAP(p_hwfn, map, chip, pq_id, vp_pq_id, rl_valid, \
160
+ rl_id, ext_voq, wrr) \
161
+ do { \
162
+ u32 __reg = 0; \
163
+ \
164
+ BUILD_BUG_ON(sizeof((map).reg) != sizeof(__reg)); \
165
+ \
166
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_PQ_VALID, 1); \
167
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_VALID, \
168
+ !!(rl_valid)); \
169
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VP_PQ_ID, (vp_pq_id)); \
170
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_RL_ID, (rl_id)); \
171
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_VOQ, (ext_voq)); \
172
+ SET_FIELD(__reg, QM_RF_PQ_MAP_##chip##_WRR_WEIGHT_GROUP, \
173
+ (wrr)); \
174
+ \
175
+ STORE_RT_REG((p_hwfn), QM_REG_TXPQMAP_RT_OFFSET + (pq_id), \
176
+ __reg); \
177
+ (map).reg = cpu_to_le32(__reg); \
198178 } while (0)
199179
200180 #define WRITE_PQ_INFO_TO_RAM 1
201181 #define PQ_INFO_ELEMENT(vp, pf, tc, port, rl_valid, rl) \
202182 (((vp) << 0) | ((pf) << 12) | ((tc) << 16) | ((port) << 20) | \
203
- ((rl_valid) << 22) | ((rl) << 24))
183
+ ((rl_valid ? 1 : 0) << 22) | (((rl) & 255) << 24) | \
184
+ (((rl) >> 8) << 9))
185
+
204186 #define PQ_INFO_RAM_GRC_ADDRESS(pq_id) \
205
- (XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM + 21776 + (pq_id) * 4)
187
+ XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM + \
188
+ XSTORM_PQ_INFO_OFFSET(pq_id)
206189
207190 /******************** INTERNAL IMPLEMENTATION *********************/
208191
....@@ -228,9 +211,6 @@
228211 STORE_RT_REG(p_hwfn,
229212 QM_REG_RLPFVOQENABLE_RT_OFFSET,
230213 (u32)voq_bit_mask);
231
- if (num_ext_voqs >= 32)
232
- STORE_RT_REG(p_hwfn, QM_REG_RLPFVOQENABLE_MSB_RT_OFFSET,
233
- (u32)(voq_bit_mask >> 32));
234214
235215 /* Write RL period */
236216 STORE_RT_REG(p_hwfn,
....@@ -259,12 +239,12 @@
259239 QM_WFQ_UPPER_BOUND);
260240 }
261241
262
-/* Prepare VPORT RL enable/disable runtime init values */
263
-static void qed_enable_vport_rl(struct qed_hwfn *p_hwfn, bool vport_rl_en)
242
+/* Prepare global RL enable/disable runtime init values */
243
+static void qed_enable_global_rl(struct qed_hwfn *p_hwfn, bool global_rl_en)
264244 {
265245 STORE_RT_REG(p_hwfn, QM_REG_RLGLBLENABLE_RT_OFFSET,
266
- vport_rl_en ? 1 : 0);
267
- if (vport_rl_en) {
246
+ global_rl_en ? 1 : 0);
247
+ if (global_rl_en) {
268248 /* Write RL period (use timer 0 only) */
269249 STORE_RT_REG(p_hwfn,
270250 QM_REG_RLGLBLPERIOD_0_RT_OFFSET,
....@@ -331,8 +311,7 @@
331311 continue;
332312
333313 /* Find number of command queue lines to divide between the
334
- * active physical TCs. In E5, 1/8 of the lines are reserved.
335
- * the lines for pure LB TC are subtracted.
314
+ * active physical TCs.
336315 */
337316 phys_lines = port_params[port_id].num_pbf_cmd_lines;
338317 phys_lines -= PBF_CMDQ_PURE_LB_LINES;
....@@ -361,11 +340,30 @@
361340 ext_voq = qed_get_ext_voq(p_hwfn,
362341 port_id,
363342 PURE_LB_TC, max_phys_tcs_per_port);
364
- qed_cmdq_lines_voq_rt_init(p_hwfn,
365
- ext_voq, PBF_CMDQ_PURE_LB_LINES);
343
+ qed_cmdq_lines_voq_rt_init(p_hwfn, ext_voq,
344
+ PBF_CMDQ_PURE_LB_LINES);
366345 }
367346 }
368347
348
+/* Prepare runtime init values to allocate guaranteed BTB blocks for the
349
+ * specified port. The guaranteed BTB space is divided between the TCs as
350
+ * follows (shared space Is currently not used):
351
+ * 1. Parameters:
352
+ * B - BTB blocks for this port
353
+ * C - Number of physical TCs for this port
354
+ * 2. Calculation:
355
+ * a. 38 blocks (9700B jumbo frame) are allocated for global per port
356
+ * headroom.
357
+ * b. B = B - 38 (remainder after global headroom allocation).
358
+ * c. MAX(38,B/(C+0.7)) blocks are allocated for the pure LB VOQ.
359
+ * d. B = B - MAX(38, B/(C+0.7)) (remainder after pure LB allocation).
360
+ * e. B/C blocks are allocated for each physical TC.
361
+ * Assumptions:
362
+ * - MTU is up to 9700 bytes (38 blocks)
363
+ * - All TCs are considered symmetrical (same rate and packet size)
364
+ * - No optimization for lossy TC (all are considered lossless). Shared space
365
+ * is not enabled and allocated for each TC.
366
+ */
369367 static void qed_btb_blocks_rt_init(
370368 struct qed_hwfn *p_hwfn,
371369 u8 max_ports_per_engine,
....@@ -424,6 +422,34 @@
424422 }
425423 }
426424
425
+/* Prepare runtime init values for the specified RL.
426
+ * Set max link speed (100Gbps) per rate limiter.
427
+ * Return -1 on error.
428
+ */
429
+static int qed_global_rl_rt_init(struct qed_hwfn *p_hwfn)
430
+{
431
+ u32 upper_bound = QM_VP_RL_UPPER_BOUND(QM_MAX_LINK_SPEED) |
432
+ (u32)QM_RL_CRD_REG_SIGN_BIT;
433
+ u32 inc_val;
434
+ u16 rl_id;
435
+
436
+ /* Go over all global RLs */
437
+ for (rl_id = 0; rl_id < MAX_QM_GLOBAL_RLS; rl_id++) {
438
+ inc_val = QM_RL_INC_VAL(QM_MAX_LINK_SPEED);
439
+
440
+ STORE_RT_REG(p_hwfn,
441
+ QM_REG_RLGLBLCRD_RT_OFFSET + rl_id,
442
+ (u32)QM_RL_CRD_REG_SIGN_BIT);
443
+ STORE_RT_REG(p_hwfn,
444
+ QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + rl_id,
445
+ upper_bound);
446
+ STORE_RT_REG(p_hwfn,
447
+ QM_REG_RLGLBLINCVAL_RT_OFFSET + rl_id, inc_val);
448
+ }
449
+
450
+ return 0;
451
+}
452
+
427453 /* Prepare Tx PQ mapping runtime init values for the specified PF */
428454 static void qed_tx_pq_map_rt_init(struct qed_hwfn *p_hwfn,
429455 struct qed_ptt *p_ptt,
....@@ -460,18 +486,17 @@
460486
461487 /* Go over all Tx PQs */
462488 for (i = 0, pq_id = p_params->start_pq; i < num_pqs; i++, pq_id++) {
463
- u8 ext_voq, vport_id_in_pf, tc_id = pq_params[i].tc_id;
464
- u32 max_qm_global_rls = MAX_QM_GLOBAL_RLS;
489
+ u16 *p_first_tx_pq_id, vport_id_in_pf;
465490 struct qm_rf_pq_map_e4 tx_pq_map;
466
- bool is_vf_pq, rl_valid;
467
- u16 *p_first_tx_pq_id;
491
+ u8 tc_id = pq_params[i].tc_id;
492
+ bool is_vf_pq;
493
+ u8 ext_voq;
468494
469495 ext_voq = qed_get_ext_voq(p_hwfn,
470496 pq_params[i].port_id,
471497 tc_id,
472498 p_params->max_phys_tcs_per_port);
473499 is_vf_pq = (i >= p_params->num_pf_pqs);
474
- rl_valid = pq_params[i].rl_valid > 0;
475500
476501 /* Update first Tx PQ of VPORT/TC */
477502 vport_id_in_pf = pq_params[i].vport_id - p_params->start_vport;
....@@ -492,21 +517,14 @@
492517 map_val);
493518 }
494519
495
- /* Check RL ID */
496
- if (rl_valid && pq_params[i].vport_id >= max_qm_global_rls) {
497
- DP_NOTICE(p_hwfn,
498
- "Invalid VPORT ID for rate limiter configuration\n");
499
- rl_valid = false;
500
- }
501
-
502520 /* Prepare PQ map entry */
503521 QM_INIT_TX_PQ_MAP(p_hwfn,
504522 tx_pq_map,
505523 E4,
506524 pq_id,
507
- rl_valid ? 1 : 0,
508525 *p_first_tx_pq_id,
509
- rl_valid ? pq_params[i].vport_id : 0,
526
+ pq_params[i].rl_valid,
527
+ pq_params[i].rl_id,
510528 ext_voq, pq_params[i].wrr_group);
511529
512530 /* Set PQ base address */
....@@ -529,9 +547,8 @@
529547 p_params->pf_id,
530548 tc_id,
531549 pq_params[i].port_id,
532
- rl_valid ? 1 : 0,
533
- rl_valid ?
534
- pq_params[i].vport_id : 0);
550
+ pq_params[i].rl_valid,
551
+ pq_params[i].rl_id);
535552 qed_wr(p_hwfn, p_ptt, PQ_INFO_RAM_GRC_ADDRESS(pq_id),
536553 pq_info);
537554 }
....@@ -669,19 +686,19 @@
669686 * Return -1 on error.
670687 */
671688 static int qed_vp_wfq_rt_init(struct qed_hwfn *p_hwfn,
672
- u8 num_vports,
689
+ u16 num_vports,
673690 struct init_qm_vport_params *vport_params)
674691 {
675
- u16 vport_pq_id;
692
+ u16 vport_pq_id, i;
676693 u32 inc_val;
677
- u8 tc, i;
694
+ u8 tc;
678695
679696 /* Go over all PF VPORTs */
680697 for (i = 0; i < num_vports; i++) {
681
- if (!vport_params[i].vport_wfq)
698
+ if (!vport_params[i].wfq)
682699 continue;
683700
684
- inc_val = QM_WFQ_INC_VAL(vport_params[i].vport_wfq);
701
+ inc_val = QM_WFQ_INC_VAL(vport_params[i].wfq);
685702 if (inc_val > QM_WFQ_MAX_INC_VAL) {
686703 DP_NOTICE(p_hwfn,
687704 "Invalid VPORT WFQ weight configuration\n");
....@@ -701,48 +718,6 @@
701718 vport_pq_id, inc_val);
702719 }
703720 }
704
- }
705
-
706
- return 0;
707
-}
708
-
709
-/* Prepare VPORT RL runtime init values for the specified VPORTs.
710
- * Return -1 on error.
711
- */
712
-static int qed_vport_rl_rt_init(struct qed_hwfn *p_hwfn,
713
- u8 start_vport,
714
- u8 num_vports,
715
- u32 link_speed,
716
- struct init_qm_vport_params *vport_params)
717
-{
718
- u8 i, vport_id;
719
- u32 inc_val;
720
-
721
- if (start_vport + num_vports >= MAX_QM_GLOBAL_RLS) {
722
- DP_NOTICE(p_hwfn,
723
- "Invalid VPORT ID for rate limiter configuration\n");
724
- return -1;
725
- }
726
-
727
- /* Go over all PF VPORTs */
728
- for (i = 0, vport_id = start_vport; i < num_vports; i++, vport_id++) {
729
- inc_val = QM_RL_INC_VAL(vport_params[i].vport_rl ?
730
- vport_params[i].vport_rl :
731
- link_speed);
732
- if (inc_val > QM_VP_RL_MAX_INC_VAL(link_speed)) {
733
- DP_NOTICE(p_hwfn,
734
- "Invalid VPORT rate-limit configuration\n");
735
- return -1;
736
- }
737
-
738
- STORE_RT_REG(p_hwfn, QM_REG_RLGLBLCRD_RT_OFFSET + vport_id,
739
- (u32)QM_RL_CRD_REG_SIGN_BIT);
740
- STORE_RT_REG(p_hwfn,
741
- QM_REG_RLGLBLUPPERBOUND_RT_OFFSET + vport_id,
742
- QM_VP_RL_UPPER_BOUND(link_speed) |
743
- (u32)QM_RL_CRD_REG_SIGN_BIT);
744
- STORE_RT_REG(p_hwfn, QM_REG_RLGLBLINCVAL_RT_OFFSET + vport_id,
745
- inc_val);
746721 }
747722
748723 return 0;
....@@ -799,23 +774,20 @@
799774 int qed_qm_common_rt_init(struct qed_hwfn *p_hwfn,
800775 struct qed_qm_common_rt_init_params *p_params)
801776 {
802
- /* Init AFullOprtnstcCrdMask */
803
- u32 mask = (QM_OPPOR_LINE_VOQ_DEF <<
804
- QM_RF_OPPORTUNISTIC_MASK_LINEVOQ_SHIFT) |
805
- (QM_BYTE_CRD_EN << QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ_SHIFT) |
806
- (p_params->pf_wfq_en <<
807
- QM_RF_OPPORTUNISTIC_MASK_PFWFQ_SHIFT) |
808
- (p_params->vport_wfq_en <<
809
- QM_RF_OPPORTUNISTIC_MASK_VPWFQ_SHIFT) |
810
- (p_params->pf_rl_en <<
811
- QM_RF_OPPORTUNISTIC_MASK_PFRL_SHIFT) |
812
- (p_params->vport_rl_en <<
813
- QM_RF_OPPORTUNISTIC_MASK_VPQCNRL_SHIFT) |
814
- (QM_OPPOR_FW_STOP_DEF <<
815
- QM_RF_OPPORTUNISTIC_MASK_FWPAUSE_SHIFT) |
816
- (QM_OPPOR_PQ_EMPTY_DEF <<
817
- QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY_SHIFT);
777
+ u32 mask = 0;
818778
779
+ /* Init AFullOprtnstcCrdMask */
780
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_LINEVOQ,
781
+ QM_OPPOR_LINE_VOQ_DEF);
782
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_BYTEVOQ, QM_BYTE_CRD_EN);
783
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFWFQ, p_params->pf_wfq_en);
784
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPWFQ, p_params->vport_wfq_en);
785
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_PFRL, p_params->pf_rl_en);
786
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_VPQCNRL,
787
+ p_params->global_rl_en);
788
+ SET_FIELD(mask, QM_RF_OPPORTUNISTIC_MASK_FWPAUSE, QM_OPPOR_FW_STOP_DEF);
789
+ SET_FIELD(mask,
790
+ QM_RF_OPPORTUNISTIC_MASK_QUEUEEMPTY, QM_OPPOR_PQ_EMPTY_DEF);
819791 STORE_RT_REG(p_hwfn, QM_REG_AFULLOPRTNSTCCRDMASK_RT_OFFSET, mask);
820792
821793 /* Enable/disable PF RL */
....@@ -824,8 +796,8 @@
824796 /* Enable/disable PF WFQ */
825797 qed_enable_pf_wfq(p_hwfn, p_params->pf_wfq_en);
826798
827
- /* Enable/disable VPORT RL */
828
- qed_enable_vport_rl(p_hwfn, p_params->vport_rl_en);
799
+ /* Enable/disable global RL */
800
+ qed_enable_global_rl(p_hwfn, p_params->global_rl_en);
829801
830802 /* Enable/disable VPORT WFQ */
831803 qed_enable_vport_wfq(p_hwfn, p_params->vport_wfq_en);
....@@ -842,6 +814,8 @@
842814 p_params->max_phys_tcs_per_port,
843815 p_params->port_params);
844816
817
+ qed_global_rl_rt_init(p_hwfn);
818
+
845819 return 0;
846820 }
847821
....@@ -853,7 +827,9 @@
853827 u32 other_mem_size_4kb = QM_PQ_MEM_4KB(p_params->num_pf_cids +
854828 p_params->num_tids) *
855829 QM_OTHER_PQS_PER_PF;
856
- u8 tc, i;
830
+ u16 i;
831
+ u8 tc;
832
+
857833
858834 /* Clear first Tx PQ ID array for each VPORT */
859835 for (i = 0; i < p_params->num_vports; i++)
....@@ -878,14 +854,8 @@
878854 if (qed_pf_rl_rt_init(p_hwfn, p_params->pf_id, p_params->pf_rl))
879855 return -1;
880856
881
- /* Set VPORT WFQ */
857
+ /* Init VPORT WFQ */
882858 if (qed_vp_wfq_rt_init(p_hwfn, p_params->num_vports, vport_params))
883
- return -1;
884
-
885
- /* Set VPORT RL */
886
- if (qed_vport_rl_rt_init(p_hwfn, p_params->start_vport,
887
- p_params->num_vports, p_params->link_speed,
888
- vport_params))
889859 return -1;
890860
891861 return 0;
....@@ -925,18 +895,19 @@
925895
926896 int qed_init_vport_wfq(struct qed_hwfn *p_hwfn,
927897 struct qed_ptt *p_ptt,
928
- u16 first_tx_pq_id[NUM_OF_TCS], u16 vport_wfq)
898
+ u16 first_tx_pq_id[NUM_OF_TCS], u16 wfq)
929899 {
930900 u16 vport_pq_id;
931901 u32 inc_val;
932902 u8 tc;
933903
934
- inc_val = QM_WFQ_INC_VAL(vport_wfq);
904
+ inc_val = QM_WFQ_INC_VAL(wfq);
935905 if (!inc_val || inc_val > QM_WFQ_MAX_INC_VAL) {
936
- DP_NOTICE(p_hwfn, "Invalid VPORT WFQ weight configuration\n");
906
+ DP_NOTICE(p_hwfn, "Invalid VPORT WFQ configuration.\n");
937907 return -1;
938908 }
939909
910
+ /* A VPORT can have several VPORT PQ IDs for various TCs */
940911 for (tc = 0; tc < NUM_OF_TCS; tc++) {
941912 vport_pq_id = first_tx_pq_id[tc];
942913 if (vport_pq_id != QM_INVALID_PQ_ID)
....@@ -948,28 +919,20 @@
948919 return 0;
949920 }
950921
951
-int qed_init_vport_rl(struct qed_hwfn *p_hwfn,
952
- struct qed_ptt *p_ptt,
953
- u8 vport_id, u32 vport_rl, u32 link_speed)
922
+int qed_init_global_rl(struct qed_hwfn *p_hwfn,
923
+ struct qed_ptt *p_ptt, u16 rl_id, u32 rate_limit)
954924 {
955
- u32 inc_val, max_qm_global_rls = MAX_QM_GLOBAL_RLS;
925
+ u32 inc_val;
956926
957
- if (vport_id >= max_qm_global_rls) {
958
- DP_NOTICE(p_hwfn,
959
- "Invalid VPORT ID for rate limiter configuration\n");
927
+ inc_val = QM_RL_INC_VAL(rate_limit);
928
+ if (inc_val > QM_VP_RL_MAX_INC_VAL(rate_limit)) {
929
+ DP_NOTICE(p_hwfn, "Invalid rate limit configuration.\n");
960930 return -1;
961931 }
962932
963
- inc_val = QM_RL_INC_VAL(vport_rl ? vport_rl : link_speed);
964
- if (inc_val > QM_VP_RL_MAX_INC_VAL(link_speed)) {
965
- DP_NOTICE(p_hwfn, "Invalid VPORT rate-limit configuration\n");
966
- return -1;
967
- }
968
-
969
- qed_wr(p_hwfn,
970
- p_ptt,
971
- QM_REG_RLGLBLCRD + vport_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
972
- qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + vport_id * 4, inc_val);
933
+ qed_wr(p_hwfn, p_ptt,
934
+ QM_REG_RLGLBLCRD + rl_id * 4, (u32)QM_RL_CRD_REG_SIGN_BIT);
935
+ qed_wr(p_hwfn, p_ptt, QM_REG_RLGLBLINCVAL + rl_id * 4, inc_val);
973936
974937 return 0;
975938 }
....@@ -1013,7 +976,6 @@
1013976 return true;
1014977 }
1015978
1016
-
1017979 #define SET_TUNNEL_TYPE_ENABLE_BIT(var, offset, enable) \
1018980 do { \
1019981 typeof(var) *__p_var = &(var); \
....@@ -1021,8 +983,67 @@
1021983 *__p_var = (*__p_var & ~BIT(__offset)) | \
1022984 ((enable) ? BIT(__offset) : 0); \
1023985 } while (0)
1024
-#define PRS_ETH_TUNN_OUTPUT_FORMAT -188897008
1025
-#define PRS_ETH_OUTPUT_FORMAT -46832
986
+
987
+#define PRS_ETH_TUNN_OUTPUT_FORMAT 0xF4DAB910
988
+#define PRS_ETH_OUTPUT_FORMAT 0xFFFF4910
989
+
990
+#define ARR_REG_WR(dev, ptt, addr, arr, arr_size) \
991
+ do { \
992
+ u32 i; \
993
+ \
994
+ for (i = 0; i < (arr_size); i++) \
995
+ qed_wr(dev, ptt, \
996
+ ((addr) + (4 * i)), \
997
+ ((u32 *)&(arr))[i]); \
998
+ } while (0)
999
+
1000
+/**
1001
+ * qed_dmae_to_grc() - Internal function for writing from host to
1002
+ * wide-bus registers (split registers are not supported yet).
1003
+ *
1004
+ * @p_hwfn: HW device data.
1005
+ * @p_ptt: PTT window used for writing the registers.
1006
+ * @p_data: Pointer to source data.
1007
+ * @addr: Destination register address.
1008
+ * @len_in_dwords: Data length in dwords (u32).
1009
+ *
1010
+ * Return: Length of the written data in dwords (u32) or -1 on invalid
1011
+ * input.
1012
+ */
1013
+static int qed_dmae_to_grc(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt,
1014
+ __le32 *p_data, u32 addr, u32 len_in_dwords)
1015
+{
1016
+ struct qed_dmae_params params = {};
1017
+ u32 *data_cpu;
1018
+ int rc;
1019
+
1020
+ if (!p_data)
1021
+ return -1;
1022
+
1023
+ /* Set DMAE params */
1024
+ SET_FIELD(params.flags, QED_DMAE_PARAMS_COMPLETION_DST, 1);
1025
+
1026
+ /* Execute DMAE command */
1027
+ rc = qed_dmae_host2grc(p_hwfn, p_ptt,
1028
+ (u64)(uintptr_t)(p_data),
1029
+ addr, len_in_dwords, &params);
1030
+
1031
+ /* If not read using DMAE, read using GRC */
1032
+ if (rc) {
1033
+ DP_VERBOSE(p_hwfn,
1034
+ QED_MSG_DEBUG,
1035
+ "Failed writing to chip using DMAE, using GRC instead\n");
1036
+
1037
+ /* Swap to CPU byteorder and write to registers using GRC */
1038
+ data_cpu = (__force u32 *)p_data;
1039
+ le32_to_cpu_array(data_cpu, len_in_dwords);
1040
+
1041
+ ARR_REG_WR(p_hwfn, p_ptt, addr, data_cpu, len_in_dwords);
1042
+ cpu_to_le32_array(data_cpu, len_in_dwords);
1043
+ }
1044
+
1045
+ return len_in_dwords;
1046
+}
10261047
10271048 void qed_set_vxlan_dest_port(struct qed_hwfn *p_hwfn,
10281049 struct qed_ptt *p_ptt, u16 dest_port)
....@@ -1166,8 +1187,8 @@
11661187 ip_geneve_enable ? 1 : 0);
11671188 }
11681189
1169
-#define PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET 4
1170
-#define PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT -927094512
1190
+#define PRS_ETH_VXLAN_NO_L2_ENABLE_OFFSET 3
1191
+#define PRS_ETH_VXLAN_NO_L2_OUTPUT_FORMAT -925189872
11711192
11721193 void qed_set_vxlan_no_l2_enable(struct qed_hwfn *p_hwfn,
11731194 struct qed_ptt *p_ptt, bool enable)
....@@ -1208,6 +1229,8 @@
12081229
12091230 void qed_gft_disable(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt, u16 pf_id)
12101231 {
1232
+ struct regpair ram_line = { };
1233
+
12111234 /* Disable gft search for PF */
12121235 qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 0);
12131236
....@@ -1217,12 +1240,9 @@
12171240 qed_wr(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id, 0);
12181241
12191242 /* Zero ramline */
1220
- qed_wr(p_hwfn,
1221
- p_ptt, PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id, 0);
1222
- qed_wr(p_hwfn,
1223
- p_ptt,
1224
- PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id + REG_SIZE,
1225
- 0);
1243
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1244
+ PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1245
+ sizeof(ram_line) / REG_SIZE);
12261246 }
12271247
12281248 void qed_gft_config(struct qed_hwfn *p_hwfn,
....@@ -1232,7 +1252,10 @@
12321252 bool udp,
12331253 bool ipv4, bool ipv6, enum gft_profile_type profile_type)
12341254 {
1235
- u32 reg_val, cam_line, ram_line_lo, ram_line_hi, search_non_ip_as_gft;
1255
+ struct regpair ram_line;
1256
+ u32 search_non_ip_as_gft;
1257
+ u32 reg_val, cam_line;
1258
+ u32 lo = 0, hi = 0;
12361259
12371260 if (!ipv6 && !ipv4)
12381261 DP_NOTICE(p_hwfn,
....@@ -1298,60 +1321,54 @@
12981321 qed_rd(p_hwfn, p_ptt, PRS_REG_GFT_CAM + CAM_LINE_SIZE * pf_id);
12991322
13001323 /* Write line to RAM - compare to filter 4 tuple */
1301
- ram_line_lo = 0;
1302
- ram_line_hi = 0;
13031324
13041325 /* Search no IP as GFT */
13051326 search_non_ip_as_gft = 0;
13061327
13071328 /* Tunnel type */
1308
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
1309
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
1329
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_DST_PORT, 1);
1330
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_OVER_IP_PROTOCOL, 1);
13101331
13111332 if (profile_type == GFT_PROFILE_TYPE_4_TUPLE) {
1312
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_DST_IP, 1);
1313
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_SRC_IP, 1);
1314
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1315
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_ETHERTYPE, 1);
1316
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_SRC_PORT, 1);
1317
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_DST_PORT, 1);
1333
+ SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
1334
+ SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
1335
+ SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1336
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1337
+ SET_FIELD(lo, GFT_RAM_LINE_SRC_PORT, 1);
1338
+ SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
13181339 } else if (profile_type == GFT_PROFILE_TYPE_L4_DST_PORT) {
1319
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1320
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_ETHERTYPE, 1);
1321
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_DST_PORT, 1);
1340
+ SET_FIELD(hi, GFT_RAM_LINE_OVER_IP_PROTOCOL, 1);
1341
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
1342
+ SET_FIELD(lo, GFT_RAM_LINE_DST_PORT, 1);
13221343 } else if (profile_type == GFT_PROFILE_TYPE_IP_DST_ADDR) {
1323
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_DST_IP, 1);
1324
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_ETHERTYPE, 1);
1344
+ SET_FIELD(hi, GFT_RAM_LINE_DST_IP, 1);
1345
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
13251346 } else if (profile_type == GFT_PROFILE_TYPE_IP_SRC_ADDR) {
1326
- SET_FIELD(ram_line_hi, GFT_RAM_LINE_SRC_IP, 1);
1327
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_ETHERTYPE, 1);
1347
+ SET_FIELD(hi, GFT_RAM_LINE_SRC_IP, 1);
1348
+ SET_FIELD(lo, GFT_RAM_LINE_ETHERTYPE, 1);
13281349 } else if (profile_type == GFT_PROFILE_TYPE_TUNNEL_TYPE) {
1329
- SET_FIELD(ram_line_lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
1350
+ SET_FIELD(lo, GFT_RAM_LINE_TUNNEL_ETHERTYPE, 1);
13301351
13311352 /* Allow tunneled traffic without inner IP */
13321353 search_non_ip_as_gft = 1;
13331354 }
13341355
1356
+ ram_line.lo = cpu_to_le32(lo);
1357
+ ram_line.hi = cpu_to_le32(hi);
1358
+
13351359 qed_wr(p_hwfn,
13361360 p_ptt, PRS_REG_SEARCH_NON_IP_AS_GFT, search_non_ip_as_gft);
1337
- qed_wr(p_hwfn,
1338
- p_ptt,
1339
- PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1340
- ram_line_lo);
1341
- qed_wr(p_hwfn,
1342
- p_ptt,
1343
- PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id + REG_SIZE,
1344
- ram_line_hi);
1361
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1362
+ PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE * pf_id,
1363
+ sizeof(ram_line) / REG_SIZE);
13451364
13461365 /* Set default profile so that no filter match will happen */
1347
- qed_wr(p_hwfn,
1348
- p_ptt,
1349
- PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
1350
- PRS_GFT_CAM_LINES_NO_MATCH, 0xffffffff);
1351
- qed_wr(p_hwfn,
1352
- p_ptt,
1353
- PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
1354
- PRS_GFT_CAM_LINES_NO_MATCH + REG_SIZE, 0x3ff);
1366
+ ram_line.lo = cpu_to_le32(0xffffffff);
1367
+ ram_line.hi = cpu_to_le32(0x3ff);
1368
+ qed_dmae_to_grc(p_hwfn, p_ptt, &ram_line.lo,
1369
+ PRS_REG_GFT_PROFILE_MASK_RAM + RAM_LINE_SIZE *
1370
+ PRS_GFT_CAM_LINES_NO_MATCH,
1371
+ sizeof(ram_line) / REG_SIZE);
13551372
13561373 /* Enable gft search */
13571374 qed_wr(p_hwfn, p_ptt, PRS_REG_SEARCH_GFT, 1);
....@@ -1366,7 +1383,7 @@
13661383 u8 crc, validation_byte = 0;
13671384 static u8 crc8_table_valid; /* automatically initialized to 0 */
13681385 u32 validation_string = 0;
1369
- u32 data_to_crc;
1386
+ __be32 data_to_crc;
13701387
13711388 if (!crc8_table_valid) {
13721389 crc8_populate_msb(cdu_crc8_table, 0x07);
....@@ -1388,10 +1405,9 @@
13881405 validation_string |= (conn_type & 0xF);
13891406
13901407 /* Convert to big-endian and calculate CRC8 */
1391
- data_to_crc = be32_to_cpu(validation_string);
1392
-
1393
- crc = crc8(cdu_crc8_table,
1394
- (u8 *)&data_to_crc, sizeof(data_to_crc), CRC8_INIT_VALUE);
1408
+ data_to_crc = cpu_to_be32(validation_string);
1409
+ crc = crc8(cdu_crc8_table, (u8 *)&data_to_crc, sizeof(data_to_crc),
1410
+ CRC8_INIT_VALUE);
13951411
13961412 /* The validation byte [7:0] is composed:
13971413 * for type A validation
....@@ -1544,3 +1560,144 @@
15441560 qed_wr(p_hwfn, p_ptt, ram_addr, assert_level[storm_id]);
15451561 }
15461562 }
1563
+
1564
+#define PHYS_ADDR_DWORDS DIV_ROUND_UP(sizeof(dma_addr_t), 4)
1565
+#define OVERLAY_HDR_SIZE_DWORDS (sizeof(struct fw_overlay_buf_hdr) / 4)
1566
+
1567
+static u32 qed_get_overlay_addr_ram_addr(struct qed_hwfn *p_hwfn, u8 storm_id)
1568
+{
1569
+ switch (storm_id) {
1570
+ case 0:
1571
+ return TSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1572
+ TSTORM_OVERLAY_BUF_ADDR_OFFSET;
1573
+ case 1:
1574
+ return MSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1575
+ MSTORM_OVERLAY_BUF_ADDR_OFFSET;
1576
+ case 2:
1577
+ return USEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1578
+ USTORM_OVERLAY_BUF_ADDR_OFFSET;
1579
+ case 3:
1580
+ return XSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1581
+ XSTORM_OVERLAY_BUF_ADDR_OFFSET;
1582
+ case 4:
1583
+ return YSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1584
+ YSTORM_OVERLAY_BUF_ADDR_OFFSET;
1585
+ case 5:
1586
+ return PSEM_REG_FAST_MEMORY + SEM_FAST_REG_INT_RAM +
1587
+ PSTORM_OVERLAY_BUF_ADDR_OFFSET;
1588
+
1589
+ default:
1590
+ return 0;
1591
+ }
1592
+}
1593
+
1594
+struct phys_mem_desc *qed_fw_overlay_mem_alloc(struct qed_hwfn *p_hwfn,
1595
+ const u32 * const
1596
+ fw_overlay_in_buf,
1597
+ u32 buf_size_in_bytes)
1598
+{
1599
+ u32 buf_size = buf_size_in_bytes / sizeof(u32), buf_offset = 0;
1600
+ struct phys_mem_desc *allocated_mem;
1601
+
1602
+ if (!buf_size)
1603
+ return NULL;
1604
+
1605
+ allocated_mem = kcalloc(NUM_STORMS, sizeof(struct phys_mem_desc),
1606
+ GFP_KERNEL);
1607
+ if (!allocated_mem)
1608
+ return NULL;
1609
+
1610
+ memset(allocated_mem, 0, NUM_STORMS * sizeof(struct phys_mem_desc));
1611
+
1612
+ /* For each Storm, set physical address in RAM */
1613
+ while (buf_offset < buf_size) {
1614
+ struct phys_mem_desc *storm_mem_desc;
1615
+ struct fw_overlay_buf_hdr *hdr;
1616
+ u32 storm_buf_size;
1617
+ u8 storm_id;
1618
+
1619
+ hdr =
1620
+ (struct fw_overlay_buf_hdr *)&fw_overlay_in_buf[buf_offset];
1621
+ storm_buf_size = GET_FIELD(hdr->data,
1622
+ FW_OVERLAY_BUF_HDR_BUF_SIZE);
1623
+ storm_id = GET_FIELD(hdr->data, FW_OVERLAY_BUF_HDR_STORM_ID);
1624
+ storm_mem_desc = allocated_mem + storm_id;
1625
+ storm_mem_desc->size = storm_buf_size * sizeof(u32);
1626
+
1627
+ /* Allocate physical memory for Storm's overlays buffer */
1628
+ storm_mem_desc->virt_addr =
1629
+ dma_alloc_coherent(&p_hwfn->cdev->pdev->dev,
1630
+ storm_mem_desc->size,
1631
+ &storm_mem_desc->phys_addr, GFP_KERNEL);
1632
+ if (!storm_mem_desc->virt_addr)
1633
+ break;
1634
+
1635
+ /* Skip overlays buffer header */
1636
+ buf_offset += OVERLAY_HDR_SIZE_DWORDS;
1637
+
1638
+ /* Copy Storm's overlays buffer to allocated memory */
1639
+ memcpy(storm_mem_desc->virt_addr,
1640
+ &fw_overlay_in_buf[buf_offset], storm_mem_desc->size);
1641
+
1642
+ /* Advance to next Storm */
1643
+ buf_offset += storm_buf_size;
1644
+ }
1645
+
1646
+ /* If memory allocation has failed, free all allocated memory */
1647
+ if (buf_offset < buf_size) {
1648
+ qed_fw_overlay_mem_free(p_hwfn, allocated_mem);
1649
+ return NULL;
1650
+ }
1651
+
1652
+ return allocated_mem;
1653
+}
1654
+
1655
+void qed_fw_overlay_init_ram(struct qed_hwfn *p_hwfn,
1656
+ struct qed_ptt *p_ptt,
1657
+ struct phys_mem_desc *fw_overlay_mem)
1658
+{
1659
+ u8 storm_id;
1660
+
1661
+ for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1662
+ struct phys_mem_desc *storm_mem_desc =
1663
+ (struct phys_mem_desc *)fw_overlay_mem + storm_id;
1664
+ u32 ram_addr, i;
1665
+
1666
+ /* Skip Storms with no FW overlays */
1667
+ if (!storm_mem_desc->virt_addr)
1668
+ continue;
1669
+
1670
+ /* Calculate overlay RAM GRC address of current PF */
1671
+ ram_addr = qed_get_overlay_addr_ram_addr(p_hwfn, storm_id) +
1672
+ sizeof(dma_addr_t) * p_hwfn->rel_pf_id;
1673
+
1674
+ /* Write Storm's overlay physical address to RAM */
1675
+ for (i = 0; i < PHYS_ADDR_DWORDS; i++, ram_addr += sizeof(u32))
1676
+ qed_wr(p_hwfn, p_ptt, ram_addr,
1677
+ ((u32 *)&storm_mem_desc->phys_addr)[i]);
1678
+ }
1679
+}
1680
+
1681
+void qed_fw_overlay_mem_free(struct qed_hwfn *p_hwfn,
1682
+ struct phys_mem_desc *fw_overlay_mem)
1683
+{
1684
+ u8 storm_id;
1685
+
1686
+ if (!fw_overlay_mem)
1687
+ return;
1688
+
1689
+ for (storm_id = 0; storm_id < NUM_STORMS; storm_id++) {
1690
+ struct phys_mem_desc *storm_mem_desc =
1691
+ (struct phys_mem_desc *)fw_overlay_mem + storm_id;
1692
+
1693
+ /* Free Storm's physical memory */
1694
+ if (storm_mem_desc->virt_addr)
1695
+ dma_free_coherent(&p_hwfn->cdev->pdev->dev,
1696
+ storm_mem_desc->size,
1697
+ storm_mem_desc->virt_addr,
1698
+ storm_mem_desc->phys_addr);
1699
+ }
1700
+
1701
+ /* Free allocated virtual memory */
1702
+ kfree(fw_overlay_mem);
1703
+}