hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/net/ethernet/huawei/hinic/hinic_hw_io.c
....@@ -1,16 +1,7 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Huawei HiNIC PCI Express Linux driver
34 * Copyright(c) 2017 Huawei Technologies Co., Ltd
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms and conditions of the GNU General Public License,
7
- * version 2, as published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
- * for more details.
13
- *
145 */
156
167 #include <linux/kernel.h>
....@@ -24,6 +15,7 @@
2415 #include <linux/io.h>
2516 #include <linux/err.h>
2617
18
+#include "hinic_hw_dev.h"
2719 #include "hinic_hw_if.h"
2820 #include "hinic_hw_eqs.h"
2921 #include "hinic_hw_wqe.h"
....@@ -43,8 +35,11 @@
4335 #define DB_IDX(db, db_base) \
4436 (((unsigned long)(db) - (unsigned long)(db_base)) / HINIC_DB_PAGE_SIZE)
4537
38
+#define HINIC_PAGE_SIZE_HW(pg_size) ((u8)ilog2((u32)((pg_size) >> 12)))
39
+
4640 enum io_cmd {
4741 IO_CMD_MODIFY_QUEUE_CTXT = 0,
42
+ IO_CMD_CLEAN_QUEUE_CTXT,
4843 };
4944
5045 static void init_db_area_idx(struct hinic_free_db_area *free_db_area)
....@@ -210,6 +205,59 @@
210205 write_rq_ctxts(func_to_io, base_qpn, num_qps));
211206 }
212207
208
+static int hinic_clean_queue_offload_ctxt(struct hinic_func_to_io *func_to_io,
209
+ enum hinic_qp_ctxt_type ctxt_type)
210
+{
211
+ struct hinic_hwif *hwif = func_to_io->hwif;
212
+ struct hinic_clean_queue_ctxt *ctxt_block;
213
+ struct pci_dev *pdev = hwif->pdev;
214
+ struct hinic_cmdq_buf cmdq_buf;
215
+ u64 out_param = 0;
216
+ int err;
217
+
218
+ err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
219
+ if (err) {
220
+ dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
221
+ return err;
222
+ }
223
+
224
+ ctxt_block = cmdq_buf.buf;
225
+ ctxt_block->cmdq_hdr.num_queues = func_to_io->max_qps;
226
+ ctxt_block->cmdq_hdr.queue_type = ctxt_type;
227
+ ctxt_block->cmdq_hdr.addr_offset = 0;
228
+
229
+ /* TSO/LRO ctxt size: 0x0:0B; 0x1:160B; 0x2:200B; 0x3:240B */
230
+ ctxt_block->ctxt_size = 0x3;
231
+
232
+ hinic_cpu_to_be32(ctxt_block, sizeof(*ctxt_block));
233
+
234
+ cmdq_buf.size = sizeof(*ctxt_block);
235
+
236
+ err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
237
+ IO_CMD_CLEAN_QUEUE_CTXT,
238
+ &cmdq_buf, &out_param);
239
+
240
+ if (err || out_param) {
241
+ dev_err(&pdev->dev, "Failed to clean offload ctxts, err: %d, out_param: 0x%llx\n",
242
+ err, out_param);
243
+
244
+ err = -EFAULT;
245
+ }
246
+
247
+ hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
248
+
249
+ return err;
250
+}
251
+
252
+static int hinic_clean_qp_offload_ctxt(struct hinic_func_to_io *func_to_io)
253
+{
254
+ /* clean LRO/TSO context space */
255
+ return (hinic_clean_queue_offload_ctxt(func_to_io,
256
+ HINIC_QP_CTXT_TYPE_SQ) ||
257
+ hinic_clean_queue_offload_ctxt(func_to_io,
258
+ HINIC_QP_CTXT_TYPE_RQ));
259
+}
260
+
213261 /**
214262 * init_qp - Initialize a Queue Pair
215263 * @func_to_io: func to io channel that holds the IO components
....@@ -234,7 +282,7 @@
234282
235283 err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->sq_wq[q_id],
236284 HINIC_SQ_WQEBB_SIZE, HINIC_SQ_PAGE_SIZE,
237
- HINIC_SQ_DEPTH, HINIC_SQ_WQE_MAX_SIZE);
285
+ func_to_io->sq_depth, HINIC_SQ_WQE_MAX_SIZE);
238286 if (err) {
239287 dev_err(&pdev->dev, "Failed to allocate WQ for SQ\n");
240288 return err;
....@@ -242,7 +290,7 @@
242290
243291 err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->rq_wq[q_id],
244292 HINIC_RQ_WQEBB_SIZE, HINIC_RQ_PAGE_SIZE,
245
- HINIC_RQ_DEPTH, HINIC_RQ_WQE_SIZE);
293
+ func_to_io->rq_depth, HINIC_RQ_WQE_SIZE);
246294 if (err) {
247295 dev_err(&pdev->dev, "Failed to allocate WQ for RQ\n");
248296 goto err_rq_alloc;
....@@ -257,6 +305,7 @@
257305
258306 func_to_io->sq_db[q_id] = db_base;
259307
308
+ qp->sq.qid = q_id;
260309 err = hinic_init_sq(&qp->sq, hwif, &func_to_io->sq_wq[q_id],
261310 sq_msix_entry,
262311 CI_ADDR(func_to_io->ci_addr_base, q_id),
....@@ -266,6 +315,7 @@
266315 goto err_sq_init;
267316 }
268317
318
+ qp->rq.qid = q_id;
269319 err = hinic_init_rq(&qp->rq, hwif, &func_to_io->rq_wq[q_id],
270320 rq_msix_entry);
271321 if (err) {
....@@ -313,8 +363,8 @@
313363 * @func_to_io: func to io channel that holds the IO components
314364 * @base_qpn: base qp number
315365 * @num_qps: number queue pairs to create
316
- * @sq_msix_entry: msix entries for sq
317
- * @rq_msix_entry: msix entries for rq
366
+ * @sq_msix_entries: msix entries for sq
367
+ * @rq_msix_entries: msix entries for rq
318368 *
319369 * Return 0 - Success, negative - Failure
320370 **/
....@@ -355,9 +405,9 @@
355405 goto err_sq_db;
356406 }
357407
358
- ci_addr_base = dma_zalloc_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
359
- &func_to_io->ci_dma_base,
360
- GFP_KERNEL);
408
+ ci_addr_base = dma_alloc_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
409
+ &func_to_io->ci_dma_base,
410
+ GFP_KERNEL);
361411 if (!ci_addr_base) {
362412 dev_err(&pdev->dev, "Failed to allocate CI area\n");
363413 err = -ENOMEM;
....@@ -378,6 +428,12 @@
378428 err = write_qp_ctxts(func_to_io, base_qpn, num_qps);
379429 if (err) {
380430 dev_err(&pdev->dev, "Failed to init QP ctxts\n");
431
+ goto err_write_qp_ctxts;
432
+ }
433
+
434
+ err = hinic_clean_qp_offload_ctxt(func_to_io);
435
+ if (err) {
436
+ dev_err(&pdev->dev, "Failed to clean QP contexts space\n");
381437 goto err_write_qp_ctxts;
382438 }
383439
....@@ -433,6 +489,33 @@
433489 devm_kfree(&pdev->dev, func_to_io->qps);
434490 }
435491
492
+int hinic_set_wq_page_size(struct hinic_hwdev *hwdev, u16 func_idx,
493
+ u32 page_size)
494
+{
495
+ struct hinic_wq_page_size page_size_info = {0};
496
+ u16 out_size = sizeof(page_size_info);
497
+ struct hinic_pfhwdev *pfhwdev;
498
+ int err;
499
+
500
+ pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
501
+
502
+ page_size_info.func_idx = func_idx;
503
+ page_size_info.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);
504
+ page_size_info.page_size = HINIC_PAGE_SIZE_HW(page_size);
505
+
506
+ err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
507
+ HINIC_COMM_CMD_PAGESIZE_SET, &page_size_info,
508
+ sizeof(page_size_info), &page_size_info,
509
+ &out_size, HINIC_MGMT_MSG_SYNC);
510
+ if (err || !out_size || page_size_info.status) {
511
+ dev_err(&hwdev->hwif->pdev->dev, "Failed to set wq page size, err: %d, status: 0x%x, out_size: 0x%0x\n",
512
+ err, page_size_info.status, out_size);
513
+ return -EFAULT;
514
+ }
515
+
516
+ return 0;
517
+}
518
+
436519 /**
437520 * hinic_io_init - Initialize the IO components
438521 * @func_to_io: func to io channel that holds the IO components
....@@ -455,6 +538,7 @@
455538 func_to_io->hwif = hwif;
456539 func_to_io->qps = NULL;
457540 func_to_io->max_qps = max_qps;
541
+ func_to_io->ceqs.hwdev = func_to_io->hwdev;
458542
459543 err = hinic_ceqs_init(&func_to_io->ceqs, hwif, num_ceqs,
460544 HINIC_DEFAULT_CEQ_LEN, HINIC_EQ_PAGE_SIZE,
....@@ -490,6 +574,14 @@
490574 func_to_io->cmdq_db_area[cmdq] = db_area;
491575 }
492576
577
+ err = hinic_set_wq_page_size(func_to_io->hwdev,
578
+ HINIC_HWIF_FUNC_IDX(hwif),
579
+ HINIC_DEFAULT_WQ_PAGE_SIZE);
580
+ if (err) {
581
+ dev_err(&func_to_io->hwif->pdev->dev, "Failed to set wq page size\n");
582
+ goto init_wq_pg_size_err;
583
+ }
584
+
493585 err = hinic_init_cmdqs(&func_to_io->cmdqs, hwif,
494586 func_to_io->cmdq_db_area);
495587 if (err) {
....@@ -500,6 +592,11 @@
500592 return 0;
501593
502594 err_init_cmdqs:
595
+ if (!HINIC_IS_VF(func_to_io->hwif))
596
+ hinic_set_wq_page_size(func_to_io->hwdev,
597
+ HINIC_HWIF_FUNC_IDX(hwif),
598
+ HINIC_HW_WQ_PAGE_SIZE);
599
+init_wq_pg_size_err:
503600 err_db_area:
504601 for (type = HINIC_CMDQ_SYNC; type < cmdq; type++)
505602 return_db_area(func_to_io, func_to_io->cmdq_db_area[type]);
....@@ -524,6 +621,11 @@
524621
525622 hinic_free_cmdqs(&func_to_io->cmdqs);
526623
624
+ if (!HINIC_IS_VF(func_to_io->hwif))
625
+ hinic_set_wq_page_size(func_to_io->hwdev,
626
+ HINIC_HWIF_FUNC_IDX(func_to_io->hwif),
627
+ HINIC_HW_WQ_PAGE_SIZE);
628
+
527629 for (cmdq = HINIC_CMDQ_SYNC; cmdq < HINIC_MAX_CMDQ_TYPES; cmdq++)
528630 return_db_area(func_to_io, func_to_io->cmdq_db_area[cmdq]);
529631