aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Pirko <jpirko@redhat.com>2010-02-24 00:11:08 -0500
committerDavid S. Miller <davem@davemloft.net>2010-02-26 07:22:27 -0500
commitfbf219f1c89b15e90ec2db5a3e9636376dc623db (patch)
treea61f07cad8a0d2b0db1cb2111e6bd624313b1459
parent6e17d45ae310758ab30623a42ad070858c9a48de (diff)
infiniband: convert to use netdev_for_each_mc_addr
Due to the loop complexicity in nes_nic.c, I'm using char* to copy mc addresses to it. Signed-off-by: Jiri Pirko <jpirko@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c85
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c8
2 files changed, 51 insertions, 42 deletions
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c
index c04f8fc6fc2d..9384f5d3d33b 100644
--- a/drivers/infiniband/hw/nes/nes_nic.c
+++ b/drivers/infiniband/hw/nes/nes_nic.c
@@ -810,6 +810,20 @@ static int nes_netdev_set_mac_address(struct net_device *netdev, void *p)
810} 810}
811 811
812 812
813static void set_allmulti(struct nes_device *nesdev, u32 nic_active_bit)
814{
815 u32 nic_active;
816
817 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
818 nic_active |= nic_active_bit;
819 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
820 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
821 nic_active &= ~nic_active_bit;
822 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
823}
824
825#define get_addr(addrs, index) ((addrs) + (index) * ETH_ALEN)
826
813/** 827/**
814 * nes_netdev_set_multicast_list 828 * nes_netdev_set_multicast_list
815 */ 829 */
@@ -818,7 +832,6 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
818 struct nes_vnic *nesvnic = netdev_priv(netdev); 832 struct nes_vnic *nesvnic = netdev_priv(netdev);
819 struct nes_device *nesdev = nesvnic->nesdev; 833 struct nes_device *nesdev = nesvnic->nesdev;
820 struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; 834 struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
821 struct dev_mc_list *multicast_addr;
822 u32 nic_active_bit; 835 u32 nic_active_bit;
823 u32 nic_active; 836 u32 nic_active;
824 u32 perfect_filter_register_address; 837 u32 perfect_filter_register_address;
@@ -831,6 +844,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
831 nics_per_function, 4); 844 nics_per_function, 4);
832 u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated; 845 u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated;
833 unsigned long flags; 846 unsigned long flags;
847 int mc_count = netdev_mc_count(netdev);
834 848
835 spin_lock_irqsave(&nesadapter->resource_lock, flags); 849 spin_lock_irqsave(&nesadapter->resource_lock, flags);
836 nic_active_bit = 1 << nesvnic->nic_index; 850 nic_active_bit = 1 << nesvnic->nic_index;
@@ -845,12 +859,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
845 mc_all_on = 1; 859 mc_all_on = 1;
846 } else if ((netdev->flags & IFF_ALLMULTI) || 860 } else if ((netdev->flags & IFF_ALLMULTI) ||
847 (nesvnic->nic_index > 3)) { 861 (nesvnic->nic_index > 3)) {
848 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 862 set_allmulti(nesdev, nic_active_bit);
849 nic_active |= nic_active_bit;
850 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, nic_active);
851 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL);
852 nic_active &= ~nic_active_bit;
853 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
854 mc_all_on = 1; 863 mc_all_on = 1;
855 } else { 864 } else {
856 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); 865 nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
@@ -862,19 +871,30 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
862 } 871 }
863 872
864 nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", 873 nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n",
865 netdev_mc_count(netdev), !!(netdev->flags & IFF_PROMISC), 874 mc_count, !!(netdev->flags & IFF_PROMISC),
866 !!(netdev->flags & IFF_ALLMULTI)); 875 !!(netdev->flags & IFF_ALLMULTI));
867 if (!mc_all_on) { 876 if (!mc_all_on) {
868 multicast_addr = netdev->mc_list; 877 char *addrs;
878 int i;
879 struct dev_mc_list *mcaddr;
880
881 addrs = kmalloc(ETH_ALEN * mc_count, GFP_ATOMIC);
882 if (!addrs) {
883 set_allmulti(nesdev, nic_active_bit);
884 goto unlock;
885 }
886 i = 0;
887 netdev_for_each_mc_addr(mcaddr, netdev)
888 memcpy(get_addr(addrs, i++),
889 mcaddr->dmi_addr, ETH_ALEN);
890
869 perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 891 perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
870 pft_entries_preallocated * 0x8; 892 pft_entries_preallocated * 0x8;
871 for (mc_index = 0; mc_index < max_pft_entries_avaiable; 893 for (i = 0, mc_index = 0; mc_index < max_pft_entries_avaiable;
872 mc_index++) { 894 mc_index++) {
873 while (multicast_addr && nesvnic->mcrq_mcast_filter && 895 while (i < mc_count && nesvnic->mcrq_mcast_filter &&
874 ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, 896 ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic,
875 multicast_addr->dmi_addr)) == 0)) { 897 get_addr(addrs, i++))) == 0));
876 multicast_addr = multicast_addr->next;
877 }
878 if (mc_nic_index < 0) 898 if (mc_nic_index < 0)
879 mc_nic_index = nesvnic->nic_index; 899 mc_nic_index = nesvnic->nic_index;
880 while (nesadapter->pft_mcast_map[mc_index] < 16 && 900 while (nesadapter->pft_mcast_map[mc_index] < 16 &&
@@ -890,17 +910,19 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
890 } 910 }
891 if (mc_index >= max_pft_entries_avaiable) 911 if (mc_index >= max_pft_entries_avaiable)
892 break; 912 break;
893 if (multicast_addr) { 913 if (i < mc_count) {
914 char *addr = get_addr(addrs, i++);
915
894 nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n", 916 nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %pM to register 0x%04X nic_idx=%d\n",
895 multicast_addr->dmi_addr, 917 addr,
896 perfect_filter_register_address+(mc_index * 8), 918 perfect_filter_register_address+(mc_index * 8),
897 mc_nic_index); 919 mc_nic_index);
898 macaddr_high = ((u16)multicast_addr->dmi_addr[0]) << 8; 920 macaddr_high = ((u16) addr[0]) << 8;
899 macaddr_high += (u16)multicast_addr->dmi_addr[1]; 921 macaddr_high += (u16) addr[1];
900 macaddr_low = ((u32)multicast_addr->dmi_addr[2]) << 24; 922 macaddr_low = ((u32) addr[2]) << 24;
901 macaddr_low += ((u32)multicast_addr->dmi_addr[3]) << 16; 923 macaddr_low += ((u32) addr[3]) << 16;
902 macaddr_low += ((u32)multicast_addr->dmi_addr[4]) << 8; 924 macaddr_low += ((u32) addr[4]) << 8;
903 macaddr_low += (u32)multicast_addr->dmi_addr[5]; 925 macaddr_low += (u32) addr[5];
904 nes_write_indexed(nesdev, 926 nes_write_indexed(nesdev,
905 perfect_filter_register_address+(mc_index * 8), 927 perfect_filter_register_address+(mc_index * 8),
906 macaddr_low); 928 macaddr_low);
@@ -908,7 +930,6 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
908 perfect_filter_register_address+4+(mc_index * 8), 930 perfect_filter_register_address+4+(mc_index * 8),
909 (u32)macaddr_high | NES_MAC_ADDR_VALID | 931 (u32)macaddr_high | NES_MAC_ADDR_VALID |
910 ((((u32)(1<<mc_nic_index)) << 16))); 932 ((((u32)(1<<mc_nic_index)) << 16)));
911 multicast_addr = multicast_addr->next;
912 nesadapter->pft_mcast_map[mc_index] = 933 nesadapter->pft_mcast_map[mc_index] =
913 nesvnic->nic_index; 934 nesvnic->nic_index;
914 } else { 935 } else {
@@ -920,21 +941,13 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
920 nesadapter->pft_mcast_map[mc_index] = 255; 941 nesadapter->pft_mcast_map[mc_index] = 255;
921 } 942 }
922 } 943 }
944 kfree(addrs);
923 /* PFT is not large enough */ 945 /* PFT is not large enough */
924 if (multicast_addr && multicast_addr->next) { 946 if (i < mc_count)
925 nic_active = nes_read_indexed(nesdev, 947 set_allmulti(nesdev, nic_active_bit);
926 NES_IDX_NIC_MULTICAST_ALL);
927 nic_active |= nic_active_bit;
928 nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL,
929 nic_active);
930 nic_active = nes_read_indexed(nesdev,
931 NES_IDX_NIC_UNICAST_ALL);
932 nic_active &= ~nic_active_bit;
933 nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL,
934 nic_active);
935 }
936 } 948 }
937 949
950unlock:
938 spin_unlock_irqrestore(&nesadapter->resource_lock, flags); 951 spin_unlock_irqrestore(&nesadapter->resource_lock, flags);
939} 952}
940 953
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index 8763c1ea5eb4..19eba3c877cb 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -767,11 +767,8 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
767 } 767 }
768} 768}
769 769
770static int ipoib_mcast_addr_is_valid(const u8 *addr, unsigned int addrlen, 770static int ipoib_mcast_addr_is_valid(const u8 *addr, const u8 *broadcast)
771 const u8 *broadcast)
772{ 771{
773 if (addrlen != INFINIBAND_ALEN)
774 return 0;
775 /* reserved QPN, prefix, scope */ 772 /* reserved QPN, prefix, scope */
776 if (memcmp(addr, broadcast, 6)) 773 if (memcmp(addr, broadcast, 6))
777 return 0; 774 return 0;
@@ -811,11 +808,10 @@ void ipoib_mcast_restart_task(struct work_struct *work)
811 clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags); 808 clear_bit(IPOIB_MCAST_FLAG_FOUND, &mcast->flags);
812 809
813 /* Mark all of the entries that are found or don't exist */ 810 /* Mark all of the entries that are found or don't exist */
814 for (mclist = dev->mc_list; mclist; mclist = mclist->next) { 811 netdev_for_each_mc_addr(mclist, dev) {
815 union ib_gid mgid; 812 union ib_gid mgid;
816 813
817 if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr, 814 if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr,
818 mclist->dmi_addrlen,
819 dev->broadcast)) 815 dev->broadcast))
820 continue; 816 continue;
821 817