@@ -1098,6 +1098,29 @@ static int ef100_probe_main(struct efx_nic *efx)
return rc;
}
+int efx_ef100_lookup_client_id(struct efx_nic *efx, efx_qword_t pciefn, u32 *id)
+{
+ MCDI_DECLARE_BUF(outbuf, MC_CMD_GET_CLIENT_HANDLE_OUT_LEN);
+ MCDI_DECLARE_BUF(inbuf, MC_CMD_GET_CLIENT_HANDLE_IN_LEN);
+ u64 pciefn_flat = le64_to_cpu(pciefn.u64[0]);
+ size_t outlen;
+ int rc;
+
+ MCDI_SET_DWORD(inbuf, GET_CLIENT_HANDLE_IN_TYPE,
+ MC_CMD_GET_CLIENT_HANDLE_IN_TYPE_FUNC);
+ MCDI_SET_QWORD(inbuf, GET_CLIENT_HANDLE_IN_FUNC,
+ pciefn_flat);
+
+ rc = efx_mcdi_rpc(efx, MC_CMD_GET_CLIENT_HANDLE, inbuf,
+ sizeof(inbuf), outbuf, sizeof(outbuf), &outlen);
+ if (rc)
+ return rc;
+ if (outlen < sizeof(outbuf))
+ return -EIO;
+ *id = MCDI_DWORD(outbuf, GET_CLIENT_HANDLE_OUT_HANDLE);
+ return 0;
+}
+
int ef100_probe_netdev_pf(struct efx_nic *efx)
{
struct ef100_nic_data *nic_data = efx->nic_data;
@@ -17,6 +17,7 @@
extern const struct efx_nic_type ef100_pf_nic_type;
extern const struct efx_nic_type ef100_vf_nic_type;
+int efx_ef100_lookup_client_id(struct efx_nic *efx, efx_qword_t pciefn, u32 *id);
int ef100_probe_netdev_pf(struct efx_nic *efx);
int ef100_probe_vf(struct efx_nic *efx);
void ef100_remove(struct efx_nic *efx);
@@ -200,6 +200,7 @@ static struct efx_rep *efx_ef100_rep_create_netdev(struct efx_nic *efx,
static int efx_ef100_configure_rep(struct efx_rep *efv)
{
struct efx_nic *efx = efv->parent;
+ efx_qword_t pciefn;
u32 selector;
int rc;
@@ -214,6 +215,22 @@ static int efx_ef100_configure_rep(struct efx_rep *efv)
/* mport label should fit in 16 bits */
WARN_ON(efv->mport >> 16);
+ /* Construct PCIE_FUNCTION structure for the representee */
+ EFX_POPULATE_QWORD_3(pciefn,
+ PCIE_FUNCTION_PF, PCIE_FUNCTION_PF_NULL,
+ PCIE_FUNCTION_VF, efv->idx,
+ PCIE_FUNCTION_INTF, PCIE_INTERFACE_CALLER);
+ /* look up representee's client ID */
+ rc = efx_ef100_lookup_client_id(efx, pciefn, &efv->clid);
+ if (rc) {
+ efv->clid = CLIENT_HANDLE_NULL;
+ pci_dbg(efx->pci_dev, "Failed to get VF %u client ID, rc %d\n",
+ efv->idx, rc);
+ } else {
+ pci_dbg(efx->pci_dev, "VF %u client ID %#x\n",
+ efv->idx, efv->clid);
+ }
+
return efx_tc_configure_default_rule_rep(efv);
}
@@ -29,6 +29,7 @@ struct efx_rep_sw_stats {
* @net_dev: representor netdevice
* @msg_enable: log message enable flags
* @mport: m-port ID of corresponding VF
+ * @clid: client ID of corresponding VF
* @idx: VF index
* @write_index: number of packets enqueued to @rx_list
* @read_index: number of packets consumed from @rx_list
@@ -45,6 +46,7 @@ struct efx_rep {
struct net_device *net_dev;
u32 msg_enable;
u32 mport;
+ u32 clid;
unsigned int idx;
unsigned int write_index, read_index;
unsigned int rx_pring_size;