xref: /dpdk/drivers/net/qede/base/ecore_vf.c (revision 2ccebadab2f1e7fa867c708cc1487986ac3be122)
13126df22SRasesh Mody /* SPDX-License-Identifier: BSD-3-Clause
29adde217SRasesh Mody  * Copyright (c) 2016 - 2018 Cavium Inc.
386a2265eSRasesh Mody  * All rights reserved.
49adde217SRasesh Mody  * www.cavium.com
586a2265eSRasesh Mody  */
686a2265eSRasesh Mody 
786a2265eSRasesh Mody #include "bcm_osal.h"
886a2265eSRasesh Mody #include "ecore.h"
986a2265eSRasesh Mody #include "ecore_hsi_eth.h"
1086a2265eSRasesh Mody #include "ecore_sriov.h"
1186a2265eSRasesh Mody #include "ecore_l2_api.h"
1286a2265eSRasesh Mody #include "ecore_vf.h"
1386a2265eSRasesh Mody #include "ecore_vfpf_if.h"
1486a2265eSRasesh Mody #include "ecore_status.h"
1586a2265eSRasesh Mody #include "reg_addr.h"
1686a2265eSRasesh Mody #include "ecore_int.h"
1786a2265eSRasesh Mody #include "ecore_l2.h"
1886a2265eSRasesh Mody #include "ecore_mcp_api.h"
1986a2265eSRasesh Mody #include "ecore_vf_api.h"
2086a2265eSRasesh Mody 
ecore_vf_pf_prep(struct ecore_hwfn * p_hwfn,u16 type,u16 length)2186a2265eSRasesh Mody static void *ecore_vf_pf_prep(struct ecore_hwfn *p_hwfn, u16 type, u16 length)
2286a2265eSRasesh Mody {
2386a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
2486a2265eSRasesh Mody 	void *p_tlv;
2586a2265eSRasesh Mody 
2686a2265eSRasesh Mody 	/* This lock is released when we receive PF's response
2786a2265eSRasesh Mody 	 * in ecore_send_msg2pf().
2886a2265eSRasesh Mody 	 * So, ecore_vf_pf_prep() and ecore_send_msg2pf()
2986a2265eSRasesh Mody 	 * must come in sequence.
3086a2265eSRasesh Mody 	 */
3186a2265eSRasesh Mody 	OSAL_MUTEX_ACQUIRE(&p_iov->mutex);
3286a2265eSRasesh Mody 
3386a2265eSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
3486a2265eSRasesh Mody 		   "preparing to send %s tlv over vf pf channel\n",
35520dd992SFerruh Yigit 		   qede_ecore_channel_tlvs_string[type]);
3686a2265eSRasesh Mody 
3786a2265eSRasesh Mody 	/* Reset Request offset */
3886a2265eSRasesh Mody 	p_iov->offset = (u8 *)(p_iov->vf2pf_request);
3986a2265eSRasesh Mody 
4086a2265eSRasesh Mody 	/* Clear mailbox - both request and reply */
4186a2265eSRasesh Mody 	OSAL_MEMSET(p_iov->vf2pf_request, 0, sizeof(union vfpf_tlvs));
4286a2265eSRasesh Mody 	OSAL_MEMSET(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs));
4386a2265eSRasesh Mody 
4486a2265eSRasesh Mody 	/* Init type and length */
4530ecf673SRasesh Mody 	p_tlv = ecore_add_tlv(&p_iov->offset, type, length);
4686a2265eSRasesh Mody 
4786a2265eSRasesh Mody 	/* Init first tlv header */
4886a2265eSRasesh Mody 	((struct vfpf_first_tlv *)p_tlv)->reply_address =
4986a2265eSRasesh Mody 	    (u64)p_iov->pf2vf_reply_phys;
5086a2265eSRasesh Mody 
5186a2265eSRasesh Mody 	return p_tlv;
5286a2265eSRasesh Mody }
5386a2265eSRasesh Mody 
ecore_vf_pf_req_end(struct ecore_hwfn * p_hwfn,enum _ecore_status_t req_status)5422d07d93SRasesh Mody static void ecore_vf_pf_req_end(struct ecore_hwfn *p_hwfn,
5522d07d93SRasesh Mody 				 enum _ecore_status_t req_status)
5622d07d93SRasesh Mody {
5722d07d93SRasesh Mody 	union pfvf_tlvs *resp = p_hwfn->vf_iov_info->pf2vf_reply;
5822d07d93SRasesh Mody 
5922d07d93SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
6022d07d93SRasesh Mody 		   "VF request status = 0x%x, PF reply status = 0x%x\n",
6122d07d93SRasesh Mody 		   req_status, resp->default_resp.hdr.status);
6222d07d93SRasesh Mody 
6322d07d93SRasesh Mody 	OSAL_MUTEX_RELEASE(&p_hwfn->vf_iov_info->mutex);
6422d07d93SRasesh Mody }
6522d07d93SRasesh Mody 
66aa96bcbdSRasesh Mody #ifdef CONFIG_ECORE_SW_CHANNEL
67aa96bcbdSRasesh Mody /* The SW channel implementation of Windows needs to know the 'exact'
68aa96bcbdSRasesh Mody  * response size of any given message. That means that for future
69aa96bcbdSRasesh Mody  * messages we'd be unable to send TLVs to PF if he'll be unable to
70aa96bcbdSRasesh Mody  * answer them if the |response| != |default response|.
71aa96bcbdSRasesh Mody  * We'd need to handshake in acquire capabilities for any such.
72aa96bcbdSRasesh Mody  */
73aa96bcbdSRasesh Mody #endif
7493fce904SRasesh Mody static enum _ecore_status_t
ecore_send_msg2pf(struct ecore_hwfn * p_hwfn,u8 * done,__rte_unused u32 resp_size)7593fce904SRasesh Mody ecore_send_msg2pf(struct ecore_hwfn *p_hwfn,
76*2ccebadaSConor Walsh 		  u8 *done, __rte_unused u32 resp_size)
7786a2265eSRasesh Mody {
7886a2265eSRasesh Mody 	union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request;
7986a2265eSRasesh Mody 	struct ustorm_trigger_vf_zone trigger;
8022d07d93SRasesh Mody 	struct ustorm_vf_zone *zone_data;
8193fce904SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
8293fce904SRasesh Mody 	int time = 100;
8322d07d93SRasesh Mody 
8422d07d93SRasesh Mody 	zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B;
8586a2265eSRasesh Mody 
8686a2265eSRasesh Mody 	/* output tlvs list */
8786a2265eSRasesh Mody 	ecore_dp_tlv_list(p_hwfn, p_req);
8886a2265eSRasesh Mody 
8986a2265eSRasesh Mody 	/* Send TLVs over HW channel */
9086a2265eSRasesh Mody 	OSAL_MEMSET(&trigger, 0, sizeof(struct ustorm_trigger_vf_zone));
9186a2265eSRasesh Mody 	trigger.vf_pf_msg_valid = 1;
9286a2265eSRasesh Mody 
9386a2265eSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
9422d07d93SRasesh Mody 		   "VF -> PF [%02x] message: [%08x, %08x] --> %p,"
9522d07d93SRasesh Mody 		   " %08x --> %p\n",
9622d07d93SRasesh Mody 		   GET_FIELD(p_hwfn->hw_info.concrete_fid,
9722d07d93SRasesh Mody 			     PXP_CONCRETE_FID_PFID),
9886a2265eSRasesh Mody 		   U64_HI(p_hwfn->vf_iov_info->vf2pf_request_phys),
9986a2265eSRasesh Mody 		   U64_LO(p_hwfn->vf_iov_info->vf2pf_request_phys),
10086a2265eSRasesh Mody 		   &zone_data->non_trigger.vf_pf_msg_addr,
10186a2265eSRasesh Mody 		   *((u32 *)&trigger), &zone_data->trigger);
10286a2265eSRasesh Mody 
10386a2265eSRasesh Mody 	REG_WR(p_hwfn,
10486a2265eSRasesh Mody 	       (osal_uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.lo,
10586a2265eSRasesh Mody 	       U64_LO(p_hwfn->vf_iov_info->vf2pf_request_phys));
10686a2265eSRasesh Mody 
10786a2265eSRasesh Mody 	REG_WR(p_hwfn,
10886a2265eSRasesh Mody 	       (osal_uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.hi,
10986a2265eSRasesh Mody 	       U64_HI(p_hwfn->vf_iov_info->vf2pf_request_phys));
11086a2265eSRasesh Mody 
11186a2265eSRasesh Mody 	/* The message data must be written first, to prevent trigger before
11286a2265eSRasesh Mody 	 * data is written.
11386a2265eSRasesh Mody 	 */
11486a2265eSRasesh Mody 	OSAL_WMB(p_hwfn->p_dev);
11586a2265eSRasesh Mody 
11686a2265eSRasesh Mody 	REG_WR(p_hwfn, (osal_uintptr_t)&zone_data->trigger,
11786a2265eSRasesh Mody 	       *((u32 *)&trigger));
11886a2265eSRasesh Mody 
11922d07d93SRasesh Mody 	/* When PF would be done with the response, it would write back to the
12022d07d93SRasesh Mody 	 * `done' address. Poll until then.
12122d07d93SRasesh Mody 	 */
12286a2265eSRasesh Mody 	while ((!*done) && time) {
12386a2265eSRasesh Mody 		OSAL_MSLEEP(25);
12486a2265eSRasesh Mody 		time--;
12586a2265eSRasesh Mody 	}
12686a2265eSRasesh Mody 
12786a2265eSRasesh Mody 	if (!*done) {
12849f4b9dcSRasesh Mody 		DP_NOTICE(p_hwfn, true,
12986a2265eSRasesh Mody 			  "VF <-- PF Timeout [Type %d]\n",
13086a2265eSRasesh Mody 			  p_req->first_tlv.tl.type);
13186a2265eSRasesh Mody 		rc = ECORE_TIMEOUT;
13286a2265eSRasesh Mody 	} else {
13349f4b9dcSRasesh Mody 		if ((*done != PFVF_STATUS_SUCCESS) &&
13449f4b9dcSRasesh Mody 		    (*done != PFVF_STATUS_NO_RESOURCE))
13549f4b9dcSRasesh Mody 			DP_NOTICE(p_hwfn, false,
13649f4b9dcSRasesh Mody 				  "PF response: %d [Type %d]\n",
13749f4b9dcSRasesh Mody 				  *done, p_req->first_tlv.tl.type);
13849f4b9dcSRasesh Mody 		else
13986a2265eSRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
14086a2265eSRasesh Mody 				   "PF response: %d [Type %d]\n",
14186a2265eSRasesh Mody 				   *done, p_req->first_tlv.tl.type);
14286a2265eSRasesh Mody 	}
14386a2265eSRasesh Mody 
14486a2265eSRasesh Mody 	return rc;
14586a2265eSRasesh Mody }
14686a2265eSRasesh Mody 
ecore_vf_pf_add_qid(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)147a90c566fSRasesh Mody static void ecore_vf_pf_add_qid(struct ecore_hwfn *p_hwfn,
148a90c566fSRasesh Mody 				struct ecore_queue_cid *p_cid)
149a90c566fSRasesh Mody {
150a90c566fSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
151a90c566fSRasesh Mody 	struct vfpf_qid_tlv *p_qid_tlv;
152a90c566fSRasesh Mody 
153a90c566fSRasesh Mody 	/* Only add QIDs for the queue if it was negotiated with PF */
154a90c566fSRasesh Mody 	if (!(p_iov->acquire_resp.pfdev_info.capabilities &
155a90c566fSRasesh Mody 	      PFVF_ACQUIRE_CAP_QUEUE_QIDS))
156a90c566fSRasesh Mody 		return;
157a90c566fSRasesh Mody 
15830ecf673SRasesh Mody 	p_qid_tlv = ecore_add_tlv(&p_iov->offset,
159a90c566fSRasesh Mody 				  CHANNEL_TLV_QID, sizeof(*p_qid_tlv));
160a90c566fSRasesh Mody 	p_qid_tlv->qid = p_cid->qid_usage_idx;
161a90c566fSRasesh Mody }
162a90c566fSRasesh Mody 
_ecore_vf_pf_release(struct ecore_hwfn * p_hwfn,bool b_final)163c73d7da7SRasesh Mody enum _ecore_status_t _ecore_vf_pf_release(struct ecore_hwfn *p_hwfn,
164c73d7da7SRasesh Mody 					  bool b_final)
165c73d7da7SRasesh Mody {
166c73d7da7SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
167c73d7da7SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
168c73d7da7SRasesh Mody 	struct vfpf_first_tlv *req;
169c73d7da7SRasesh Mody 	u32 size;
170c73d7da7SRasesh Mody 	enum _ecore_status_t rc;
171c73d7da7SRasesh Mody 
172c73d7da7SRasesh Mody 	/* clear mailbox and prep first tlv */
173c73d7da7SRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_RELEASE, sizeof(*req));
174c73d7da7SRasesh Mody 
175c73d7da7SRasesh Mody 	/* add list termination tlv */
176c73d7da7SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
177c73d7da7SRasesh Mody 		      CHANNEL_TLV_LIST_END,
178c73d7da7SRasesh Mody 		      sizeof(struct channel_list_end_tlv));
179c73d7da7SRasesh Mody 
180c73d7da7SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
181c73d7da7SRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
182c73d7da7SRasesh Mody 
183c73d7da7SRasesh Mody 	if (rc == ECORE_SUCCESS && resp->hdr.status != PFVF_STATUS_SUCCESS)
184c73d7da7SRasesh Mody 		rc = ECORE_AGAIN;
185c73d7da7SRasesh Mody 
186c73d7da7SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
187c73d7da7SRasesh Mody 	if (!b_final)
188c73d7da7SRasesh Mody 		return rc;
189c73d7da7SRasesh Mody 
190c73d7da7SRasesh Mody 	p_hwfn->b_int_enabled = 0;
191c73d7da7SRasesh Mody 
192c73d7da7SRasesh Mody 	if (p_iov->vf2pf_request)
193c73d7da7SRasesh Mody 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
194c73d7da7SRasesh Mody 				       p_iov->vf2pf_request,
195c73d7da7SRasesh Mody 				       p_iov->vf2pf_request_phys,
196c73d7da7SRasesh Mody 				       sizeof(union vfpf_tlvs));
197c73d7da7SRasesh Mody 	if (p_iov->pf2vf_reply)
198c73d7da7SRasesh Mody 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
199c73d7da7SRasesh Mody 				       p_iov->pf2vf_reply,
200c73d7da7SRasesh Mody 				       p_iov->pf2vf_reply_phys,
201c73d7da7SRasesh Mody 				       sizeof(union pfvf_tlvs));
202c73d7da7SRasesh Mody 
203c73d7da7SRasesh Mody 	if (p_iov->bulletin.p_virt) {
204c73d7da7SRasesh Mody 		size = sizeof(struct ecore_bulletin_content);
205c73d7da7SRasesh Mody 		OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev,
206c73d7da7SRasesh Mody 				       p_iov->bulletin.p_virt,
207c73d7da7SRasesh Mody 				       p_iov->bulletin.phys,
208c73d7da7SRasesh Mody 				       size);
209c73d7da7SRasesh Mody 	}
210c73d7da7SRasesh Mody 
211c73d7da7SRasesh Mody #ifdef CONFIG_ECORE_LOCK_ALLOC
212c73d7da7SRasesh Mody 	OSAL_MUTEX_DEALLOC(&p_iov->mutex);
213c73d7da7SRasesh Mody #endif
214c73d7da7SRasesh Mody 
215c73d7da7SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_hwfn->vf_iov_info);
216c73d7da7SRasesh Mody 	p_hwfn->vf_iov_info = OSAL_NULL;
217c73d7da7SRasesh Mody 
218c73d7da7SRasesh Mody 	return rc;
219c73d7da7SRasesh Mody }
220c73d7da7SRasesh Mody 
ecore_vf_pf_release(struct ecore_hwfn * p_hwfn)221c73d7da7SRasesh Mody enum _ecore_status_t ecore_vf_pf_release(struct ecore_hwfn *p_hwfn)
222c73d7da7SRasesh Mody {
223c73d7da7SRasesh Mody 	return _ecore_vf_pf_release(p_hwfn, true);
224c73d7da7SRasesh Mody }
225c73d7da7SRasesh Mody 
ecore_vf_pf_acquire_reduce_resc(struct ecore_hwfn * p_hwfn,struct vf_pf_resc_request * p_req,struct pf_vf_resc * p_resp)22622d07d93SRasesh Mody static void ecore_vf_pf_acquire_reduce_resc(struct ecore_hwfn *p_hwfn,
22722d07d93SRasesh Mody 					    struct vf_pf_resc_request *p_req,
22822d07d93SRasesh Mody 					    struct pf_vf_resc *p_resp)
22922d07d93SRasesh Mody {
23022d07d93SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
231a90c566fSRasesh Mody 		   "PF unwilling to fullill resource request: rxq [%02x/%02x] txq [%02x/%02x] sbs [%02x/%02x] mac [%02x/%02x] vlan [%02x/%02x] mc [%02x/%02x] cids [%02x/%02x]. Try PF recommended amount\n",
23222d07d93SRasesh Mody 		   p_req->num_rxqs, p_resp->num_rxqs,
23322d07d93SRasesh Mody 		   p_req->num_rxqs, p_resp->num_txqs,
23422d07d93SRasesh Mody 		   p_req->num_sbs, p_resp->num_sbs,
23522d07d93SRasesh Mody 		   p_req->num_mac_filters, p_resp->num_mac_filters,
23622d07d93SRasesh Mody 		   p_req->num_vlan_filters, p_resp->num_vlan_filters,
237a90c566fSRasesh Mody 		   p_req->num_mc_filters, p_resp->num_mc_filters,
238a90c566fSRasesh Mody 		   p_req->num_cids, p_resp->num_cids);
23922d07d93SRasesh Mody 
24022d07d93SRasesh Mody 	/* humble our request */
24122d07d93SRasesh Mody 	p_req->num_txqs = p_resp->num_txqs;
24222d07d93SRasesh Mody 	p_req->num_rxqs = p_resp->num_rxqs;
24322d07d93SRasesh Mody 	p_req->num_sbs = p_resp->num_sbs;
24422d07d93SRasesh Mody 	p_req->num_mac_filters = p_resp->num_mac_filters;
24522d07d93SRasesh Mody 	p_req->num_vlan_filters = p_resp->num_vlan_filters;
24622d07d93SRasesh Mody 	p_req->num_mc_filters = p_resp->num_mc_filters;
247a90c566fSRasesh Mody 	p_req->num_cids = p_resp->num_cids;
24822d07d93SRasesh Mody }
24986a2265eSRasesh Mody 
250f44ca48cSManish Chopra static enum _ecore_status_t
ecore_vf_pf_soft_flr_acquire(struct ecore_hwfn * p_hwfn)251f44ca48cSManish Chopra ecore_vf_pf_soft_flr_acquire(struct ecore_hwfn *p_hwfn)
252f44ca48cSManish Chopra {
253f44ca48cSManish Chopra 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
254f44ca48cSManish Chopra 	struct pfvf_def_resp_tlv *resp;
255f44ca48cSManish Chopra 	struct vfpf_soft_flr_tlv *req;
256f44ca48cSManish Chopra 	enum _ecore_status_t rc;
257f44ca48cSManish Chopra 
258f44ca48cSManish Chopra 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_SOFT_FLR, sizeof(*req));
259f44ca48cSManish Chopra 
260f44ca48cSManish Chopra 	/* add list termination tlv */
261f44ca48cSManish Chopra 	ecore_add_tlv(&p_iov->offset,
262f44ca48cSManish Chopra 		      CHANNEL_TLV_LIST_END,
263f44ca48cSManish Chopra 		      sizeof(struct channel_list_end_tlv));
264f44ca48cSManish Chopra 
265f44ca48cSManish Chopra 	resp = &p_iov->pf2vf_reply->default_resp;
266f44ca48cSManish Chopra 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
267f44ca48cSManish Chopra 
268f44ca48cSManish Chopra 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV, "rc=0x%x\n", rc);
269f44ca48cSManish Chopra 
270f44ca48cSManish Chopra 	/* to release the mutex as ecore_vf_pf_acquire() take the mutex */
271f44ca48cSManish Chopra 	ecore_vf_pf_req_end(p_hwfn, ECORE_AGAIN);
272f44ca48cSManish Chopra 
273f44ca48cSManish Chopra 	/* As of today, there is no mechanism in place for VF to know the FLR
274f44ca48cSManish Chopra 	 * status, so sufficiently (worst case time) wait for FLR to complete,
275f44ca48cSManish Chopra 	 * as mailbox request to MFW by the PF for initiating VF flr and PF
276f44ca48cSManish Chopra 	 * processing VF FLR could take time.
277f44ca48cSManish Chopra 	 */
278f44ca48cSManish Chopra 	OSAL_MSLEEP(3000);
279f44ca48cSManish Chopra 
280f44ca48cSManish Chopra 	return ecore_vf_pf_acquire(p_hwfn);
281f44ca48cSManish Chopra }
282f44ca48cSManish Chopra 
ecore_vf_pf_acquire(struct ecore_hwfn * p_hwfn)283f44ca48cSManish Chopra enum _ecore_status_t ecore_vf_pf_acquire(struct ecore_hwfn *p_hwfn)
28486a2265eSRasesh Mody {
28586a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
28686a2265eSRasesh Mody 	struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp;
28786a2265eSRasesh Mody 	struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info;
28886a2265eSRasesh Mody 	struct ecore_vf_acquire_sw_info vf_sw_info;
2893b307c55SRasesh Mody 	struct ecore_dev *p_dev = p_hwfn->p_dev;
290f44ca48cSManish Chopra 	u8 retry_cnt = p_iov->acquire_retry_cnt;
29122d07d93SRasesh Mody 	struct vf_pf_resc_request *p_resc;
29286a2265eSRasesh Mody 	bool resources_acquired = false;
29322d07d93SRasesh Mody 	struct vfpf_acquire_tlv *req;
29422d07d93SRasesh Mody 	int attempts = 0;
29522d07d93SRasesh Mody 	enum _ecore_status_t rc = ECORE_SUCCESS;
29686a2265eSRasesh Mody 
29786a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
29886a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_ACQUIRE, sizeof(*req));
29922d07d93SRasesh Mody 	p_resc = &req->resc_request;
30086a2265eSRasesh Mody 
30186a2265eSRasesh Mody 	/* @@@ TBD: PF may not be ready bnx2x_get_vf_id... */
30286a2265eSRasesh Mody 	req->vfdev_info.opaque_fid = p_hwfn->hw_info.opaque_fid;
30386a2265eSRasesh Mody 
30422d07d93SRasesh Mody 	p_resc->num_rxqs = ECORE_MAX_VF_CHAINS_PER_PF;
30522d07d93SRasesh Mody 	p_resc->num_txqs = ECORE_MAX_VF_CHAINS_PER_PF;
30622d07d93SRasesh Mody 	p_resc->num_sbs = ECORE_MAX_VF_CHAINS_PER_PF;
30722d07d93SRasesh Mody 	p_resc->num_mac_filters = ECORE_ETH_VF_NUM_MAC_FILTERS;
30822d07d93SRasesh Mody 	p_resc->num_vlan_filters = ECORE_ETH_VF_NUM_VLAN_FILTERS;
309a90c566fSRasesh Mody 	p_resc->num_cids = ECORE_ETH_VF_DEFAULT_NUM_CIDS;
31086a2265eSRasesh Mody 
31186a2265eSRasesh Mody 	OSAL_MEMSET(&vf_sw_info, 0, sizeof(vf_sw_info));
31286a2265eSRasesh Mody 	OSAL_VF_FILL_ACQUIRE_RESC_REQ(p_hwfn, &req->resc_request, &vf_sw_info);
31386a2265eSRasesh Mody 
31486a2265eSRasesh Mody 	req->vfdev_info.os_type = vf_sw_info.os_type;
31586a2265eSRasesh Mody 	req->vfdev_info.driver_version = vf_sw_info.driver_version;
31686a2265eSRasesh Mody 	req->vfdev_info.fw_major = FW_MAJOR_VERSION;
31786a2265eSRasesh Mody 	req->vfdev_info.fw_minor = FW_MINOR_VERSION;
31886a2265eSRasesh Mody 	req->vfdev_info.fw_revision = FW_REVISION_VERSION;
31986a2265eSRasesh Mody 	req->vfdev_info.fw_engineering = FW_ENGINEERING_VERSION;
32022d07d93SRasesh Mody 	req->vfdev_info.eth_fp_hsi_major = ETH_HSI_VER_MAJOR;
32122d07d93SRasesh Mody 	req->vfdev_info.eth_fp_hsi_minor = ETH_HSI_VER_MINOR;
32286a2265eSRasesh Mody 
32322d07d93SRasesh Mody 	/* Fill capability field with any non-deprecated config we support */
32422d07d93SRasesh Mody 	req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_100G;
32586a2265eSRasesh Mody 
326c73d7da7SRasesh Mody 	/* If we've mapped the doorbell bar, try using queue qids */
327c73d7da7SRasesh Mody 	if (p_iov->b_doorbell_bar)
328c73d7da7SRasesh Mody 		req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_PHYSICAL_BAR |
329c73d7da7SRasesh Mody 						VFPF_ACQUIRE_CAP_QUEUE_QIDS;
330c73d7da7SRasesh Mody 
33186a2265eSRasesh Mody 	/* pf 2 vf bulletin board address */
33286a2265eSRasesh Mody 	req->bulletin_addr = p_iov->bulletin.phys;
33386a2265eSRasesh Mody 	req->bulletin_size = p_iov->bulletin.size;
33486a2265eSRasesh Mody 
33586a2265eSRasesh Mody 	/* add list termination tlv */
33630ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
33786a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
33886a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
33986a2265eSRasesh Mody 
34086a2265eSRasesh Mody 	while (!resources_acquired) {
34186a2265eSRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
34286a2265eSRasesh Mody 			   "attempting to acquire resources\n");
34386a2265eSRasesh Mody 
34422d07d93SRasesh Mody 		/* Clear response buffer, as this might be a re-send */
34522d07d93SRasesh Mody 		OSAL_MEMSET(p_iov->pf2vf_reply, 0,
34622d07d93SRasesh Mody 			    sizeof(union pfvf_tlvs));
34722d07d93SRasesh Mody 
34886a2265eSRasesh Mody 		/* send acquire request */
34986a2265eSRasesh Mody 		rc = ecore_send_msg2pf(p_hwfn,
35086a2265eSRasesh Mody 				       &resp->hdr.status, sizeof(*resp));
351f44ca48cSManish Chopra 
352f44ca48cSManish Chopra 		if (retry_cnt && rc == ECORE_TIMEOUT) {
353f44ca48cSManish Chopra 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
354f44ca48cSManish Chopra 				   "VF retrying to acquire due to VPC timeout\n");
355f44ca48cSManish Chopra 			retry_cnt--;
356f44ca48cSManish Chopra 			continue;
357f44ca48cSManish Chopra 		}
358f44ca48cSManish Chopra 
359c83cbe71SRasesh Mody 		if (rc != ECORE_SUCCESS)
360c83cbe71SRasesh Mody 			goto exit;
36186a2265eSRasesh Mody 
36286a2265eSRasesh Mody 		/* copy acquire response from buffer to p_hwfn */
36386a2265eSRasesh Mody 		OSAL_MEMCPY(&p_iov->acquire_resp,
36486a2265eSRasesh Mody 			    resp, sizeof(p_iov->acquire_resp));
36586a2265eSRasesh Mody 
36686a2265eSRasesh Mody 		attempts++;
36786a2265eSRasesh Mody 
36886a2265eSRasesh Mody 		if (resp->hdr.status == PFVF_STATUS_SUCCESS) {
36922d07d93SRasesh Mody 			/* PF agrees to allocate our resources */
37022d07d93SRasesh Mody 			if (!(resp->pfdev_info.capabilities &
37122d07d93SRasesh Mody 			      PFVF_ACQUIRE_CAP_POST_FW_OVERRIDE)) {
37222d07d93SRasesh Mody 				/* It's possible legacy PF mistakenly accepted;
37322d07d93SRasesh Mody 				 * but we don't care - simply mark it as
37422d07d93SRasesh Mody 				 * legacy and continue.
37522d07d93SRasesh Mody 				 */
37622d07d93SRasesh Mody 				req->vfdev_info.capabilities |=
37722d07d93SRasesh Mody 					VFPF_ACQUIRE_CAP_PRE_FP_HSI;
37822d07d93SRasesh Mody 			}
37986a2265eSRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
38086a2265eSRasesh Mody 				   "resources acquired\n");
38186a2265eSRasesh Mody 			resources_acquired = true;
38286a2265eSRasesh Mody 		} /* PF refuses to allocate our resources */
38322d07d93SRasesh Mody 		else if (resp->hdr.status == PFVF_STATUS_NO_RESOURCE &&
384f44ca48cSManish Chopra 			 attempts < ECORE_VF_ACQUIRE_THRESH) {
38522d07d93SRasesh Mody 			ecore_vf_pf_acquire_reduce_resc(p_hwfn, p_resc,
38622d07d93SRasesh Mody 							&resp->resc);
38786a2265eSRasesh Mody 
38822d07d93SRasesh Mody 		} else if (resp->hdr.status == PFVF_STATUS_NOT_SUPPORTED) {
38922d07d93SRasesh Mody 			if (pfdev_info->major_fp_hsi &&
39022d07d93SRasesh Mody 			    (pfdev_info->major_fp_hsi != ETH_HSI_VER_MAJOR)) {
39122d07d93SRasesh Mody 				DP_NOTICE(p_hwfn, false,
39222d07d93SRasesh Mody 					  "PF uses an incompatible fastpath HSI"
39322d07d93SRasesh Mody 					  " %02x.%02x [VF requires %02x.%02x]."
39422d07d93SRasesh Mody 					  " Please change to a VF driver using"
39522d07d93SRasesh Mody 					  " %02x.xx.\n",
39622d07d93SRasesh Mody 					  pfdev_info->major_fp_hsi,
39722d07d93SRasesh Mody 					  pfdev_info->minor_fp_hsi,
39822d07d93SRasesh Mody 					  ETH_HSI_VER_MAJOR, ETH_HSI_VER_MINOR,
39922d07d93SRasesh Mody 					  pfdev_info->major_fp_hsi);
40022d07d93SRasesh Mody 				rc = ECORE_INVAL;
40122d07d93SRasesh Mody 				goto exit;
40222d07d93SRasesh Mody 			}
40386a2265eSRasesh Mody 
40422d07d93SRasesh Mody 			if (!pfdev_info->major_fp_hsi) {
40522d07d93SRasesh Mody 				if (req->vfdev_info.capabilities &
40622d07d93SRasesh Mody 				    VFPF_ACQUIRE_CAP_PRE_FP_HSI) {
40722d07d93SRasesh Mody 					DP_NOTICE(p_hwfn, false,
40822d07d93SRasesh Mody 						  "PF uses very old drivers."
40922d07d93SRasesh Mody 						  " Please change to a VF"
41022d07d93SRasesh Mody 						  " driver using no later than"
41122d07d93SRasesh Mody 						  " 8.8.x.x.\n");
41222d07d93SRasesh Mody 					rc = ECORE_INVAL;
41322d07d93SRasesh Mody 					goto exit;
41422d07d93SRasesh Mody 				} else {
41522d07d93SRasesh Mody 					DP_INFO(p_hwfn,
41622d07d93SRasesh Mody 						"PF is old - try re-acquire to"
41722d07d93SRasesh Mody 						" see if it supports FW-version"
41822d07d93SRasesh Mody 						" override\n");
41922d07d93SRasesh Mody 					req->vfdev_info.capabilities |=
42022d07d93SRasesh Mody 						VFPF_ACQUIRE_CAP_PRE_FP_HSI;
4216087d8a9SRasesh Mody 					continue;
42222d07d93SRasesh Mody 				}
42322d07d93SRasesh Mody 			}
424a1f761e1SRasesh Mody 
425a1f761e1SRasesh Mody 			/* If PF/VF are using same Major, PF must have had
426a1f761e1SRasesh Mody 			 * it's reasons. Simply fail.
427a1f761e1SRasesh Mody 			 */
428a1f761e1SRasesh Mody 			DP_NOTICE(p_hwfn, false,
429a1f761e1SRasesh Mody 				  "PF rejected acquisition by VF\n");
430a1f761e1SRasesh Mody 			rc = ECORE_INVAL;
431a1f761e1SRasesh Mody 			goto exit;
432f44ca48cSManish Chopra 		} else if (resp->hdr.status == PFVF_STATUS_ACQUIRED) {
433f44ca48cSManish Chopra 			ecore_vf_pf_req_end(p_hwfn, ECORE_AGAIN);
434f44ca48cSManish Chopra 			return ecore_vf_pf_soft_flr_acquire(p_hwfn);
43586a2265eSRasesh Mody 		} else {
43686a2265eSRasesh Mody 			DP_ERR(p_hwfn,
43722d07d93SRasesh Mody 			       "PF returned err %d to VF acquisition request\n",
43886a2265eSRasesh Mody 			       resp->hdr.status);
43922d07d93SRasesh Mody 			rc = ECORE_AGAIN;
44022d07d93SRasesh Mody 			goto exit;
44186a2265eSRasesh Mody 		}
44286a2265eSRasesh Mody 	}
44386a2265eSRasesh Mody 
44422d07d93SRasesh Mody 	/* Mark the PF as legacy, if needed */
44522d07d93SRasesh Mody 	if (req->vfdev_info.capabilities &
44622d07d93SRasesh Mody 	    VFPF_ACQUIRE_CAP_PRE_FP_HSI)
44722d07d93SRasesh Mody 		p_iov->b_pre_fp_hsi = true;
44822d07d93SRasesh Mody 
449a90c566fSRasesh Mody 	/* In case PF doesn't support multi-queue Tx, update the number of
450a90c566fSRasesh Mody 	 * CIDs to reflect the number of queues [older PFs didn't fill that
451a90c566fSRasesh Mody 	 * field].
452a90c566fSRasesh Mody 	 */
453a90c566fSRasesh Mody 	if (!(resp->pfdev_info.capabilities &
454a90c566fSRasesh Mody 	      PFVF_ACQUIRE_CAP_QUEUE_QIDS))
455a90c566fSRasesh Mody 		resp->resc.num_cids = resp->resc.num_rxqs +
456a90c566fSRasesh Mody 				      resp->resc.num_txqs;
457a90c566fSRasesh Mody 
45886a2265eSRasesh Mody 	rc = OSAL_VF_UPDATE_ACQUIRE_RESC_RESP(p_hwfn, &resp->resc);
45986a2265eSRasesh Mody 	if (rc) {
46086a2265eSRasesh Mody 		DP_NOTICE(p_hwfn, true,
46122d07d93SRasesh Mody 			  "VF_UPDATE_ACQUIRE_RESC_RESP Failed:"
46222d07d93SRasesh Mody 			  " status = 0x%x.\n",
46386a2265eSRasesh Mody 			  rc);
46422d07d93SRasesh Mody 		rc = ECORE_AGAIN;
46522d07d93SRasesh Mody 		goto exit;
46686a2265eSRasesh Mody 	}
46786a2265eSRasesh Mody 
46886a2265eSRasesh Mody 	/* Update bulletin board size with response from PF */
46986a2265eSRasesh Mody 	p_iov->bulletin.size = resp->bulletin_size;
47086a2265eSRasesh Mody 
47186a2265eSRasesh Mody 	/* get HW info */
4723b307c55SRasesh Mody 	p_dev->type = resp->pfdev_info.dev_type;
4733b307c55SRasesh Mody 	p_dev->chip_rev = (u8)resp->pfdev_info.chip_rev;
47486a2265eSRasesh Mody 
47586a2265eSRasesh Mody 	DP_INFO(p_hwfn, "Chip details - %s%d\n",
4763b307c55SRasesh Mody 		ECORE_IS_BB(p_dev) ? "BB" : "AH",
47786a2265eSRasesh Mody 		CHIP_REV_IS_A0(p_hwfn->p_dev) ? 0 : 1);
47886a2265eSRasesh Mody 
4793b307c55SRasesh Mody 	p_dev->chip_num = pfdev_info->chip_num & 0xffff;
48086a2265eSRasesh Mody 
48122d07d93SRasesh Mody 	/* Learn of the possibility of CMT */
48222d07d93SRasesh Mody 	if (IS_LEAD_HWFN(p_hwfn)) {
48322d07d93SRasesh Mody 		if (resp->pfdev_info.capabilities & PFVF_ACQUIRE_CAP_100G) {
484f1e4b6c0SHarish Patil 			DP_INFO(p_hwfn, "100g VF\n");
4853b307c55SRasesh Mody 			p_dev->num_hwfns = 2;
48622d07d93SRasesh Mody 		}
48786a2265eSRasesh Mody 	}
48886a2265eSRasesh Mody 
48922d07d93SRasesh Mody 	/* @DPDK */
490d0ef40a1SDharmik Thakkar 	if (((p_iov->b_pre_fp_hsi == true) &
49122d07d93SRasesh Mody 	    ETH_HSI_VER_MINOR) &&
49222d07d93SRasesh Mody 	    (resp->pfdev_info.minor_fp_hsi < ETH_HSI_VER_MINOR))
49322d07d93SRasesh Mody 		DP_INFO(p_hwfn,
49422d07d93SRasesh Mody 			"PF is using older fastpath HSI;"
49522d07d93SRasesh Mody 			" %02x.%02x is configured\n",
49622d07d93SRasesh Mody 			ETH_HSI_VER_MAJOR,
49722d07d93SRasesh Mody 			resp->pfdev_info.minor_fp_hsi);
49822d07d93SRasesh Mody 
49922d07d93SRasesh Mody exit:
50022d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
50122d07d93SRasesh Mody 
50222d07d93SRasesh Mody 	return rc;
50322d07d93SRasesh Mody }
50422d07d93SRasesh Mody 
ecore_vf_hw_bar_size(struct ecore_hwfn * p_hwfn,enum BAR_ID bar_id)505c73d7da7SRasesh Mody u32 ecore_vf_hw_bar_size(struct ecore_hwfn *p_hwfn,
506c73d7da7SRasesh Mody 			 enum BAR_ID bar_id)
507c73d7da7SRasesh Mody {
508c73d7da7SRasesh Mody 	u32 bar_size;
509c73d7da7SRasesh Mody 
510c73d7da7SRasesh Mody 	/* Regview size is fixed */
511c73d7da7SRasesh Mody 	if (bar_id == BAR_ID_0)
512c73d7da7SRasesh Mody 		return 1 << 17;
513c73d7da7SRasesh Mody 
514c73d7da7SRasesh Mody 	/* Doorbell is received from PF */
515c73d7da7SRasesh Mody 	bar_size = p_hwfn->vf_iov_info->acquire_resp.pfdev_info.bar_size;
516c73d7da7SRasesh Mody 	if (bar_size)
517c73d7da7SRasesh Mody 		return 1 << bar_size;
518c73d7da7SRasesh Mody 	return 0;
519c73d7da7SRasesh Mody }
520c73d7da7SRasesh Mody 
521f44ca48cSManish Chopra enum _ecore_status_t
ecore_vf_hw_prepare(struct ecore_hwfn * p_hwfn,struct ecore_hw_prepare_params * p_params)522f44ca48cSManish Chopra ecore_vf_hw_prepare(struct ecore_hwfn *p_hwfn,
523f44ca48cSManish Chopra 		    struct ecore_hw_prepare_params *p_params)
52486a2265eSRasesh Mody {
525c73d7da7SRasesh Mody 	struct ecore_hwfn *p_lead = ECORE_LEADING_HWFN(p_hwfn->p_dev);
52622d07d93SRasesh Mody 	struct ecore_vf_iov *p_iov;
52722d07d93SRasesh Mody 	u32 reg;
528c73d7da7SRasesh Mody 	enum _ecore_status_t rc;
52986a2265eSRasesh Mody 
53022d07d93SRasesh Mody 	/* Set number of hwfns - might be overridden once leading hwfn learns
53122d07d93SRasesh Mody 	 * actual configuration from PF.
53222d07d93SRasesh Mody 	 */
53322d07d93SRasesh Mody 	if (IS_LEAD_HWFN(p_hwfn))
53422d07d93SRasesh Mody 		p_hwfn->p_dev->num_hwfns = 1;
53586a2265eSRasesh Mody 
53622d07d93SRasesh Mody 	reg = PXP_VF_BAR0_ME_OPAQUE_ADDRESS;
53722d07d93SRasesh Mody 	p_hwfn->hw_info.opaque_fid = (u16)REG_RD(p_hwfn, reg);
53886a2265eSRasesh Mody 
53922d07d93SRasesh Mody 	reg = PXP_VF_BAR0_ME_CONCRETE_ADDRESS;
54022d07d93SRasesh Mody 	p_hwfn->hw_info.concrete_fid = REG_RD(p_hwfn, reg);
54186a2265eSRasesh Mody 
54286a2265eSRasesh Mody 	/* Allocate vf sriov info */
54322d07d93SRasesh Mody 	p_iov = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*p_iov));
54422d07d93SRasesh Mody 	if (!p_iov) {
54586a2265eSRasesh Mody 		DP_NOTICE(p_hwfn, true,
54686a2265eSRasesh Mody 			  "Failed to allocate `struct ecore_sriov'\n");
54786a2265eSRasesh Mody 		return ECORE_NOMEM;
54886a2265eSRasesh Mody 	}
54986a2265eSRasesh Mody 
550c73d7da7SRasesh Mody 	/* Doorbells are tricky; Upper-layer has alreday set the hwfn doorbell
551c73d7da7SRasesh Mody 	 * value, but there are several incompatibily scenarios where that
552c73d7da7SRasesh Mody 	 * would be incorrect and we'd need to override it.
553c73d7da7SRasesh Mody 	 */
554c73d7da7SRasesh Mody 	if (p_hwfn->doorbells == OSAL_NULL) {
555c73d7da7SRasesh Mody 		p_hwfn->doorbells = (u8 OSAL_IOMEM *)p_hwfn->regview +
556c73d7da7SRasesh Mody 						     PXP_VF_BAR0_START_DQ;
557c73d7da7SRasesh Mody 	} else if (p_hwfn == p_lead) {
558c73d7da7SRasesh Mody 		/* For leading hw-function, value is always correct, but need
559c73d7da7SRasesh Mody 		 * to handle scenario where legacy PF would not support 100g
560c73d7da7SRasesh Mody 		 * mapped bars later.
561c73d7da7SRasesh Mody 		 */
562c73d7da7SRasesh Mody 		p_iov->b_doorbell_bar = true;
563c73d7da7SRasesh Mody 	} else {
564c73d7da7SRasesh Mody 		/* here, value would be correct ONLY if the leading hwfn
565c73d7da7SRasesh Mody 		 * received indication that mapped-bars are supported.
566c73d7da7SRasesh Mody 		 */
567c73d7da7SRasesh Mody 		if (p_lead->vf_iov_info->b_doorbell_bar)
568c73d7da7SRasesh Mody 			p_iov->b_doorbell_bar = true;
569c73d7da7SRasesh Mody 		else
570c73d7da7SRasesh Mody 			p_hwfn->doorbells = (u8 OSAL_IOMEM *)
571c73d7da7SRasesh Mody 					    p_hwfn->regview +
572c73d7da7SRasesh Mody 					    PXP_VF_BAR0_START_DQ;
573c73d7da7SRasesh Mody 	}
574c73d7da7SRasesh Mody 
57586a2265eSRasesh Mody 	/* Allocate vf2pf msg */
57622d07d93SRasesh Mody 	p_iov->vf2pf_request = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
57722d07d93SRasesh Mody 							 &p_iov->
57886a2265eSRasesh Mody 							 vf2pf_request_phys,
57986a2265eSRasesh Mody 							 sizeof(union
58086a2265eSRasesh Mody 								vfpf_tlvs));
58122d07d93SRasesh Mody 	if (!p_iov->vf2pf_request) {
58286a2265eSRasesh Mody 		DP_NOTICE(p_hwfn, true,
58386a2265eSRasesh Mody 			 "Failed to allocate `vf2pf_request' DMA memory\n");
58422d07d93SRasesh Mody 		goto free_p_iov;
58586a2265eSRasesh Mody 	}
58686a2265eSRasesh Mody 
58722d07d93SRasesh Mody 	p_iov->pf2vf_reply = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
58822d07d93SRasesh Mody 						       &p_iov->
58986a2265eSRasesh Mody 						       pf2vf_reply_phys,
59086a2265eSRasesh Mody 						       sizeof(union pfvf_tlvs));
59122d07d93SRasesh Mody 	if (!p_iov->pf2vf_reply) {
59286a2265eSRasesh Mody 		DP_NOTICE(p_hwfn, true,
59386a2265eSRasesh Mody 			  "Failed to allocate `pf2vf_reply' DMA memory\n");
59486a2265eSRasesh Mody 		goto free_vf2pf_request;
59586a2265eSRasesh Mody 	}
59686a2265eSRasesh Mody 
59786a2265eSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
59822d07d93SRasesh Mody 		   "VF's Request mailbox [%p virt 0x%lx phys], "
59922d07d93SRasesh Mody 		   "Response mailbox [%p virt 0x%lx phys]\n",
60022d07d93SRasesh Mody 		   p_iov->vf2pf_request,
60122d07d93SRasesh Mody 		   (unsigned long)p_iov->vf2pf_request_phys,
60222d07d93SRasesh Mody 		   p_iov->pf2vf_reply,
60322d07d93SRasesh Mody 		   (unsigned long)p_iov->pf2vf_reply_phys);
60486a2265eSRasesh Mody 
60586a2265eSRasesh Mody 	/* Allocate Bulletin board */
60622d07d93SRasesh Mody 	p_iov->bulletin.size = sizeof(struct ecore_bulletin_content);
60722d07d93SRasesh Mody 	p_iov->bulletin.p_virt = OSAL_DMA_ALLOC_COHERENT(p_hwfn->p_dev,
60822d07d93SRasesh Mody 							   &p_iov->bulletin.
60986a2265eSRasesh Mody 							   phys,
61022d07d93SRasesh Mody 							   p_iov->bulletin.
61186a2265eSRasesh Mody 							   size);
6124eae6b01SRasesh Mody 	if (!p_iov->bulletin.p_virt) {
6134eae6b01SRasesh Mody 		DP_NOTICE(p_hwfn, false, "Failed to alloc bulletin memory\n");
6144eae6b01SRasesh Mody 		goto free_pf2vf_reply;
6154eae6b01SRasesh Mody 	}
61686a2265eSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
61722d07d93SRasesh Mody 		   "VF's bulletin Board [%p virt 0x%lx phys 0x%08x bytes]\n",
61822d07d93SRasesh Mody 		   p_iov->bulletin.p_virt, (unsigned long)p_iov->bulletin.phys,
61922d07d93SRasesh Mody 		   p_iov->bulletin.size);
62086a2265eSRasesh Mody 
62122c99696SRasesh Mody #ifdef CONFIG_ECORE_LOCK_ALLOC
6224eae6b01SRasesh Mody 	if (OSAL_MUTEX_ALLOC(p_hwfn, &p_iov->mutex)) {
6234eae6b01SRasesh Mody 		DP_NOTICE(p_hwfn, false, "Failed to allocate p_iov->mutex\n");
6244eae6b01SRasesh Mody 		goto free_bulletin_mem;
6254eae6b01SRasesh Mody 	}
62622c99696SRasesh Mody #endif
62722d07d93SRasesh Mody 	OSAL_MUTEX_INIT(&p_iov->mutex);
62886a2265eSRasesh Mody 
629f44ca48cSManish Chopra 	p_iov->acquire_retry_cnt = p_params->acquire_retry_cnt;
63022d07d93SRasesh Mody 	p_hwfn->vf_iov_info = p_iov;
63186a2265eSRasesh Mody 
63286a2265eSRasesh Mody 	p_hwfn->hw_info.personality = ECORE_PCI_ETH;
63386a2265eSRasesh Mody 
634c73d7da7SRasesh Mody 	rc = ecore_vf_pf_acquire(p_hwfn);
635c73d7da7SRasesh Mody 
636c73d7da7SRasesh Mody 	/* If VF is 100g using a mapped bar and PF is too old to support that,
637c73d7da7SRasesh Mody 	 * acquisition would succeed - but the VF would have no way knowing
638c73d7da7SRasesh Mody 	 * the size of the doorbell bar configured in HW and thus will not
639c73d7da7SRasesh Mody 	 * know how to split it for 2nd hw-function.
640c73d7da7SRasesh Mody 	 * In this case we re-try without the indication of the mapped
641c73d7da7SRasesh Mody 	 * doorbell.
642c73d7da7SRasesh Mody 	 */
643c73d7da7SRasesh Mody 	if (rc == ECORE_SUCCESS &&
644c73d7da7SRasesh Mody 	    p_iov->b_doorbell_bar &&
645c73d7da7SRasesh Mody 	    !ecore_vf_hw_bar_size(p_hwfn, BAR_ID_1) &&
646c73d7da7SRasesh Mody 	    ECORE_IS_CMT(p_hwfn->p_dev)) {
647c73d7da7SRasesh Mody 		rc = _ecore_vf_pf_release(p_hwfn, false);
648c73d7da7SRasesh Mody 		if (rc != ECORE_SUCCESS)
649c73d7da7SRasesh Mody 			return rc;
650c73d7da7SRasesh Mody 
651c73d7da7SRasesh Mody 		p_iov->b_doorbell_bar = false;
652c73d7da7SRasesh Mody 		p_hwfn->doorbells = (u8 OSAL_IOMEM *)p_hwfn->regview +
653c73d7da7SRasesh Mody 						     PXP_VF_BAR0_START_DQ;
654c73d7da7SRasesh Mody 		rc = ecore_vf_pf_acquire(p_hwfn);
655c73d7da7SRasesh Mody 	}
656c73d7da7SRasesh Mody 
657c73d7da7SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
658c73d7da7SRasesh Mody 		   "Regview [%p], Doorbell [%p], Device-doorbell [%p]\n",
659c73d7da7SRasesh Mody 		   p_hwfn->regview, p_hwfn->doorbells,
660c73d7da7SRasesh Mody 		   p_hwfn->p_dev->doorbells);
661c73d7da7SRasesh Mody 
662c73d7da7SRasesh Mody 	return rc;
66386a2265eSRasesh Mody 
6644eae6b01SRasesh Mody #ifdef CONFIG_ECORE_LOCK_ALLOC
6654eae6b01SRasesh Mody free_bulletin_mem:
6664eae6b01SRasesh Mody 	OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, p_iov->bulletin.p_virt,
6674eae6b01SRasesh Mody 			       p_iov->bulletin.phys,
6684eae6b01SRasesh Mody 			       p_iov->bulletin.size);
6694eae6b01SRasesh Mody #endif
6704eae6b01SRasesh Mody free_pf2vf_reply:
6714eae6b01SRasesh Mody 	OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, p_iov->pf2vf_reply,
6724eae6b01SRasesh Mody 			       p_iov->pf2vf_reply_phys,
6734eae6b01SRasesh Mody 			       sizeof(union pfvf_tlvs));
67486a2265eSRasesh Mody free_vf2pf_request:
67522d07d93SRasesh Mody 	OSAL_DMA_FREE_COHERENT(p_hwfn->p_dev, p_iov->vf2pf_request,
67622d07d93SRasesh Mody 			       p_iov->vf2pf_request_phys,
67786a2265eSRasesh Mody 			       sizeof(union vfpf_tlvs));
67822d07d93SRasesh Mody free_p_iov:
67922d07d93SRasesh Mody 	OSAL_FREE(p_hwfn->p_dev, p_iov);
68086a2265eSRasesh Mody 
68122d07d93SRasesh Mody 	return ECORE_NOMEM;
68286a2265eSRasesh Mody }
68386a2265eSRasesh Mody 
6840b090fd3SRasesh Mody /* @DPDK - changed enum ecore_tunn_clss to enum ecore_tunn_mode */
6850b090fd3SRasesh Mody static void
__ecore_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv * p_req,struct ecore_tunn_update_type * p_src,enum ecore_tunn_mode mask,u8 * p_cls)6860b090fd3SRasesh Mody __ecore_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv *p_req,
6870b090fd3SRasesh Mody 			     struct ecore_tunn_update_type *p_src,
6880b090fd3SRasesh Mody 			     enum ecore_tunn_mode mask, u8 *p_cls)
6890b090fd3SRasesh Mody {
6900b090fd3SRasesh Mody 	if (p_src->b_update_mode) {
6910b090fd3SRasesh Mody 		p_req->tun_mode_update_mask |= (1 << mask);
6920b090fd3SRasesh Mody 
6930b090fd3SRasesh Mody 		if (p_src->b_mode_enabled)
6940b090fd3SRasesh Mody 			p_req->tunn_mode |= (1 << mask);
6950b090fd3SRasesh Mody 	}
6960b090fd3SRasesh Mody 
6970b090fd3SRasesh Mody 	*p_cls = p_src->tun_cls;
6980b090fd3SRasesh Mody }
6990b090fd3SRasesh Mody 
7000b090fd3SRasesh Mody /* @DPDK - changed enum ecore_tunn_clss to enum ecore_tunn_mode */
7010b090fd3SRasesh Mody static void
ecore_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv * p_req,struct ecore_tunn_update_type * p_src,enum ecore_tunn_mode mask,u8 * p_cls,struct ecore_tunn_update_udp_port * p_port,u8 * p_update_port,u16 * p_udp_port)7020b090fd3SRasesh Mody ecore_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv *p_req,
7030b090fd3SRasesh Mody 			   struct ecore_tunn_update_type *p_src,
7040b090fd3SRasesh Mody 			   enum ecore_tunn_mode mask, u8 *p_cls,
7050b090fd3SRasesh Mody 			   struct ecore_tunn_update_udp_port *p_port,
7060b090fd3SRasesh Mody 			   u8 *p_update_port, u16 *p_udp_port)
7070b090fd3SRasesh Mody {
7080b090fd3SRasesh Mody 	if (p_port->b_update_port) {
7090b090fd3SRasesh Mody 		*p_update_port = 1;
7100b090fd3SRasesh Mody 		*p_udp_port = p_port->port;
7110b090fd3SRasesh Mody 	}
7120b090fd3SRasesh Mody 
7130b090fd3SRasesh Mody 	__ecore_vf_prep_tunn_req_tlv(p_req, p_src, mask, p_cls);
7140b090fd3SRasesh Mody }
7150b090fd3SRasesh Mody 
ecore_vf_set_vf_start_tunn_update_param(struct ecore_tunnel_info * p_tun)7160b090fd3SRasesh Mody void ecore_vf_set_vf_start_tunn_update_param(struct ecore_tunnel_info *p_tun)
7170b090fd3SRasesh Mody {
7180b090fd3SRasesh Mody 	if (p_tun->vxlan.b_mode_enabled)
7190b090fd3SRasesh Mody 		p_tun->vxlan.b_update_mode = true;
7200b090fd3SRasesh Mody 	if (p_tun->l2_geneve.b_mode_enabled)
7210b090fd3SRasesh Mody 		p_tun->l2_geneve.b_update_mode = true;
7220b090fd3SRasesh Mody 	if (p_tun->ip_geneve.b_mode_enabled)
7230b090fd3SRasesh Mody 		p_tun->ip_geneve.b_update_mode = true;
7240b090fd3SRasesh Mody 	if (p_tun->l2_gre.b_mode_enabled)
7250b090fd3SRasesh Mody 		p_tun->l2_gre.b_update_mode = true;
7260b090fd3SRasesh Mody 	if (p_tun->ip_gre.b_mode_enabled)
7270b090fd3SRasesh Mody 		p_tun->ip_gre.b_update_mode = true;
7280b090fd3SRasesh Mody 
7290b090fd3SRasesh Mody 	p_tun->b_update_rx_cls = true;
7300b090fd3SRasesh Mody 	p_tun->b_update_tx_cls = true;
7310b090fd3SRasesh Mody }
7320b090fd3SRasesh Mody 
7330b090fd3SRasesh Mody static void
__ecore_vf_update_tunn_param(struct ecore_tunn_update_type * p_tun,u16 feature_mask,u8 tunn_mode,u8 tunn_cls,enum ecore_tunn_mode val)7340b090fd3SRasesh Mody __ecore_vf_update_tunn_param(struct ecore_tunn_update_type *p_tun,
7350b090fd3SRasesh Mody 			     u16 feature_mask, u8 tunn_mode, u8 tunn_cls,
7360b090fd3SRasesh Mody 			     enum ecore_tunn_mode val)
7370b090fd3SRasesh Mody {
7380b090fd3SRasesh Mody 	if (feature_mask & (1 << val)) {
7390b090fd3SRasesh Mody 		p_tun->b_mode_enabled = tunn_mode;
7400b090fd3SRasesh Mody 		p_tun->tun_cls = tunn_cls;
7410b090fd3SRasesh Mody 	} else {
7420b090fd3SRasesh Mody 		p_tun->b_mode_enabled = false;
7430b090fd3SRasesh Mody 	}
7440b090fd3SRasesh Mody }
7450b090fd3SRasesh Mody 
7460b090fd3SRasesh Mody static void
ecore_vf_update_tunn_param(struct ecore_hwfn * p_hwfn,struct ecore_tunnel_info * p_tun,struct pfvf_update_tunn_param_tlv * p_resp)7470b090fd3SRasesh Mody ecore_vf_update_tunn_param(struct ecore_hwfn *p_hwfn,
7480b090fd3SRasesh Mody 			   struct ecore_tunnel_info *p_tun,
7490b090fd3SRasesh Mody 			   struct pfvf_update_tunn_param_tlv *p_resp)
7500b090fd3SRasesh Mody {
7510b090fd3SRasesh Mody 	/* Update mode and classes provided by PF */
7520b090fd3SRasesh Mody 	u16 feat_mask = p_resp->tunn_feature_mask;
7530b090fd3SRasesh Mody 
7540b090fd3SRasesh Mody 	__ecore_vf_update_tunn_param(&p_tun->vxlan, feat_mask,
7550b090fd3SRasesh Mody 				     p_resp->vxlan_mode, p_resp->vxlan_clss,
7560b090fd3SRasesh Mody 				     ECORE_MODE_VXLAN_TUNN);
7570b090fd3SRasesh Mody 	__ecore_vf_update_tunn_param(&p_tun->l2_geneve, feat_mask,
7580b090fd3SRasesh Mody 				     p_resp->l2geneve_mode,
7590b090fd3SRasesh Mody 				     p_resp->l2geneve_clss,
7600b090fd3SRasesh Mody 				     ECORE_MODE_L2GENEVE_TUNN);
7610b090fd3SRasesh Mody 	__ecore_vf_update_tunn_param(&p_tun->ip_geneve, feat_mask,
7620b090fd3SRasesh Mody 				     p_resp->ipgeneve_mode,
7630b090fd3SRasesh Mody 				     p_resp->ipgeneve_clss,
7640b090fd3SRasesh Mody 				     ECORE_MODE_IPGENEVE_TUNN);
7650b090fd3SRasesh Mody 	__ecore_vf_update_tunn_param(&p_tun->l2_gre, feat_mask,
7660b090fd3SRasesh Mody 				     p_resp->l2gre_mode, p_resp->l2gre_clss,
7670b090fd3SRasesh Mody 				     ECORE_MODE_L2GRE_TUNN);
7680b090fd3SRasesh Mody 	__ecore_vf_update_tunn_param(&p_tun->ip_gre, feat_mask,
7690b090fd3SRasesh Mody 				     p_resp->ipgre_mode, p_resp->ipgre_clss,
7700b090fd3SRasesh Mody 				     ECORE_MODE_IPGRE_TUNN);
7710b090fd3SRasesh Mody 	p_tun->geneve_port.port = p_resp->geneve_udp_port;
7720b090fd3SRasesh Mody 	p_tun->vxlan_port.port = p_resp->vxlan_udp_port;
7730b090fd3SRasesh Mody 
7740b090fd3SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
7750b090fd3SRasesh Mody 		   "tunn mode: vxlan=0x%x, l2geneve=0x%x, ipgeneve=0x%x, l2gre=0x%x, ipgre=0x%x",
7760b090fd3SRasesh Mody 		   p_tun->vxlan.b_mode_enabled, p_tun->l2_geneve.b_mode_enabled,
7770b090fd3SRasesh Mody 		   p_tun->ip_geneve.b_mode_enabled,
7780b090fd3SRasesh Mody 		   p_tun->l2_gre.b_mode_enabled,
7790b090fd3SRasesh Mody 		   p_tun->ip_gre.b_mode_enabled);
7800b090fd3SRasesh Mody }
7810b090fd3SRasesh Mody 
7820b090fd3SRasesh Mody enum _ecore_status_t
ecore_vf_pf_tunnel_param_update(struct ecore_hwfn * p_hwfn,struct ecore_tunnel_info * p_src)7830b090fd3SRasesh Mody ecore_vf_pf_tunnel_param_update(struct ecore_hwfn *p_hwfn,
7840b090fd3SRasesh Mody 				struct ecore_tunnel_info *p_src)
7850b090fd3SRasesh Mody {
7860b090fd3SRasesh Mody 	struct ecore_tunnel_info *p_tun = &p_hwfn->p_dev->tunnel;
7870b090fd3SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
7880b090fd3SRasesh Mody 	struct pfvf_update_tunn_param_tlv *p_resp;
7890b090fd3SRasesh Mody 	struct vfpf_update_tunn_param_tlv *p_req;
7900b090fd3SRasesh Mody 	enum _ecore_status_t rc;
7910b090fd3SRasesh Mody 
7920b090fd3SRasesh Mody 	p_req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_UPDATE_TUNN_PARAM,
7930b090fd3SRasesh Mody 				 sizeof(*p_req));
7940b090fd3SRasesh Mody 
7950b090fd3SRasesh Mody 	if (p_src->b_update_rx_cls && p_src->b_update_tx_cls)
7960b090fd3SRasesh Mody 		p_req->update_tun_cls = 1;
7970b090fd3SRasesh Mody 
7980b090fd3SRasesh Mody 	ecore_vf_prep_tunn_req_tlv(p_req, &p_src->vxlan, ECORE_MODE_VXLAN_TUNN,
7990b090fd3SRasesh Mody 				   &p_req->vxlan_clss, &p_src->vxlan_port,
8000b090fd3SRasesh Mody 				   &p_req->update_vxlan_port,
8010b090fd3SRasesh Mody 				   &p_req->vxlan_port);
8020b090fd3SRasesh Mody 	ecore_vf_prep_tunn_req_tlv(p_req, &p_src->l2_geneve,
8030b090fd3SRasesh Mody 				   ECORE_MODE_L2GENEVE_TUNN,
8040b090fd3SRasesh Mody 				   &p_req->l2geneve_clss, &p_src->geneve_port,
8050b090fd3SRasesh Mody 				   &p_req->update_geneve_port,
8060b090fd3SRasesh Mody 				   &p_req->geneve_port);
8070b090fd3SRasesh Mody 	__ecore_vf_prep_tunn_req_tlv(p_req, &p_src->ip_geneve,
8080b090fd3SRasesh Mody 				     ECORE_MODE_IPGENEVE_TUNN,
8090b090fd3SRasesh Mody 				     &p_req->ipgeneve_clss);
8100b090fd3SRasesh Mody 	__ecore_vf_prep_tunn_req_tlv(p_req, &p_src->l2_gre,
8110b090fd3SRasesh Mody 				     ECORE_MODE_L2GRE_TUNN, &p_req->l2gre_clss);
8120b090fd3SRasesh Mody 	__ecore_vf_prep_tunn_req_tlv(p_req, &p_src->ip_gre,
8130b090fd3SRasesh Mody 				     ECORE_MODE_IPGRE_TUNN, &p_req->ipgre_clss);
8140b090fd3SRasesh Mody 
8150b090fd3SRasesh Mody 	/* add list termination tlv */
81630ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
8170b090fd3SRasesh Mody 		      CHANNEL_TLV_LIST_END,
8180b090fd3SRasesh Mody 		      sizeof(struct channel_list_end_tlv));
8190b090fd3SRasesh Mody 
8200b090fd3SRasesh Mody 	p_resp = &p_iov->pf2vf_reply->tunn_param_resp;
8210b090fd3SRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &p_resp->hdr.status, sizeof(*p_resp));
8220b090fd3SRasesh Mody 
8230b090fd3SRasesh Mody 	if (rc)
8240b090fd3SRasesh Mody 		goto exit;
8250b090fd3SRasesh Mody 
8260b090fd3SRasesh Mody 	if (p_resp->hdr.status != PFVF_STATUS_SUCCESS) {
8270b090fd3SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
8280b090fd3SRasesh Mody 			   "Failed to update tunnel parameters\n");
8290b090fd3SRasesh Mody 		rc = ECORE_INVAL;
8300b090fd3SRasesh Mody 	}
8310b090fd3SRasesh Mody 
8320b090fd3SRasesh Mody 	ecore_vf_update_tunn_param(p_hwfn, p_tun, p_resp);
8330b090fd3SRasesh Mody exit:
8340b090fd3SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
8350b090fd3SRasesh Mody 	return rc;
8360b090fd3SRasesh Mody }
8370b090fd3SRasesh Mody 
838a55e422eSRasesh Mody enum _ecore_status_t
ecore_vf_pf_rxq_start(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,u16 bd_max_bytes,dma_addr_t bd_chain_phys_addr,dma_addr_t cqe_pbl_addr,u16 cqe_pbl_size,void OSAL_IOMEM ** pp_prod)839a55e422eSRasesh Mody ecore_vf_pf_rxq_start(struct ecore_hwfn *p_hwfn,
840a55e422eSRasesh Mody 		      struct ecore_queue_cid *p_cid,
84186a2265eSRasesh Mody 		      u16 bd_max_bytes,
84286a2265eSRasesh Mody 		      dma_addr_t bd_chain_phys_addr,
84386a2265eSRasesh Mody 		      dma_addr_t cqe_pbl_addr,
84486a2265eSRasesh Mody 		      u16 cqe_pbl_size,
84586a2265eSRasesh Mody 		      void OSAL_IOMEM **pp_prod)
84686a2265eSRasesh Mody {
84786a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
84822d07d93SRasesh Mody 	struct pfvf_start_queue_resp_tlv *resp;
84986a2265eSRasesh Mody 	struct vfpf_start_rxq_tlv *req;
850a55e422eSRasesh Mody 	u16 rx_qid = p_cid->rel.queue_id;
85193fce904SRasesh Mody 	enum _ecore_status_t rc;
85286a2265eSRasesh Mody 
85386a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
85486a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_RXQ, sizeof(*req));
85586a2265eSRasesh Mody 
85686a2265eSRasesh Mody 	req->rx_qid = rx_qid;
85786a2265eSRasesh Mody 	req->cqe_pbl_addr = cqe_pbl_addr;
85886a2265eSRasesh Mody 	req->cqe_pbl_size = cqe_pbl_size;
85986a2265eSRasesh Mody 	req->rxq_addr = bd_chain_phys_addr;
8606e4fcea9SRasesh Mody 	req->hw_sb = p_cid->sb_igu_id;
8616e4fcea9SRasesh Mody 	req->sb_index = p_cid->sb_idx;
86286a2265eSRasesh Mody 	req->bd_max_bytes = bd_max_bytes;
86322d07d93SRasesh Mody 	req->stat_id = -1; /* Keep initialized, for future compatibility */
86422d07d93SRasesh Mody 
86522d07d93SRasesh Mody 	/* If PF is legacy, we'll need to calculate producers ourselves
86622d07d93SRasesh Mody 	 * as well as clean them.
86722d07d93SRasesh Mody 	 */
868a55e422eSRasesh Mody 	if (p_iov->b_pre_fp_hsi) {
86922d07d93SRasesh Mody 		u8 hw_qid = p_iov->acquire_resp.resc.hw_qid[rx_qid];
87022d07d93SRasesh Mody 		u32 init_prod_val = 0;
87122d07d93SRasesh Mody 
8723b307c55SRasesh Mody 		*pp_prod = (u8 OSAL_IOMEM *)p_hwfn->regview +
87322d07d93SRasesh Mody 			   MSTORM_QZONE_START(p_hwfn->p_dev) +
87422d07d93SRasesh Mody 			   (hw_qid) * MSTORM_QZONE_SIZE;
87522d07d93SRasesh Mody 
87622d07d93SRasesh Mody 		/* Init the rcq, rx bd and rx sge (if valid) producers to 0 */
87722d07d93SRasesh Mody 		__internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32),
87822d07d93SRasesh Mody 				  (u32 *)(&init_prod_val));
87922d07d93SRasesh Mody 	}
88086a2265eSRasesh Mody 
881a90c566fSRasesh Mody 	ecore_vf_pf_add_qid(p_hwfn, p_cid);
882a90c566fSRasesh Mody 
88386a2265eSRasesh Mody 	/* add list termination tlv */
88430ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
88586a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
88686a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
88786a2265eSRasesh Mody 
88822d07d93SRasesh Mody 	resp = &p_iov->pf2vf_reply->queue_start;
88986a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
89086a2265eSRasesh Mody 	if (rc)
89122d07d93SRasesh Mody 		goto exit;
89286a2265eSRasesh Mody 
89322d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
89422d07d93SRasesh Mody 		rc = ECORE_INVAL;
89522d07d93SRasesh Mody 		goto exit;
89622d07d93SRasesh Mody 	}
89722d07d93SRasesh Mody 
89822d07d93SRasesh Mody 	/* Learn the address of the producer from the response */
899a55e422eSRasesh Mody 	if (!p_iov->b_pre_fp_hsi) {
90022d07d93SRasesh Mody 		u32 init_prod_val = 0;
90122d07d93SRasesh Mody 
90222d07d93SRasesh Mody 		*pp_prod = (u8 OSAL_IOMEM *)p_hwfn->regview + resp->offset;
90322d07d93SRasesh Mody 		DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
90422d07d93SRasesh Mody 			   "Rxq[0x%02x]: producer at %p [offset 0x%08x]\n",
90522d07d93SRasesh Mody 			   rx_qid, *pp_prod, resp->offset);
90622d07d93SRasesh Mody 
90722d07d93SRasesh Mody 		/* Init the rcq, rx bd and rx sge (if valid) producers to 0.
90822d07d93SRasesh Mody 		 * It was actually the PF's responsibility, but since some
90922d07d93SRasesh Mody 		 * old PFs might fail to do so, we do this as well.
91022d07d93SRasesh Mody 		 */
91122d07d93SRasesh Mody 		OSAL_BUILD_BUG_ON(ETH_HSI_VER_MAJOR != 3);
91222d07d93SRasesh Mody 		__internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32),
91322d07d93SRasesh Mody 				  (u32 *)&init_prod_val);
91422d07d93SRasesh Mody 	}
91522d07d93SRasesh Mody 
91622d07d93SRasesh Mody exit:
91722d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
91886a2265eSRasesh Mody 
91986a2265eSRasesh Mody 	return rc;
92086a2265eSRasesh Mody }
92186a2265eSRasesh Mody 
ecore_vf_pf_rxq_stop(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,bool cqe_completion)92286a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_rxq_stop(struct ecore_hwfn *p_hwfn,
923a55e422eSRasesh Mody 					  struct ecore_queue_cid *p_cid,
924a55e422eSRasesh Mody 					  bool cqe_completion)
92586a2265eSRasesh Mody {
92686a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
92786a2265eSRasesh Mody 	struct vfpf_stop_rxqs_tlv *req;
92822d07d93SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
92993fce904SRasesh Mody 	enum _ecore_status_t rc;
93086a2265eSRasesh Mody 
93186a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
93286a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_RXQS, sizeof(*req));
93386a2265eSRasesh Mody 
934a55e422eSRasesh Mody 	req->rx_qid = p_cid->rel.queue_id;
93586a2265eSRasesh Mody 	req->num_rxqs = 1;
93686a2265eSRasesh Mody 	req->cqe_completion = cqe_completion;
93786a2265eSRasesh Mody 
938a90c566fSRasesh Mody 	ecore_vf_pf_add_qid(p_hwfn, p_cid);
939a90c566fSRasesh Mody 
94086a2265eSRasesh Mody 	/* add list termination tlv */
94130ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
94286a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
94386a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
94486a2265eSRasesh Mody 
94522d07d93SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
94686a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
94786a2265eSRasesh Mody 	if (rc)
94822d07d93SRasesh Mody 		goto exit;
94986a2265eSRasesh Mody 
95022d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
95122d07d93SRasesh Mody 		rc = ECORE_INVAL;
95222d07d93SRasesh Mody 		goto exit;
95322d07d93SRasesh Mody 	}
95422d07d93SRasesh Mody 
95522d07d93SRasesh Mody exit:
95622d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
95786a2265eSRasesh Mody 
95886a2265eSRasesh Mody 	return rc;
95986a2265eSRasesh Mody }
96086a2265eSRasesh Mody 
961a55e422eSRasesh Mody enum _ecore_status_t
ecore_vf_pf_txq_start(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid,dma_addr_t pbl_addr,u16 pbl_size,void OSAL_IOMEM ** pp_doorbell)962a55e422eSRasesh Mody ecore_vf_pf_txq_start(struct ecore_hwfn *p_hwfn,
963a55e422eSRasesh Mody 		      struct ecore_queue_cid *p_cid,
964a55e422eSRasesh Mody 		      dma_addr_t pbl_addr, u16 pbl_size,
96586a2265eSRasesh Mody 		      void OSAL_IOMEM **pp_doorbell)
96686a2265eSRasesh Mody {
96786a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
96822d07d93SRasesh Mody 	struct pfvf_start_queue_resp_tlv *resp;
96986a2265eSRasesh Mody 	struct vfpf_start_txq_tlv *req;
970a55e422eSRasesh Mody 	u16 qid = p_cid->rel.queue_id;
97193fce904SRasesh Mody 	enum _ecore_status_t rc;
97286a2265eSRasesh Mody 
97386a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
97486a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_TXQ, sizeof(*req));
97586a2265eSRasesh Mody 
976a55e422eSRasesh Mody 	req->tx_qid = qid;
97786a2265eSRasesh Mody 
97886a2265eSRasesh Mody 	/* Tx */
97986a2265eSRasesh Mody 	req->pbl_addr = pbl_addr;
98086a2265eSRasesh Mody 	req->pbl_size = pbl_size;
9816e4fcea9SRasesh Mody 	req->hw_sb = p_cid->sb_igu_id;
9826e4fcea9SRasesh Mody 	req->sb_index = p_cid->sb_idx;
98386a2265eSRasesh Mody 
984a90c566fSRasesh Mody 	ecore_vf_pf_add_qid(p_hwfn, p_cid);
985a90c566fSRasesh Mody 
98686a2265eSRasesh Mody 	/* add list termination tlv */
98730ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
98886a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
98986a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
99086a2265eSRasesh Mody 
99122d07d93SRasesh Mody 	resp  = &p_iov->pf2vf_reply->queue_start;
99286a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
99386a2265eSRasesh Mody 	if (rc)
99422d07d93SRasesh Mody 		goto exit;
99586a2265eSRasesh Mody 
99622d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
99722d07d93SRasesh Mody 		rc = ECORE_INVAL;
99822d07d93SRasesh Mody 		goto exit;
99922d07d93SRasesh Mody 	}
100086a2265eSRasesh Mody 
100122d07d93SRasesh Mody 	/* Modern PFs provide the actual offsets, while legacy
100222d07d93SRasesh Mody 	 * provided only the queue id.
100322d07d93SRasesh Mody 	 */
100422d07d93SRasesh Mody 	if (!p_iov->b_pre_fp_hsi) {
100522d07d93SRasesh Mody 		*pp_doorbell = (u8 OSAL_IOMEM *)p_hwfn->doorbells +
100622d07d93SRasesh Mody 						resp->offset;
100722d07d93SRasesh Mody 	} else {
1008a55e422eSRasesh Mody 		u8 cid = p_iov->acquire_resp.resc.cid[qid];
100986a2265eSRasesh Mody 
101086a2265eSRasesh Mody 		*pp_doorbell = (u8 OSAL_IOMEM *)p_hwfn->doorbells +
101186a2265eSRasesh Mody 						DB_ADDR_VF(cid, DQ_DEMS_LEGACY);
101286a2265eSRasesh Mody 	}
101386a2265eSRasesh Mody 
101422d07d93SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
101522d07d93SRasesh Mody 		   "Txq[0x%02x]: doorbell at %p [offset 0x%08x]\n",
1016a55e422eSRasesh Mody 		   qid, *pp_doorbell, resp->offset);
101722d07d93SRasesh Mody exit:
101822d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
101922d07d93SRasesh Mody 
102086a2265eSRasesh Mody 	return rc;
102186a2265eSRasesh Mody }
102286a2265eSRasesh Mody 
ecore_vf_pf_txq_stop(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid * p_cid)1023a55e422eSRasesh Mody enum _ecore_status_t ecore_vf_pf_txq_stop(struct ecore_hwfn *p_hwfn,
1024a55e422eSRasesh Mody 					  struct ecore_queue_cid *p_cid)
102586a2265eSRasesh Mody {
102686a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
102786a2265eSRasesh Mody 	struct vfpf_stop_txqs_tlv *req;
102822d07d93SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
102993fce904SRasesh Mody 	enum _ecore_status_t rc;
103086a2265eSRasesh Mody 
103186a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
103286a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_TXQS, sizeof(*req));
103386a2265eSRasesh Mody 
1034a55e422eSRasesh Mody 	req->tx_qid = p_cid->rel.queue_id;
103586a2265eSRasesh Mody 	req->num_txqs = 1;
103686a2265eSRasesh Mody 
1037a90c566fSRasesh Mody 	ecore_vf_pf_add_qid(p_hwfn, p_cid);
1038a90c566fSRasesh Mody 
103986a2265eSRasesh Mody 	/* add list termination tlv */
104030ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
104186a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
104286a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
104386a2265eSRasesh Mody 
104422d07d93SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
104586a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
104686a2265eSRasesh Mody 	if (rc)
104722d07d93SRasesh Mody 		goto exit;
104886a2265eSRasesh Mody 
104922d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
105022d07d93SRasesh Mody 		rc = ECORE_INVAL;
105122d07d93SRasesh Mody 		goto exit;
105222d07d93SRasesh Mody 	}
105322d07d93SRasesh Mody 
105422d07d93SRasesh Mody exit:
105522d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
105686a2265eSRasesh Mody 
105786a2265eSRasesh Mody 	return rc;
105886a2265eSRasesh Mody }
105986a2265eSRasesh Mody 
ecore_vf_pf_rxqs_update(struct ecore_hwfn * p_hwfn,struct ecore_queue_cid ** pp_cid,u8 num_rxqs,u8 comp_cqe_flg,u8 comp_event_flg)106086a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_rxqs_update(struct ecore_hwfn *p_hwfn,
1061a55e422eSRasesh Mody 					     struct ecore_queue_cid **pp_cid,
106286a2265eSRasesh Mody 					     u8 num_rxqs,
1063a55e422eSRasesh Mody 					     u8 comp_cqe_flg,
1064a55e422eSRasesh Mody 					     u8 comp_event_flg)
106586a2265eSRasesh Mody {
106686a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
106786a2265eSRasesh Mody 	struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp;
106886a2265eSRasesh Mody 	struct vfpf_update_rxq_tlv *req;
106993fce904SRasesh Mody 	enum _ecore_status_t rc;
107086a2265eSRasesh Mody 
1071a90c566fSRasesh Mody 	/* Starting with CHANNEL_TLV_QID and the need for additional queue
1072a90c566fSRasesh Mody 	 * information, this API stopped supporting multiple rxqs.
1073a90c566fSRasesh Mody 	 * TODO - remove this and change the API to accept a single queue-cid
1074a90c566fSRasesh Mody 	 * in a follow-up patch.
1075a55e422eSRasesh Mody 	 */
1076a90c566fSRasesh Mody 	if (num_rxqs != 1) {
1077a90c566fSRasesh Mody 		DP_NOTICE(p_hwfn, true,
1078a90c566fSRasesh Mody 			  "VFs can no longer update more than a single queue\n");
1079a55e422eSRasesh Mody 		return ECORE_INVAL;
1080a90c566fSRasesh Mody 	}
1081a55e422eSRasesh Mody 
108286a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
108386a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_UPDATE_RXQ, sizeof(*req));
108486a2265eSRasesh Mody 
1085a55e422eSRasesh Mody 	req->rx_qid = (*pp_cid)->rel.queue_id;
1086a90c566fSRasesh Mody 	req->num_rxqs = 1;
108786a2265eSRasesh Mody 
108886a2265eSRasesh Mody 	if (comp_cqe_flg)
108986a2265eSRasesh Mody 		req->flags |= VFPF_RXQ_UPD_COMPLETE_CQE_FLAG;
109086a2265eSRasesh Mody 	if (comp_event_flg)
109186a2265eSRasesh Mody 		req->flags |= VFPF_RXQ_UPD_COMPLETE_EVENT_FLAG;
109286a2265eSRasesh Mody 
1093a90c566fSRasesh Mody 	ecore_vf_pf_add_qid(p_hwfn, *pp_cid);
1094a90c566fSRasesh Mody 
109586a2265eSRasesh Mody 	/* add list termination tlv */
109630ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
109786a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
109886a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
109986a2265eSRasesh Mody 
110086a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
110186a2265eSRasesh Mody 	if (rc)
110222d07d93SRasesh Mody 		goto exit;
110386a2265eSRasesh Mody 
110422d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
110522d07d93SRasesh Mody 		rc = ECORE_INVAL;
110622d07d93SRasesh Mody 		goto exit;
110722d07d93SRasesh Mody 	}
110822d07d93SRasesh Mody 
110922d07d93SRasesh Mody exit:
111022d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
111186a2265eSRasesh Mody 	return rc;
111286a2265eSRasesh Mody }
111386a2265eSRasesh Mody 
111486a2265eSRasesh Mody enum _ecore_status_t
ecore_vf_pf_vport_start(struct ecore_hwfn * p_hwfn,u8 vport_id,u16 mtu,u8 inner_vlan_removal,enum ecore_tpa_mode tpa_mode,u8 max_buffers_per_cqe,u8 only_untagged)111586a2265eSRasesh Mody ecore_vf_pf_vport_start(struct ecore_hwfn *p_hwfn, u8 vport_id,
111686a2265eSRasesh Mody 			u16 mtu, u8 inner_vlan_removal,
111786a2265eSRasesh Mody 			enum ecore_tpa_mode tpa_mode, u8 max_buffers_per_cqe,
111886a2265eSRasesh Mody 			u8 only_untagged)
111986a2265eSRasesh Mody {
112086a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
112186a2265eSRasesh Mody 	struct vfpf_vport_start_tlv *req;
112222d07d93SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
112393fce904SRasesh Mody 	enum _ecore_status_t rc;
112493fce904SRasesh Mody 	int i;
112586a2265eSRasesh Mody 
112686a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
112786a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_START, sizeof(*req));
112886a2265eSRasesh Mody 
112986a2265eSRasesh Mody 	req->mtu = mtu;
113086a2265eSRasesh Mody 	req->vport_id = vport_id;
113186a2265eSRasesh Mody 	req->inner_vlan_removal = inner_vlan_removal;
113286a2265eSRasesh Mody 	req->tpa_mode = tpa_mode;
113386a2265eSRasesh Mody 	req->max_buffers_per_cqe = max_buffers_per_cqe;
113486a2265eSRasesh Mody 	req->only_untagged = only_untagged;
113586a2265eSRasesh Mody 
113686a2265eSRasesh Mody 	/* status blocks */
11376e4fcea9SRasesh Mody 	for (i = 0; i < p_hwfn->vf_iov_info->acquire_resp.resc.num_sbs; i++) {
11386e4fcea9SRasesh Mody 		struct ecore_sb_info *p_sb = p_hwfn->vf_iov_info->sbs_info[i];
11396e4fcea9SRasesh Mody 
11406e4fcea9SRasesh Mody 		if (p_sb)
11416e4fcea9SRasesh Mody 			req->sb_addr[i] = p_sb->sb_phys;
11426e4fcea9SRasesh Mody 	}
114386a2265eSRasesh Mody 
114486a2265eSRasesh Mody 	/* add list termination tlv */
114530ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
114686a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
114786a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
114886a2265eSRasesh Mody 
114922d07d93SRasesh Mody 	resp  = &p_iov->pf2vf_reply->default_resp;
115086a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
115186a2265eSRasesh Mody 	if (rc)
115222d07d93SRasesh Mody 		goto exit;
115386a2265eSRasesh Mody 
115422d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
115522d07d93SRasesh Mody 		rc = ECORE_INVAL;
115622d07d93SRasesh Mody 		goto exit;
115722d07d93SRasesh Mody 	}
115822d07d93SRasesh Mody 
115922d07d93SRasesh Mody exit:
116022d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
116186a2265eSRasesh Mody 
116286a2265eSRasesh Mody 	return rc;
116386a2265eSRasesh Mody }
116486a2265eSRasesh Mody 
ecore_vf_pf_vport_stop(struct ecore_hwfn * p_hwfn)116586a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_vport_stop(struct ecore_hwfn *p_hwfn)
116686a2265eSRasesh Mody {
116786a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
116886a2265eSRasesh Mody 	struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp;
116993fce904SRasesh Mody 	enum _ecore_status_t rc;
117086a2265eSRasesh Mody 
117186a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
117286a2265eSRasesh Mody 	ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_TEARDOWN,
117386a2265eSRasesh Mody 			 sizeof(struct vfpf_first_tlv));
117486a2265eSRasesh Mody 
117586a2265eSRasesh Mody 	/* add list termination tlv */
117630ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
117786a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
117886a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
117986a2265eSRasesh Mody 
118086a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
118186a2265eSRasesh Mody 	if (rc)
118222d07d93SRasesh Mody 		goto exit;
118386a2265eSRasesh Mody 
118422d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
118522d07d93SRasesh Mody 		rc = ECORE_INVAL;
118622d07d93SRasesh Mody 		goto exit;
118722d07d93SRasesh Mody 	}
118822d07d93SRasesh Mody 
118922d07d93SRasesh Mody exit:
119022d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
119186a2265eSRasesh Mody 
119286a2265eSRasesh Mody 	return rc;
119386a2265eSRasesh Mody }
119486a2265eSRasesh Mody 
119522d07d93SRasesh Mody static bool
ecore_vf_handle_vp_update_is_needed(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_update_params * p_data,u16 tlv)119622d07d93SRasesh Mody ecore_vf_handle_vp_update_is_needed(struct ecore_hwfn *p_hwfn,
119722d07d93SRasesh Mody 				    struct ecore_sp_vport_update_params *p_data,
119822d07d93SRasesh Mody 				    u16 tlv)
119922d07d93SRasesh Mody {
120022d07d93SRasesh Mody 	switch (tlv) {
120122d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_ACTIVATE:
120222d07d93SRasesh Mody 		return !!(p_data->update_vport_active_rx_flg ||
120322d07d93SRasesh Mody 			  p_data->update_vport_active_tx_flg);
120422d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_TX_SWITCH:
120522d07d93SRasesh Mody #ifndef ASIC_ONLY
120622d07d93SRasesh Mody 		/* FPGA doesn't have PVFC and so can't support tx-switching */
120722d07d93SRasesh Mody 		return !!(p_data->update_tx_switching_flg &&
120822d07d93SRasesh Mody 			  !CHIP_REV_IS_FPGA(p_hwfn->p_dev));
120922d07d93SRasesh Mody #else
121022d07d93SRasesh Mody 		return !!p_data->update_tx_switching_flg;
121122d07d93SRasesh Mody #endif
121222d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_VLAN_STRIP:
121322d07d93SRasesh Mody 		return !!p_data->update_inner_vlan_removal_flg;
121422d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN:
121522d07d93SRasesh Mody 		return !!p_data->update_accept_any_vlan_flg;
121622d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_MCAST:
121722d07d93SRasesh Mody 		return !!p_data->update_approx_mcast_flg;
121822d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM:
121922d07d93SRasesh Mody 		return !!(p_data->accept_flags.update_rx_mode_config ||
122022d07d93SRasesh Mody 			  p_data->accept_flags.update_tx_mode_config);
122122d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_RSS:
122222d07d93SRasesh Mody 		return !!p_data->rss_params;
122322d07d93SRasesh Mody 	case CHANNEL_TLV_VPORT_UPDATE_SGE_TPA:
122422d07d93SRasesh Mody 		return !!p_data->sge_tpa_params;
122522d07d93SRasesh Mody 	default:
122622d07d93SRasesh Mody 		DP_INFO(p_hwfn, "Unexpected vport-update TLV[%d] %s\n",
1227520dd992SFerruh Yigit 			tlv, qede_ecore_channel_tlvs_string[tlv]);
122822d07d93SRasesh Mody 		return false;
122922d07d93SRasesh Mody 	}
123022d07d93SRasesh Mody }
123122d07d93SRasesh Mody 
123286a2265eSRasesh Mody static void
ecore_vf_handle_vp_update_tlvs_resp(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_update_params * p_data)123386a2265eSRasesh Mody ecore_vf_handle_vp_update_tlvs_resp(struct ecore_hwfn *p_hwfn,
123486a2265eSRasesh Mody 				    struct ecore_sp_vport_update_params *p_data)
123586a2265eSRasesh Mody {
123686a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
123786a2265eSRasesh Mody 	struct pfvf_def_resp_tlv *p_resp;
123886a2265eSRasesh Mody 	u16 tlv;
123986a2265eSRasesh Mody 
124022d07d93SRasesh Mody 	for (tlv = CHANNEL_TLV_VPORT_UPDATE_ACTIVATE;
124122d07d93SRasesh Mody 	     tlv < CHANNEL_TLV_VPORT_UPDATE_MAX;
124222d07d93SRasesh Mody 	     tlv++) {
124322d07d93SRasesh Mody 		if (!ecore_vf_handle_vp_update_is_needed(p_hwfn, p_data, tlv))
124422d07d93SRasesh Mody 			continue;
124586a2265eSRasesh Mody 
124686a2265eSRasesh Mody 		p_resp = (struct pfvf_def_resp_tlv *)
124786a2265eSRasesh Mody 		    ecore_iov_search_list_tlvs(p_hwfn, p_iov->pf2vf_reply, tlv);
124886a2265eSRasesh Mody 		if (p_resp && p_resp->hdr.status)
124986a2265eSRasesh Mody 			DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
125022d07d93SRasesh Mody 				   "TLV[%d] type %s Configuration %s\n",
1251520dd992SFerruh Yigit 				   tlv, qede_ecore_channel_tlvs_string[tlv],
125222d07d93SRasesh Mody 				   (p_resp && p_resp->hdr.status) ? "succeeded"
125322d07d93SRasesh Mody 								  : "failed");
125486a2265eSRasesh Mody 	}
125586a2265eSRasesh Mody }
125686a2265eSRasesh Mody 
125786a2265eSRasesh Mody enum _ecore_status_t
ecore_vf_pf_vport_update(struct ecore_hwfn * p_hwfn,struct ecore_sp_vport_update_params * p_params)125886a2265eSRasesh Mody ecore_vf_pf_vport_update(struct ecore_hwfn *p_hwfn,
125986a2265eSRasesh Mody 			 struct ecore_sp_vport_update_params *p_params)
126086a2265eSRasesh Mody {
126186a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
126286a2265eSRasesh Mody 	struct vfpf_vport_update_tlv *req;
126386a2265eSRasesh Mody 	struct pfvf_def_resp_tlv *resp;
126486a2265eSRasesh Mody 	u8 update_rx, update_tx;
126586a2265eSRasesh Mody 	u32 resp_size = 0;
126686a2265eSRasesh Mody 	u16 size, tlv;
126793fce904SRasesh Mody 	enum _ecore_status_t rc;
126886a2265eSRasesh Mody 
126986a2265eSRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
127086a2265eSRasesh Mody 	resp_size = sizeof(*resp);
127186a2265eSRasesh Mody 
127286a2265eSRasesh Mody 	update_rx = p_params->update_vport_active_rx_flg;
127386a2265eSRasesh Mody 	update_tx = p_params->update_vport_active_tx_flg;
127486a2265eSRasesh Mody 
127586a2265eSRasesh Mody 	/* clear mailbox and prep header tlv */
127686a2265eSRasesh Mody 	ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_UPDATE, sizeof(*req));
127786a2265eSRasesh Mody 
127886a2265eSRasesh Mody 	/* Prepare extended tlvs */
127986a2265eSRasesh Mody 	if (update_rx || update_tx) {
128022d07d93SRasesh Mody 		struct vfpf_vport_update_activate_tlv *p_act_tlv;
128122d07d93SRasesh Mody 
128286a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_activate_tlv);
128330ecf673SRasesh Mody 		p_act_tlv = ecore_add_tlv(&p_iov->offset,
128486a2265eSRasesh Mody 					  CHANNEL_TLV_VPORT_UPDATE_ACTIVATE,
128586a2265eSRasesh Mody 					  size);
128686a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
128786a2265eSRasesh Mody 
128886a2265eSRasesh Mody 		if (update_rx) {
128986a2265eSRasesh Mody 			p_act_tlv->update_rx = update_rx;
129086a2265eSRasesh Mody 			p_act_tlv->active_rx = p_params->vport_active_rx_flg;
129186a2265eSRasesh Mody 		}
129286a2265eSRasesh Mody 
129386a2265eSRasesh Mody 		if (update_tx) {
129486a2265eSRasesh Mody 			p_act_tlv->update_tx = update_tx;
129586a2265eSRasesh Mody 			p_act_tlv->active_tx = p_params->vport_active_tx_flg;
129686a2265eSRasesh Mody 		}
129786a2265eSRasesh Mody 	}
129886a2265eSRasesh Mody 
129986a2265eSRasesh Mody 	if (p_params->update_inner_vlan_removal_flg) {
130022d07d93SRasesh Mody 		struct vfpf_vport_update_vlan_strip_tlv *p_vlan_tlv;
130122d07d93SRasesh Mody 
130286a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_vlan_strip_tlv);
130330ecf673SRasesh Mody 		p_vlan_tlv = ecore_add_tlv(&p_iov->offset,
130486a2265eSRasesh Mody 					   CHANNEL_TLV_VPORT_UPDATE_VLAN_STRIP,
130586a2265eSRasesh Mody 					   size);
130686a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
130786a2265eSRasesh Mody 
130886a2265eSRasesh Mody 		p_vlan_tlv->remove_vlan = p_params->inner_vlan_removal_flg;
130986a2265eSRasesh Mody 	}
131086a2265eSRasesh Mody 
131186a2265eSRasesh Mody 	if (p_params->update_tx_switching_flg) {
131222d07d93SRasesh Mody 		struct vfpf_vport_update_tx_switch_tlv *p_tx_switch_tlv;
131322d07d93SRasesh Mody 
131486a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_tx_switch_tlv);
131586a2265eSRasesh Mody 		tlv = CHANNEL_TLV_VPORT_UPDATE_TX_SWITCH;
131630ecf673SRasesh Mody 		p_tx_switch_tlv = ecore_add_tlv(&p_iov->offset,
131786a2265eSRasesh Mody 						tlv, size);
131886a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
131986a2265eSRasesh Mody 
132086a2265eSRasesh Mody 		p_tx_switch_tlv->tx_switching = p_params->tx_switching_flg;
132186a2265eSRasesh Mody 	}
132286a2265eSRasesh Mody 
132386a2265eSRasesh Mody 	if (p_params->update_approx_mcast_flg) {
132422d07d93SRasesh Mody 		struct vfpf_vport_update_mcast_bin_tlv *p_mcast_tlv;
132522d07d93SRasesh Mody 
132686a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_mcast_bin_tlv);
132730ecf673SRasesh Mody 		p_mcast_tlv = ecore_add_tlv(&p_iov->offset,
132886a2265eSRasesh Mody 					    CHANNEL_TLV_VPORT_UPDATE_MCAST,
132986a2265eSRasesh Mody 					    size);
133086a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
133186a2265eSRasesh Mody 
133286a2265eSRasesh Mody 		OSAL_MEMCPY(p_mcast_tlv->bins, p_params->bins,
1333413ecf29SHarish Patil 			    sizeof(u32) * ETH_MULTICAST_MAC_BINS_IN_REGS);
133486a2265eSRasesh Mody 	}
133586a2265eSRasesh Mody 
133686a2265eSRasesh Mody 	update_rx = p_params->accept_flags.update_rx_mode_config;
133786a2265eSRasesh Mody 	update_tx = p_params->accept_flags.update_tx_mode_config;
133886a2265eSRasesh Mody 
133986a2265eSRasesh Mody 	if (update_rx || update_tx) {
134022d07d93SRasesh Mody 		struct vfpf_vport_update_accept_param_tlv *p_accept_tlv;
134122d07d93SRasesh Mody 
134286a2265eSRasesh Mody 		tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM;
134386a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_accept_param_tlv);
134430ecf673SRasesh Mody 		p_accept_tlv = ecore_add_tlv(&p_iov->offset, tlv, size);
134586a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
134686a2265eSRasesh Mody 
134786a2265eSRasesh Mody 		if (update_rx) {
134886a2265eSRasesh Mody 			p_accept_tlv->update_rx_mode = update_rx;
134986a2265eSRasesh Mody 			p_accept_tlv->rx_accept_filter =
135086a2265eSRasesh Mody 			    p_params->accept_flags.rx_accept_filter;
135186a2265eSRasesh Mody 		}
135286a2265eSRasesh Mody 
135386a2265eSRasesh Mody 		if (update_tx) {
135486a2265eSRasesh Mody 			p_accept_tlv->update_tx_mode = update_tx;
135586a2265eSRasesh Mody 			p_accept_tlv->tx_accept_filter =
135686a2265eSRasesh Mody 			    p_params->accept_flags.tx_accept_filter;
135786a2265eSRasesh Mody 		}
135886a2265eSRasesh Mody 	}
135986a2265eSRasesh Mody 
136086a2265eSRasesh Mody 	if (p_params->rss_params) {
136186a2265eSRasesh Mody 		struct ecore_rss_params *rss_params = p_params->rss_params;
136222d07d93SRasesh Mody 		struct vfpf_vport_update_rss_tlv *p_rss_tlv;
136369d7ba88SRasesh Mody 		int i, table_size;
136486a2265eSRasesh Mody 
136586a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_rss_tlv);
136630ecf673SRasesh Mody 		p_rss_tlv = ecore_add_tlv(&p_iov->offset,
136786a2265eSRasesh Mody 					  CHANNEL_TLV_VPORT_UPDATE_RSS, size);
136886a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
136986a2265eSRasesh Mody 
137086a2265eSRasesh Mody 		if (rss_params->update_rss_config)
137186a2265eSRasesh Mody 			p_rss_tlv->update_rss_flags |=
137286a2265eSRasesh Mody 			    VFPF_UPDATE_RSS_CONFIG_FLAG;
137386a2265eSRasesh Mody 		if (rss_params->update_rss_capabilities)
137486a2265eSRasesh Mody 			p_rss_tlv->update_rss_flags |=
137586a2265eSRasesh Mody 			    VFPF_UPDATE_RSS_CAPS_FLAG;
137686a2265eSRasesh Mody 		if (rss_params->update_rss_ind_table)
137786a2265eSRasesh Mody 			p_rss_tlv->update_rss_flags |=
137886a2265eSRasesh Mody 			    VFPF_UPDATE_RSS_IND_TABLE_FLAG;
137986a2265eSRasesh Mody 		if (rss_params->update_rss_key)
138086a2265eSRasesh Mody 			p_rss_tlv->update_rss_flags |= VFPF_UPDATE_RSS_KEY_FLAG;
138186a2265eSRasesh Mody 
138286a2265eSRasesh Mody 		p_rss_tlv->rss_enable = rss_params->rss_enable;
138386a2265eSRasesh Mody 		p_rss_tlv->rss_caps = rss_params->rss_caps;
138486a2265eSRasesh Mody 		p_rss_tlv->rss_table_size_log = rss_params->rss_table_size_log;
138569d7ba88SRasesh Mody 
138669d7ba88SRasesh Mody 		table_size = OSAL_MIN_T(int, T_ETH_INDIRECTION_TABLE_SIZE,
138769d7ba88SRasesh Mody 					1 << p_rss_tlv->rss_table_size_log);
138869d7ba88SRasesh Mody 		for (i = 0; i < table_size; i++) {
138969d7ba88SRasesh Mody 			struct ecore_queue_cid *p_queue;
139069d7ba88SRasesh Mody 
139169d7ba88SRasesh Mody 			p_queue = rss_params->rss_ind_table[i];
139269d7ba88SRasesh Mody 			p_rss_tlv->rss_ind_table[i] = p_queue->rel.queue_id;
139369d7ba88SRasesh Mody 		}
139469d7ba88SRasesh Mody 
139586a2265eSRasesh Mody 		OSAL_MEMCPY(p_rss_tlv->rss_key, rss_params->rss_key,
139686a2265eSRasesh Mody 			    sizeof(rss_params->rss_key));
139786a2265eSRasesh Mody 	}
139886a2265eSRasesh Mody 
139986a2265eSRasesh Mody 	if (p_params->update_accept_any_vlan_flg) {
140022d07d93SRasesh Mody 		struct vfpf_vport_update_accept_any_vlan_tlv *p_any_vlan_tlv;
140122d07d93SRasesh Mody 
140286a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_accept_any_vlan_tlv);
140386a2265eSRasesh Mody 		tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN;
140430ecf673SRasesh Mody 		p_any_vlan_tlv = ecore_add_tlv(&p_iov->offset, tlv, size);
140586a2265eSRasesh Mody 
140686a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
140786a2265eSRasesh Mody 		p_any_vlan_tlv->accept_any_vlan = p_params->accept_any_vlan;
140886a2265eSRasesh Mody 		p_any_vlan_tlv->update_accept_any_vlan_flg =
140986a2265eSRasesh Mody 		    p_params->update_accept_any_vlan_flg;
141086a2265eSRasesh Mody 	}
141186a2265eSRasesh Mody 
141286a2265eSRasesh Mody 	if (p_params->sge_tpa_params) {
141322d07d93SRasesh Mody 		struct ecore_sge_tpa_params *sge_tpa_params;
141422d07d93SRasesh Mody 		struct vfpf_vport_update_sge_tpa_tlv *p_sge_tpa_tlv;
141586a2265eSRasesh Mody 
141622d07d93SRasesh Mody 		sge_tpa_params = p_params->sge_tpa_params;
141786a2265eSRasesh Mody 		size = sizeof(struct vfpf_vport_update_sge_tpa_tlv);
141830ecf673SRasesh Mody 		p_sge_tpa_tlv = ecore_add_tlv(&p_iov->offset,
141986a2265eSRasesh Mody 					      CHANNEL_TLV_VPORT_UPDATE_SGE_TPA,
142086a2265eSRasesh Mody 					      size);
142186a2265eSRasesh Mody 		resp_size += sizeof(struct pfvf_def_resp_tlv);
142286a2265eSRasesh Mody 
142386a2265eSRasesh Mody 		if (sge_tpa_params->update_tpa_en_flg)
142486a2265eSRasesh Mody 			p_sge_tpa_tlv->update_sge_tpa_flags |=
142586a2265eSRasesh Mody 			    VFPF_UPDATE_TPA_EN_FLAG;
142686a2265eSRasesh Mody 		if (sge_tpa_params->update_tpa_param_flg)
142786a2265eSRasesh Mody 			p_sge_tpa_tlv->update_sge_tpa_flags |=
142886a2265eSRasesh Mody 			    VFPF_UPDATE_TPA_PARAM_FLAG;
142986a2265eSRasesh Mody 
143086a2265eSRasesh Mody 		if (sge_tpa_params->tpa_ipv4_en_flg)
143186a2265eSRasesh Mody 			p_sge_tpa_tlv->sge_tpa_flags |= VFPF_TPA_IPV4_EN_FLAG;
143286a2265eSRasesh Mody 		if (sge_tpa_params->tpa_ipv6_en_flg)
143386a2265eSRasesh Mody 			p_sge_tpa_tlv->sge_tpa_flags |= VFPF_TPA_IPV6_EN_FLAG;
143486a2265eSRasesh Mody 		if (sge_tpa_params->tpa_pkt_split_flg)
143586a2265eSRasesh Mody 			p_sge_tpa_tlv->sge_tpa_flags |= VFPF_TPA_PKT_SPLIT_FLAG;
143686a2265eSRasesh Mody 		if (sge_tpa_params->tpa_hdr_data_split_flg)
143786a2265eSRasesh Mody 			p_sge_tpa_tlv->sge_tpa_flags |=
143886a2265eSRasesh Mody 			    VFPF_TPA_HDR_DATA_SPLIT_FLAG;
143986a2265eSRasesh Mody 		if (sge_tpa_params->tpa_gro_consistent_flg)
144086a2265eSRasesh Mody 			p_sge_tpa_tlv->sge_tpa_flags |=
144186a2265eSRasesh Mody 			    VFPF_TPA_GRO_CONSIST_FLAG;
144292bed231SHarish Patil 		if (sge_tpa_params->tpa_ipv4_tunn_en_flg)
144392bed231SHarish Patil 			p_sge_tpa_tlv->sge_tpa_flags |=
144492bed231SHarish Patil 			    VFPF_TPA_TUNN_IPV4_EN_FLAG;
144592bed231SHarish Patil 		if (sge_tpa_params->tpa_ipv6_tunn_en_flg)
144692bed231SHarish Patil 			p_sge_tpa_tlv->sge_tpa_flags |=
144792bed231SHarish Patil 			    VFPF_TPA_TUNN_IPV6_EN_FLAG;
144886a2265eSRasesh Mody 
144986a2265eSRasesh Mody 		p_sge_tpa_tlv->tpa_max_aggs_num =
145086a2265eSRasesh Mody 		    sge_tpa_params->tpa_max_aggs_num;
145186a2265eSRasesh Mody 		p_sge_tpa_tlv->tpa_max_size = sge_tpa_params->tpa_max_size;
145286a2265eSRasesh Mody 		p_sge_tpa_tlv->tpa_min_size_to_start =
145386a2265eSRasesh Mody 		    sge_tpa_params->tpa_min_size_to_start;
145486a2265eSRasesh Mody 		p_sge_tpa_tlv->tpa_min_size_to_cont =
145586a2265eSRasesh Mody 		    sge_tpa_params->tpa_min_size_to_cont;
145686a2265eSRasesh Mody 
145786a2265eSRasesh Mody 		p_sge_tpa_tlv->max_buffers_per_cqe =
145886a2265eSRasesh Mody 		    sge_tpa_params->max_buffers_per_cqe;
145986a2265eSRasesh Mody 	}
146086a2265eSRasesh Mody 
146186a2265eSRasesh Mody 	/* add list termination tlv */
146230ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
146386a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
146486a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
146586a2265eSRasesh Mody 
146686a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, resp_size);
146786a2265eSRasesh Mody 	if (rc)
146822d07d93SRasesh Mody 		goto exit;
146986a2265eSRasesh Mody 
147022d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
147122d07d93SRasesh Mody 		rc = ECORE_INVAL;
147222d07d93SRasesh Mody 		goto exit;
147322d07d93SRasesh Mody 	}
147486a2265eSRasesh Mody 
147586a2265eSRasesh Mody 	ecore_vf_handle_vp_update_tlvs_resp(p_hwfn, p_params);
147686a2265eSRasesh Mody 
147722d07d93SRasesh Mody exit:
147822d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
147922d07d93SRasesh Mody 
148086a2265eSRasesh Mody 	return rc;
148186a2265eSRasesh Mody }
148286a2265eSRasesh Mody 
ecore_vf_pf_reset(struct ecore_hwfn * p_hwfn)148386a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_reset(struct ecore_hwfn *p_hwfn)
148486a2265eSRasesh Mody {
148586a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
148622d07d93SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
148786a2265eSRasesh Mody 	struct vfpf_first_tlv *req;
148893fce904SRasesh Mody 	enum _ecore_status_t rc;
148986a2265eSRasesh Mody 
149086a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
149186a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_CLOSE, sizeof(*req));
149286a2265eSRasesh Mody 
149386a2265eSRasesh Mody 	/* add list termination tlv */
149430ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
149586a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
149686a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
149786a2265eSRasesh Mody 
149822d07d93SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
149986a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
150086a2265eSRasesh Mody 	if (rc)
150122d07d93SRasesh Mody 		goto exit;
150286a2265eSRasesh Mody 
150322d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
150422d07d93SRasesh Mody 		rc = ECORE_AGAIN;
150522d07d93SRasesh Mody 		goto exit;
150622d07d93SRasesh Mody 	}
150786a2265eSRasesh Mody 
150886a2265eSRasesh Mody 	p_hwfn->b_int_enabled = 0;
150986a2265eSRasesh Mody 
151022d07d93SRasesh Mody exit:
151122d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
151222d07d93SRasesh Mody 
151322d07d93SRasesh Mody 	return rc;
151486a2265eSRasesh Mody }
151586a2265eSRasesh Mody 
ecore_vf_pf_filter_mcast(struct ecore_hwfn * p_hwfn,struct ecore_filter_mcast * p_filter_cmd)151686a2265eSRasesh Mody void ecore_vf_pf_filter_mcast(struct ecore_hwfn *p_hwfn,
151786a2265eSRasesh Mody 			      struct ecore_filter_mcast *p_filter_cmd)
151886a2265eSRasesh Mody {
151986a2265eSRasesh Mody 	struct ecore_sp_vport_update_params sp_params;
152086a2265eSRasesh Mody 	int i;
152186a2265eSRasesh Mody 
152286a2265eSRasesh Mody 	OSAL_MEMSET(&sp_params, 0, sizeof(sp_params));
152386a2265eSRasesh Mody 	sp_params.update_approx_mcast_flg = 1;
152486a2265eSRasesh Mody 
152586a2265eSRasesh Mody 	if (p_filter_cmd->opcode == ECORE_FILTER_ADD) {
152686a2265eSRasesh Mody 		for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) {
152786a2265eSRasesh Mody 			u32 bit;
152886a2265eSRasesh Mody 
152986a2265eSRasesh Mody 			bit = ecore_mcast_bin_from_mac(p_filter_cmd->mac[i]);
1530413ecf29SHarish Patil 			sp_params.bins[bit / 32] |= 1 << (bit % 32);
153186a2265eSRasesh Mody 		}
153286a2265eSRasesh Mody 	}
153386a2265eSRasesh Mody 
153486a2265eSRasesh Mody 	ecore_vf_pf_vport_update(p_hwfn, &sp_params);
153586a2265eSRasesh Mody }
153686a2265eSRasesh Mody 
ecore_vf_pf_filter_ucast(struct ecore_hwfn * p_hwfn,struct ecore_filter_ucast * p_ucast)153786a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_filter_ucast(struct ecore_hwfn *p_hwfn,
153886a2265eSRasesh Mody 					      struct ecore_filter_ucast
153986a2265eSRasesh Mody 					      *p_ucast)
154086a2265eSRasesh Mody {
154186a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
154286a2265eSRasesh Mody 	struct vfpf_ucast_filter_tlv *req;
154322d07d93SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
154493fce904SRasesh Mody 	enum _ecore_status_t rc;
154586a2265eSRasesh Mody 
154686a2265eSRasesh Mody 	/* Sanitize */
154786a2265eSRasesh Mody 	if (p_ucast->opcode == ECORE_FILTER_MOVE) {
154886a2265eSRasesh Mody 		DP_NOTICE(p_hwfn, true,
154986a2265eSRasesh Mody 			  "VFs don't support Moving of filters\n");
155086a2265eSRasesh Mody 		return ECORE_INVAL;
155186a2265eSRasesh Mody 	}
155286a2265eSRasesh Mody 
155386a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
155486a2265eSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_UCAST_FILTER, sizeof(*req));
155586a2265eSRasesh Mody 	req->opcode = (u8)p_ucast->opcode;
155686a2265eSRasesh Mody 	req->type = (u8)p_ucast->type;
155786a2265eSRasesh Mody 	OSAL_MEMCPY(req->mac, p_ucast->mac, ETH_ALEN);
155886a2265eSRasesh Mody 	req->vlan = p_ucast->vlan;
155986a2265eSRasesh Mody 
156086a2265eSRasesh Mody 	/* add list termination tlv */
156130ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
156286a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
156386a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
156486a2265eSRasesh Mody 
156522d07d93SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
156686a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
156786a2265eSRasesh Mody 	if (rc)
156822d07d93SRasesh Mody 		goto exit;
156922d07d93SRasesh Mody 
157022d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
157122d07d93SRasesh Mody 		rc = ECORE_AGAIN;
157222d07d93SRasesh Mody 		goto exit;
157322d07d93SRasesh Mody 	}
157422d07d93SRasesh Mody 
157522d07d93SRasesh Mody exit:
157622d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
157722d07d93SRasesh Mody 
157886a2265eSRasesh Mody 	return rc;
157986a2265eSRasesh Mody }
158086a2265eSRasesh Mody 
ecore_vf_pf_int_cleanup(struct ecore_hwfn * p_hwfn)158186a2265eSRasesh Mody enum _ecore_status_t ecore_vf_pf_int_cleanup(struct ecore_hwfn *p_hwfn)
158286a2265eSRasesh Mody {
158386a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
158486a2265eSRasesh Mody 	struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp;
158593fce904SRasesh Mody 	enum _ecore_status_t rc;
158686a2265eSRasesh Mody 
158786a2265eSRasesh Mody 	/* clear mailbox and prep first tlv */
158886a2265eSRasesh Mody 	ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_INT_CLEANUP,
158986a2265eSRasesh Mody 			 sizeof(struct vfpf_first_tlv));
159086a2265eSRasesh Mody 
159186a2265eSRasesh Mody 	/* add list termination tlv */
159230ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
159386a2265eSRasesh Mody 		      CHANNEL_TLV_LIST_END,
159486a2265eSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
159586a2265eSRasesh Mody 
159686a2265eSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
159786a2265eSRasesh Mody 	if (rc)
159822d07d93SRasesh Mody 		goto exit;
159922d07d93SRasesh Mody 
160022d07d93SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS) {
160122d07d93SRasesh Mody 		rc = ECORE_INVAL;
160222d07d93SRasesh Mody 		goto exit;
160322d07d93SRasesh Mody 	}
160422d07d93SRasesh Mody 
160522d07d93SRasesh Mody exit:
160622d07d93SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
160722d07d93SRasesh Mody 
160886a2265eSRasesh Mody 	return rc;
160922d07d93SRasesh Mody }
161086a2265eSRasesh Mody 
ecore_vf_pf_get_coalesce(struct ecore_hwfn * p_hwfn,u16 * p_coal,struct ecore_queue_cid * p_cid)1611823a84aaSRasesh Mody enum _ecore_status_t ecore_vf_pf_get_coalesce(struct ecore_hwfn *p_hwfn,
1612823a84aaSRasesh Mody 					      u16 *p_coal,
1613823a84aaSRasesh Mody 					      struct ecore_queue_cid *p_cid)
1614823a84aaSRasesh Mody {
1615823a84aaSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1616823a84aaSRasesh Mody 	struct pfvf_read_coal_resp_tlv *resp;
1617823a84aaSRasesh Mody 	struct vfpf_read_coal_req_tlv *req;
1618823a84aaSRasesh Mody 	enum _ecore_status_t rc;
1619823a84aaSRasesh Mody 
1620823a84aaSRasesh Mody 	/* clear mailbox and prep header tlv */
1621823a84aaSRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_COALESCE_READ,
1622823a84aaSRasesh Mody 			       sizeof(*req));
1623823a84aaSRasesh Mody 	req->qid = p_cid->rel.queue_id;
1624823a84aaSRasesh Mody 	req->is_rx = p_cid->b_is_rx ? 1 : 0;
1625823a84aaSRasesh Mody 
1626823a84aaSRasesh Mody 	ecore_add_tlv(&p_iov->offset, CHANNEL_TLV_LIST_END,
1627823a84aaSRasesh Mody 		      sizeof(struct channel_list_end_tlv));
1628823a84aaSRasesh Mody 	resp = &p_iov->pf2vf_reply->read_coal_resp;
1629823a84aaSRasesh Mody 
1630823a84aaSRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
1631823a84aaSRasesh Mody 	if (rc != ECORE_SUCCESS)
1632823a84aaSRasesh Mody 		goto exit;
1633823a84aaSRasesh Mody 
1634823a84aaSRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS)
1635823a84aaSRasesh Mody 		goto exit;
1636823a84aaSRasesh Mody 
1637823a84aaSRasesh Mody 	*p_coal = resp->coal;
1638823a84aaSRasesh Mody exit:
1639823a84aaSRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
1640823a84aaSRasesh Mody 
1641823a84aaSRasesh Mody 	return rc;
1642823a84aaSRasesh Mody }
1643823a84aaSRasesh Mody 
16446b8962e0SRasesh Mody enum _ecore_status_t
ecore_vf_pf_set_coalesce(struct ecore_hwfn * p_hwfn,u16 rx_coal,u16 tx_coal,struct ecore_queue_cid * p_cid)16456b8962e0SRasesh Mody ecore_vf_pf_set_coalesce(struct ecore_hwfn *p_hwfn, u16 rx_coal, u16 tx_coal,
16466b8962e0SRasesh Mody 			 struct ecore_queue_cid     *p_cid)
16476b8962e0SRasesh Mody {
16486b8962e0SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
16496b8962e0SRasesh Mody 	struct vfpf_update_coalesce *req;
16506b8962e0SRasesh Mody 	struct pfvf_def_resp_tlv *resp;
16516b8962e0SRasesh Mody 	enum _ecore_status_t rc;
16526b8962e0SRasesh Mody 
16536b8962e0SRasesh Mody 	/* clear mailbox and prep header tlv */
16546b8962e0SRasesh Mody 	req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_COALESCE_UPDATE,
16556b8962e0SRasesh Mody 			       sizeof(*req));
16566b8962e0SRasesh Mody 
16576b8962e0SRasesh Mody 	req->rx_coal = rx_coal;
16586b8962e0SRasesh Mody 	req->tx_coal = tx_coal;
16596b8962e0SRasesh Mody 	req->qid = p_cid->rel.queue_id;
16606b8962e0SRasesh Mody 
16616b8962e0SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
16626b8962e0SRasesh Mody 		   "Setting coalesce rx_coal = %d, tx_coal = %d at queue = %d\n",
16636b8962e0SRasesh Mody 		   rx_coal, tx_coal, req->qid);
16646b8962e0SRasesh Mody 
16656b8962e0SRasesh Mody 	/* add list termination tlv */
166630ecf673SRasesh Mody 	ecore_add_tlv(&p_iov->offset, CHANNEL_TLV_LIST_END,
16676b8962e0SRasesh Mody 		      sizeof(struct channel_list_end_tlv));
16686b8962e0SRasesh Mody 
16696b8962e0SRasesh Mody 	resp = &p_iov->pf2vf_reply->default_resp;
16706b8962e0SRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp));
16716b8962e0SRasesh Mody 
16726b8962e0SRasesh Mody 	if (rc != ECORE_SUCCESS)
16736b8962e0SRasesh Mody 		goto exit;
16746b8962e0SRasesh Mody 
16756b8962e0SRasesh Mody 	if (resp->hdr.status != PFVF_STATUS_SUCCESS)
16766b8962e0SRasesh Mody 		goto exit;
16776b8962e0SRasesh Mody 
16786b8962e0SRasesh Mody 	p_hwfn->p_dev->rx_coalesce_usecs = rx_coal;
16796b8962e0SRasesh Mody 	p_hwfn->p_dev->tx_coalesce_usecs = tx_coal;
16806b8962e0SRasesh Mody 
16816b8962e0SRasesh Mody exit:
16826b8962e0SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
16836b8962e0SRasesh Mody 	return rc;
16846b8962e0SRasesh Mody }
16856b8962e0SRasesh Mody 
1686d121a6b5SRasesh Mody enum _ecore_status_t
ecore_vf_pf_update_mtu(struct ecore_hwfn * p_hwfn,u16 mtu)1687d121a6b5SRasesh Mody ecore_vf_pf_update_mtu(struct ecore_hwfn *p_hwfn, u16 mtu)
1688d121a6b5SRasesh Mody {
1689d121a6b5SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
1690d121a6b5SRasesh Mody 	struct vfpf_update_mtu_tlv *p_req;
1691d121a6b5SRasesh Mody 	struct pfvf_def_resp_tlv *p_resp;
1692d121a6b5SRasesh Mody 	enum _ecore_status_t rc;
1693d121a6b5SRasesh Mody 
1694d121a6b5SRasesh Mody 	if (!mtu)
1695d121a6b5SRasesh Mody 		return ECORE_INVAL;
1696d121a6b5SRasesh Mody 
1697d121a6b5SRasesh Mody 	/* clear mailbox and prep header tlv */
1698d121a6b5SRasesh Mody 	p_req = ecore_vf_pf_prep(p_hwfn, CHANNEL_TLV_UPDATE_MTU,
1699d121a6b5SRasesh Mody 				 sizeof(*p_req));
1700d121a6b5SRasesh Mody 	p_req->mtu = mtu;
1701d121a6b5SRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
1702d121a6b5SRasesh Mody 		   "Requesting MTU update to %d\n", mtu);
1703d121a6b5SRasesh Mody 
1704d121a6b5SRasesh Mody 	/* add list termination tlv */
1705d121a6b5SRasesh Mody 	ecore_add_tlv(&p_iov->offset,
1706d121a6b5SRasesh Mody 		      CHANNEL_TLV_LIST_END,
1707d121a6b5SRasesh Mody 		      sizeof(struct channel_list_end_tlv));
1708d121a6b5SRasesh Mody 
1709d121a6b5SRasesh Mody 	p_resp = &p_iov->pf2vf_reply->default_resp;
1710d121a6b5SRasesh Mody 	rc = ecore_send_msg2pf(p_hwfn, &p_resp->hdr.status, sizeof(*p_resp));
1711d121a6b5SRasesh Mody 	if (p_resp->hdr.status == PFVF_STATUS_NOT_SUPPORTED)
1712d121a6b5SRasesh Mody 		rc = ECORE_INVAL;
1713d121a6b5SRasesh Mody 
1714d121a6b5SRasesh Mody 	ecore_vf_pf_req_end(p_hwfn, rc);
1715d121a6b5SRasesh Mody 
1716d121a6b5SRasesh Mody 	return rc;
1717d121a6b5SRasesh Mody }
1718d121a6b5SRasesh Mody 
ecore_vf_get_igu_sb_id(struct ecore_hwfn * p_hwfn,u16 sb_id)171922d07d93SRasesh Mody u16 ecore_vf_get_igu_sb_id(struct ecore_hwfn *p_hwfn,
172022d07d93SRasesh Mody 			   u16               sb_id)
172122d07d93SRasesh Mody {
172222d07d93SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
172386a2265eSRasesh Mody 
172422d07d93SRasesh Mody 	if (!p_iov) {
172522d07d93SRasesh Mody 		DP_NOTICE(p_hwfn, true, "vf_sriov_info isn't initialized\n");
172622d07d93SRasesh Mody 		return 0;
172722d07d93SRasesh Mody 	}
172822d07d93SRasesh Mody 
172922d07d93SRasesh Mody 	return p_iov->acquire_resp.resc.hw_sbs[sb_id].hw_sb_id;
173086a2265eSRasesh Mody }
173186a2265eSRasesh Mody 
ecore_vf_set_sb_info(struct ecore_hwfn * p_hwfn,u16 sb_id,struct ecore_sb_info * p_sb)17326e4fcea9SRasesh Mody void ecore_vf_set_sb_info(struct ecore_hwfn *p_hwfn,
17336e4fcea9SRasesh Mody 			  u16 sb_id, struct ecore_sb_info *p_sb)
17346e4fcea9SRasesh Mody {
17356e4fcea9SRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
17366e4fcea9SRasesh Mody 
17376e4fcea9SRasesh Mody 	if (!p_iov) {
17386e4fcea9SRasesh Mody 		DP_NOTICE(p_hwfn, true, "vf_sriov_info isn't initialized\n");
17396e4fcea9SRasesh Mody 		return;
17406e4fcea9SRasesh Mody 	}
17416e4fcea9SRasesh Mody 
17426e4fcea9SRasesh Mody 	if (sb_id >= PFVF_MAX_SBS_PER_VF) {
17436e4fcea9SRasesh Mody 		DP_NOTICE(p_hwfn, true, "Can't configure SB %04x\n", sb_id);
17446e4fcea9SRasesh Mody 		return;
17456e4fcea9SRasesh Mody 	}
17466e4fcea9SRasesh Mody 
17476e4fcea9SRasesh Mody 	p_iov->sbs_info[sb_id] = p_sb;
17486e4fcea9SRasesh Mody }
17496e4fcea9SRasesh Mody 
ecore_vf_read_bulletin(struct ecore_hwfn * p_hwfn,u8 * p_change)175086a2265eSRasesh Mody enum _ecore_status_t ecore_vf_read_bulletin(struct ecore_hwfn *p_hwfn,
175186a2265eSRasesh Mody 					    u8 *p_change)
175286a2265eSRasesh Mody {
175386a2265eSRasesh Mody 	struct ecore_vf_iov *p_iov = p_hwfn->vf_iov_info;
175422d07d93SRasesh Mody 	struct ecore_bulletin_content shadow;
175522d07d93SRasesh Mody 	u32 crc, crc_size;
175686a2265eSRasesh Mody 
175722d07d93SRasesh Mody 	crc_size = sizeof(p_iov->bulletin.p_virt->crc);
175886a2265eSRasesh Mody 	*p_change = 0;
175986a2265eSRasesh Mody 
176086a2265eSRasesh Mody 	/* Need to guarantee PF is not in the middle of writing it */
176186a2265eSRasesh Mody 	OSAL_MEMCPY(&shadow, p_iov->bulletin.p_virt, p_iov->bulletin.size);
176286a2265eSRasesh Mody 
176386a2265eSRasesh Mody 	/* If version did not update, no need to do anything */
176486a2265eSRasesh Mody 	if (shadow.version == p_iov->bulletin_shadow.version)
176586a2265eSRasesh Mody 		return ECORE_SUCCESS;
176686a2265eSRasesh Mody 
176786a2265eSRasesh Mody 	/* Verify the bulletin we see is valid */
176803637634SRasesh Mody 	crc = OSAL_CRC32(0, (u8 *)&shadow + crc_size,
176986a2265eSRasesh Mody 			 p_iov->bulletin.size - crc_size);
177086a2265eSRasesh Mody 	if (crc != shadow.crc)
177186a2265eSRasesh Mody 		return ECORE_AGAIN;
177286a2265eSRasesh Mody 
177386a2265eSRasesh Mody 	/* Set the shadow bulletin and process it */
177486a2265eSRasesh Mody 	OSAL_MEMCPY(&p_iov->bulletin_shadow, &shadow, p_iov->bulletin.size);
177586a2265eSRasesh Mody 
177686a2265eSRasesh Mody 	DP_VERBOSE(p_hwfn, ECORE_MSG_IOV,
177786a2265eSRasesh Mody 		   "Read a bulletin update %08x\n", shadow.version);
177886a2265eSRasesh Mody 
177986a2265eSRasesh Mody 	*p_change = 1;
178086a2265eSRasesh Mody 
178186a2265eSRasesh Mody 	return ECORE_SUCCESS;
178286a2265eSRasesh Mody }
178386a2265eSRasesh Mody 
__ecore_vf_get_link_params(struct ecore_mcp_link_params * p_params,struct ecore_bulletin_content * p_bulletin)178430ecf673SRasesh Mody void __ecore_vf_get_link_params(struct ecore_mcp_link_params *p_params,
178586a2265eSRasesh Mody 				struct ecore_bulletin_content *p_bulletin)
178686a2265eSRasesh Mody {
178786a2265eSRasesh Mody 	OSAL_MEMSET(p_params, 0, sizeof(*p_params));
178886a2265eSRasesh Mody 
178986a2265eSRasesh Mody 	p_params->speed.autoneg = p_bulletin->req_autoneg;
179086a2265eSRasesh Mody 	p_params->speed.advertised_speeds = p_bulletin->req_adv_speed;
179186a2265eSRasesh Mody 	p_params->speed.forced_speed = p_bulletin->req_forced_speed;
179286a2265eSRasesh Mody 	p_params->pause.autoneg = p_bulletin->req_autoneg_pause;
179386a2265eSRasesh Mody 	p_params->pause.forced_rx = p_bulletin->req_forced_rx;
179486a2265eSRasesh Mody 	p_params->pause.forced_tx = p_bulletin->req_forced_tx;
179586a2265eSRasesh Mody 	p_params->loopback_mode = p_bulletin->req_loopback;
179686a2265eSRasesh Mody }
179786a2265eSRasesh Mody 
ecore_vf_get_link_params(struct ecore_hwfn * p_hwfn,struct ecore_mcp_link_params * params)179886a2265eSRasesh Mody void ecore_vf_get_link_params(struct ecore_hwfn *p_hwfn,
179986a2265eSRasesh Mody 			      struct ecore_mcp_link_params *params)
180086a2265eSRasesh Mody {
180130ecf673SRasesh Mody 	__ecore_vf_get_link_params(params,
180286a2265eSRasesh Mody 				   &p_hwfn->vf_iov_info->bulletin_shadow);
180386a2265eSRasesh Mody }
180486a2265eSRasesh Mody 
__ecore_vf_get_link_state(struct ecore_mcp_link_state * p_link,struct ecore_bulletin_content * p_bulletin)180530ecf673SRasesh Mody void __ecore_vf_get_link_state(struct ecore_mcp_link_state *p_link,
180686a2265eSRasesh Mody 			       struct ecore_bulletin_content *p_bulletin)
180786a2265eSRasesh Mody {
180886a2265eSRasesh Mody 	OSAL_MEMSET(p_link, 0, sizeof(*p_link));
180986a2265eSRasesh Mody 
181086a2265eSRasesh Mody 	p_link->link_up = p_bulletin->link_up;
181186a2265eSRasesh Mody 	p_link->speed = p_bulletin->speed;
181286a2265eSRasesh Mody 	p_link->full_duplex = p_bulletin->full_duplex;
181386a2265eSRasesh Mody 	p_link->an = p_bulletin->autoneg;
181486a2265eSRasesh Mody 	p_link->an_complete = p_bulletin->autoneg_complete;
181586a2265eSRasesh Mody 	p_link->parallel_detection = p_bulletin->parallel_detection;
181686a2265eSRasesh Mody 	p_link->pfc_enabled = p_bulletin->pfc_enabled;
181786a2265eSRasesh Mody 	p_link->partner_adv_speed = p_bulletin->partner_adv_speed;
181886a2265eSRasesh Mody 	p_link->partner_tx_flow_ctrl_en = p_bulletin->partner_tx_flow_ctrl_en;
181986a2265eSRasesh Mody 	p_link->partner_rx_flow_ctrl_en = p_bulletin->partner_rx_flow_ctrl_en;
182086a2265eSRasesh Mody 	p_link->partner_adv_pause = p_bulletin->partner_adv_pause;
182186a2265eSRasesh Mody 	p_link->sfp_tx_fault = p_bulletin->sfp_tx_fault;
182286a2265eSRasesh Mody }
182386a2265eSRasesh Mody 
ecore_vf_get_link_state(struct ecore_hwfn * p_hwfn,struct ecore_mcp_link_state * link)182486a2265eSRasesh Mody void ecore_vf_get_link_state(struct ecore_hwfn *p_hwfn,
182586a2265eSRasesh Mody 			     struct ecore_mcp_link_state *link)
182686a2265eSRasesh Mody {
182730ecf673SRasesh Mody 	__ecore_vf_get_link_state(link,
182886a2265eSRasesh Mody 				  &p_hwfn->vf_iov_info->bulletin_shadow);
182986a2265eSRasesh Mody }
183086a2265eSRasesh Mody 
__ecore_vf_get_link_caps(struct ecore_mcp_link_capabilities * p_link_caps,struct ecore_bulletin_content * p_bulletin)183130ecf673SRasesh Mody void __ecore_vf_get_link_caps(struct ecore_mcp_link_capabilities *p_link_caps,
183286a2265eSRasesh Mody 			      struct ecore_bulletin_content *p_bulletin)
183386a2265eSRasesh Mody {
183486a2265eSRasesh Mody 	OSAL_MEMSET(p_link_caps, 0, sizeof(*p_link_caps));
183586a2265eSRasesh Mody 	p_link_caps->speed_capabilities = p_bulletin->capability_speed;
183686a2265eSRasesh Mody }
183786a2265eSRasesh Mody 
ecore_vf_get_link_caps(struct ecore_hwfn * p_hwfn,struct ecore_mcp_link_capabilities * p_link_caps)183886a2265eSRasesh Mody void ecore_vf_get_link_caps(struct ecore_hwfn *p_hwfn,
183986a2265eSRasesh Mody 			    struct ecore_mcp_link_capabilities *p_link_caps)
184086a2265eSRasesh Mody {
184130ecf673SRasesh Mody 	__ecore_vf_get_link_caps(p_link_caps,
184286a2265eSRasesh Mody 				 &p_hwfn->vf_iov_info->bulletin_shadow);
184386a2265eSRasesh Mody }
184486a2265eSRasesh Mody 
ecore_vf_get_num_rxqs(struct ecore_hwfn * p_hwfn,u8 * num_rxqs)184586a2265eSRasesh Mody void ecore_vf_get_num_rxqs(struct ecore_hwfn *p_hwfn, u8 *num_rxqs)
184686a2265eSRasesh Mody {
184786a2265eSRasesh Mody 	*num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs;
184886a2265eSRasesh Mody }
184986a2265eSRasesh Mody 
ecore_vf_get_num_txqs(struct ecore_hwfn * p_hwfn,u8 * num_txqs)1850eb8e81adSRasesh Mody void ecore_vf_get_num_txqs(struct ecore_hwfn *p_hwfn,
1851eb8e81adSRasesh Mody 			   u8 *num_txqs)
1852eb8e81adSRasesh Mody {
1853eb8e81adSRasesh Mody 	*num_txqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_txqs;
1854eb8e81adSRasesh Mody }
1855eb8e81adSRasesh Mody 
ecore_vf_get_port_mac(struct ecore_hwfn * p_hwfn,u8 * port_mac)185686a2265eSRasesh Mody void ecore_vf_get_port_mac(struct ecore_hwfn *p_hwfn, u8 *port_mac)
185786a2265eSRasesh Mody {
185886a2265eSRasesh Mody 	OSAL_MEMCPY(port_mac,
185986a2265eSRasesh Mody 		    p_hwfn->vf_iov_info->acquire_resp.pfdev_info.port_mac,
186086a2265eSRasesh Mody 		    ETH_ALEN);
186186a2265eSRasesh Mody }
186286a2265eSRasesh Mody 
ecore_vf_get_num_vlan_filters(struct ecore_hwfn * p_hwfn,u8 * num_vlan_filters)186386a2265eSRasesh Mody void ecore_vf_get_num_vlan_filters(struct ecore_hwfn *p_hwfn,
186486a2265eSRasesh Mody 				   u8 *num_vlan_filters)
186586a2265eSRasesh Mody {
186686a2265eSRasesh Mody 	struct ecore_vf_iov *p_vf;
186786a2265eSRasesh Mody 
186886a2265eSRasesh Mody 	p_vf = p_hwfn->vf_iov_info;
186986a2265eSRasesh Mody 	*num_vlan_filters = p_vf->acquire_resp.resc.num_vlan_filters;
187086a2265eSRasesh Mody }
187186a2265eSRasesh Mody 
ecore_vf_get_num_sbs(struct ecore_hwfn * p_hwfn,u32 * num_sbs)1872f1e4b6c0SHarish Patil void ecore_vf_get_num_sbs(struct ecore_hwfn *p_hwfn,
1873f1e4b6c0SHarish Patil 			  u32 *num_sbs)
1874f1e4b6c0SHarish Patil {
1875f1e4b6c0SHarish Patil 	struct ecore_vf_iov *p_vf;
1876f1e4b6c0SHarish Patil 
1877f1e4b6c0SHarish Patil 	p_vf = p_hwfn->vf_iov_info;
1878f1e4b6c0SHarish Patil 	*num_sbs = (u32)p_vf->acquire_resp.resc.num_sbs;
1879f1e4b6c0SHarish Patil }
1880f1e4b6c0SHarish Patil 
ecore_vf_get_num_mac_filters(struct ecore_hwfn * p_hwfn,u32 * num_mac_filters)18813320ca8cSRasesh Mody void ecore_vf_get_num_mac_filters(struct ecore_hwfn *p_hwfn,
18823320ca8cSRasesh Mody 				  u32 *num_mac_filters)
18833320ca8cSRasesh Mody {
18843320ca8cSRasesh Mody 	struct ecore_vf_iov *p_vf = p_hwfn->vf_iov_info;
18853320ca8cSRasesh Mody 
18863320ca8cSRasesh Mody 	*num_mac_filters = p_vf->acquire_resp.resc.num_mac_filters;
18873320ca8cSRasesh Mody }
18883320ca8cSRasesh Mody 
ecore_vf_check_mac(struct ecore_hwfn * p_hwfn,u8 * mac)188986a2265eSRasesh Mody bool ecore_vf_check_mac(struct ecore_hwfn *p_hwfn, u8 *mac)
189086a2265eSRasesh Mody {
189186a2265eSRasesh Mody 	struct ecore_bulletin_content *bulletin;
189286a2265eSRasesh Mody 
189386a2265eSRasesh Mody 	bulletin = &p_hwfn->vf_iov_info->bulletin_shadow;
189486a2265eSRasesh Mody 	if (!(bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED)))
189586a2265eSRasesh Mody 		return true;
189686a2265eSRasesh Mody 
189786a2265eSRasesh Mody 	/* Forbid VF from changing a MAC enforced by PF */
189886a2265eSRasesh Mody 	if (OSAL_MEMCMP(bulletin->mac, mac, ETH_ALEN))
189986a2265eSRasesh Mody 		return false;
190086a2265eSRasesh Mody 
190186a2265eSRasesh Mody 	return false;
190286a2265eSRasesh Mody }
190386a2265eSRasesh Mody 
ecore_vf_bulletin_get_forced_mac(struct ecore_hwfn * hwfn,u8 * dst_mac,u8 * p_is_forced)190486a2265eSRasesh Mody bool ecore_vf_bulletin_get_forced_mac(struct ecore_hwfn *hwfn, u8 *dst_mac,
190586a2265eSRasesh Mody 				      u8 *p_is_forced)
190686a2265eSRasesh Mody {
190786a2265eSRasesh Mody 	struct ecore_bulletin_content *bulletin;
190886a2265eSRasesh Mody 
190986a2265eSRasesh Mody 	bulletin = &hwfn->vf_iov_info->bulletin_shadow;
191086a2265eSRasesh Mody 
191186a2265eSRasesh Mody 	if (bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED)) {
191286a2265eSRasesh Mody 		if (p_is_forced)
191386a2265eSRasesh Mody 			*p_is_forced = 1;
191486a2265eSRasesh Mody 	} else if (bulletin->valid_bitmap & (1 << VFPF_BULLETIN_MAC_ADDR)) {
191586a2265eSRasesh Mody 		if (p_is_forced)
191686a2265eSRasesh Mody 			*p_is_forced = 0;
191786a2265eSRasesh Mody 	} else {
191886a2265eSRasesh Mody 		return false;
191986a2265eSRasesh Mody 	}
192086a2265eSRasesh Mody 
192186a2265eSRasesh Mody 	OSAL_MEMCPY(dst_mac, bulletin->mac, ETH_ALEN);
192286a2265eSRasesh Mody 
192386a2265eSRasesh Mody 	return true;
192486a2265eSRasesh Mody }
192586a2265eSRasesh Mody 
ecore_vf_bulletin_get_udp_ports(struct ecore_hwfn * p_hwfn,u16 * p_vxlan_port,u16 * p_geneve_port)19264727343dSRasesh Mody void ecore_vf_bulletin_get_udp_ports(struct ecore_hwfn *p_hwfn,
19274727343dSRasesh Mody 				     u16 *p_vxlan_port,
19284727343dSRasesh Mody 				     u16 *p_geneve_port)
19294727343dSRasesh Mody {
19304727343dSRasesh Mody 	struct ecore_bulletin_content *p_bulletin;
19314727343dSRasesh Mody 
19324727343dSRasesh Mody 	p_bulletin = &p_hwfn->vf_iov_info->bulletin_shadow;
19334727343dSRasesh Mody 
19344727343dSRasesh Mody 	*p_vxlan_port = p_bulletin->vxlan_udp_port;
19354727343dSRasesh Mody 	*p_geneve_port = p_bulletin->geneve_udp_port;
19364727343dSRasesh Mody }
19374727343dSRasesh Mody 
ecore_vf_bulletin_get_forced_vlan(struct ecore_hwfn * hwfn,u16 * dst_pvid)193886a2265eSRasesh Mody bool ecore_vf_bulletin_get_forced_vlan(struct ecore_hwfn *hwfn, u16 *dst_pvid)
193986a2265eSRasesh Mody {
194086a2265eSRasesh Mody 	struct ecore_bulletin_content *bulletin;
194186a2265eSRasesh Mody 
194286a2265eSRasesh Mody 	bulletin = &hwfn->vf_iov_info->bulletin_shadow;
194386a2265eSRasesh Mody 
194486a2265eSRasesh Mody 	if (!(bulletin->valid_bitmap & (1 << VLAN_ADDR_FORCED)))
194586a2265eSRasesh Mody 		return false;
194686a2265eSRasesh Mody 
194786a2265eSRasesh Mody 	if (dst_pvid)
194886a2265eSRasesh Mody 		*dst_pvid = bulletin->pvid;
194986a2265eSRasesh Mody 
195086a2265eSRasesh Mody 	return true;
195186a2265eSRasesh Mody }
195286a2265eSRasesh Mody 
ecore_vf_get_pre_fp_hsi(struct ecore_hwfn * p_hwfn)195322d07d93SRasesh Mody bool ecore_vf_get_pre_fp_hsi(struct ecore_hwfn *p_hwfn)
195422d07d93SRasesh Mody {
195522d07d93SRasesh Mody 	return p_hwfn->vf_iov_info->b_pre_fp_hsi;
195622d07d93SRasesh Mody }
195722d07d93SRasesh Mody 
ecore_vf_get_fw_version(struct ecore_hwfn * p_hwfn,u16 * fw_major,u16 * fw_minor,u16 * fw_rev,u16 * fw_eng)195886a2265eSRasesh Mody void ecore_vf_get_fw_version(struct ecore_hwfn *p_hwfn,
195986a2265eSRasesh Mody 			     u16 *fw_major, u16 *fw_minor, u16 *fw_rev,
196086a2265eSRasesh Mody 			     u16 *fw_eng)
196186a2265eSRasesh Mody {
196286a2265eSRasesh Mody 	struct pf_vf_pfdev_info *info;
196386a2265eSRasesh Mody 
196486a2265eSRasesh Mody 	info = &p_hwfn->vf_iov_info->acquire_resp.pfdev_info;
196586a2265eSRasesh Mody 
196686a2265eSRasesh Mody 	*fw_major = info->fw_major;
196786a2265eSRasesh Mody 	*fw_minor = info->fw_minor;
196886a2265eSRasesh Mody 	*fw_rev = info->fw_rev;
196986a2265eSRasesh Mody 	*fw_eng = info->fw_eng;
197086a2265eSRasesh Mody }
197101491d29SRasesh Mody 
197201491d29SRasesh Mody #ifdef CONFIG_ECORE_SW_CHANNEL
ecore_vf_set_hw_channel(struct ecore_hwfn * p_hwfn,bool b_is_hw)197301491d29SRasesh Mody void ecore_vf_set_hw_channel(struct ecore_hwfn *p_hwfn, bool b_is_hw)
197401491d29SRasesh Mody {
197501491d29SRasesh Mody 	p_hwfn->vf_iov_info->b_hw_channel = b_is_hw;
197601491d29SRasesh Mody }
197701491d29SRasesh Mody #endif
1978