X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fqede%2Fbase%2Fecore_sriov.c;h=0279709cd1754a7182853288721b6018b4d38f52;hb=98abf84ee0e0719a6b64652cee239ab82e74f7b1;hp=ed9ace236f28be47e5dbd258529b4b05d412384a;hpb=40cf1e753eb2d8b63cf7265270fa3c8aa73d8dfa;p=dpdk.git diff --git a/drivers/net/qede/base/ecore_sriov.c b/drivers/net/qede/base/ecore_sriov.c index ed9ace236f..0279709cd1 100644 --- a/drivers/net/qede/base/ecore_sriov.c +++ b/drivers/net/qede/base/ecore_sriov.c @@ -590,8 +590,7 @@ enum _ecore_status_t ecore_iov_alloc(struct ecore_hwfn *p_hwfn) p_sriov = OSAL_ZALLOC(p_hwfn->p_dev, GFP_KERNEL, sizeof(*p_sriov)); if (!p_sriov) { - DP_NOTICE(p_hwfn, true, - "Failed to allocate `struct ecore_sriov'\n"); + DP_NOTICE(p_hwfn, false, "Failed to allocate `struct ecore_sriov'\n"); return ECORE_NOMEM; } @@ -648,7 +647,7 @@ enum _ecore_status_t ecore_iov_hw_info(struct ecore_hwfn *p_hwfn) p_dev->p_iov_info = OSAL_ZALLOC(p_dev, GFP_KERNEL, sizeof(*p_dev->p_iov_info)); if (!p_dev->p_iov_info) { - DP_NOTICE(p_hwfn, true, + DP_NOTICE(p_hwfn, false, "Can't support IOV due to lack of memory\n"); return ECORE_NOMEM; } @@ -865,6 +864,11 @@ ecore_iov_enable_vf_access(struct ecore_hwfn *p_hwfn, u32 igu_vf_conf = IGU_VF_CONF_FUNC_EN; enum _ecore_status_t rc = ECORE_SUCCESS; + /* It's possible VF was previously considered malicious - + * clear the indication even if we're only going to disable VF. + */ + vf->b_malicious = false; + if (vf->to_disable) return ECORE_SUCCESS; @@ -877,8 +881,6 @@ ecore_iov_enable_vf_access(struct ecore_hwfn *p_hwfn, ecore_iov_vf_igu_reset(p_hwfn, p_ptt, vf); - /* It's possible VF was previously considered malicious */ - vf->b_malicious = false; rc = ecore_iov_enable_vf_access_msix(p_hwfn, p_ptt, vf->abs_vf_id, vf->num_sbs); if (rc != ECORE_SUCCESS) @@ -1381,7 +1383,7 @@ static void ecore_iov_send_response(struct ecore_hwfn *p_hwfn, mbx->sw_mbx.response_size = length + sizeof(struct channel_list_end_tlv); - if (!p_hwfn->p_dev->b_hw_channel) + if (!p_vf->b_hw_channel) return; #endif @@ -1397,14 +1399,18 @@ static void ecore_iov_send_response(struct ecore_hwfn *p_hwfn, (sizeof(union pfvf_tlvs) - sizeof(u64)) / 4, ¶ms); - ecore_dmae_host2host(p_hwfn, p_ptt, mbx->reply_phys, - mbx->req_virt->first_tlv.reply_address, - sizeof(u64) / 4, ¶ms); - + /* Once PF copies the rc to the VF, the latter can continue and + * and send an additional message. So we have to make sure the + * channel would be re-set to ready prior to that. + */ REG_WR(p_hwfn, GTT_BAR0_MAP_REG_USDM_RAM + USTORM_VF_PF_CHANNEL_READY_OFFSET(eng_vf_id), 1); + ecore_dmae_host2host(p_hwfn, p_ptt, mbx->reply_phys, + mbx->req_virt->first_tlv.reply_address, + sizeof(u64) / 4, ¶ms); + OSAL_IOV_PF_RESP_TYPE(p_hwfn, p_vf->relative_vf_id, status); } @@ -1538,7 +1544,62 @@ static void ecore_iov_vf_cleanup(struct ecore_hwfn *p_hwfn, OSAL_IOV_VF_CLEANUP(p_hwfn, p_vf->relative_vf_id); } +/* Returns either 0, or log(size) */ +static u32 ecore_iov_vf_db_bar_size(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt) +{ + u32 val = ecore_rd(p_hwfn, p_ptt, PGLUE_B_REG_VF_BAR1_SIZE); + + if (val) + return val + 11; + return 0; +} + +static void +ecore_iov_vf_mbx_acquire_resc_cids(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, + struct ecore_vf_info *p_vf, + struct vf_pf_resc_request *p_req, + struct pf_vf_resc *p_resp) +{ + u8 num_vf_cons = p_hwfn->pf_params.eth_pf_params.num_vf_cons; + u8 db_size = DB_ADDR_VF(1, DQ_DEMS_LEGACY) - + DB_ADDR_VF(0, DQ_DEMS_LEGACY); + u32 bar_size; + + p_resp->num_cids = OSAL_MIN_T(u8, p_req->num_cids, num_vf_cons); + + /* If VF didn't bother asking for QIDs than don't bother limiting + * number of CIDs. The VF doesn't care about the number, and this + * has the likely result of causing an additional acquisition. + */ + if (!(p_vf->acquire.vfdev_info.capabilities & + VFPF_ACQUIRE_CAP_QUEUE_QIDS)) + return; + + /* If doorbell bar was mapped by VF, limit the VF CIDs to an amount + * that would make sure doorbells for all CIDs fall within the bar. + * If it doesn't, make sure regview window is sufficient. + */ + if (p_vf->acquire.vfdev_info.capabilities & + VFPF_ACQUIRE_CAP_PHYSICAL_BAR) { + bar_size = ecore_iov_vf_db_bar_size(p_hwfn, p_ptt); + if (bar_size) + bar_size = 1 << bar_size; + + if (ECORE_IS_CMT(p_hwfn->p_dev)) + bar_size /= 2; + } else { + bar_size = PXP_VF_BAR0_DQ_LENGTH; + } + + if (bar_size / db_size < 256) + p_resp->num_cids = OSAL_MIN_T(u8, p_resp->num_cids, + (u8)(bar_size / db_size)); +} + static u8 ecore_iov_vf_mbx_acquire_resc(struct ecore_hwfn *p_hwfn, + struct ecore_ptt *p_ptt, struct ecore_vf_info *p_vf, struct vf_pf_resc_request *p_req, struct pf_vf_resc *p_resp) @@ -1573,9 +1634,7 @@ static u8 ecore_iov_vf_mbx_acquire_resc(struct ecore_hwfn *p_hwfn, p_resp->num_vlan_filters = OSAL_MIN_T(u8, p_vf->num_vlan_filters, p_req->num_vlan_filters); - p_resp->num_cids = - OSAL_MIN_T(u8, p_req->num_cids, - p_hwfn->pf_params.eth_pf_params.num_vf_cons); + ecore_iov_vf_mbx_acquire_resc_cids(p_hwfn, p_ptt, p_vf, p_req, p_resp); /* This isn't really needed/enforced, but some legacy VFs might depend * on the correct filling of this field. @@ -1739,6 +1798,10 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn *p_hwfn, if (req->vfdev_info.capabilities & VFPF_ACQUIRE_CAP_QUEUE_QIDS) pfdev_info->capabilities |= PFVF_ACQUIRE_CAP_QUEUE_QIDS; + /* Share the sizes of the bars with VF */ + resp->pfdev_info.bar_size = (u8)ecore_iov_vf_db_bar_size(p_hwfn, + p_ptt); + ecore_iov_vf_mbx_acquire_stats(&pfdev_info->stats_info); OSAL_MEMCPY(pfdev_info->port_mac, p_hwfn->hw_info.hw_mac_addr, @@ -1764,7 +1827,7 @@ static void ecore_iov_vf_mbx_acquire(struct ecore_hwfn *p_hwfn, /* Fill resources available to VF; Make sure there are enough to * satisfy the VF's request. */ - vfpf_status = ecore_iov_vf_mbx_acquire_resc(p_hwfn, vf, + vfpf_status = ecore_iov_vf_mbx_acquire_resc(p_hwfn, p_ptt, vf, &req->resc_request, resc); if (vfpf_status != PFVF_STATUS_SUCCESS) goto out; @@ -1904,7 +1967,8 @@ ecore_iov_configure_vport_forced(struct ecore_hwfn *p_hwfn, if (!p_vf->vport_instance) return ECORE_INVAL; - if (events & (1 << MAC_ADDR_FORCED)) { + if ((events & (1 << MAC_ADDR_FORCED)) || + p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) { /* Since there's no way [currently] of removing the MAC, * we can always assume this means we need to force it. */ @@ -1925,7 +1989,11 @@ ecore_iov_configure_vport_forced(struct ecore_hwfn *p_hwfn, return rc; } - p_vf->configured_features |= 1 << MAC_ADDR_FORCED; + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) + p_vf->configured_features |= + 1 << VFPF_BULLETIN_MAC_ADDR; + else + p_vf->configured_features |= 1 << MAC_ADDR_FORCED; } if (events & (1 << VLAN_ADDR_FORCED)) { @@ -2116,6 +2184,7 @@ static void ecore_iov_vf_mbx_stop_vport(struct ecore_hwfn *p_hwfn, u8 status = PFVF_STATUS_SUCCESS; enum _ecore_status_t rc; + OSAL_IOV_VF_VPORT_STOP(p_hwfn, vf); vf->vport_instance--; vf->spoof_chk = false; @@ -3148,8 +3217,8 @@ static void ecore_iov_vf_mbx_vport_update(struct ecore_hwfn *p_hwfn, "Upper-layer prevents said VF" " configuration\n"); else - DP_NOTICE(p_hwfn, true, - "No feature tlvs found for vport update\n"); + DP_VERBOSE(p_hwfn, ECORE_MSG_IOV, + "No feature tlvs found for vport update\n"); status = PFVF_STATUS_NOT_SUPPORTED; goto out; } @@ -3354,12 +3423,13 @@ static void ecore_iov_vf_mbx_ucast_filter(struct ecore_hwfn *p_hwfn, goto out; } - /* Update shadow copy of the VF configuration */ + /* Update shadow copy of the VF configuration. In case shadow indicates + * the action should be blocked return success to VF to imitate the + * firmware behaviour in such case. + */ if (ecore_iov_vf_update_unicast_shadow(p_hwfn, vf, ¶ms) != - ECORE_SUCCESS) { - status = PFVF_STATUS_FAILURE; + ECORE_SUCCESS) goto out; - } /* Determine if the unicast filtering is acceptible by PF */ if ((p_bulletin->valid_bitmap & (1 << VLAN_ADDR_FORCED)) && @@ -4304,7 +4374,11 @@ void ecore_iov_bulletin_set_forced_mac(struct ecore_hwfn *p_hwfn, return; } - feature = 1 << MAC_ADDR_FORCED; + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) + feature = 1 << VFPF_BULLETIN_MAC_ADDR; + else + feature = 1 << MAC_ADDR_FORCED; + OSAL_MEMCPY(vf_info->bulletin.p_virt->mac, mac, ETH_ALEN); vf_info->bulletin.p_virt->valid_bitmap |= feature; @@ -4345,9 +4419,13 @@ enum _ecore_status_t ecore_iov_bulletin_set_mac(struct ecore_hwfn *p_hwfn, vf_info->bulletin.p_virt->valid_bitmap |= feature; + if (p_hwfn->pf_params.eth_pf_params.allow_vf_mac_change) + ecore_iov_configure_vport_forced(p_hwfn, vf_info, feature); + return ECORE_SUCCESS; } +#ifndef LINUX_REMOVE enum _ecore_status_t ecore_iov_bulletin_set_forced_untagged_default(struct ecore_hwfn *p_hwfn, bool b_untagged_only, int vfid) @@ -4404,6 +4482,7 @@ void ecore_iov_get_vfs_opaque_fid(struct ecore_hwfn *p_hwfn, int vfid, *opaque_fid = vf_info->opaque_fid; } +#endif void ecore_iov_bulletin_set_forced_vlan(struct ecore_hwfn *p_hwfn, u16 pvid, int vfid) @@ -4591,6 +4670,22 @@ u32 ecore_iov_pfvf_msg_length(void) return sizeof(union pfvf_tlvs); } +u8 *ecore_iov_bulletin_get_mac(struct ecore_hwfn *p_hwfn, + u16 rel_vf_id) +{ + struct ecore_vf_info *p_vf; + + p_vf = ecore_iov_get_vf_info(p_hwfn, rel_vf_id, true); + if (!p_vf || !p_vf->bulletin.p_virt) + return OSAL_NULL; + + if (!(p_vf->bulletin.p_virt->valid_bitmap & + (1 << VFPF_BULLETIN_MAC_ADDR))) + return OSAL_NULL; + + return p_vf->bulletin.p_virt->mac; +} + u8 *ecore_iov_bulletin_get_forced_mac(struct ecore_hwfn *p_hwfn, u16 rel_vf_id) { struct ecore_vf_info *p_vf; @@ -4771,3 +4866,17 @@ ecore_iov_get_vf_min_rate(struct ecore_hwfn *p_hwfn, int vfid) else return 0; } + +#ifdef CONFIG_ECORE_SW_CHANNEL +void ecore_iov_set_vf_hw_channel(struct ecore_hwfn *p_hwfn, int vfid, + bool b_is_hw) +{ + struct ecore_vf_info *vf_info; + + vf_info = ecore_iov_get_vf_info(p_hwfn, (u16)vfid, true); + if (!vf_info) + return; + + vf_info->b_hw_channel = b_is_hw; +} +#endif