Commit 7e36d3d7 authored by Vadim Makhervaks's avatar Vadim Makhervaks Committed by Roland Dreier

RDMA/nes: Enhanced PFT management scheme

Change management of perfect filter table to allow enhanced
performance applications.
Signed-off-by: default avatarVadim Makhervaks <vmakhervaks@neteffect.com>
Signed-off-by: default avatarSweta Bhatt <sweta.bhatt@einfochips.com>
Signed-off-by: default avatarChien Tung <ctung@neteffect.com>
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent 1bb28499
...@@ -363,6 +363,9 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) { ...@@ -363,6 +363,9 @@ struct nes_adapter *nes_init_adapter(struct nes_device *nesdev, u8 hw_rev) {
} }
nes_init_csr_ne020(nesdev, hw_rev, port_count); nes_init_csr_ne020(nesdev, hw_rev, port_count);
memset(nesadapter->pft_mcast_map, 255,
sizeof nesadapter->pft_mcast_map);
/* populate the new nesadapter */ /* populate the new nesadapter */
nesadapter->devfn = nesdev->pcidev->devfn; nesadapter->devfn = nesdev->pcidev->devfn;
nesadapter->bus_number = nesdev->pcidev->bus->number; nesadapter->bus_number = nesdev->pcidev->bus->number;
......
...@@ -968,6 +968,7 @@ struct nes_arp_entry { ...@@ -968,6 +968,7 @@ struct nes_arp_entry {
#define DEFAULT_JUMBO_NES_QL_TARGET 40 #define DEFAULT_JUMBO_NES_QL_TARGET 40
#define DEFAULT_JUMBO_NES_QL_HIGH 128 #define DEFAULT_JUMBO_NES_QL_HIGH 128
#define NES_NIC_CQ_DOWNWARD_TREND 16 #define NES_NIC_CQ_DOWNWARD_TREND 16
#define NES_PFT_SIZE 48
struct nes_hw_tune_timer { struct nes_hw_tune_timer {
/* u16 cq_count; */ /* u16 cq_count; */
...@@ -1117,6 +1118,7 @@ struct nes_adapter { ...@@ -1117,6 +1118,7 @@ struct nes_adapter {
u8 virtwq; u8 virtwq;
u8 et_use_adaptive_rx_coalesce; u8 et_use_adaptive_rx_coalesce;
u8 adapter_fcn_count; u8 adapter_fcn_count;
u8 pft_mcast_map[NES_PFT_SIZE];
}; };
struct nes_pbl { struct nes_pbl {
......
...@@ -91,6 +91,7 @@ static struct nic_qp_map *nic_qp_mapping_per_function[] = { ...@@ -91,6 +91,7 @@ static struct nic_qp_map *nic_qp_mapping_per_function[] = {
static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK static const u32 default_msg = NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK
| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
static int debug = -1; static int debug = -1;
static int nics_per_function = 1;
/** /**
* nes_netdev_poll * nes_netdev_poll
...@@ -201,7 +202,8 @@ static int nes_netdev_open(struct net_device *netdev) ...@@ -201,7 +202,8 @@ static int nes_netdev_open(struct net_device *netdev)
nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW" nes_debug(NES_DBG_NETDEV, "i=%d, perfect filter table index= %d, PERF FILTER LOW"
" (Addr:%08X) = %08X, HIGH = %08X.\n", " (Addr:%08X) = %08X, HIGH = %08X.\n",
i, nesvnic->qp_nic_index[i], i, nesvnic->qp_nic_index[i],
NES_IDX_PERFECT_FILTER_LOW+((nesvnic->perfect_filter_index + i) * 8), NES_IDX_PERFECT_FILTER_LOW+
(nesvnic->qp_nic_index[i] * 8),
macaddr_low, macaddr_low,
(u32)macaddr_high | NES_MAC_ADDR_VALID | (u32)macaddr_high | NES_MAC_ADDR_VALID |
((((u32)nesvnic->nic_index) << 16))); ((((u32)nesvnic->nic_index) << 16)));
...@@ -833,6 +835,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) ...@@ -833,6 +835,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
{ {
struct nes_vnic *nesvnic = netdev_priv(netdev); struct nes_vnic *nesvnic = netdev_priv(netdev);
struct nes_device *nesdev = nesvnic->nesdev; struct nes_device *nesdev = nesvnic->nesdev;
struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
struct dev_mc_list *multicast_addr; struct dev_mc_list *multicast_addr;
u32 nic_active_bit; u32 nic_active_bit;
u32 nic_active; u32 nic_active;
...@@ -842,7 +845,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) ...@@ -842,7 +845,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
u8 mc_all_on = 0; u8 mc_all_on = 0;
u8 mc_index; u8 mc_index;
int mc_nic_index = -1; int mc_nic_index = -1;
u8 pft_entries_preallocated = max(nesadapter->adapter_fcn_count *
nics_per_function, 4);
u8 max_pft_entries_avaiable = NES_PFT_SIZE - pft_entries_preallocated;
unsigned long flags;
spin_lock_irqsave(&nesadapter->resource_lock, flags);
nic_active_bit = 1 << nesvnic->nic_index; nic_active_bit = 1 << nesvnic->nic_index;
if (netdev->flags & IFF_PROMISC) { if (netdev->flags & IFF_PROMISC) {
...@@ -853,7 +861,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) ...@@ -853,7 +861,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
nic_active |= nic_active_bit; nic_active |= nic_active_bit;
nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active); nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
mc_all_on = 1; mc_all_on = 1;
} else if ((netdev->flags & IFF_ALLMULTI) || (netdev->mc_count > NES_MULTICAST_PF_MAX) || } else if ((netdev->flags & IFF_ALLMULTI) ||
(nesvnic->nic_index > 3)) { (nesvnic->nic_index > 3)) {
nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL); nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
nic_active |= nic_active_bit; nic_active |= nic_active_bit;
...@@ -872,17 +880,34 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev) ...@@ -872,17 +880,34 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
} }
nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n", nes_debug(NES_DBG_NIC_RX, "Number of MC entries = %d, Promiscous = %d, All Multicast = %d.\n",
netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0, netdev->mc_count, !!(netdev->flags & IFF_PROMISC),
(netdev->flags & IFF_ALLMULTI)?1:0); !!(netdev->flags & IFF_ALLMULTI));
if (!mc_all_on) { if (!mc_all_on) {
multicast_addr = netdev->mc_list; multicast_addr = netdev->mc_list;
perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80; perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
perfect_filter_register_address += nesvnic->nic_index*0x40; pft_entries_preallocated * 0x8;
for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) { for (mc_index = 0; mc_index < max_pft_entries_avaiable;
while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0)) mc_index++) {
while (multicast_addr && nesvnic->mcrq_mcast_filter &&
((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic,
multicast_addr->dmi_addr)) == 0)) {
multicast_addr = multicast_addr->next; multicast_addr = multicast_addr->next;
}
if (mc_nic_index < 0) if (mc_nic_index < 0)
mc_nic_index = nesvnic->nic_index; mc_nic_index = nesvnic->nic_index;
while (nesadapter->pft_mcast_map[mc_index] < 16 &&
nesadapter->pft_mcast_map[mc_index] !=
nesvnic->nic_index &&
mc_index < max_pft_entries_avaiable) {
nes_debug(NES_DBG_NIC_RX,
"mc_index=%d skipping nic_index=%d,\
used for=%d \n", mc_index,
nesvnic->nic_index,
nesadapter->pft_mcast_map[mc_index]);
mc_index++;
}
if (mc_index >= max_pft_entries_avaiable)
break;
if (multicast_addr) { if (multicast_addr) {
DECLARE_MAC_BUF(mac); DECLARE_MAC_BUF(mac);
nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n", 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,15 +928,33 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
(u32)macaddr_high | NES_MAC_ADDR_VALID | (u32)macaddr_high | NES_MAC_ADDR_VALID |
((((u32)(1<<mc_nic_index)) << 16))); ((((u32)(1<<mc_nic_index)) << 16)));
multicast_addr = multicast_addr->next; multicast_addr = multicast_addr->next;
nesadapter->pft_mcast_map[mc_index] =
nesvnic->nic_index;
} else { } else {
nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n", nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n",
perfect_filter_register_address+(mc_index * 8)); perfect_filter_register_address+(mc_index * 8));
nes_write_indexed(nesdev, nes_write_indexed(nesdev,
perfect_filter_register_address+4+(mc_index * 8), perfect_filter_register_address+4+(mc_index * 8),
0); 0);
nesadapter->pft_mcast_map[mc_index] = 255;
} }
} }
/* PFT is not large enough */
if (multicast_addr && multicast_addr->next) {
nic_active = nes_read_indexed(nesdev,
NES_IDX_NIC_MULTICAST_ALL);
nic_active |= nic_active_bit;
nes_write_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL,
nic_active);
nic_active = nes_read_indexed(nesdev,
NES_IDX_NIC_UNICAST_ALL);
nic_active &= ~nic_active_bit;
nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL,
nic_active);
}
} }
spin_unlock_irqrestore(&nesadapter->resource_lock, flags);
} }
...@@ -1615,7 +1658,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev, ...@@ -1615,7 +1658,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id, nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id,
nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index); nesvnic->nic_index, nesvnic->logical_port, nesdev->mac_index);
if (nesvnic->nesdev->nesadapter->port_count == 1) { if (nesvnic->nesdev->nesadapter->port_count == 1 &&
nesvnic->nesdev->nesadapter->adapter_fcn_count == 1) {
nesvnic->qp_nic_index[0] = nesvnic->nic_index; nesvnic->qp_nic_index[0] = nesvnic->nic_index;
nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1; nesvnic->qp_nic_index[1] = nesvnic->nic_index + 1;
if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) { 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,11 +1671,14 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3; nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3;
} }
} else { } else {
if (nesvnic->nesdev->nesadapter->port_count == 2) { if (nesvnic->nesdev->nesadapter->port_count == 2 ||
nesvnic->qp_nic_index[0] = nesvnic->nic_index; (nesvnic->nesdev->nesadapter->port_count == 1 &&
nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2; nesvnic->nesdev->nesadapter->adapter_fcn_count == 2)) {
nesvnic->qp_nic_index[2] = 0xf; nesvnic->qp_nic_index[0] = nesvnic->nic_index;
nesvnic->qp_nic_index[3] = 0xf; nesvnic->qp_nic_index[1] = nesvnic->nic_index
+ 2;
nesvnic->qp_nic_index[2] = 0xf;
nesvnic->qp_nic_index[3] = 0xf;
} else { } else {
nesvnic->qp_nic_index[0] = nesvnic->nic_index; nesvnic->qp_nic_index[0] = nesvnic->nic_index;
nesvnic->qp_nic_index[1] = 0xf; nesvnic->qp_nic_index[1] = 0xf;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment