From 03c5d770c24cd673d105fbf1a9706ae838272091 Mon Sep 17 00:00:00 2001 From: Amit Kumar Salecha Date: Tue, 31 Aug 2010 17:17:52 +0000 Subject: qlcnic: mac vlan learning support Hypervisor allows, two VM's interfaces to have same mac address. These VM's interfaces get differentiate with Vlan tag. This patch add support to learn and configure mac+vlan filter on device. Signed-off-by: Amit Kumar Salecha Signed-off-by: David S. Miller --- drivers/net/qlcnic/qlcnic_main.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'drivers/net/qlcnic/qlcnic_main.c') diff --git a/drivers/net/qlcnic/qlcnic_main.c b/drivers/net/qlcnic/qlcnic_main.c index 0fbfb53f2594..5a6445a691b3 100644 --- a/drivers/net/qlcnic/qlcnic_main.c +++ b/drivers/net/qlcnic/qlcnic_main.c @@ -1826,7 +1826,7 @@ static void qlcnic_free_lb_filters_mem(struct qlcnic_adapter *adapter) } static void qlcnic_change_filter(struct qlcnic_adapter *adapter, - u64 uaddr, struct qlcnic_host_tx_ring *tx_ring) + u64 uaddr, u16 vlan_id, struct qlcnic_host_tx_ring *tx_ring) { struct cmd_desc_type0 *hwdesc; struct qlcnic_nic_req *req; @@ -1845,9 +1845,11 @@ static void qlcnic_change_filter(struct qlcnic_adapter *adapter, req->req_hdr = cpu_to_le64(word); mac_req = (struct qlcnic_mac_req *)&(req->words[0]); - mac_req->op = QLCNIC_MAC_ADD; + mac_req->op = vlan_id ? QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_ADD; memcpy(mac_req->mac_addr, &uaddr, ETH_ALEN); + req->words[1] = cpu_to_le64(vlan_id); + tx_ring->producer = get_next_index(producer, tx_ring->num_desc); } @@ -1865,6 +1867,7 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, struct hlist_node *tmp_hnode, *n; struct hlist_head *head; u64 src_addr = 0; + u16 vlan_id = 0; u8 hindex; if (!compare_ether_addr(phdr->h_source, adapter->mac_addr)) @@ -1873,12 +1876,16 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, if (adapter->fhash.fnum >= adapter->fhash.fmax) return; + /* Only NPAR capable devices support vlan based learning*/ + if (adapter->flags & QLCNIC_ESWITCH_ENABLED) + vlan_id = first_desc->vlan_TCI; memcpy(&src_addr, phdr->h_source, ETH_ALEN); hindex = QLCNIC_MAC_HASH(src_addr) & (QLCNIC_LB_MAX_FILTERS - 1); head = &(adapter->fhash.fhead[hindex]); hlist_for_each_entry_safe(tmp_fil, tmp_hnode, n, head, fnode) { - if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN)) { + if (!memcmp(tmp_fil->faddr, &src_addr, ETH_ALEN) && + tmp_fil->vlan_id == vlan_id) { tmp_fil->ftime = jiffies; return; } @@ -1888,9 +1895,10 @@ qlcnic_send_filter(struct qlcnic_adapter *adapter, if (!fil) return; - qlcnic_change_filter(adapter, src_addr, tx_ring); + qlcnic_change_filter(adapter, src_addr, vlan_id, tx_ring); fil->ftime = jiffies; + fil->vlan_id = vlan_id; memcpy(fil->faddr, &src_addr, ETH_ALEN); spin_lock(&adapter->mac_learn_lock); hlist_add_head(&(fil->fnode), head); -- cgit v1.2.3-59-g8ed1b