|
@@ -2309,15 +2309,12 @@ out:
|
|
qed_iov_send_response(p_hwfn, p_ptt, vf, length, status);
|
|
qed_iov_send_response(p_hwfn, p_ptt, vf, length, status);
|
|
}
|
|
}
|
|
|
|
|
|
-static int qed_iov_vf_update_unicast_shadow(struct qed_hwfn *p_hwfn,
|
|
|
|
- struct qed_vf_info *p_vf,
|
|
|
|
- struct qed_filter_ucast *p_params)
|
|
|
|
|
|
+static int qed_iov_vf_update_vlan_shadow(struct qed_hwfn *p_hwfn,
|
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
|
+ struct qed_filter_ucast *p_params)
|
|
{
|
|
{
|
|
int i;
|
|
int i;
|
|
|
|
|
|
- if (p_params->type == QED_FILTER_MAC)
|
|
|
|
- return 0;
|
|
|
|
-
|
|
|
|
/* First remove entries and then add new ones */
|
|
/* First remove entries and then add new ones */
|
|
if (p_params->opcode == QED_FILTER_REMOVE) {
|
|
if (p_params->opcode == QED_FILTER_REMOVE) {
|
|
for (i = 0; i < QED_ETH_VF_NUM_VLAN_FILTERS + 1; i++)
|
|
for (i = 0; i < QED_ETH_VF_NUM_VLAN_FILTERS + 1; i++)
|
|
@@ -2370,6 +2367,80 @@ static int qed_iov_vf_update_unicast_shadow(struct qed_hwfn *p_hwfn,
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int qed_iov_vf_update_mac_shadow(struct qed_hwfn *p_hwfn,
|
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
|
+ struct qed_filter_ucast *p_params)
|
|
|
|
+{
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ /* If we're in forced-mode, we don't allow any change */
|
|
|
|
+ if (p_vf->bulletin.p_virt->valid_bitmap & (1 << MAC_ADDR_FORCED))
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ /* First remove entries and then add new ones */
|
|
|
|
+ if (p_params->opcode == QED_FILTER_REMOVE) {
|
|
|
|
+ for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
|
|
|
|
+ if (ether_addr_equal(p_vf->shadow_config.macs[i],
|
|
|
|
+ p_params->mac)) {
|
|
|
|
+ memset(p_vf->shadow_config.macs[i], 0,
|
|
|
|
+ ETH_ALEN);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (i == QED_ETH_VF_NUM_MAC_FILTERS) {
|
|
|
|
+ DP_VERBOSE(p_hwfn, QED_MSG_IOV,
|
|
|
|
+ "MAC isn't configured\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+ } else if (p_params->opcode == QED_FILTER_REPLACE ||
|
|
|
|
+ p_params->opcode == QED_FILTER_FLUSH) {
|
|
|
|
+ for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++)
|
|
|
|
+ memset(p_vf->shadow_config.macs[i], 0, ETH_ALEN);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /* List the new MAC address */
|
|
|
|
+ if (p_params->opcode != QED_FILTER_ADD &&
|
|
|
|
+ p_params->opcode != QED_FILTER_REPLACE)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ for (i = 0; i < QED_ETH_VF_NUM_MAC_FILTERS; i++) {
|
|
|
|
+ if (is_zero_ether_addr(p_vf->shadow_config.macs[i])) {
|
|
|
|
+ ether_addr_copy(p_vf->shadow_config.macs[i],
|
|
|
|
+ p_params->mac);
|
|
|
|
+ DP_VERBOSE(p_hwfn, QED_MSG_IOV,
|
|
|
|
+ "Added MAC at %d entry in shadow\n", i);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (i == QED_ETH_VF_NUM_MAC_FILTERS) {
|
|
|
|
+ DP_VERBOSE(p_hwfn, QED_MSG_IOV, "No available place for MAC\n");
|
|
|
|
+ return -EINVAL;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int
|
|
|
|
+qed_iov_vf_update_unicast_shadow(struct qed_hwfn *p_hwfn,
|
|
|
|
+ struct qed_vf_info *p_vf,
|
|
|
|
+ struct qed_filter_ucast *p_params)
|
|
|
|
+{
|
|
|
|
+ int rc = 0;
|
|
|
|
+
|
|
|
|
+ if (p_params->type == QED_FILTER_MAC) {
|
|
|
|
+ rc = qed_iov_vf_update_mac_shadow(p_hwfn, p_vf, p_params);
|
|
|
|
+ if (rc)
|
|
|
|
+ return rc;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (p_params->type == QED_FILTER_VLAN)
|
|
|
|
+ rc = qed_iov_vf_update_vlan_shadow(p_hwfn, p_vf, p_params);
|
|
|
|
+
|
|
|
|
+ return rc;
|
|
|
|
+}
|
|
|
|
+
|
|
int qed_iov_chk_ucast(struct qed_hwfn *hwfn,
|
|
int qed_iov_chk_ucast(struct qed_hwfn *hwfn,
|
|
int vfid, struct qed_filter_ucast *params)
|
|
int vfid, struct qed_filter_ucast *params)
|
|
{
|
|
{
|