@@ -439,6 +439,62 @@ static int otx2_tc_parse_actions(struct otx2_nic *nic,
439439	return  0 ;
440440}
441441
442+ static  int  otx2_tc_process_vlan (struct  otx2_nic  * nic , struct  flow_msg  * flow_spec ,
443+ 				struct  flow_msg  * flow_mask , struct  flow_rule  * rule ,
444+ 				struct  npc_install_flow_req  * req , bool  is_inner )
445+ {
446+ 	struct  flow_match_vlan  match ;
447+ 	u16  vlan_tci , vlan_tci_mask ;
448+ 
449+ 	if  (is_inner )
450+ 		flow_rule_match_cvlan (rule , & match );
451+ 	else 
452+ 		flow_rule_match_vlan (rule , & match );
453+ 
454+ 	if  (!eth_type_vlan (match .key -> vlan_tpid )) {
455+ 		netdev_err (nic -> netdev , "vlan tpid 0x%x not supported\n" ,
456+ 			   ntohs (match .key -> vlan_tpid ));
457+ 		return  - EOPNOTSUPP ;
458+ 	}
459+ 
460+ 	if  (!match .mask -> vlan_id ) {
461+ 		struct  flow_action_entry  * act ;
462+ 		int  i ;
463+ 
464+ 		flow_action_for_each (i , act , & rule -> action ) {
465+ 			if  (act -> id  ==  FLOW_ACTION_DROP ) {
466+ 				netdev_err (nic -> netdev ,
467+ 					   "vlan tpid 0x%x with vlan_id %d is not supported for DROP rule.\n" ,
468+ 					   ntohs (match .key -> vlan_tpid ), match .key -> vlan_id );
469+ 				return  - EOPNOTSUPP ;
470+ 			}
471+ 		}
472+ 	}
473+ 
474+ 	if  (match .mask -> vlan_id  || 
475+ 	    match .mask -> vlan_dei  || 
476+ 	    match .mask -> vlan_priority ) {
477+ 		vlan_tci  =  match .key -> vlan_id  |
478+ 			   match .key -> vlan_dei  << 12  |
479+ 			   match .key -> vlan_priority  << 13 ;
480+ 
481+ 		vlan_tci_mask  =  match .mask -> vlan_id  |
482+ 				match .mask -> vlan_dei  << 12  |
483+ 				match .mask -> vlan_priority  << 13 ;
484+ 		if  (is_inner ) {
485+ 			flow_spec -> vlan_itci  =  htons (vlan_tci );
486+ 			flow_mask -> vlan_itci  =  htons (vlan_tci_mask );
487+ 			req -> features  |= BIT_ULL (NPC_INNER_VID );
488+ 		} else  {
489+ 			flow_spec -> vlan_tci  =  htons (vlan_tci );
490+ 			flow_mask -> vlan_tci  =  htons (vlan_tci_mask );
491+ 			req -> features  |= BIT_ULL (NPC_OUTER_VID );
492+ 		}
493+ 	}
494+ 
495+ 	return  0 ;
496+ }
497+ 
442498static  int  otx2_tc_prepare_flow (struct  otx2_nic  * nic , struct  otx2_tc_flow  * node ,
443499				struct  flow_cls_offload  * f ,
444500				struct  npc_install_flow_req  * req )
@@ -458,6 +514,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
458514	      BIT_ULL (FLOW_DISSECTOR_KEY_BASIC ) |
459515	      BIT_ULL (FLOW_DISSECTOR_KEY_ETH_ADDRS ) |
460516	      BIT_ULL (FLOW_DISSECTOR_KEY_VLAN ) |
517+ 	      BIT (FLOW_DISSECTOR_KEY_CVLAN ) |
461518	      BIT_ULL (FLOW_DISSECTOR_KEY_IPV4_ADDRS ) |
462519	      BIT_ULL (FLOW_DISSECTOR_KEY_IPV6_ADDRS ) |
463520	      BIT_ULL (FLOW_DISSECTOR_KEY_PORTS ) |
@@ -591,47 +648,19 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
591648	}
592649
593650	if  (flow_rule_match_key (rule , FLOW_DISSECTOR_KEY_VLAN )) {
594- 		struct  flow_match_vlan  match ;
595- 		u16  vlan_tci , vlan_tci_mask ;
596- 
597- 		flow_rule_match_vlan (rule , & match );
598- 
599- 		if  (ntohs (match .key -> vlan_tpid ) !=  ETH_P_8021Q ) {
600- 			netdev_err (nic -> netdev , "vlan tpid 0x%x not supported\n" ,
601- 				   ntohs (match .key -> vlan_tpid ));
602- 			return  - EOPNOTSUPP ;
603- 		}
651+ 		int  ret ;
604652
605- 		if  (!match .mask -> vlan_id ) {
606- 			struct  flow_action_entry  * act ;
607- 			int  i ;
608- 
609- 			flow_action_for_each (i , act , & rule -> action ) {
610- 				if  (act -> id  ==  FLOW_ACTION_DROP ) {
611- 					netdev_err (nic -> netdev ,
612- 						   "vlan tpid 0x%x with vlan_id %d is not supported for DROP rule.\n" ,
613- 						   ntohs (match .key -> vlan_tpid ),
614- 						   match .key -> vlan_id );
615- 					return  - EOPNOTSUPP ;
616- 				}
617- 			}
618- 		}
619- 
620- 		if  (match .mask -> vlan_id  || 
621- 		    match .mask -> vlan_dei  || 
622- 		    match .mask -> vlan_priority ) {
623- 			vlan_tci  =  match .key -> vlan_id  |
624- 				   match .key -> vlan_dei  << 12  |
625- 				   match .key -> vlan_priority  << 13 ;
653+ 		ret  =  otx2_tc_process_vlan (nic , flow_spec , flow_mask , rule , req , false);
654+ 		if  (ret )
655+ 			return  ret ;
656+ 	}
626657
627- 			vlan_tci_mask  =  match .mask -> vlan_id  |
628- 					match .mask -> vlan_dei  << 12  |
629- 					match .mask -> vlan_priority  << 13 ;
658+ 	if  (flow_rule_match_key (rule , FLOW_DISSECTOR_KEY_CVLAN )) {
659+ 		int  ret ;
630660
631- 			flow_spec -> vlan_tci  =  htons (vlan_tci );
632- 			flow_mask -> vlan_tci  =  htons (vlan_tci_mask );
633- 			req -> features  |= BIT_ULL (NPC_OUTER_VID );
634- 		}
661+ 		ret  =  otx2_tc_process_vlan (nic , flow_spec , flow_mask , rule , req , true);
662+ 		if  (ret )
663+ 			return  ret ;
635664	}
636665
637666	if  (flow_rule_match_key (rule , FLOW_DISSECTOR_KEY_IPV4_ADDRS )) {
0 commit comments