aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRajesh Borundia <rajesh.borundia@qlogic.com>2014-05-09 02:51:30 -0400
committerDavid S. Miller <davem@davemloft.net>2014-05-09 13:08:57 -0400
commit74b7ba1a8bc994f92cfe4716d80c17f90df5eba3 (patch)
treece5979d71d3c242a0d4d77920dce787f0663f363
parent132a3f2bee7600366244097658c4c89ac99a8981 (diff)
qlcnic: Add support to process commands in atomic context
o Commands from VF may sleep during PF-VF communication. Earlier we use to process qlcnic_sriov_vf_set_multi function in process context. Now individual commands that are called in atomic context are processed in process context without waiting for completion of command. Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c24
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c4
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h3
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c137
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c36
6 files changed, 99 insertions, 107 deletions
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 09fe9c276f1c..7bad613becba 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -1693,7 +1693,7 @@ int qlcnic_read_mac_addr(struct qlcnic_adapter *);
1693int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int); 1693int qlcnic_setup_netdev(struct qlcnic_adapter *, struct net_device *, int);
1694void qlcnic_set_netdev_features(struct qlcnic_adapter *, 1694void qlcnic_set_netdev_features(struct qlcnic_adapter *,
1695 struct qlcnic_esw_func_cfg *); 1695 struct qlcnic_esw_func_cfg *);
1696void qlcnic_sriov_vf_schedule_multi(struct net_device *); 1696void qlcnic_sriov_vf_set_multi(struct net_device *);
1697int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8); 1697int qlcnic_is_valid_nic_func(struct qlcnic_adapter *, u8);
1698int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *, 1698int qlcnic_get_pci_func_type(struct qlcnic_adapter *, u16, u16 *, u16 *,
1699 u16 *); 1699 u16 *);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
index 9f3adf4e70b5..e5352b70314a 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hw.c
@@ -567,28 +567,14 @@ static void __qlcnic_set_multi(struct net_device *netdev, u16 vlan)
567void qlcnic_set_multi(struct net_device *netdev) 567void qlcnic_set_multi(struct net_device *netdev)
568{ 568{
569 struct qlcnic_adapter *adapter = netdev_priv(netdev); 569 struct qlcnic_adapter *adapter = netdev_priv(netdev);
570 struct qlcnic_mac_vlan_list *cur;
571 struct netdev_hw_addr *ha;
572 size_t temp;
573 570
574 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 571 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
575 return; 572 return;
576 if (qlcnic_sriov_vf_check(adapter)) { 573
577 if (!netdev_mc_empty(netdev)) { 574 if (qlcnic_sriov_vf_check(adapter))
578 netdev_for_each_mc_addr(ha, netdev) { 575 qlcnic_sriov_vf_set_multi(netdev);
579 temp = sizeof(struct qlcnic_mac_vlan_list); 576 else
580 cur = kzalloc(temp, GFP_ATOMIC); 577 __qlcnic_set_multi(netdev, 0);
581 if (cur == NULL)
582 break;
583 memcpy(cur->mac_addr,
584 ha->addr, ETH_ALEN);
585 list_add_tail(&cur->list, &adapter->vf_mc_list);
586 }
587 }
588 qlcnic_sriov_vf_schedule_multi(adapter->netdev);
589 return;
590 }
591 __qlcnic_set_multi(netdev, 0);
592} 578}
593 579
594int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode) 580int qlcnic_82xx_nic_set_promisc(struct qlcnic_adapter *adapter, u32 mode)
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 28ebe1ba5a0b..1a52a781401f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1917,8 +1917,6 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
1917 if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state)) 1917 if (!test_and_clear_bit(__QLCNIC_DEV_UP, &adapter->state))
1918 return; 1918 return;
1919 1919
1920 if (qlcnic_sriov_vf_check(adapter))
1921 qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc);
1922 smp_mb(); 1920 smp_mb();
1923 netif_carrier_off(netdev); 1921 netif_carrier_off(netdev);
1924 adapter->ahw->linkup = 0; 1922 adapter->ahw->linkup = 0;
@@ -1930,6 +1928,8 @@ void __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
1930 qlcnic_delete_lb_filters(adapter); 1928 qlcnic_delete_lb_filters(adapter);
1931 1929
1932 qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE); 1930 qlcnic_nic_set_promisc(adapter, QLCNIC_NIU_NON_PROMISC_MODE);
1931 if (qlcnic_sriov_vf_check(adapter))
1932 qlcnic_sriov_cleanup_async_list(&adapter->ahw->sriov->bc);
1933 1933
1934 qlcnic_napi_disable(adapter); 1934 qlcnic_napi_disable(adapter);
1935 1935
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
index 396bd1fd1d27..54159bde2bc7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov.h
@@ -151,13 +151,14 @@ struct qlcnic_vf_info {
151 struct qlcnic_trans_list rcv_pend; 151 struct qlcnic_trans_list rcv_pend;
152 struct qlcnic_adapter *adapter; 152 struct qlcnic_adapter *adapter;
153 struct qlcnic_vport *vp; 153 struct qlcnic_vport *vp;
154 struct mutex vlan_list_lock; /* Lock for VLAN list */ 154 spinlock_t vlan_list_lock; /* Lock for VLAN list */
155}; 155};
156 156
157struct qlcnic_async_work_list { 157struct qlcnic_async_work_list {
158 struct list_head list; 158 struct list_head list;
159 struct work_struct work; 159 struct work_struct work;
160 void *ptr; 160 void *ptr;
161 struct qlcnic_cmd_args *cmd;
161}; 162};
162 163
163struct qlcnic_back_channel { 164struct qlcnic_back_channel {
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
index 4eccc2b74f67..44cd5bd03744 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c
@@ -39,6 +39,8 @@ static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *, u8);
39static void qlcnic_sriov_process_bc_cmd(struct work_struct *); 39static void qlcnic_sriov_process_bc_cmd(struct work_struct *);
40static int qlcnic_sriov_vf_shutdown(struct pci_dev *); 40static int qlcnic_sriov_vf_shutdown(struct pci_dev *);
41static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *); 41static int qlcnic_sriov_vf_resume(struct qlcnic_adapter *);
42static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *,
43 struct qlcnic_cmd_args *);
42 44
43static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = { 45static struct qlcnic_hardware_ops qlcnic_sriov_vf_hw_ops = {
44 .read_crb = qlcnic_83xx_read_crb, 46 .read_crb = qlcnic_83xx_read_crb,
@@ -181,7 +183,7 @@ int qlcnic_sriov_init(struct qlcnic_adapter *adapter, int num_vfs)
181 vf->adapter = adapter; 183 vf->adapter = adapter;
182 vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i); 184 vf->pci_func = qlcnic_sriov_virtid_fn(adapter, i);
183 mutex_init(&vf->send_cmd_lock); 185 mutex_init(&vf->send_cmd_lock);
184 mutex_init(&vf->vlan_list_lock); 186 spin_lock_init(&vf->vlan_list_lock);
185 INIT_LIST_HEAD(&vf->rcv_act.wait_list); 187 INIT_LIST_HEAD(&vf->rcv_act.wait_list);
186 INIT_LIST_HEAD(&vf->rcv_pend.wait_list); 188 INIT_LIST_HEAD(&vf->rcv_pend.wait_list);
187 spin_lock_init(&vf->rcv_act.lock); 189 spin_lock_init(&vf->rcv_act.lock);
@@ -1356,7 +1358,7 @@ static int qlcnic_sriov_retry_bc_cmd(struct qlcnic_adapter *adapter,
1356 return -EIO; 1358 return -EIO;
1357} 1359}
1358 1360
1359static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, 1361static int __qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
1360 struct qlcnic_cmd_args *cmd) 1362 struct qlcnic_cmd_args *cmd)
1361{ 1363{
1362 struct qlcnic_hardware_context *ahw = adapter->ahw; 1364 struct qlcnic_hardware_context *ahw = adapter->ahw;
@@ -1428,6 +1430,16 @@ cleanup_transaction:
1428 return rsp; 1430 return rsp;
1429} 1431}
1430 1432
1433
1434static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter,
1435 struct qlcnic_cmd_args *cmd)
1436{
1437 if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT)
1438 return qlcnic_sriov_async_issue_cmd(adapter, cmd);
1439 else
1440 return __qlcnic_sriov_issue_cmd(adapter, cmd);
1441}
1442
1431static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op) 1443static int qlcnic_sriov_channel_cfg_cmd(struct qlcnic_adapter *adapter, u8 cmd_op)
1432{ 1444{
1433 struct qlcnic_cmd_args cmd; 1445 struct qlcnic_cmd_args cmd;
@@ -1458,58 +1470,28 @@ out:
1458 return ret; 1470 return ret;
1459} 1471}
1460 1472
1461static void qlcnic_vf_add_mc_list(struct net_device *netdev) 1473static void qlcnic_vf_add_mc_list(struct net_device *netdev, const u8 *mac)
1462{ 1474{
1463 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1475 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1464 struct qlcnic_sriov *sriov = adapter->ahw->sriov; 1476 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1465 struct qlcnic_mac_vlan_list *cur;
1466 struct list_head *head, tmp_list;
1467 struct qlcnic_vf_info *vf; 1477 struct qlcnic_vf_info *vf;
1468 u16 vlan_id; 1478 u16 vlan_id;
1469 int i; 1479 int i;
1470 1480
1471 static const u8 bcast_addr[ETH_ALEN] = {
1472 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1473 };
1474
1475 vf = &adapter->ahw->sriov->vf_info[0]; 1481 vf = &adapter->ahw->sriov->vf_info[0];
1476 INIT_LIST_HEAD(&tmp_list);
1477 head = &adapter->vf_mc_list;
1478 netif_addr_lock_bh(netdev);
1479
1480 while (!list_empty(head)) {
1481 cur = list_entry(head->next, struct qlcnic_mac_vlan_list, list);
1482 list_move(&cur->list, &tmp_list);
1483 }
1484
1485 netif_addr_unlock_bh(netdev);
1486 1482
1487 while (!list_empty(&tmp_list)) { 1483 if (!qlcnic_sriov_check_any_vlan(vf)) {
1488 cur = list_entry((&tmp_list)->next, 1484 qlcnic_nic_add_mac(adapter, mac, 0);
1489 struct qlcnic_mac_vlan_list, list); 1485 } else {
1490 if (!qlcnic_sriov_check_any_vlan(vf)) { 1486 spin_lock(&vf->vlan_list_lock);
1491 qlcnic_nic_add_mac(adapter, bcast_addr, 0); 1487 for (i = 0; i < sriov->num_allowed_vlans; i++) {
1492 qlcnic_nic_add_mac(adapter, cur->mac_addr, 0); 1488 vlan_id = vf->sriov_vlans[i];
1493 } else { 1489 if (vlan_id)
1494 mutex_lock(&vf->vlan_list_lock); 1490 qlcnic_nic_add_mac(adapter, mac, vlan_id);
1495 for (i = 0; i < sriov->num_allowed_vlans; i++) {
1496 vlan_id = vf->sriov_vlans[i];
1497 if (vlan_id) {
1498 qlcnic_nic_add_mac(adapter, bcast_addr,
1499 vlan_id);
1500 qlcnic_nic_add_mac(adapter,
1501 cur->mac_addr,
1502 vlan_id);
1503 }
1504 }
1505 mutex_unlock(&vf->vlan_list_lock);
1506 if (qlcnic_84xx_check(adapter)) {
1507 qlcnic_nic_add_mac(adapter, bcast_addr, 0);
1508 qlcnic_nic_add_mac(adapter, cur->mac_addr, 0);
1509 }
1510 } 1491 }
1511 list_del(&cur->list); 1492 spin_unlock(&vf->vlan_list_lock);
1512 kfree(cur); 1493 if (qlcnic_84xx_check(adapter))
1494 qlcnic_nic_add_mac(adapter, mac, 0);
1513 } 1495 }
1514} 1496}
1515 1497
@@ -1518,6 +1500,7 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc)
1518 struct list_head *head = &bc->async_list; 1500 struct list_head *head = &bc->async_list;
1519 struct qlcnic_async_work_list *entry; 1501 struct qlcnic_async_work_list *entry;
1520 1502
1503 flush_workqueue(bc->bc_async_wq);
1521 while (!list_empty(head)) { 1504 while (!list_empty(head)) {
1522 entry = list_entry(head->next, struct qlcnic_async_work_list, 1505 entry = list_entry(head->next, struct qlcnic_async_work_list,
1523 list); 1506 list);
@@ -1527,10 +1510,14 @@ void qlcnic_sriov_cleanup_async_list(struct qlcnic_back_channel *bc)
1527 } 1510 }
1528} 1511}
1529 1512
1530static void qlcnic_sriov_vf_set_multi(struct net_device *netdev) 1513void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
1531{ 1514{
1532 struct qlcnic_adapter *adapter = netdev_priv(netdev); 1515 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1533 struct qlcnic_hardware_context *ahw = adapter->ahw; 1516 struct qlcnic_hardware_context *ahw = adapter->ahw;
1517 static const u8 bcast_addr[ETH_ALEN] = {
1518 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
1519 };
1520 struct netdev_hw_addr *ha;
1534 u32 mode = VPORT_MISS_MODE_DROP; 1521 u32 mode = VPORT_MISS_MODE_DROP;
1535 1522
1536 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state)) 1523 if (!test_bit(__QLCNIC_FW_ATTACHED, &adapter->state))
@@ -1542,23 +1529,27 @@ static void qlcnic_sriov_vf_set_multi(struct net_device *netdev)
1542 } else if ((netdev->flags & IFF_ALLMULTI) || 1529 } else if ((netdev->flags & IFF_ALLMULTI) ||
1543 (netdev_mc_count(netdev) > ahw->max_mc_count)) { 1530 (netdev_mc_count(netdev) > ahw->max_mc_count)) {
1544 mode = VPORT_MISS_MODE_ACCEPT_MULTI; 1531 mode = VPORT_MISS_MODE_ACCEPT_MULTI;
1532 } else {
1533 qlcnic_vf_add_mc_list(netdev, bcast_addr);
1534 if (!netdev_mc_empty(netdev)) {
1535 netdev_for_each_mc_addr(ha, netdev)
1536 qlcnic_vf_add_mc_list(netdev, ha->addr);
1537 }
1545 } 1538 }
1546 1539
1547 if (qlcnic_sriov_vf_check(adapter))
1548 qlcnic_vf_add_mc_list(netdev);
1549
1550 qlcnic_nic_set_promisc(adapter, mode); 1540 qlcnic_nic_set_promisc(adapter, mode);
1551} 1541}
1552 1542
1553static void qlcnic_sriov_handle_async_multi(struct work_struct *work) 1543static void qlcnic_sriov_handle_async_issue_cmd(struct work_struct *work)
1554{ 1544{
1555 struct qlcnic_async_work_list *entry; 1545 struct qlcnic_async_work_list *entry;
1556 struct net_device *netdev; 1546 struct qlcnic_adapter *adapter;
1547 struct qlcnic_cmd_args *cmd;
1557 1548
1558 entry = container_of(work, struct qlcnic_async_work_list, work); 1549 entry = container_of(work, struct qlcnic_async_work_list, work);
1559 netdev = (struct net_device *)entry->ptr; 1550 adapter = entry->ptr;
1560 1551 cmd = entry->cmd;
1561 qlcnic_sriov_vf_set_multi(netdev); 1552 __qlcnic_sriov_issue_cmd(adapter, cmd);
1562 return; 1553 return;
1563} 1554}
1564 1555
@@ -1588,8 +1579,9 @@ qlcnic_sriov_get_free_node_async_work(struct qlcnic_back_channel *bc)
1588 return entry; 1579 return entry;
1589} 1580}
1590 1581
1591static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc, 1582static void qlcnic_sriov_schedule_async_cmd(struct qlcnic_back_channel *bc,
1592 work_func_t func, void *data) 1583 work_func_t func, void *data,
1584 struct qlcnic_cmd_args *cmd)
1593{ 1585{
1594 struct qlcnic_async_work_list *entry = NULL; 1586 struct qlcnic_async_work_list *entry = NULL;
1595 1587
@@ -1598,21 +1590,23 @@ static void qlcnic_sriov_schedule_bc_async_work(struct qlcnic_back_channel *bc,
1598 return; 1590 return;
1599 1591
1600 entry->ptr = data; 1592 entry->ptr = data;
1593 entry->cmd = cmd;
1601 INIT_WORK(&entry->work, func); 1594 INIT_WORK(&entry->work, func);
1602 queue_work(bc->bc_async_wq, &entry->work); 1595 queue_work(bc->bc_async_wq, &entry->work);
1603} 1596}
1604 1597
1605void qlcnic_sriov_vf_schedule_multi(struct net_device *netdev) 1598static int qlcnic_sriov_async_issue_cmd(struct qlcnic_adapter *adapter,
1599 struct qlcnic_cmd_args *cmd)
1606{ 1600{
1607 1601
1608 struct qlcnic_adapter *adapter = netdev_priv(netdev);
1609 struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc; 1602 struct qlcnic_back_channel *bc = &adapter->ahw->sriov->bc;
1610 1603
1611 if (adapter->need_fw_reset) 1604 if (adapter->need_fw_reset)
1612 return; 1605 return -EIO;
1613 1606
1614 qlcnic_sriov_schedule_bc_async_work(bc, qlcnic_sriov_handle_async_multi, 1607 qlcnic_sriov_schedule_async_cmd(bc, qlcnic_sriov_handle_async_issue_cmd,
1615 netdev); 1608 adapter, cmd);
1609 return 0;
1616} 1610}
1617 1611
1618static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter) 1612static int qlcnic_sriov_vf_reinit_driver(struct qlcnic_adapter *adapter)
@@ -1890,7 +1884,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov,
1890 if (!vf->sriov_vlans) 1884 if (!vf->sriov_vlans)
1891 return err; 1885 return err;
1892 1886
1893 mutex_lock(&vf->vlan_list_lock); 1887 spin_lock_bh(&vf->vlan_list_lock);
1894 1888
1895 for (i = 0; i < sriov->num_allowed_vlans; i++) { 1889 for (i = 0; i < sriov->num_allowed_vlans; i++) {
1896 if (vf->sriov_vlans[i] == vlan_id) { 1890 if (vf->sriov_vlans[i] == vlan_id) {
@@ -1899,7 +1893,7 @@ static int qlcnic_sriov_check_vlan_id(struct qlcnic_sriov *sriov,
1899 } 1893 }
1900 } 1894 }
1901 1895
1902 mutex_unlock(&vf->vlan_list_lock); 1896 spin_unlock_bh(&vf->vlan_list_lock);
1903 return err; 1897 return err;
1904} 1898}
1905 1899
@@ -1908,12 +1902,12 @@ static int qlcnic_sriov_validate_num_vlans(struct qlcnic_sriov *sriov,
1908{ 1902{
1909 int err = 0; 1903 int err = 0;
1910 1904
1911 mutex_lock(&vf->vlan_list_lock); 1905 spin_lock_bh(&vf->vlan_list_lock);
1912 1906
1913 if (vf->num_vlan >= sriov->num_allowed_vlans) 1907 if (vf->num_vlan >= sriov->num_allowed_vlans)
1914 err = -EINVAL; 1908 err = -EINVAL;
1915 1909
1916 mutex_unlock(&vf->vlan_list_lock); 1910 spin_unlock_bh(&vf->vlan_list_lock);
1917 return err; 1911 return err;
1918} 1912}
1919 1913
@@ -1966,7 +1960,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id,
1966 if (!vf->sriov_vlans) 1960 if (!vf->sriov_vlans)
1967 return; 1961 return;
1968 1962
1969 mutex_lock(&vf->vlan_list_lock); 1963 spin_lock_bh(&vf->vlan_list_lock);
1970 1964
1971 switch (opcode) { 1965 switch (opcode) {
1972 case QLC_VLAN_ADD: 1966 case QLC_VLAN_ADD:
@@ -1979,7 +1973,7 @@ static void qlcnic_sriov_vlan_operation(struct qlcnic_vf_info *vf, u16 vlan_id,
1979 netdev_err(adapter->netdev, "Invalid VLAN operation\n"); 1973 netdev_err(adapter->netdev, "Invalid VLAN operation\n");
1980 } 1974 }
1981 1975
1982 mutex_unlock(&vf->vlan_list_lock); 1976 spin_unlock_bh(&vf->vlan_list_lock);
1983 return; 1977 return;
1984} 1978}
1985 1979
@@ -1987,6 +1981,7 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter,
1987 u16 vid, u8 enable) 1981 u16 vid, u8 enable)
1988{ 1982{
1989 struct qlcnic_sriov *sriov = adapter->ahw->sriov; 1983 struct qlcnic_sriov *sriov = adapter->ahw->sriov;
1984 struct net_device *netdev = adapter->netdev;
1990 struct qlcnic_vf_info *vf; 1985 struct qlcnic_vf_info *vf;
1991 struct qlcnic_cmd_args cmd; 1986 struct qlcnic_cmd_args cmd;
1992 int ret; 1987 int ret;
@@ -2012,14 +2007,18 @@ int qlcnic_sriov_cfg_vf_guest_vlan(struct qlcnic_adapter *adapter,
2012 dev_err(&adapter->pdev->dev, 2007 dev_err(&adapter->pdev->dev,
2013 "Failed to configure guest VLAN, err=%d\n", ret); 2008 "Failed to configure guest VLAN, err=%d\n", ret);
2014 } else { 2009 } else {
2010 netif_addr_lock_bh(netdev);
2015 qlcnic_free_mac_list(adapter); 2011 qlcnic_free_mac_list(adapter);
2012 netif_addr_unlock_bh(netdev);
2016 2013
2017 if (enable) 2014 if (enable)
2018 qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD); 2015 qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_ADD);
2019 else 2016 else
2020 qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE); 2017 qlcnic_sriov_vlan_operation(vf, vid, QLC_VLAN_DELETE);
2021 2018
2022 qlcnic_set_multi(adapter->netdev); 2019 netif_addr_lock_bh(netdev);
2020 qlcnic_set_multi(netdev);
2021 netif_addr_unlock_bh(netdev);
2023 } 2022 }
2024 2023
2025 qlcnic_free_mbx_args(&cmd); 2024 qlcnic_free_mbx_args(&cmd);
@@ -2150,11 +2149,11 @@ bool qlcnic_sriov_check_any_vlan(struct qlcnic_vf_info *vf)
2150{ 2149{
2151 bool err = false; 2150 bool err = false;
2152 2151
2153 mutex_lock(&vf->vlan_list_lock); 2152 spin_lock_bh(&vf->vlan_list_lock);
2154 2153
2155 if (vf->num_vlan) 2154 if (vf->num_vlan)
2156 err = true; 2155 err = true;
2157 2156
2158 mutex_unlock(&vf->vlan_list_lock); 2157 spin_unlock_bh(&vf->vlan_list_lock);
2159 return err; 2158 return err;
2160} 2159}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index df409086e4d3..199ab7c6fbad 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -784,7 +784,7 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
784 struct qlcnic_vf_info *vf, 784 struct qlcnic_vf_info *vf,
785 u16 vlan, u8 op) 785 u16 vlan, u8 op)
786{ 786{
787 struct qlcnic_cmd_args cmd; 787 struct qlcnic_cmd_args *cmd;
788 struct qlcnic_macvlan_mbx mv; 788 struct qlcnic_macvlan_mbx mv;
789 struct qlcnic_vport *vp; 789 struct qlcnic_vport *vp;
790 u8 *addr; 790 u8 *addr;
@@ -794,21 +794,27 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
794 794
795 vp = vf->vp; 795 vp = vf->vp;
796 796
797 if (qlcnic_alloc_mbx_args(&cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN)) 797 cmd = kzalloc(sizeof(*cmd), GFP_ATOMIC);
798 if (!cmd)
798 return -ENOMEM; 799 return -ENOMEM;
799 800
801 err = qlcnic_alloc_mbx_args(cmd, adapter, QLCNIC_CMD_CONFIG_MAC_VLAN);
802 if (err)
803 goto free_cmd;
804
805 cmd->type = QLC_83XX_MBX_CMD_NO_WAIT;
800 vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func); 806 vpid = qlcnic_sriov_pf_get_vport_handle(adapter, vf->pci_func);
801 if (vpid < 0) { 807 if (vpid < 0) {
802 err = -EINVAL; 808 err = -EINVAL;
803 goto out; 809 goto free_args;
804 } 810 }
805 811
806 if (vlan) 812 if (vlan)
807 op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ? 813 op = ((op == QLCNIC_MAC_ADD || op == QLCNIC_MAC_VLAN_ADD) ?
808 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL); 814 QLCNIC_MAC_VLAN_ADD : QLCNIC_MAC_VLAN_DEL);
809 815
810 cmd.req.arg[1] = op | (1 << 8) | (3 << 6); 816 cmd->req.arg[1] = op | (1 << 8) | (3 << 6);
811 cmd.req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31; 817 cmd->req.arg[1] |= ((vpid & 0xffff) << 16) | BIT_31;
812 818
813 addr = vp->mac; 819 addr = vp->mac;
814 mv.vlan = vlan; 820 mv.vlan = vlan;
@@ -818,18 +824,18 @@ static int qlcnic_sriov_cfg_vf_def_mac(struct qlcnic_adapter *adapter,
818 mv.mac_addr3 = addr[3]; 824 mv.mac_addr3 = addr[3];
819 mv.mac_addr4 = addr[4]; 825 mv.mac_addr4 = addr[4];
820 mv.mac_addr5 = addr[5]; 826 mv.mac_addr5 = addr[5];
821 buf = &cmd.req.arg[2]; 827 buf = &cmd->req.arg[2];
822 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx)); 828 memcpy(buf, &mv, sizeof(struct qlcnic_macvlan_mbx));
823 829
824 err = qlcnic_issue_cmd(adapter, &cmd); 830 err = qlcnic_issue_cmd(adapter, cmd);
825 831
826 if (err) 832 if (!err)
827 dev_err(&adapter->pdev->dev, 833 return err;
828 "MAC-VLAN %s to CAM failed, err=%d.\n",
829 ((op == 1) ? "add " : "delete "), err);
830 834
831out: 835free_args:
832 qlcnic_free_mbx_args(&cmd); 836 qlcnic_free_mbx_args(cmd);
837free_cmd:
838 kfree(cmd);
833 return err; 839 return err;
834} 840}
835 841
@@ -851,7 +857,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter,
851 857
852 sriov = adapter->ahw->sriov; 858 sriov = adapter->ahw->sriov;
853 859
854 mutex_lock(&vf->vlan_list_lock); 860 spin_lock_bh(&vf->vlan_list_lock);
855 if (vf->num_vlan) { 861 if (vf->num_vlan) {
856 for (i = 0; i < sriov->num_allowed_vlans; i++) { 862 for (i = 0; i < sriov->num_allowed_vlans; i++) {
857 vlan = vf->sriov_vlans[i]; 863 vlan = vf->sriov_vlans[i];
@@ -860,7 +866,7 @@ static void qlcnic_83xx_cfg_default_mac_vlan(struct qlcnic_adapter *adapter,
860 opcode); 866 opcode);
861 } 867 }
862 } 868 }
863 mutex_unlock(&vf->vlan_list_lock); 869 spin_unlock_bh(&vf->vlan_list_lock);
864 870
865 if (vf->vp->vlan_mode != QLC_PVID_MODE) { 871 if (vf->vp->vlan_mode != QLC_PVID_MODE) {
866 if (qlcnic_83xx_pf_check(adapter) && 872 if (qlcnic_83xx_pf_check(adapter) &&