14
14
#include <net/dsa.h>
15
15
#include "dsa_priv.h"
16
16
17
- /* For Ingress (Host -> KSZ), 2 bytes are added before FCS.
18
- * ---------------------------------------------------------------------------
19
- * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
20
- * ---------------------------------------------------------------------------
21
- * tag0 : Prioritization (not used now)
22
- * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
23
- *
24
- * For Egress (KSZ -> Host), 1 byte is added before FCS.
25
- * ---------------------------------------------------------------------------
26
- * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
27
- * ---------------------------------------------------------------------------
28
- * tag0 : zero-based value represents port
29
- * (eg, 0x00=port1, 0x02=port3, 0x06=port7)
30
- */
31
-
32
- #define KSZ_INGRESS_TAG_LEN 2
33
- #define KSZ_EGRESS_TAG_LEN 1
17
+ /* Typically only one byte is used for tail tag. */
18
+ #define KSZ_EGRESS_TAG_LEN 1
34
19
35
- static struct sk_buff * ksz_xmit (struct sk_buff * skb , struct net_device * dev )
20
+ static struct sk_buff * ksz_common_xmit (struct sk_buff * skb ,
21
+ struct net_device * dev , int len )
36
22
{
37
- struct dsa_port * dp = dsa_slave_to_port (dev );
38
23
struct sk_buff * nskb ;
39
24
int padlen ;
40
- u8 * tag ;
41
25
42
26
padlen = (skb -> len >= ETH_ZLEN ) ? 0 : ETH_ZLEN - skb -> len ;
43
27
44
- if (skb_tailroom (skb ) >= padlen + KSZ_INGRESS_TAG_LEN ) {
28
+ if (skb_tailroom (skb ) >= padlen + len ) {
45
29
/* Let dsa_slave_xmit() free skb */
46
30
if (__skb_put_padto (skb , skb -> len + padlen , false))
47
31
return NULL ;
48
32
49
33
nskb = skb ;
50
34
} else {
51
35
nskb = alloc_skb (NET_IP_ALIGN + skb -> len +
52
- padlen + KSZ_INGRESS_TAG_LEN , GFP_ATOMIC );
36
+ padlen + len , GFP_ATOMIC );
53
37
if (!nskb )
54
38
return NULL ;
55
39
skb_reserve (nskb , NET_IP_ALIGN );
@@ -70,34 +54,88 @@ static struct sk_buff *ksz_xmit(struct sk_buff *skb, struct net_device *dev)
70
54
consume_skb (skb );
71
55
}
72
56
73
- tag = skb_put (nskb , KSZ_INGRESS_TAG_LEN );
74
- tag [0 ] = 0 ;
75
- tag [1 ] = 1 << dp -> index ; /* destination port */
76
-
77
57
return nskb ;
78
58
}
79
59
80
- static struct sk_buff * ksz_rcv (struct sk_buff * skb , struct net_device * dev ,
81
- struct packet_type * pt )
60
+ static struct sk_buff * ksz_common_rcv (struct sk_buff * skb ,
61
+ struct net_device * dev ,
62
+ unsigned int port , unsigned int len )
82
63
{
83
- u8 * tag ;
84
- int source_port ;
64
+ skb -> dev = dsa_master_find_slave (dev , 0 , port );
65
+ if (!skb -> dev )
66
+ return NULL ;
85
67
86
- tag = skb_tail_pointer (skb ) - KSZ_EGRESS_TAG_LEN ;
68
+ pskb_trim_rcsum (skb , skb -> len - len ) ;
87
69
88
- source_port = tag [0 ] & 7 ;
70
+ return skb ;
71
+ }
89
72
90
- skb -> dev = dsa_master_find_slave (dev , 0 , source_port );
91
- if (!skb -> dev )
73
+ /*
74
+ * For Ingress (Host -> KSZ9477), 2 bytes are added before FCS.
75
+ * ---------------------------------------------------------------------------
76
+ * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|tag1(1byte)|FCS(4bytes)
77
+ * ---------------------------------------------------------------------------
78
+ * tag0 : Prioritization (not used now)
79
+ * tag1 : each bit represents port (eg, 0x01=port1, 0x02=port2, 0x10=port5)
80
+ *
81
+ * For Egress (KSZ9477 -> Host), 1 byte is added before FCS.
82
+ * ---------------------------------------------------------------------------
83
+ * DA(6bytes)|SA(6bytes)|....|Data(nbytes)|tag0(1byte)|FCS(4bytes)
84
+ * ---------------------------------------------------------------------------
85
+ * tag0 : zero-based value represents port
86
+ * (eg, 0x00=port1, 0x02=port3, 0x06=port7)
87
+ */
88
+
89
+ #define KSZ9477_INGRESS_TAG_LEN 2
90
+ #define KSZ9477_PTP_TAG_LEN 4
91
+ #define KSZ9477_PTP_TAG_INDICATION 0x80
92
+
93
+ #define KSZ9477_TAIL_TAG_OVERRIDE BIT(9)
94
+ #define KSZ9477_TAIL_TAG_LOOKUP BIT(10)
95
+
96
+ static struct sk_buff * ksz9477_xmit (struct sk_buff * skb ,
97
+ struct net_device * dev )
98
+ {
99
+ struct dsa_port * dp = dsa_slave_to_port (dev );
100
+ struct sk_buff * nskb ;
101
+ u16 * tag ;
102
+ u8 * addr ;
103
+
104
+ nskb = ksz_common_xmit (skb , dev , KSZ9477_INGRESS_TAG_LEN );
105
+ if (!nskb )
92
106
return NULL ;
93
107
94
- pskb_trim_rcsum (skb , skb -> len - KSZ_EGRESS_TAG_LEN );
108
+ /* Tag encoding */
109
+ tag = skb_put (nskb , KSZ9477_INGRESS_TAG_LEN );
110
+ addr = skb_mac_header (nskb );
95
111
96
- return skb ;
112
+ * tag = BIT (dp -> index );
113
+
114
+ if (is_link_local_ether_addr (addr ))
115
+ * tag |= KSZ9477_TAIL_TAG_OVERRIDE ;
116
+
117
+ * tag = cpu_to_be16 (* tag );
118
+
119
+ return nskb ;
120
+ }
121
+
122
+ static struct sk_buff * ksz9477_rcv (struct sk_buff * skb , struct net_device * dev ,
123
+ struct packet_type * pt )
124
+ {
125
+ /* Tag decoding */
126
+ u8 * tag = skb_tail_pointer (skb ) - KSZ_EGRESS_TAG_LEN ;
127
+ unsigned int port = tag [0 ] & 7 ;
128
+ unsigned int len = KSZ_EGRESS_TAG_LEN ;
129
+
130
+ /* Extra 4-bytes PTP timestamp */
131
+ if (tag [0 ] & KSZ9477_PTP_TAG_INDICATION )
132
+ len += KSZ9477_PTP_TAG_LEN ;
133
+
134
+ return ksz_common_rcv (skb , dev , port , len );
97
135
}
98
136
99
- const struct dsa_device_ops ksz_netdev_ops = {
100
- .xmit = ksz_xmit ,
101
- .rcv = ksz_rcv ,
102
- .overhead = KSZ_INGRESS_TAG_LEN ,
137
+ const struct dsa_device_ops ksz9477_netdev_ops = {
138
+ .xmit = ksz9477_xmit ,
139
+ .rcv = ksz9477_rcv ,
140
+ .overhead = KSZ9477_INGRESS_TAG_LEN ,
103
141
};
0 commit comments