All of lore.kernel.org
 help / color / mirror / Atom feed
* [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address
@ 2020-02-28 14:00 chandu
  0 siblings, 0 replies; 3+ messages in thread
From: chandu @ 2020-02-28 14:00 UTC (permalink / raw)
  To: dev; +Cc: Ravi1.Kumar, Amaranath.Somalapuram

From: Chandu Babu N <chandu@amd.com>

implement eth_dev_ops uc_hash_table_set and uc_all_hash_table_set

Signed-off-by: Chandu Babu N <chandu@amd.com>
---
 drivers/net/axgbe/axgbe_common.h |  2 +
 drivers/net/axgbe/axgbe_dev.c    | 60 ++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.c | 79 ++++++++++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.h | 10 +++-
 4 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index 2ac4d8946..72683aa65 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -292,6 +292,8 @@
 #define MAC_MACAHR(i)	(MAC_MACA0HR + ((i) * 8))
 #define MAC_MACALR(i)	(MAC_MACA0LR + ((i) * 8))
 
+#define MAC_HTR(i)	(MAC_HTR0 + ((i) * MAC_HTR_INC))
+
 /* MAC register entry bit positions and sizes */
 #define MAC_HWF0R_ADDMACADRSEL_INDEX	18
 #define MAC_HWF0R_ADDMACADRSEL_WIDTH	5
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index f830b7230..5f0f19592 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -1008,6 +1008,50 @@ static void axgbe_enable_mtl_interrupts(struct axgbe_port *pdata)
 	}
 }
 
+static uint32_t bitrev32(uint32_t x)
+{
+	x = (x >> 16) | (x << 16);
+	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+	return x;
+}
+
+static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+	return crc;
+}
+
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add)
+{
+	uint32_t crc, htable_index, htable_bitmask;
+
+	crc = bitrev32(~crc32_le(~0, addr, RTE_ETHER_ADDR_LEN));
+	crc >>= pdata->hash_table_shift;
+	htable_index = crc >> 5;
+	htable_bitmask = 1 << (crc & 0x1f);
+
+	if (add) {
+		pdata->uc_hash_table[htable_index] |= htable_bitmask;
+		pdata->uc_hash_mac_addr++;
+	} else {
+		pdata->uc_hash_table[htable_index] &= ~htable_bitmask;
+		pdata->uc_hash_mac_addr--;
+	}
+	PMD_DRV_LOG(DEBUG, "%s MAC hash table Bit %d at Index %#x\n",
+		    add ? "set" : "clear", (crc & 0x1f), htable_index);
+
+	AXGMAC_IOWRITE(pdata, MAC_HTR(htable_index),
+		       pdata->uc_hash_table[htable_index]);
+}
+
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr, uint32_t index)
 {
 	unsigned int mac_addr_hi, mac_addr_lo;
@@ -1051,6 +1095,21 @@ static int axgbe_set_mac_address(struct axgbe_port *pdata, u8 *addr)
 	return 0;
 }
 
+static void axgbe_config_mac_hash_table(struct axgbe_port *pdata)
+{
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	pdata->hash_table_shift = 0;
+	pdata->hash_table_count = 0;
+	pdata->uc_hash_mac_addr = 0;
+	memset(pdata->uc_hash_table, 0, sizeof(pdata->uc_hash_table));
+
+	if (hw_feat->hash_table_size) {
+		pdata->hash_table_shift = 26 - (hw_feat->hash_table_size >> 7);
+		pdata->hash_table_count = hw_feat->hash_table_size / 32;
+	}
+}
+
 static void axgbe_config_mac_address(struct axgbe_port *pdata)
 {
 	axgbe_set_mac_address(pdata, pdata->mac_addr.addr_bytes);
@@ -1129,6 +1188,7 @@ static int axgbe_init(struct axgbe_port *pdata)
 	axgbe_enable_mtl_interrupts(pdata);
 
 	/* Initialize MAC related features */
+	axgbe_config_mac_hash_table(pdata);
 	axgbe_config_mac_address(pdata);
 	axgbe_config_jumbo_enable(pdata);
 	axgbe_config_flow_control(pdata);
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 34cc0fbb8..a1d048a9d 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -30,6 +30,11 @@ static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 static int axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 				      struct rte_ether_addr *mc_addr_set,
 				      uint32_t nb_mc_addr);
