@@ -1045,6 +1045,66 @@ static void i40e_disable_vf_mappings(struct i40e_vf *vf)
i40e_flush(hw);
}
+/**
+ * i40e_add_vmmac_to_list
+ * @vf: pointer to the VF info
+ * @macaddr: pointer to the MAC address
+ *
+ * add MAC address into the MAC list for VM
+ **/
+static int i40e_add_vmmac_to_list(struct i40e_vf *vf,
+ const u8 *macaddr)
+{
+ struct i40e_vm_mac *mac_elem;
+
+ mac_elem = kzalloc(sizeof(*mac_elem), GFP_ATOMIC);
+ if (!mac_elem)
+ return -ENOMEM;
+ ether_addr_copy(mac_elem->macaddr, macaddr);
+ INIT_LIST_HEAD(&mac_elem->list);
+ list_add(&mac_elem->list, &vf->vm_mac_list);
+ return 0;
+}
+
+/**
+ * i40e_del_vmmac_from_list
+ * @vf: pointer to the VF info
+ * @macaddr: pointer to the MAC address
+ *
+ * delete MAC address from the MAC list for VM
+ **/
+static void i40e_del_vmmac_from_list(struct i40e_vf *vf, const u8 *macaddr)
+{
+ struct i40e_vm_mac *entry, *tmp;
+
+ list_for_each_entry_safe(entry, tmp, &vf->vm_mac_list, list) {
+ if (ether_addr_equal(macaddr, entry->macaddr)) {
+ list_del(&entry->list);
+ kfree(entry);
+ break;
+ }
+ }
+}
+
+/**
+ * i40e_free_vmmac_list
+ * @vf: pointer to the VF info
+ *
+ * remove whole list of MAC addresses for VM
+ **/
+static void i40e_free_vmmac_list(struct i40e_vf *vf)
+{
+ struct i40e_vm_mac *entry, *tmp;
+
+ if (list_empty(&vf->vm_mac_list))
+ return;
+
+ list_for_each_entry_safe(entry, tmp, &vf->vm_mac_list, list) {
+ list_del(&entry->list);
+ kfree(entry);
+ }
+}
+
/**
* i40e_free_vf_res
* @vf: pointer to the VF info
@@ -1120,6 +1180,9 @@ static void i40e_free_vf_res(struct i40e_vf *vf)
wr32(hw, reg_idx, reg);
i40e_flush(hw);
}
+
+ i40e_free_vmmac_list(vf);
+
/* reset some of the state variables keeping track of the resources */
vf->num_queue_pairs = 0;
clear_bit(I40E_VF_STATE_MC_PROMISC, &vf->vf_states);
@@ -2975,7 +3038,6 @@ static inline int i40e_check_vf_permission(struct i40e_vf *vf,
}
/**
- * i40e_vc_add_mac_addr_msg
* i40e_vc_ether_addr_type - get type of virtchnl_ether_addr
* @vc_ether_addr: used to extract the type
**/
@@ -67,6 +67,12 @@ struct i40e_time_mac {
u8 addr[ETH_ALEN];
};
+/* used for MAC list 'vm_mac_list' to recognize MACs added by VM */
+struct i40e_vm_mac {
+ struct list_head list;
+ u8 macaddr[ETH_ALEN];
+};
+
/* VF information structure */
struct i40e_vf {
struct i40e_pf *pf;
@@ -111,6 +117,9 @@ struct i40e_vf {
bool spoofchk;
u16 num_vlan;
+ /* MAC list created by VM */
+ struct list_head vm_mac_list;
+
/* ADq related variables */
bool adq_enabled; /* flag to enable adq */
u8 num_tc;