aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSathya Perla <sathya.perla@emulex.com>2011-08-02 15:57:44 -0400
committerDavid S. Miller <davem@davemloft.net>2011-08-03 06:23:30 -0400
commit5b8821b787495273ba4fb333a3561c6da382a9a7 (patch)
tree61b27b53817ac151ab41a08ac91751c8336fdae5
parentc0e64ef4899df4cedc872871e54e2c069d29e519 (diff)
be2net: use RX_FILTER cmd to program multicast addresses
Use this cmd for both promiscous and multicast address programming. Get rid of the old MULTICAST_SET cmd. Signed-off-by: Sathya Perla <sathya.perla@emulex.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/benet/be.h4
-rw-r--r--drivers/net/benet/be_cmds.c103
-rw-r--r--drivers/net/benet/be_cmds.h20
-rw-r--r--drivers/net/benet/be_main.c28
4 files changed, 41 insertions, 114 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 8d897d1a93ba..1e7f0094e382 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -334,7 +334,7 @@ struct be_adapter {
334 u8 vlan_tag[VLAN_N_VID]; 334 u8 vlan_tag[VLAN_N_VID];
335 u8 vlan_prio_bmap; /* Available Priority BitMap */ 335 u8 vlan_prio_bmap; /* Available Priority BitMap */
336 u16 recommended_prio; /* Recommended Priority */ 336 u16 recommended_prio; /* Recommended Priority */
337 struct be_dma_mem mc_cmd_mem; 337 struct be_dma_mem rx_filter; /* Cmd DMA mem for rx-filter */
338 338
339 struct be_dma_mem stats_cmd; 339 struct be_dma_mem stats_cmd;
340 /* Work queue used to perform periodic tasks like getting statistics */ 340 /* Work queue used to perform periodic tasks like getting statistics */
@@ -381,6 +381,8 @@ struct be_adapter {
381#define BE_GEN2 2 381#define BE_GEN2 2
382#define BE_GEN3 3 382#define BE_GEN3 3
383 383
384#define ON 1
385#define OFF 0
384#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \ 386#define lancer_chip(adapter) ((adapter->pdev->device == OC_DEVICE_ID3) || \
385 (adapter->pdev->device == OC_DEVICE_ID4)) 387 (adapter->pdev->device == OC_DEVICE_ID4))
386 388
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 73fd949a6e7d..f138fbb2e4a8 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -1548,72 +1548,11 @@ err:
1548 return status; 1548 return status;
1549} 1549}
1550 1550
1551/* Uses MCC for this command as it may be called in BH context 1551int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 value)
1552 * Uses synchronous mcc
1553 */
1554int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en)
1555{
1556 struct be_mcc_wrb *wrb;
1557 struct be_cmd_req_rx_filter *req;
1558 struct be_dma_mem promiscous_cmd;
1559 struct be_sge *sge;
1560 int status;
1561
1562 memset(&promiscous_cmd, 0, sizeof(struct be_dma_mem));
1563 promiscous_cmd.size = sizeof(struct be_cmd_req_rx_filter);
1564 promiscous_cmd.va = pci_alloc_consistent(adapter->pdev,
1565 promiscous_cmd.size, &promiscous_cmd.dma);
1566 if (!promiscous_cmd.va) {
1567 dev_err(&adapter->pdev->dev,
1568 "Memory allocation failure\n");
1569 return -ENOMEM;
1570 }
1571
1572 spin_lock_bh(&adapter->mcc_lock);
1573
1574 wrb = wrb_from_mccq(adapter);
1575 if (!wrb) {
1576 status = -EBUSY;
1577 goto err;
1578 }
1579
1580 req = promiscous_cmd.va;
1581 sge = nonembedded_sgl(wrb);
1582
1583 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
1584 OPCODE_COMMON_NTWK_RX_FILTER);
1585 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1586 OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
1587
1588 req->if_id = cpu_to_le32(adapter->if_handle);
1589 req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS
1590 | BE_IF_FLAGS_VLAN_PROMISCUOUS);
1591 if (en)
1592 req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS
1593 | BE_IF_FLAGS_VLAN_PROMISCUOUS);
1594
1595 sge->pa_hi = cpu_to_le32(upper_32_bits(promiscous_cmd.dma));
1596 sge->pa_lo = cpu_to_le32(promiscous_cmd.dma & 0xFFFFFFFF);
1597 sge->len = cpu_to_le32(promiscous_cmd.size);
1598
1599 status = be_mcc_notify_wait(adapter);
1600
1601err:
1602 spin_unlock_bh(&adapter->mcc_lock);
1603 pci_free_consistent(adapter->pdev, promiscous_cmd.size,
1604 promiscous_cmd.va, promiscous_cmd.dma);
1605 return status;
1606}
1607
1608/*
1609 * Uses MCC for this command as it may be called in BH context
1610 * (mc == NULL) => multicast promiscuous
1611 */
1612int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
1613 struct net_device *netdev, struct be_dma_mem *mem)
1614{ 1552{
1615 struct be_mcc_wrb *wrb; 1553 struct be_mcc_wrb *wrb;
1616 struct be_cmd_req_mcast_mac_config *req = mem->va; 1554 struct be_dma_mem *mem = &adapter->rx_filter;
1555 struct be_cmd_req_rx_filter *req = mem->va;
1617 struct be_sge *sge; 1556 struct be_sge *sge;
1618 int status; 1557 int status;
1619 1558
@@ -1625,33 +1564,35 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
1625 goto err; 1564 goto err;
1626 } 1565 }
1627 sge = nonembedded_sgl(wrb); 1566 sge = nonembedded_sgl(wrb);
1628 memset(req, 0, sizeof(*req));
1629
1630 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
1631 OPCODE_COMMON_NTWK_MULTICAST_SET);
1632 sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma)); 1567 sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
1633 sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF); 1568 sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
1634 sge->len = cpu_to_le32(mem->size); 1569 sge->len = cpu_to_le32(mem->size);
1570 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1,
1571 OPCODE_COMMON_NTWK_RX_FILTER);
1635 1572
1573 memset(req, 0, sizeof(*req));
1636 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 1574 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1637 OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); 1575 OPCODE_COMMON_NTWK_RX_FILTER, sizeof(*req));
1638 1576
1639 req->interface_id = if_id; 1577 req->if_id = cpu_to_le32(adapter->if_handle);
1640 if (netdev) { 1578 if (flags & IFF_PROMISC) {
1641 int i; 1579 req->if_flags_mask = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
1580 BE_IF_FLAGS_VLAN_PROMISCUOUS);
1581 if (value == ON)
1582 req->if_flags = cpu_to_le32(BE_IF_FLAGS_PROMISCUOUS |
1583 BE_IF_FLAGS_VLAN_PROMISCUOUS);
1584 } else if (flags & IFF_ALLMULTI) {
1585 req->if_flags_mask = req->if_flags =
1586 cpu_to_le32(BE_IF_FLAGS_MCAST_PROMISCUOUS);
1587 } else {
1642 struct netdev_hw_addr *ha; 1588 struct netdev_hw_addr *ha;
1589 int i = 0;
1643 1590
1644 req->num_mac = cpu_to_le16(netdev_mc_count(netdev)); 1591 req->mcast_num = cpu_to_le16(netdev_mc_count(adapter->netdev));
1645 1592 netdev_for_each_mc_addr(ha, adapter->netdev)
1646 i = 0; 1593 memcpy(req->mcast_mac[i++].byte, ha->addr, ETH_ALEN);
1647 netdev_for_each_mc_addr(ha, netdev)
1648 memcpy(req->mac[i++].byte, ha->addr, ETH_ALEN);
1649 } else {
1650 req->promiscuous = 1;
1651 } 1594 }
1652 1595
1653 status = be_mcc_notify_wait(adapter);
1654
1655err: 1596err:
1656 spin_unlock_bh(&adapter->mcc_lock); 1597 spin_unlock_bh(&adapter->mcc_lock);
1657 return status; 1598 return status;
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 6db545fb56d5..008bfae9cd3d 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -910,21 +910,12 @@ struct be_cmd_req_vlan_config {
910 u16 normal_vlan[64]; 910 u16 normal_vlan[64];
911} __packed; 911} __packed;
912 912
913/******************** Multicast MAC Config *******************/ 913/******************* RX FILTER ******************************/
914#define BE_MAX_MC 64 /* set mcast promisc if > 64 */ 914#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
915struct macaddr { 915struct macaddr {
916 u8 byte[ETH_ALEN]; 916 u8 byte[ETH_ALEN];
917}; 917};
918 918
919struct be_cmd_req_mcast_mac_config {
920 struct be_cmd_req_hdr hdr;
921 u16 num_mac;
922 u8 promiscuous;
923 u8 interface_id;
924 struct macaddr mac[BE_MAX_MC];
925} __packed;
926
927/******************* RX FILTER ******************************/
928struct be_cmd_req_rx_filter { 919struct be_cmd_req_rx_filter {
929 struct be_cmd_req_hdr hdr; 920 struct be_cmd_req_hdr hdr;
930 u32 global_flags_mask; 921 u32 global_flags_mask;
@@ -932,11 +923,10 @@ struct be_cmd_req_rx_filter {
932 u32 if_flags_mask; 923 u32 if_flags_mask;
933 u32 if_flags; 924 u32 if_flags;
934 u32 if_id; 925 u32 if_id;
935 u32 multicast_num; 926 u32 mcast_num;
936 struct macaddr mac[BE_MAX_MC]; 927 struct macaddr mcast_mac[BE_MAX_MC];
937}; 928};
938 929
939
940/******************** Link Status Query *******************/ 930/******************** Link Status Query *******************/
941struct be_cmd_req_link_status { 931struct be_cmd_req_link_status {
942 struct be_cmd_req_hdr hdr; 932 struct be_cmd_req_hdr hdr;
@@ -1455,9 +1445,7 @@ extern int be_cmd_modify_eqd(struct be_adapter *adapter, u32 eq_id, u32 eqd);
1455extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, 1445extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
1456 u16 *vtag_array, u32 num, bool untagged, 1446 u16 *vtag_array, u32 num, bool untagged,
1457 bool promiscuous); 1447 bool promiscuous);
1458extern int be_cmd_promiscuous_config(struct be_adapter *adapter, bool en); 1448extern int be_cmd_rx_filter(struct be_adapter *adapter, u32 flags, u32 status);
1459extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
1460 struct net_device *netdev, struct be_dma_mem *mem);
1461extern int be_cmd_set_flow_control(struct be_adapter *adapter, 1449extern int be_cmd_set_flow_control(struct be_adapter *adapter,
1462 u32 tx_fc, u32 rx_fc); 1450 u32 tx_fc, u32 rx_fc);
1463extern int be_cmd_get_flow_control(struct be_adapter *adapter, 1451extern int be_cmd_get_flow_control(struct be_adapter *adapter,
diff --git a/drivers/net/benet/be_main.c b/drivers/net/benet/be_main.c
index 32a5b1100114..5890bca01c07 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -782,7 +782,7 @@ static void be_set_multicast_list(struct net_device *netdev)
782 struct be_adapter *adapter = netdev_priv(netdev); 782 struct be_adapter *adapter = netdev_priv(netdev);
783 783
784 if (netdev->flags & IFF_PROMISC) { 784 if (netdev->flags & IFF_PROMISC) {
785 be_cmd_promiscuous_config(adapter, true); 785 be_cmd_rx_filter(adapter, IFF_PROMISC, ON);
786 adapter->promiscuous = true; 786 adapter->promiscuous = true;
787 goto done; 787 goto done;
788 } 788 }
@@ -790,7 +790,7 @@ static void be_set_multicast_list(struct net_device *netdev)
790 /* BE was previously in promiscuous mode; disable it */ 790 /* BE was previously in promiscuous mode; disable it */
791 if (adapter->promiscuous) { 791 if (adapter->promiscuous) {
792 adapter->promiscuous = false; 792 adapter->promiscuous = false;
793 be_cmd_promiscuous_config(adapter, false); 793 be_cmd_rx_filter(adapter, IFF_PROMISC, OFF);
794 794
795 if (adapter->vlans_added) 795 if (adapter->vlans_added)
796 be_vid_config(adapter, false, 0); 796 be_vid_config(adapter, false, 0);
@@ -798,14 +798,12 @@ static void be_set_multicast_list(struct net_device *netdev)
798 798
799 /* Enable multicast promisc if num configured exceeds what we support */ 799 /* Enable multicast promisc if num configured exceeds what we support */
800 if (netdev->flags & IFF_ALLMULTI || 800 if (netdev->flags & IFF_ALLMULTI ||
801 netdev_mc_count(netdev) > BE_MAX_MC) { 801 netdev_mc_count(netdev) > BE_MAX_MC) {
802 be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 802 be_cmd_rx_filter(adapter, IFF_ALLMULTI, ON);
803 &adapter->mc_cmd_mem);
804 goto done; 803 goto done;
805 } 804 }
806 805
807 be_cmd_multicast_set(adapter, adapter->if_handle, netdev, 806 be_cmd_rx_filter(adapter, IFF_MULTICAST, ON);
808 &adapter->mc_cmd_mem);
809done: 807done:
810 return; 808 return;
811} 809}
@@ -2976,7 +2974,7 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
2976 dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, 2974 dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
2977 mem->dma); 2975 mem->dma);
2978 2976
2979 mem = &adapter->mc_cmd_mem; 2977 mem = &adapter->rx_filter;
2980 if (mem->va) 2978 if (mem->va)
2981 dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va, 2979 dma_free_coherent(&adapter->pdev->dev, mem->size, mem->va,
2982 mem->dma); 2980 mem->dma);
@@ -2986,7 +2984,7 @@ static int be_ctrl_init(struct be_adapter *adapter)
2986{ 2984{
2987 struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; 2985 struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
2988 struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; 2986 struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
2989 struct be_dma_mem *mc_cmd_mem = &adapter->mc_cmd_mem; 2987 struct be_dma_mem *rx_filter = &adapter->rx_filter;
2990 int status; 2988 int status;
2991 2989
2992 status = be_map_pci_bars(adapter); 2990 status = be_map_pci_bars(adapter);
@@ -3002,21 +3000,19 @@ static int be_ctrl_init(struct be_adapter *adapter)
3002 status = -ENOMEM; 3000 status = -ENOMEM;
3003 goto unmap_pci_bars; 3001 goto unmap_pci_bars;
3004 } 3002 }
3005
3006 mbox_mem_align->size = sizeof(struct be_mcc_mailbox); 3003 mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
3007 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); 3004 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
3008 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); 3005 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
3009 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); 3006 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
3010 3007
3011 mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config); 3008 rx_filter->size = sizeof(struct be_cmd_req_rx_filter);
3012 mc_cmd_mem->va = dma_alloc_coherent(&adapter->pdev->dev, 3009 rx_filter->va = dma_alloc_coherent(&adapter->pdev->dev, rx_filter->size,
3013 mc_cmd_mem->size, &mc_cmd_mem->dma, 3010 &rx_filter->dma, GFP_KERNEL);
3014 GFP_KERNEL); 3011 if (rx_filter->va == NULL) {
3015 if (mc_cmd_mem->va == NULL) {
3016 status = -ENOMEM; 3012 status = -ENOMEM;
3017 goto free_mbox; 3013 goto free_mbox;
3018 } 3014 }
3019 memset(mc_cmd_mem->va, 0, mc_cmd_mem->size); 3015 memset(rx_filter->va, 0, rx_filter->size);
3020 3016
3021 mutex_init(&adapter->mbox_lock); 3017 mutex_init(&adapter->mbox_lock);
3022 spin_lock_init(&adapter->mcc_lock); 3018 spin_lock_init(&adapter->mcc_lock);