+static int axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+				       struct rte_ether_addr *mac_addr,
+				       uint8_t add);
+static int axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev,
+					   uint8_t add);
 static int axgbe_dev_link_update(struct rte_eth_dev *dev,
 				 int wait_to_complete);
 static int axgbe_dev_get_regs(struct rte_eth_dev *dev,
@@ -174,6 +179,8 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = {
 	.mac_addr_add         = axgbe_dev_mac_addr_add,
 	.mac_addr_remove      = axgbe_dev_mac_addr_remove,
 	.set_mc_addr_list     = axgbe_dev_set_mc_addr_list,
+	.uc_hash_table_set    = axgbe_dev_uc_hash_table_set,
+	.uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
 	.link_update          = axgbe_dev_link_update,
 	.get_reg	      = axgbe_dev_get_regs,
 	.stats_get            = axgbe_dev_stats_get,
@@ -452,6 +459,65 @@ axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mac_addr, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
+
+	if (pdata->uc_hash_mac_addr > 0) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
+static int
+axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+	uint32_t index;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	for (index = 0; index < pdata->hash_table_count; index++) {
+		if (add)
+			pdata->uc_hash_table[index] = ~0;
+		else
+			pdata->uc_hash_table[index] = 0;
+
+		PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n",
+			    add ? "set" : "clear", index);
+
+		AXGMAC_IOWRITE(pdata, MAC_HTR(index),
+			       pdata->uc_hash_table[index]);
+	}
+
+	if (add) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 axgbe_dev_link_update(struct rte_eth_dev *dev,
@@ -892,6 +958,7 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
 	dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
 	dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
+	dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
 
 	dev_info->rx_offload_capa =
@@ -1206,6 +1273,18 @@ eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
 		return -ENOMEM;
 	}
 
+	/* Allocate memory for storing hash filter MAC addresses */
+	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
+	eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
+						    len, 0);
+
+	if (eth_dev->data->hash_mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR,
+			     "Failed to allocate %d bytes needed to "
+			     "store MAC addresses", len);
+		return -ENOMEM;
+	}
+
 	if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
 		rte_eth_random_addr(pdata->mac_addr.addr_bytes);
 
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 781d170e5..3969317fd 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -17,6 +17,7 @@
 #define AXGBE_RX_MAX_BUF_SIZE		(0x3fff & ~(64 - 1))
 #define AXGBE_RX_MIN_BUF_SIZE		(RTE_ETHER_MAX_LEN + VLAN_HLEN)
 #define AXGBE_MAX_MAC_ADDRS		32
+#define AXGBE_MAX_HASH_MAC_ADDRS	256
 
 #define AXGBE_RX_BUF_ALIGN		64
 
@@ -83,7 +84,7 @@
 	(((_x) < 1024) ? 0 : ((_x) / AXGMAC_FLOW_CONTROL_UNIT) - 2)
 #define AXGMAC_FLOW_CONTROL_MAX		33280
 
-/* Maximum MAC address hash table size (256 bits = 8 bytes) */
+/* Maximum MAC address hash table size (256 bits = 8 dword) */
 #define AXGBE_MAC_HASH_TABLE_SIZE	8
 
 /* Receive Side Scaling */
@@ -625,6 +626,12 @@ struct axgbe_port {
 	uint32_t rx_csum_enable;
 
 	struct axgbe_mmc_stats mmc_stats;
+
+	/* Hash filtering */
+	unsigned int hash_table_shift;
+	unsigned int hash_table_count;
+	unsigned int uc_hash_mac_addr;
+	unsigned int uc_hash_table[AXGBE_MAC_HASH_TABLE_SIZE];
 };
 
 void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if);
@@ -633,5 +640,6 @@ void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if);
 void axgbe_init_function_ptrs_i2c(struct axgbe_i2c_if *i2c_if);
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr,
 			     uint32_t index);
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add);
 
 #endif /* RTE_ETH_AXGBE_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address
  2020-02-28 14:20 [dpdk-dev] [PATCH v1 1/2] net/axgbe: add additional MAC address support chandu
