hc
2024-05-14 bedbef8ad3e75a304af6361af235302bcc61d06b
kernel/include/linux/qed/qed_chain.h
....@@ -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 #ifndef _QED_CHAIN_H
....@@ -37,6 +11,7 @@
3711 #include <asm/byteorder.h>
3812 #include <linux/kernel.h>
3913 #include <linux/list.h>
14
+#include <linux/sizes.h>
4015 #include <linux/slab.h>
4116 #include <linux/qed/common_hsi.h>
4217
....@@ -52,9 +27,9 @@
5227 };
5328
5429 enum qed_chain_use_mode {
55
- QED_CHAIN_USE_TO_PRODUCE, /* Chain starts empty */
56
- QED_CHAIN_USE_TO_CONSUME, /* Chain starts full */
57
- QED_CHAIN_USE_TO_CONSUME_PRODUCE, /* Chain starts empty */
30
+ QED_CHAIN_USE_TO_PRODUCE, /* Chain starts empty */
31
+ QED_CHAIN_USE_TO_CONSUME, /* Chain starts full */
32
+ QED_CHAIN_USE_TO_CONSUME_PRODUCE, /* Chain starts empty */
5833 };
5934
6035 enum qed_chain_cnt_type {
....@@ -66,197 +41,230 @@
6641 };
6742
6843 struct qed_chain_next {
69
- struct regpair next_phys;
70
- void *next_virt;
44
+ struct regpair next_phys;
45
+ void *next_virt;
7146 };
7247
7348 struct qed_chain_pbl_u16 {
74
- u16 prod_page_idx;
75
- u16 cons_page_idx;
49
+ u16 prod_page_idx;
50
+ u16 cons_page_idx;
7651 };
7752
7853 struct qed_chain_pbl_u32 {
79
- u32 prod_page_idx;
80
- u32 cons_page_idx;
81
-};
82
-
83
-struct qed_chain_ext_pbl {
84
- dma_addr_t p_pbl_phys;
85
- void *p_pbl_virt;
54
+ u32 prod_page_idx;
55
+ u32 cons_page_idx;
8656 };
8757
8858 struct qed_chain_u16 {
8959 /* Cyclic index of next element to produce/consme */
90
- u16 prod_idx;
91
- u16 cons_idx;
60
+ u16 prod_idx;
61
+ u16 cons_idx;
9262 };
9363
9464 struct qed_chain_u32 {
9565 /* Cyclic index of next element to produce/consme */
96
- u32 prod_idx;
97
- u32 cons_idx;
66
+ u32 prod_idx;
67
+ u32 cons_idx;
9868 };
9969
10070 struct addr_tbl_entry {
101
- void *virt_addr;
102
- dma_addr_t dma_map;
71
+ void *virt_addr;
72
+ dma_addr_t dma_map;
10373 };
10474
10575 struct qed_chain {
106
- /* fastpath portion of the chain - required for commands such
76
+ /* Fastpath portion of the chain - required for commands such
10777 * as produce / consume.
10878 */
79
+
10980 /* Point to next element to produce/consume */
110
- void *p_prod_elem;
111
- void *p_cons_elem;
81
+ void *p_prod_elem;
82
+ void *p_cons_elem;
11283
11384 /* Fastpath portions of the PBL [if exists] */
85
+
11486 struct {
11587 /* Table for keeping the virtual and physical addresses of the
11688 * chain pages, respectively to the physical addresses
11789 * in the pbl table.
11890 */
119
- struct addr_tbl_entry *pp_addr_tbl;
91
+ struct addr_tbl_entry *pp_addr_tbl;
12092
12193 union {
122
- struct qed_chain_pbl_u16 u16;
123
- struct qed_chain_pbl_u32 u32;
124
- } c;
125
- } pbl;
94
+ struct qed_chain_pbl_u16 u16;
95
+ struct qed_chain_pbl_u32 u32;
96
+ } c;
97
+ } pbl;
12698
12799 union {
128
- struct qed_chain_u16 chain16;
129
- struct qed_chain_u32 chain32;
130
- } u;
100
+ struct qed_chain_u16 chain16;
101
+ struct qed_chain_u32 chain32;
102
+ } u;
131103
132104 /* Capacity counts only usable elements */
133
- u32 capacity;
134
- u32 page_cnt;
105
+ u32 capacity;
106
+ u32 page_cnt;
135107
136
- enum qed_chain_mode mode;
108
+ enum qed_chain_mode mode;
137109
138110 /* Elements information for fast calculations */
139
- u16 elem_per_page;
140
- u16 elem_per_page_mask;
141
- u16 elem_size;
142
- u16 next_page_mask;
143
- u16 usable_per_page;
144
- u8 elem_unusable;
111
+ u16 elem_per_page;
112
+ u16 elem_per_page_mask;
113
+ u16 elem_size;
114
+ u16 next_page_mask;
115
+ u16 usable_per_page;
116
+ u8 elem_unusable;
145117
146
- u8 cnt_type;
118
+ enum qed_chain_cnt_type cnt_type;
147119
148120 /* Slowpath of the chain - required for initialization and destruction,
149121 * but isn't involved in regular functionality.
150122 */
151123
124
+ u32 page_size;
125
+
152126 /* Base address of a pre-allocated buffer for pbl */
153127 struct {
154
- dma_addr_t p_phys_table;
155
- void *p_virt_table;
156
- } pbl_sp;
128
+ __le64 *table_virt;
129
+ dma_addr_t table_phys;
130
+ size_t table_size;
131
+ } pbl_sp;
157132
158133 /* Address of first page of the chain - the address is required
159
- * for fastpath operation [consume/produce] but only for the the SINGLE
134
+ * for fastpath operation [consume/produce] but only for the SINGLE
160135 * flavour which isn't considered fastpath [== SPQ].
161136 */
162
- void *p_virt_addr;
163
- dma_addr_t p_phys_addr;
137
+ void *p_virt_addr;
138
+ dma_addr_t p_phys_addr;
164139
165140 /* Total number of elements [for entire chain] */
166
- u32 size;
141
+ u32 size;
167142
168
- u8 intended_use;
143
+ enum qed_chain_use_mode intended_use;
169144
170
- bool b_external_pbl;
145
+ bool b_external_pbl;
171146 };
172147
173
-#define QED_CHAIN_PBL_ENTRY_SIZE (8)
174
-#define QED_CHAIN_PAGE_SIZE (0x1000)
175
-#define ELEMS_PER_PAGE(elem_size) (QED_CHAIN_PAGE_SIZE / (elem_size))
148
+struct qed_chain_init_params {
149
+ enum qed_chain_mode mode;
150
+ enum qed_chain_use_mode intended_use;
151
+ enum qed_chain_cnt_type cnt_type;
176152
177
-#define UNUSABLE_ELEMS_PER_PAGE(elem_size, mode) \
178
- (((mode) == QED_CHAIN_MODE_NEXT_PTR) ? \
179
- (u8)(1 + ((sizeof(struct qed_chain_next) - 1) / \
180
- (elem_size))) : 0)
153
+ u32 page_size;
154
+ u32 num_elems;
155
+ size_t elem_size;
181156
182
-#define USABLE_ELEMS_PER_PAGE(elem_size, mode) \
183
- ((u32)(ELEMS_PER_PAGE(elem_size) - \
184
- UNUSABLE_ELEMS_PER_PAGE(elem_size, mode)))
157
+ void *ext_pbl_virt;
158
+ dma_addr_t ext_pbl_phys;
159
+};
185160
186
-#define QED_CHAIN_PAGE_CNT(elem_cnt, elem_size, mode) \
187
- DIV_ROUND_UP(elem_cnt, USABLE_ELEMS_PER_PAGE(elem_size, mode))
161
+#define QED_CHAIN_PAGE_SIZE SZ_4K
188162
189
-#define is_chain_u16(p) ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U16)
190
-#define is_chain_u32(p) ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U32)
163
+#define ELEMS_PER_PAGE(elem_size, page_size) \
164
+ ((page_size) / (elem_size))
165
+
166
+#define UNUSABLE_ELEMS_PER_PAGE(elem_size, mode) \
167
+ (((mode) == QED_CHAIN_MODE_NEXT_PTR) ? \
168
+ (u8)(1 + ((sizeof(struct qed_chain_next) - 1) / (elem_size))) : \
169
+ 0)
170
+
171
+#define USABLE_ELEMS_PER_PAGE(elem_size, page_size, mode) \
172
+ ((u32)(ELEMS_PER_PAGE((elem_size), (page_size)) - \
173
+ UNUSABLE_ELEMS_PER_PAGE((elem_size), (mode))))
174
+
175
+#define QED_CHAIN_PAGE_CNT(elem_cnt, elem_size, page_size, mode) \
176
+ DIV_ROUND_UP((elem_cnt), \
177
+ USABLE_ELEMS_PER_PAGE((elem_size), (page_size), (mode)))
178
+
179
+#define is_chain_u16(p) \
180
+ ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U16)
181
+#define is_chain_u32(p) \
182
+ ((p)->cnt_type == QED_CHAIN_CNT_TYPE_U32)
191183
192184 /* Accessors */
193
-static inline u16 qed_chain_get_prod_idx(struct qed_chain *p_chain)
185
+
186
+static inline u16 qed_chain_get_prod_idx(const struct qed_chain *chain)
194187 {
195
- return p_chain->u.chain16.prod_idx;
188
+ return chain->u.chain16.prod_idx;
196189 }
197190
198
-static inline u16 qed_chain_get_cons_idx(struct qed_chain *p_chain)
191
+static inline u16 qed_chain_get_cons_idx(const struct qed_chain *chain)
199192 {
200
- return p_chain->u.chain16.cons_idx;
193
+ return chain->u.chain16.cons_idx;
201194 }
202195
203
-static inline u32 qed_chain_get_cons_idx_u32(struct qed_chain *p_chain)
196
+static inline u32 qed_chain_get_prod_idx_u32(const struct qed_chain *chain)
204197 {
205
- return p_chain->u.chain32.cons_idx;
198
+ return chain->u.chain32.prod_idx;
206199 }
207200
208
-static inline u16 qed_chain_get_elem_left(struct qed_chain *p_chain)
201
+static inline u32 qed_chain_get_cons_idx_u32(const struct qed_chain *chain)
209202 {
210
- u16 elem_per_page = p_chain->elem_per_page;
211
- u32 prod = p_chain->u.chain16.prod_idx;
212
- u32 cons = p_chain->u.chain16.cons_idx;
203
+ return chain->u.chain32.cons_idx;
204
+}
205
+
206
+static inline u16 qed_chain_get_elem_used(const struct qed_chain *chain)
207
+{
208
+ u32 prod = qed_chain_get_prod_idx(chain);
209
+ u32 cons = qed_chain_get_cons_idx(chain);
210
+ u16 elem_per_page = chain->elem_per_page;
213211 u16 used;
214212
215213 if (prod < cons)
216214 prod += (u32)U16_MAX + 1;
217215
218216 used = (u16)(prod - cons);
219
- if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
220
- used -= prod / elem_per_page - cons / elem_per_page;
217
+ if (chain->mode == QED_CHAIN_MODE_NEXT_PTR)
218
+ used -= (u16)(prod / elem_per_page - cons / elem_per_page);
221219
222
- return (u16)(p_chain->capacity - used);
220
+ return used;
223221 }
224222
225
-static inline u32 qed_chain_get_elem_left_u32(struct qed_chain *p_chain)
223
+static inline u16 qed_chain_get_elem_left(const struct qed_chain *chain)
226224 {
227
- u16 elem_per_page = p_chain->elem_per_page;
228
- u64 prod = p_chain->u.chain32.prod_idx;
229
- u64 cons = p_chain->u.chain32.cons_idx;
225
+ return (u16)(chain->capacity - qed_chain_get_elem_used(chain));
226
+}
227
+
228
+static inline u32 qed_chain_get_elem_used_u32(const struct qed_chain *chain)
229
+{
230
+ u64 prod = qed_chain_get_prod_idx_u32(chain);
231
+ u64 cons = qed_chain_get_cons_idx_u32(chain);
232
+ u16 elem_per_page = chain->elem_per_page;
230233 u32 used;
231234
232235 if (prod < cons)
233236 prod += (u64)U32_MAX + 1;
234237
235238 used = (u32)(prod - cons);
236
- if (p_chain->mode == QED_CHAIN_MODE_NEXT_PTR)
239
+ if (chain->mode == QED_CHAIN_MODE_NEXT_PTR)
237240 used -= (u32)(prod / elem_per_page - cons / elem_per_page);
238241
239
- return p_chain->capacity - used;
242
+ return used;
240243 }
241244
242
-static inline u16 qed_chain_get_usable_per_page(struct qed_chain *p_chain)
245
+static inline u32 qed_chain_get_elem_left_u32(const struct qed_chain *chain)
243246 {
244
- return p_chain->usable_per_page;
247
+ return chain->capacity - qed_chain_get_elem_used_u32(chain);
245248 }
246249
247
-static inline u8 qed_chain_get_unusable_per_page(struct qed_chain *p_chain)
250
+static inline u16 qed_chain_get_usable_per_page(const struct qed_chain *chain)
248251 {
249
- return p_chain->elem_unusable;
252
+ return chain->usable_per_page;
250253 }
251254
252
-static inline u32 qed_chain_get_page_cnt(struct qed_chain *p_chain)
255
+static inline u8 qed_chain_get_unusable_per_page(const struct qed_chain *chain)
253256 {
254
- return p_chain->page_cnt;
257
+ return chain->elem_unusable;
255258 }
256259
257
-static inline dma_addr_t qed_chain_get_pbl_phys(struct qed_chain *p_chain)
260
+static inline u32 qed_chain_get_page_cnt(const struct qed_chain *chain)
258261 {
259
- return p_chain->pbl_sp.p_phys_table;
262
+ return chain->page_cnt;
263
+}
264
+
265
+static inline dma_addr_t qed_chain_get_pbl_phys(const struct qed_chain *chain)
266
+{
267
+ return chain->pbl_sp.table_phys;
260268 }
261269
262270 /**
....@@ -511,118 +519,6 @@
511519 }
512520
513521 /**
514
- * @brief qed_chain_init - Initalizes a basic chain struct
515
- *
516
- * @param p_chain
517
- * @param p_virt_addr
518
- * @param p_phys_addr physical address of allocated buffer's beginning
519
- * @param page_cnt number of pages in the allocated buffer
520
- * @param elem_size size of each element in the chain
521
- * @param intended_use
522
- * @param mode
523
- */
524
-static inline void qed_chain_init_params(struct qed_chain *p_chain,
525
- u32 page_cnt,
526
- u8 elem_size,
527
- enum qed_chain_use_mode intended_use,
528
- enum qed_chain_mode mode,
529
- enum qed_chain_cnt_type cnt_type)
530
-{
531
- /* chain fixed parameters */
532
- p_chain->p_virt_addr = NULL;
533
- p_chain->p_phys_addr = 0;
534
- p_chain->elem_size = elem_size;
535
- p_chain->intended_use = (u8)intended_use;
536
- p_chain->mode = mode;
537
- p_chain->cnt_type = (u8)cnt_type;
538
-
539
- p_chain->elem_per_page = ELEMS_PER_PAGE(elem_size);
540
- p_chain->usable_per_page = USABLE_ELEMS_PER_PAGE(elem_size, mode);
541
- p_chain->elem_per_page_mask = p_chain->elem_per_page - 1;
542
- p_chain->elem_unusable = UNUSABLE_ELEMS_PER_PAGE(elem_size, mode);
543
- p_chain->next_page_mask = (p_chain->usable_per_page &
544
- p_chain->elem_per_page_mask);
545
-
546
- p_chain->page_cnt = page_cnt;
547
- p_chain->capacity = p_chain->usable_per_page * page_cnt;
548
- p_chain->size = p_chain->elem_per_page * page_cnt;
549
-
550
- p_chain->pbl_sp.p_phys_table = 0;
551
- p_chain->pbl_sp.p_virt_table = NULL;
552
- p_chain->pbl.pp_addr_tbl = NULL;
553
-}
554
-
555
-/**
556
- * @brief qed_chain_init_mem -
557
- *
558
- * Initalizes a basic chain struct with its chain buffers
559
- *
560
- * @param p_chain
561
- * @param p_virt_addr virtual address of allocated buffer's beginning
562
- * @param p_phys_addr physical address of allocated buffer's beginning
563
- *
564
- */
565
-static inline void qed_chain_init_mem(struct qed_chain *p_chain,
566
- void *p_virt_addr, dma_addr_t p_phys_addr)
567
-{
568
- p_chain->p_virt_addr = p_virt_addr;
569
- p_chain->p_phys_addr = p_phys_addr;
570
-}
571
-
572
-/**
573
- * @brief qed_chain_init_pbl_mem -
574
- *
575
- * Initalizes a basic chain struct with its pbl buffers
576
- *
577
- * @param p_chain
578
- * @param p_virt_pbl pointer to a pre allocated side table which will hold
579
- * virtual page addresses.
580
- * @param p_phys_pbl pointer to a pre-allocated side table which will hold
581
- * physical page addresses.
582
- * @param pp_virt_addr_tbl
583
- * pointer to a pre-allocated side table which will hold
584
- * the virtual addresses of the chain pages.
585
- *
586
- */
587
-static inline void qed_chain_init_pbl_mem(struct qed_chain *p_chain,
588
- void *p_virt_pbl,
589
- dma_addr_t p_phys_pbl,
590
- struct addr_tbl_entry *pp_addr_tbl)
591
-{
592
- p_chain->pbl_sp.p_phys_table = p_phys_pbl;
593
- p_chain->pbl_sp.p_virt_table = p_virt_pbl;
594
- p_chain->pbl.pp_addr_tbl = pp_addr_tbl;
595
-}
596
-
597
-/**
598
- * @brief qed_chain_init_next_ptr_elem -
599
- *
600
- * Initalizes a next pointer element
601
- *
602
- * @param p_chain
603
- * @param p_virt_curr virtual address of a chain page of which the next
604
- * pointer element is initialized
605
- * @param p_virt_next virtual address of the next chain page
606
- * @param p_phys_next physical address of the next chain page
607
- *
608
- */
609
-static inline void
610
-qed_chain_init_next_ptr_elem(struct qed_chain *p_chain,
611
- void *p_virt_curr,
612
- void *p_virt_next, dma_addr_t p_phys_next)
613
-{
614
- struct qed_chain_next *p_next;
615
- u32 size;
616
-
617
- size = p_chain->elem_size * p_chain->usable_per_page;
618
- p_next = (struct qed_chain_next *)((u8 *)p_virt_curr + size);
619
-
620
- DMA_REGPAIR_LE(p_next->next_phys, p_phys_next);
621
-
622
- p_next->next_virt = p_virt_next;
623
-}
624
-
625
-/**
626522 * @brief qed_chain_get_last_elem -
627523 *
628524 * Returns a pointer to the last element of the chain
....@@ -729,7 +625,7 @@
729625
730626 for (i = 0; i < page_cnt; i++)
731627 memset(p_chain->pbl.pp_addr_tbl[i].virt_addr, 0,
732
- QED_CHAIN_PAGE_SIZE);
628
+ p_chain->page_size);
733629 }
734630
735631 #endif