xref: /linux/drivers/net/ethernet/broadcom/bnge/bnge_hwrm_lib.c (revision 8be4d31cb8aaeea27bde4b7ddb26e28a89062ebf)
1fb7d8b61SVikas Gupta // SPDX-License-Identifier: GPL-2.0
2fb7d8b61SVikas Gupta // Copyright (c) 2025 Broadcom.
3fb7d8b61SVikas Gupta 
4fb7d8b61SVikas Gupta #include <linux/errno.h>
5fb7d8b61SVikas Gupta #include <linux/kernel.h>
6fb7d8b61SVikas Gupta #include <linux/mm.h>
7fb7d8b61SVikas Gupta #include <linux/pci.h>
8*c34632dbSAndy Gospodarek #include <linux/bnxt/hsi.h>
9fb7d8b61SVikas Gupta 
10fb7d8b61SVikas Gupta #include "bnge.h"
11fb7d8b61SVikas Gupta #include "bnge_hwrm.h"
12fb7d8b61SVikas Gupta #include "bnge_hwrm_lib.h"
1329c5b358SVikas Gupta #include "bnge_rmem.h"
14627c67f0SVikas Gupta #include "bnge_resc.h"
15fb7d8b61SVikas Gupta 
bnge_hwrm_ver_get(struct bnge_dev * bd)16fb7d8b61SVikas Gupta int bnge_hwrm_ver_get(struct bnge_dev *bd)
17fb7d8b61SVikas Gupta {
18fb7d8b61SVikas Gupta 	u32 dev_caps_cfg, hwrm_ver, hwrm_spec_code;
19fb7d8b61SVikas Gupta 	u16 fw_maj, fw_min, fw_bld, fw_rsv;
20fb7d8b61SVikas Gupta 	struct hwrm_ver_get_output *resp;
21fb7d8b61SVikas Gupta 	struct hwrm_ver_get_input *req;
22fb7d8b61SVikas Gupta 	int rc;
23fb7d8b61SVikas Gupta 
24fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_VER_GET);
25fb7d8b61SVikas Gupta 	if (rc)
26fb7d8b61SVikas Gupta 		return rc;
27fb7d8b61SVikas Gupta 
28fb7d8b61SVikas Gupta 	bnge_hwrm_req_flags(bd, req, BNGE_HWRM_FULL_WAIT);
29fb7d8b61SVikas Gupta 	bd->hwrm_max_req_len = HWRM_MAX_REQ_LEN;
30fb7d8b61SVikas Gupta 	req->hwrm_intf_maj = HWRM_VERSION_MAJOR;
31fb7d8b61SVikas Gupta 	req->hwrm_intf_min = HWRM_VERSION_MINOR;
32fb7d8b61SVikas Gupta 	req->hwrm_intf_upd = HWRM_VERSION_UPDATE;
33fb7d8b61SVikas Gupta 
34fb7d8b61SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
35fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
36fb7d8b61SVikas Gupta 	if (rc)
37fb7d8b61SVikas Gupta 		goto hwrm_ver_get_exit;
38fb7d8b61SVikas Gupta 
39fb7d8b61SVikas Gupta 	memcpy(&bd->ver_resp, resp, sizeof(struct hwrm_ver_get_output));
40fb7d8b61SVikas Gupta 
41fb7d8b61SVikas Gupta 	hwrm_spec_code = resp->hwrm_intf_maj_8b << 16 |
42fb7d8b61SVikas Gupta 			 resp->hwrm_intf_min_8b << 8 |
43fb7d8b61SVikas Gupta 			 resp->hwrm_intf_upd_8b;
44fb7d8b61SVikas Gupta 	hwrm_ver = HWRM_VERSION_MAJOR << 16 | HWRM_VERSION_MINOR << 8 |
45fb7d8b61SVikas Gupta 			HWRM_VERSION_UPDATE;
46fb7d8b61SVikas Gupta 
47fb7d8b61SVikas Gupta 	if (hwrm_spec_code > hwrm_ver)
48fb7d8b61SVikas Gupta 		snprintf(bd->hwrm_ver_supp, FW_VER_STR_LEN, "%d.%d.%d",
49fb7d8b61SVikas Gupta 			 HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR,
50fb7d8b61SVikas Gupta 			 HWRM_VERSION_UPDATE);
51fb7d8b61SVikas Gupta 	else
52fb7d8b61SVikas Gupta 		snprintf(bd->hwrm_ver_supp, FW_VER_STR_LEN, "%d.%d.%d",
53fb7d8b61SVikas Gupta 			 resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b,
54fb7d8b61SVikas Gupta 			 resp->hwrm_intf_upd_8b);
55fb7d8b61SVikas Gupta 
56fb7d8b61SVikas Gupta 	fw_maj = le16_to_cpu(resp->hwrm_fw_major);
57fb7d8b61SVikas Gupta 	fw_min = le16_to_cpu(resp->hwrm_fw_minor);
58fb7d8b61SVikas Gupta 	fw_bld = le16_to_cpu(resp->hwrm_fw_build);
59fb7d8b61SVikas Gupta 	fw_rsv = le16_to_cpu(resp->hwrm_fw_patch);
60fb7d8b61SVikas Gupta 
61fb7d8b61SVikas Gupta 	bd->fw_ver_code = BNGE_FW_VER_CODE(fw_maj, fw_min, fw_bld, fw_rsv);
62fb7d8b61SVikas Gupta 	snprintf(bd->fw_ver_str, FW_VER_STR_LEN, "%d.%d.%d.%d",
63fb7d8b61SVikas Gupta 		 fw_maj, fw_min, fw_bld, fw_rsv);
64fb7d8b61SVikas Gupta 
65fb7d8b61SVikas Gupta 	if (strlen(resp->active_pkg_name)) {
66fb7d8b61SVikas Gupta 		int fw_ver_len = strlen(bd->fw_ver_str);
67fb7d8b61SVikas Gupta 
68fb7d8b61SVikas Gupta 		snprintf(bd->fw_ver_str + fw_ver_len,
69fb7d8b61SVikas Gupta 			 FW_VER_STR_LEN - fw_ver_len - 1, "/pkg %s",
70fb7d8b61SVikas Gupta 			 resp->active_pkg_name);
71fb7d8b61SVikas Gupta 		bd->fw_cap |= BNGE_FW_CAP_PKG_VER;
72fb7d8b61SVikas Gupta 	}
73fb7d8b61SVikas Gupta 
74fb7d8b61SVikas Gupta 	bd->hwrm_cmd_timeout = le16_to_cpu(resp->def_req_timeout);
75fb7d8b61SVikas Gupta 	if (!bd->hwrm_cmd_timeout)
76fb7d8b61SVikas Gupta 		bd->hwrm_cmd_timeout = BNGE_DFLT_HWRM_CMD_TIMEOUT;
77fb7d8b61SVikas Gupta 	bd->hwrm_cmd_max_timeout = le16_to_cpu(resp->max_req_timeout) * 1000;
78fb7d8b61SVikas Gupta 	if (!bd->hwrm_cmd_max_timeout)
79fb7d8b61SVikas Gupta 		bd->hwrm_cmd_max_timeout = BNGE_HWRM_CMD_MAX_TIMEOUT;
80fb7d8b61SVikas Gupta 	else if (bd->hwrm_cmd_max_timeout > BNGE_HWRM_CMD_MAX_TIMEOUT)
81fb7d8b61SVikas Gupta 		dev_warn(bd->dev, "Default HWRM commands max timeout increased to %d seconds\n",
82fb7d8b61SVikas Gupta 			 bd->hwrm_cmd_max_timeout / 1000);
83fb7d8b61SVikas Gupta 
84fb7d8b61SVikas Gupta 	bd->hwrm_max_req_len = le16_to_cpu(resp->max_req_win_len);
85fb7d8b61SVikas Gupta 	bd->hwrm_max_ext_req_len = le16_to_cpu(resp->max_ext_req_len);
86fb7d8b61SVikas Gupta 
87fb7d8b61SVikas Gupta 	if (bd->hwrm_max_ext_req_len < HWRM_MAX_REQ_LEN)
88fb7d8b61SVikas Gupta 		bd->hwrm_max_ext_req_len = HWRM_MAX_REQ_LEN;
89fb7d8b61SVikas Gupta 
90fb7d8b61SVikas Gupta 	bd->chip_num = le16_to_cpu(resp->chip_num);
91fb7d8b61SVikas Gupta 	bd->chip_rev = resp->chip_rev;
92fb7d8b61SVikas Gupta 
93fb7d8b61SVikas Gupta 	dev_caps_cfg = le32_to_cpu(resp->dev_caps_cfg);
94fb7d8b61SVikas Gupta 	if ((dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED) &&
95fb7d8b61SVikas Gupta 	    (dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_SHORT_CMD_REQUIRED))
96fb7d8b61SVikas Gupta 		bd->fw_cap |= BNGE_FW_CAP_SHORT_CMD;
97fb7d8b61SVikas Gupta 
98fb7d8b61SVikas Gupta 	if (dev_caps_cfg & VER_GET_RESP_DEV_CAPS_CFG_KONG_MB_CHNL_SUPPORTED)
99fb7d8b61SVikas Gupta 		bd->fw_cap |= BNGE_FW_CAP_KONG_MB_CHNL;
100fb7d8b61SVikas Gupta 
101fb7d8b61SVikas Gupta 	if (dev_caps_cfg &
102fb7d8b61SVikas Gupta 	    VER_GET_RESP_DEV_CAPS_CFG_CFA_ADV_FLOW_MGNT_SUPPORTED)
103fb7d8b61SVikas Gupta 		bd->fw_cap |= BNGE_FW_CAP_CFA_ADV_FLOW;
104fb7d8b61SVikas Gupta 
105fb7d8b61SVikas Gupta hwrm_ver_get_exit:
106fb7d8b61SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
107fb7d8b61SVikas Gupta 	return rc;
108fb7d8b61SVikas Gupta }
109fb7d8b61SVikas Gupta 
110fb7d8b61SVikas Gupta int
bnge_hwrm_nvm_dev_info(struct bnge_dev * bd,struct hwrm_nvm_get_dev_info_output * nvm_info)111fb7d8b61SVikas Gupta bnge_hwrm_nvm_dev_info(struct bnge_dev *bd,
112fb7d8b61SVikas Gupta 		       struct hwrm_nvm_get_dev_info_output *nvm_info)
113fb7d8b61SVikas Gupta {
114fb7d8b61SVikas Gupta 	struct hwrm_nvm_get_dev_info_output *resp;
115fb7d8b61SVikas Gupta 	struct hwrm_nvm_get_dev_info_input *req;
116fb7d8b61SVikas Gupta 	int rc;
117fb7d8b61SVikas Gupta 
118fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_NVM_GET_DEV_INFO);
119fb7d8b61SVikas Gupta 	if (rc)
120fb7d8b61SVikas Gupta 		return rc;
121fb7d8b61SVikas Gupta 
122fb7d8b61SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
123fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
124fb7d8b61SVikas Gupta 	if (!rc)
125fb7d8b61SVikas Gupta 		memcpy(nvm_info, resp, sizeof(*resp));
126fb7d8b61SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
127fb7d8b61SVikas Gupta 	return rc;
128fb7d8b61SVikas Gupta }
129fb7d8b61SVikas Gupta 
bnge_hwrm_func_reset(struct bnge_dev * bd)130fb7d8b61SVikas Gupta int bnge_hwrm_func_reset(struct bnge_dev *bd)
131fb7d8b61SVikas Gupta {
132fb7d8b61SVikas Gupta 	struct hwrm_func_reset_input *req;
133fb7d8b61SVikas Gupta 	int rc;
134fb7d8b61SVikas Gupta 
135fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_RESET);
136fb7d8b61SVikas Gupta 	if (rc)
137fb7d8b61SVikas Gupta 		return rc;
138fb7d8b61SVikas Gupta 
139fb7d8b61SVikas Gupta 	req->enables = 0;
140fb7d8b61SVikas Gupta 	bnge_hwrm_req_timeout(bd, req, BNGE_HWRM_RESET_TIMEOUT);
141fb7d8b61SVikas Gupta 	return bnge_hwrm_req_send(bd, req);
142fb7d8b61SVikas Gupta }
143fb7d8b61SVikas Gupta 
bnge_hwrm_fw_set_time(struct bnge_dev * bd)144fb7d8b61SVikas Gupta int bnge_hwrm_fw_set_time(struct bnge_dev *bd)
145fb7d8b61SVikas Gupta {
146fb7d8b61SVikas Gupta 	struct hwrm_fw_set_time_input *req;
147fb7d8b61SVikas Gupta 	struct tm tm;
148fb7d8b61SVikas Gupta 	int rc;
149fb7d8b61SVikas Gupta 
150fb7d8b61SVikas Gupta 	time64_to_tm(ktime_get_real_seconds(), 0, &tm);
151fb7d8b61SVikas Gupta 
152fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FW_SET_TIME);
153fb7d8b61SVikas Gupta 	if (rc)
154fb7d8b61SVikas Gupta 		return rc;
155fb7d8b61SVikas Gupta 
156fb7d8b61SVikas Gupta 	req->year = cpu_to_le16(1900 + tm.tm_year);
157fb7d8b61SVikas Gupta 	req->month = 1 + tm.tm_mon;
158fb7d8b61SVikas Gupta 	req->day = tm.tm_mday;
159fb7d8b61SVikas Gupta 	req->hour = tm.tm_hour;
160fb7d8b61SVikas Gupta 	req->minute = tm.tm_min;
161fb7d8b61SVikas Gupta 	req->second = tm.tm_sec;
162fb7d8b61SVikas Gupta 	return bnge_hwrm_req_send(bd, req);
163fb7d8b61SVikas Gupta }
164fb7d8b61SVikas Gupta 
bnge_hwrm_func_drv_rgtr(struct bnge_dev * bd)165fb7d8b61SVikas Gupta int bnge_hwrm_func_drv_rgtr(struct bnge_dev *bd)
166fb7d8b61SVikas Gupta {
167fb7d8b61SVikas Gupta 	struct hwrm_func_drv_rgtr_output *resp;
168fb7d8b61SVikas Gupta 	struct hwrm_func_drv_rgtr_input *req;
169fb7d8b61SVikas Gupta 	u32 flags;
170fb7d8b61SVikas Gupta 	int rc;
171fb7d8b61SVikas Gupta 
172fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_DRV_RGTR);
173fb7d8b61SVikas Gupta 	if (rc)
174fb7d8b61SVikas Gupta 		return rc;
175fb7d8b61SVikas Gupta 
176fb7d8b61SVikas Gupta 	req->enables = cpu_to_le32(FUNC_DRV_RGTR_REQ_ENABLES_OS_TYPE |
177fb7d8b61SVikas Gupta 				   FUNC_DRV_RGTR_REQ_ENABLES_VER |
178fb7d8b61SVikas Gupta 				   FUNC_DRV_RGTR_REQ_ENABLES_ASYNC_EVENT_FWD);
179fb7d8b61SVikas Gupta 
180fb7d8b61SVikas Gupta 	req->os_type = cpu_to_le16(FUNC_DRV_RGTR_REQ_OS_TYPE_LINUX);
181fb7d8b61SVikas Gupta 	flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE;
182fb7d8b61SVikas Gupta 
183fb7d8b61SVikas Gupta 	req->flags = cpu_to_le32(flags);
184fb7d8b61SVikas Gupta 	req->ver_maj_8b = DRV_VER_MAJ;
185fb7d8b61SVikas Gupta 	req->ver_min_8b = DRV_VER_MIN;
186fb7d8b61SVikas Gupta 	req->ver_upd_8b = DRV_VER_UPD;
187fb7d8b61SVikas Gupta 	req->ver_maj = cpu_to_le16(DRV_VER_MAJ);
188fb7d8b61SVikas Gupta 	req->ver_min = cpu_to_le16(DRV_VER_MIN);
189fb7d8b61SVikas Gupta 	req->ver_upd = cpu_to_le16(DRV_VER_UPD);
190fb7d8b61SVikas Gupta 
191fb7d8b61SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
192fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
193fb7d8b61SVikas Gupta 	if (!rc) {
194fb7d8b61SVikas Gupta 		set_bit(BNGE_STATE_DRV_REGISTERED, &bd->state);
195fb7d8b61SVikas Gupta 		if (resp->flags &
196fb7d8b61SVikas Gupta 		    cpu_to_le32(FUNC_DRV_RGTR_RESP_FLAGS_IF_CHANGE_SUPPORTED))
197fb7d8b61SVikas Gupta 			bd->fw_cap |= BNGE_FW_CAP_IF_CHANGE;
198fb7d8b61SVikas Gupta 	}
199fb7d8b61SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
200fb7d8b61SVikas Gupta 	return rc;
201fb7d8b61SVikas Gupta }
202fb7d8b61SVikas Gupta 
bnge_hwrm_func_drv_unrgtr(struct bnge_dev * bd)203fb7d8b61SVikas Gupta int bnge_hwrm_func_drv_unrgtr(struct bnge_dev *bd)
204fb7d8b61SVikas Gupta {
205fb7d8b61SVikas Gupta 	struct hwrm_func_drv_unrgtr_input *req;
206fb7d8b61SVikas Gupta 	int rc;
207fb7d8b61SVikas Gupta 
208fb7d8b61SVikas Gupta 	if (!test_and_clear_bit(BNGE_STATE_DRV_REGISTERED, &bd->state))
209fb7d8b61SVikas Gupta 		return 0;
210fb7d8b61SVikas Gupta 
211fb7d8b61SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_DRV_UNRGTR);
212fb7d8b61SVikas Gupta 	if (rc)
213fb7d8b61SVikas Gupta 		return rc;
214fb7d8b61SVikas Gupta 	return bnge_hwrm_req_send(bd, req);
215fb7d8b61SVikas Gupta }
21629c5b358SVikas Gupta 
bnge_init_ctx_initializer(struct bnge_ctx_mem_type * ctxm,u8 init_val,u8 init_offset,bool init_mask_set)21729c5b358SVikas Gupta static void bnge_init_ctx_initializer(struct bnge_ctx_mem_type *ctxm,
21829c5b358SVikas Gupta 				      u8 init_val, u8 init_offset,
21929c5b358SVikas Gupta 				      bool init_mask_set)
22029c5b358SVikas Gupta {
22129c5b358SVikas Gupta 	ctxm->init_value = init_val;
22229c5b358SVikas Gupta 	ctxm->init_offset = BNGE_CTX_INIT_INVALID_OFFSET;
22329c5b358SVikas Gupta 	if (init_mask_set)
22429c5b358SVikas Gupta 		ctxm->init_offset = init_offset * 4;
22529c5b358SVikas Gupta 	else
22629c5b358SVikas Gupta 		ctxm->init_value = 0;
22729c5b358SVikas Gupta }
22829c5b358SVikas Gupta 
bnge_alloc_all_ctx_pg_info(struct bnge_dev * bd,int ctx_max)22929c5b358SVikas Gupta static int bnge_alloc_all_ctx_pg_info(struct bnge_dev *bd, int ctx_max)
23029c5b358SVikas Gupta {
23129c5b358SVikas Gupta 	struct bnge_ctx_mem_info *ctx = bd->ctx;
23229c5b358SVikas Gupta 	u16 type;
23329c5b358SVikas Gupta 
23429c5b358SVikas Gupta 	for (type = 0; type < ctx_max; type++) {
23529c5b358SVikas Gupta 		struct bnge_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
23629c5b358SVikas Gupta 		int n = 1;
23729c5b358SVikas Gupta 
23829c5b358SVikas Gupta 		if (!ctxm->max_entries)
23929c5b358SVikas Gupta 			continue;
24029c5b358SVikas Gupta 
24129c5b358SVikas Gupta 		if (ctxm->instance_bmap)
24229c5b358SVikas Gupta 			n = hweight32(ctxm->instance_bmap);
24329c5b358SVikas Gupta 		ctxm->pg_info = kcalloc(n, sizeof(*ctxm->pg_info), GFP_KERNEL);
24429c5b358SVikas Gupta 		if (!ctxm->pg_info)
24529c5b358SVikas Gupta 			return -ENOMEM;
24629c5b358SVikas Gupta 	}
24729c5b358SVikas Gupta 
24829c5b358SVikas Gupta 	return 0;
24929c5b358SVikas Gupta }
25029c5b358SVikas Gupta 
25129c5b358SVikas Gupta #define BNGE_CTX_INIT_VALID(flags)	\
25229c5b358SVikas Gupta 	(!!((flags) &			\
25329c5b358SVikas Gupta 	    FUNC_BACKING_STORE_QCAPS_V2_RESP_FLAGS_ENABLE_CTX_KIND_INIT))
25429c5b358SVikas Gupta 
bnge_hwrm_func_backing_store_qcaps(struct bnge_dev * bd)25529c5b358SVikas Gupta int bnge_hwrm_func_backing_store_qcaps(struct bnge_dev *bd)
25629c5b358SVikas Gupta {
25729c5b358SVikas Gupta 	struct hwrm_func_backing_store_qcaps_v2_output *resp;
25829c5b358SVikas Gupta 	struct hwrm_func_backing_store_qcaps_v2_input *req;
25929c5b358SVikas Gupta 	struct bnge_ctx_mem_info *ctx;
26029c5b358SVikas Gupta 	u16 type;
26129c5b358SVikas Gupta 	int rc;
26229c5b358SVikas Gupta 
26329c5b358SVikas Gupta 	if (bd->ctx)
26429c5b358SVikas Gupta 		return 0;
26529c5b358SVikas Gupta 
26629c5b358SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_BACKING_STORE_QCAPS_V2);
26729c5b358SVikas Gupta 	if (rc)
26829c5b358SVikas Gupta 		return rc;
26929c5b358SVikas Gupta 
27029c5b358SVikas Gupta 	ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
27129c5b358SVikas Gupta 	if (!ctx)
27229c5b358SVikas Gupta 		return -ENOMEM;
27329c5b358SVikas Gupta 	bd->ctx = ctx;
27429c5b358SVikas Gupta 
27529c5b358SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
27629c5b358SVikas Gupta 
27729c5b358SVikas Gupta 	for (type = 0; type < BNGE_CTX_V2_MAX; ) {
27829c5b358SVikas Gupta 		struct bnge_ctx_mem_type *ctxm = &ctx->ctx_arr[type];
27929c5b358SVikas Gupta 		u8 init_val, init_off, i;
28029c5b358SVikas Gupta 		__le32 *p;
28129c5b358SVikas Gupta 		u32 flags;
28229c5b358SVikas Gupta 
28329c5b358SVikas Gupta 		req->type = cpu_to_le16(type);
28429c5b358SVikas Gupta 		rc = bnge_hwrm_req_send(bd, req);
28529c5b358SVikas Gupta 		if (rc)
28629c5b358SVikas Gupta 			goto ctx_done;
28729c5b358SVikas Gupta 		flags = le32_to_cpu(resp->flags);
28829c5b358SVikas Gupta 		type = le16_to_cpu(resp->next_valid_type);
28929c5b358SVikas Gupta 		if (!(flags &
29029c5b358SVikas Gupta 		      FUNC_BACKING_STORE_QCAPS_V2_RESP_FLAGS_TYPE_VALID))
29129c5b358SVikas Gupta 			continue;
29229c5b358SVikas Gupta 
29329c5b358SVikas Gupta 		ctxm->type = le16_to_cpu(resp->type);
29429c5b358SVikas Gupta 		ctxm->entry_size = le16_to_cpu(resp->entry_size);
29529c5b358SVikas Gupta 		ctxm->flags = flags;
29629c5b358SVikas Gupta 		ctxm->instance_bmap = le32_to_cpu(resp->instance_bit_map);
29729c5b358SVikas Gupta 		ctxm->entry_multiple = resp->entry_multiple;
29829c5b358SVikas Gupta 		ctxm->max_entries = le32_to_cpu(resp->max_num_entries);
29929c5b358SVikas Gupta 		ctxm->min_entries = le32_to_cpu(resp->min_num_entries);
30029c5b358SVikas Gupta 		init_val = resp->ctx_init_value;
30129c5b358SVikas Gupta 		init_off = resp->ctx_init_offset;
30229c5b358SVikas Gupta 		bnge_init_ctx_initializer(ctxm, init_val, init_off,
30329c5b358SVikas Gupta 					  BNGE_CTX_INIT_VALID(flags));
30429c5b358SVikas Gupta 		ctxm->split_entry_cnt = min_t(u8, resp->subtype_valid_cnt,
30529c5b358SVikas Gupta 					      BNGE_MAX_SPLIT_ENTRY);
30629c5b358SVikas Gupta 		for (i = 0, p = &resp->split_entry_0; i < ctxm->split_entry_cnt;
30729c5b358SVikas Gupta 		     i++, p++)
30829c5b358SVikas Gupta 			ctxm->split[i] = le32_to_cpu(*p);
30929c5b358SVikas Gupta 	}
31029c5b358SVikas Gupta 	rc = bnge_alloc_all_ctx_pg_info(bd, BNGE_CTX_V2_MAX);
31129c5b358SVikas Gupta 
31229c5b358SVikas Gupta ctx_done:
31329c5b358SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
31429c5b358SVikas Gupta 	return rc;
31529c5b358SVikas Gupta }
31629c5b358SVikas Gupta 
bnge_hwrm_set_pg_attr(struct bnge_ring_mem_info * rmem,u8 * pg_attr,__le64 * pg_dir)31729c5b358SVikas Gupta static void bnge_hwrm_set_pg_attr(struct bnge_ring_mem_info *rmem, u8 *pg_attr,
31829c5b358SVikas Gupta 				  __le64 *pg_dir)
31929c5b358SVikas Gupta {
32029c5b358SVikas Gupta 	if (!rmem->nr_pages)
32129c5b358SVikas Gupta 		return;
32229c5b358SVikas Gupta 
32329c5b358SVikas Gupta 	BNGE_SET_CTX_PAGE_ATTR(*pg_attr);
32429c5b358SVikas Gupta 	if (rmem->depth >= 1) {
32529c5b358SVikas Gupta 		if (rmem->depth == 2)
32629c5b358SVikas Gupta 			*pg_attr |= 2;
32729c5b358SVikas Gupta 		else
32829c5b358SVikas Gupta 			*pg_attr |= 1;
32929c5b358SVikas Gupta 		*pg_dir = cpu_to_le64(rmem->dma_pg_tbl);
33029c5b358SVikas Gupta 	} else {
33129c5b358SVikas Gupta 		*pg_dir = cpu_to_le64(rmem->dma_arr[0]);
33229c5b358SVikas Gupta 	}
33329c5b358SVikas Gupta }
33429c5b358SVikas Gupta 
bnge_hwrm_func_backing_store(struct bnge_dev * bd,struct bnge_ctx_mem_type * ctxm,bool last)33529c5b358SVikas Gupta int bnge_hwrm_func_backing_store(struct bnge_dev *bd,
33629c5b358SVikas Gupta 				 struct bnge_ctx_mem_type *ctxm,
33729c5b358SVikas Gupta 				 bool last)
33829c5b358SVikas Gupta {
33929c5b358SVikas Gupta 	struct hwrm_func_backing_store_cfg_v2_input *req;
34029c5b358SVikas Gupta 	u32 instance_bmap = ctxm->instance_bmap;
34129c5b358SVikas Gupta 	int i, j, rc = 0, n = 1;
34229c5b358SVikas Gupta 	__le32 *p;
34329c5b358SVikas Gupta 
34429c5b358SVikas Gupta 	if (!(ctxm->flags & BNGE_CTX_MEM_TYPE_VALID) || !ctxm->pg_info)
34529c5b358SVikas Gupta 		return 0;
34629c5b358SVikas Gupta 
34729c5b358SVikas Gupta 	if (instance_bmap)
34829c5b358SVikas Gupta 		n = hweight32(ctxm->instance_bmap);
34929c5b358SVikas Gupta 	else
35029c5b358SVikas Gupta 		instance_bmap = 1;
35129c5b358SVikas Gupta 
35229c5b358SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_BACKING_STORE_CFG_V2);
35329c5b358SVikas Gupta 	if (rc)
35429c5b358SVikas Gupta 		return rc;
35529c5b358SVikas Gupta 	bnge_hwrm_req_hold(bd, req);
35629c5b358SVikas Gupta 	req->type = cpu_to_le16(ctxm->type);
35729c5b358SVikas Gupta 	req->entry_size = cpu_to_le16(ctxm->entry_size);
35829c5b358SVikas Gupta 	req->subtype_valid_cnt = ctxm->split_entry_cnt;
35929c5b358SVikas Gupta 	for (i = 0, p = &req->split_entry_0; i < ctxm->split_entry_cnt; i++)
36029c5b358SVikas Gupta 		p[i] = cpu_to_le32(ctxm->split[i]);
36129c5b358SVikas Gupta 	for (i = 0, j = 0; j < n && !rc; i++) {
36229c5b358SVikas Gupta 		struct bnge_ctx_pg_info *ctx_pg;
36329c5b358SVikas Gupta 
36429c5b358SVikas Gupta 		if (!(instance_bmap & (1 << i)))
36529c5b358SVikas Gupta 			continue;
36629c5b358SVikas Gupta 		req->instance = cpu_to_le16(i);
36729c5b358SVikas Gupta 		ctx_pg = &ctxm->pg_info[j++];
36829c5b358SVikas Gupta 		if (!ctx_pg->entries)
36929c5b358SVikas Gupta 			continue;
37029c5b358SVikas Gupta 		req->num_entries = cpu_to_le32(ctx_pg->entries);
37129c5b358SVikas Gupta 		bnge_hwrm_set_pg_attr(&ctx_pg->ring_mem,
37229c5b358SVikas Gupta 				      &req->page_size_pbl_level,
37329c5b358SVikas Gupta 				      &req->page_dir);
37429c5b358SVikas Gupta 		if (last && j == n)
37529c5b358SVikas Gupta 			req->flags =
37629c5b358SVikas Gupta 				cpu_to_le32(BNGE_BS_CFG_ALL_DONE);
37729c5b358SVikas Gupta 		rc = bnge_hwrm_req_send(bd, req);
37829c5b358SVikas Gupta 	}
37929c5b358SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
38029c5b358SVikas Gupta 
38129c5b358SVikas Gupta 	return rc;
38229c5b358SVikas Gupta }
383627c67f0SVikas Gupta 
bnge_hwrm_get_rings(struct bnge_dev * bd)384627c67f0SVikas Gupta static int bnge_hwrm_get_rings(struct bnge_dev *bd)
385627c67f0SVikas Gupta {
386627c67f0SVikas Gupta 	struct bnge_hw_resc *hw_resc = &bd->hw_resc;
387627c67f0SVikas Gupta 	struct hwrm_func_qcfg_output *resp;
388627c67f0SVikas Gupta 	struct hwrm_func_qcfg_input *req;
389627c67f0SVikas Gupta 	u16 cp, stats;
390627c67f0SVikas Gupta 	u16 rx, tx;
391627c67f0SVikas Gupta 	int rc;
392627c67f0SVikas Gupta 
393627c67f0SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG);
394627c67f0SVikas Gupta 	if (rc)
395627c67f0SVikas Gupta 		return rc;
396627c67f0SVikas Gupta 
397627c67f0SVikas Gupta 	req->fid = cpu_to_le16(0xffff);
398627c67f0SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
399627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
400627c67f0SVikas Gupta 	if (rc) {
401627c67f0SVikas Gupta 		bnge_hwrm_req_drop(bd, req);
402627c67f0SVikas Gupta 		return rc;
403627c67f0SVikas Gupta 	}
404627c67f0SVikas Gupta 
405627c67f0SVikas Gupta 	hw_resc->resv_tx_rings = le16_to_cpu(resp->alloc_tx_rings);
406627c67f0SVikas Gupta 	hw_resc->resv_rx_rings = le16_to_cpu(resp->alloc_rx_rings);
407627c67f0SVikas Gupta 	hw_resc->resv_hw_ring_grps =
408627c67f0SVikas Gupta 		le32_to_cpu(resp->alloc_hw_ring_grps);
409627c67f0SVikas Gupta 	hw_resc->resv_vnics = le16_to_cpu(resp->alloc_vnics);
410627c67f0SVikas Gupta 	hw_resc->resv_rsscos_ctxs = le16_to_cpu(resp->alloc_rsscos_ctx);
411627c67f0SVikas Gupta 	cp = le16_to_cpu(resp->alloc_cmpl_rings);
412627c67f0SVikas Gupta 	stats = le16_to_cpu(resp->alloc_stat_ctx);
413627c67f0SVikas Gupta 	hw_resc->resv_irqs = cp;
414627c67f0SVikas Gupta 	rx = hw_resc->resv_rx_rings;
415627c67f0SVikas Gupta 	tx = hw_resc->resv_tx_rings;
416627c67f0SVikas Gupta 	if (bnge_is_agg_reqd(bd))
417627c67f0SVikas Gupta 		rx >>= 1;
418627c67f0SVikas Gupta 	if (cp < (rx + tx)) {
419627c67f0SVikas Gupta 		rc = bnge_fix_rings_count(&rx, &tx, cp, false);
420627c67f0SVikas Gupta 		if (rc)
421627c67f0SVikas Gupta 			goto get_rings_exit;
422627c67f0SVikas Gupta 		if (bnge_is_agg_reqd(bd))
423627c67f0SVikas Gupta 			rx <<= 1;
424627c67f0SVikas Gupta 		hw_resc->resv_rx_rings = rx;
425627c67f0SVikas Gupta 		hw_resc->resv_tx_rings = tx;
426627c67f0SVikas Gupta 	}
427627c67f0SVikas Gupta 	hw_resc->resv_irqs = le16_to_cpu(resp->alloc_msix);
428627c67f0SVikas Gupta 	hw_resc->resv_hw_ring_grps = rx;
429627c67f0SVikas Gupta 	hw_resc->resv_cp_rings = cp;
430627c67f0SVikas Gupta 	hw_resc->resv_stat_ctxs = stats;
431627c67f0SVikas Gupta 
432627c67f0SVikas Gupta get_rings_exit:
433627c67f0SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
434627c67f0SVikas Gupta 	return rc;
435627c67f0SVikas Gupta }
436627c67f0SVikas Gupta 
437627c67f0SVikas Gupta static struct hwrm_func_cfg_input *
__bnge_hwrm_reserve_pf_rings(struct bnge_dev * bd,struct bnge_hw_rings * hwr)438627c67f0SVikas Gupta __bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr)
439627c67f0SVikas Gupta {
440627c67f0SVikas Gupta 	struct hwrm_func_cfg_input *req;
441627c67f0SVikas Gupta 	u32 enables = 0;
442627c67f0SVikas Gupta 
443627c67f0SVikas Gupta 	if (bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG))
444627c67f0SVikas Gupta 		return NULL;
445627c67f0SVikas Gupta 
446627c67f0SVikas Gupta 	req->fid = cpu_to_le16(0xffff);
447627c67f0SVikas Gupta 	enables |= hwr->tx ? FUNC_CFG_REQ_ENABLES_NUM_TX_RINGS : 0;
448627c67f0SVikas Gupta 	req->num_tx_rings = cpu_to_le16(hwr->tx);
449627c67f0SVikas Gupta 
450627c67f0SVikas Gupta 	enables |= hwr->rx ? FUNC_CFG_REQ_ENABLES_NUM_RX_RINGS : 0;
451627c67f0SVikas Gupta 	enables |= hwr->stat ? FUNC_CFG_REQ_ENABLES_NUM_STAT_CTXS : 0;
452627c67f0SVikas Gupta 	enables |= hwr->nq ? FUNC_CFG_REQ_ENABLES_NUM_MSIX : 0;
453627c67f0SVikas Gupta 	enables |= hwr->cmpl ? FUNC_CFG_REQ_ENABLES_NUM_CMPL_RINGS : 0;
454627c67f0SVikas Gupta 	enables |= hwr->vnic ? FUNC_CFG_REQ_ENABLES_NUM_VNICS : 0;
455627c67f0SVikas Gupta 	enables |= hwr->rss_ctx ? FUNC_CFG_REQ_ENABLES_NUM_RSSCOS_CTXS : 0;
456627c67f0SVikas Gupta 
457627c67f0SVikas Gupta 	req->num_rx_rings = cpu_to_le16(hwr->rx);
458627c67f0SVikas Gupta 	req->num_rsscos_ctxs = cpu_to_le16(hwr->rss_ctx);
459627c67f0SVikas Gupta 	req->num_cmpl_rings = cpu_to_le16(hwr->cmpl);
460627c67f0SVikas Gupta 	req->num_msix = cpu_to_le16(hwr->nq);
461627c67f0SVikas Gupta 	req->num_stat_ctxs = cpu_to_le16(hwr->stat);
462627c67f0SVikas Gupta 	req->num_vnics = cpu_to_le16(hwr->vnic);
463627c67f0SVikas Gupta 	req->enables = cpu_to_le32(enables);
464627c67f0SVikas Gupta 
465627c67f0SVikas Gupta 	return req;
466627c67f0SVikas Gupta }
467627c67f0SVikas Gupta 
468627c67f0SVikas Gupta static int
bnge_hwrm_reserve_pf_rings(struct bnge_dev * bd,struct bnge_hw_rings * hwr)469627c67f0SVikas Gupta bnge_hwrm_reserve_pf_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr)
470627c67f0SVikas Gupta {
471627c67f0SVikas Gupta 	struct hwrm_func_cfg_input *req;
472627c67f0SVikas Gupta 	int rc;
473627c67f0SVikas Gupta 
474627c67f0SVikas Gupta 	req = __bnge_hwrm_reserve_pf_rings(bd, hwr);
475627c67f0SVikas Gupta 	if (!req)
476627c67f0SVikas Gupta 		return -ENOMEM;
477627c67f0SVikas Gupta 
478627c67f0SVikas Gupta 	if (!req->enables) {
479627c67f0SVikas Gupta 		bnge_hwrm_req_drop(bd, req);
480627c67f0SVikas Gupta 		return 0;
481627c67f0SVikas Gupta 	}
482627c67f0SVikas Gupta 
483627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
484627c67f0SVikas Gupta 	if (rc)
485627c67f0SVikas Gupta 		return rc;
486627c67f0SVikas Gupta 
487627c67f0SVikas Gupta 	return bnge_hwrm_get_rings(bd);
488627c67f0SVikas Gupta }
489627c67f0SVikas Gupta 
bnge_hwrm_reserve_rings(struct bnge_dev * bd,struct bnge_hw_rings * hwr)490627c67f0SVikas Gupta int bnge_hwrm_reserve_rings(struct bnge_dev *bd, struct bnge_hw_rings *hwr)
491627c67f0SVikas Gupta {
492627c67f0SVikas Gupta 	return bnge_hwrm_reserve_pf_rings(bd, hwr);
493627c67f0SVikas Gupta }
494627c67f0SVikas Gupta 
bnge_hwrm_func_qcfg(struct bnge_dev * bd)495627c67f0SVikas Gupta int bnge_hwrm_func_qcfg(struct bnge_dev *bd)
496627c67f0SVikas Gupta {
497627c67f0SVikas Gupta 	struct hwrm_func_qcfg_output *resp;
498627c67f0SVikas Gupta 	struct hwrm_func_qcfg_input *req;
499627c67f0SVikas Gupta 	int rc;
500627c67f0SVikas Gupta 
501627c67f0SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCFG);
502627c67f0SVikas Gupta 	if (rc)
503627c67f0SVikas Gupta 		return rc;
504627c67f0SVikas Gupta 
505627c67f0SVikas Gupta 	req->fid = cpu_to_le16(0xffff);
506627c67f0SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
507627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
508627c67f0SVikas Gupta 	if (rc)
509627c67f0SVikas Gupta 		goto func_qcfg_exit;
510627c67f0SVikas Gupta 
511627c67f0SVikas Gupta 	bd->max_mtu = le16_to_cpu(resp->max_mtu_configured);
512627c67f0SVikas Gupta 	if (!bd->max_mtu)
513627c67f0SVikas Gupta 		bd->max_mtu = BNGE_MAX_MTU;
514627c67f0SVikas Gupta 
515627c67f0SVikas Gupta 	if (bd->db_size)
516627c67f0SVikas Gupta 		goto func_qcfg_exit;
517627c67f0SVikas Gupta 
518627c67f0SVikas Gupta 	bd->db_offset = le16_to_cpu(resp->legacy_l2_db_size_kb) * 1024;
519627c67f0SVikas Gupta 	bd->db_size = PAGE_ALIGN(le16_to_cpu(resp->l2_doorbell_bar_size_kb) *
520627c67f0SVikas Gupta 			1024);
521627c67f0SVikas Gupta 	if (!bd->db_size || bd->db_size > pci_resource_len(bd->pdev, 2) ||
522627c67f0SVikas Gupta 	    bd->db_size <= bd->db_offset)
523627c67f0SVikas Gupta 		bd->db_size = pci_resource_len(bd->pdev, 2);
524627c67f0SVikas Gupta 
525627c67f0SVikas Gupta func_qcfg_exit:
526627c67f0SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
527627c67f0SVikas Gupta 	return rc;
528627c67f0SVikas Gupta }
529627c67f0SVikas Gupta 
bnge_hwrm_func_resc_qcaps(struct bnge_dev * bd)530627c67f0SVikas Gupta int bnge_hwrm_func_resc_qcaps(struct bnge_dev *bd)
531627c67f0SVikas Gupta {
532627c67f0SVikas Gupta 	struct hwrm_func_resource_qcaps_output *resp;
533627c67f0SVikas Gupta 	struct bnge_hw_resc *hw_resc = &bd->hw_resc;
534627c67f0SVikas Gupta 	struct hwrm_func_resource_qcaps_input *req;
535627c67f0SVikas Gupta 	int rc;
536627c67f0SVikas Gupta 
537627c67f0SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_RESOURCE_QCAPS);
538627c67f0SVikas Gupta 	if (rc)
539627c67f0SVikas Gupta 		return rc;
540627c67f0SVikas Gupta 
541627c67f0SVikas Gupta 	req->fid = cpu_to_le16(0xffff);
542627c67f0SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
543627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send_silent(bd, req);
544627c67f0SVikas Gupta 	if (rc)
545627c67f0SVikas Gupta 		goto hwrm_func_resc_qcaps_exit;
546627c67f0SVikas Gupta 
547627c67f0SVikas Gupta 	hw_resc->max_tx_sch_inputs = le16_to_cpu(resp->max_tx_scheduler_inputs);
548627c67f0SVikas Gupta 	hw_resc->min_rsscos_ctxs = le16_to_cpu(resp->min_rsscos_ctx);
549627c67f0SVikas Gupta 	hw_resc->max_rsscos_ctxs = le16_to_cpu(resp->max_rsscos_ctx);
550627c67f0SVikas Gupta 	hw_resc->min_cp_rings = le16_to_cpu(resp->min_cmpl_rings);
551627c67f0SVikas Gupta 	hw_resc->max_cp_rings = le16_to_cpu(resp->max_cmpl_rings);
552627c67f0SVikas Gupta 	hw_resc->min_tx_rings = le16_to_cpu(resp->min_tx_rings);
553627c67f0SVikas Gupta 	hw_resc->max_tx_rings = le16_to_cpu(resp->max_tx_rings);
554627c67f0SVikas Gupta 	hw_resc->min_rx_rings = le16_to_cpu(resp->min_rx_rings);
555627c67f0SVikas Gupta 	hw_resc->max_rx_rings = le16_to_cpu(resp->max_rx_rings);
556627c67f0SVikas Gupta 	hw_resc->min_hw_ring_grps = le16_to_cpu(resp->min_hw_ring_grps);
557627c67f0SVikas Gupta 	hw_resc->max_hw_ring_grps = le16_to_cpu(resp->max_hw_ring_grps);
558627c67f0SVikas Gupta 	hw_resc->min_l2_ctxs = le16_to_cpu(resp->min_l2_ctxs);
559627c67f0SVikas Gupta 	hw_resc->max_l2_ctxs = le16_to_cpu(resp->max_l2_ctxs);
560627c67f0SVikas Gupta 	hw_resc->min_vnics = le16_to_cpu(resp->min_vnics);
561627c67f0SVikas Gupta 	hw_resc->max_vnics = le16_to_cpu(resp->max_vnics);
562627c67f0SVikas Gupta 	hw_resc->min_stat_ctxs = le16_to_cpu(resp->min_stat_ctx);
563627c67f0SVikas Gupta 	hw_resc->max_stat_ctxs = le16_to_cpu(resp->max_stat_ctx);
564627c67f0SVikas Gupta 
565627c67f0SVikas Gupta 	hw_resc->max_nqs = le16_to_cpu(resp->max_msix);
566627c67f0SVikas Gupta 	hw_resc->max_hw_ring_grps = hw_resc->max_rx_rings;
567627c67f0SVikas Gupta 
568627c67f0SVikas Gupta hwrm_func_resc_qcaps_exit:
569627c67f0SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
570627c67f0SVikas Gupta 	return rc;
571627c67f0SVikas Gupta }
572627c67f0SVikas Gupta 
bnge_hwrm_func_qcaps(struct bnge_dev * bd)573627c67f0SVikas Gupta int bnge_hwrm_func_qcaps(struct bnge_dev *bd)
574627c67f0SVikas Gupta {
575627c67f0SVikas Gupta 	struct hwrm_func_qcaps_output *resp;
576627c67f0SVikas Gupta 	struct hwrm_func_qcaps_input *req;
577627c67f0SVikas Gupta 	struct bnge_pf_info *pf = &bd->pf;
578627c67f0SVikas Gupta 	u32 flags;
579627c67f0SVikas Gupta 	int rc;
580627c67f0SVikas Gupta 
581627c67f0SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_FUNC_QCAPS);
582627c67f0SVikas Gupta 	if (rc)
583627c67f0SVikas Gupta 		return rc;
584627c67f0SVikas Gupta 
585627c67f0SVikas Gupta 	req->fid = cpu_to_le16(0xffff);
586627c67f0SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
587627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
588627c67f0SVikas Gupta 	if (rc)
589627c67f0SVikas Gupta 		goto hwrm_func_qcaps_exit;
590627c67f0SVikas Gupta 
591627c67f0SVikas Gupta 	flags = le32_to_cpu(resp->flags);
592627c67f0SVikas Gupta 	if (flags & FUNC_QCAPS_RESP_FLAGS_ROCE_V1_SUPPORTED)
593627c67f0SVikas Gupta 		bd->flags |= BNGE_EN_ROCE_V1;
594627c67f0SVikas Gupta 	if (flags & FUNC_QCAPS_RESP_FLAGS_ROCE_V2_SUPPORTED)
595627c67f0SVikas Gupta 		bd->flags |= BNGE_EN_ROCE_V2;
596627c67f0SVikas Gupta 
597627c67f0SVikas Gupta 	pf->fw_fid = le16_to_cpu(resp->fid);
598627c67f0SVikas Gupta 	pf->port_id = le16_to_cpu(resp->port_id);
599627c67f0SVikas Gupta 	memcpy(pf->mac_addr, resp->mac_address, ETH_ALEN);
600627c67f0SVikas Gupta 
601627c67f0SVikas Gupta 	bd->tso_max_segs = le16_to_cpu(resp->max_tso_segs);
602627c67f0SVikas Gupta 
603627c67f0SVikas Gupta hwrm_func_qcaps_exit:
604627c67f0SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
605627c67f0SVikas Gupta 	return rc;
606627c67f0SVikas Gupta }
607627c67f0SVikas Gupta 
bnge_hwrm_vnic_qcaps(struct bnge_dev * bd)608627c67f0SVikas Gupta int bnge_hwrm_vnic_qcaps(struct bnge_dev *bd)
609627c67f0SVikas Gupta {
610627c67f0SVikas Gupta 	struct hwrm_vnic_qcaps_output *resp;
611627c67f0SVikas Gupta 	struct hwrm_vnic_qcaps_input *req;
612627c67f0SVikas Gupta 	int rc;
613627c67f0SVikas Gupta 
614627c67f0SVikas Gupta 	bd->hw_ring_stats_size = sizeof(struct ctx_hw_stats);
615627c67f0SVikas Gupta 	bd->rss_cap &= ~BNGE_RSS_CAP_NEW_RSS_CAP;
616627c67f0SVikas Gupta 
617627c67f0SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_VNIC_QCAPS);
618627c67f0SVikas Gupta 	if (rc)
619627c67f0SVikas Gupta 		return rc;
620627c67f0SVikas Gupta 
621627c67f0SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
622627c67f0SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
623627c67f0SVikas Gupta 	if (!rc) {
624627c67f0SVikas Gupta 		u32 flags = le32_to_cpu(resp->flags);
625627c67f0SVikas Gupta 
626627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_VLAN_STRIP_CAP)
627627c67f0SVikas Gupta 			bd->fw_cap |= BNGE_FW_CAP_VLAN_RX_STRIP;
628627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_HASH_TYPE_DELTA_CAP)
629627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_RSS_HASH_TYPE_DELTA;
630627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_PROF_TCAM_MODE_ENABLED)
631627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_RSS_TCAM;
632627c67f0SVikas Gupta 		bd->max_tpa_v2 = le16_to_cpu(resp->max_aggs_supported);
633627c67f0SVikas Gupta 		if (bd->max_tpa_v2)
634627c67f0SVikas Gupta 			bd->hw_ring_stats_size = BNGE_RING_STATS_SIZE;
635627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_HW_TUNNEL_TPA_CAP)
636627c67f0SVikas Gupta 			bd->fw_cap |= BNGE_FW_CAP_VNIC_TUNNEL_TPA;
637627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_AH_SPI_IPV4_CAP)
638627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_AH_V4_RSS_CAP;
639627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_AH_SPI_IPV6_CAP)
640627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_AH_V6_RSS_CAP;
641627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_ESP_SPI_IPV4_CAP)
642627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_ESP_V4_RSS_CAP;
643627c67f0SVikas Gupta 		if (flags & VNIC_QCAPS_RESP_FLAGS_RSS_IPSEC_ESP_SPI_IPV6_CAP)
644627c67f0SVikas Gupta 			bd->rss_cap |= BNGE_RSS_CAP_ESP_V6_RSS_CAP;
645627c67f0SVikas Gupta 	}
646627c67f0SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
647627c67f0SVikas Gupta 
648627c67f0SVikas Gupta 	return rc;
649627c67f0SVikas Gupta }
6503fa9e977SVikas Gupta 
6513fa9e977SVikas Gupta #define BNGE_CNPQ(q_profile)	\
6523fa9e977SVikas Gupta 		((q_profile) ==	\
6533fa9e977SVikas Gupta 		 QUEUE_QPORTCFG_RESP_QUEUE_ID0_SERVICE_PROFILE_LOSSY_ROCE_CNP)
6543fa9e977SVikas Gupta 
bnge_hwrm_queue_qportcfg(struct bnge_dev * bd)6553fa9e977SVikas Gupta int bnge_hwrm_queue_qportcfg(struct bnge_dev *bd)
6563fa9e977SVikas Gupta {
6573fa9e977SVikas Gupta 	struct hwrm_queue_qportcfg_output *resp;
6583fa9e977SVikas Gupta 	struct hwrm_queue_qportcfg_input *req;
6593fa9e977SVikas Gupta 	u8 i, j, *qptr;
6603fa9e977SVikas Gupta 	bool no_rdma;
6613fa9e977SVikas Gupta 	int rc;
6623fa9e977SVikas Gupta 
6633fa9e977SVikas Gupta 	rc = bnge_hwrm_req_init(bd, req, HWRM_QUEUE_QPORTCFG);
6643fa9e977SVikas Gupta 	if (rc)
6653fa9e977SVikas Gupta 		return rc;
6663fa9e977SVikas Gupta 
6673fa9e977SVikas Gupta 	resp = bnge_hwrm_req_hold(bd, req);
6683fa9e977SVikas Gupta 	rc = bnge_hwrm_req_send(bd, req);
6693fa9e977SVikas Gupta 	if (rc)
6703fa9e977SVikas Gupta 		goto qportcfg_exit;
6713fa9e977SVikas Gupta 
6723fa9e977SVikas Gupta 	if (!resp->max_configurable_queues) {
6733fa9e977SVikas Gupta 		rc = -EINVAL;
6743fa9e977SVikas Gupta 		goto qportcfg_exit;
6753fa9e977SVikas Gupta 	}
6763fa9e977SVikas Gupta 	bd->max_tc = resp->max_configurable_queues;
6773fa9e977SVikas Gupta 	bd->max_lltc = resp->max_configurable_lossless_queues;
6783fa9e977SVikas Gupta 	if (bd->max_tc > BNGE_MAX_QUEUE)
6793fa9e977SVikas Gupta 		bd->max_tc = BNGE_MAX_QUEUE;
6803fa9e977SVikas Gupta 
6813fa9e977SVikas Gupta 	no_rdma = !bnge_is_roce_en(bd);
6823fa9e977SVikas Gupta 	qptr = &resp->queue_id0;
6833fa9e977SVikas Gupta 	for (i = 0, j = 0; i < bd->max_tc; i++) {
6843fa9e977SVikas Gupta 		bd->q_info[j].queue_id = *qptr;
6853fa9e977SVikas Gupta 		bd->q_ids[i] = *qptr++;
6863fa9e977SVikas Gupta 		bd->q_info[j].queue_profile = *qptr++;
6873fa9e977SVikas Gupta 		bd->tc_to_qidx[j] = j;
6883fa9e977SVikas Gupta 		if (!BNGE_CNPQ(bd->q_info[j].queue_profile) || no_rdma)
6893fa9e977SVikas Gupta 			j++;
6903fa9e977SVikas Gupta 	}
6913fa9e977SVikas Gupta 	bd->max_q = bd->max_tc;
6923fa9e977SVikas Gupta 	bd->max_tc = max_t(u8, j, 1);
6933fa9e977SVikas Gupta 
6943fa9e977SVikas Gupta 	if (resp->queue_cfg_info & QUEUE_QPORTCFG_RESP_QUEUE_CFG_INFO_ASYM_CFG)
6953fa9e977SVikas Gupta 		bd->max_tc = 1;
6963fa9e977SVikas Gupta 
6973fa9e977SVikas Gupta 	if (bd->max_lltc > bd->max_tc)
6983fa9e977SVikas Gupta 		bd->max_lltc = bd->max_tc;
6993fa9e977SVikas Gupta 
7003fa9e977SVikas Gupta qportcfg_exit:
7013fa9e977SVikas Gupta 	bnge_hwrm_req_drop(bd, req);
7023fa9e977SVikas Gupta 	return rc;
7033fa9e977SVikas Gupta }
704