@ 2020-02-28 14:20 ` chandu
  0 siblings, 0 replies; 3+ messages in thread
From: chandu @ 2020-02-28 14:20 UTC (permalink / raw)
  To: dev; +Cc: Ravi1.Kumar, Amaranath.Somalapuram

From: Chandu Babu N <chandu@amd.com>

implement eth_dev_ops uc_hash_table_set and uc_all_hash_table_set

Signed-off-by: Chandu Babu N <chandu@amd.com>
---
 drivers/net/axgbe/axgbe_common.h |  2 +
 drivers/net/axgbe/axgbe_dev.c    | 60 ++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.c | 79 ++++++++++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.h | 10 +++-
 4 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index 2ac4d8946..72683aa65 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -292,6 +292,8 @@
 #define MAC_MACAHR(i)	(MAC_MACA0HR + ((i) * 8))
 #define MAC_MACALR(i)	(MAC_MACA0LR + ((i) * 8))
 
+#define MAC_HTR(i)	(MAC_HTR0 + ((i) * MAC_HTR_INC))
+
 /* MAC register entry bit positions and sizes */
 #define MAC_HWF0R_ADDMACADRSEL_INDEX	18
 #define MAC_HWF0R_ADDMACADRSEL_WIDTH	5
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index f830b7230..5f0f19592 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -1008,6 +1008,50 @@ static void axgbe_enable_mtl_interrupts(struct axgbe_port *pdata)
 	}
 }
 
+static uint32_t bitrev32(uint32_t x)
+{
+	x = (x >> 16) | (x << 16);
+	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+	return x;
+}
+
+static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+	return crc;
+}
+
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add)
+{
+	uint32_t crc, htable_index, htable_bitmask;
+
+	crc = bitrev32(~crc32_le(~0, addr, RTE_ETHER_ADDR_LEN));
+	crc >>= pdata->hash_table_shift;
+	htable_index = crc >> 5;
+	htable_bitmask = 1 << (crc & 0x1f);
+
+	if (add) {
+		pdata->uc_hash_table[htable_index] |= htable_bitmask;
+		pdata->uc_hash_mac_addr++;
+	} else {
+		pdata->uc_hash_table[htable_index] &= ~htable_bitmask;
+		pdata->uc_hash_mac_addr--;
+	}
+	PMD_DRV_LOG(DEBUG, "%s MAC hash table Bit %d at Index %#x\n",
+		    add ? "set" : "clear", (crc & 0x1f), htable_index);
+
+	AXGMAC_IOWRITE(pdata, MAC_HTR(htable_index),
+		       pdata->uc_hash_table[htable_index]);
+}
+
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr, uint32_t index)
 {
 	unsigned int mac_addr_hi, mac_addr_lo;
@@ -1051,6 +1095,21 @@ static int axgbe_set_mac_address(struct axgbe_port *pdata, u8 *addr)
 	return 0;
 }
 
+static void axgbe_config_mac_hash_table(struct axgbe_port *pdata)
+{
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	pdata->hash_table_shift = 0;
+	pdata->hash_table_count = 0;
+	pdata->uc_hash_mac_addr = 0;
+	memset(pdata->uc_hash_table, 0, sizeof(pdata->uc_hash_table));
+
+	if (hw_feat->hash_table_size) {
+		pdata->hash_table_shift = 26 - (hw_feat->hash_table_size >> 7);
+		pdata->hash_table_count = hw_feat->hash_table_size / 32;
+	}
+}
+
 static void axgbe_config_mac_address(struct axgbe_port *pdata)
 {
 	axgbe_set_mac_address(pdata, pdata->mac_addr.addr_bytes);
@@ -1129,6 +1188,7 @@ static int axgbe_init(struct axgbe_port *pdata)
 	axgbe_enable_mtl_interrupts(pdata);
 
 	/* Initialize MAC related features */
+	axgbe_config_mac_hash_table(pdata);
 	axgbe_config_mac_address(pdata);
 	axgbe_config_jumbo_enable(pdata);
 	axgbe_config_flow_control(pdata);
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 34cc0fbb8..a1d048a9d 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -30,6 +30,11 @@ static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 static int axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 				      struct rte_ether_addr *mc_addr_set,
 				      uint32_t nb_mc_addr);
+static int axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+				       struct rte_ether_addr *mac_addr,
+				       uint8_t add);
+static int axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev,
+					   uint8_t add);
 static int axgbe_dev_link_update(struct rte_eth_dev *dev,
 				 int wait_to_complete);
 static int axgbe_dev_get_regs(struct rte_eth_dev *dev,
@@ -174,6 +179,8 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = {
 	.mac_addr_add         = axgbe_dev_mac_addr_add,
 	.mac_addr_remove      = axgbe_dev_mac_addr_remove,
 	.set_mc_addr_list     = axgbe_dev_set_mc_addr_list,
+	.uc_hash_table_set    = axgbe_dev_uc_hash_table_set,
+	.uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
 	.link_update          = axgbe_dev_link_update,
 	.get_reg	      = axgbe_dev_get_regs,
 	.stats_get            = axgbe_dev_stats_get,
@@ -452,6 +459,65 @@ axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mac_addr, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
+
+	if (pdata->uc_hash_mac_addr > 0) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
+static int
+axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+	uint32_t index;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	for (index = 0; index < pdata->hash_table_count; index++) {
+		if (add)
+			pdata->uc_hash_table[index] = ~0;
+		else
+			pdata->uc_hash_table[index] = 0;
+
+		PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n",
+			    add ? "set" : "clear", index);
+
+		AXGMAC_IOWRITE(pdata, MAC_HTR(index),
+			       pdata->uc_hash_table[index]);
+	}
+
+	if (add) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 axgbe_dev_link_update(struct rte_eth_dev *dev,
@@ -892,6 +958,7 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
 	dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
 	dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
+	dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
 
 	dev_info->rx_offload_capa =
@@ -1206,6 +1273,18 @@ eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
 		return -ENOMEM;
 	}
 
+	/* Allocate memory for storing hash filter MAC addresses */
+	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
+	eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
+						    len, 0);
+
+	if (eth_dev->data->hash_mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR,
+			     "Failed to allocate %d bytes needed to "
+			     "store MAC addresses", len);
+		return -ENOMEM;
+	}
+
 	if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
 		rte_eth_random_addr(pdata->mac_addr.addr_bytes);
 
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 781d170e5..3969317fd 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -17,6 +17,7 @@
 #define AXGBE_RX_MAX_BUF_SIZE		(0x3fff & ~(64 - 1))
 #define AXGBE_RX_MIN_BUF_SIZE		(RTE_ETHER_MAX_LEN + VLAN_HLEN)
 #define AXGBE_MAX_MAC_ADDRS		32
+#define AXGBE_MAX_HASH_MAC_ADDRS	256
 
 #define AXGBE_RX_BUF_ALIGN		64
 
@@ -83,7 +84,7 @@
 	(((_x) < 1024) ? 0 : ((_x) / AXGMAC_FLOW_CONTROL_UNIT) - 2)
 #define AXGMAC_FLOW_CONTROL_MAX		33280
 
-/* Maximum MAC address hash table size (256 bits = 8 bytes) */
+/* Maximum MAC address hash table size (256 bits = 8 dword) */
 #define AXGBE_MAC_HASH_TABLE_SIZE	8
 
 /* Receive Side Scaling */
@@ -625,6 +626,12 @@ struct axgbe_port {
 	uint32_t rx_csum_enable;
 
 	struct axgbe_mmc_stats mmc_stats;
+
+	/* Hash filtering */
+	unsigned int hash_table_shift;
+	unsigned int hash_table_count;
+	unsigned int uc_hash_mac_addr;
+	unsigned int uc_hash_table[AXGBE_MAC_HASH_TABLE_SIZE];
 };
 
 void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if);
@@ -633,5 +640,6 @@ void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if);
 void axgbe_init_function_ptrs_i2c(struct axgbe_i2c_if *i2c_if);
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr,
 			     uint32_t index);
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add);
 
 #endif /* RTE_ETH_AXGBE_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address
  2020-02-28 14:06 [dpdk-dev] [PATCH v1 1/2] net/axgbe: add additional MAC address support chandu
@ 2020-02-28 14:06 ` chandu
  0 siblings, 0 replies; 3+ messages in thread
