11408cc1fSYuval Mintz /* QLogic qed NIC Driver 2e8f1cb50SMintz, Yuval * Copyright (c) 2015-2017 QLogic Corporation 31408cc1fSYuval Mintz * 4e8f1cb50SMintz, Yuval * This software is available to you under a choice of one of two 5e8f1cb50SMintz, Yuval * licenses. You may choose to be licensed under the terms of the GNU 6e8f1cb50SMintz, Yuval * General Public License (GPL) Version 2, available from the file 7e8f1cb50SMintz, Yuval * COPYING in the main directory of this source tree, or the 8e8f1cb50SMintz, Yuval * OpenIB.org BSD license below: 9e8f1cb50SMintz, Yuval * 10e8f1cb50SMintz, Yuval * Redistribution and use in source and binary forms, with or 11e8f1cb50SMintz, Yuval * without modification, are permitted provided that the following 12e8f1cb50SMintz, Yuval * conditions are met: 13e8f1cb50SMintz, Yuval * 14e8f1cb50SMintz, Yuval * - Redistributions of source code must retain the above 15e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 16e8f1cb50SMintz, Yuval * disclaimer. 17e8f1cb50SMintz, Yuval * 18e8f1cb50SMintz, Yuval * - Redistributions in binary form must reproduce the above 19e8f1cb50SMintz, Yuval * copyright notice, this list of conditions and the following 20e8f1cb50SMintz, Yuval * disclaimer in the documentation and /or other materials 21e8f1cb50SMintz, Yuval * provided with the distribution. 22e8f1cb50SMintz, Yuval * 23e8f1cb50SMintz, Yuval * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 24e8f1cb50SMintz, Yuval * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 25e8f1cb50SMintz, Yuval * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 26e8f1cb50SMintz, Yuval * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS 27e8f1cb50SMintz, Yuval * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN 28e8f1cb50SMintz, Yuval * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 29e8f1cb50SMintz, Yuval * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 30e8f1cb50SMintz, Yuval * SOFTWARE. 311408cc1fSYuval Mintz */ 321408cc1fSYuval Mintz 3336558c3dSYuval Mintz #include <linux/crc32.h> 34eff16960SYuval Mintz #include <linux/etherdevice.h> 351408cc1fSYuval Mintz #include "qed.h" 361408cc1fSYuval Mintz #include "qed_sriov.h" 371408cc1fSYuval Mintz #include "qed_vf.h" 381408cc1fSYuval Mintz 391408cc1fSYuval Mintz static void *qed_vf_pf_prep(struct qed_hwfn *p_hwfn, u16 type, u16 length) 401408cc1fSYuval Mintz { 411408cc1fSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 421408cc1fSYuval Mintz void *p_tlv; 431408cc1fSYuval Mintz 441408cc1fSYuval Mintz /* This lock is released when we receive PF's response 451408cc1fSYuval Mintz * in qed_send_msg2pf(). 461408cc1fSYuval Mintz * So, qed_vf_pf_prep() and qed_send_msg2pf() 471408cc1fSYuval Mintz * must come in sequence. 481408cc1fSYuval Mintz */ 491408cc1fSYuval Mintz mutex_lock(&(p_iov->mutex)); 501408cc1fSYuval Mintz 511408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, 521408cc1fSYuval Mintz QED_MSG_IOV, 531408cc1fSYuval Mintz "preparing to send 0x%04x tlv over vf pf channel\n", 541408cc1fSYuval Mintz type); 551408cc1fSYuval Mintz 561408cc1fSYuval Mintz /* Reset Requst offset */ 571408cc1fSYuval Mintz p_iov->offset = (u8 *)p_iov->vf2pf_request; 581408cc1fSYuval Mintz 591408cc1fSYuval Mintz /* Clear mailbox - both request and reply */ 601408cc1fSYuval Mintz memset(p_iov->vf2pf_request, 0, sizeof(union vfpf_tlvs)); 611408cc1fSYuval Mintz memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs)); 621408cc1fSYuval Mintz 631408cc1fSYuval Mintz /* Init type and length */ 641408cc1fSYuval Mintz p_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, type, length); 651408cc1fSYuval Mintz 661408cc1fSYuval Mintz /* Init first tlv header */ 671408cc1fSYuval Mintz ((struct vfpf_first_tlv *)p_tlv)->reply_address = 681408cc1fSYuval Mintz (u64)p_iov->pf2vf_reply_phys; 691408cc1fSYuval Mintz 701408cc1fSYuval Mintz return p_tlv; 711408cc1fSYuval Mintz } 721408cc1fSYuval Mintz 73b0bccb69SYuval Mintz static void qed_vf_pf_req_end(struct qed_hwfn *p_hwfn, int req_status) 74b0bccb69SYuval Mintz { 75b0bccb69SYuval Mintz union pfvf_tlvs *resp = p_hwfn->vf_iov_info->pf2vf_reply; 76b0bccb69SYuval Mintz 77b0bccb69SYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 78b0bccb69SYuval Mintz "VF request status = 0x%x, PF reply status = 0x%x\n", 79b0bccb69SYuval Mintz req_status, resp->default_resp.hdr.status); 80b0bccb69SYuval Mintz 81b0bccb69SYuval Mintz mutex_unlock(&(p_hwfn->vf_iov_info->mutex)); 82b0bccb69SYuval Mintz } 83b0bccb69SYuval Mintz 841408cc1fSYuval Mintz static int qed_send_msg2pf(struct qed_hwfn *p_hwfn, u8 *done, u32 resp_size) 851408cc1fSYuval Mintz { 861408cc1fSYuval Mintz union vfpf_tlvs *p_req = p_hwfn->vf_iov_info->vf2pf_request; 871408cc1fSYuval Mintz struct ustorm_trigger_vf_zone trigger; 881408cc1fSYuval Mintz struct ustorm_vf_zone *zone_data; 891408cc1fSYuval Mintz int rc = 0, time = 100; 901408cc1fSYuval Mintz 911408cc1fSYuval Mintz zone_data = (struct ustorm_vf_zone *)PXP_VF_BAR0_START_USDM_ZONE_B; 921408cc1fSYuval Mintz 931408cc1fSYuval Mintz /* output tlvs list */ 941408cc1fSYuval Mintz qed_dp_tlv_list(p_hwfn, p_req); 951408cc1fSYuval Mintz 961408cc1fSYuval Mintz /* need to add the END TLV to the message size */ 971408cc1fSYuval Mintz resp_size += sizeof(struct channel_list_end_tlv); 981408cc1fSYuval Mintz 991408cc1fSYuval Mintz /* Send TLVs over HW channel */ 1001408cc1fSYuval Mintz memset(&trigger, 0, sizeof(struct ustorm_trigger_vf_zone)); 1011408cc1fSYuval Mintz trigger.vf_pf_msg_valid = 1; 1021408cc1fSYuval Mintz 1031408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, 1041408cc1fSYuval Mintz QED_MSG_IOV, 1051408cc1fSYuval Mintz "VF -> PF [%02x] message: [%08x, %08x] --> %p, %08x --> %p\n", 1061408cc1fSYuval Mintz GET_FIELD(p_hwfn->hw_info.concrete_fid, 1071408cc1fSYuval Mintz PXP_CONCRETE_FID_PFID), 1081408cc1fSYuval Mintz upper_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys), 1091408cc1fSYuval Mintz lower_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys), 1101408cc1fSYuval Mintz &zone_data->non_trigger.vf_pf_msg_addr, 1111408cc1fSYuval Mintz *((u32 *)&trigger), &zone_data->trigger); 1121408cc1fSYuval Mintz 1131408cc1fSYuval Mintz REG_WR(p_hwfn, 1141408cc1fSYuval Mintz (uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.lo, 1151408cc1fSYuval Mintz lower_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys)); 1161408cc1fSYuval Mintz 1171408cc1fSYuval Mintz REG_WR(p_hwfn, 1181408cc1fSYuval Mintz (uintptr_t)&zone_data->non_trigger.vf_pf_msg_addr.hi, 1191408cc1fSYuval Mintz upper_32_bits(p_hwfn->vf_iov_info->vf2pf_request_phys)); 1201408cc1fSYuval Mintz 1211408cc1fSYuval Mintz /* The message data must be written first, to prevent trigger before 1221408cc1fSYuval Mintz * data is written. 1231408cc1fSYuval Mintz */ 1241408cc1fSYuval Mintz wmb(); 1251408cc1fSYuval Mintz 1261408cc1fSYuval Mintz REG_WR(p_hwfn, (uintptr_t)&zone_data->trigger, *((u32 *)&trigger)); 1271408cc1fSYuval Mintz 1281408cc1fSYuval Mintz /* When PF would be done with the response, it would write back to the 1291408cc1fSYuval Mintz * `done' address. Poll until then. 1301408cc1fSYuval Mintz */ 1311408cc1fSYuval Mintz while ((!*done) && time) { 1321408cc1fSYuval Mintz msleep(25); 1331408cc1fSYuval Mintz time--; 1341408cc1fSYuval Mintz } 1351408cc1fSYuval Mintz 1361408cc1fSYuval Mintz if (!*done) { 13781e64ef6SMintz, Yuval DP_NOTICE(p_hwfn, 1381408cc1fSYuval Mintz "VF <-- PF Timeout [Type %d]\n", 1391408cc1fSYuval Mintz p_req->first_tlv.tl.type); 1401408cc1fSYuval Mintz rc = -EBUSY; 1411408cc1fSYuval Mintz } else { 14281e64ef6SMintz, Yuval if ((*done != PFVF_STATUS_SUCCESS) && 14381e64ef6SMintz, Yuval (*done != PFVF_STATUS_NO_RESOURCE)) 14481e64ef6SMintz, Yuval DP_NOTICE(p_hwfn, 14581e64ef6SMintz, Yuval "PF response: %d [Type %d]\n", 14681e64ef6SMintz, Yuval *done, p_req->first_tlv.tl.type); 14781e64ef6SMintz, Yuval else 1481408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 1491408cc1fSYuval Mintz "PF response: %d [Type %d]\n", 1501408cc1fSYuval Mintz *done, p_req->first_tlv.tl.type); 1511408cc1fSYuval Mintz } 1521408cc1fSYuval Mintz 1531408cc1fSYuval Mintz return rc; 1541408cc1fSYuval Mintz } 1551408cc1fSYuval Mintz 15608bc8f15SMintz, Yuval static void qed_vf_pf_add_qid(struct qed_hwfn *p_hwfn, 15708bc8f15SMintz, Yuval struct qed_queue_cid *p_cid) 15808bc8f15SMintz, Yuval { 15908bc8f15SMintz, Yuval struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 16008bc8f15SMintz, Yuval struct vfpf_qid_tlv *p_qid_tlv; 16108bc8f15SMintz, Yuval 16208bc8f15SMintz, Yuval /* Only add QIDs for the queue if it was negotiated with PF */ 16308bc8f15SMintz, Yuval if (!(p_iov->acquire_resp.pfdev_info.capabilities & 16408bc8f15SMintz, Yuval PFVF_ACQUIRE_CAP_QUEUE_QIDS)) 16508bc8f15SMintz, Yuval return; 16608bc8f15SMintz, Yuval 16708bc8f15SMintz, Yuval p_qid_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, 16808bc8f15SMintz, Yuval CHANNEL_TLV_QID, sizeof(*p_qid_tlv)); 16908bc8f15SMintz, Yuval p_qid_tlv->qid = p_cid->qid_usage_idx; 17008bc8f15SMintz, Yuval } 17108bc8f15SMintz, Yuval 172bf774d14SYueHaibing static int _qed_vf_pf_release(struct qed_hwfn *p_hwfn, bool b_final) 1731a850bfcSMintz, Yuval { 1741a850bfcSMintz, Yuval struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1751a850bfcSMintz, Yuval struct pfvf_def_resp_tlv *resp; 1761a850bfcSMintz, Yuval struct vfpf_first_tlv *req; 1771a850bfcSMintz, Yuval u32 size; 1781a850bfcSMintz, Yuval int rc; 1791a850bfcSMintz, Yuval 1801a850bfcSMintz, Yuval /* clear mailbox and prep first tlv */ 1811a850bfcSMintz, Yuval req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_RELEASE, sizeof(*req)); 1821a850bfcSMintz, Yuval 1831a850bfcSMintz, Yuval /* add list termination tlv */ 1841a850bfcSMintz, Yuval qed_add_tlv(p_hwfn, &p_iov->offset, 1851a850bfcSMintz, Yuval CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 1861a850bfcSMintz, Yuval 1871a850bfcSMintz, Yuval resp = &p_iov->pf2vf_reply->default_resp; 1881a850bfcSMintz, Yuval rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 1891a850bfcSMintz, Yuval 1901a850bfcSMintz, Yuval if (!rc && resp->hdr.status != PFVF_STATUS_SUCCESS) 1911a850bfcSMintz, Yuval rc = -EAGAIN; 1921a850bfcSMintz, Yuval 1931a850bfcSMintz, Yuval qed_vf_pf_req_end(p_hwfn, rc); 1941a850bfcSMintz, Yuval if (!b_final) 1951a850bfcSMintz, Yuval return rc; 1961a850bfcSMintz, Yuval 1971a850bfcSMintz, Yuval p_hwfn->b_int_enabled = 0; 1981a850bfcSMintz, Yuval 1991a850bfcSMintz, Yuval if (p_iov->vf2pf_request) 2001a850bfcSMintz, Yuval dma_free_coherent(&p_hwfn->cdev->pdev->dev, 2011a850bfcSMintz, Yuval sizeof(union vfpf_tlvs), 2021a850bfcSMintz, Yuval p_iov->vf2pf_request, 2031a850bfcSMintz, Yuval p_iov->vf2pf_request_phys); 2041a850bfcSMintz, Yuval if (p_iov->pf2vf_reply) 2051a850bfcSMintz, Yuval dma_free_coherent(&p_hwfn->cdev->pdev->dev, 2061a850bfcSMintz, Yuval sizeof(union pfvf_tlvs), 2071a850bfcSMintz, Yuval p_iov->pf2vf_reply, p_iov->pf2vf_reply_phys); 2081a850bfcSMintz, Yuval 2091a850bfcSMintz, Yuval if (p_iov->bulletin.p_virt) { 2101a850bfcSMintz, Yuval size = sizeof(struct qed_bulletin_content); 2111a850bfcSMintz, Yuval dma_free_coherent(&p_hwfn->cdev->pdev->dev, 2121a850bfcSMintz, Yuval size, 2131a850bfcSMintz, Yuval p_iov->bulletin.p_virt, p_iov->bulletin.phys); 2141a850bfcSMintz, Yuval } 2151a850bfcSMintz, Yuval 2161a850bfcSMintz, Yuval kfree(p_hwfn->vf_iov_info); 2171a850bfcSMintz, Yuval p_hwfn->vf_iov_info = NULL; 2181a850bfcSMintz, Yuval 2191a850bfcSMintz, Yuval return rc; 2201a850bfcSMintz, Yuval } 2211a850bfcSMintz, Yuval 2221a850bfcSMintz, Yuval int qed_vf_pf_release(struct qed_hwfn *p_hwfn) 2231a850bfcSMintz, Yuval { 2241a850bfcSMintz, Yuval return _qed_vf_pf_release(p_hwfn, true); 2251a850bfcSMintz, Yuval } 2261a850bfcSMintz, Yuval 2271408cc1fSYuval Mintz #define VF_ACQUIRE_THRESH 3 2281cf2b1a9SYuval Mintz static void qed_vf_pf_acquire_reduce_resc(struct qed_hwfn *p_hwfn, 2291cf2b1a9SYuval Mintz struct vf_pf_resc_request *p_req, 2301cf2b1a9SYuval Mintz struct pf_vf_resc *p_resp) 2311cf2b1a9SYuval Mintz { 2321cf2b1a9SYuval Mintz DP_VERBOSE(p_hwfn, 2331cf2b1a9SYuval Mintz QED_MSG_IOV, 23408bc8f15SMintz, Yuval "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", 2351cf2b1a9SYuval Mintz p_req->num_rxqs, 2361cf2b1a9SYuval Mintz p_resp->num_rxqs, 2371cf2b1a9SYuval Mintz p_req->num_rxqs, 2381cf2b1a9SYuval Mintz p_resp->num_txqs, 2391cf2b1a9SYuval Mintz p_req->num_sbs, 2401cf2b1a9SYuval Mintz p_resp->num_sbs, 2411cf2b1a9SYuval Mintz p_req->num_mac_filters, 2421cf2b1a9SYuval Mintz p_resp->num_mac_filters, 2431cf2b1a9SYuval Mintz p_req->num_vlan_filters, 2441cf2b1a9SYuval Mintz p_resp->num_vlan_filters, 24508bc8f15SMintz, Yuval p_req->num_mc_filters, 24608bc8f15SMintz, Yuval p_resp->num_mc_filters, p_req->num_cids, p_resp->num_cids); 2471cf2b1a9SYuval Mintz 2481cf2b1a9SYuval Mintz /* humble our request */ 2491cf2b1a9SYuval Mintz p_req->num_txqs = p_resp->num_txqs; 2501cf2b1a9SYuval Mintz p_req->num_rxqs = p_resp->num_rxqs; 2511cf2b1a9SYuval Mintz p_req->num_sbs = p_resp->num_sbs; 2521cf2b1a9SYuval Mintz p_req->num_mac_filters = p_resp->num_mac_filters; 2531cf2b1a9SYuval Mintz p_req->num_vlan_filters = p_resp->num_vlan_filters; 2541cf2b1a9SYuval Mintz p_req->num_mc_filters = p_resp->num_mc_filters; 25508bc8f15SMintz, Yuval p_req->num_cids = p_resp->num_cids; 2561cf2b1a9SYuval Mintz } 2571408cc1fSYuval Mintz 2581408cc1fSYuval Mintz static int qed_vf_pf_acquire(struct qed_hwfn *p_hwfn) 2591408cc1fSYuval Mintz { 2601408cc1fSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 2611408cc1fSYuval Mintz struct pfvf_acquire_resp_tlv *resp = &p_iov->pf2vf_reply->acquire_resp; 2621408cc1fSYuval Mintz struct pf_vf_pfdev_info *pfdev_info = &resp->pfdev_info; 2631cf2b1a9SYuval Mintz struct vf_pf_resc_request *p_resc; 264327852ecSManish Chopra u8 retry_cnt = VF_ACQUIRE_THRESH; 2651408cc1fSYuval Mintz bool resources_acquired = false; 2661408cc1fSYuval Mintz struct vfpf_acquire_tlv *req; 2671408cc1fSYuval Mintz int rc = 0, attempts = 0; 2681408cc1fSYuval Mintz 2691408cc1fSYuval Mintz /* clear mailbox and prep first tlv */ 2701408cc1fSYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_ACQUIRE, sizeof(*req)); 2711cf2b1a9SYuval Mintz p_resc = &req->resc_request; 2721408cc1fSYuval Mintz 2731408cc1fSYuval Mintz /* starting filling the request */ 2741408cc1fSYuval Mintz req->vfdev_info.opaque_fid = p_hwfn->hw_info.opaque_fid; 2751408cc1fSYuval Mintz 2761cf2b1a9SYuval Mintz p_resc->num_rxqs = QED_MAX_VF_CHAINS_PER_PF; 2771cf2b1a9SYuval Mintz p_resc->num_txqs = QED_MAX_VF_CHAINS_PER_PF; 2781cf2b1a9SYuval Mintz p_resc->num_sbs = QED_MAX_VF_CHAINS_PER_PF; 2791cf2b1a9SYuval Mintz p_resc->num_mac_filters = QED_ETH_VF_NUM_MAC_FILTERS; 2801cf2b1a9SYuval Mintz p_resc->num_vlan_filters = QED_ETH_VF_NUM_VLAN_FILTERS; 28108bc8f15SMintz, Yuval p_resc->num_cids = QED_ETH_VF_DEFAULT_NUM_CIDS; 2821408cc1fSYuval Mintz 2831408cc1fSYuval Mintz req->vfdev_info.os_type = VFPF_ACQUIRE_OS_LINUX; 2841408cc1fSYuval Mintz req->vfdev_info.fw_major = FW_MAJOR_VERSION; 2851408cc1fSYuval Mintz req->vfdev_info.fw_minor = FW_MINOR_VERSION; 2861408cc1fSYuval Mintz req->vfdev_info.fw_revision = FW_REVISION_VERSION; 2871408cc1fSYuval Mintz req->vfdev_info.fw_engineering = FW_ENGINEERING_VERSION; 2881fe614d1SYuval Mintz req->vfdev_info.eth_fp_hsi_major = ETH_HSI_VER_MAJOR; 2891fe614d1SYuval Mintz req->vfdev_info.eth_fp_hsi_minor = ETH_HSI_VER_MINOR; 2901408cc1fSYuval Mintz 2911408cc1fSYuval Mintz /* Fill capability field with any non-deprecated config we support */ 2921408cc1fSYuval Mintz req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_100G; 2931408cc1fSYuval Mintz 2941a850bfcSMintz, Yuval /* If we've mapped the doorbell bar, try using queue qids */ 295cbb8a12cSMintz, Yuval if (p_iov->b_doorbell_bar) { 2961a850bfcSMintz, Yuval req->vfdev_info.capabilities |= VFPF_ACQUIRE_CAP_PHYSICAL_BAR | 2971a850bfcSMintz, Yuval VFPF_ACQUIRE_CAP_QUEUE_QIDS; 298cbb8a12cSMintz, Yuval p_resc->num_cids = QED_ETH_VF_MAX_NUM_CIDS; 299cbb8a12cSMintz, Yuval } 3001a850bfcSMintz, Yuval 3011408cc1fSYuval Mintz /* pf 2 vf bulletin board address */ 3021408cc1fSYuval Mintz req->bulletin_addr = p_iov->bulletin.phys; 3031408cc1fSYuval Mintz req->bulletin_size = p_iov->bulletin.size; 3041408cc1fSYuval Mintz 3051408cc1fSYuval Mintz /* add list termination tlv */ 3061408cc1fSYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 3071408cc1fSYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 3081408cc1fSYuval Mintz 3091408cc1fSYuval Mintz while (!resources_acquired) { 3101408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, 3111408cc1fSYuval Mintz QED_MSG_IOV, "attempting to acquire resources\n"); 3121408cc1fSYuval Mintz 313d8c2c7e3SYuval Mintz /* Clear response buffer, as this might be a re-send */ 314d8c2c7e3SYuval Mintz memset(p_iov->pf2vf_reply, 0, sizeof(union pfvf_tlvs)); 315d8c2c7e3SYuval Mintz 3161408cc1fSYuval Mintz /* send acquire request */ 3171408cc1fSYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 318327852ecSManish Chopra 319327852ecSManish Chopra /* Re-try acquire in case of vf-pf hw channel timeout */ 320327852ecSManish Chopra if (retry_cnt && rc == -EBUSY) { 321327852ecSManish Chopra DP_VERBOSE(p_hwfn, QED_MSG_IOV, 322327852ecSManish Chopra "VF retrying to acquire due to VPC timeout\n"); 323327852ecSManish Chopra retry_cnt--; 324327852ecSManish Chopra continue; 325327852ecSManish Chopra } 326327852ecSManish Chopra 3271408cc1fSYuval Mintz if (rc) 32866117a9dSDan Carpenter goto exit; 3291408cc1fSYuval Mintz 3301408cc1fSYuval Mintz /* copy acquire response from buffer to p_hwfn */ 3311408cc1fSYuval Mintz memcpy(&p_iov->acquire_resp, resp, sizeof(p_iov->acquire_resp)); 3321408cc1fSYuval Mintz 3331408cc1fSYuval Mintz attempts++; 3341408cc1fSYuval Mintz 3351408cc1fSYuval Mintz if (resp->hdr.status == PFVF_STATUS_SUCCESS) { 3361408cc1fSYuval Mintz /* PF agrees to allocate our resources */ 3371408cc1fSYuval Mintz if (!(resp->pfdev_info.capabilities & 3381408cc1fSYuval Mintz PFVF_ACQUIRE_CAP_POST_FW_OVERRIDE)) { 339d8c2c7e3SYuval Mintz /* It's possible legacy PF mistakenly accepted; 340d8c2c7e3SYuval Mintz * but we don't care - simply mark it as 341d8c2c7e3SYuval Mintz * legacy and continue. 342d8c2c7e3SYuval Mintz */ 343d8c2c7e3SYuval Mintz req->vfdev_info.capabilities |= 344d8c2c7e3SYuval Mintz VFPF_ACQUIRE_CAP_PRE_FP_HSI; 3451408cc1fSYuval Mintz } 3461408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, "resources acquired\n"); 3471408cc1fSYuval Mintz resources_acquired = true; 3481408cc1fSYuval Mintz } else if (resp->hdr.status == PFVF_STATUS_NO_RESOURCE && 3491408cc1fSYuval Mintz attempts < VF_ACQUIRE_THRESH) { 3501cf2b1a9SYuval Mintz qed_vf_pf_acquire_reduce_resc(p_hwfn, p_resc, 3511cf2b1a9SYuval Mintz &resp->resc); 352d8c2c7e3SYuval Mintz } else if (resp->hdr.status == PFVF_STATUS_NOT_SUPPORTED) { 353d8c2c7e3SYuval Mintz if (pfdev_info->major_fp_hsi && 3541fe614d1SYuval Mintz (pfdev_info->major_fp_hsi != ETH_HSI_VER_MAJOR)) { 3551fe614d1SYuval Mintz DP_NOTICE(p_hwfn, 3561fe614d1SYuval Mintz "PF uses an incompatible fastpath HSI %02x.%02x [VF requires %02x.%02x]. Please change to a VF driver using %02x.xx.\n", 3571fe614d1SYuval Mintz pfdev_info->major_fp_hsi, 3581fe614d1SYuval Mintz pfdev_info->minor_fp_hsi, 3591fe614d1SYuval Mintz ETH_HSI_VER_MAJOR, 360d8c2c7e3SYuval Mintz ETH_HSI_VER_MINOR, 361d8c2c7e3SYuval Mintz pfdev_info->major_fp_hsi); 362d8c2c7e3SYuval Mintz rc = -EINVAL; 363d8c2c7e3SYuval Mintz goto exit; 364d8c2c7e3SYuval Mintz } 365d8c2c7e3SYuval Mintz 366d8c2c7e3SYuval Mintz if (!pfdev_info->major_fp_hsi) { 367d8c2c7e3SYuval Mintz if (req->vfdev_info.capabilities & 368d8c2c7e3SYuval Mintz VFPF_ACQUIRE_CAP_PRE_FP_HSI) { 369d8c2c7e3SYuval Mintz DP_NOTICE(p_hwfn, 370d8c2c7e3SYuval Mintz "PF uses very old drivers. Please change to a VF driver using no later than 8.8.x.x.\n"); 371d8c2c7e3SYuval Mintz rc = -EINVAL; 372d8c2c7e3SYuval Mintz goto exit; 373d8c2c7e3SYuval Mintz } else { 374d8c2c7e3SYuval Mintz DP_INFO(p_hwfn, 375d8c2c7e3SYuval Mintz "PF is old - try re-acquire to see if it supports FW-version override\n"); 376d8c2c7e3SYuval Mintz req->vfdev_info.capabilities |= 377d8c2c7e3SYuval Mintz VFPF_ACQUIRE_CAP_PRE_FP_HSI; 378d8c2c7e3SYuval Mintz continue; 379d8c2c7e3SYuval Mintz } 380d8c2c7e3SYuval Mintz } 381d8c2c7e3SYuval Mintz 382d8c2c7e3SYuval Mintz /* If PF/VF are using same Major, PF must have had 383d8c2c7e3SYuval Mintz * it's reasons. Simply fail. 384d8c2c7e3SYuval Mintz */ 385d8c2c7e3SYuval Mintz DP_NOTICE(p_hwfn, "PF rejected acquisition by VF\n"); 386d8c2c7e3SYuval Mintz rc = -EINVAL; 387d8c2c7e3SYuval Mintz goto exit; 3881408cc1fSYuval Mintz } else { 3891408cc1fSYuval Mintz DP_ERR(p_hwfn, 3901408cc1fSYuval Mintz "PF returned error %d to VF acquisition request\n", 3911408cc1fSYuval Mintz resp->hdr.status); 392d8c2c7e3SYuval Mintz rc = -EAGAIN; 393d8c2c7e3SYuval Mintz goto exit; 3941408cc1fSYuval Mintz } 3951408cc1fSYuval Mintz } 3961408cc1fSYuval Mintz 397d8c2c7e3SYuval Mintz /* Mark the PF as legacy, if needed */ 398d8c2c7e3SYuval Mintz if (req->vfdev_info.capabilities & VFPF_ACQUIRE_CAP_PRE_FP_HSI) 399d8c2c7e3SYuval Mintz p_iov->b_pre_fp_hsi = true; 400d8c2c7e3SYuval Mintz 40108bc8f15SMintz, Yuval /* In case PF doesn't support multi-queue Tx, update the number of 40208bc8f15SMintz, Yuval * CIDs to reflect the number of queues [older PFs didn't fill that 40308bc8f15SMintz, Yuval * field]. 40408bc8f15SMintz, Yuval */ 40508bc8f15SMintz, Yuval if (!(resp->pfdev_info.capabilities & PFVF_ACQUIRE_CAP_QUEUE_QIDS)) 40608bc8f15SMintz, Yuval resp->resc.num_cids = resp->resc.num_rxqs + resp->resc.num_txqs; 40708bc8f15SMintz, Yuval 4081408cc1fSYuval Mintz /* Update bulletin board size with response from PF */ 4091408cc1fSYuval Mintz p_iov->bulletin.size = resp->bulletin_size; 4101408cc1fSYuval Mintz 4111408cc1fSYuval Mintz /* get HW info */ 4121408cc1fSYuval Mintz p_hwfn->cdev->type = resp->pfdev_info.dev_type; 4131408cc1fSYuval Mintz p_hwfn->cdev->chip_rev = resp->pfdev_info.chip_rev; 4141408cc1fSYuval Mintz 4151408cc1fSYuval Mintz p_hwfn->cdev->chip_num = pfdev_info->chip_num & 0xffff; 4161408cc1fSYuval Mintz 4171408cc1fSYuval Mintz /* Learn of the possibility of CMT */ 4181408cc1fSYuval Mintz if (IS_LEAD_HWFN(p_hwfn)) { 4191408cc1fSYuval Mintz if (resp->pfdev_info.capabilities & PFVF_ACQUIRE_CAP_100G) { 4201408cc1fSYuval Mintz DP_NOTICE(p_hwfn, "100g VF\n"); 4211408cc1fSYuval Mintz p_hwfn->cdev->num_hwfns = 2; 4221408cc1fSYuval Mintz } 4231408cc1fSYuval Mintz } 4241408cc1fSYuval Mintz 425d8c2c7e3SYuval Mintz if (!p_iov->b_pre_fp_hsi && 4261fe614d1SYuval Mintz (resp->pfdev_info.minor_fp_hsi < ETH_HSI_VER_MINOR)) { 4271fe614d1SYuval Mintz DP_INFO(p_hwfn, 4281fe614d1SYuval Mintz "PF is using older fastpath HSI; %02x.%02x is configured\n", 4291fe614d1SYuval Mintz ETH_HSI_VER_MAJOR, resp->pfdev_info.minor_fp_hsi); 4301fe614d1SYuval Mintz } 4311fe614d1SYuval Mintz 432d8c2c7e3SYuval Mintz exit: 433b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 434b0bccb69SYuval Mintz 435d8c2c7e3SYuval Mintz return rc; 4361408cc1fSYuval Mintz } 4371408cc1fSYuval Mintz 4381a850bfcSMintz, Yuval u32 qed_vf_hw_bar_size(struct qed_hwfn *p_hwfn, enum BAR_ID bar_id) 4391a850bfcSMintz, Yuval { 4401a850bfcSMintz, Yuval u32 bar_size; 4411a850bfcSMintz, Yuval 4421a850bfcSMintz, Yuval /* Regview size is fixed */ 4431a850bfcSMintz, Yuval if (bar_id == BAR_ID_0) 4441a850bfcSMintz, Yuval return 1 << 17; 4451a850bfcSMintz, Yuval 4461a850bfcSMintz, Yuval /* Doorbell is received from PF */ 4471a850bfcSMintz, Yuval bar_size = p_hwfn->vf_iov_info->acquire_resp.pfdev_info.bar_size; 4481a850bfcSMintz, Yuval if (bar_size) 4491a850bfcSMintz, Yuval return 1 << bar_size; 4501a850bfcSMintz, Yuval return 0; 4511a850bfcSMintz, Yuval } 4521a850bfcSMintz, Yuval 4531408cc1fSYuval Mintz int qed_vf_hw_prepare(struct qed_hwfn *p_hwfn) 4541408cc1fSYuval Mintz { 4551a850bfcSMintz, Yuval struct qed_hwfn *p_lead = QED_LEADING_HWFN(p_hwfn->cdev); 4561408cc1fSYuval Mintz struct qed_vf_iov *p_iov; 4571408cc1fSYuval Mintz u32 reg; 4581a850bfcSMintz, Yuval int rc; 4591408cc1fSYuval Mintz 4601408cc1fSYuval Mintz /* Set number of hwfns - might be overriden once leading hwfn learns 4611408cc1fSYuval Mintz * actual configuration from PF. 4621408cc1fSYuval Mintz */ 4631408cc1fSYuval Mintz if (IS_LEAD_HWFN(p_hwfn)) 4641408cc1fSYuval Mintz p_hwfn->cdev->num_hwfns = 1; 4651408cc1fSYuval Mintz 4661408cc1fSYuval Mintz reg = PXP_VF_BAR0_ME_OPAQUE_ADDRESS; 4671408cc1fSYuval Mintz p_hwfn->hw_info.opaque_fid = (u16)REG_RD(p_hwfn, reg); 4681408cc1fSYuval Mintz 4691408cc1fSYuval Mintz reg = PXP_VF_BAR0_ME_CONCRETE_ADDRESS; 4701408cc1fSYuval Mintz p_hwfn->hw_info.concrete_fid = REG_RD(p_hwfn, reg); 4711408cc1fSYuval Mintz 4721408cc1fSYuval Mintz /* Allocate vf sriov info */ 4731408cc1fSYuval Mintz p_iov = kzalloc(sizeof(*p_iov), GFP_KERNEL); 4742591c280SJoe Perches if (!p_iov) 4751408cc1fSYuval Mintz return -ENOMEM; 4761408cc1fSYuval Mintz 4771a850bfcSMintz, Yuval /* Doorbells are tricky; Upper-layer has alreday set the hwfn doorbell 4781a850bfcSMintz, Yuval * value, but there are several incompatibily scenarios where that 4791a850bfcSMintz, Yuval * would be incorrect and we'd need to override it. 4801a850bfcSMintz, Yuval */ 4811a850bfcSMintz, Yuval if (!p_hwfn->doorbells) { 4821a850bfcSMintz, Yuval p_hwfn->doorbells = (u8 __iomem *)p_hwfn->regview + 4831a850bfcSMintz, Yuval PXP_VF_BAR0_START_DQ; 4841a850bfcSMintz, Yuval } else if (p_hwfn == p_lead) { 4851a850bfcSMintz, Yuval /* For leading hw-function, value is always correct, but need 4861a850bfcSMintz, Yuval * to handle scenario where legacy PF would not support 100g 4871a850bfcSMintz, Yuval * mapped bars later. 4881a850bfcSMintz, Yuval */ 4891a850bfcSMintz, Yuval p_iov->b_doorbell_bar = true; 4901a850bfcSMintz, Yuval } else { 4911a850bfcSMintz, Yuval /* here, value would be correct ONLY if the leading hwfn 4921a850bfcSMintz, Yuval * received indication that mapped-bars are supported. 4931a850bfcSMintz, Yuval */ 4941a850bfcSMintz, Yuval if (p_lead->vf_iov_info->b_doorbell_bar) 4951a850bfcSMintz, Yuval p_iov->b_doorbell_bar = true; 4961a850bfcSMintz, Yuval else 4971a850bfcSMintz, Yuval p_hwfn->doorbells = (u8 __iomem *) 4981a850bfcSMintz, Yuval p_hwfn->regview + PXP_VF_BAR0_START_DQ; 4991a850bfcSMintz, Yuval } 5001a850bfcSMintz, Yuval 5011408cc1fSYuval Mintz /* Allocate vf2pf msg */ 5021408cc1fSYuval Mintz p_iov->vf2pf_request = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 5031408cc1fSYuval Mintz sizeof(union vfpf_tlvs), 5041408cc1fSYuval Mintz &p_iov->vf2pf_request_phys, 5051408cc1fSYuval Mintz GFP_KERNEL); 5062591c280SJoe Perches if (!p_iov->vf2pf_request) 5071408cc1fSYuval Mintz goto free_p_iov; 5081408cc1fSYuval Mintz 5091408cc1fSYuval Mintz p_iov->pf2vf_reply = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 5101408cc1fSYuval Mintz sizeof(union pfvf_tlvs), 5111408cc1fSYuval Mintz &p_iov->pf2vf_reply_phys, 5121408cc1fSYuval Mintz GFP_KERNEL); 5132591c280SJoe Perches if (!p_iov->pf2vf_reply) 5141408cc1fSYuval Mintz goto free_vf2pf_request; 5151408cc1fSYuval Mintz 5161408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, 5171408cc1fSYuval Mintz QED_MSG_IOV, 5181408cc1fSYuval Mintz "VF's Request mailbox [%p virt 0x%llx phys], Response mailbox [%p virt 0x%llx phys]\n", 5191408cc1fSYuval Mintz p_iov->vf2pf_request, 5201408cc1fSYuval Mintz (u64) p_iov->vf2pf_request_phys, 5211408cc1fSYuval Mintz p_iov->pf2vf_reply, (u64)p_iov->pf2vf_reply_phys); 5221408cc1fSYuval Mintz 5231408cc1fSYuval Mintz /* Allocate Bulletin board */ 5241408cc1fSYuval Mintz p_iov->bulletin.size = sizeof(struct qed_bulletin_content); 5251408cc1fSYuval Mintz p_iov->bulletin.p_virt = dma_alloc_coherent(&p_hwfn->cdev->pdev->dev, 5261408cc1fSYuval Mintz p_iov->bulletin.size, 5271408cc1fSYuval Mintz &p_iov->bulletin.phys, 5281408cc1fSYuval Mintz GFP_KERNEL); 5291408cc1fSYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 5301408cc1fSYuval Mintz "VF's bulletin Board [%p virt 0x%llx phys 0x%08x bytes]\n", 5311408cc1fSYuval Mintz p_iov->bulletin.p_virt, 5321408cc1fSYuval Mintz (u64)p_iov->bulletin.phys, p_iov->bulletin.size); 5331408cc1fSYuval Mintz 5341408cc1fSYuval Mintz mutex_init(&p_iov->mutex); 5351408cc1fSYuval Mintz 5361408cc1fSYuval Mintz p_hwfn->vf_iov_info = p_iov; 5371408cc1fSYuval Mintz 5381408cc1fSYuval Mintz p_hwfn->hw_info.personality = QED_PCI_ETH; 5391408cc1fSYuval Mintz 5401a850bfcSMintz, Yuval rc = qed_vf_pf_acquire(p_hwfn); 5411a850bfcSMintz, Yuval 5421a850bfcSMintz, Yuval /* If VF is 100g using a mapped bar and PF is too old to support that, 5431a850bfcSMintz, Yuval * acquisition would succeed - but the VF would have no way knowing 5441a850bfcSMintz, Yuval * the size of the doorbell bar configured in HW and thus will not 5451a850bfcSMintz, Yuval * know how to split it for 2nd hw-function. 5461a850bfcSMintz, Yuval * In this case we re-try without the indication of the mapped 5471a850bfcSMintz, Yuval * doorbell. 5481a850bfcSMintz, Yuval */ 5491a850bfcSMintz, Yuval if (!rc && p_iov->b_doorbell_bar && 5501a850bfcSMintz, Yuval !qed_vf_hw_bar_size(p_hwfn, BAR_ID_1) && 5511a850bfcSMintz, Yuval (p_hwfn->cdev->num_hwfns > 1)) { 5521a850bfcSMintz, Yuval rc = _qed_vf_pf_release(p_hwfn, false); 5531a850bfcSMintz, Yuval if (rc) 5541a850bfcSMintz, Yuval return rc; 5551a850bfcSMintz, Yuval 5561a850bfcSMintz, Yuval p_iov->b_doorbell_bar = false; 5571a850bfcSMintz, Yuval p_hwfn->doorbells = (u8 __iomem *)p_hwfn->regview + 5581a850bfcSMintz, Yuval PXP_VF_BAR0_START_DQ; 5591a850bfcSMintz, Yuval rc = qed_vf_pf_acquire(p_hwfn); 5601a850bfcSMintz, Yuval } 5611a850bfcSMintz, Yuval 5621a850bfcSMintz, Yuval DP_VERBOSE(p_hwfn, QED_MSG_IOV, 5631a850bfcSMintz, Yuval "Regview [%p], Doorbell [%p], Device-doorbell [%p]\n", 5641a850bfcSMintz, Yuval p_hwfn->regview, p_hwfn->doorbells, p_hwfn->cdev->doorbells); 5651a850bfcSMintz, Yuval 5661a850bfcSMintz, Yuval return rc; 5671408cc1fSYuval Mintz 5681408cc1fSYuval Mintz free_vf2pf_request: 5691408cc1fSYuval Mintz dma_free_coherent(&p_hwfn->cdev->pdev->dev, 5701408cc1fSYuval Mintz sizeof(union vfpf_tlvs), 5711408cc1fSYuval Mintz p_iov->vf2pf_request, p_iov->vf2pf_request_phys); 5721408cc1fSYuval Mintz free_p_iov: 5731408cc1fSYuval Mintz kfree(p_iov); 5741408cc1fSYuval Mintz 5751408cc1fSYuval Mintz return -ENOMEM; 5761408cc1fSYuval Mintz } 577d8c2c7e3SYuval Mintz #define TSTORM_QZONE_START PXP_VF_BAR0_START_SDM_ZONE_A 578d8c2c7e3SYuval Mintz #define MSTORM_QZONE_START(dev) (TSTORM_QZONE_START + \ 579d8c2c7e3SYuval Mintz (TSTORM_QZONE_SIZE * NUM_OF_L2_QUEUES(dev))) 5801408cc1fSYuval Mintz 581eaf3c0c6SChopra, Manish static void 582eaf3c0c6SChopra, Manish __qed_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv *p_req, 583eaf3c0c6SChopra, Manish struct qed_tunn_update_type *p_src, 584db803f36SNathan Chancellor enum qed_tunn_mode mask, u8 *p_cls) 585eaf3c0c6SChopra, Manish { 586eaf3c0c6SChopra, Manish if (p_src->b_update_mode) { 587eaf3c0c6SChopra, Manish p_req->tun_mode_update_mask |= BIT(mask); 588eaf3c0c6SChopra, Manish 589eaf3c0c6SChopra, Manish if (p_src->b_mode_enabled) 590eaf3c0c6SChopra, Manish p_req->tunn_mode |= BIT(mask); 591eaf3c0c6SChopra, Manish } 592eaf3c0c6SChopra, Manish 593eaf3c0c6SChopra, Manish *p_cls = p_src->tun_cls; 594eaf3c0c6SChopra, Manish } 595eaf3c0c6SChopra, Manish 596eaf3c0c6SChopra, Manish static void 597eaf3c0c6SChopra, Manish qed_vf_prep_tunn_req_tlv(struct vfpf_update_tunn_param_tlv *p_req, 598eaf3c0c6SChopra, Manish struct qed_tunn_update_type *p_src, 599db803f36SNathan Chancellor enum qed_tunn_mode mask, 600eaf3c0c6SChopra, Manish u8 *p_cls, struct qed_tunn_update_udp_port *p_port, 601eaf3c0c6SChopra, Manish u8 *p_update_port, u16 *p_udp_port) 602eaf3c0c6SChopra, Manish { 603eaf3c0c6SChopra, Manish if (p_port->b_update_port) { 604eaf3c0c6SChopra, Manish *p_update_port = 1; 605eaf3c0c6SChopra, Manish *p_udp_port = p_port->port; 606eaf3c0c6SChopra, Manish } 607eaf3c0c6SChopra, Manish 608eaf3c0c6SChopra, Manish __qed_vf_prep_tunn_req_tlv(p_req, p_src, mask, p_cls); 609eaf3c0c6SChopra, Manish } 610eaf3c0c6SChopra, Manish 611eaf3c0c6SChopra, Manish void qed_vf_set_vf_start_tunn_update_param(struct qed_tunnel_info *p_tun) 612eaf3c0c6SChopra, Manish { 613eaf3c0c6SChopra, Manish if (p_tun->vxlan.b_mode_enabled) 614eaf3c0c6SChopra, Manish p_tun->vxlan.b_update_mode = true; 615eaf3c0c6SChopra, Manish if (p_tun->l2_geneve.b_mode_enabled) 616eaf3c0c6SChopra, Manish p_tun->l2_geneve.b_update_mode = true; 617eaf3c0c6SChopra, Manish if (p_tun->ip_geneve.b_mode_enabled) 618eaf3c0c6SChopra, Manish p_tun->ip_geneve.b_update_mode = true; 619eaf3c0c6SChopra, Manish if (p_tun->l2_gre.b_mode_enabled) 620eaf3c0c6SChopra, Manish p_tun->l2_gre.b_update_mode = true; 621eaf3c0c6SChopra, Manish if (p_tun->ip_gre.b_mode_enabled) 622eaf3c0c6SChopra, Manish p_tun->ip_gre.b_update_mode = true; 623eaf3c0c6SChopra, Manish 624eaf3c0c6SChopra, Manish p_tun->b_update_rx_cls = true; 625eaf3c0c6SChopra, Manish p_tun->b_update_tx_cls = true; 626eaf3c0c6SChopra, Manish } 627eaf3c0c6SChopra, Manish 628eaf3c0c6SChopra, Manish static void 629eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(struct qed_tunn_update_type *p_tun, 630eaf3c0c6SChopra, Manish u16 feature_mask, u8 tunn_mode, 631eaf3c0c6SChopra, Manish u8 tunn_cls, enum qed_tunn_mode val) 632eaf3c0c6SChopra, Manish { 633eaf3c0c6SChopra, Manish if (feature_mask & BIT(val)) { 634eaf3c0c6SChopra, Manish p_tun->b_mode_enabled = tunn_mode; 635eaf3c0c6SChopra, Manish p_tun->tun_cls = tunn_cls; 636eaf3c0c6SChopra, Manish } else { 637eaf3c0c6SChopra, Manish p_tun->b_mode_enabled = false; 638eaf3c0c6SChopra, Manish } 639eaf3c0c6SChopra, Manish } 640eaf3c0c6SChopra, Manish 641eaf3c0c6SChopra, Manish static void qed_vf_update_tunn_param(struct qed_hwfn *p_hwfn, 642eaf3c0c6SChopra, Manish struct qed_tunnel_info *p_tun, 643eaf3c0c6SChopra, Manish struct pfvf_update_tunn_param_tlv *p_resp) 644eaf3c0c6SChopra, Manish { 645eaf3c0c6SChopra, Manish /* Update mode and classes provided by PF */ 646eaf3c0c6SChopra, Manish u16 feat_mask = p_resp->tunn_feature_mask; 647eaf3c0c6SChopra, Manish 648eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(&p_tun->vxlan, feat_mask, 649eaf3c0c6SChopra, Manish p_resp->vxlan_mode, p_resp->vxlan_clss, 650eaf3c0c6SChopra, Manish QED_MODE_VXLAN_TUNN); 651eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(&p_tun->l2_geneve, feat_mask, 652eaf3c0c6SChopra, Manish p_resp->l2geneve_mode, 653eaf3c0c6SChopra, Manish p_resp->l2geneve_clss, 654eaf3c0c6SChopra, Manish QED_MODE_L2GENEVE_TUNN); 655eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(&p_tun->ip_geneve, feat_mask, 656eaf3c0c6SChopra, Manish p_resp->ipgeneve_mode, 657eaf3c0c6SChopra, Manish p_resp->ipgeneve_clss, 658eaf3c0c6SChopra, Manish QED_MODE_IPGENEVE_TUNN); 659eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(&p_tun->l2_gre, feat_mask, 660eaf3c0c6SChopra, Manish p_resp->l2gre_mode, p_resp->l2gre_clss, 661eaf3c0c6SChopra, Manish QED_MODE_L2GRE_TUNN); 662eaf3c0c6SChopra, Manish __qed_vf_update_tunn_param(&p_tun->ip_gre, feat_mask, 663eaf3c0c6SChopra, Manish p_resp->ipgre_mode, p_resp->ipgre_clss, 664eaf3c0c6SChopra, Manish QED_MODE_IPGRE_TUNN); 665eaf3c0c6SChopra, Manish p_tun->geneve_port.port = p_resp->geneve_udp_port; 666eaf3c0c6SChopra, Manish p_tun->vxlan_port.port = p_resp->vxlan_udp_port; 667eaf3c0c6SChopra, Manish 668eaf3c0c6SChopra, Manish DP_VERBOSE(p_hwfn, QED_MSG_IOV, 669eaf3c0c6SChopra, Manish "tunn mode: vxlan=0x%x, l2geneve=0x%x, ipgeneve=0x%x, l2gre=0x%x, ipgre=0x%x", 670eaf3c0c6SChopra, Manish p_tun->vxlan.b_mode_enabled, p_tun->l2_geneve.b_mode_enabled, 671eaf3c0c6SChopra, Manish p_tun->ip_geneve.b_mode_enabled, 672eaf3c0c6SChopra, Manish p_tun->l2_gre.b_mode_enabled, p_tun->ip_gre.b_mode_enabled); 673eaf3c0c6SChopra, Manish } 674eaf3c0c6SChopra, Manish 675eaf3c0c6SChopra, Manish int qed_vf_pf_tunnel_param_update(struct qed_hwfn *p_hwfn, 676eaf3c0c6SChopra, Manish struct qed_tunnel_info *p_src) 677eaf3c0c6SChopra, Manish { 678eaf3c0c6SChopra, Manish struct qed_tunnel_info *p_tun = &p_hwfn->cdev->tunnel; 679eaf3c0c6SChopra, Manish struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 680eaf3c0c6SChopra, Manish struct pfvf_update_tunn_param_tlv *p_resp; 681eaf3c0c6SChopra, Manish struct vfpf_update_tunn_param_tlv *p_req; 682eaf3c0c6SChopra, Manish int rc; 683eaf3c0c6SChopra, Manish 684eaf3c0c6SChopra, Manish p_req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_UPDATE_TUNN_PARAM, 685eaf3c0c6SChopra, Manish sizeof(*p_req)); 686eaf3c0c6SChopra, Manish 687eaf3c0c6SChopra, Manish if (p_src->b_update_rx_cls && p_src->b_update_tx_cls) 688eaf3c0c6SChopra, Manish p_req->update_tun_cls = 1; 689eaf3c0c6SChopra, Manish 690eaf3c0c6SChopra, Manish qed_vf_prep_tunn_req_tlv(p_req, &p_src->vxlan, QED_MODE_VXLAN_TUNN, 691eaf3c0c6SChopra, Manish &p_req->vxlan_clss, &p_src->vxlan_port, 692eaf3c0c6SChopra, Manish &p_req->update_vxlan_port, 693eaf3c0c6SChopra, Manish &p_req->vxlan_port); 694eaf3c0c6SChopra, Manish qed_vf_prep_tunn_req_tlv(p_req, &p_src->l2_geneve, 695eaf3c0c6SChopra, Manish QED_MODE_L2GENEVE_TUNN, 696eaf3c0c6SChopra, Manish &p_req->l2geneve_clss, &p_src->geneve_port, 697eaf3c0c6SChopra, Manish &p_req->update_geneve_port, 698eaf3c0c6SChopra, Manish &p_req->geneve_port); 699eaf3c0c6SChopra, Manish __qed_vf_prep_tunn_req_tlv(p_req, &p_src->ip_geneve, 700eaf3c0c6SChopra, Manish QED_MODE_IPGENEVE_TUNN, 701eaf3c0c6SChopra, Manish &p_req->ipgeneve_clss); 702eaf3c0c6SChopra, Manish __qed_vf_prep_tunn_req_tlv(p_req, &p_src->l2_gre, 703eaf3c0c6SChopra, Manish QED_MODE_L2GRE_TUNN, &p_req->l2gre_clss); 704eaf3c0c6SChopra, Manish __qed_vf_prep_tunn_req_tlv(p_req, &p_src->ip_gre, 705eaf3c0c6SChopra, Manish QED_MODE_IPGRE_TUNN, &p_req->ipgre_clss); 706eaf3c0c6SChopra, Manish 707eaf3c0c6SChopra, Manish /* add list termination tlv */ 708eaf3c0c6SChopra, Manish qed_add_tlv(p_hwfn, &p_iov->offset, 709eaf3c0c6SChopra, Manish CHANNEL_TLV_LIST_END, 710eaf3c0c6SChopra, Manish sizeof(struct channel_list_end_tlv)); 711eaf3c0c6SChopra, Manish 712eaf3c0c6SChopra, Manish p_resp = &p_iov->pf2vf_reply->tunn_param_resp; 713eaf3c0c6SChopra, Manish rc = qed_send_msg2pf(p_hwfn, &p_resp->hdr.status, sizeof(*p_resp)); 714eaf3c0c6SChopra, Manish 715eaf3c0c6SChopra, Manish if (rc) 716eaf3c0c6SChopra, Manish goto exit; 717eaf3c0c6SChopra, Manish 718eaf3c0c6SChopra, Manish if (p_resp->hdr.status != PFVF_STATUS_SUCCESS) { 719eaf3c0c6SChopra, Manish DP_VERBOSE(p_hwfn, QED_MSG_IOV, 720eaf3c0c6SChopra, Manish "Failed to update tunnel parameters\n"); 721eaf3c0c6SChopra, Manish rc = -EINVAL; 722eaf3c0c6SChopra, Manish } 723eaf3c0c6SChopra, Manish 724eaf3c0c6SChopra, Manish qed_vf_update_tunn_param(p_hwfn, p_tun, p_resp); 725eaf3c0c6SChopra, Manish exit: 726eaf3c0c6SChopra, Manish qed_vf_pf_req_end(p_hwfn, rc); 727eaf3c0c6SChopra, Manish return rc; 728eaf3c0c6SChopra, Manish } 729eaf3c0c6SChopra, Manish 7303da7a37aSMintz, Yuval int 7313da7a37aSMintz, Yuval qed_vf_pf_rxq_start(struct qed_hwfn *p_hwfn, 7323da7a37aSMintz, Yuval struct qed_queue_cid *p_cid, 733dacd88d6SYuval Mintz u16 bd_max_bytes, 734dacd88d6SYuval Mintz dma_addr_t bd_chain_phys_addr, 735dacd88d6SYuval Mintz dma_addr_t cqe_pbl_addr, 736dacd88d6SYuval Mintz u16 cqe_pbl_size, void __iomem **pp_prod) 737dacd88d6SYuval Mintz { 738dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 739dacd88d6SYuval Mintz struct pfvf_start_queue_resp_tlv *resp; 740dacd88d6SYuval Mintz struct vfpf_start_rxq_tlv *req; 7413da7a37aSMintz, Yuval u8 rx_qid = p_cid->rel.queue_id; 742dacd88d6SYuval Mintz int rc; 743dacd88d6SYuval Mintz 744dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 745dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_RXQ, sizeof(*req)); 746dacd88d6SYuval Mintz 747dacd88d6SYuval Mintz req->rx_qid = rx_qid; 748dacd88d6SYuval Mintz req->cqe_pbl_addr = cqe_pbl_addr; 749dacd88d6SYuval Mintz req->cqe_pbl_size = cqe_pbl_size; 750dacd88d6SYuval Mintz req->rxq_addr = bd_chain_phys_addr; 751f604b17dSMintz, Yuval req->hw_sb = p_cid->sb_igu_id; 752f604b17dSMintz, Yuval req->sb_index = p_cid->sb_idx; 753dacd88d6SYuval Mintz req->bd_max_bytes = bd_max_bytes; 754dacd88d6SYuval Mintz req->stat_id = -1; 755dacd88d6SYuval Mintz 756d8c2c7e3SYuval Mintz /* If PF is legacy, we'll need to calculate producers ourselves 757d8c2c7e3SYuval Mintz * as well as clean them. 758d8c2c7e3SYuval Mintz */ 7593da7a37aSMintz, Yuval if (p_iov->b_pre_fp_hsi) { 760d8c2c7e3SYuval Mintz u8 hw_qid = p_iov->acquire_resp.resc.hw_qid[rx_qid]; 761d8c2c7e3SYuval Mintz u32 init_prod_val = 0; 762d8c2c7e3SYuval Mintz 7633da7a37aSMintz, Yuval *pp_prod = (u8 __iomem *) 7643da7a37aSMintz, Yuval p_hwfn->regview + 765d8c2c7e3SYuval Mintz MSTORM_QZONE_START(p_hwfn->cdev) + 766d8c2c7e3SYuval Mintz hw_qid * MSTORM_QZONE_SIZE; 767d8c2c7e3SYuval Mintz 768d8c2c7e3SYuval Mintz /* Init the rcq, rx bd and rx sge (if valid) producers to 0 */ 769d8c2c7e3SYuval Mintz __internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32), 770d8c2c7e3SYuval Mintz (u32 *)(&init_prod_val)); 771d8c2c7e3SYuval Mintz } 77208bc8f15SMintz, Yuval 77308bc8f15SMintz, Yuval qed_vf_pf_add_qid(p_hwfn, p_cid); 77408bc8f15SMintz, Yuval 775dacd88d6SYuval Mintz /* add list termination tlv */ 776dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 777dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 778dacd88d6SYuval Mintz 779dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->queue_start; 780dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 781dacd88d6SYuval Mintz if (rc) 782b0bccb69SYuval Mintz goto exit; 783dacd88d6SYuval Mintz 784b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 785b0bccb69SYuval Mintz rc = -EINVAL; 786b0bccb69SYuval Mintz goto exit; 787b0bccb69SYuval Mintz } 788dacd88d6SYuval Mintz 789dacd88d6SYuval Mintz /* Learn the address of the producer from the response */ 7903da7a37aSMintz, Yuval if (!p_iov->b_pre_fp_hsi) { 791b21290b7SYuval Mintz u32 init_prod_val = 0; 792dacd88d6SYuval Mintz 793dacd88d6SYuval Mintz *pp_prod = (u8 __iomem *)p_hwfn->regview + resp->offset; 794dacd88d6SYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 795dacd88d6SYuval Mintz "Rxq[0x%02x]: producer at %p [offset 0x%08x]\n", 796dacd88d6SYuval Mintz rx_qid, *pp_prod, resp->offset); 797dacd88d6SYuval Mintz 798dacd88d6SYuval Mintz /* Init the rcq, rx bd and rx sge (if valid) producers to 0 */ 799b21290b7SYuval Mintz __internal_ram_wr(p_hwfn, *pp_prod, sizeof(u32), 800dacd88d6SYuval Mintz (u32 *)&init_prod_val); 801dacd88d6SYuval Mintz } 802b0bccb69SYuval Mintz exit: 803b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 804dacd88d6SYuval Mintz 805dacd88d6SYuval Mintz return rc; 806dacd88d6SYuval Mintz } 807dacd88d6SYuval Mintz 8083da7a37aSMintz, Yuval int qed_vf_pf_rxq_stop(struct qed_hwfn *p_hwfn, 8093da7a37aSMintz, Yuval struct qed_queue_cid *p_cid, bool cqe_completion) 810dacd88d6SYuval Mintz { 811dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 812dacd88d6SYuval Mintz struct vfpf_stop_rxqs_tlv *req; 813dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp; 814dacd88d6SYuval Mintz int rc; 815dacd88d6SYuval Mintz 816dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 817dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_RXQS, sizeof(*req)); 818dacd88d6SYuval Mintz 8193da7a37aSMintz, Yuval req->rx_qid = p_cid->rel.queue_id; 820dacd88d6SYuval Mintz req->num_rxqs = 1; 821dacd88d6SYuval Mintz req->cqe_completion = cqe_completion; 822dacd88d6SYuval Mintz 82308bc8f15SMintz, Yuval qed_vf_pf_add_qid(p_hwfn, p_cid); 82408bc8f15SMintz, Yuval 825dacd88d6SYuval Mintz /* add list termination tlv */ 826dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 827dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 828dacd88d6SYuval Mintz 829dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 830dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 831dacd88d6SYuval Mintz if (rc) 832b0bccb69SYuval Mintz goto exit; 833dacd88d6SYuval Mintz 834b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 835b0bccb69SYuval Mintz rc = -EINVAL; 836b0bccb69SYuval Mintz goto exit; 837b0bccb69SYuval Mintz } 838b0bccb69SYuval Mintz 839b0bccb69SYuval Mintz exit: 840b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 841dacd88d6SYuval Mintz 842dacd88d6SYuval Mintz return rc; 843dacd88d6SYuval Mintz } 844dacd88d6SYuval Mintz 8453da7a37aSMintz, Yuval int 8463da7a37aSMintz, Yuval qed_vf_pf_txq_start(struct qed_hwfn *p_hwfn, 8473da7a37aSMintz, Yuval struct qed_queue_cid *p_cid, 848dacd88d6SYuval Mintz dma_addr_t pbl_addr, 849dacd88d6SYuval Mintz u16 pbl_size, void __iomem **pp_doorbell) 850dacd88d6SYuval Mintz { 851dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 8525040acf5SYuval Mintz struct pfvf_start_queue_resp_tlv *resp; 853dacd88d6SYuval Mintz struct vfpf_start_txq_tlv *req; 8543da7a37aSMintz, Yuval u16 qid = p_cid->rel.queue_id; 855dacd88d6SYuval Mintz int rc; 856dacd88d6SYuval Mintz 857dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 858dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_START_TXQ, sizeof(*req)); 859dacd88d6SYuval Mintz 8603da7a37aSMintz, Yuval req->tx_qid = qid; 861dacd88d6SYuval Mintz 862dacd88d6SYuval Mintz /* Tx */ 863dacd88d6SYuval Mintz req->pbl_addr = pbl_addr; 864dacd88d6SYuval Mintz req->pbl_size = pbl_size; 865f604b17dSMintz, Yuval req->hw_sb = p_cid->sb_igu_id; 866f604b17dSMintz, Yuval req->sb_index = p_cid->sb_idx; 867dacd88d6SYuval Mintz 86808bc8f15SMintz, Yuval qed_vf_pf_add_qid(p_hwfn, p_cid); 86908bc8f15SMintz, Yuval 870dacd88d6SYuval Mintz /* add list termination tlv */ 871dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 872dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 873dacd88d6SYuval Mintz 8745040acf5SYuval Mintz resp = &p_iov->pf2vf_reply->queue_start; 875dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 876dacd88d6SYuval Mintz if (rc) 8775040acf5SYuval Mintz goto exit; 878dacd88d6SYuval Mintz 8795040acf5SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 8805040acf5SYuval Mintz rc = -EINVAL; 8815040acf5SYuval Mintz goto exit; 8825040acf5SYuval Mintz } 883dacd88d6SYuval Mintz 884d8c2c7e3SYuval Mintz /* Modern PFs provide the actual offsets, while legacy 885d8c2c7e3SYuval Mintz * provided only the queue id. 886d8c2c7e3SYuval Mintz */ 887d8c2c7e3SYuval Mintz if (!p_iov->b_pre_fp_hsi) { 8883da7a37aSMintz, Yuval *pp_doorbell = (u8 __iomem *)p_hwfn->doorbells + resp->offset; 889d8c2c7e3SYuval Mintz } else { 8903da7a37aSMintz, Yuval u8 cid = p_iov->acquire_resp.resc.cid[qid]; 891d8c2c7e3SYuval Mintz 892d8c2c7e3SYuval Mintz *pp_doorbell = (u8 __iomem *)p_hwfn->doorbells + 8933da7a37aSMintz, Yuval qed_db_addr_vf(cid, 8943da7a37aSMintz, Yuval DQ_DEMS_LEGACY); 895d8c2c7e3SYuval Mintz } 896dacd88d6SYuval Mintz 8975040acf5SYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 898cbb8a12cSMintz, Yuval "Txq[0x%02x.%02x]: doorbell at %p [offset 0x%08x]\n", 899cbb8a12cSMintz, Yuval qid, p_cid->qid_usage_idx, *pp_doorbell, resp->offset); 9005040acf5SYuval Mintz exit: 901b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 902dacd88d6SYuval Mintz 903dacd88d6SYuval Mintz return rc; 904dacd88d6SYuval Mintz } 905dacd88d6SYuval Mintz 9063da7a37aSMintz, Yuval int qed_vf_pf_txq_stop(struct qed_hwfn *p_hwfn, struct qed_queue_cid *p_cid) 907dacd88d6SYuval Mintz { 908dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 909dacd88d6SYuval Mintz struct vfpf_stop_txqs_tlv *req; 910dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp; 911dacd88d6SYuval Mintz int rc; 912dacd88d6SYuval Mintz 913dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 914dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_STOP_TXQS, sizeof(*req)); 915dacd88d6SYuval Mintz 9163da7a37aSMintz, Yuval req->tx_qid = p_cid->rel.queue_id; 917dacd88d6SYuval Mintz req->num_txqs = 1; 918dacd88d6SYuval Mintz 91908bc8f15SMintz, Yuval qed_vf_pf_add_qid(p_hwfn, p_cid); 92008bc8f15SMintz, Yuval 921dacd88d6SYuval Mintz /* add list termination tlv */ 922dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 923dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 924dacd88d6SYuval Mintz 925dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 926dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 927dacd88d6SYuval Mintz if (rc) 928b0bccb69SYuval Mintz goto exit; 929dacd88d6SYuval Mintz 930b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 931b0bccb69SYuval Mintz rc = -EINVAL; 932b0bccb69SYuval Mintz goto exit; 933b0bccb69SYuval Mintz } 934b0bccb69SYuval Mintz 935b0bccb69SYuval Mintz exit: 936b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 937dacd88d6SYuval Mintz 938dacd88d6SYuval Mintz return rc; 939dacd88d6SYuval Mintz } 940dacd88d6SYuval Mintz 941dacd88d6SYuval Mintz int qed_vf_pf_vport_start(struct qed_hwfn *p_hwfn, 942dacd88d6SYuval Mintz u8 vport_id, 943dacd88d6SYuval Mintz u16 mtu, 944dacd88d6SYuval Mintz u8 inner_vlan_removal, 945dacd88d6SYuval Mintz enum qed_tpa_mode tpa_mode, 94608feecd7SYuval Mintz u8 max_buffers_per_cqe, u8 only_untagged) 947dacd88d6SYuval Mintz { 948dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 949dacd88d6SYuval Mintz struct vfpf_vport_start_tlv *req; 950dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp; 951dacd88d6SYuval Mintz int rc, i; 952dacd88d6SYuval Mintz 953dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 954dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_START, sizeof(*req)); 955dacd88d6SYuval Mintz 956dacd88d6SYuval Mintz req->mtu = mtu; 957dacd88d6SYuval Mintz req->vport_id = vport_id; 958dacd88d6SYuval Mintz req->inner_vlan_removal = inner_vlan_removal; 959dacd88d6SYuval Mintz req->tpa_mode = tpa_mode; 960dacd88d6SYuval Mintz req->max_buffers_per_cqe = max_buffers_per_cqe; 96108feecd7SYuval Mintz req->only_untagged = only_untagged; 962dacd88d6SYuval Mintz 963dacd88d6SYuval Mintz /* status blocks */ 96450a20714SMintz, Yuval for (i = 0; i < p_hwfn->vf_iov_info->acquire_resp.resc.num_sbs; i++) { 96550a20714SMintz, Yuval struct qed_sb_info *p_sb = p_hwfn->vf_iov_info->sbs_info[i]; 96650a20714SMintz, Yuval 96750a20714SMintz, Yuval if (p_sb) 96850a20714SMintz, Yuval req->sb_addr[i] = p_sb->sb_phys; 96950a20714SMintz, Yuval } 970dacd88d6SYuval Mintz 971dacd88d6SYuval Mintz /* add list termination tlv */ 972dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 973dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 974dacd88d6SYuval Mintz 975dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 976dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 977dacd88d6SYuval Mintz if (rc) 978b0bccb69SYuval Mintz goto exit; 979dacd88d6SYuval Mintz 980b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 981b0bccb69SYuval Mintz rc = -EINVAL; 982b0bccb69SYuval Mintz goto exit; 983b0bccb69SYuval Mintz } 984b0bccb69SYuval Mintz 985b0bccb69SYuval Mintz exit: 986b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 987dacd88d6SYuval Mintz 988dacd88d6SYuval Mintz return rc; 989dacd88d6SYuval Mintz } 990dacd88d6SYuval Mintz 991dacd88d6SYuval Mintz int qed_vf_pf_vport_stop(struct qed_hwfn *p_hwfn) 992dacd88d6SYuval Mintz { 993dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 994dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp; 995dacd88d6SYuval Mintz int rc; 996dacd88d6SYuval Mintz 997dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 998dacd88d6SYuval Mintz qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_TEARDOWN, 999dacd88d6SYuval Mintz sizeof(struct vfpf_first_tlv)); 1000dacd88d6SYuval Mintz 1001dacd88d6SYuval Mintz /* add list termination tlv */ 1002dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 1003dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 1004dacd88d6SYuval Mintz 1005dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 1006dacd88d6SYuval Mintz if (rc) 1007b0bccb69SYuval Mintz goto exit; 1008dacd88d6SYuval Mintz 1009b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 1010b0bccb69SYuval Mintz rc = -EINVAL; 1011b0bccb69SYuval Mintz goto exit; 1012b0bccb69SYuval Mintz } 1013b0bccb69SYuval Mintz 1014b0bccb69SYuval Mintz exit: 1015b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 1016dacd88d6SYuval Mintz 1017dacd88d6SYuval Mintz return rc; 1018dacd88d6SYuval Mintz } 1019dacd88d6SYuval Mintz 1020dacd88d6SYuval Mintz static bool 1021dacd88d6SYuval Mintz qed_vf_handle_vp_update_is_needed(struct qed_hwfn *p_hwfn, 1022dacd88d6SYuval Mintz struct qed_sp_vport_update_params *p_data, 1023dacd88d6SYuval Mintz u16 tlv) 1024dacd88d6SYuval Mintz { 1025dacd88d6SYuval Mintz switch (tlv) { 1026dacd88d6SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_ACTIVATE: 1027dacd88d6SYuval Mintz return !!(p_data->update_vport_active_rx_flg || 1028dacd88d6SYuval Mintz p_data->update_vport_active_tx_flg); 102917b235c1SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_TX_SWITCH: 103017b235c1SYuval Mintz return !!p_data->update_tx_switching_flg; 103117b235c1SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_VLAN_STRIP: 103217b235c1SYuval Mintz return !!p_data->update_inner_vlan_removal_flg; 103308feecd7SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN: 103408feecd7SYuval Mintz return !!p_data->update_accept_any_vlan_flg; 1035dacd88d6SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_MCAST: 1036dacd88d6SYuval Mintz return !!p_data->update_approx_mcast_flg; 1037dacd88d6SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM: 1038dacd88d6SYuval Mintz return !!(p_data->accept_flags.update_rx_mode_config || 1039dacd88d6SYuval Mintz p_data->accept_flags.update_tx_mode_config); 1040dacd88d6SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_RSS: 1041dacd88d6SYuval Mintz return !!p_data->rss_params; 104217b235c1SYuval Mintz case CHANNEL_TLV_VPORT_UPDATE_SGE_TPA: 104317b235c1SYuval Mintz return !!p_data->sge_tpa_params; 1044dacd88d6SYuval Mintz default: 1045dacd88d6SYuval Mintz DP_INFO(p_hwfn, "Unexpected vport-update TLV[%d]\n", 1046dacd88d6SYuval Mintz tlv); 1047dacd88d6SYuval Mintz return false; 1048dacd88d6SYuval Mintz } 1049dacd88d6SYuval Mintz } 1050dacd88d6SYuval Mintz 1051dacd88d6SYuval Mintz static void 1052dacd88d6SYuval Mintz qed_vf_handle_vp_update_tlvs_resp(struct qed_hwfn *p_hwfn, 1053dacd88d6SYuval Mintz struct qed_sp_vport_update_params *p_data) 1054dacd88d6SYuval Mintz { 1055dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1056dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *p_resp; 1057dacd88d6SYuval Mintz u16 tlv; 1058dacd88d6SYuval Mintz 1059dacd88d6SYuval Mintz for (tlv = CHANNEL_TLV_VPORT_UPDATE_ACTIVATE; 1060dacd88d6SYuval Mintz tlv < CHANNEL_TLV_VPORT_UPDATE_MAX; tlv++) { 1061dacd88d6SYuval Mintz if (!qed_vf_handle_vp_update_is_needed(p_hwfn, p_data, tlv)) 1062dacd88d6SYuval Mintz continue; 1063dacd88d6SYuval Mintz 1064dacd88d6SYuval Mintz p_resp = (struct pfvf_def_resp_tlv *) 1065dacd88d6SYuval Mintz qed_iov_search_list_tlvs(p_hwfn, p_iov->pf2vf_reply, 1066dacd88d6SYuval Mintz tlv); 1067dacd88d6SYuval Mintz if (p_resp && p_resp->hdr.status) 1068dacd88d6SYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 1069dacd88d6SYuval Mintz "TLV[%d] Configuration %s\n", 1070dacd88d6SYuval Mintz tlv, 1071dacd88d6SYuval Mintz (p_resp && p_resp->hdr.status) ? "succeeded" 1072dacd88d6SYuval Mintz : "failed"); 1073dacd88d6SYuval Mintz } 1074dacd88d6SYuval Mintz } 1075dacd88d6SYuval Mintz 1076dacd88d6SYuval Mintz int qed_vf_pf_vport_update(struct qed_hwfn *p_hwfn, 1077dacd88d6SYuval Mintz struct qed_sp_vport_update_params *p_params) 1078dacd88d6SYuval Mintz { 1079dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1080dacd88d6SYuval Mintz struct vfpf_vport_update_tlv *req; 1081dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp; 1082dacd88d6SYuval Mintz u8 update_rx, update_tx; 1083dacd88d6SYuval Mintz u32 resp_size = 0; 1084dacd88d6SYuval Mintz u16 size, tlv; 1085dacd88d6SYuval Mintz int rc; 1086dacd88d6SYuval Mintz 1087dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 1088dacd88d6SYuval Mintz resp_size = sizeof(*resp); 1089dacd88d6SYuval Mintz 1090dacd88d6SYuval Mintz update_rx = p_params->update_vport_active_rx_flg; 1091dacd88d6SYuval Mintz update_tx = p_params->update_vport_active_tx_flg; 1092dacd88d6SYuval Mintz 1093dacd88d6SYuval Mintz /* clear mailbox and prep header tlv */ 1094dacd88d6SYuval Mintz qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_VPORT_UPDATE, sizeof(*req)); 1095dacd88d6SYuval Mintz 1096dacd88d6SYuval Mintz /* Prepare extended tlvs */ 1097dacd88d6SYuval Mintz if (update_rx || update_tx) { 1098dacd88d6SYuval Mintz struct vfpf_vport_update_activate_tlv *p_act_tlv; 1099dacd88d6SYuval Mintz 1100dacd88d6SYuval Mintz size = sizeof(struct vfpf_vport_update_activate_tlv); 1101dacd88d6SYuval Mintz p_act_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, 1102dacd88d6SYuval Mintz CHANNEL_TLV_VPORT_UPDATE_ACTIVATE, 1103dacd88d6SYuval Mintz size); 1104dacd88d6SYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 1105dacd88d6SYuval Mintz 1106dacd88d6SYuval Mintz if (update_rx) { 1107dacd88d6SYuval Mintz p_act_tlv->update_rx = update_rx; 1108dacd88d6SYuval Mintz p_act_tlv->active_rx = p_params->vport_active_rx_flg; 1109dacd88d6SYuval Mintz } 1110dacd88d6SYuval Mintz 1111dacd88d6SYuval Mintz if (update_tx) { 1112dacd88d6SYuval Mintz p_act_tlv->update_tx = update_tx; 1113dacd88d6SYuval Mintz p_act_tlv->active_tx = p_params->vport_active_tx_flg; 1114dacd88d6SYuval Mintz } 1115dacd88d6SYuval Mintz } 1116dacd88d6SYuval Mintz 1117831bfb0eSYuval Mintz if (p_params->update_tx_switching_flg) { 1118831bfb0eSYuval Mintz struct vfpf_vport_update_tx_switch_tlv *p_tx_switch_tlv; 1119831bfb0eSYuval Mintz 1120831bfb0eSYuval Mintz size = sizeof(struct vfpf_vport_update_tx_switch_tlv); 1121831bfb0eSYuval Mintz tlv = CHANNEL_TLV_VPORT_UPDATE_TX_SWITCH; 1122831bfb0eSYuval Mintz p_tx_switch_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, 1123831bfb0eSYuval Mintz tlv, size); 1124831bfb0eSYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 1125831bfb0eSYuval Mintz 1126831bfb0eSYuval Mintz p_tx_switch_tlv->tx_switching = p_params->tx_switching_flg; 1127831bfb0eSYuval Mintz } 1128831bfb0eSYuval Mintz 1129dacd88d6SYuval Mintz if (p_params->update_approx_mcast_flg) { 1130dacd88d6SYuval Mintz struct vfpf_vport_update_mcast_bin_tlv *p_mcast_tlv; 1131dacd88d6SYuval Mintz 1132dacd88d6SYuval Mintz size = sizeof(struct vfpf_vport_update_mcast_bin_tlv); 1133dacd88d6SYuval Mintz p_mcast_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, 1134dacd88d6SYuval Mintz CHANNEL_TLV_VPORT_UPDATE_MCAST, size); 1135dacd88d6SYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 1136dacd88d6SYuval Mintz 1137dacd88d6SYuval Mintz memcpy(p_mcast_tlv->bins, p_params->bins, 113825c020a9SSudarsana Reddy Kalluru sizeof(u32) * ETH_MULTICAST_MAC_BINS_IN_REGS); 1139dacd88d6SYuval Mintz } 1140dacd88d6SYuval Mintz 1141dacd88d6SYuval Mintz update_rx = p_params->accept_flags.update_rx_mode_config; 1142dacd88d6SYuval Mintz update_tx = p_params->accept_flags.update_tx_mode_config; 1143dacd88d6SYuval Mintz 1144dacd88d6SYuval Mintz if (update_rx || update_tx) { 1145dacd88d6SYuval Mintz struct vfpf_vport_update_accept_param_tlv *p_accept_tlv; 1146dacd88d6SYuval Mintz 1147dacd88d6SYuval Mintz tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_PARAM; 1148dacd88d6SYuval Mintz size = sizeof(struct vfpf_vport_update_accept_param_tlv); 1149dacd88d6SYuval Mintz p_accept_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, tlv, size); 1150dacd88d6SYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 1151dacd88d6SYuval Mintz 1152dacd88d6SYuval Mintz if (update_rx) { 1153dacd88d6SYuval Mintz p_accept_tlv->update_rx_mode = update_rx; 1154dacd88d6SYuval Mintz p_accept_tlv->rx_accept_filter = 1155dacd88d6SYuval Mintz p_params->accept_flags.rx_accept_filter; 1156dacd88d6SYuval Mintz } 1157dacd88d6SYuval Mintz 1158dacd88d6SYuval Mintz if (update_tx) { 1159dacd88d6SYuval Mintz p_accept_tlv->update_tx_mode = update_tx; 1160dacd88d6SYuval Mintz p_accept_tlv->tx_accept_filter = 1161dacd88d6SYuval Mintz p_params->accept_flags.tx_accept_filter; 1162dacd88d6SYuval Mintz } 1163dacd88d6SYuval Mintz } 1164dacd88d6SYuval Mintz 1165dacd88d6SYuval Mintz if (p_params->rss_params) { 1166dacd88d6SYuval Mintz struct qed_rss_params *rss_params = p_params->rss_params; 1167dacd88d6SYuval Mintz struct vfpf_vport_update_rss_tlv *p_rss_tlv; 1168f29ffdb6SMintz, Yuval int i, table_size; 1169dacd88d6SYuval Mintz 1170dacd88d6SYuval Mintz size = sizeof(struct vfpf_vport_update_rss_tlv); 1171dacd88d6SYuval Mintz p_rss_tlv = qed_add_tlv(p_hwfn, 1172dacd88d6SYuval Mintz &p_iov->offset, 1173dacd88d6SYuval Mintz CHANNEL_TLV_VPORT_UPDATE_RSS, size); 1174dacd88d6SYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 1175dacd88d6SYuval Mintz 1176dacd88d6SYuval Mintz if (rss_params->update_rss_config) 1177dacd88d6SYuval Mintz p_rss_tlv->update_rss_flags |= 1178dacd88d6SYuval Mintz VFPF_UPDATE_RSS_CONFIG_FLAG; 1179dacd88d6SYuval Mintz if (rss_params->update_rss_capabilities) 1180dacd88d6SYuval Mintz p_rss_tlv->update_rss_flags |= 1181dacd88d6SYuval Mintz VFPF_UPDATE_RSS_CAPS_FLAG; 1182dacd88d6SYuval Mintz if (rss_params->update_rss_ind_table) 1183dacd88d6SYuval Mintz p_rss_tlv->update_rss_flags |= 1184dacd88d6SYuval Mintz VFPF_UPDATE_RSS_IND_TABLE_FLAG; 1185dacd88d6SYuval Mintz if (rss_params->update_rss_key) 1186dacd88d6SYuval Mintz p_rss_tlv->update_rss_flags |= VFPF_UPDATE_RSS_KEY_FLAG; 1187dacd88d6SYuval Mintz 1188dacd88d6SYuval Mintz p_rss_tlv->rss_enable = rss_params->rss_enable; 1189dacd88d6SYuval Mintz p_rss_tlv->rss_caps = rss_params->rss_caps; 1190dacd88d6SYuval Mintz p_rss_tlv->rss_table_size_log = rss_params->rss_table_size_log; 1191f29ffdb6SMintz, Yuval 1192f29ffdb6SMintz, Yuval table_size = min_t(int, T_ETH_INDIRECTION_TABLE_SIZE, 1193f29ffdb6SMintz, Yuval 1 << p_rss_tlv->rss_table_size_log); 1194f29ffdb6SMintz, Yuval for (i = 0; i < table_size; i++) { 1195f29ffdb6SMintz, Yuval struct qed_queue_cid *p_queue; 1196f29ffdb6SMintz, Yuval 1197f29ffdb6SMintz, Yuval p_queue = rss_params->rss_ind_table[i]; 1198f29ffdb6SMintz, Yuval p_rss_tlv->rss_ind_table[i] = p_queue->rel.queue_id; 1199f29ffdb6SMintz, Yuval } 1200dacd88d6SYuval Mintz memcpy(p_rss_tlv->rss_key, rss_params->rss_key, 1201dacd88d6SYuval Mintz sizeof(rss_params->rss_key)); 1202dacd88d6SYuval Mintz } 1203dacd88d6SYuval Mintz 120408feecd7SYuval Mintz if (p_params->update_accept_any_vlan_flg) { 120508feecd7SYuval Mintz struct vfpf_vport_update_accept_any_vlan_tlv *p_any_vlan_tlv; 120608feecd7SYuval Mintz 120708feecd7SYuval Mintz size = sizeof(struct vfpf_vport_update_accept_any_vlan_tlv); 120808feecd7SYuval Mintz tlv = CHANNEL_TLV_VPORT_UPDATE_ACCEPT_ANY_VLAN; 120908feecd7SYuval Mintz p_any_vlan_tlv = qed_add_tlv(p_hwfn, &p_iov->offset, tlv, size); 121008feecd7SYuval Mintz 121108feecd7SYuval Mintz resp_size += sizeof(struct pfvf_def_resp_tlv); 121208feecd7SYuval Mintz p_any_vlan_tlv->accept_any_vlan = p_params->accept_any_vlan; 121308feecd7SYuval Mintz p_any_vlan_tlv->update_accept_any_vlan_flg = 121408feecd7SYuval Mintz p_params->update_accept_any_vlan_flg; 121508feecd7SYuval Mintz } 121608feecd7SYuval Mintz 1217dacd88d6SYuval Mintz /* add list termination tlv */ 1218dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 1219dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 1220dacd88d6SYuval Mintz 1221dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, resp_size); 1222dacd88d6SYuval Mintz if (rc) 1223b0bccb69SYuval Mintz goto exit; 1224dacd88d6SYuval Mintz 1225b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 1226b0bccb69SYuval Mintz rc = -EINVAL; 1227b0bccb69SYuval Mintz goto exit; 1228b0bccb69SYuval Mintz } 1229dacd88d6SYuval Mintz 1230dacd88d6SYuval Mintz qed_vf_handle_vp_update_tlvs_resp(p_hwfn, p_params); 1231dacd88d6SYuval Mintz 1232b0bccb69SYuval Mintz exit: 1233b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 1234b0bccb69SYuval Mintz 1235dacd88d6SYuval Mintz return rc; 1236dacd88d6SYuval Mintz } 1237dacd88d6SYuval Mintz 12380b55e27dSYuval Mintz int qed_vf_pf_reset(struct qed_hwfn *p_hwfn) 12390b55e27dSYuval Mintz { 12400b55e27dSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 12410b55e27dSYuval Mintz struct pfvf_def_resp_tlv *resp; 12420b55e27dSYuval Mintz struct vfpf_first_tlv *req; 12430b55e27dSYuval Mintz int rc; 12440b55e27dSYuval Mintz 12450b55e27dSYuval Mintz /* clear mailbox and prep first tlv */ 12460b55e27dSYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_CLOSE, sizeof(*req)); 12470b55e27dSYuval Mintz 12480b55e27dSYuval Mintz /* add list termination tlv */ 12490b55e27dSYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 12500b55e27dSYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 12510b55e27dSYuval Mintz 12520b55e27dSYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 12530b55e27dSYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 12540b55e27dSYuval Mintz if (rc) 1255b0bccb69SYuval Mintz goto exit; 12560b55e27dSYuval Mintz 1257b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 1258b0bccb69SYuval Mintz rc = -EAGAIN; 1259b0bccb69SYuval Mintz goto exit; 1260b0bccb69SYuval Mintz } 12610b55e27dSYuval Mintz 12620b55e27dSYuval Mintz p_hwfn->b_int_enabled = 0; 12630b55e27dSYuval Mintz 1264b0bccb69SYuval Mintz exit: 1265b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 1266b0bccb69SYuval Mintz 1267b0bccb69SYuval Mintz return rc; 12680b55e27dSYuval Mintz } 12690b55e27dSYuval Mintz 1270dacd88d6SYuval Mintz void qed_vf_pf_filter_mcast(struct qed_hwfn *p_hwfn, 1271dacd88d6SYuval Mintz struct qed_filter_mcast *p_filter_cmd) 1272dacd88d6SYuval Mintz { 1273dacd88d6SYuval Mintz struct qed_sp_vport_update_params sp_params; 1274dacd88d6SYuval Mintz int i; 1275dacd88d6SYuval Mintz 1276dacd88d6SYuval Mintz memset(&sp_params, 0, sizeof(sp_params)); 1277dacd88d6SYuval Mintz sp_params.update_approx_mcast_flg = 1; 1278dacd88d6SYuval Mintz 1279dacd88d6SYuval Mintz if (p_filter_cmd->opcode == QED_FILTER_ADD) { 1280dacd88d6SYuval Mintz for (i = 0; i < p_filter_cmd->num_mc_addrs; i++) { 1281dacd88d6SYuval Mintz u32 bit; 1282dacd88d6SYuval Mintz 1283dacd88d6SYuval Mintz bit = qed_mcast_bin_from_mac(p_filter_cmd->mac[i]); 128425c020a9SSudarsana Reddy Kalluru sp_params.bins[bit / 32] |= 1 << (bit % 32); 1285dacd88d6SYuval Mintz } 1286dacd88d6SYuval Mintz } 1287dacd88d6SYuval Mintz 1288dacd88d6SYuval Mintz qed_vf_pf_vport_update(p_hwfn, &sp_params); 1289dacd88d6SYuval Mintz } 1290dacd88d6SYuval Mintz 1291dacd88d6SYuval Mintz int qed_vf_pf_filter_ucast(struct qed_hwfn *p_hwfn, 1292dacd88d6SYuval Mintz struct qed_filter_ucast *p_ucast) 1293dacd88d6SYuval Mintz { 1294dacd88d6SYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1295dacd88d6SYuval Mintz struct vfpf_ucast_filter_tlv *req; 1296dacd88d6SYuval Mintz struct pfvf_def_resp_tlv *resp; 1297dacd88d6SYuval Mintz int rc; 1298dacd88d6SYuval Mintz 1299dacd88d6SYuval Mintz /* clear mailbox and prep first tlv */ 1300dacd88d6SYuval Mintz req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_UCAST_FILTER, sizeof(*req)); 1301dacd88d6SYuval Mintz req->opcode = (u8) p_ucast->opcode; 1302dacd88d6SYuval Mintz req->type = (u8) p_ucast->type; 1303dacd88d6SYuval Mintz memcpy(req->mac, p_ucast->mac, ETH_ALEN); 1304dacd88d6SYuval Mintz req->vlan = p_ucast->vlan; 1305dacd88d6SYuval Mintz 1306dacd88d6SYuval Mintz /* add list termination tlv */ 1307dacd88d6SYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 1308dacd88d6SYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 1309dacd88d6SYuval Mintz 1310dacd88d6SYuval Mintz resp = &p_iov->pf2vf_reply->default_resp; 1311dacd88d6SYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 1312dacd88d6SYuval Mintz if (rc) 1313b0bccb69SYuval Mintz goto exit; 1314b0bccb69SYuval Mintz 1315b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 1316b0bccb69SYuval Mintz rc = -EAGAIN; 1317b0bccb69SYuval Mintz goto exit; 1318b0bccb69SYuval Mintz } 1319b0bccb69SYuval Mintz 1320b0bccb69SYuval Mintz exit: 1321b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 1322b0bccb69SYuval Mintz 1323dacd88d6SYuval Mintz return rc; 1324dacd88d6SYuval Mintz } 1325dacd88d6SYuval Mintz 13260b55e27dSYuval Mintz int qed_vf_pf_int_cleanup(struct qed_hwfn *p_hwfn) 13270b55e27dSYuval Mintz { 13280b55e27dSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 13290b55e27dSYuval Mintz struct pfvf_def_resp_tlv *resp = &p_iov->pf2vf_reply->default_resp; 13300b55e27dSYuval Mintz int rc; 13310b55e27dSYuval Mintz 13320b55e27dSYuval Mintz /* clear mailbox and prep first tlv */ 13330b55e27dSYuval Mintz qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_INT_CLEANUP, 13340b55e27dSYuval Mintz sizeof(struct vfpf_first_tlv)); 13350b55e27dSYuval Mintz 13360b55e27dSYuval Mintz /* add list termination tlv */ 13370b55e27dSYuval Mintz qed_add_tlv(p_hwfn, &p_iov->offset, 13380b55e27dSYuval Mintz CHANNEL_TLV_LIST_END, sizeof(struct channel_list_end_tlv)); 13390b55e27dSYuval Mintz 13400b55e27dSYuval Mintz rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 13410b55e27dSYuval Mintz if (rc) 1342b0bccb69SYuval Mintz goto exit; 1343b0bccb69SYuval Mintz 1344b0bccb69SYuval Mintz if (resp->hdr.status != PFVF_STATUS_SUCCESS) { 1345b0bccb69SYuval Mintz rc = -EINVAL; 1346b0bccb69SYuval Mintz goto exit; 1347b0bccb69SYuval Mintz } 1348b0bccb69SYuval Mintz 1349b0bccb69SYuval Mintz exit: 1350b0bccb69SYuval Mintz qed_vf_pf_req_end(p_hwfn, rc); 1351b0bccb69SYuval Mintz 13520b55e27dSYuval Mintz return rc; 13530b55e27dSYuval Mintz } 13540b55e27dSYuval Mintz 1355bf5a94bfSRahul Verma int qed_vf_pf_get_coalesce(struct qed_hwfn *p_hwfn, 1356bf5a94bfSRahul Verma u16 *p_coal, struct qed_queue_cid *p_cid) 1357bf5a94bfSRahul Verma { 1358bf5a94bfSRahul Verma struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1359bf5a94bfSRahul Verma struct pfvf_read_coal_resp_tlv *resp; 1360bf5a94bfSRahul Verma struct vfpf_read_coal_req_tlv *req; 1361bf5a94bfSRahul Verma int rc; 1362bf5a94bfSRahul Verma 1363bf5a94bfSRahul Verma /* clear mailbox and prep header tlv */ 1364bf5a94bfSRahul Verma req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_COALESCE_READ, sizeof(*req)); 1365bf5a94bfSRahul Verma req->qid = p_cid->rel.queue_id; 1366bf5a94bfSRahul Verma req->is_rx = p_cid->b_is_rx ? 1 : 0; 1367bf5a94bfSRahul Verma 1368bf5a94bfSRahul Verma qed_add_tlv(p_hwfn, &p_iov->offset, CHANNEL_TLV_LIST_END, 1369bf5a94bfSRahul Verma sizeof(struct channel_list_end_tlv)); 1370bf5a94bfSRahul Verma resp = &p_iov->pf2vf_reply->read_coal_resp; 1371bf5a94bfSRahul Verma 1372bf5a94bfSRahul Verma rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 1373bf5a94bfSRahul Verma if (rc) 1374bf5a94bfSRahul Verma goto exit; 1375bf5a94bfSRahul Verma 1376bf5a94bfSRahul Verma if (resp->hdr.status != PFVF_STATUS_SUCCESS) 1377bf5a94bfSRahul Verma goto exit; 1378bf5a94bfSRahul Verma 1379bf5a94bfSRahul Verma *p_coal = resp->coal; 1380bf5a94bfSRahul Verma exit: 1381bf5a94bfSRahul Verma qed_vf_pf_req_end(p_hwfn, rc); 1382bf5a94bfSRahul Verma 1383bf5a94bfSRahul Verma return rc; 1384bf5a94bfSRahul Verma } 1385bf5a94bfSRahul Verma 1386477f2d14SRahul Verma int 1387809c45a0SShahed Shaikh qed_vf_pf_bulletin_update_mac(struct qed_hwfn *p_hwfn, 1388809c45a0SShahed Shaikh u8 *p_mac) 1389809c45a0SShahed Shaikh { 1390809c45a0SShahed Shaikh struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1391809c45a0SShahed Shaikh struct vfpf_bulletin_update_mac_tlv *p_req; 1392809c45a0SShahed Shaikh struct pfvf_def_resp_tlv *p_resp; 1393809c45a0SShahed Shaikh int rc; 1394809c45a0SShahed Shaikh 1395809c45a0SShahed Shaikh if (!p_mac) 1396809c45a0SShahed Shaikh return -EINVAL; 1397809c45a0SShahed Shaikh 1398809c45a0SShahed Shaikh /* clear mailbox and prep header tlv */ 1399809c45a0SShahed Shaikh p_req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_BULLETIN_UPDATE_MAC, 1400809c45a0SShahed Shaikh sizeof(*p_req)); 1401809c45a0SShahed Shaikh ether_addr_copy(p_req->mac, p_mac); 1402809c45a0SShahed Shaikh DP_VERBOSE(p_hwfn, QED_MSG_IOV, 1403809c45a0SShahed Shaikh "Requesting bulletin update for MAC[%pM]\n", p_mac); 1404809c45a0SShahed Shaikh 1405809c45a0SShahed Shaikh /* add list termination tlv */ 1406809c45a0SShahed Shaikh qed_add_tlv(p_hwfn, &p_iov->offset, CHANNEL_TLV_LIST_END, 1407809c45a0SShahed Shaikh sizeof(struct channel_list_end_tlv)); 1408809c45a0SShahed Shaikh 1409809c45a0SShahed Shaikh p_resp = &p_iov->pf2vf_reply->default_resp; 1410809c45a0SShahed Shaikh rc = qed_send_msg2pf(p_hwfn, &p_resp->hdr.status, sizeof(*p_resp)); 1411809c45a0SShahed Shaikh qed_vf_pf_req_end(p_hwfn, rc); 1412809c45a0SShahed Shaikh return rc; 1413809c45a0SShahed Shaikh } 1414809c45a0SShahed Shaikh 1415809c45a0SShahed Shaikh int 1416477f2d14SRahul Verma qed_vf_pf_set_coalesce(struct qed_hwfn *p_hwfn, 1417477f2d14SRahul Verma u16 rx_coal, u16 tx_coal, struct qed_queue_cid *p_cid) 1418477f2d14SRahul Verma { 1419477f2d14SRahul Verma struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 1420477f2d14SRahul Verma struct vfpf_update_coalesce *req; 1421477f2d14SRahul Verma struct pfvf_def_resp_tlv *resp; 1422477f2d14SRahul Verma int rc; 1423477f2d14SRahul Verma 1424477f2d14SRahul Verma /* clear mailbox and prep header tlv */ 1425477f2d14SRahul Verma req = qed_vf_pf_prep(p_hwfn, CHANNEL_TLV_COALESCE_UPDATE, sizeof(*req)); 1426477f2d14SRahul Verma 1427477f2d14SRahul Verma req->rx_coal = rx_coal; 1428477f2d14SRahul Verma req->tx_coal = tx_coal; 1429477f2d14SRahul Verma req->qid = p_cid->rel.queue_id; 1430477f2d14SRahul Verma 1431477f2d14SRahul Verma DP_VERBOSE(p_hwfn, 1432477f2d14SRahul Verma QED_MSG_IOV, 1433477f2d14SRahul Verma "Setting coalesce rx_coal = %d, tx_coal = %d at queue = %d\n", 1434477f2d14SRahul Verma rx_coal, tx_coal, req->qid); 1435477f2d14SRahul Verma 1436477f2d14SRahul Verma /* add list termination tlv */ 1437477f2d14SRahul Verma qed_add_tlv(p_hwfn, &p_iov->offset, CHANNEL_TLV_LIST_END, 1438477f2d14SRahul Verma sizeof(struct channel_list_end_tlv)); 1439477f2d14SRahul Verma 1440477f2d14SRahul Verma resp = &p_iov->pf2vf_reply->default_resp; 1441477f2d14SRahul Verma rc = qed_send_msg2pf(p_hwfn, &resp->hdr.status, sizeof(*resp)); 1442477f2d14SRahul Verma if (rc) 1443477f2d14SRahul Verma goto exit; 1444477f2d14SRahul Verma 1445477f2d14SRahul Verma if (resp->hdr.status != PFVF_STATUS_SUCCESS) 1446477f2d14SRahul Verma goto exit; 1447477f2d14SRahul Verma 1448477f2d14SRahul Verma if (rx_coal) 1449477f2d14SRahul Verma p_hwfn->cdev->rx_coalesce_usecs = rx_coal; 1450477f2d14SRahul Verma 1451477f2d14SRahul Verma if (tx_coal) 1452477f2d14SRahul Verma p_hwfn->cdev->tx_coalesce_usecs = tx_coal; 1453477f2d14SRahul Verma 1454477f2d14SRahul Verma exit: 1455477f2d14SRahul Verma qed_vf_pf_req_end(p_hwfn, rc); 1456477f2d14SRahul Verma return rc; 1457477f2d14SRahul Verma } 1458477f2d14SRahul Verma 14591408cc1fSYuval Mintz u16 qed_vf_get_igu_sb_id(struct qed_hwfn *p_hwfn, u16 sb_id) 14601408cc1fSYuval Mintz { 14611408cc1fSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 14621408cc1fSYuval Mintz 14631408cc1fSYuval Mintz if (!p_iov) { 14641408cc1fSYuval Mintz DP_NOTICE(p_hwfn, "vf_sriov_info isn't initialized\n"); 14651408cc1fSYuval Mintz return 0; 14661408cc1fSYuval Mintz } 14671408cc1fSYuval Mintz 14681408cc1fSYuval Mintz return p_iov->acquire_resp.resc.hw_sbs[sb_id].hw_sb_id; 14691408cc1fSYuval Mintz } 14701408cc1fSYuval Mintz 147150a20714SMintz, Yuval void qed_vf_set_sb_info(struct qed_hwfn *p_hwfn, 147250a20714SMintz, Yuval u16 sb_id, struct qed_sb_info *p_sb) 147350a20714SMintz, Yuval { 147450a20714SMintz, Yuval struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 147550a20714SMintz, Yuval 147650a20714SMintz, Yuval if (!p_iov) { 147750a20714SMintz, Yuval DP_NOTICE(p_hwfn, "vf_sriov_info isn't initialized\n"); 147850a20714SMintz, Yuval return; 147950a20714SMintz, Yuval } 148050a20714SMintz, Yuval 148150a20714SMintz, Yuval if (sb_id >= PFVF_MAX_SBS_PER_VF) { 148250a20714SMintz, Yuval DP_NOTICE(p_hwfn, "Can't configure SB %04x\n", sb_id); 148350a20714SMintz, Yuval return; 148450a20714SMintz, Yuval } 148550a20714SMintz, Yuval 148650a20714SMintz, Yuval p_iov->sbs_info[sb_id] = p_sb; 148750a20714SMintz, Yuval } 148850a20714SMintz, Yuval 148936558c3dSYuval Mintz int qed_vf_read_bulletin(struct qed_hwfn *p_hwfn, u8 *p_change) 149036558c3dSYuval Mintz { 149136558c3dSYuval Mintz struct qed_vf_iov *p_iov = p_hwfn->vf_iov_info; 149236558c3dSYuval Mintz struct qed_bulletin_content shadow; 149336558c3dSYuval Mintz u32 crc, crc_size; 149436558c3dSYuval Mintz 149536558c3dSYuval Mintz crc_size = sizeof(p_iov->bulletin.p_virt->crc); 149636558c3dSYuval Mintz *p_change = 0; 149736558c3dSYuval Mintz 149836558c3dSYuval Mintz /* Need to guarantee PF is not in the middle of writing it */ 149936558c3dSYuval Mintz memcpy(&shadow, p_iov->bulletin.p_virt, p_iov->bulletin.size); 150036558c3dSYuval Mintz 150136558c3dSYuval Mintz /* If version did not update, no need to do anything */ 150236558c3dSYuval Mintz if (shadow.version == p_iov->bulletin_shadow.version) 150336558c3dSYuval Mintz return 0; 150436558c3dSYuval Mintz 150536558c3dSYuval Mintz /* Verify the bulletin we see is valid */ 150636558c3dSYuval Mintz crc = crc32(0, (u8 *)&shadow + crc_size, 150736558c3dSYuval Mintz p_iov->bulletin.size - crc_size); 150836558c3dSYuval Mintz if (crc != shadow.crc) 150936558c3dSYuval Mintz return -EAGAIN; 151036558c3dSYuval Mintz 151136558c3dSYuval Mintz /* Set the shadow bulletin and process it */ 151236558c3dSYuval Mintz memcpy(&p_iov->bulletin_shadow, &shadow, p_iov->bulletin.size); 151336558c3dSYuval Mintz 151436558c3dSYuval Mintz DP_VERBOSE(p_hwfn, QED_MSG_IOV, 151536558c3dSYuval Mintz "Read a bulletin update %08x\n", shadow.version); 151636558c3dSYuval Mintz 151736558c3dSYuval Mintz *p_change = 1; 151836558c3dSYuval Mintz 151936558c3dSYuval Mintz return 0; 152036558c3dSYuval Mintz } 152136558c3dSYuval Mintz 152236558c3dSYuval Mintz void __qed_vf_get_link_params(struct qed_hwfn *p_hwfn, 152336558c3dSYuval Mintz struct qed_mcp_link_params *p_params, 152436558c3dSYuval Mintz struct qed_bulletin_content *p_bulletin) 152536558c3dSYuval Mintz { 152636558c3dSYuval Mintz memset(p_params, 0, sizeof(*p_params)); 152736558c3dSYuval Mintz 152836558c3dSYuval Mintz p_params->speed.autoneg = p_bulletin->req_autoneg; 152936558c3dSYuval Mintz p_params->speed.advertised_speeds = p_bulletin->req_adv_speed; 153036558c3dSYuval Mintz p_params->speed.forced_speed = p_bulletin->req_forced_speed; 153136558c3dSYuval Mintz p_params->pause.autoneg = p_bulletin->req_autoneg_pause; 153236558c3dSYuval Mintz p_params->pause.forced_rx = p_bulletin->req_forced_rx; 153336558c3dSYuval Mintz p_params->pause.forced_tx = p_bulletin->req_forced_tx; 153436558c3dSYuval Mintz p_params->loopback_mode = p_bulletin->req_loopback; 153536558c3dSYuval Mintz } 153636558c3dSYuval Mintz 153736558c3dSYuval Mintz void qed_vf_get_link_params(struct qed_hwfn *p_hwfn, 153836558c3dSYuval Mintz struct qed_mcp_link_params *params) 153936558c3dSYuval Mintz { 154036558c3dSYuval Mintz __qed_vf_get_link_params(p_hwfn, params, 154136558c3dSYuval Mintz &(p_hwfn->vf_iov_info->bulletin_shadow)); 154236558c3dSYuval Mintz } 154336558c3dSYuval Mintz 154436558c3dSYuval Mintz void __qed_vf_get_link_state(struct qed_hwfn *p_hwfn, 154536558c3dSYuval Mintz struct qed_mcp_link_state *p_link, 154636558c3dSYuval Mintz struct qed_bulletin_content *p_bulletin) 154736558c3dSYuval Mintz { 154836558c3dSYuval Mintz memset(p_link, 0, sizeof(*p_link)); 154936558c3dSYuval Mintz 155036558c3dSYuval Mintz p_link->link_up = p_bulletin->link_up; 155136558c3dSYuval Mintz p_link->speed = p_bulletin->speed; 155236558c3dSYuval Mintz p_link->full_duplex = p_bulletin->full_duplex; 155336558c3dSYuval Mintz p_link->an = p_bulletin->autoneg; 155436558c3dSYuval Mintz p_link->an_complete = p_bulletin->autoneg_complete; 155536558c3dSYuval Mintz p_link->parallel_detection = p_bulletin->parallel_detection; 155636558c3dSYuval Mintz p_link->pfc_enabled = p_bulletin->pfc_enabled; 155736558c3dSYuval Mintz p_link->partner_adv_speed = p_bulletin->partner_adv_speed; 155836558c3dSYuval Mintz p_link->partner_tx_flow_ctrl_en = p_bulletin->partner_tx_flow_ctrl_en; 155936558c3dSYuval Mintz p_link->partner_rx_flow_ctrl_en = p_bulletin->partner_rx_flow_ctrl_en; 156036558c3dSYuval Mintz p_link->partner_adv_pause = p_bulletin->partner_adv_pause; 156136558c3dSYuval Mintz p_link->sfp_tx_fault = p_bulletin->sfp_tx_fault; 156236558c3dSYuval Mintz } 156336558c3dSYuval Mintz 156436558c3dSYuval Mintz void qed_vf_get_link_state(struct qed_hwfn *p_hwfn, 156536558c3dSYuval Mintz struct qed_mcp_link_state *link) 156636558c3dSYuval Mintz { 156736558c3dSYuval Mintz __qed_vf_get_link_state(p_hwfn, link, 156836558c3dSYuval Mintz &(p_hwfn->vf_iov_info->bulletin_shadow)); 156936558c3dSYuval Mintz } 157036558c3dSYuval Mintz 157136558c3dSYuval Mintz void __qed_vf_get_link_caps(struct qed_hwfn *p_hwfn, 157236558c3dSYuval Mintz struct qed_mcp_link_capabilities *p_link_caps, 157336558c3dSYuval Mintz struct qed_bulletin_content *p_bulletin) 157436558c3dSYuval Mintz { 157536558c3dSYuval Mintz memset(p_link_caps, 0, sizeof(*p_link_caps)); 157636558c3dSYuval Mintz p_link_caps->speed_capabilities = p_bulletin->capability_speed; 157736558c3dSYuval Mintz } 157836558c3dSYuval Mintz 157936558c3dSYuval Mintz void qed_vf_get_link_caps(struct qed_hwfn *p_hwfn, 158036558c3dSYuval Mintz struct qed_mcp_link_capabilities *p_link_caps) 158136558c3dSYuval Mintz { 158236558c3dSYuval Mintz __qed_vf_get_link_caps(p_hwfn, p_link_caps, 158336558c3dSYuval Mintz &(p_hwfn->vf_iov_info->bulletin_shadow)); 158436558c3dSYuval Mintz } 158536558c3dSYuval Mintz 15861408cc1fSYuval Mintz void qed_vf_get_num_rxqs(struct qed_hwfn *p_hwfn, u8 *num_rxqs) 15871408cc1fSYuval Mintz { 15881408cc1fSYuval Mintz *num_rxqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_rxqs; 15891408cc1fSYuval Mintz } 15901408cc1fSYuval Mintz 15910db711bbSMintz, Yuval void qed_vf_get_num_txqs(struct qed_hwfn *p_hwfn, u8 *num_txqs) 15920db711bbSMintz, Yuval { 15930db711bbSMintz, Yuval *num_txqs = p_hwfn->vf_iov_info->acquire_resp.resc.num_txqs; 15940db711bbSMintz, Yuval } 15950db711bbSMintz, Yuval 1596cbb8a12cSMintz, Yuval void qed_vf_get_num_cids(struct qed_hwfn *p_hwfn, u8 *num_cids) 1597cbb8a12cSMintz, Yuval { 1598cbb8a12cSMintz, Yuval *num_cids = p_hwfn->vf_iov_info->acquire_resp.resc.num_cids; 1599cbb8a12cSMintz, Yuval } 1600cbb8a12cSMintz, Yuval 16011408cc1fSYuval Mintz void qed_vf_get_port_mac(struct qed_hwfn *p_hwfn, u8 *port_mac) 16021408cc1fSYuval Mintz { 16031408cc1fSYuval Mintz memcpy(port_mac, 16041408cc1fSYuval Mintz p_hwfn->vf_iov_info->acquire_resp.pfdev_info.port_mac, ETH_ALEN); 16051408cc1fSYuval Mintz } 16061408cc1fSYuval Mintz 16071408cc1fSYuval Mintz void qed_vf_get_num_vlan_filters(struct qed_hwfn *p_hwfn, u8 *num_vlan_filters) 16081408cc1fSYuval Mintz { 16091408cc1fSYuval Mintz struct qed_vf_iov *p_vf; 16101408cc1fSYuval Mintz 16111408cc1fSYuval Mintz p_vf = p_hwfn->vf_iov_info; 16121408cc1fSYuval Mintz *num_vlan_filters = p_vf->acquire_resp.resc.num_vlan_filters; 16131408cc1fSYuval Mintz } 16141408cc1fSYuval Mintz 1615b0fca312SMintz, Yuval void qed_vf_get_num_mac_filters(struct qed_hwfn *p_hwfn, u8 *num_mac_filters) 1616b0fca312SMintz, Yuval { 1617b0fca312SMintz, Yuval struct qed_vf_iov *p_vf = p_hwfn->vf_iov_info; 1618b0fca312SMintz, Yuval 1619b0fca312SMintz, Yuval *num_mac_filters = p_vf->acquire_resp.resc.num_mac_filters; 1620b0fca312SMintz, Yuval } 1621b0fca312SMintz, Yuval 1622eff16960SYuval Mintz bool qed_vf_check_mac(struct qed_hwfn *p_hwfn, u8 *mac) 1623eff16960SYuval Mintz { 1624eff16960SYuval Mintz struct qed_bulletin_content *bulletin; 1625eff16960SYuval Mintz 1626eff16960SYuval Mintz bulletin = &p_hwfn->vf_iov_info->bulletin_shadow; 1627eff16960SYuval Mintz if (!(bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED))) 1628eff16960SYuval Mintz return true; 1629eff16960SYuval Mintz 1630eff16960SYuval Mintz /* Forbid VF from changing a MAC enforced by PF */ 1631eff16960SYuval Mintz if (ether_addr_equal(bulletin->mac, mac)) 1632eff16960SYuval Mintz return false; 1633eff16960SYuval Mintz 1634eff16960SYuval Mintz return false; 1635eff16960SYuval Mintz } 1636eff16960SYuval Mintz 1637ba56947aSBaoyou Xie static bool qed_vf_bulletin_get_forced_mac(struct qed_hwfn *hwfn, 1638eff16960SYuval Mintz u8 *dst_mac, u8 *p_is_forced) 1639eff16960SYuval Mintz { 1640eff16960SYuval Mintz struct qed_bulletin_content *bulletin; 1641eff16960SYuval Mintz 1642eff16960SYuval Mintz bulletin = &hwfn->vf_iov_info->bulletin_shadow; 1643eff16960SYuval Mintz 1644eff16960SYuval Mintz if (bulletin->valid_bitmap & (1 << MAC_ADDR_FORCED)) { 1645eff16960SYuval Mintz if (p_is_forced) 1646eff16960SYuval Mintz *p_is_forced = 1; 1647eff16960SYuval Mintz } else if (bulletin->valid_bitmap & (1 << VFPF_BULLETIN_MAC_ADDR)) { 1648eff16960SYuval Mintz if (p_is_forced) 1649eff16960SYuval Mintz *p_is_forced = 0; 1650eff16960SYuval Mintz } else { 1651eff16960SYuval Mintz return false; 1652eff16960SYuval Mintz } 1653eff16960SYuval Mintz 1654eff16960SYuval Mintz ether_addr_copy(dst_mac, bulletin->mac); 1655eff16960SYuval Mintz 1656eff16960SYuval Mintz return true; 1657eff16960SYuval Mintz } 1658eff16960SYuval Mintz 165997379f15SChopra, Manish static void 166097379f15SChopra, Manish qed_vf_bulletin_get_udp_ports(struct qed_hwfn *p_hwfn, 166197379f15SChopra, Manish u16 *p_vxlan_port, u16 *p_geneve_port) 166297379f15SChopra, Manish { 166397379f15SChopra, Manish struct qed_bulletin_content *p_bulletin; 166497379f15SChopra, Manish 166597379f15SChopra, Manish p_bulletin = &p_hwfn->vf_iov_info->bulletin_shadow; 166697379f15SChopra, Manish 166797379f15SChopra, Manish *p_vxlan_port = p_bulletin->vxlan_udp_port; 166897379f15SChopra, Manish *p_geneve_port = p_bulletin->geneve_udp_port; 166997379f15SChopra, Manish } 167097379f15SChopra, Manish 16711408cc1fSYuval Mintz void qed_vf_get_fw_version(struct qed_hwfn *p_hwfn, 16721408cc1fSYuval Mintz u16 *fw_major, u16 *fw_minor, 16731408cc1fSYuval Mintz u16 *fw_rev, u16 *fw_eng) 16741408cc1fSYuval Mintz { 16751408cc1fSYuval Mintz struct pf_vf_pfdev_info *info; 16761408cc1fSYuval Mintz 16771408cc1fSYuval Mintz info = &p_hwfn->vf_iov_info->acquire_resp.pfdev_info; 16781408cc1fSYuval Mintz 16791408cc1fSYuval Mintz *fw_major = info->fw_major; 16801408cc1fSYuval Mintz *fw_minor = info->fw_minor; 16811408cc1fSYuval Mintz *fw_rev = info->fw_rev; 16821408cc1fSYuval Mintz *fw_eng = info->fw_eng; 16831408cc1fSYuval Mintz } 168436558c3dSYuval Mintz 168536558c3dSYuval Mintz static void qed_handle_bulletin_change(struct qed_hwfn *hwfn) 168636558c3dSYuval Mintz { 1687eff16960SYuval Mintz struct qed_eth_cb_ops *ops = hwfn->cdev->protocol_ops.eth; 1688eff16960SYuval Mintz u8 mac[ETH_ALEN], is_mac_exist, is_mac_forced; 1689eff16960SYuval Mintz void *cookie = hwfn->cdev->ops_cookie; 169097379f15SChopra, Manish u16 vxlan_port, geneve_port; 1691eff16960SYuval Mintz 169297379f15SChopra, Manish qed_vf_bulletin_get_udp_ports(hwfn, &vxlan_port, &geneve_port); 1693eff16960SYuval Mintz is_mac_exist = qed_vf_bulletin_get_forced_mac(hwfn, mac, 1694eff16960SYuval Mintz &is_mac_forced); 1695c3aaa403SYuval Mintz if (is_mac_exist && cookie) 1696c3aaa403SYuval Mintz ops->force_mac(cookie, mac, !!is_mac_forced); 1697eff16960SYuval Mintz 169897379f15SChopra, Manish ops->ports_update(cookie, vxlan_port, geneve_port); 169997379f15SChopra, Manish 170036558c3dSYuval Mintz /* Always update link configuration according to bulletin */ 1701706d0891SRahul Verma qed_link_update(hwfn, NULL); 170236558c3dSYuval Mintz } 170336558c3dSYuval Mintz 170436558c3dSYuval Mintz void qed_iov_vf_task(struct work_struct *work) 170536558c3dSYuval Mintz { 170636558c3dSYuval Mintz struct qed_hwfn *hwfn = container_of(work, struct qed_hwfn, 170736558c3dSYuval Mintz iov_task.work); 170836558c3dSYuval Mintz u8 change = 0; 170936558c3dSYuval Mintz 171036558c3dSYuval Mintz if (test_and_clear_bit(QED_IOV_WQ_STOP_WQ_FLAG, &hwfn->iov_task_flags)) 171136558c3dSYuval Mintz return; 171236558c3dSYuval Mintz 171336558c3dSYuval Mintz /* Handle bulletin board changes */ 171436558c3dSYuval Mintz qed_vf_read_bulletin(hwfn, &change); 171565ed2ffdSMintz, Yuval if (test_and_clear_bit(QED_IOV_WQ_VF_FORCE_LINK_QUERY_FLAG, 171665ed2ffdSMintz, Yuval &hwfn->iov_task_flags)) 171765ed2ffdSMintz, Yuval change = 1; 171836558c3dSYuval Mintz if (change) 171936558c3dSYuval Mintz qed_handle_bulletin_change(hwfn); 172036558c3dSYuval Mintz 172136558c3dSYuval Mintz /* As VF is polling bulletin board, need to constantly re-schedule */ 172236558c3dSYuval Mintz queue_delayed_work(hwfn->iov_wq, &hwfn->iov_task, HZ); 172336558c3dSYuval Mintz } 1724