diff options
author | Rajesh Borundia <rajesh.borundia@qlogic.com> | 2013-03-29 05:46:38 +0000 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-03-29 15:51:06 -0400 |
commit | e8b508ef71fb70ec761086532716b19d3c4773e5 (patch) | |
tree | 22e27a6c8369ffff72375ead0a120bbf16b9f9a0 /drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | |
parent | 7cb03b2347d5edace4fb8e7dd9d6c3889368a179 (diff) | |
download | linux-stable-e8b508ef71fb70ec761086532716b19d3c4773e5.tar.gz linux-stable-e8b508ef71fb70ec761086532716b19d3c4773e5.tar.bz2 linux-stable-e8b508ef71fb70ec761086532716b19d3c4773e5.zip |
qlcnic: Support atomic commands
o VFs might get scheduled out after sending a command to a PF
and scheduled in after receiving a response. Implement a
worker thread to handle atomic commands.
Signed-off-by: Manish Chopra <manish.chopra@qlogic.com>
Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c')
-rw-r--r-- | drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c | 47 |
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c index f89cc7a3fe6c..ddc130b23378 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c @@ -496,7 +496,7 @@ int qlcnic_nic_add_mac(struct qlcnic_adapter *adapter, const u8 *addr) return 0; } -void qlcnic_set_multi(struct net_device *netdev) +void __qlcnic_set_multi(struct net_device *netdev) { struct qlcnic_adapter *adapter = netdev_priv(netdev); struct netdev_hw_addr *ha; @@ -508,7 +508,8 @@ void qlcnic_set_multi(struct net_device *netdev) if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) return; - qlcnic_nic_add_mac(adapter, adapter->mac_addr); + if (!qlcnic_sriov_vf_check(adapter)) + qlcnic_nic_add_mac(adapter, adapter->mac_addr); qlcnic_nic_add_mac(adapter, bcast_addr); if (netdev->flags & IFF_PROMISC) { @@ -523,23 +524,53 @@ void qlcnic_set_multi(struct net_device *netdev) goto send_fw_cmd; } - if (!netdev_mc_empty(netdev)) { + if (!netdev_mc_empty(netdev) && !qlcnic_sriov_vf_check(adapter)) { netdev_for_each_mc_addr(ha, netdev) { qlcnic_nic_add_mac(adapter, ha->addr); } } + if (qlcnic_sriov_vf_check(adapter)) + qlcnic_vf_add_mc_list(netdev); + send_fw_cmd: - if (mode == VPORT_MISS_MODE_ACCEPT_ALL && !adapter->fdb_mac_learn) { - qlcnic_alloc_lb_filters_mem(adapter); - adapter->drv_mac_learn = true; - } else { - adapter->drv_mac_learn = false; + if (!qlcnic_sriov_vf_check(adapter)) { + if (mode == VPORT_MISS_MODE_ACCEPT_ALL && + !adapter->fdb_mac_learn) { + qlcnic_alloc_lb_filters_mem(adapter); + adapter->drv_mac_learn = true; + } else { + adapter->drv_mac_learn = false; + } } qlcnic_nic_set_promisc(adapter, mode); } +void qlcnic_set_multi(struct net_device *netdev) +{ + struct qlcnic_adapter *adapter = netdev_priv(netdev); + struct netdev_hw_addr *ha; + struct qlcnic_mac_list_s *cur; + + if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) + return; + if (qlcnic_sriov_vf_check(adapter)) { + if (!netdev_mc_empty(netdev)) { + netdev_for_each_mc_addr(ha, netdev) { + cur = kzalloc(sizeof(struct qlcnic_mac_list_s), + GFP_ATOMIC); + memcpy(cur->mac_addr, + ha->addr, ETH_ALEN); + list_add_tail(&cur->list, &adapter->vf_mc_list); + } + } + qlcnic_sriov_vf_schedule_multi(adapter->netdev); + return; + } + __qlcnic_set_multi(netdev); +} + int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) { struct qlcnic_nic_req req; |