From: chandu @ 2020-02-28 14:06 UTC (permalink / raw)
  To: dev; +Cc: Ravi1.Kumar, Amaranath.Somalapuram

From: Chandu Babu N <chandu@amd.com>

implement eth_dev_ops uc_hash_table_set and uc_all_hash_table_set

Signed-off-by: Chandu Babu N <chandu@amd.com>
---
 drivers/net/axgbe/axgbe_common.h |  2 +
 drivers/net/axgbe/axgbe_dev.c    | 60 ++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.c | 79 ++++++++++++++++++++++++++++++++
 drivers/net/axgbe/axgbe_ethdev.h | 10 +++-
 4 files changed, 150 insertions(+), 1 deletion(-)

diff --git a/drivers/net/axgbe/axgbe_common.h b/drivers/net/axgbe/axgbe_common.h
index 2ac4d8946..72683aa65 100644
--- a/drivers/net/axgbe/axgbe_common.h
+++ b/drivers/net/axgbe/axgbe_common.h
@@ -292,6 +292,8 @@
 #define MAC_MACAHR(i)	(MAC_MACA0HR + ((i) * 8))
 #define MAC_MACALR(i)	(MAC_MACA0LR + ((i) * 8))
 
+#define MAC_HTR(i)	(MAC_HTR0 + ((i) * MAC_HTR_INC))
+
 /* MAC register entry bit positions and sizes */
 #define MAC_HWF0R_ADDMACADRSEL_INDEX	18
 #define MAC_HWF0R_ADDMACADRSEL_WIDTH	5
