diff options
author | Sathya Perla <sathyap@serverengines.com> | 2009-11-22 17:01:10 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-11-23 13:44:18 -0500 |
commit | e7b909a68cfb83e4bafdadac39534969ce260518 (patch) | |
tree | ab8e12fdcb4524598de8b8c867c27ada237e8b1d /drivers/net | |
parent | 9d4fb27db90043cd2640e4bc778f9c755d3c17c1 (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')
-rw-r--r-- | drivers/net/benet/be.h | 1 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.c | 23 | ||||
-rw-r--r-- | drivers/net/benet/be_cmds.h | 7 | ||||
-rw-r--r-- | drivers/net/benet/be_main.c | 41 |
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 | */ |
992 | int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | 992 | int 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 */ | ||
594 | struct macaddr { | 596 | struct 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 | ||
606 | static inline struct be_hw_stats * | 608 | static inline struct be_hw_stats * |
@@ -829,7 +831,8 @@ extern int be_cmd_vlan_config(struct be_adapter *adapter, u32 if_id, | |||
829 | extern int be_cmd_promiscuous_config(struct be_adapter *adapter, | 831 | extern int be_cmd_promiscuous_config(struct be_adapter *adapter, |
830 | u8 port_num, bool en); | 832 | u8 port_num, bool en); |
831 | extern int be_cmd_multicast_set(struct be_adapter *adapter, u32 if_id, | 833 | extern 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); | ||
833 | extern int be_cmd_set_flow_control(struct be_adapter *adapter, | 836 | extern int be_cmd_set_flow_control(struct be_adapter *adapter, |
834 | u32 tx_fc, u32 rx_fc); | 837 | u32 tx_fc, u32 rx_fc); |
835 | extern int be_cmd_get_flow_control(struct be_adapter *adapter, | 838 | extern 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); |
572 | done: | 574 | done: |
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 | ||
2014 | static int be_ctrl_init(struct be_adapter *adapter) | 2021 | static 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 | |||
2060 | free_mbox: | ||
2061 | pci_free_consistent(adapter->pdev, mbox_mem_alloc->size, | ||
2062 | mbox_mem_alloc->va, mbox_mem_alloc->dma); | ||
2063 | |||
2064 | unmap_pci_bars: | ||
2065 | be_unmap_pci_bars(adapter); | ||
2066 | |||
2067 | done: | ||
2068 | return status; | ||
2040 | } | 2069 | } |
2041 | 2070 | ||
2042 | static void be_stats_cleanup(struct be_adapter *adapter) | 2071 | static void be_stats_cleanup(struct be_adapter *adapter) |