Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -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);

	memset(nesadapter->pft_mcast_map, 255,
	       sizeof nesadapter->pft_mcast_map);

	/* populate the new nesadapter */
	nesadapter->devfn = nesdev->pcidev->devfn;
	nesadapter->bus_number = nesdev->pcidev->bus->number;
+2 −0
Original line number Diff line number Diff line
@@ -968,6 +968,7 @@ struct nes_arp_entry {
#define DEFAULT_JUMBO_NES_QL_TARGET 40
#define DEFAULT_JUMBO_NES_QL_HIGH   128
#define NES_NIC_CQ_DOWNWARD_TREND   16
#define NES_PFT_SIZE		    48

struct nes_hw_tune_timer {
    /* u16 cq_count; */
@@ -1117,6 +1118,7 @@ struct nes_adapter {
	u8            virtwq;
	u8            et_use_adaptive_rx_coalesce;
	u8            adapter_fcn_count;
	u8 pft_mcast_map[NES_PFT_SIZE];
};

struct nes_pbl {
+62 −14
Original line number Diff line number Diff line
@@ -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
		| NETIF_MSG_IFUP | NETIF_MSG_IFDOWN;
static int debug = -1;
static int nics_per_function = 1;

/**
 * nes_netdev_poll
@@ -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"
				" (Addr:%08X) = %08X, HIGH = %08X.\n",
				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,
				(u32)macaddr_high | NES_MAC_ADDR_VALID |
				((((u32)nesvnic->nic_index) << 16)));
@@ -833,6 +835,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
{
	struct nes_vnic *nesvnic = netdev_priv(netdev);
	struct nes_device *nesdev = nesvnic->nesdev;
	struct nes_adapter *nesadapter = nesvnic->nesdev->nesadapter;
	struct dev_mc_list *multicast_addr;
	u32 nic_active_bit;
	u32 nic_active;
@@ -842,7 +845,12 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
	u8 mc_all_on = 0;
	u8 mc_index;
	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;

	if (netdev->flags & IFF_PROMISC) {
@@ -853,7 +861,7 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
		nic_active |= nic_active_bit;
		nes_write_indexed(nesdev, NES_IDX_NIC_UNICAST_ALL, nic_active);
		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)) {
		nic_active = nes_read_indexed(nesdev, NES_IDX_NIC_MULTICAST_ALL);
		nic_active |= nic_active_bit;
@@ -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",
			  netdev->mc_count, (netdev->flags & IFF_PROMISC)?1:0,
			  (netdev->flags & IFF_ALLMULTI)?1:0);
		  netdev->mc_count, !!(netdev->flags & IFF_PROMISC),
		  !!(netdev->flags & IFF_ALLMULTI));
	if (!mc_all_on) {
		multicast_addr = netdev->mc_list;
		perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW + 0x80;
		perfect_filter_register_address += nesvnic->nic_index*0x40;
		for (mc_index=0; mc_index < NES_MULTICAST_PF_MAX; mc_index++) {
			while (multicast_addr && nesvnic->mcrq_mcast_filter && ((mc_nic_index = nesvnic->mcrq_mcast_filter(nesvnic, multicast_addr->dmi_addr)) == 0))
		perfect_filter_register_address = NES_IDX_PERFECT_FILTER_LOW +
						pft_entries_preallocated * 0x8;
		for (mc_index = 0; mc_index < max_pft_entries_avaiable;
		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;
			}
			if (mc_nic_index < 0)
				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) {
				DECLARE_MAC_BUF(mac);
				nes_debug(NES_DBG_NIC_RX, "Assigning MC Address %s to register 0x%04X nic_idx=%d\n",
@@ -903,17 +928,35 @@ static void nes_netdev_set_multicast_list(struct net_device *netdev)
						(u32)macaddr_high | NES_MAC_ADDR_VALID |
						((((u32)(1<<mc_nic_index)) << 16)));
				multicast_addr = multicast_addr->next;
				nesadapter->pft_mcast_map[mc_index] =
							nesvnic->nic_index;
			} else {
				nes_debug(NES_DBG_NIC_RX, "Clearing MC Address at register 0x%04X\n",
						  perfect_filter_register_address+(mc_index * 8));
				nes_write_indexed(nesdev,
						perfect_filter_register_address+4+(mc_index * 8),
						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);
}


/**
 * nes_netdev_change_mtu
@@ -1615,7 +1658,9 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
			nesvnic, (unsigned long)netdev->features, nesvnic->nic.qp_id,
			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[1] = nesvnic->nic_index + 1;
		if (nes_drv_opt & NES_DRV_OPT_DUAL_LOGICAL_PORT) {
@@ -1626,9 +1671,12 @@ struct net_device *nes_netdev_init(struct nes_device *nesdev,
			nesvnic->qp_nic_index[3] = nesvnic->nic_index + 3;
		}
	} else {
		if (nesvnic->nesdev->nesadapter->port_count == 2) {
		if (nesvnic->nesdev->nesadapter->port_count == 2 ||
			(nesvnic->nesdev->nesadapter->port_count == 1 &&
			nesvnic->nesdev->nesadapter->adapter_fcn_count == 2)) {
				nesvnic->qp_nic_index[0] = nesvnic->nic_index;
			nesvnic->qp_nic_index[1] = nesvnic->nic_index + 2;
				nesvnic->qp_nic_index[1] = nesvnic->nic_index
									+ 2;
				nesvnic->qp_nic_index[2] = 0xf;
				nesvnic->qp_nic_index[3] = 0xf;
		} else {