mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	net: ethernet: mtk_eth_soc: ppe: add support for flow accounting
The PPE units found in MT7622 and newer support packet and byte
accounting of hw-offloaded flows. Add support for reading those counters
as found in MediaTek's SDK[1].
[1]: bc6a6a375c
Tested-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Daniel Golle <daniel@makrotopia.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
			
			
This commit is contained in:
		
							parent
							
								
									c0a440031d
								
							
						
					
					
						commit
						3fbe4d8c0e
					
				
					 7 changed files with 172 additions and 9 deletions
				
			
		| 
						 | 
					@ -4697,8 +4697,8 @@ static int mtk_probe(struct platform_device *pdev)
 | 
				
			||||||
		for (i = 0; i < num_ppe; i++) {
 | 
							for (i = 0; i < num_ppe; i++) {
 | 
				
			||||||
			u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
 | 
								u32 ppe_addr = eth->soc->reg_map->ppe_base + i * 0x400;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr,
 | 
								eth->ppe[i] = mtk_ppe_init(eth, eth->base + ppe_addr, i);
 | 
				
			||||||
						   eth->soc->offload_version, i);
 | 
					
 | 
				
			||||||
			if (!eth->ppe[i]) {
 | 
								if (!eth->ppe[i]) {
 | 
				
			||||||
				err = -ENOMEM;
 | 
									err = -ENOMEM;
 | 
				
			||||||
				goto err_deinit_ppe;
 | 
									goto err_deinit_ppe;
 | 
				
			||||||
| 
						 | 
					@ -4820,6 +4820,7 @@ static const struct mtk_soc_data mt7622_data = {
 | 
				
			||||||
	.required_pctl = false,
 | 
						.required_pctl = false,
 | 
				
			||||||
	.offload_version = 2,
 | 
						.offload_version = 2,
 | 
				
			||||||
	.hash_offset = 2,
 | 
						.hash_offset = 2,
 | 
				
			||||||
 | 
						.has_accounting = true,
 | 
				
			||||||
	.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
 | 
						.foe_entry_size = sizeof(struct mtk_foe_entry) - 16,
 | 
				
			||||||
	.txrx = {
 | 
						.txrx = {
 | 
				
			||||||
		.txd_size = sizeof(struct mtk_tx_dma),
 | 
							.txd_size = sizeof(struct mtk_tx_dma),
 | 
				
			||||||
| 
						 | 
					@ -4857,6 +4858,7 @@ static const struct mtk_soc_data mt7629_data = {
 | 
				
			||||||
	.hw_features = MTK_HW_FEATURES,
 | 
						.hw_features = MTK_HW_FEATURES,
 | 
				
			||||||
	.required_clks = MT7629_CLKS_BITMAP,
 | 
						.required_clks = MT7629_CLKS_BITMAP,
 | 
				
			||||||
	.required_pctl = false,
 | 
						.required_pctl = false,
 | 
				
			||||||
 | 
						.has_accounting = true,
 | 
				
			||||||
	.txrx = {
 | 
						.txrx = {
 | 
				
			||||||
		.txd_size = sizeof(struct mtk_tx_dma),
 | 
							.txd_size = sizeof(struct mtk_tx_dma),
 | 
				
			||||||
		.rxd_size = sizeof(struct mtk_rx_dma),
 | 
							.rxd_size = sizeof(struct mtk_rx_dma),
 | 
				
			||||||
| 
						 | 
					@ -4877,6 +4879,7 @@ static const struct mtk_soc_data mt7981_data = {
 | 
				
			||||||
	.offload_version = 2,
 | 
						.offload_version = 2,
 | 
				
			||||||
	.hash_offset = 4,
 | 
						.hash_offset = 4,
 | 
				
			||||||
	.foe_entry_size = sizeof(struct mtk_foe_entry),
 | 
						.foe_entry_size = sizeof(struct mtk_foe_entry),
 | 
				
			||||||
 | 
						.has_accounting = true,
 | 
				
			||||||
	.txrx = {
 | 
						.txrx = {
 | 
				
			||||||
		.txd_size = sizeof(struct mtk_tx_dma_v2),
 | 
							.txd_size = sizeof(struct mtk_tx_dma_v2),
 | 
				
			||||||
		.rxd_size = sizeof(struct mtk_rx_dma_v2),
 | 
							.rxd_size = sizeof(struct mtk_rx_dma_v2),
 | 
				
			||||||
| 
						 | 
					@ -4897,6 +4900,7 @@ static const struct mtk_soc_data mt7986_data = {
 | 
				
			||||||
	.offload_version = 2,
 | 
						.offload_version = 2,
 | 
				
			||||||
	.hash_offset = 4,
 | 
						.hash_offset = 4,
 | 
				
			||||||
	.foe_entry_size = sizeof(struct mtk_foe_entry),
 | 
						.foe_entry_size = sizeof(struct mtk_foe_entry),
 | 
				
			||||||
 | 
						.has_accounting = true,
 | 
				
			||||||
	.txrx = {
 | 
						.txrx = {
 | 
				
			||||||
		.txd_size = sizeof(struct mtk_tx_dma_v2),
 | 
							.txd_size = sizeof(struct mtk_tx_dma_v2),
 | 
				
			||||||
		.rxd_size = sizeof(struct mtk_rx_dma_v2),
 | 
							.rxd_size = sizeof(struct mtk_rx_dma_v2),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1070,6 +1070,8 @@ struct mtk_reg_map {
 | 
				
			||||||
 *				the extra setup for those pins used by GMAC.
 | 
					 *				the extra setup for those pins used by GMAC.
 | 
				
			||||||
 * @hash_offset			Flow table hash offset.
 | 
					 * @hash_offset			Flow table hash offset.
 | 
				
			||||||
 * @foe_entry_size		Foe table entry size.
 | 
					 * @foe_entry_size		Foe table entry size.
 | 
				
			||||||
 | 
					 * @has_accounting		Bool indicating support for accounting of
 | 
				
			||||||
 | 
					 *				offloaded flows.
 | 
				
			||||||
 * @txd_size			Tx DMA descriptor size.
 | 
					 * @txd_size			Tx DMA descriptor size.
 | 
				
			||||||
 * @rxd_size			Rx DMA descriptor size.
 | 
					 * @rxd_size			Rx DMA descriptor size.
 | 
				
			||||||
 * @rx_irq_done_mask		Rx irq done register mask.
 | 
					 * @rx_irq_done_mask		Rx irq done register mask.
 | 
				
			||||||
| 
						 | 
					@ -1087,6 +1089,7 @@ struct mtk_soc_data {
 | 
				
			||||||
	u8		hash_offset;
 | 
						u8		hash_offset;
 | 
				
			||||||
	u16		foe_entry_size;
 | 
						u16		foe_entry_size;
 | 
				
			||||||
	netdev_features_t hw_features;
 | 
						netdev_features_t hw_features;
 | 
				
			||||||
 | 
						bool		has_accounting;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		u32	txd_size;
 | 
							u32	txd_size;
 | 
				
			||||||
		u32	rxd_size;
 | 
							u32	rxd_size;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,6 +74,48 @@ static int mtk_ppe_wait_busy(struct mtk_ppe *ppe)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mtk_ppe_mib_wait_busy(struct mtk_ppe *ppe)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
						u32 val;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = readl_poll_timeout(ppe->base + MTK_PPE_MIB_SER_CR, val,
 | 
				
			||||||
 | 
									 !(val & MTK_PPE_MIB_SER_CR_ST),
 | 
				
			||||||
 | 
									 20, MTK_PPE_WAIT_TIMEOUT_US);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							dev_err(ppe->dev, "MIB table busy");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return ret;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int mtk_mib_entry_read(struct mtk_ppe *ppe, u16 index, u64 *bytes, u64 *packets)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						u32 byte_cnt_low, byte_cnt_high, pkt_cnt_low, pkt_cnt_high;
 | 
				
			||||||
 | 
						u32 val, cnt_r0, cnt_r1, cnt_r2;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						val = FIELD_PREP(MTK_PPE_MIB_SER_CR_ADDR, index) | MTK_PPE_MIB_SER_CR_ST;
 | 
				
			||||||
 | 
						ppe_w32(ppe, MTK_PPE_MIB_SER_CR, val);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = mtk_ppe_mib_wait_busy(ppe);
 | 
				
			||||||
 | 
						if (ret)
 | 
				
			||||||
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cnt_r0 = readl(ppe->base + MTK_PPE_MIB_SER_R0);
 | 
				
			||||||
 | 
						cnt_r1 = readl(ppe->base + MTK_PPE_MIB_SER_R1);
 | 
				
			||||||
 | 
						cnt_r2 = readl(ppe->base + MTK_PPE_MIB_SER_R2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						byte_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW, cnt_r0);
 | 
				
			||||||
 | 
						byte_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH, cnt_r1);
 | 
				
			||||||
 | 
						pkt_cnt_low = FIELD_GET(MTK_PPE_MIB_SER_R1_PKT_CNT_LOW, cnt_r1);
 | 
				
			||||||
 | 
						pkt_cnt_high = FIELD_GET(MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH, cnt_r2);
 | 
				
			||||||
 | 
						*bytes = ((u64)byte_cnt_high << 32) | byte_cnt_low;
 | 
				
			||||||
 | 
						*packets = (pkt_cnt_high << 16) | pkt_cnt_low;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
 | 
					static void mtk_ppe_cache_clear(struct mtk_ppe *ppe)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
 | 
						ppe_set(ppe, MTK_PPE_CACHE_CTL, MTK_PPE_CACHE_CTL_CLEAR);
 | 
				
			||||||
| 
						 | 
					@ -458,6 +500,13 @@ __mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry)
 | 
				
			||||||
		hwe->ib1 &= ~MTK_FOE_IB1_STATE;
 | 
							hwe->ib1 &= ~MTK_FOE_IB1_STATE;
 | 
				
			||||||
		hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
 | 
							hwe->ib1 |= FIELD_PREP(MTK_FOE_IB1_STATE, MTK_FOE_STATE_INVALID);
 | 
				
			||||||
		dma_wmb();
 | 
							dma_wmb();
 | 
				
			||||||
 | 
							if (ppe->accounting) {
 | 
				
			||||||
 | 
								struct mtk_foe_accounting *acct;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								acct = ppe->acct_table + entry->hash * sizeof(*acct);
 | 
				
			||||||
 | 
								acct->packets = 0;
 | 
				
			||||||
 | 
								acct->bytes = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	entry->hash = 0xffff;
 | 
						entry->hash = 0xffff;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -565,6 +614,9 @@ __mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_foe_entry *entry,
 | 
				
			||||||
	wmb();
 | 
						wmb();
 | 
				
			||||||
	hwe->ib1 = entry->ib1;
 | 
						hwe->ib1 = entry->ib1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ppe->accounting)
 | 
				
			||||||
 | 
							*mtk_foe_entry_ib2(eth, hwe) |= MTK_FOE_IB2_MIB_CNT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dma_wmb();
 | 
						dma_wmb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtk_ppe_cache_clear(ppe);
 | 
						mtk_ppe_cache_clear(ppe);
 | 
				
			||||||
| 
						 | 
					@ -756,11 +808,39 @@ int mtk_ppe_prepare_reset(struct mtk_ppe *ppe)
 | 
				
			||||||
	return mtk_ppe_wait_busy(ppe);
 | 
						return mtk_ppe_wait_busy(ppe);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 | 
					struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
 | 
				
			||||||
			     int version, int index)
 | 
											 struct mtk_foe_accounting *diff)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						struct mtk_foe_accounting *acct;
 | 
				
			||||||
 | 
						int size = sizeof(struct mtk_foe_accounting);
 | 
				
			||||||
 | 
						u64 bytes, packets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!ppe->accounting)
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (mtk_mib_entry_read(ppe, index, &bytes, &packets))
 | 
				
			||||||
 | 
							return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acct = ppe->acct_table + index * size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						acct->bytes += bytes;
 | 
				
			||||||
 | 
						acct->packets += packets;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (diff) {
 | 
				
			||||||
 | 
							diff->bytes = bytes;
 | 
				
			||||||
 | 
							diff->packets = packets;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return acct;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						bool accounting = eth->soc->has_accounting;
 | 
				
			||||||
	const struct mtk_soc_data *soc = eth->soc;
 | 
						const struct mtk_soc_data *soc = eth->soc;
 | 
				
			||||||
 | 
						struct mtk_foe_accounting *acct;
 | 
				
			||||||
	struct device *dev = eth->dev;
 | 
						struct device *dev = eth->dev;
 | 
				
			||||||
 | 
						struct mtk_mib_entry *mib;
 | 
				
			||||||
	struct mtk_ppe *ppe;
 | 
						struct mtk_ppe *ppe;
 | 
				
			||||||
	u32 foe_flow_size;
 | 
						u32 foe_flow_size;
 | 
				
			||||||
	void *foe;
 | 
						void *foe;
 | 
				
			||||||
| 
						 | 
					@ -777,7 +857,8 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 | 
				
			||||||
	ppe->base = base;
 | 
						ppe->base = base;
 | 
				
			||||||
	ppe->eth = eth;
 | 
						ppe->eth = eth;
 | 
				
			||||||
	ppe->dev = dev;
 | 
						ppe->dev = dev;
 | 
				
			||||||
	ppe->version = version;
 | 
						ppe->version = eth->soc->offload_version;
 | 
				
			||||||
 | 
						ppe->accounting = accounting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	foe = dmam_alloc_coherent(ppe->dev,
 | 
						foe = dmam_alloc_coherent(ppe->dev,
 | 
				
			||||||
				  MTK_PPE_ENTRIES * soc->foe_entry_size,
 | 
									  MTK_PPE_ENTRIES * soc->foe_entry_size,
 | 
				
			||||||
| 
						 | 
					@ -793,6 +874,23 @@ struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 | 
				
			||||||
	if (!ppe->foe_flow)
 | 
						if (!ppe->foe_flow)
 | 
				
			||||||
		goto err_free_l2_flows;
 | 
							goto err_free_l2_flows;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (accounting) {
 | 
				
			||||||
 | 
							mib = dmam_alloc_coherent(ppe->dev, MTK_PPE_ENTRIES * sizeof(*mib),
 | 
				
			||||||
 | 
										  &ppe->mib_phys, GFP_KERNEL);
 | 
				
			||||||
 | 
							if (!mib)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ppe->mib_table = mib;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							acct = devm_kzalloc(dev, MTK_PPE_ENTRIES * sizeof(*acct),
 | 
				
			||||||
 | 
									    GFP_KERNEL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (!acct)
 | 
				
			||||||
 | 
								return NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ppe->acct_table = acct;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtk_ppe_debugfs_init(ppe, index);
 | 
						mtk_ppe_debugfs_init(ppe, index);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return ppe;
 | 
						return ppe;
 | 
				
			||||||
| 
						 | 
					@ -922,6 +1020,16 @@ void mtk_ppe_start(struct mtk_ppe *ppe)
 | 
				
			||||||
		ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
 | 
							ppe_w32(ppe, MTK_PPE_DEFAULT_CPU_PORT1, 0xcb777);
 | 
				
			||||||
		ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
 | 
							ppe_w32(ppe, MTK_PPE_SBW_CTRL, 0x7f);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ppe->accounting && ppe->mib_phys) {
 | 
				
			||||||
 | 
							ppe_w32(ppe, MTK_PPE_MIB_TB_BASE, ppe->mib_phys);
 | 
				
			||||||
 | 
							ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_EN,
 | 
				
			||||||
 | 
								MTK_PPE_MIB_CFG_EN);
 | 
				
			||||||
 | 
							ppe_m32(ppe, MTK_PPE_MIB_CFG, MTK_PPE_MIB_CFG_RD_CLR,
 | 
				
			||||||
 | 
								MTK_PPE_MIB_CFG_RD_CLR);
 | 
				
			||||||
 | 
							ppe_m32(ppe, MTK_PPE_MIB_CACHE_CTL, MTK_PPE_MIB_CACHE_CTL_EN,
 | 
				
			||||||
 | 
								MTK_PPE_MIB_CFG_RD_CLR);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mtk_ppe_stop(struct mtk_ppe *ppe)
 | 
					int mtk_ppe_stop(struct mtk_ppe *ppe)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -57,6 +57,7 @@ enum {
 | 
				
			||||||
#define MTK_FOE_IB2_MULTICAST		BIT(8)
 | 
					#define MTK_FOE_IB2_MULTICAST		BIT(8)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MTK_FOE_IB2_WDMA_QID2		GENMASK(13, 12)
 | 
					#define MTK_FOE_IB2_WDMA_QID2		GENMASK(13, 12)
 | 
				
			||||||
 | 
					#define MTK_FOE_IB2_MIB_CNT		BIT(15)
 | 
				
			||||||
#define MTK_FOE_IB2_WDMA_DEVIDX		BIT(16)
 | 
					#define MTK_FOE_IB2_WDMA_DEVIDX		BIT(16)
 | 
				
			||||||
#define MTK_FOE_IB2_WDMA_WINFO		BIT(17)
 | 
					#define MTK_FOE_IB2_WDMA_WINFO		BIT(17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -285,16 +286,34 @@ struct mtk_flow_entry {
 | 
				
			||||||
	unsigned long cookie;
 | 
						unsigned long cookie;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mtk_mib_entry {
 | 
				
			||||||
 | 
						u32	byt_cnt_l;
 | 
				
			||||||
 | 
						u16	byt_cnt_h;
 | 
				
			||||||
 | 
						u32	pkt_cnt_l;
 | 
				
			||||||
 | 
						u8	pkt_cnt_h;
 | 
				
			||||||
 | 
						u8	_rsv0;
 | 
				
			||||||
 | 
						u32	_rsv1;
 | 
				
			||||||
 | 
					} __packed;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct mtk_foe_accounting {
 | 
				
			||||||
 | 
						u64	bytes;
 | 
				
			||||||
 | 
						u64	packets;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mtk_ppe {
 | 
					struct mtk_ppe {
 | 
				
			||||||
	struct mtk_eth *eth;
 | 
						struct mtk_eth *eth;
 | 
				
			||||||
	struct device *dev;
 | 
						struct device *dev;
 | 
				
			||||||
	void __iomem *base;
 | 
						void __iomem *base;
 | 
				
			||||||
	int version;
 | 
						int version;
 | 
				
			||||||
	char dirname[5];
 | 
						char dirname[5];
 | 
				
			||||||
 | 
						bool accounting;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void *foe_table;
 | 
						void *foe_table;
 | 
				
			||||||
	dma_addr_t foe_phys;
 | 
						dma_addr_t foe_phys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						struct mtk_mib_entry *mib_table;
 | 
				
			||||||
 | 
						dma_addr_t mib_phys;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	u16 foe_check_time[MTK_PPE_ENTRIES];
 | 
						u16 foe_check_time[MTK_PPE_ENTRIES];
 | 
				
			||||||
	struct hlist_head *foe_flow;
 | 
						struct hlist_head *foe_flow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -303,8 +322,8 @@ struct mtk_ppe {
 | 
				
			||||||
	void *acct_table;
 | 
						void *acct_table;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base,
 | 
					struct mtk_ppe *mtk_ppe_init(struct mtk_eth *eth, void __iomem *base, int index);
 | 
				
			||||||
			     int version, int index);
 | 
					
 | 
				
			||||||
void mtk_ppe_deinit(struct mtk_eth *eth);
 | 
					void mtk_ppe_deinit(struct mtk_eth *eth);
 | 
				
			||||||
void mtk_ppe_start(struct mtk_ppe *ppe);
 | 
					void mtk_ppe_start(struct mtk_ppe *ppe);
 | 
				
			||||||
int mtk_ppe_stop(struct mtk_ppe *ppe);
 | 
					int mtk_ppe_stop(struct mtk_ppe *ppe);
 | 
				
			||||||
| 
						 | 
					@ -359,5 +378,7 @@ int mtk_foe_entry_commit(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 | 
				
			||||||
void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 | 
					void mtk_foe_entry_clear(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 | 
				
			||||||
int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 | 
					int mtk_foe_entry_idle_time(struct mtk_ppe *ppe, struct mtk_flow_entry *entry);
 | 
				
			||||||
int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
 | 
					int mtk_ppe_debugfs_init(struct mtk_ppe *ppe, int index);
 | 
				
			||||||
 | 
					struct mtk_foe_accounting *mtk_foe_entry_get_mib(struct mtk_ppe *ppe, u32 index,
 | 
				
			||||||
 | 
											 struct mtk_foe_accounting *diff);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +82,7 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 | 
				
			||||||
		struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
 | 
							struct mtk_foe_entry *entry = mtk_foe_get_entry(ppe, i);
 | 
				
			||||||
		struct mtk_foe_mac_info *l2;
 | 
							struct mtk_foe_mac_info *l2;
 | 
				
			||||||
		struct mtk_flow_addr_info ai = {};
 | 
							struct mtk_flow_addr_info ai = {};
 | 
				
			||||||
 | 
							struct mtk_foe_accounting *acct;
 | 
				
			||||||
		unsigned char h_source[ETH_ALEN];
 | 
							unsigned char h_source[ETH_ALEN];
 | 
				
			||||||
		unsigned char h_dest[ETH_ALEN];
 | 
							unsigned char h_dest[ETH_ALEN];
 | 
				
			||||||
		int type, state;
 | 
							int type, state;
 | 
				
			||||||
| 
						 | 
					@ -95,6 +96,8 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 | 
				
			||||||
		if (bind && state != MTK_FOE_STATE_BIND)
 | 
							if (bind && state != MTK_FOE_STATE_BIND)
 | 
				
			||||||
			continue;
 | 
								continue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							acct = mtk_foe_entry_get_mib(ppe, i, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | 
							type = FIELD_GET(MTK_FOE_IB1_PACKET_TYPE, entry->ib1);
 | 
				
			||||||
		seq_printf(m, "%05x %s %7s", i,
 | 
							seq_printf(m, "%05x %s %7s", i,
 | 
				
			||||||
			   mtk_foe_entry_state_str(state),
 | 
								   mtk_foe_entry_state_str(state),
 | 
				
			||||||
| 
						 | 
					@ -153,9 +156,11 @@ mtk_ppe_debugfs_foe_show(struct seq_file *m, void *private, bool bind)
 | 
				
			||||||
		*((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
 | 
							*((__be16 *)&h_dest[4]) = htons(l2->dest_mac_lo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		seq_printf(m, " eth=%pM->%pM etype=%04x"
 | 
							seq_printf(m, " eth=%pM->%pM etype=%04x"
 | 
				
			||||||
			      " vlan=%d,%d ib1=%08x ib2=%08x\n",
 | 
								      " vlan=%d,%d ib1=%08x ib2=%08x"
 | 
				
			||||||
 | 
								      " packets=%llu bytes=%llu\n",
 | 
				
			||||||
			   h_source, h_dest, ntohs(l2->etype),
 | 
								   h_source, h_dest, ntohs(l2->etype),
 | 
				
			||||||
			   l2->vlan1, l2->vlan2, entry->ib1, ib2);
 | 
								   l2->vlan1, l2->vlan2, entry->ib1, ib2,
 | 
				
			||||||
 | 
								   acct ? acct->packets : 0, acct ? acct->bytes : 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -497,6 +497,7 @@ static int
 | 
				
			||||||
mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 | 
					mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct mtk_flow_entry *entry;
 | 
						struct mtk_flow_entry *entry;
 | 
				
			||||||
 | 
						struct mtk_foe_accounting diff;
 | 
				
			||||||
	u32 idle;
 | 
						u32 idle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	entry = rhashtable_lookup(ð->flow_table, &f->cookie,
 | 
						entry = rhashtable_lookup(ð->flow_table, &f->cookie,
 | 
				
			||||||
| 
						 | 
					@ -507,6 +508,13 @@ mtk_flow_offload_stats(struct mtk_eth *eth, struct flow_cls_offload *f)
 | 
				
			||||||
	idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
 | 
						idle = mtk_foe_entry_idle_time(eth->ppe[entry->ppe_index], entry);
 | 
				
			||||||
	f->stats.lastused = jiffies - idle * HZ;
 | 
						f->stats.lastused = jiffies - idle * HZ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (entry->hash != 0xFFFF &&
 | 
				
			||||||
 | 
						    mtk_foe_entry_get_mib(eth->ppe[entry->ppe_index], entry->hash,
 | 
				
			||||||
 | 
									  &diff)) {
 | 
				
			||||||
 | 
							f->stats.pkts += diff.packets;
 | 
				
			||||||
 | 
							f->stats.bytes += diff.bytes;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,6 +149,20 @@ enum {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MTK_PPE_MIB_TB_BASE			0x338
 | 
					#define MTK_PPE_MIB_TB_BASE			0x338
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_CR			0x33C
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_CR_ST			BIT(16)
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_CR_ADDR			GENMASK(13, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R0			0x340
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R0_BYTE_CNT_LOW		GENMASK(31, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R1			0x344
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R1_PKT_CNT_LOW		GENMASK(31, 16)
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R1_BYTE_CNT_HIGH	GENMASK(15, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R2			0x348
 | 
				
			||||||
 | 
					#define MTK_PPE_MIB_SER_R2_PKT_CNT_HIGH		GENMASK(23, 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MTK_PPE_MIB_CACHE_CTL			0x350
 | 
					#define MTK_PPE_MIB_CACHE_CTL			0x350
 | 
				
			||||||
#define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
 | 
					#define MTK_PPE_MIB_CACHE_CTL_EN		BIT(0)
 | 
				
			||||||
#define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
 | 
					#define MTK_PPE_MIB_CACHE_CTL_FLUSH		BIT(2)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue