AR8327/AR8337 VLAN ID > 128 not working & tagged and untagged on same port not working [Fixed]

AR8327/AR8337 VLAN ID > 128 not working & tagged and untagged on same port not working [Fixed]

Issue Description

swconfig could not set VLANID > 128

  1. $ swconfig dev switch0 vlan 100 set ports '0t 1' 
  2. ok 
  3. # swconfig dev switch0 vlan 4090 set ports '0t 1' 
  4. failed 

switch config

swconfig

  1. root@oakridge:/proc# swconfig  
  2. swconfig dev <dev> [port <port>|vlan <vlan>] (help|set <key> <value>|get <key>|load <config>|show) 
  3. root@oakridge:/proc# swconfig dev eth0 show 
  4. Global attributes: 
  5. enable_vlan: 1 
  6. max_frame_size: 1528 
  7. dump_arl: MAC: 78:4f:43:53:c5:e3 PORTMAP: 0x04 
  8. MAC: fc:ad:0f:06:9f:90 PORTMAP: 0x01 
  9. MAC: e4:a4:71:fb:49:10 PORTMAP: 0x04 
  10. MAC: f4:0f:24:2d:da:08 PORTMAP: 0x04 
  11. MAC: a4:f1:e8:8e:d9:ce PORTMAP: 0x04 
  12. MAC: f4:0f:24:28:cb:ba PORTMAP: 0x04 
  13. MAC: 00:ae:0c:2b:1c:ed PORTMAP: 0x04 
  14. MAC: e0:1c:41:e8:ff:80 PORTMAP: 0x04 
  15. MAC: e0:1c:41:e8:ff:86 PORTMAP: 0x04 
  16. MAC: a8:88:08:ea:ce:2b PORTMAP: 0x04 
  17. MAC: 00:ec:ac:ce:80:8c PORTMAP: 0x04 
  18. MAC: 98:e7:f4:96:80:1e PORTMAP: 0x04 
  19. MAC: 38:a4:ed:a1:db:aa PORTMAP: 0x04 
  20. MAC: 00:e0:4c:68:03:b7 PORTMAP: 0x04 
  21. MAC: 70:14:a6:cd:8a:c2 PORTMAP: 0x04 
  22. MAC: fc:ad:0f:06:a5:20 PORTMAP: 0x04 
  23.  
  24. igmp_snooping: ??? 
  25. Port 0
  26. mib: Port 0 MIB counters 
  27. RxBroad : 41 
  28. RxPause : 0 
  29. RxMulti : 35 
  30. RxFcsErr : 0 
  31. RxAlignErr : 0 
  32. RxRunt : 0 
  33. RxFragment : 0 
  34. Rx64Byte : 181 
  35. Rx128Byte : 263 
  36. Rx256Byte : 173 
  37. Rx512Byte : 7 
  38. Rx1024Byte : 0 
  39. Rx1518Byte : 0 
  40. RxMaxByte : 0 
  41. RxTooLong : 0 
  42. RxGoodByte : 73830 
  43. RxBadByte : 0 
  44. RxOverFlow : 0 
  45. Filtered : 30 
  46. TxBroad : 3373 
  47. TxPause : 0 
  48. TxMulti : 3821 
  49. TxUnderRun : 0 
  50. Tx64Byte : 0 
  51. Tx128Byte : 4875 
  52. Tx256Byte : 1551 
  53. Tx512Byte : 1105 
  54. Tx1024Byte : 159 
  55. Tx1518Byte : 21 
  56. TxMaxByte : 1 
  57. TxOverSize : 0 
  58. TxByte : 1233825 
  59. TxCollision : 0 
  60. TxAbortCol : 0 
  61. TxMultiCol : 0 
  62. TxSingleCol : 0 
  63. TxExcDefer : 0 
  64. TxDefer : 0 
  65. TxLateCol : 0 
  66.  
  67. pvid: 0 
  68. link: port:0 link:up speed:1000baseT full-duplex txflow rxflow  
  69. Port 1
  70. mib: Port 1 MIB counters 
  71. RxBroad : 0 
  72. RxPause : 0 
  73. RxMulti : 0 
  74. RxFcsErr : 0 
  75. RxAlignErr : 0 
  76. RxRunt : 0 
  77. RxFragment : 0 
  78. Rx64Byte : 0 
  79. Rx128Byte : 0 
  80. Rx256Byte : 0 
  81. Rx512Byte : 0 
  82. Rx1024Byte : 0 
  83. Rx1518Byte : 0 
  84. RxMaxByte : 0 
  85. RxTooLong : 0 
  86. RxGoodByte : 0 
  87. RxBadByte : 0 
  88. RxOverFlow : 0 
  89. Filtered : 0 
  90. TxBroad : 0 
  91. TxPause : 0 
  92. TxMulti : 0 
  93. TxUnderRun : 0 
  94. Tx64Byte : 0 
  95. Tx128Byte : 0 
  96. Tx256Byte : 0 
  97. Tx512Byte : 0 
  98. Tx1024Byte : 0 
  99. Tx1518Byte : 0 
  100. TxMaxByte : 0 
  101. TxOverSize : 0 
  102. TxByte : 0 
  103. TxCollision : 0 
  104. TxAbortCol : 0 
  105. TxMultiCol : 0 
  106. TxSingleCol : 0 
  107. TxExcDefer : 0 
  108. TxDefer : 0 
  109. TxLateCol : 0 
  110.  
  111. pvid: 1 
  112. link: port:1 link:down 
  113. Port 2
  114. mib: Port 2 MIB counters 
  115. RxBroad : 3376 
  116. RxPause : 0 
  117. RxMulti : 3824 
  118. RxFcsErr : 0 
  119. RxAlignErr : 0 
  120. RxRunt : 0 
  121. RxFragment : 0 
  122. Rx64Byte : 1545 
  123. Rx128Byte : 3340 
  124. Rx256Byte : 1592 
  125. Rx512Byte : 1065 
  126. Rx1024Byte : 156 
  127. Rx1518Byte : 22 
  128. RxMaxByte : 0 
  129. RxTooLong : 0 
  130. RxGoodByte : 1204383 
  131. RxBadByte : 0 
  132. RxOverFlow : 0 
  133. Filtered : 8 
  134. TxBroad : 36 
  135. TxPause : 0 
  136. TxMulti : 10 
  137. TxUnderRun : 0 
  138. Tx64Byte : 263 
  139. Tx128Byte : 159 
  140. Tx256Byte : 168 
  141. Tx512Byte : 4 
  142. Tx1024Byte : 0 
  143. Tx1518Byte : 0 
  144. TxMaxByte : 0 
  145. TxOverSize : 0 
  146. TxByte : 68312 
  147. TxCollision : 0 
  148. TxAbortCol : 0 
  149. TxMultiCol : 0 
  150. TxSingleCol : 0 
  151. TxExcDefer : 0 
  152. TxDefer : 0 
  153. TxLateCol : 0 
  154.  
  155. pvid: 2 
  156. link: port:2 link:up speed:1000baseT full-duplex auto 
  157. Port 3
  158. mib: Port 3 MIB counters 
  159. RxBroad : 0 
  160. RxPause : 0 
  161. RxMulti : 0 
  162. RxFcsErr : 0 
  163. RxAlignErr : 0 
  164. RxRunt : 0 
  165. RxFragment : 0 
  166. Rx64Byte : 0 
  167. Rx128Byte : 0 
  168. Rx256Byte : 0 
  169. Rx512Byte : 0 
  170. Rx1024Byte : 0 
  171. Rx1518Byte : 0 
  172. RxMaxByte : 0 
  173. RxTooLong : 0 
  174. RxGoodByte : 0 
  175. RxBadByte : 0 
  176. RxOverFlow : 0 
  177. Filtered : 0 
  178. TxBroad : 0 
  179. TxPause : 0 
  180. TxMulti : 0 
  181. TxUnderRun : 0 
  182. Tx64Byte : 0 
  183. Tx128Byte : 0 
  184. Tx256Byte : 0 
  185. Tx512Byte : 0 
  186. Tx1024Byte : 0 
  187. Tx1518Byte : 0 
  188. TxMaxByte : 0 
  189. TxOverSize : 0 
  190. TxByte : 0 
  191. TxCollision : 0 
  192. TxAbortCol : 0 
  193. TxMultiCol : 0 
  194. TxSingleCol : 0 
  195. TxExcDefer : 0 
  196. TxDefer : 0 
  197. TxLateCol : 0 
  198.  
  199. pvid: 0 
  200. link: port:3 link:down 
  201. Port 4
  202. mib: Port 4 MIB counters 
  203. RxBroad : 0 
  204. RxPause : 0 
  205. RxMulti : 0 
  206. RxFcsErr : 0 
  207. RxAlignErr : 0 
  208. RxRunt : 0 
  209. RxFragment : 0 
  210. Rx64Byte : 0 
  211. Rx128Byte : 0 
  212. Rx256Byte : 0 
  213. Rx512Byte : 0 
  214. Rx1024Byte : 0 
  215. Rx1518Byte : 0 
  216. RxMaxByte : 0 
  217. RxTooLong : 0 
  218. RxGoodByte : 0 
  219. RxBadByte : 0 
  220. RxOverFlow : 0 
  221. Filtered : 0 
  222. TxBroad : 0 
  223. TxPause : 0 
  224. TxMulti : 0 
  225. TxUnderRun : 0 
  226. Tx64Byte : 0 
  227. Tx128Byte : 0 
  228. Tx256Byte : 0 
  229. Tx512Byte : 0 
  230. Tx1024Byte : 0 
  231. Tx1518Byte : 0 
  232. TxMaxByte : 0 
  233. TxOverSize : 0 
  234. TxByte : 0 
  235. TxCollision : 0 
  236. TxAbortCol : 0 
  237. TxMultiCol : 0 
  238. TxSingleCol : 0 
  239. TxExcDefer : 0 
  240. TxDefer : 0 
  241. TxLateCol : 0 
  242.  
  243. pvid: 0 
  244. link: port:4 link:down 
  245. Port 5
  246. mib: Port 5 MIB counters 
  247. RxBroad : 0 
  248. RxPause : 0 
  249. RxMulti : 0 
  250. RxFcsErr : 0 
  251. RxAlignErr : 0 
  252. RxRunt : 0 
  253. RxFragment : 0 
  254. Rx64Byte : 0 
  255. Rx128Byte : 0 
  256. Rx256Byte : 0 
  257. Rx512Byte : 0 
  258. Rx1024Byte : 0 
  259. Rx1518Byte : 0 
  260. RxMaxByte : 0 
  261. RxTooLong : 0 
  262. RxGoodByte : 0 
  263. RxBadByte : 0 
  264. RxOverFlow : 0 
  265. Filtered : 0 
  266. TxBroad : 0 
  267. TxPause : 0 
  268. TxMulti : 0 
  269. TxUnderRun : 0 
  270. Tx64Byte : 0 
  271. Tx128Byte : 0 
  272. Tx256Byte : 0 
  273. Tx512Byte : 0 
  274. Tx1024Byte : 0 
  275. Tx1518Byte : 0 
  276. TxMaxByte : 0 
  277. TxOverSize : 0 
  278. TxByte : 0 
  279. TxCollision : 0 
  280. TxAbortCol : 0 
  281. TxMultiCol : 0 
  282. TxSingleCol : 0 
  283. TxExcDefer : 0 
  284. TxDefer : 0 
  285. TxLateCol : 0 
  286.  
  287. pvid: 0 
  288. link: port:5 link:down 
  289. Port 6
  290. mib: Port 6 MIB counters 
  291. RxBroad : 0 
  292. RxPause : 0 
  293. RxMulti : 0 
  294. RxFcsErr : 0 
  295. RxAlignErr : 0 
  296. RxRunt : 0 
  297. RxFragment : 0 
  298. Rx64Byte : 0 
  299. Rx128Byte : 0 
  300. Rx256Byte : 0 
  301. Rx512Byte : 0 
  302. Rx1024Byte : 0 
  303. Rx1518Byte : 0 
  304. RxMaxByte : 0 
  305. RxTooLong : 0 
  306. RxGoodByte : 0 
  307. RxBadByte : 0 
  308. RxOverFlow : 0 
  309. Filtered : 0 
  310. TxBroad : 0 
  311. TxPause : 0 
  312. TxMulti : 0 
  313. TxUnderRun : 0 
  314. Tx64Byte : 0 
  315. Tx128Byte : 0 
  316. Tx256Byte : 0 
  317. Tx512Byte : 0 
  318. Tx1024Byte : 0 
  319. Tx1518Byte : 0 
  320. TxMaxByte : 0 
  321. TxOverSize : 0 
  322. TxByte : 0 
  323. TxCollision : 0 
  324. TxAbortCol : 0 
  325. TxMultiCol : 0 
  326. TxSingleCol : 0 
  327. TxExcDefer : 0 
  328. TxDefer : 0 
  329. TxLateCol : 0 
  330.  
  331. pvid: 0 
  332. link: port:6 link:up speed:1000baseT full-duplex  
  333. VLAN 1
  334. vid: 1 
  335. ports: 0t 1  
  336. VLAN 2
  337. vid: 2 
  338. ports: 0t 2  

