diff options
Diffstat (limited to 'drivers/net/ethernet/marvell')
| -rw-r--r-- | drivers/net/ethernet/marvell/mvneta.c | 2 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvneta_bm.c | 4 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2.h | 18 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c | 118 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h | 28 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c | 134 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c | 23 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/skge.c | 14 | ||||
| -rw-r--r-- | drivers/net/ethernet/marvell/sky2.c | 14 | 
9 files changed, 253 insertions, 102 deletions
diff --git a/drivers/net/ethernet/marvell/mvneta.c b/drivers/net/ethernet/marvell/mvneta.c index 94dc0a272644..895bfed26a8a 100644 --- a/drivers/net/ethernet/marvell/mvneta.c +++ b/drivers/net/ethernet/marvell/mvneta.c @@ -1119,7 +1119,7 @@ static void mvneta_bm_update_mtu(struct mvneta_port *pp, int mtu)  			SKB_DATA_ALIGN(MVNETA_RX_BUF_SIZE(bm_pool->pkt_size));  	/* Fill entire long pool */ -	num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC); +	num = hwbm_pool_add(hwbm_pool, hwbm_pool->size);  	if (num != hwbm_pool->size) {  		WARN(1, "pool %d: %d of %d allocated\n",  		     bm_pool->id, num, hwbm_pool->size); diff --git a/drivers/net/ethernet/marvell/mvneta_bm.c b/drivers/net/ethernet/marvell/mvneta_bm.c index de468e1bdba9..82ee2bcca6fd 100644 --- a/drivers/net/ethernet/marvell/mvneta_bm.c +++ b/drivers/net/ethernet/marvell/mvneta_bm.c @@ -190,7 +190,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,  			SKB_DATA_ALIGN(sizeof(struct skb_shared_info));  		hwbm_pool->construct = mvneta_bm_construct;  		hwbm_pool->priv = new_pool; -		spin_lock_init(&hwbm_pool->lock); +		mutex_init(&hwbm_pool->buf_lock);  		/* Create new pool */  		err = mvneta_bm_pool_create(priv, new_pool); @@ -201,7 +201,7 @@ struct mvneta_bm_pool *mvneta_bm_pool_use(struct mvneta_bm *priv, u8 pool_id,  		}  		/* Allocate buffers for this pool */ -		num = hwbm_pool_add(hwbm_pool, hwbm_pool->size, GFP_ATOMIC); +		num = hwbm_pool_add(hwbm_pool, hwbm_pool->size);  		if (num != hwbm_pool->size) {  			WARN(1, "pool %d: %d of %d allocated\n",  			     new_pool->id, num, hwbm_pool->size); diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h index d67c970f02e5..4d9564ba68f6 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2.h @@ -329,8 +329,26 @@  #define     MVPP22_BM_ADDR_HIGH_VIRT_RLS_MASK	0xff00  #define     MVPP22_BM_ADDR_HIGH_VIRT_RLS_SHIFT	8 +/* Packet Processor per-port counters */ +#define MVPP2_OVERRUN_ETH_DROP			0x7000 +#define MVPP2_CLS_ETH_DROP			0x7020 +  /* Hit counters registers */  #define MVPP2_CTRS_IDX				0x7040 +#define     MVPP22_CTRS_TX_CTR(port, txq)	((txq) | ((port) << 3) | BIT(7)) +#define MVPP2_TX_DESC_ENQ_CTR			0x7100 +#define MVPP2_TX_DESC_ENQ_TO_DDR_CTR		0x7104 +#define MVPP2_TX_BUFF_ENQ_TO_DDR_CTR		0x7108 +#define MVPP2_TX_DESC_ENQ_HW_FWD_CTR		0x710c +#define MVPP2_RX_DESC_ENQ_CTR			0x7120 +#define MVPP2_TX_PKTS_DEQ_CTR			0x7130 +#define MVPP2_TX_PKTS_FULL_QUEUE_DROP_CTR	0x7200 +#define MVPP2_TX_PKTS_EARLY_DROP_CTR		0x7204 +#define MVPP2_TX_PKTS_BM_DROP_CTR		0x7208 +#define MVPP2_TX_PKTS_BM_MC_DROP_CTR		0x720c +#define MVPP2_RX_PKTS_FULL_QUEUE_DROP_CTR	0x7220 +#define MVPP2_RX_PKTS_EARLY_DROP_CTR		0x7224 +#define MVPP2_RX_PKTS_BM_DROP_CTR		0x7228  #define MVPP2_CLS_DEC_TBL_HIT_CTR		0x7700  #define MVPP2_CLS_FLOW_TBL_HIT_CTR		0x7704 diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c index e47c00c5f829..b195fb5d61f4 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.c @@ -44,17 +44,17 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* TCP over IPv4 flows, Not fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK), @@ -79,17 +79,17 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* TCP over IPv4 flows, fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP4, MVPP2_FL_IP4_TCP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK), @@ -114,17 +114,17 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* UDP over IPv4 flows, Not fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_NF_TAG, -		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK), @@ -149,17 +149,17 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* UDP over IPv4 flows, fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4 | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OPT | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP4, MVPP2_FL_IP4_UDP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OTHER | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK), @@ -178,12 +178,12 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* TCP over IPv6 flows, not fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_TAG, -		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_NF_TAG, -		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK), @@ -202,13 +202,13 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* TCP over IPv6 flows, fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_IP_FRAG_TRUE |  		       MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_TCP6, MVPP2_FL_IP6_TCP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_IP_FRAG_TRUE |  		       MVPP2_PRS_RI_L4_TCP,  		       MVPP2_PRS_IP_MASK), @@ -228,12 +228,12 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* UDP over IPv6 flows, not fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_TAG, -		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_NF_TAG, -		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_5T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK), @@ -252,13 +252,13 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* UDP over IPv6 flows, fragmented, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6 | MVPP2_PRS_RI_IP_FRAG_TRUE |  		       MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_UDP6, MVPP2_FL_IP6_UDP_FRAG_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6_EXT | MVPP2_PRS_RI_IP_FRAG_TRUE |  		       MVPP2_PRS_RI_L4_UDP,  		       MVPP2_PRS_IP_MASK), @@ -279,15 +279,15 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* IPv4 flows, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4,  		       MVPP2_PRS_RI_L3_PROTO_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OPT,  		       MVPP2_PRS_RI_L3_PROTO_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_IP4, MVPP2_FL_IP4_TAG, -		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP4_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP4_OTHER,  		       MVPP2_PRS_RI_L3_PROTO_MASK), @@ -303,11 +303,11 @@ static const struct mvpp2_cls_flow cls_flows[MVPP2_N_PRS_FLOWS] = {  	/* IPv6 flows, with vlan tag */  	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6,  		       MVPP2_PRS_RI_L3_PROTO_MASK),  	MVPP2_DEF_FLOW(MVPP22_FLOW_IP6, MVPP2_FL_IP6_TAG, -		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_OPT_VLAN, +		       MVPP22_CLS_HEK_IP6_2T | MVPP22_CLS_HEK_TAGGED,  		       MVPP2_PRS_RI_L3_IP6,  		       MVPP2_PRS_RI_L3_PROTO_MASK), @@ -596,7 +596,7 @@ static void mvpp2_cls_flow_init(struct mvpp2 *priv,  	mvpp2_cls_flow_eng_set(&fe, MVPP22_CLS_ENGINE_C2);  	mvpp2_cls_flow_port_id_sel(&fe, true); -	mvpp2_cls_flow_lu_type_set(&fe, MVPP22_FLOW_ETHERNET); +	mvpp2_cls_flow_lu_type_set(&fe, MVPP22_CLS_LU_TYPE_ALL);  	/* Add all ports */  	for (i = 0; i < MVPP2_MAX_PORTS; i++) @@ -655,6 +655,9 @@ static int mvpp2_flow_set_hek_fields(struct mvpp2_cls_flow_entry *fe,  		case MVPP22_CLS_HEK_OPT_VLAN:  			field_id = MVPP22_CLS_FIELD_VLAN;  			break; +		case MVPP22_CLS_HEK_OPT_VLAN_PRI: +			field_id = MVPP22_CLS_FIELD_VLAN_PRI; +			break;  		case MVPP22_CLS_HEK_OPT_IP4SA:  			field_id = MVPP22_CLS_FIELD_IP4SA;  			break; @@ -689,6 +692,10 @@ static int mvpp2_cls_hek_field_size(u32 field)  	switch (field) {  	case MVPP22_CLS_HEK_OPT_MAC_DA:  		return 48; +	case MVPP22_CLS_HEK_OPT_VLAN: +		return 12; +	case MVPP22_CLS_HEK_OPT_VLAN_PRI: +		return 3;  	case MVPP22_CLS_HEK_OPT_IP4SA:  	case MVPP22_CLS_HEK_OPT_IP4DA:  		return 32; @@ -777,6 +784,9 @@ u16 mvpp2_flow_get_hek_fields(struct mvpp2_cls_flow_entry *fe)  		case MVPP22_CLS_FIELD_VLAN:  			hash_opts |= MVPP22_CLS_HEK_OPT_VLAN;  			break; +		case MVPP22_CLS_FIELD_VLAN_PRI: +			hash_opts |= MVPP22_CLS_HEK_OPT_VLAN_PRI; +			break;  		case MVPP22_CLS_FIELD_L3_PROTO:  			hash_opts |= MVPP22_CLS_HEK_OPT_L3_PROTO;  			break; @@ -861,7 +871,7 @@ static void mvpp2_port_c2_cls_init(struct mvpp2_port *port)  	/* Match on Lookup Type */  	c2.tcam[4] |= MVPP22_CLS_C2_TCAM_EN(MVPP22_CLS_C2_LU_TYPE(MVPP2_CLS_LU_TYPE_MASK)); -	c2.tcam[4] |= MVPP22_CLS_C2_LU_TYPE(MVPP22_FLOW_ETHERNET); +	c2.tcam[4] |= MVPP22_CLS_C2_LU_TYPE(MVPP22_CLS_LU_TYPE_ALL);  	/* Update RSS status after matching this entry */  	c2.act = MVPP22_CLS_C2_ACT_RSS_EN(MVPP22_C2_UPD_LOCK); @@ -1081,13 +1091,13 @@ static int mvpp2_port_c2_tcam_rule_add(struct mvpp2_port *port,  	rule->c2_index = c2.index; -	c2.tcam[0] = (rule->c2_tcam & 0xffff) | +	c2.tcam[3] = (rule->c2_tcam & 0xffff) |  		     ((rule->c2_tcam_mask & 0xffff) << 16); -	c2.tcam[1] = ((rule->c2_tcam >> 16) & 0xffff) | +	c2.tcam[2] = ((rule->c2_tcam >> 16) & 0xffff) |  		     (((rule->c2_tcam_mask >> 16) & 0xffff) << 16); -	c2.tcam[2] = ((rule->c2_tcam >> 32) & 0xffff) | +	c2.tcam[1] = ((rule->c2_tcam >> 32) & 0xffff) |  		     (((rule->c2_tcam_mask >> 32) & 0xffff) << 16); -	c2.tcam[3] = ((rule->c2_tcam >> 48) & 0xffff) | +	c2.tcam[0] = ((rule->c2_tcam >> 48) & 0xffff) |  		     (((rule->c2_tcam_mask >> 48) & 0xffff) << 16);  	pmap = BIT(port->id); @@ -1201,6 +1211,9 @@ static int mvpp2_port_flt_rfs_rule_insert(struct mvpp2_port *port,  		if (!flow)  			return 0; +		if ((rule->hek_fields & flow->supported_hash_opts) != rule->hek_fields) +			continue; +  		index = MVPP2_CLS_FLT_C2_RFS(port->id, flow->flow_id, rule->loc);  		mvpp2_cls_flow_read(priv, index, &fe); @@ -1219,7 +1232,44 @@ static int mvpp2_port_flt_rfs_rule_insert(struct mvpp2_port *port,  static int mvpp2_cls_c2_build_match(struct mvpp2_rfs_rule *rule)  {  	struct flow_rule *flow = rule->flow; -	int offs = 64; +	int offs = 0; + +	/* The order of insertion in C2 tcam must match the order in which +	 * the fields are found in the header +	 */ +	if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_VLAN)) { +		struct flow_match_vlan match; + +		flow_rule_match_vlan(flow, &match); +		if (match.mask->vlan_id) { +			rule->hek_fields |= MVPP22_CLS_HEK_OPT_VLAN; + +			rule->c2_tcam |= ((u64)match.key->vlan_id) << offs; +			rule->c2_tcam_mask |= ((u64)match.mask->vlan_id) << offs; + +			/* Don't update the offset yet */ +		} + +		if (match.mask->vlan_priority) { +			rule->hek_fields |= MVPP22_CLS_HEK_OPT_VLAN_PRI; + +			/* VLAN pri is always at offset 13 relative to the +			 * current offset +			 */ +			rule->c2_tcam |= ((u64)match.key->vlan_priority) << +				(offs + 13); +			rule->c2_tcam_mask |= ((u64)match.mask->vlan_priority) << +				(offs + 13); +		} + +		if (match.mask->vlan_dei) +			return -EOPNOTSUPP; + +		/* vlan id and prio always seem to take a full 16-bit slot in +		 * the Header Extracted Key. +		 */ +		offs += 16; +	}  	if (flow_rule_match_key(flow, FLOW_DISSECTOR_KEY_PORTS)) {  		struct flow_match_ports match; @@ -1227,18 +1277,18 @@ static int mvpp2_cls_c2_build_match(struct mvpp2_rfs_rule *rule)  		flow_rule_match_ports(flow, &match);  		if (match.mask->src) {  			rule->hek_fields |= MVPP22_CLS_HEK_OPT_L4SIP; -			offs -= mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4SIP);  			rule->c2_tcam |= ((u64)ntohs(match.key->src)) << offs;  			rule->c2_tcam_mask |= ((u64)ntohs(match.mask->src)) << offs; +			offs += mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4SIP);  		}  		if (match.mask->dst) {  			rule->hek_fields |= MVPP22_CLS_HEK_OPT_L4DIP; -			offs -= mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4DIP);  			rule->c2_tcam |= ((u64)ntohs(match.key->dst)) << offs;  			rule->c2_tcam_mask |= ((u64)ntohs(match.mask->dst)) << offs; +			offs += mvpp2_cls_hek_field_size(MVPP22_CLS_HEK_OPT_L4DIP);  		}  	} diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h index 26cc1176e758..8867f25afab4 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_cls.h @@ -33,15 +33,16 @@ enum mvpp2_cls_engine {  };  #define MVPP22_CLS_HEK_OPT_MAC_DA	BIT(0) -#define MVPP22_CLS_HEK_OPT_VLAN		BIT(1) -#define MVPP22_CLS_HEK_OPT_L3_PROTO	BIT(2) -#define MVPP22_CLS_HEK_OPT_IP4SA	BIT(3) -#define MVPP22_CLS_HEK_OPT_IP4DA	BIT(4) -#define MVPP22_CLS_HEK_OPT_IP6SA	BIT(5) -#define MVPP22_CLS_HEK_OPT_IP6DA	BIT(6) -#define MVPP22_CLS_HEK_OPT_L4SIP	BIT(7) -#define MVPP22_CLS_HEK_OPT_L4DIP	BIT(8) -#define MVPP22_CLS_HEK_N_FIELDS		9 +#define MVPP22_CLS_HEK_OPT_VLAN_PRI	BIT(1) +#define MVPP22_CLS_HEK_OPT_VLAN		BIT(2) +#define MVPP22_CLS_HEK_OPT_L3_PROTO	BIT(3) +#define MVPP22_CLS_HEK_OPT_IP4SA	BIT(4) +#define MVPP22_CLS_HEK_OPT_IP4DA	BIT(5) +#define MVPP22_CLS_HEK_OPT_IP6SA	BIT(6) +#define MVPP22_CLS_HEK_OPT_IP6DA	BIT(7) +#define MVPP22_CLS_HEK_OPT_L4SIP	BIT(8) +#define MVPP22_CLS_HEK_OPT_L4DIP	BIT(9) +#define MVPP22_CLS_HEK_N_FIELDS		10  #define MVPP22_CLS_HEK_L4_OPTS	(MVPP22_CLS_HEK_OPT_L4SIP | \  				 MVPP22_CLS_HEK_OPT_L4DIP) @@ -59,8 +60,12 @@ enum mvpp2_cls_engine {  #define MVPP22_CLS_HEK_IP6_5T	(MVPP22_CLS_HEK_IP6_2T | \  				 MVPP22_CLS_HEK_L4_OPTS) +#define MVPP22_CLS_HEK_TAGGED	(MVPP22_CLS_HEK_OPT_VLAN | \ +				 MVPP22_CLS_HEK_OPT_VLAN_PRI) +  enum mvpp2_cls_field_id {  	MVPP22_CLS_FIELD_MAC_DA = 0x03, +	MVPP22_CLS_FIELD_VLAN_PRI = 0x05,  	MVPP22_CLS_FIELD_VLAN = 0x06,  	MVPP22_CLS_FIELD_L3_PROTO = 0x0f,  	MVPP22_CLS_FIELD_IP4SA = 0x10, @@ -180,6 +185,11 @@ enum mvpp2_prs_flow {  /* LU Type defined for all engines, and specified in the flow table */  #define MVPP2_CLS_LU_TYPE_MASK			0x3f +enum mvpp2_cls_lu_type { +	/* rule->loc is used as a lu-type for the entries 0 - 62. */ +	MVPP22_CLS_LU_TYPE_ALL = 63, +}; +  #define MVPP2_N_FLOWS		(MVPP2_FL_LAST - MVPP2_FL_START)  struct mvpp2_cls_flow { diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c index 772caf0bdecd..c51f1d5b550b 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c @@ -1258,6 +1258,17 @@ static u64 mvpp2_read_count(struct mvpp2_port *port,  	return val;  } +/* Some counters are accessed indirectly by first writing an index to + * MVPP2_CTRS_IDX. The index can represent various resources depending on the + * register we access, it can be a hit counter for some classification tables, + * a counter specific to a rxq, a txq or a buffer pool. + */ +static u32 mvpp2_read_index(struct mvpp2 *priv, u32 index, u32 reg) +{ +	mvpp2_write(priv, MVPP2_CTRS_IDX, index); +	return mvpp2_read(priv, reg); +} +  /* Due to the fact that software statistics and hardware statistics are, by   * design, incremented at different moments in the chain of packet processing,   * it is very likely that incoming packets could have been dropped after being @@ -1267,7 +1278,7 @@ static u64 mvpp2_read_count(struct mvpp2_port *port,   * Hence, statistics gathered from userspace with ifconfig (software) and   * ethtool (hardware) cannot be compared.   */ -static const struct mvpp2_ethtool_counter mvpp2_ethtool_regs[] = { +static const struct mvpp2_ethtool_counter mvpp2_ethtool_mib_regs[] = {  	{ MVPP2_MIB_GOOD_OCTETS_RCVD, "good_octets_received", true },  	{ MVPP2_MIB_BAD_OCTETS_RCVD, "bad_octets_received" },  	{ MVPP2_MIB_CRC_ERRORS_SENT, "crc_errors_sent" }, @@ -1297,31 +1308,114 @@ static const struct mvpp2_ethtool_counter mvpp2_ethtool_regs[] = {  	{ MVPP2_MIB_LATE_COLLISION, "late_collision" },  }; +static const struct mvpp2_ethtool_counter mvpp2_ethtool_port_regs[] = { +	{ MVPP2_OVERRUN_ETH_DROP, "rx_fifo_or_parser_overrun_drops" }, +	{ MVPP2_CLS_ETH_DROP, "rx_classifier_drops" }, +}; + +static const struct mvpp2_ethtool_counter mvpp2_ethtool_txq_regs[] = { +	{ MVPP2_TX_DESC_ENQ_CTR, "txq_%d_desc_enqueue" }, +	{ MVPP2_TX_DESC_ENQ_TO_DDR_CTR, "txq_%d_desc_enqueue_to_ddr" }, +	{ MVPP2_TX_BUFF_ENQ_TO_DDR_CTR, "txq_%d_buff_euqueue_to_ddr" }, +	{ MVPP2_TX_DESC_ENQ_HW_FWD_CTR, "txq_%d_desc_hardware_forwarded" }, +	{ MVPP2_TX_PKTS_DEQ_CTR, "txq_%d_packets_dequeued" }, +	{ MVPP2_TX_PKTS_FULL_QUEUE_DROP_CTR, "txq_%d_queue_full_drops" }, +	{ MVPP2_TX_PKTS_EARLY_DROP_CTR, "txq_%d_packets_early_drops" }, +	{ MVPP2_TX_PKTS_BM_DROP_CTR, "txq_%d_packets_bm_drops" }, +	{ MVPP2_TX_PKTS_BM_MC_DROP_CTR, "txq_%d_packets_rep_bm_drops" }, +}; + +static const struct mvpp2_ethtool_counter mvpp2_ethtool_rxq_regs[] = { +	{ MVPP2_RX_DESC_ENQ_CTR, "rxq_%d_desc_enqueue" }, +	{ MVPP2_RX_PKTS_FULL_QUEUE_DROP_CTR, "rxq_%d_queue_full_drops" }, +	{ MVPP2_RX_PKTS_EARLY_DROP_CTR, "rxq_%d_packets_early_drops" }, +	{ MVPP2_RX_PKTS_BM_DROP_CTR, "rxq_%d_packets_bm_drops" }, +}; + +#define MVPP2_N_ETHTOOL_STATS(ntxqs, nrxqs)	(ARRAY_SIZE(mvpp2_ethtool_mib_regs) + \ +						 ARRAY_SIZE(mvpp2_ethtool_port_regs) + \ +						 (ARRAY_SIZE(mvpp2_ethtool_txq_regs) * (ntxqs)) + \ +						 (ARRAY_SIZE(mvpp2_ethtool_rxq_regs) * (nrxqs))) +  static void mvpp2_ethtool_get_strings(struct net_device *netdev, u32 sset,  				      u8 *data)  { -	if (sset == ETH_SS_STATS) { -		int i; +	struct mvpp2_port *port = netdev_priv(netdev); +	int i, q; + +	if (sset != ETH_SS_STATS) +		return; + +	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_mib_regs); i++) { +		strscpy(data, mvpp2_ethtool_mib_regs[i].string, +			ETH_GSTRING_LEN); +		data += ETH_GSTRING_LEN; +	} -		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++) -			memcpy(data + i * ETH_GSTRING_LEN, -			       &mvpp2_ethtool_regs[i].string, ETH_GSTRING_LEN); +	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_port_regs); i++) { +		strscpy(data, mvpp2_ethtool_port_regs[i].string, +			ETH_GSTRING_LEN); +		data += ETH_GSTRING_LEN; +	} + +	for (q = 0; q < port->ntxqs; q++) { +		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) { +			snprintf(data, ETH_GSTRING_LEN, +				 mvpp2_ethtool_txq_regs[i].string, q); +			data += ETH_GSTRING_LEN; +		} +	} + +	for (q = 0; q < port->nrxqs; q++) { +		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) { +			snprintf(data, ETH_GSTRING_LEN, +				 mvpp2_ethtool_rxq_regs[i].string, +				 q); +			data += ETH_GSTRING_LEN; +		}  	}  } +static void mvpp2_read_stats(struct mvpp2_port *port) +{ +	u64 *pstats; +	int i, q; + +	pstats = port->ethtool_stats; + +	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_mib_regs); i++) +		*pstats++ += mvpp2_read_count(port, &mvpp2_ethtool_mib_regs[i]); + +	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_port_regs); i++) +		*pstats++ += mvpp2_read(port->priv, +					mvpp2_ethtool_port_regs[i].offset + +					4 * port->id); + +	for (q = 0; q < port->ntxqs; q++) +		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_txq_regs); i++) +			*pstats++ += mvpp2_read_index(port->priv, +						      MVPP22_CTRS_TX_CTR(port->id, i), +						      mvpp2_ethtool_txq_regs[i].offset); + +	/* Rxqs are numbered from 0 from the user standpoint, but not from the +	 * driver's. We need to add the  port->first_rxq offset. +	 */ +	for (q = 0; q < port->nrxqs; q++) +		for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_rxq_regs); i++) +			*pstats++ += mvpp2_read_index(port->priv, +						      port->first_rxq + i, +						      mvpp2_ethtool_rxq_regs[i].offset); +} +  static void mvpp2_gather_hw_statistics(struct work_struct *work)  {  	struct delayed_work *del_work = to_delayed_work(work);  	struct mvpp2_port *port = container_of(del_work, struct mvpp2_port,  					       stats_work); -	u64 *pstats; -	int i;  	mutex_lock(&port->gather_stats_lock); -	pstats = port->ethtool_stats; -	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++) -		*pstats++ += mvpp2_read_count(port, &mvpp2_ethtool_regs[i]); +	mvpp2_read_stats(port);  	/* No need to read again the counters right after this function if it  	 * was called asynchronously by the user (ie. use of ethtool). @@ -1345,27 +1439,24 @@ static void mvpp2_ethtool_get_stats(struct net_device *dev,  	mutex_lock(&port->gather_stats_lock);  	memcpy(data, port->ethtool_stats, -	       sizeof(u64) * ARRAY_SIZE(mvpp2_ethtool_regs)); +	       sizeof(u64) * MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs));  	mutex_unlock(&port->gather_stats_lock);  }  static int mvpp2_ethtool_get_sset_count(struct net_device *dev, int sset)  { +	struct mvpp2_port *port = netdev_priv(dev); +  	if (sset == ETH_SS_STATS) -		return ARRAY_SIZE(mvpp2_ethtool_regs); +		return MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs);  	return -EOPNOTSUPP;  }  static void mvpp2_mac_reset_assert(struct mvpp2_port *port)  { -	unsigned int i;  	u32 val; -	/* Read the GOP statistics to reset the hardware counters */ -	for (i = 0; i < ARRAY_SIZE(mvpp2_ethtool_regs); i++) -		mvpp2_read_count(port, &mvpp2_ethtool_regs[i]); -  	val = readl(port->base + MVPP2_GMAC_CTRL_2_REG) |  	      MVPP2_GMAC_PORT_RESET_MASK;  	writel(val, port->base + MVPP2_GMAC_CTRL_2_REG); @@ -4372,6 +4463,11 @@ static int mvpp2_port_init(struct mvpp2_port *port)  	if (err)  		goto err_free_percpu; +	/* Clear all port stats */ +	mvpp2_read_stats(port); +	memset(port->ethtool_stats, 0, +	       MVPP2_N_ETHTOOL_STATS(port->ntxqs, port->nrxqs) * sizeof(u64)); +  	return 0;  err_free_percpu: @@ -5053,7 +5149,7 @@ static int mvpp2_port_probe(struct platform_device *pdev,  	}  	port->ethtool_stats = devm_kcalloc(&pdev->dev, -					   ARRAY_SIZE(mvpp2_ethtool_regs), +					   MVPP2_N_ETHTOOL_STATS(ntxqs, nrxqs),  					   sizeof(u64), GFP_KERNEL);  	if (!port->ethtool_stats) {  		err = -ENOMEM; diff --git a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c index 392fd895f278..ae2240074d8e 100644 --- a/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c +++ b/drivers/net/ethernet/marvell/mvpp2/mvpp2_prs.c @@ -1905,8 +1905,7 @@ static int mvpp2_prs_ip6_init(struct mvpp2 *priv)  }  /* Find tcam entry with matched pair <vid,port> */ -static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid, -				    u16 mask) +static int mvpp2_prs_vid_range_find(struct mvpp2_port *port, u16 vid, u16 mask)  {  	unsigned char byte[2], enable[2];  	struct mvpp2_prs_entry pe; @@ -1914,13 +1913,13 @@ static int mvpp2_prs_vid_range_find(struct mvpp2 *priv, int pmap, u16 vid,  	int tid;  	/* Go through the all entries with MVPP2_PRS_LU_VID */ -	for (tid = MVPP2_PE_VID_FILT_RANGE_START; -	     tid <= MVPP2_PE_VID_FILT_RANGE_END; tid++) { -		if (!priv->prs_shadow[tid].valid || -		    priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID) +	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id); +	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) { +		if (!port->priv->prs_shadow[tid].valid || +		    port->priv->prs_shadow[tid].lu != MVPP2_PRS_LU_VID)  			continue; -		mvpp2_prs_init_from_hw(priv, &pe, tid); +		mvpp2_prs_init_from_hw(port->priv, &pe, tid);  		mvpp2_prs_tcam_data_byte_get(&pe, 2, &byte[0], &enable[0]);  		mvpp2_prs_tcam_data_byte_get(&pe, 3, &byte[1], &enable[1]); @@ -1950,7 +1949,7 @@ int mvpp2_prs_vid_entry_add(struct mvpp2_port *port, u16 vid)  	memset(&pe, 0, sizeof(pe));  	/* Scan TCAM and see if entry with this <vid,port> already exist */ -	tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, mask); +	tid = mvpp2_prs_vid_range_find(port, vid, mask);  	reg_val = mvpp2_read(priv, MVPP2_MH_REG(port->id));  	if (reg_val & MVPP2_DSA_EXTENDED) @@ -2008,7 +2007,7 @@ void mvpp2_prs_vid_entry_remove(struct mvpp2_port *port, u16 vid)  	int tid;  	/* Scan TCAM and see if entry with this <vid,port> already exist */ -	tid = mvpp2_prs_vid_range_find(priv, (1 << port->id), vid, 0xfff); +	tid = mvpp2_prs_vid_range_find(port, vid, 0xfff);  	/* No such entry */  	if (tid < 0) @@ -2026,8 +2025,10 @@ void mvpp2_prs_vid_remove_all(struct mvpp2_port *port)  	for (tid = MVPP2_PRS_VID_PORT_FIRST(port->id);  	     tid <= MVPP2_PRS_VID_PORT_LAST(port->id); tid++) { -		if (priv->prs_shadow[tid].valid) -			mvpp2_prs_vid_entry_remove(port, tid); +		if (priv->prs_shadow[tid].valid) { +			mvpp2_prs_hw_inv(priv, tid); +			priv->prs_shadow[tid].valid = false; +		}  	}  } diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 654ac534b10e..35a92fd2cf39 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only  /*   * New driver for Marvell Yukon chipset and SysKonnect Gigabit   * Ethernet adapters. Based on earlier sk98lin, e100 and @@ -8,19 +9,6 @@   * those should be done at higher levels.   *   * Copyright (C) 2004, 2005 Stephen Hemminger <shemminger@osdl.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt diff --git a/drivers/net/ethernet/marvell/sky2.c b/drivers/net/ethernet/marvell/sky2.c index 5adf307fbbfd..fe518c854d1f 100644 --- a/drivers/net/ethernet/marvell/sky2.c +++ b/drivers/net/ethernet/marvell/sky2.c @@ -1,3 +1,4 @@ +// SPDX-License-Identifier: GPL-2.0-only  /*   * New driver for Marvell Yukon 2 chipset.   * Based on earlier sk98lin, and skge driver. @@ -7,19 +8,6 @@   * those should be done at higher levels.   *   * Copyright (C) 2005 Stephen Hemminger <shemminger@osdl.org> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.   */  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt  | 