diff --git a/drivers/net/axgbe/axgbe_dev.c b/drivers/net/axgbe/axgbe_dev.c
index f830b7230..5f0f19592 100644
--- a/drivers/net/axgbe/axgbe_dev.c
+++ b/drivers/net/axgbe/axgbe_dev.c
@@ -1008,6 +1008,50 @@ static void axgbe_enable_mtl_interrupts(struct axgbe_port *pdata)
 	}
 }
 
+static uint32_t bitrev32(uint32_t x)
+{
+	x = (x >> 16) | (x << 16);
+	x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+	x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+	x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+	x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+	return x;
+}
+
+static uint32_t crc32_le(uint32_t crc, uint8_t *p, uint32_t len)
+{
+	int i;
+	while (len--) {
+		crc ^= *p++;
+		for (i = 0; i < 8; i++)
+			crc = (crc >> 1) ^ ((crc & 1) ? 0xedb88320 : 0);
+	}
+	return crc;
+}
+
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add)
+{
+	uint32_t crc, htable_index, htable_bitmask;
+
+	crc = bitrev32(~crc32_le(~0, addr, RTE_ETHER_ADDR_LEN));
+	crc >>= pdata->hash_table_shift;
+	htable_index = crc >> 5;
+	htable_bitmask = 1 << (crc & 0x1f);
+
+	if (add) {
+		pdata->uc_hash_table[htable_index] |= htable_bitmask;
+		pdata->uc_hash_mac_addr++;
+	} else {
+		pdata->uc_hash_table[htable_index] &= ~htable_bitmask;
+		pdata->uc_hash_mac_addr--;
+	}
+	PMD_DRV_LOG(DEBUG, "%s MAC hash table Bit %d at Index %#x\n",
+		    add ? "set" : "clear", (crc & 0x1f), htable_index);
+
+	AXGMAC_IOWRITE(pdata, MAC_HTR(htable_index),
+		       pdata->uc_hash_table[htable_index]);
+}
+
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr, uint32_t index)
 {
 	unsigned int mac_addr_hi, mac_addr_lo;
@@ -1051,6 +1095,21 @@ static int axgbe_set_mac_address(struct axgbe_port *pdata, u8 *addr)
 	return 0;
 }
 