Analysis

AR8327 driver locates kernel/drivers/net/phy/ar8216.c
in order to compatible to old AR8X16 device, max vlan id defined to 128.
give the patch here, in order to support VLANID > 128

  1. diff --git a/drivers/net/phy/ar8216.c b/drivers/net/phy/ar8216.c 
  2. index 864b778..3e8ceed 100755 
  3. --- a/drivers/net/phy/ar8216.c 
  4. +++ b/drivers/net/phy/ar8216.c 
  5. @@ -41,7 +41,12 @@ 
  6. #endif 
  7.  
  8. /* size of the vlan table */ 
  9. +#if OK_PATCH 
  10. +/* for AR8327 */ 
  11. +#define AR8X16_MAX_VLANS 4096 
  12. +#else /* !OK_PATCH */ 
  13. #define AR8X16_MAX_VLANS 128 
  14. +#endif /* OK_PATCH */ 
  15. #define AR8X16_PROBE_RETRIES 10 
  16. #define AR8X16_MAX_PORTS 8 

tagged and untagged on the same port not working

analysis

  1. diff --git a/drivers/net/phy/ar8216.c b/drivers/net/phy/ar8216.c 
  2. index 3e8ceed..33c873c 100755 
  3. --- a/drivers/net/phy/ar8216.c 
  4. +++ b/drivers/net/phy/ar8216.c 
  5. @@ -84,7 +84,11 @@ struct ar8xxx_chip { 
  6. u32 (*read_port_status)(struct ar8216_priv *priv, int port); 
  7. int (*atu_flush)(struct ar8216_priv *priv); 
  8. void (*vtu_flush)(struct ar8216_priv *priv); 
  9. +#if OK_PATCH 
  10. + void (*vtu_load_vlan)(struct ar8216_priv *priv, u32 vlan); 
  11. +#else 
  12. void (*vtu_load_vlan)(struct ar8216_priv *priv, u32 vid, u32 port_mask); 
  13. +#endif 
  14. int (*atu_dump)(struct ar8216_priv *priv); 
  15. int (*igmp_snooping)(struct ar8216_priv *priv, u32 enable); 
  16.  
  17. @@ -124,7 +128,12 @@ struct ar8216_priv { 
  18. bool vlan; 
  19. u16 vlan_id[AR8X16_MAX_VLANS]; 
  20. u8 vlan_table[AR8X16_MAX_VLANS]; 
  21. - u8 vlan_tagged; 
  22. +#if OK_PATCH 
  23. + u8 vlan_tagged_8216; 
  24. + u8 vlan_tagged_8327[AR8X16_MAX_VLANS]; 
  25. +#else 
  26. + u8 vlan_tagged; 
  27. +#endif 
  28. u16 pvid[AR8X16_MAX_PORTS]; 
  29. /* if set, the vlan interface is UP */ 
  30. u8 vlan_status[AR8X16_MAX_VLANS]; 
  31. @@ -631,7 +640,11 @@ ar8216_mangle_rx(struct net_device *dev, struct sk_buff *skb) 
  32. port = buf[0] & 0xf; 
  33.  
  34. /* no need to fix up packets coming from a tagged source */ 
  35. +#if OK_PATCH 
  36. + if (priv->vlan_tagged_8216 & (1 << port)) 
  37. +#else 
  38. if (priv->vlan_tagged & (1 << port)) 
  39. +#endif 
  40. return; 
  41.  
  42. /* lookup port vid from local table, the switch passes an invalid vlan id */ 
  43. @@ -685,9 +698,17 @@ ar8216_vtu_flush(struct ar8216_priv *priv) 

  44.  
  45. static void 
  46. +#if OK_PATCH 
  47. +ar8216_vtu_load_vlan(struct ar8216_priv *priv, u32 vlan) 
  48. +#else 
  49. ar8216_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  50. +#endif 

  51. - u32 op; 
  52. + u32 op; 
  53. +#if OK_PATCH 
  54. + u32 vid = priv->vlan_id[vlan]; 
  55. + u32 port_mask = priv->vlan_table[vlan]; 
  56. +#endif 
  57.  
  58. op = AR8216_VTU_OP_LOAD | (vid << AR8216_VTU_VID_S); 
  59. ar8216_vtu_op(priv, op, port_mask); 
  60. @@ -1609,11 +1630,20 @@ ar8327_vtu_flush(struct ar8216_priv *priv) 

  61.  
  62. static void 
  63. +#if OK_PATCH 
  64. +ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vlan) 
  65. +#else 
  66. ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  67. +#endif 

  68. u32 op; 
  69. u32 val; 
  70. - int i; 
  71. + int i; 
  72. +#if OK_PATCH 
  73. + u32 vid = priv->vlan_id[vlan]; 
  74. + u32 port_mask = priv->vlan_table[vlan]; 
  75. + u32 tagged = priv->vlan_tagged_8327[vlan]; 
  76. +#endif 
  77.  
  78. op = AR8327_VTU_FUNC1_OP_LOAD | (vid << AR8327_VTU_FUNC1_VID_S); 
  79. val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL; 
  80. @@ -1622,9 +1652,13 @@ ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  81.  
  82. if ((port_mask & BIT(i)) == 0) 
  83. mode = AR8327_VTU_FUNC0_EG_MODE_NOT; 
  84. - else if (priv->vlan == 0) 
  85. - mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; 
  86. - else if (priv->vlan_tagged & BIT(i)) 
  87. + else if (priv->vlan == 0) 
  88. + mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; 
  89. +#if OK_PATCH 
  90. + else if (tagged& BIT(i)) 
  91. +#else 
  92. + else if (priv->vlan_tagged & BIT(i)) 
  93. +#endif 
  94. mode = AR8327_VTU_FUNC0_EG_MODE_TAG; 
  95. else 
  96. mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG; 
  97. @@ -1638,13 +1672,26 @@ static void 
  98. ar8327_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress, 
  99. u32 members, u32 pvid) 

  100. - u32 t; 
  101. - u32 mode; 
  102. + u32 t; 
  103. + u32 mode; 
  104. + 
  105. +#if OK_PATCH 
  106. + if (priv->vlan) { 
  107. + pvid = priv->vlan_id[priv->pvid[port]]; 
  108. + mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
  109. + ingress = AR8216_IN_SECURE; 
  110. + } else { 
  111. + pvid = port; 
  112. + mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH; 
  113. + ingress = AR8216_IN_PORT_ONLY; 
  114. + } 
  115. +#endif 
  116.  
  117. t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S; 
  118. t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S; 
  119. priv->write(priv, AR8327_REG_PORT_VLAN0(port), t); 
  120.  
  121. +#if !OK_PATCH 
  122. mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
  123. switch (egress) { 
  124. case AR8216_OUT_KEEP: 
  125. @@ -1657,6 +1704,7 @@ ar8327_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress, 
  126. mode = AR8327_PORT_VLAN1_OUT_MODE_TAG; 
  127. break; 

  128. +#endif 
  129.  
  130. t = AR8327_PORT_VLAN1_PORT_VLAN_PROP; 
  131. t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S; 
  132. @@ -1813,22 +1861,40 @@ ar8216_sw_get_port_link(struct switch_dev *dev, int port, 

  133.  
  134. static int 
  135. +#if OK_PATCH 
  136. +ar8xxx_sw_get_ports(struct switch_val *val, int ports, u8 port_mask, u8 tagged) 
  137. +#else 
  138. ar8216_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
  139. +#endif 

  140. +#if !OK_PATCH 
  141. struct ar8216_priv *priv = to_ar8216(dev); 
  142. u8 ports = priv->vlan_table[val->port_vlan]; 
  143. +#endif 
  144. int i; 
  145.  
  146. val->len = 0; 
  147. +#if OK_PATCH 
  148. + for (i = 0; i < ports; i++) { 
  149. +#else 
  150. for (i = 0; i < dev->ports; i++) { 
  151. +#endif 
  152. struct switch_port *p; 
  153.  
  154. - if (!(ports & (1 << i))) 
  155. - continue; 
  156. +#if OK_PATCH 
  157. + if (!(port_mask & (1 << i))) 
  158. +#else 
  159. + if (!(ports & (1 << i))) 
  160. +#endif 
  161. + continue; 
  162.  
  163. p = &val->value.ports[val->len++]; 
  164. p->id = i; 
  165. - if (priv->vlan_tagged & (1 << i)) 
  166. +#if OK_PATCH 
  167. + if (tagged & BIT(i)) 
  168. +#else 
  169. + if (priv->vlan_tagged & (1 << i)) 
  170. +#endif 
  171. p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); 
  172. else 
  173. p->flags = 0; 
  174. @@ -1840,17 +1906,42 @@ static int 
  175. ar8216_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 

  176. struct ar8216_priv *priv = to_ar8216(dev); 
  177. - u8 *vt = &priv->vlan_table[val->port_vlan]; 
  178. + u8 *vt = &priv->vlan_table[val->port_vlan]; 
  179. +#if OK_PATCH 
  180. + u8 *tagged = &priv->vlan_tagged_8216; 
  181. +#endif 
  182. int i, j; 
  183.  
  184. *vt = 0; 
  185. for (i = 0; i < val->len; i++) { 
  186. struct switch_port *p = &val->value.ports[i]; 
  187.  
  188. +#if OK_PATCH 
  189. + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
  190. + 
  191. + /* if port was untagged before then 
  192. + * remove him from other vlans */ 
  193. + if(*tagged & BIT(p->id)){ 
  194. + for (j = 0; j < AR8X16_MAX_VLANS; j++) { 
  195. + if (j == val->port_vlan) 
  196. + continue; 
  197. + 
  198. + priv->vlan_table[j] &= ~(BIT(p->id)); 
  199. + } 
  200. + } 
  201. + 
  202. + *tagged |= BIT(p->id); 
  203. + 
  204. +#else 
  205. if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { 
  206. priv->vlan_tagged |= (1 << p->id); 
  207. +#endif 
  208. } else { 
  209. - priv->vlan_tagged &= ~(1 << p->id); 
  210. +#if OK_PATCH 
  211. + *tagged &= ~(BIT(p->id)); 
  212. +#else 
  213. + priv->vlan_tagged &= ~(1 << p->id); 
  214. +#endif 
  215. priv->pvid[p->id] = val->port_vlan; 
  216.  
  217. /* make sure that an untagged port does not 
  218. @@ -1867,6 +1958,54 @@ ar8216_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
  219. return 0; 

  220.  
  221. +#if OK_PATCH 
  222. + static int 
  223. +ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
  224. +{ 
  225. + struct ar8216_priv *priv = to_ar8216(dev); 
  226. + u8 *vt = &priv->vlan_table[val->port_vlan]; 
  227. + u8 *vlan_tagged = priv->vlan_tagged_8327; 
  228. + u8 *tagged = &vlan_tagged[val->port_vlan]; 
  229. + 
  230. + int i; 
  231. + 
  232. + *vt = 0; 
  233. + *tagged = 0; 
  234. + for (i = 0; i < val->len; i++) { 
  235. + struct switch_port *p = &val->value.ports[i]; 
  236. + 
  237. + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
  238. + *tagged |= BIT(p->id); 
  239. + } else { 
  240. + priv->pvid[p->id] = val->port_vlan; 
  241. + } 
  242. + 
  243. + *vt |= BIT(p->id); 
  244. + } 
  245. + return 0; 
  246. +} 
  247. + static int 
  248. +ar8216_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
  249. +{ 
  250. + int ports = dev->ports; 
  251. + struct ar8216_priv *priv = to_ar8216(dev); 
  252. + u8 port_mask = priv->vlan_table[val->port_vlan]; 
  253. + u8 tagged = priv->vlan_tagged_8216; 
  254. + 
  255. + return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
  256. +} 
  257. + static int 
  258. +ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
  259. +{ 
  260. + int ports = dev->ports; 
  261. + struct ar8216_priv *priv = to_ar8216(dev); 
  262. + u8 port_mask = priv->vlan_table[val->port_vlan]; 
  263. + u8 tagged = priv->vlan_tagged_8327[val->port_vlan]; 
  264. + 
  265. + return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
  266. +} 
  267. +#endif 
  268. + 
  269. static int 
  270. ar8216_sw_hw_apply(struct switch_dev *dev) 

  271. @@ -1894,8 +2033,12 @@ ar8216_sw_hw_apply(struct switch_dev *dev) 
  272. portmask[i] |= vp & ~mask; 

  273.  
  274. - priv->chip->vtu_load_vlan(priv, priv->vlan_id[j], 
  275. - priv->vlan_table[j]); 
  276. +#if OK_PATCH 
  277. + priv->chip->vtu_load_vlan(priv, j); 
  278. +#else 
  279. + priv->chip->vtu_load_vlan(priv, priv->vlan_id[j], 
  280. + priv->vlan_table[j]); 
  281. +#endif 

  282. } else { 
  283. /* vlan disabled: 
  284. @@ -1916,7 +2059,11 @@ ar8216_sw_hw_apply(struct switch_dev *dev) 
  285.  
  286. if (priv->vlan) { 
  287. pvid = priv->vlan_id[priv->pvid[i]]; 
  288. +#if OK_PATCH 
  289. + if (priv->vlan_tagged_8216 & (1 << i)) 
  290. +#else 
  291. if (priv->vlan_tagged & (1 << i)) 
  292. +#endif 
  293. egress = AR8216_OUT_ADD_VLAN; 
  294. else 
  295. egress = AR8216_OUT_STRIP_VLAN; 
  296. @@ -2267,6 +2414,30 @@ static const struct switch_dev_ops ar8216_sw_ops = { 
  297. .set_reg_val = ar8216_sw_set_reg_val, 
  298. }; 
  299.  
  300. +#if OK_PATCH 
  301. +static const struct switch_dev_ops ar8327_sw_ops = { 
  302. + .attr_global = { 
  303. + .attr = ar8216_globals, 
  304. + .n_attr = ARRAY_SIZE(ar8216_globals), 
  305. + }, 
  306. + .attr_port = { 
  307. + .attr = ar8216_port, 
  308. + .n_attr = ARRAY_SIZE(ar8216_port), 
  309. + }, 
  310. + .attr_vlan = { 
  311. + .attr = ar8216_vlan, 
  312. + .n_attr = ARRAY_SIZE(ar8216_vlan), 
  313. + }, 
  314. + .get_port_pvid = ar8216_sw_get_pvid, 
  315. + .set_port_pvid = ar8216_sw_set_pvid, 
  316. + .get_vlan_ports = ar8327_sw_get_ports, 
  317. + .set_vlan_ports = ar8327_sw_set_ports, 
  318. + .apply_config = ar8216_sw_hw_apply, 
  319. + .reset_switch = ar8216_sw_reset_switch, 
  320. + .get_port_link = ar8216_sw_get_port_link, 
  321. +}; 
  322. +#endif 
  323. + 
  324. static int 
  325. ar8216_id_chip(struct ar8216_priv *priv) 

  326. @@ -2757,8 +2928,15 @@ ar8216_config_init(struct phy_device *pdev) 
  327. pdev->priv = priv; 
  328.  
  329. swdev = &priv->dev; 
  330. - swdev->cpu_port = AR8216_PORT_CPU; 
  331. + swdev->cpu_port = AR8216_PORT_CPU; 
  332. +#if OK_PATCH 
  333. + if(chip_is_ar8327(priv) || chip_is_ar8337(priv)) 
  334. + swdev->ops = &ar8327_sw_ops; 
  335. + else 
  336. + swdev->ops = &ar8216_sw_ops; 
  337. +#else 
  338. swdev->ops = &ar8216_sw_ops; 
  339. +#endif 
  340. swdev->ports = AR8216_NUM_PORTS; 
  341.  
  342. if (chip_is_ar8316(priv)) { 

nicephil@gmail.com 2017-3-23

posted on 2017-03-23 18:57  nicephil  阅读(1168)  评论(0编辑  收藏  举报

导航