diff options
author | Vadim Makhervaks <vmakhervaks@neteffect.com> | 2008-10-03 15:21:18 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2008-10-03 15:21:18 -0400 |
commit | 7e36d3d732438de894802f87a0ca21372e00fb74 (patch) | |
tree | 4f86671c059e8e8ef542a268ebb12813a2270a0f /drivers/infiniband/hw/nes | |
parent | 1bb28499979d926806139bbdef6969fc37621118 (diff) |
RDMA/nes: Enhanced PFT management scheme
Change management of perfect filter table to allow enhanced
performance applications.
Signed-off-by: Vadim Makhervaks <vmakhervaks@neteffect.com>
Signed-off-by: Sweta Bhatt <sweta.bhatt@einfochips.com>
Signed-off-by: Chien Tung <ctung@neteffect.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/nes')
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.c | 3 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_hw.h | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/nes/nes_nic.c | 76 |
3 files changed, 67 insertions, 14 deletions
diff --git a/drivers/infiniband/hw/nes/nes_hw.c b/drivers/infiniband/hw/nes/nes_hw.c index 5e13c26de07d..eca3520565fe 100644 --- a/drivers/infiniband/hw/nes/nes_hw.c +++ b/drivers/infiniband/hw/nes/nes_hw.c | |||
@@ -363,6 +363,9 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { | |||
363 | } | 363 | } |
364 | nes_init_csr_ne020(nesdev, hw_rev, port_count); | 364 | nes_init_csr_ne020(nesdev, hw_rev, port_count); |
365 | 365 | ||
366 | memset(nesadapter->pft_mcast_map, 255, | ||
367 | sizeof nesadapter->pft_mcast_map); | ||
368 | |||
366 | /* populate the new nesadapter */ | 369 | /* populate the new nesadapter */ |
367 | nesadapter->devfn = nesdev->pcidev->devfn; | 370 | nesadapter->devfn = nesdev->pcidev->devfn; |
368 | nesadapter->bus_number = nesdev->pcidev->bus->number; | 371 | nesadapter->bus_number = nesdev->pcidev->bus->number; |
diff --git a/drivers/infiniband/hw/nes/nes_hw.h b/drivers/infiniband/hw/nes/nes_hw.h index 1b93c571b931..610b9d859597 100644 --- a/drivers/infiniband/hw/nes/nes_hw.h +++ b/drivers/infiniband/hw/nes/nes_hw.h | |||
@@ -968,6 +968,7 @@ struct nes_arp_entry { | |||
968 | #define DEFAULT_JUMBO_NES_QL_TARGET 40 | 968 | #define DEFAULT_JUMBO_NES_QL_TARGET 40 |
969 | #define DEFAULT_JUMBO_NES_QL_HIGH 128 | 969 | #define DEFAULT_JUMBO_NES_QL_HIGH 128 |
970 | #define NES_NIC_CQ_DOWNWARD_TREND 16 | 970 | #define NES_NIC_CQ_DOWNWARD_TREND 16 |
971 | #define NES_PFT_SIZE 48 | ||
971 | 972 | ||
972 | struct nes_hw_tune_timer { | 973 | struct nes_hw_tune_timer { |
973 | /* u16 cq_count; */ | 974 | /* u16 cq_count; */ |
@@ -1117,6 +1118,7 @@ struct nes_adapter { | |||
1117 | u8 virtwq; | 1118 | u8 virtwq; |
1118 | u8 et_use_adaptive_rx_coalesce; | 1119 | u8 et_use_adaptive_rx_coalesce; |
1119 | u8 adapter_fcn_count; | 1120 | u8 adapter_fcn_count; |
1121 | u8 pft_mcast_map[NES_PFT_SIZE]; | ||
1120 | }; | 1122 | }; |
1121 | 1123 | ||
1122 | struct nes_pbl { | 1124 | struct nes_pbl { |
diff --git a/drivers/infiniband/hw/nes/nes_nic.c b/drivers/infiniband/hw/nes/nes_nic.c index 639d0fcc00b4..730358637bb6 100644 --- a/drivers/infiniband/hw/nes/nes_nic.c +++ b/drivers/infiniband/hw/nes/nes_nic.c | |||
@@ -91,6 +91,7 @@ static struct nic_qp_map *nic_qp_mapping_per_function[] = { | |||
91 | static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | 91 | static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK |
92 | | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; | 92 | | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; |
93 | static int debug = -1; | 93 | static int debug = -1; |
94 | static int nics_per_function = 1; | ||
94 | 95 | ||
95 | /** | 96 | /** |
96 | * nes_netdev_poll | 97 | * nes_netdev_poll |
@@ -201,7 +202,8 @@ static int nes_netdev_open(struct net_device *netdev) | |||
201 | nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW" | 202 | nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW" |
202 | " (Addr:%08X) = %08X, HIGH = %08X.\n", | 203 | " (Addr:%08X) = %08X, HIGH = %08X.\n", |
203 | i, nesvnic->qp_nic_index[i], | 204 | i, nesvnic->qp_nic_index[i], |
204 | NES_IDX_PERFECT_FILTER_LOW+((nesvnic->perfect_filter_index + i) * 8), | 205 | NES_IDX_PERFECT_FILTER_LOW+ |
206 | (nesvnic->qp_nic_index[i] * 8), | ||
205 | macaddr_low, | 207 | macaddr_low, |
206 | (u32)macaddr_high | NES_MAC_ADDR_VALID | | 208 | (u32)macaddr_high | NES_MAC_ADDR_VALID | |
207 | ((((u32)nesvnic->nic_index) << 16))); | 209 | ((((u32)nesvnic->nic_index) << 16))); |
@@ -833,6 +835,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
833 | { | 835 | { |
834 | struct nes_vnic *nesvnic = netdev_priv(netdev); | 836 | struct nes_vnic *nesvnic = netdev_priv(netdev); |
835 | struct nes_device *nesdev = nesvnic->nesdev; | 837 | struct nes_device *nesdev = nesvnic->nesdev; |
838 | struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter; | ||
836 | struct dev_mc_list *multicast_addr; | 839 | struct dev_mc_list *multicast_addr; |
837 | u32 nic_active_bit; | 840 | u32 nic_active_bit; |
838 | u32 nic_active; | 841 | u32 nic_active; |
@@ -842,7 +845,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
842 | u8 mc_all_on = 0; | 845 | u8 mc_all_on = 0; |
843 | u8 mc_index; | 846 | u8 mc_index; |
844 | int mc_nic_index = -1; | 847 | int mc_nic_index = -1; |
848 | u8 pft_entries_preallocated = max(nesadapter->adapter_fcn_count * | ||
849 | nics_per_function, 4); | ||
850 | u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated; | ||
851 | unsigned long flags; | ||
845 | 852 | ||
853 | spin_lock_irqsave(&nesadapter->resource_lock, flags); | ||
846 | nic_active_bit = 1 << nesvnic->nic_index; | 854 | nic_active_bit = 1 << nesvnic->nic_index; |
847 | 855 | ||
848 | if (netdev->flags & IFF_PROMISC) { | 856 | if (netdev->flags & IFF_PROMISC) { |
@@ -853,7 +861,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
853 | nic_active |= nic_active_bit; | 861 | nic_active |= nic_active_bit; |
854 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); | 862 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); |
855 | mc_all_on = 1; | 863 | mc_all_on = 1; |
856 | } else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > NES_MULTICAST_PF_MAX) || | 864 | } else if ((netdev->flags & IFF_ALLMULTI) || |
857 | (nesvnic->nic_index > 3)) { | 865 | (nesvnic->nic_index > 3)) { |
858 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); | 866 | nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); |
859 | nic_active |= nic_active_bit; | 867 | nic_active |= nic_active_bit; |
@@ -872,17 +880,34 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
872 | } | 880 | } |
873 | 881 | ||
874 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", | 882 | nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", |
875 | netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0, | 883 | netdev->mc_count, !!(netdev->flags & IFF_PROMISC), |
876 | (netdev->flags & IFF_ALLMULTI)?1:0); | 884 | !!(netdev->flags & IFF_ALLMULTI)); |
877 | if (!mc_all_on) { | 885 | if (!mc_all_on) { |
878 | multicast_addr = netdev->mc_list; | 886 | multicast_addr = netdev->mc_list; |
879 | perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80; | 887 | perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + |
880 | perfect_filter_register_address += nesvnic->nic_index*0x40; | 888 | pft_entries_preallocated * 0x8; |
881 | for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) { | 889 | for (mc_index = 0; mc_index < max_pft_entries_avaiable; |
882 | while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0)) | 890 | mc_index++) { |
891 | while (multicast_addr && nesvnic->mcrq_mcast_filter && | ||
892 | ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, | ||
893 | multicast_addr->dmi_addr)) == 0)) { | ||
883 | multicast_addr = multicast_addr->next; | 894 | multicast_addr = multicast_addr->next; |
895 | } | ||
884 | if (mc_nic_index < 0) | 896 | if (mc_nic_index < 0) |
885 | mc_nic_index = nesvnic->nic_index; | 897 | mc_nic_index = nesvnic->nic_index; |
898 | while (nesadapter->pft_mcast_map[mc_index] < 16 && | ||
899 | nesadapter->pft_mcast_map[mc_index] != | ||
900 | nesvnic->nic_index && | ||
901 | mc_index < max_pft_entries_avaiable) { | ||
902 | nes_debug(NES_DBG_NIC_RX, | ||
903 | "mc_index=%d skipping nic_index=%d,\ | ||
904 | used for=%d \n", mc_index, | ||
905 | nesvnic->nic_index, | ||
906 | nesadapter->pft_mcast_map[mc_index]); | ||
907 | mc_index++; | ||
908 | } | ||
909 | if (mc_index >= max_pft_entries_avaiable) | ||
910 | break; | ||
886 | if (multicast_addr) { | 911 | if (multicast_addr) { |
887 | DECLARE_MAC_BUF(mac); | 912 | DECLARE_MAC_BUF(mac); |
888 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n", | 913 | nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n", |
@@ -903,15 +928,33 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) | |||
903 | (u32)macaddr_high | NES_MAC_ADDR_VALID | | 928 | (u32)macaddr_high | NES_MAC_ADDR_VALID | |
904 | ((((u32)(1<<mc_nic_index)) << 16))); | 929 | ((((u32)(1<<mc_nic_index)) << 16))); |
905 | multicast_addr = multicast_addr->next; | 930 | multicast_addr = multicast_addr->next; |
931 | nesadapter->pft_mcast_map[mc_index] = | ||
932 | nesvnic->nic_index; | ||
906 | } else { | 933 | } else { |
907 | nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n", | 934 | nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n", |
908 | perfect_filter_register_address+(mc_index * 8)); | 935 | perfect_filter_register_address+(mc_index * 8)); |
909 | nes_write_indexed(nesdev, | 936 | nes_write_indexed(nesdev, |
910 | perfect_filter_register_address+4+(mc_index * 8), | 937 | perfect_filter_register_address+4+(mc_index * 8), |
911 | 0); | 938 | 0); |
939 | nesadapter->pft_mcast_map[mc_index] = 255; | ||
912 | } | 940 | } |
913 | } | 941 | } |
942 | /* PFT is not large enough */ | ||
943 | if (multicast_addr && multicast_addr->next) { | ||
944 | nic_active = nes_read_indexed(nesdev, | ||
945 | NES_IDX_NIC_MULTICAST_ALL); | ||
946 | nic_active |= nic_active_bit; | ||
947 | nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL, | ||
948 | nic_active); | ||
949 | nic_active = nes_read_indexed(nesdev, | ||
950 | NES_IDX_NIC_UNICAST_ALL); | ||
951 | nic_active &= ~nic_active_bit; | ||
952 | nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, | ||
953 | nic_active); | ||
954 | } | ||
914 | } | 955 | } |
956 | |||
957 | spin_unlock_irqrestore(&nesadapter->resource_lock, flags); | ||
915 | } | 958 | } |
916 | 959 | ||
917 | 960 | ||
@@ -1615,7 +1658,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1615 | nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id, | 1658 | nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id, |
1616 | nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index); | 1659 | nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index); |
1617 | 1660 | ||
1618 | if (nesvnic->nesdev->nesadapter->port_count == 1) { | 1661 | if (nesvnic->nesdev->nesadapter->port_count == 1 && |
1662 | nesvnic->nesdev->nesadapter->adapter_fcn_count == 1) { | ||
1663 | |||
1619 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; | 1664 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; |
1620 | nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1; | 1665 | nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1; |
1621 | if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) { | 1666 | if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) { |
@@ -1626,11 +1671,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, | |||
1626 | nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3; | 1671 | nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3; |
1627 | } | 1672 | } |
1628 | } else { | 1673 | } else { |
1629 | if (nesvnic->nesdev->nesadapter->port_count == 2) { | 1674 | if (nesvnic->nesdev->nesadapter->port_count == 2 || |
1630 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; | 1675 | (nesvnic->nesdev->nesadapter->port_count == 1 && |
1631 | nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2; | 1676 | nesvnic->nesdev->nesadapter->adapter_fcn_count == 2)) { |
1632 | nesvnic->qp_nic_index[2] = 0xf; | 1677 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; |
1633 | nesvnic->qp_nic_index[3] = 0xf; | 1678 | nesvnic->qp_nic_index[1] = nesvnic->nic_index |
1679 | + 2; | ||
1680 | nesvnic->qp_nic_index[2] = 0xf; | ||
1681 | nesvnic->qp_nic_index[3] = 0xf; | ||
1634 | } else { | 1682 | } else { |
1635 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; | 1683 | nesvnic->qp_nic_index[0] = nesvnic->nic_index; |
1636 | nesvnic->qp_nic_index[1] = 0xf; | 1684 | nesvnic->qp_nic_index[1] = 0xf; |