+static void axgbe_config_mac_hash_table(struct axgbe_port *pdata)
+{
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	pdata->hash_table_shift = 0;
+	pdata->hash_table_count = 0;
+	pdata->uc_hash_mac_addr = 0;
+	memset(pdata->uc_hash_table, 0, sizeof(pdata->uc_hash_table));
+
+	if (hw_feat->hash_table_size) {
+		pdata->hash_table_shift = 26 - (hw_feat->hash_table_size >> 7);
+		pdata->hash_table_count = hw_feat->hash_table_size / 32;
+	}
+}
+
 static void axgbe_config_mac_address(struct axgbe_port *pdata)
 {
 	axgbe_set_mac_address(pdata, pdata->mac_addr.addr_bytes);
@@ -1129,6 +1188,7 @@ static int axgbe_init(struct axgbe_port *pdata)
 	axgbe_enable_mtl_interrupts(pdata);
 
 	/* Initialize MAC related features */
+	axgbe_config_mac_hash_table(pdata);
 	axgbe_config_mac_address(pdata);
 	axgbe_config_jumbo_enable(pdata);
 	axgbe_config_flow_control(pdata);
diff --git a/drivers/net/axgbe/axgbe_ethdev.c b/drivers/net/axgbe/axgbe_ethdev.c
index 34cc0fbb8..a1d048a9d 100644
--- a/drivers/net/axgbe/axgbe_ethdev.c
+++ b/drivers/net/axgbe/axgbe_ethdev.c
@@ -30,6 +30,11 @@ static void axgbe_dev_mac_addr_remove(struct rte_eth_dev *dev, uint32_t index);
 static int axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 				      struct rte_ether_addr *mc_addr_set,
 				      uint32_t nb_mc_addr);
+static int axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+				       struct rte_ether_addr *mac_addr,
+				       uint8_t add);
+static int axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev,
+					   uint8_t add);
 static int axgbe_dev_link_update(struct rte_eth_dev *dev,
 				 int wait_to_complete);
 static int axgbe_dev_get_regs(struct rte_eth_dev *dev,
@@ -174,6 +179,8 @@ static const struct eth_dev_ops axgbe_eth_dev_ops = {
 	.mac_addr_add         = axgbe_dev_mac_addr_add,
 	.mac_addr_remove      = axgbe_dev_mac_addr_remove,
 	.set_mc_addr_list     = axgbe_dev_set_mc_addr_list,
+	.uc_hash_table_set    = axgbe_dev_uc_hash_table_set,
+	.uc_all_hash_table_set = axgbe_dev_uc_all_hash_table_set,
 	.link_update          = axgbe_dev_link_update,
 	.get_reg	      = axgbe_dev_get_regs,
 	.stats_get            = axgbe_dev_stats_get,
@@ -452,6 +459,65 @@ axgbe_dev_set_mc_addr_list(struct rte_eth_dev *dev,
 	return 0;
 }
 
+static int
+axgbe_dev_uc_hash_table_set(struct rte_eth_dev *dev,
+			    struct rte_ether_addr *mac_addr, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	axgbe_set_mac_hash_table(pdata, (u8 *)mac_addr, add);
+
+	if (pdata->uc_hash_mac_addr > 0) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
+static int
+axgbe_dev_uc_all_hash_table_set(struct rte_eth_dev *dev, uint8_t add)
+{
+	struct axgbe_port *pdata = dev->data->dev_private;
+	struct axgbe_hw_features *hw_feat = &pdata->hw_feat;
+	uint32_t index;
+
+	if (!hw_feat->hash_table_size) {
+		PMD_DRV_LOG(ERR, "MAC Hash Table not supported\n");
+		return -ENOTSUP;
+	}
+
+	for (index = 0; index < pdata->hash_table_count; index++) {
+		if (add)
+			pdata->uc_hash_table[index] = ~0;
+		else
+			pdata->uc_hash_table[index] = 0;
+
+		PMD_DRV_LOG(DEBUG, "%s MAC hash table at Index %#x\n",
+			    add ? "set" : "clear", index);
+
+		AXGMAC_IOWRITE(pdata, MAC_HTR(index),
+			       pdata->uc_hash_table[index]);
+	}
+
+	if (add) {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 1);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 1);
+	} else {
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HPF, 0);
+		AXGMAC_IOWRITE_BITS(pdata, MAC_PFR, HUC, 0);
+	}
+	return 0;
+}
+
 /* return 0 means link status changed, -1 means not changed */
 static int
 axgbe_dev_link_update(struct rte_eth_dev *dev,
@@ -892,6 +958,7 @@ axgbe_dev_info_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	dev_info->min_rx_bufsize = AXGBE_RX_MIN_BUF_SIZE;
 	dev_info->max_rx_pktlen = AXGBE_RX_MAX_BUF_SIZE;
 	dev_info->max_mac_addrs = pdata->hw_feat.addn_mac + 1;
+	dev_info->max_hash_mac_addrs = pdata->hw_feat.hash_table_size;
 	dev_info->speed_capa =  ETH_LINK_SPEED_10G;
 
 	dev_info->rx_offload_capa =
@@ -1206,6 +1273,18 @@ eth_axgbe_dev_init(struct rte_eth_dev *eth_dev)
 		return -ENOMEM;
 	}
 
