Commit 6ddc7608 authored by Yuval Mintz's avatar Yuval Mintz Committed by David S. Miller

qed*: IOV support spoof-checking

Add support in `ndo_set_vf_spoofchk' for allowing PF control over
its VF spoof-checking configuration.
Signed-off-by: default avatarYuval Mintz <Yuval.Mintz@qlogic.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 733def6a
...@@ -381,6 +381,10 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn, ...@@ -381,6 +381,10 @@ int qed_sp_vport_update(struct qed_hwfn *p_hwfn,
p_ramrod->common.tx_switching_en = p_params->tx_switching_flg; p_ramrod->common.tx_switching_en = p_params->tx_switching_flg;
p_cmn->update_tx_switching_en_flg = p_params->update_tx_switching_flg; p_cmn->update_tx_switching_en_flg = p_params->update_tx_switching_flg;
p_cmn->anti_spoofing_en = p_params->anti_spoofing_en;
val = p_params->update_anti_spoofing_en_flg;
p_ramrod->common.update_anti_spoofing_en_flg = val;
rc = qed_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params); rc = qed_sp_vport_update_rss(p_hwfn, p_ramrod, p_rss_params);
if (rc) { if (rc) {
/* Return spq entry which is taken in qed_sp_init_request()*/ /* Return spq entry which is taken in qed_sp_init_request()*/
......
...@@ -149,6 +149,8 @@ struct qed_sp_vport_update_params { ...@@ -149,6 +149,8 @@ struct qed_sp_vport_update_params {
u8 update_tx_switching_flg; u8 update_tx_switching_flg;
u8 tx_switching_flg; u8 tx_switching_flg;
u8 update_approx_mcast_flg; u8 update_approx_mcast_flg;
u8 update_anti_spoofing_en_flg;
u8 anti_spoofing_en;
u8 update_accept_any_vlan_flg; u8 update_accept_any_vlan_flg;
u8 accept_any_vlan; u8 accept_any_vlan;
unsigned long bins[8]; unsigned long bins[8];
......
...@@ -1234,6 +1234,39 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn, ...@@ -1234,6 +1234,39 @@ static void qed_iov_vf_mbx_acquire(struct qed_hwfn *p_hwfn,
sizeof(struct pfvf_acquire_resp_tlv), vfpf_status); sizeof(struct pfvf_acquire_resp_tlv), vfpf_status);
} }
static int __qed_iov_spoofchk_set(struct qed_hwfn *p_hwfn,
struct qed_vf_info *p_vf, bool val)
{
struct qed_sp_vport_update_params params;
int rc;
if (val == p_vf->spoof_chk) {
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
"Spoofchk value[%d] is already configured\n", val);
return 0;
}
memset(&params, 0, sizeof(struct qed_sp_vport_update_params));
params.opaque_fid = p_vf->opaque_fid;
params.vport_id = p_vf->vport_id;
params.update_anti_spoofing_en_flg = 1;
params.anti_spoofing_en = val;
rc = qed_sp_vport_update(p_hwfn, &params, QED_SPQ_MODE_EBLOCK, NULL);
if (rc) {
p_vf->spoof_chk = val;
p_vf->req_spoofchk_val = p_vf->spoof_chk;
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
"Spoofchk val[%d] configured\n", val);
} else {
DP_VERBOSE(p_hwfn, QED_MSG_IOV,
"Spoofchk configuration[val:%d] failed for VF[%d]\n",
val, p_vf->relative_vf_id);
}
return rc;
}
static int qed_iov_reconfigure_unicast_vlan(struct qed_hwfn *p_hwfn, static int qed_iov_reconfigure_unicast_vlan(struct qed_hwfn *p_hwfn,
struct qed_vf_info *p_vf) struct qed_vf_info *p_vf)
{ {
...@@ -1476,6 +1509,8 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn, ...@@ -1476,6 +1509,8 @@ static void qed_iov_vf_mbx_start_vport(struct qed_hwfn *p_hwfn,
/* Force configuration if needed on the newly opened vport */ /* Force configuration if needed on the newly opened vport */
qed_iov_configure_vport_forced(p_hwfn, vf, *p_bitmap); qed_iov_configure_vport_forced(p_hwfn, vf, *p_bitmap);
__qed_iov_spoofchk_set(p_hwfn, vf, vf->req_spoofchk_val);
} }
qed_iov_prepare_resp(p_hwfn, p_ptt, vf, CHANNEL_TLV_VPORT_START, qed_iov_prepare_resp(p_hwfn, p_ptt, vf, CHANNEL_TLV_VPORT_START,
sizeof(struct pfvf_def_resp_tlv), status); sizeof(struct pfvf_def_resp_tlv), status);
...@@ -1489,6 +1524,7 @@ static void qed_iov_vf_mbx_stop_vport(struct qed_hwfn *p_hwfn, ...@@ -1489,6 +1524,7 @@ static void qed_iov_vf_mbx_stop_vport(struct qed_hwfn *p_hwfn,
int rc; int rc;
vf->vport_instance--; vf->vport_instance--;
vf->spoof_chk = false;
rc = qed_sp_vport_stop(p_hwfn, vf->opaque_fid, vf->vport_id); rc = qed_sp_vport_stop(p_hwfn, vf->opaque_fid, vf->vport_id);
if (rc != 0) { if (rc != 0) {
...@@ -2782,6 +2818,17 @@ void qed_iov_bulletin_set_forced_vlan(struct qed_hwfn *p_hwfn, ...@@ -2782,6 +2818,17 @@ void qed_iov_bulletin_set_forced_vlan(struct qed_hwfn *p_hwfn,
qed_iov_configure_vport_forced(p_hwfn, vf_info, feature); qed_iov_configure_vport_forced(p_hwfn, vf_info, feature);
} }
static bool qed_iov_vf_has_vport_instance(struct qed_hwfn *p_hwfn, int vfid)
{
struct qed_vf_info *p_vf_info;
p_vf_info = qed_iov_get_vf_info(p_hwfn, (u16) vfid, true);
if (!p_vf_info)
return false;
return !!p_vf_info->vport_instance;
}
bool qed_iov_is_vf_stopped(struct qed_hwfn *p_hwfn, int vfid) bool qed_iov_is_vf_stopped(struct qed_hwfn *p_hwfn, int vfid)
{ {
struct qed_vf_info *p_vf_info; struct qed_vf_info *p_vf_info;
...@@ -2793,6 +2840,34 @@ bool qed_iov_is_vf_stopped(struct qed_hwfn *p_hwfn, int vfid) ...@@ -2793,6 +2840,34 @@ bool qed_iov_is_vf_stopped(struct qed_hwfn *p_hwfn, int vfid)
return p_vf_info->state == VF_STOPPED; return p_vf_info->state == VF_STOPPED;
} }
int qed_iov_spoofchk_set(struct qed_hwfn *p_hwfn, int vfid, bool val)
{
struct qed_vf_info *vf;
int rc = -EINVAL;
if (!qed_iov_pf_sanity_check(p_hwfn, vfid)) {
DP_NOTICE(p_hwfn,
"SR-IOV sanity check failed, can't set spoofchk\n");
goto out;
}
vf = qed_iov_get_vf_info(p_hwfn, (u16) vfid, true);
if (!vf)
goto out;
if (!qed_iov_vf_has_vport_instance(p_hwfn, vfid)) {
/* After VF VPORT start PF will configure spoof check */
vf->req_spoofchk_val = val;
rc = 0;
goto out;
}
rc = __qed_iov_spoofchk_set(p_hwfn, vf, val);
out:
return rc;
}
static u8 *qed_iov_bulletin_get_forced_mac(struct qed_hwfn *p_hwfn, static u8 *qed_iov_bulletin_get_forced_mac(struct qed_hwfn *p_hwfn,
u16 rel_vf_id) u16 rel_vf_id)
{ {
...@@ -3179,6 +3254,21 @@ static int qed_set_vf_link_state(struct qed_dev *cdev, ...@@ -3179,6 +3254,21 @@ static int qed_set_vf_link_state(struct qed_dev *cdev,
return 0; return 0;
} }
static int qed_spoof_configure(struct qed_dev *cdev, int vfid, bool val)
{
int i, rc = -EINVAL;
for_each_hwfn(cdev, i) {
struct qed_hwfn *p_hwfn = &cdev->hwfns[i];
rc = qed_iov_spoofchk_set(p_hwfn, vfid, val);
if (rc)
break;
}
return rc;
}
static int qed_configure_max_vf_rate(struct qed_dev *cdev, int vfid, int rate) static int qed_configure_max_vf_rate(struct qed_dev *cdev, int vfid, int rate)
{ {
int i; int i;
...@@ -3417,5 +3507,6 @@ const struct qed_iov_hv_ops qed_iov_ops_pass = { ...@@ -3417,5 +3507,6 @@ const struct qed_iov_hv_ops qed_iov_ops_pass = {
.set_mac = &qed_sriov_pf_set_mac, .set_mac = &qed_sriov_pf_set_mac,
.set_vlan = &qed_sriov_pf_set_vlan, .set_vlan = &qed_sriov_pf_set_vlan,
.set_link_state = &qed_set_vf_link_state, .set_link_state = &qed_set_vf_link_state,
.set_spoof = &qed_spoof_configure,
.set_rate = &qed_set_vf_rate, .set_rate = &qed_set_vf_rate,
}; };
...@@ -154,6 +154,8 @@ struct qed_vf_info { ...@@ -154,6 +154,8 @@ struct qed_vf_info {
u16 igu_sbs[QED_MAX_VF_CHAINS_PER_PF]; u16 igu_sbs[QED_MAX_VF_CHAINS_PER_PF];
u8 num_active_rxqs; u8 num_active_rxqs;
struct qed_public_vf_info p_vf_info; struct qed_public_vf_info p_vf_info;
bool spoof_chk;
bool req_spoofchk_val;
/* Stores the configuration requested by VF */ /* Stores the configuration requested by VF */
struct qed_vf_shadow_config shadow_config; struct qed_vf_shadow_config shadow_config;
......
...@@ -1802,6 +1802,16 @@ static int qede_set_vf_rate(struct net_device *dev, int vfidx, ...@@ -1802,6 +1802,16 @@ static int qede_set_vf_rate(struct net_device *dev, int vfidx,
max_tx_rate); max_tx_rate);
} }
static int qede_set_vf_spoofchk(struct net_device *dev, int vfidx, bool val)
{
struct qede_dev *edev = netdev_priv(dev);
if (!edev->ops)
return -EINVAL;
return edev->ops->iov->set_spoof(edev->cdev, vfidx, val);
}
static int qede_set_vf_link_state(struct net_device *dev, int vfidx, static int qede_set_vf_link_state(struct net_device *dev, int vfidx,
int link_state) int link_state)
{ {
...@@ -2142,6 +2152,7 @@ static const struct net_device_ops qede_netdev_ops = { ...@@ -2142,6 +2152,7 @@ static const struct net_device_ops qede_netdev_ops = {
.ndo_get_stats64 = qede_get_stats64, .ndo_get_stats64 = qede_get_stats64,
#ifdef CONFIG_QED_SRIOV #ifdef CONFIG_QED_SRIOV
.ndo_set_vf_link_state = qede_set_vf_link_state, .ndo_set_vf_link_state = qede_set_vf_link_state,
.ndo_set_vf_spoofchk = qede_set_vf_spoofchk,
.ndo_set_vf_rate = qede_set_vf_rate, .ndo_set_vf_rate = qede_set_vf_rate,
#endif #endif
#ifdef CONFIG_QEDE_VXLAN #ifdef CONFIG_QEDE_VXLAN
......
...@@ -22,6 +22,8 @@ struct qed_iov_hv_ops { ...@@ -22,6 +22,8 @@ struct qed_iov_hv_ops {
int (*set_link_state) (struct qed_dev *cdev, int vf_id, int (*set_link_state) (struct qed_dev *cdev, int vf_id,
int link_state); int link_state);
int (*set_spoof) (struct qed_dev *cdev, int vfid, bool val);
int (*set_rate) (struct qed_dev *cdev, int vfid, int (*set_rate) (struct qed_dev *cdev, int vfid,
u32 min_rate, u32 max_rate); u32 min_rate, u32 max_rate);
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment