cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hinic_hw_io.c (16523B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Huawei HiNIC PCI Express Linux driver
      4 * Copyright(c) 2017 Huawei Technologies Co., Ltd
      5 */
      6
      7#include <linux/kernel.h>
      8#include <linux/types.h>
      9#include <linux/pci.h>
     10#include <linux/device.h>
     11#include <linux/errno.h>
     12#include <linux/slab.h>
     13#include <linux/semaphore.h>
     14#include <linux/dma-mapping.h>
     15#include <linux/io.h>
     16#include <linux/err.h>
     17
     18#include "hinic_hw_dev.h"
     19#include "hinic_hw_if.h"
     20#include "hinic_hw_eqs.h"
     21#include "hinic_hw_wqe.h"
     22#include "hinic_hw_wq.h"
     23#include "hinic_hw_cmdq.h"
     24#include "hinic_hw_qp_ctxt.h"
     25#include "hinic_hw_qp.h"
     26#include "hinic_hw_io.h"
     27
     28#define CI_Q_ADDR_SIZE                  sizeof(u32)
     29
     30#define CI_ADDR(base_addr, q_id)        ((base_addr) + \
     31					 (q_id) * CI_Q_ADDR_SIZE)
     32
     33#define CI_TABLE_SIZE(num_qps)          ((num_qps) * CI_Q_ADDR_SIZE)
     34
     35#define DB_IDX(db, db_base)             \
     36	(((unsigned long)(db) - (unsigned long)(db_base)) / HINIC_DB_PAGE_SIZE)
     37
     38#define HINIC_PAGE_SIZE_HW(pg_size)	((u8)ilog2((u32)((pg_size) >> 12)))
     39
     40enum io_cmd {
     41	IO_CMD_MODIFY_QUEUE_CTXT = 0,
     42	IO_CMD_CLEAN_QUEUE_CTXT,
     43};
     44
     45static void init_db_area_idx(struct hinic_free_db_area *free_db_area)
     46{
     47	int i;
     48
     49	for (i = 0; i < HINIC_DB_MAX_AREAS; i++)
     50		free_db_area->db_idx[i] = i;
     51
     52	free_db_area->alloc_pos = 0;
     53	free_db_area->return_pos = HINIC_DB_MAX_AREAS;
     54
     55	free_db_area->num_free = HINIC_DB_MAX_AREAS;
     56
     57	sema_init(&free_db_area->idx_lock, 1);
     58}
     59
     60static void __iomem *get_db_area(struct hinic_func_to_io *func_to_io)
     61{
     62	struct hinic_free_db_area *free_db_area = &func_to_io->free_db_area;
     63	int pos, idx;
     64
     65	down(&free_db_area->idx_lock);
     66
     67	free_db_area->num_free--;
     68
     69	if (free_db_area->num_free < 0) {
     70		free_db_area->num_free++;
     71		up(&free_db_area->idx_lock);
     72		return ERR_PTR(-ENOMEM);
     73	}
     74
     75	pos = free_db_area->alloc_pos++;
     76	pos &= HINIC_DB_MAX_AREAS - 1;
     77
     78	idx = free_db_area->db_idx[pos];
     79
     80	free_db_area->db_idx[pos] = -1;
     81
     82	up(&free_db_area->idx_lock);
     83
     84	return func_to_io->db_base + idx * HINIC_DB_PAGE_SIZE;
     85}
     86
     87static void return_db_area(struct hinic_func_to_io *func_to_io,
     88			   void __iomem *db_base)
     89{
     90	struct hinic_free_db_area *free_db_area = &func_to_io->free_db_area;
     91	int pos, idx = DB_IDX(db_base, func_to_io->db_base);
     92
     93	down(&free_db_area->idx_lock);
     94
     95	pos = free_db_area->return_pos++;
     96	pos &= HINIC_DB_MAX_AREAS - 1;
     97
     98	free_db_area->db_idx[pos] = idx;
     99
    100	free_db_area->num_free++;
    101
    102	up(&free_db_area->idx_lock);
    103}
    104
    105static int write_sq_ctxts(struct hinic_func_to_io *func_to_io, u16 base_qpn,
    106			  u16 num_sqs)
    107{
    108	struct hinic_hwif *hwif = func_to_io->hwif;
    109	struct hinic_sq_ctxt_block *sq_ctxt_block;
    110	struct pci_dev *pdev = hwif->pdev;
    111	struct hinic_cmdq_buf cmdq_buf;
    112	struct hinic_sq_ctxt *sq_ctxt;
    113	struct hinic_qp *qp;
    114	u64 out_param;
    115	int err, i;
    116
    117	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
    118	if (err) {
    119		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
    120		return err;
    121	}
    122
    123	sq_ctxt_block = cmdq_buf.buf;
    124	sq_ctxt = sq_ctxt_block->sq_ctxt;
    125
    126	hinic_qp_prepare_header(&sq_ctxt_block->hdr, HINIC_QP_CTXT_TYPE_SQ,
    127				num_sqs, func_to_io->max_qps);
    128	for (i = 0; i < num_sqs; i++) {
    129		qp = &func_to_io->qps[i];
    130
    131		hinic_sq_prepare_ctxt(&sq_ctxt[i], &qp->sq,
    132				      base_qpn + qp->q_id);
    133	}
    134
    135	cmdq_buf.size = HINIC_SQ_CTXT_SIZE(num_sqs);
    136
    137	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
    138				     IO_CMD_MODIFY_QUEUE_CTXT, &cmdq_buf,
    139				     &out_param);
    140	if (err || out_param != 0) {
    141		dev_err(&pdev->dev, "Failed to set SQ ctxts\n");
    142		err = -EFAULT;
    143	}
    144
    145	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
    146	return err;
    147}
    148
    149static int write_rq_ctxts(struct hinic_func_to_io *func_to_io, u16 base_qpn,
    150			  u16 num_rqs)
    151{
    152	struct hinic_hwif *hwif = func_to_io->hwif;
    153	struct hinic_rq_ctxt_block *rq_ctxt_block;
    154	struct pci_dev *pdev = hwif->pdev;
    155	struct hinic_cmdq_buf cmdq_buf;
    156	struct hinic_rq_ctxt *rq_ctxt;
    157	struct hinic_qp *qp;
    158	u64 out_param;
    159	int err, i;
    160
    161	err = hinic_alloc_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
    162	if (err) {
    163		dev_err(&pdev->dev, "Failed to allocate cmdq buf\n");
    164		return err;
    165	}
    166
    167	rq_ctxt_block = cmdq_buf.buf;
    168	rq_ctxt = rq_ctxt_block->rq_ctxt;
    169
    170	hinic_qp_prepare_header(&rq_ctxt_block->hdr, HINIC_QP_CTXT_TYPE_RQ,
    171				num_rqs, func_to_io->max_qps);
    172	for (i = 0; i < num_rqs; i++) {
    173		qp = &func_to_io->qps[i];
    174
    175		hinic_rq_prepare_ctxt(&rq_ctxt[i], &qp->rq,
    176				      base_qpn + qp->q_id);
    177	}
    178
    179	cmdq_buf.size = HINIC_RQ_CTXT_SIZE(num_rqs);
    180
    181	err = hinic_cmdq_direct_resp(&func_to_io->cmdqs, HINIC_MOD_L2NIC,
    182				     IO_CMD_MODIFY_QUEUE_CTXT, &cmdq_buf,
    183				     &out_param);
    184	if (err || out_param != 0) {
    185		dev_err(&pdev->dev, "Failed to set RQ ctxts\n");
    186		err = -EFAULT;
    187	}
    188
    189	hinic_free_cmdq_buf(&func_to_io->cmdqs, &cmdq_buf);
    190	return err;
    191}
    192
    193/**
    194 * write_qp_ctxts - write the qp ctxt to HW
    195 * @func_to_io: func to io channel that holds the IO components
    196 * @base_qpn: first qp number
    197 * @num_qps: number of qps to write
    198 *
    199 * Return 0 - Success, negative - Failure
    200 **/
    201static int write_qp_ctxts(struct hinic_func_to_io *func_to_io, u16 base_qpn,
    202			  u16 num_qps)
    203{
    204	return (write_sq_ctxts(func_to_io, base_qpn, num_qps) ||
    205		write_rq_ctxts(func_to_io, base_qpn, num_qps));
    206}
    207
    208static 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
    252static 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
    261/**
    262 * init_qp - Initialize a Queue Pair
    263 * @func_to_io: func to io channel that holds the IO components
    264 * @qp: pointer to the qp to initialize
    265 * @q_id: the id of the qp
    266 * @sq_msix_entry: msix entry for sq
    267 * @rq_msix_entry: msix entry for rq
    268 *
    269 * Return 0 - Success, negative - Failure
    270 **/
    271static int init_qp(struct hinic_func_to_io *func_to_io,
    272		   struct hinic_qp *qp, int q_id,
    273		   struct msix_entry *sq_msix_entry,
    274		   struct msix_entry *rq_msix_entry)
    275{
    276	struct hinic_hwif *hwif = func_to_io->hwif;
    277	struct pci_dev *pdev = hwif->pdev;
    278	void __iomem *db_base;
    279	int err;
    280
    281	qp->q_id = q_id;
    282
    283	err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->sq_wq[q_id],
    284				HINIC_SQ_WQEBB_SIZE, HINIC_SQ_PAGE_SIZE,
    285				func_to_io->sq_depth, HINIC_SQ_WQE_MAX_SIZE);
    286	if (err) {
    287		dev_err(&pdev->dev, "Failed to allocate WQ for SQ\n");
    288		return err;
    289	}
    290
    291	err = hinic_wq_allocate(&func_to_io->wqs, &func_to_io->rq_wq[q_id],
    292				HINIC_RQ_WQEBB_SIZE, HINIC_RQ_PAGE_SIZE,
    293				func_to_io->rq_depth, HINIC_RQ_WQE_SIZE);
    294	if (err) {
    295		dev_err(&pdev->dev, "Failed to allocate WQ for RQ\n");
    296		goto err_rq_alloc;
    297	}
    298
    299	db_base = get_db_area(func_to_io);
    300	if (IS_ERR(db_base)) {
    301		dev_err(&pdev->dev, "Failed to get DB area for SQ\n");
    302		err = PTR_ERR(db_base);
    303		goto err_get_db;
    304	}
    305
    306	func_to_io->sq_db[q_id] = db_base;
    307
    308	qp->sq.qid = q_id;
    309	err = hinic_init_sq(&qp->sq, hwif, &func_to_io->sq_wq[q_id],
    310			    sq_msix_entry,
    311			    CI_ADDR(func_to_io->ci_addr_base, q_id),
    312			    CI_ADDR(func_to_io->ci_dma_base, q_id), db_base);
    313	if (err) {
    314		dev_err(&pdev->dev, "Failed to init SQ\n");
    315		goto err_sq_init;
    316	}
    317
    318	qp->rq.qid = q_id;
    319	err = hinic_init_rq(&qp->rq, hwif, &func_to_io->rq_wq[q_id],
    320			    rq_msix_entry);
    321	if (err) {
    322		dev_err(&pdev->dev, "Failed to init RQ\n");
    323		goto err_rq_init;
    324	}
    325
    326	return 0;
    327
    328err_rq_init:
    329	hinic_clean_sq(&qp->sq);
    330
    331err_sq_init:
    332	return_db_area(func_to_io, db_base);
    333
    334err_get_db:
    335	hinic_wq_free(&func_to_io->wqs, &func_to_io->rq_wq[q_id]);
    336
    337err_rq_alloc:
    338	hinic_wq_free(&func_to_io->wqs, &func_to_io->sq_wq[q_id]);
    339	return err;
    340}
    341
    342/**
    343 * destroy_qp - Clean the resources of a Queue Pair
    344 * @func_to_io: func to io channel that holds the IO components
    345 * @qp: pointer to the qp to clean
    346 **/
    347static void destroy_qp(struct hinic_func_to_io *func_to_io,
    348		       struct hinic_qp *qp)
    349{
    350	int q_id = qp->q_id;
    351
    352	hinic_clean_rq(&qp->rq);
    353	hinic_clean_sq(&qp->sq);
    354
    355	return_db_area(func_to_io, func_to_io->sq_db[q_id]);
    356
    357	hinic_wq_free(&func_to_io->wqs, &func_to_io->rq_wq[q_id]);
    358	hinic_wq_free(&func_to_io->wqs, &func_to_io->sq_wq[q_id]);
    359}
    360
    361/**
    362 * hinic_io_create_qps - Create Queue Pairs
    363 * @func_to_io: func to io channel that holds the IO components
    364 * @base_qpn: base qp number
    365 * @num_qps: number queue pairs to create
    366 * @sq_msix_entries: msix entries for sq
    367 * @rq_msix_entries: msix entries for rq
    368 *
    369 * Return 0 - Success, negative - Failure
    370 **/
    371int hinic_io_create_qps(struct hinic_func_to_io *func_to_io,
    372			u16 base_qpn, int num_qps,
    373			struct msix_entry *sq_msix_entries,
    374			struct msix_entry *rq_msix_entries)
    375{
    376	struct hinic_hwif *hwif = func_to_io->hwif;
    377	struct pci_dev *pdev = hwif->pdev;
    378	void *ci_addr_base;
    379	int i, j, err;
    380
    381	func_to_io->qps = devm_kcalloc(&pdev->dev, num_qps,
    382				       sizeof(*func_to_io->qps), GFP_KERNEL);
    383	if (!func_to_io->qps)
    384		return -ENOMEM;
    385
    386	func_to_io->sq_wq = devm_kcalloc(&pdev->dev, num_qps,
    387					 sizeof(*func_to_io->sq_wq), GFP_KERNEL);
    388	if (!func_to_io->sq_wq) {
    389		err = -ENOMEM;
    390		goto err_sq_wq;
    391	}
    392
    393	func_to_io->rq_wq = devm_kcalloc(&pdev->dev, num_qps,
    394					 sizeof(*func_to_io->rq_wq), GFP_KERNEL);
    395	if (!func_to_io->rq_wq) {
    396		err = -ENOMEM;
    397		goto err_rq_wq;
    398	}
    399
    400	func_to_io->sq_db = devm_kcalloc(&pdev->dev, num_qps,
    401					 sizeof(*func_to_io->sq_db), GFP_KERNEL);
    402	if (!func_to_io->sq_db) {
    403		err = -ENOMEM;
    404		goto err_sq_db;
    405	}
    406
    407	ci_addr_base = dma_alloc_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
    408					  &func_to_io->ci_dma_base,
    409					  GFP_KERNEL);
    410	if (!ci_addr_base) {
    411		dev_err(&pdev->dev, "Failed to allocate CI area\n");
    412		err = -ENOMEM;
    413		goto err_ci_base;
    414	}
    415
    416	func_to_io->ci_addr_base = ci_addr_base;
    417
    418	for (i = 0; i < num_qps; i++) {
    419		err = init_qp(func_to_io, &func_to_io->qps[i], i,
    420			      &sq_msix_entries[i], &rq_msix_entries[i]);
    421		if (err) {
    422			dev_err(&pdev->dev, "Failed to create QP %d\n", i);
    423			goto err_init_qp;
    424		}
    425	}
    426
    427	err = write_qp_ctxts(func_to_io, base_qpn, num_qps);
    428	if (err) {
    429		dev_err(&pdev->dev, "Failed to init QP ctxts\n");
    430		goto err_write_qp_ctxts;
    431	}
    432
    433	err = hinic_clean_qp_offload_ctxt(func_to_io);
    434	if (err) {
    435		dev_err(&pdev->dev, "Failed to clean QP contexts space\n");
    436		goto err_write_qp_ctxts;
    437	}
    438
    439	return 0;
    440
    441err_write_qp_ctxts:
    442err_init_qp:
    443	for (j = 0; j < i; j++)
    444		destroy_qp(func_to_io, &func_to_io->qps[j]);
    445
    446	dma_free_coherent(&pdev->dev, CI_TABLE_SIZE(num_qps),
    447			  func_to_io->ci_addr_base, func_to_io->ci_dma_base);
    448
    449err_ci_base:
    450	devm_kfree(&pdev->dev, func_to_io->sq_db);
    451
    452err_sq_db:
    453	devm_kfree(&pdev->dev, func_to_io->rq_wq);
    454
    455err_rq_wq:
    456	devm_kfree(&pdev->dev, func_to_io->sq_wq);
    457
    458err_sq_wq:
    459	devm_kfree(&pdev->dev, func_to_io->qps);
    460	return err;
    461}
    462
    463/**
    464 * hinic_io_destroy_qps - Destroy the IO Queue Pairs
    465 * @func_to_io: func to io channel that holds the IO components
    466 * @num_qps: number queue pairs to destroy
    467 **/
    468void hinic_io_destroy_qps(struct hinic_func_to_io *func_to_io, int num_qps)
    469{
    470	struct hinic_hwif *hwif = func_to_io->hwif;
    471	struct pci_dev *pdev = hwif->pdev;
    472	size_t ci_table_size;
    473	int i;
    474
    475	ci_table_size = CI_TABLE_SIZE(num_qps);
    476
    477	for (i = 0; i < num_qps; i++)
    478		destroy_qp(func_to_io, &func_to_io->qps[i]);
    479
    480	dma_free_coherent(&pdev->dev, ci_table_size, func_to_io->ci_addr_base,
    481			  func_to_io->ci_dma_base);
    482
    483	devm_kfree(&pdev->dev, func_to_io->sq_db);
    484
    485	devm_kfree(&pdev->dev, func_to_io->rq_wq);
    486	devm_kfree(&pdev->dev, func_to_io->sq_wq);
    487
    488	devm_kfree(&pdev->dev, func_to_io->qps);
    489}
    490
    491int hinic_set_wq_page_size(struct hinic_hwdev *hwdev, u16 func_idx,
    492			   u32 page_size)
    493{
    494	struct hinic_wq_page_size page_size_info = {0};
    495	u16 out_size = sizeof(page_size_info);
    496	struct hinic_pfhwdev *pfhwdev;
    497	int err;
    498
    499	pfhwdev = container_of(hwdev, struct hinic_pfhwdev, hwdev);
    500
    501	page_size_info.func_idx = func_idx;
    502	page_size_info.ppf_idx = HINIC_HWIF_PPF_IDX(hwdev->hwif);
    503	page_size_info.page_size = HINIC_PAGE_SIZE_HW(page_size);
    504
    505	err = hinic_msg_to_mgmt(&pfhwdev->pf_to_mgmt, HINIC_MOD_COMM,
    506				HINIC_COMM_CMD_PAGESIZE_SET, &page_size_info,
    507				sizeof(page_size_info), &page_size_info,
    508				&out_size, HINIC_MGMT_MSG_SYNC);
    509	if (err || !out_size || page_size_info.status) {
    510		dev_err(&hwdev->hwif->pdev->dev, "Failed to set wq page size, err: %d, status: 0x%x, out_size: 0x%0x\n",
    511			err, page_size_info.status, out_size);
    512		return -EFAULT;
    513	}
    514
    515	return 0;
    516}
    517
    518/**
    519 * hinic_io_init - Initialize the IO components
    520 * @func_to_io: func to io channel that holds the IO components
    521 * @hwif: HW interface for accessing IO
    522 * @max_qps: maximum QPs in HW
    523 * @num_ceqs: number completion event queues
    524 * @ceq_msix_entries: msix entries for ceqs
    525 *
    526 * Return 0 - Success, negative - Failure
    527 **/
    528int hinic_io_init(struct hinic_func_to_io *func_to_io,
    529		  struct hinic_hwif *hwif, u16 max_qps, int num_ceqs,
    530		  struct msix_entry *ceq_msix_entries)
    531{
    532	struct pci_dev *pdev = hwif->pdev;
    533	enum hinic_cmdq_type cmdq, type;
    534	void __iomem *db_area;
    535	int err;
    536
    537	func_to_io->hwif = hwif;
    538	func_to_io->qps = NULL;
    539	func_to_io->max_qps = max_qps;
    540	func_to_io->ceqs.hwdev = func_to_io->hwdev;
    541
    542	err = hinic_ceqs_init(&func_to_io->ceqs, hwif, num_ceqs,
    543			      HINIC_DEFAULT_CEQ_LEN, HINIC_EQ_PAGE_SIZE,
    544			      ceq_msix_entries);
    545	if (err) {
    546		dev_err(&pdev->dev, "Failed to init CEQs\n");
    547		return err;
    548	}
    549
    550	err = hinic_wqs_alloc(&func_to_io->wqs, 2 * max_qps, hwif);
    551	if (err) {
    552		dev_err(&pdev->dev, "Failed to allocate WQS for IO\n");
    553		goto err_wqs_alloc;
    554	}
    555
    556	func_to_io->db_base = pci_ioremap_bar(pdev, HINIC_PCI_DB_BAR);
    557	if (!func_to_io->db_base) {
    558		dev_err(&pdev->dev, "Failed to remap IO DB area\n");
    559		err = -ENOMEM;
    560		goto err_db_ioremap;
    561	}
    562
    563	init_db_area_idx(&func_to_io->free_db_area);
    564
    565	for (cmdq = HINIC_CMDQ_SYNC; cmdq < HINIC_MAX_CMDQ_TYPES; cmdq++) {
    566		db_area = get_db_area(func_to_io);
    567		if (IS_ERR(db_area)) {
    568			dev_err(&pdev->dev, "Failed to get cmdq db area\n");
    569			err = PTR_ERR(db_area);
    570			goto err_db_area;
    571		}
    572
    573		func_to_io->cmdq_db_area[cmdq] = db_area;
    574	}
    575
    576	err = hinic_set_wq_page_size(func_to_io->hwdev,
    577				     HINIC_HWIF_FUNC_IDX(hwif),
    578				     HINIC_DEFAULT_WQ_PAGE_SIZE);
    579	if (err) {
    580		dev_err(&func_to_io->hwif->pdev->dev, "Failed to set wq page size\n");
    581		goto init_wq_pg_size_err;
    582	}
    583
    584	err = hinic_init_cmdqs(&func_to_io->cmdqs, hwif,
    585			       func_to_io->cmdq_db_area);
    586	if (err) {
    587		dev_err(&pdev->dev, "Failed to initialize cmdqs\n");
    588		goto err_init_cmdqs;
    589	}
    590
    591	return 0;
    592
    593err_init_cmdqs:
    594	if (!HINIC_IS_VF(func_to_io->hwif))
    595		hinic_set_wq_page_size(func_to_io->hwdev,
    596				       HINIC_HWIF_FUNC_IDX(hwif),
    597				       HINIC_HW_WQ_PAGE_SIZE);
    598init_wq_pg_size_err:
    599err_db_area:
    600	for (type = HINIC_CMDQ_SYNC; type < cmdq; type++)
    601		return_db_area(func_to_io, func_to_io->cmdq_db_area[type]);
    602
    603	iounmap(func_to_io->db_base);
    604
    605err_db_ioremap:
    606	hinic_wqs_free(&func_to_io->wqs);
    607
    608err_wqs_alloc:
    609	hinic_ceqs_free(&func_to_io->ceqs);
    610	return err;
    611}
    612
    613/**
    614 * hinic_io_free - Free the IO components
    615 * @func_to_io: func to io channel that holds the IO components
    616 **/
    617void hinic_io_free(struct hinic_func_to_io *func_to_io)
    618{
    619	enum hinic_cmdq_type cmdq;
    620
    621	hinic_free_cmdqs(&func_to_io->cmdqs);
    622
    623	if (!HINIC_IS_VF(func_to_io->hwif))
    624		hinic_set_wq_page_size(func_to_io->hwdev,
    625				       HINIC_HWIF_FUNC_IDX(func_to_io->hwif),
    626				       HINIC_HW_WQ_PAGE_SIZE);
    627
    628	for (cmdq = HINIC_CMDQ_SYNC; cmdq < HINIC_MAX_CMDQ_TYPES; cmdq++)
    629		return_db_area(func_to_io, func_to_io->cmdq_db_area[cmdq]);
    630
    631	iounmap(func_to_io->db_base);
    632	hinic_wqs_free(&func_to_io->wqs);
    633	hinic_ceqs_free(&func_to_io->ceqs);
    634}