+	/* Allocate memory for storing hash filter MAC addresses */
+	len = RTE_ETHER_ADDR_LEN * AXGBE_MAX_HASH_MAC_ADDRS;
+	eth_dev->data->hash_mac_addrs = rte_zmalloc("axgbe_hash_mac_addr",
+						    len, 0);
+
+	if (eth_dev->data->hash_mac_addrs == NULL) {
+		PMD_INIT_LOG(ERR,
+			     "Failed to allocate %d bytes needed to "
+			     "store MAC addresses", len);
+		return -ENOMEM;
+	}
+
 	if (!rte_is_valid_assigned_ether_addr(&pdata->mac_addr))
 		rte_eth_random_addr(pdata->mac_addr.addr_bytes);
 
diff --git a/drivers/net/axgbe/axgbe_ethdev.h b/drivers/net/axgbe/axgbe_ethdev.h
index 781d170e5..3969317fd 100644
--- a/drivers/net/axgbe/axgbe_ethdev.h
+++ b/drivers/net/axgbe/axgbe_ethdev.h
@@ -17,6 +17,7 @@
 #define AXGBE_RX_MAX_BUF_SIZE		(0x3fff & ~(64 - 1))
 #define AXGBE_RX_MIN_BUF_SIZE		(RTE_ETHER_MAX_LEN + VLAN_HLEN)
 #define AXGBE_MAX_MAC_ADDRS		32
+#define AXGBE_MAX_HASH_MAC_ADDRS	256
 
 #define AXGBE_RX_BUF_ALIGN		64
 
@@ -83,7 +84,7 @@
 	(((_x) < 1024) ? 0 : ((_x) / AXGMAC_FLOW_CONTROL_UNIT) - 2)
 #define AXGMAC_FLOW_CONTROL_MAX		33280
 
-/* Maximum MAC address hash table size (256 bits = 8 bytes) */
+/* Maximum MAC address hash table size (256 bits = 8 dword) */
 #define AXGBE_MAC_HASH_TABLE_SIZE	8
 
 /* Receive Side Scaling */
@@ -625,6 +626,12 @@ struct axgbe_port {
 	uint32_t rx_csum_enable;
 
 	struct axgbe_mmc_stats mmc_stats;
+
+	/* Hash filtering */
+	unsigned int hash_table_shift;
+	unsigned int hash_table_count;
+	unsigned int uc_hash_mac_addr;
+	unsigned int uc_hash_table[AXGBE_MAC_HASH_TABLE_SIZE];
 };
 
 void axgbe_init_function_ptrs_dev(struct axgbe_hw_if *hw_if);
@@ -633,5 +640,6 @@ void axgbe_init_function_ptrs_phy_v2(struct axgbe_phy_if *phy_if);
 void axgbe_init_function_ptrs_i2c(struct axgbe_i2c_if *i2c_if);
 void axgbe_set_mac_addn_addr(struct axgbe_port *pdata, u8 *addr,
 			     uint32_t index);
+void axgbe_set_mac_hash_table(struct axgbe_port *pdata, u8 *addr, bool add);
 
 #endif /* RTE_ETH_AXGBE_H_ */
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-02-28 14:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-28 14:00 [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address chandu
2020-02-28 14:06 [dpdk-dev] [PATCH v1 1/2] net/axgbe: add additional MAC address support chandu
2020-02-28 14:06 ` [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address chandu
2020-02-28 14:20 [dpdk-dev] [PATCH v1 1/2] net/axgbe: add additional MAC address support chandu
2020-02-28 14:20 ` [dpdk-dev] [PATCH v1 2/2] net/axgbe: add unicast hash table for mac address chandu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.