aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorVadim Makhervaks <vmakhervaks@neteffect.com>2008-10-03 15:21:18 -0400
committerRoland Dreier <rolandd@cisco.com>2008-10-03 15:21:18 -0400
commit7e36d3d732438de894802f87a0ca21372e00fb74 (patch)
tree4f86671c059e8e8ef542a268ebb12813a2270a0f /drivers/infiniband
parent1bb28499979d926806139bbdef6969fc37621118 (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')
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.c3
-rw-r--r--drivers/infiniband/hw/nes/nes_hw.h2
-rw-r--r--drivers/infiniband/hw/nes/nes_nic.c76
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
972struct nes_hw_tune_timer { 973struct 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
1122struct nes_pbl { 1124struct 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[] = {
91static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK 91static 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;
93static int debug = -1; 93static int debug = -1;
94static 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;