aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/benet
diff options
context:
space:
mode:
authorSathya Perla <sathyap@serverengines.com>2009-11-22 17:01:10 -0500
committerDavid S. Miller <davem@davemloft.net>2009-11-23 13:44:18 -0500
commite7b909a68cfb83e4bafdadac39534969ce260518 (patch)
treeab8e12fdcb4524598de8b8c867c27ada237e8b1d /drivers/net/benet
parent9d4fb27db90043cd2640e4bc778f9c755d3c17c1 (diff)
be2net: support configuration of 64 multicast addresses instead of 32
To send upto 64 addresses in the multicast-set cmd, the non-embeeded cmd format that provides for a bigger buffer is used instead of an embedded format. Signed-off-by: Sathya Perla <sathyap@serverengines.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/benet')
-rw-r--r--drivers/net/benet/be.h1
-rw-r--r--drivers/net/benet/be_cmds.c23
-rw-r--r--drivers/net/benet/be_cmds.h7
-rw-r--r--drivers/net/benet/be_main.c41
4 files changed, 55 insertions, 17 deletions
diff --git a/drivers/net/benet/be.h b/drivers/net/benet/be.h
index 67e165cf3f4e..dc7c19e49111 100644
--- a/drivers/net/benet/be.h
+++ b/drivers/net/benet/be.h
@@ -254,6 +254,7 @@ struct be_adapter {
254 struct vlan_group *vlan_grp; 254 struct vlan_group *vlan_grp;
255 u16 num_vlans; 255 u16 num_vlans;
256 u8 vlan_tag[VLAN_GROUP_ARRAY_LEN]; 256 u8 vlan_tag[VLAN_GROUP_ARRAY_LEN];
257 struct be_dma_mem mc_cmd_mem;
257 258
258 struct be_stats_obj stats; 259 struct be_stats_obj stats;
259 /* Work queue used to perform periodic tasks like getting statistics */ 260 /* Work queue used to perform periodic tasks like getting statistics */
diff --git a/drivers/net/benet/be_cmds.c b/drivers/net/benet/be_cmds.c
index 808ad0dd4115..31980f863d12 100644
--- a/drivers/net/benet/be_cmds.c
+++ b/drivers/net/benet/be_cmds.c
@@ -990,24 +990,30 @@ int be_cmd_promiscuous_config(struct be_adapter *adapter, u8 port_num, bool en)
990 * (mc == NULL) => multicast promiscous 990 * (mc == NULL) => multicast promiscous
991 */ 991 */
992int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, 992int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
993 struct dev_mc_list *mc_list, u32 mc_count) 993 struct dev_mc_list *mc_list, u32 mc_count,
994 struct be_dma_mem *mem)
994{ 995{
995#define BE_MAX_MC 32 /* set mcast promisc if > 32 */
996 struct be_mcc_wrb *wrb; 996 struct be_mcc_wrb *wrb;
997 struct be_cmd_req_mcast_mac_config *req; 997 struct be_cmd_req_mcast_mac_config *req = mem->va;
998 struct be_sge *sge;
999 int status;
998 1000
999 spin_lock_bh(&adapter->mcc_lock); 1001 spin_lock_bh(&adapter->mcc_lock);
1000 1002
1001 wrb = wrb_from_mccq(adapter); 1003 wrb = wrb_from_mccq(adapter);
1002 req = embedded_payload(wrb); 1004 sge = nonembedded_sgl(wrb);
1005 memset(req, 0, sizeof(*req));
1003 1006
1004 be_wrb_hdr_prepare(wrb, sizeof(*req), true, 0); 1007 be_wrb_hdr_prepare(wrb, sizeof(*req), false, 1);
1008 sge->pa_hi = cpu_to_le32(upper_32_bits(mem->dma));
1009 sge->pa_lo = cpu_to_le32(mem->dma & 0xFFFFFFFF);
1010 sge->len = cpu_to_le32(mem->size);
1005 1011
1006 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON, 1012 be_cmd_hdr_prepare(&req->hdr, CMD_SUBSYSTEM_COMMON,
1007 OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req)); 1013 OPCODE_COMMON_NTWK_MULTICAST_SET, sizeof(*req));
1008 1014
1009 req->interface_id = if_id; 1015 req->interface_id = if_id;
1010 if (mc_list && mc_count <= BE_MAX_MC) { 1016 if (mc_list) {
1011 int i; 1017 int i;
1012 struct dev_mc_list *mc; 1018 struct dev_mc_list *mc;
1013 1019
@@ -1019,11 +1025,10 @@ int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
1019 req->promiscuous = 1; 1025 req->promiscuous = 1;
1020 } 1026 }
1021 1027
1022 be_mcc_notify_wait(adapter); 1028 status = be_mcc_notify_wait(adapter);
1023 1029
1024 spin_unlock_bh(&adapter->mcc_lock); 1030 spin_unlock_bh(&adapter->mcc_lock);
1025 1031 return status;
1026 return 0;
1027} 1032}
1028 1033
1029/* Uses synchrounous mcc */ 1034/* Uses synchrounous mcc */
diff --git a/drivers/net/benet/be_cmds.h b/drivers/net/benet/be_cmds.h
index 6a430e4d1755..3b31abc01b5c 100644
--- a/drivers/net/benet/be_cmds.h
+++ b/drivers/net/benet/be_cmds.h
@@ -591,6 +591,8 @@ struct be_cmd_req_promiscuous_config {
591 u16 rsvd0; 591 u16 rsvd0;
592} __packed; 592} __packed;
593 593
594/******************** Multicast MAC Config *******************/
595#define BE_MAX_MC 64 /* set mcast promisc if > 64 */
594struct macaddr { 596struct macaddr {
595 u8 byte[ETH_ALEN]; 597 u8 byte[ETH_ALEN];
596}; 598};
@@ -600,7 +602,7 @@ struct be_cmd_req_mcast_mac_config {
600 u16 num_mac; 602 u16 num_mac;
601 u8 promiscuous; 603 u8 promiscuous;
602 u8 interface_id; 604 u8 interface_id;
603 struct macaddr mac[32]; 605 struct macaddr mac[BE_MAX_MC];
604} __packed; 606} __packed;
605 607
606static inline struct be_hw_stats * 608static inline struct be_hw_stats *
@@ -829,7 +831,8 @@ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id,
829extern int be_cmd_promiscuous_config(struct be_adapter *adapter, 831extern int be_cmd_promiscuous_config(struct be_adapter *adapter,
830 u8 port_num, bool en); 832 u8 port_num, bool en);
831extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, 833extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id,
832 struct dev_mc_list *mc_list, u32 mc_count); 834 struct dev_mc_list *mc_list, u32 mc_count,
835 struct be_dma_mem *mem);
833extern int be_cmd_set_flow_control(struct be_adapter *adapter, 836extern int be_cmd_set_flow_control(struct be_adapter *adapter,
834 u32 tx_fc, u32 rx_fc); 837 u32 tx_fc, u32 rx_fc);
835extern int be_cmd_get_flow_control(struct be_adapter *adapter, 838extern 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 921103c40195..919fd82ebbae 100644
--- a/drivers/net/benet/be_main.c
+++ b/drivers/net/benet/be_main.c
@@ -562,13 +562,15 @@ static void be_set_multicast_list(struct net_device *netdev)
562 be_cmd_promiscuous_config(adapter, adapter->port_num, 0); 562 be_cmd_promiscuous_config(adapter, adapter->port_num, 0);
563 } 563 }
564 564
565 if (netdev->flags & IFF_ALLMULTI) { 565 /* Enable multicast promisc if num configured exceeds what we support */
566 be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0); 566 if (netdev->flags & IFF_ALLMULTI || netdev->mc_count > BE_MAX_MC) {
567 be_cmd_multicast_set(adapter, adapter->if_handle, NULL, 0,
568 &adapter->mc_cmd_mem);
567 goto done; 569 goto done;
568 } 570 }
569 571
570 be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list, 572 be_cmd_multicast_set(adapter, adapter->if_handle, netdev->mc_list,
571 netdev->mc_count); 573 netdev->mc_count, &adapter->mc_cmd_mem);
572done: 574done:
573 return; 575 return;
574} 576}
@@ -2009,34 +2011,61 @@ static void be_ctrl_cleanup(struct be_adapter *adapter)
2009 if (mem->va) 2011 if (mem->va)
2010 pci_free_consistent(adapter->pdev, mem->size, 2012 pci_free_consistent(adapter->pdev, mem->size,
2011 mem->va, mem->dma); 2013 mem->va, mem->dma);
2014
2015 mem = &adapter->mc_cmd_mem;
2016 if (mem->va)
2017 pci_free_consistent(adapter->pdev, mem->size,
2018 mem->va, mem->dma);
2012} 2019}
2013 2020
2014static int be_ctrl_init(struct be_adapter *adapter) 2021static int be_ctrl_init(struct be_adapter *adapter)
2015{ 2022{
2016 struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced; 2023 struct be_dma_mem *mbox_mem_alloc = &adapter->mbox_mem_alloced;
2017 struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem; 2024 struct be_dma_mem *mbox_mem_align = &adapter->mbox_mem;
2025 struct be_dma_mem *mc_cmd_mem = &adapter->mc_cmd_mem;
2018 int status; 2026 int status;
2019 2027
2020 status = be_map_pci_bars(adapter); 2028 status = be_map_pci_bars(adapter);
2021 if (status) 2029 if (status)
2022 return status; 2030 goto done;
2023 2031
2024 mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16; 2032 mbox_mem_alloc->size = sizeof(struct be_mcc_mailbox) + 16;
2025 mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev, 2033 mbox_mem_alloc->va = pci_alloc_consistent(adapter->pdev,
2026 mbox_mem_alloc->size, &mbox_mem_alloc->dma); 2034 mbox_mem_alloc->size, &mbox_mem_alloc->dma);
2027 if (!mbox_mem_alloc->va) { 2035 if (!mbox_mem_alloc->va) {
2028 be_unmap_pci_bars(adapter); 2036 status = -ENOMEM;
2029 return -1; 2037 goto unmap_pci_bars;
2030 } 2038 }
2039
2031 mbox_mem_align->size = sizeof(struct be_mcc_mailbox); 2040 mbox_mem_align->size = sizeof(struct be_mcc_mailbox);
2032 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16); 2041 mbox_mem_align->va = PTR_ALIGN(mbox_mem_alloc->va, 16);
2033 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16); 2042 mbox_mem_align->dma = PTR_ALIGN(mbox_mem_alloc->dma, 16);
2034 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox)); 2043 memset(mbox_mem_align->va, 0, sizeof(struct be_mcc_mailbox));
2044
2045 mc_cmd_mem->size = sizeof(struct be_cmd_req_mcast_mac_config);
2046 mc_cmd_mem->va = pci_alloc_consistent(adapter->pdev, mc_cmd_mem->size,
2047 &mc_cmd_mem->dma);
2048 if (mc_cmd_mem->va == NULL) {
2049 status = -ENOMEM;
2050 goto free_mbox;
2051 }
2052 memset(mc_cmd_mem->va, 0, mc_cmd_mem->size);
2053
2035 spin_lock_init(&adapter->mbox_lock); 2054 spin_lock_init(&adapter->mbox_lock);
2036 spin_lock_init(&adapter->mcc_lock); 2055 spin_lock_init(&adapter->mcc_lock);
2037 spin_lock_init(&adapter->mcc_cq_lock); 2056 spin_lock_init(&adapter->mcc_cq_lock);
2038 2057
2039 return 0; 2058 return 0;
2059
2060free_mbox:
2061 pci_free_consistent(adapter->pdev, mbox_mem_alloc->size,
2062 mbox_mem_alloc->va, mbox_mem_alloc->dma);
2063
2064unmap_pci_bars:
2065 be_unmap_pci_bars(adapter);
2066
2067done:
2068 return status;
2040} 2069}
2041 2070
2042static void be_stats_cleanup(struct be_adapter *adapter) 2071static void be_stats_cleanup(struct be_adapter *adapter)