mirror of
				https://kernel.googlesource.com/pub/scm/linux/kernel/git/torvalds/linux
				synced 2025-10-31 16:12:44 +10:00 
			
		
		
		
	net: dsa: tag_ksz: add tag handling for Microchip LAN937x
The Microchip LAN937X switches have a tagging protocol which is very similar to KSZ tagging. So that the implementation is added to tag_ksz.c and reused common APIs Signed-off-by: Prasanna Vengateshan <prasanna.vengateshan@microchip.com> Signed-off-by: Arun Ramadoss <arun.ramadoss@microchip.com> Reviewed-by: Vladimir Oltean <olteanv@gmail.com> Reviewed-by: Florian Fainelli <f.fainelli@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									8926d94e5c
								
							
						
					
					
						commit
						092f875131
					
				| @ -54,6 +54,7 @@ struct phylink_link_state; | ||||
| #define DSA_TAG_PROTO_RTL8_4_VALUE		24 | ||||
| #define DSA_TAG_PROTO_RTL8_4T_VALUE		25 | ||||
| #define DSA_TAG_PROTO_RZN1_A5PSW_VALUE		26 | ||||
| #define DSA_TAG_PROTO_LAN937X_VALUE		27 | ||||
| 
 | ||||
| enum dsa_tag_protocol { | ||||
| 	DSA_TAG_PROTO_NONE		= DSA_TAG_PROTO_NONE_VALUE, | ||||
| @ -83,6 +84,7 @@ enum dsa_tag_protocol { | ||||
| 	DSA_TAG_PROTO_RTL8_4		= DSA_TAG_PROTO_RTL8_4_VALUE, | ||||
| 	DSA_TAG_PROTO_RTL8_4T		= DSA_TAG_PROTO_RTL8_4T_VALUE, | ||||
| 	DSA_TAG_PROTO_RZN1_A5PSW	= DSA_TAG_PROTO_RZN1_A5PSW_VALUE, | ||||
| 	DSA_TAG_PROTO_LAN937X		= DSA_TAG_PROTO_LAN937X_VALUE, | ||||
| }; | ||||
| 
 | ||||
| struct dsa_switch; | ||||
|  | ||||
| @ -87,10 +87,10 @@ config NET_DSA_TAG_MTK | ||||
| 	  Mediatek switches. | ||||
| 
 | ||||
| config NET_DSA_TAG_KSZ | ||||
| 	tristate "Tag driver for Microchip 8795/9477/9893 families of switches" | ||||
| 	tristate "Tag driver for Microchip 8795/937x/9477/9893 families of switches" | ||||
| 	help | ||||
| 	  Say Y if you want to enable support for tagging frames for the | ||||
| 	  Microchip 8795/9477/9893 families of switches. | ||||
| 	  Microchip 8795/937x/9477/9893 families of switches. | ||||
| 
 | ||||
| config NET_DSA_TAG_OCELOT | ||||
| 	tristate "Tag driver for Ocelot family of switches, using NPI port" | ||||
|  | ||||
| @ -193,10 +193,69 @@ static const struct dsa_device_ops ksz9893_netdev_ops = { | ||||
| DSA_TAG_DRIVER(ksz9893_netdev_ops); | ||||
| MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_KSZ9893); | ||||
| 
 | ||||
| /* For xmit, 2 bytes are added before FCS.
 | ||||
|  * --------------------------------------------------------------------------- | ||||
|  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes) | ||||
|  * --------------------------------------------------------------------------- | ||||
|  * tag0 : represents tag override, lookup and valid | ||||
|  * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x80=port8) | ||||
|  * | ||||
|  * For rcv, 1 byte is added before FCS. | ||||
|  * --------------------------------------------------------------------------- | ||||
|  * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes) | ||||
|  * --------------------------------------------------------------------------- | ||||
|  * tag0 : zero-based value represents port | ||||
|  *	  (eg, 0x00=port1, 0x02=port3, 0x07=port8) | ||||
|  */ | ||||
| #define LAN937X_EGRESS_TAG_LEN		2 | ||||
| 
 | ||||
| #define LAN937X_TAIL_TAG_BLOCKING_OVERRIDE	BIT(11) | ||||
| #define LAN937X_TAIL_TAG_LOOKUP			BIT(12) | ||||
| #define LAN937X_TAIL_TAG_VALID			BIT(13) | ||||
| #define LAN937X_TAIL_TAG_PORT_MASK		7 | ||||
| 
 | ||||
| static struct sk_buff *lan937x_xmit(struct sk_buff *skb, | ||||
| 				    struct net_device *dev) | ||||
| { | ||||
| 	struct dsa_port *dp = dsa_slave_to_port(dev); | ||||
| 	const struct ethhdr *hdr = eth_hdr(skb); | ||||
| 	__be16 *tag; | ||||
| 	u16 val; | ||||
| 
 | ||||
| 	if (skb->ip_summed == CHECKSUM_PARTIAL && skb_checksum_help(skb)) | ||||
| 		return NULL; | ||||
| 
 | ||||
| 	tag = skb_put(skb, LAN937X_EGRESS_TAG_LEN); | ||||
| 
 | ||||
| 	val = BIT(dp->index); | ||||
| 
 | ||||
| 	if (is_link_local_ether_addr(hdr->h_dest)) | ||||
| 		val |= LAN937X_TAIL_TAG_BLOCKING_OVERRIDE; | ||||
| 
 | ||||
| 	/* Tail tag valid bit - This bit should always be set by the CPU */ | ||||
| 	val |= LAN937X_TAIL_TAG_VALID; | ||||
| 
 | ||||
| 	put_unaligned_be16(val, tag); | ||||
| 
 | ||||
| 	return skb; | ||||
| } | ||||
| 
 | ||||
| static const struct dsa_device_ops lan937x_netdev_ops = { | ||||
| 	.name	= "lan937x", | ||||
| 	.proto	= DSA_TAG_PROTO_LAN937X, | ||||
| 	.xmit	= lan937x_xmit, | ||||
| 	.rcv	= ksz9477_rcv, | ||||
| 	.needed_tailroom = LAN937X_EGRESS_TAG_LEN, | ||||
| }; | ||||
| 
 | ||||
| DSA_TAG_DRIVER(lan937x_netdev_ops); | ||||
| MODULE_ALIAS_DSA_TAG_DRIVER(DSA_TAG_PROTO_LAN937X); | ||||
| 
 | ||||
| static struct dsa_tag_driver *dsa_tag_driver_array[] = { | ||||
| 	&DSA_TAG_DRIVER_NAME(ksz8795_netdev_ops), | ||||
| 	&DSA_TAG_DRIVER_NAME(ksz9477_netdev_ops), | ||||
| 	&DSA_TAG_DRIVER_NAME(ksz9893_netdev_ops), | ||||
| 	&DSA_TAG_DRIVER_NAME(lan937x_netdev_ops), | ||||
| }; | ||||
| 
 | ||||
| module_dsa_tag_drivers(dsa_tag_driver_array); | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user