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.  
  46. static void 
  47. +#if OK_PATCH 
  48. +ar8216_vtu_load_vlan(struct ar8216_priv *priv, u32 vlan) 
  49. +#else 
  50. ar8216_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  51. +#endif 
  52. { 
  53. - u32 op; 
  54. + u32 op; 
  55. +#if OK_PATCH 
  56. + u32 vid = priv->vlan_id[vlan]; 
  57. + u32 port_mask = priv->vlan_table[vlan]; 
  58. +#endif 
  59.  
  60. op = AR8216_VTU_OP_LOAD | (vid << AR8216_VTU_VID_S); 
  61. ar8216_vtu_op(priv, op, port_mask); 
  62. @@ -1609,11 +1630,20 @@ ar8327_vtu_flush(struct ar8216_priv *priv) 
  63. } 
  64.  
  65. static void 
  66. +#if OK_PATCH 
  67. +ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vlan) 
  68. +#else 
  69. ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  70. +#endif 
  71. { 
  72. u32 op; 
  73. u32 val; 
  74. - int i; 
  75. + int i; 
  76. +#if OK_PATCH 
  77. + u32 vid = priv->vlan_id[vlan]; 
  78. + u32 port_mask = priv->vlan_table[vlan]; 
  79. + u32 tagged = priv->vlan_tagged_8327[vlan]; 
  80. +#endif 
  81.  
  82. op = AR8327_VTU_FUNC1_OP_LOAD | (vid << AR8327_VTU_FUNC1_VID_S); 
  83. val = AR8327_VTU_FUNC0_VALID | AR8327_VTU_FUNC0_IVL; 
  84. @@ -1622,9 +1652,13 @@ ar8327_vtu_load_vlan(struct ar8216_priv *priv, u32 vid, u32 port_mask) 
  85.  
  86. if ((port_mask & BIT(i)) == 0) 
  87. mode = AR8327_VTU_FUNC0_EG_MODE_NOT; 
  88. - else if (priv->vlan == 0) 
  89. - mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; 
  90. - else if (priv->vlan_tagged & BIT(i)) 
  91. + else if (priv->vlan == 0) 
  92. + mode = AR8327_VTU_FUNC0_EG_MODE_KEEP; 
  93. +#if OK_PATCH 
  94. + else if (tagged& BIT(i)) 
  95. +#else 
  96. + else if (priv->vlan_tagged & BIT(i)) 
  97. +#endif 
  98. mode = AR8327_VTU_FUNC0_EG_MODE_TAG; 
  99. else 
  100. mode = AR8327_VTU_FUNC0_EG_MODE_UNTAG; 
  101. @@ -1638,13 +1672,26 @@ static void 
  102. ar8327_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress, 
  103. u32 members, u32 pvid) 
  104. { 
  105. - u32 t; 
  106. - u32 mode; 
  107. + u32 t; 
  108. + u32 mode; 
  109. + 
  110. +#if OK_PATCH 
  111. + if (priv->vlan) { 
  112. + pvid = priv->vlan_id[priv->pvid[port]]; 
  113. + mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
  114. + ingress = AR8216_IN_SECURE; 
  115. + } else { 
  116. + pvid = port; 
  117. + mode = AR8327_PORT_VLAN1_OUT_MODE_UNTOUCH; 
  118. + ingress = AR8216_IN_PORT_ONLY; 
  119. + } 
  120. +#endif 
  121.  
  122. t = pvid << AR8327_PORT_VLAN0_DEF_SVID_S; 
  123. t |= pvid << AR8327_PORT_VLAN0_DEF_CVID_S; 
  124. priv->write(priv, AR8327_REG_PORT_VLAN0(port), t); 
  125.  
  126. +#if !OK_PATCH 
  127. mode = AR8327_PORT_VLAN1_OUT_MODE_UNMOD; 
  128. switch (egress) { 
  129. case AR8216_OUT_KEEP: 
  130. @@ -1657,6 +1704,7 @@ ar8327_setup_port(struct ar8216_priv *priv, int port, u32 egress, u32 ingress, 
  131. mode = AR8327_PORT_VLAN1_OUT_MODE_TAG; 
  132. break; 
  133. } 
  134. +#endif 
  135.  
  136. t = AR8327_PORT_VLAN1_PORT_VLAN_PROP; 
  137. t |= mode << AR8327_PORT_VLAN1_OUT_MODE_S; 
  138. @@ -1813,22 +1861,40 @@ ar8216_sw_get_port_link(struct switch_dev *dev, int port, 
  139. } 
  140.  
  141. static int 
  142. +#if OK_PATCH 
  143. +ar8xxx_sw_get_ports(struct switch_val *val, int ports, u8 port_mask, u8 tagged) 
  144. +#else 
  145. ar8216_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
  146. +#endif 
  147. { 
  148. +#if !OK_PATCH 
  149. struct ar8216_priv *priv = to_ar8216(dev); 
  150. u8 ports = priv->vlan_table[val->port_vlan]; 
  151. +#endif 
  152. int i; 
  153.  
  154. val->len = 0; 
  155. +#if OK_PATCH 
  156. + for (i = 0; i < ports; i++) { 
  157. +#else 
  158. for (i = 0; i < dev->ports; i++) { 
  159. +#endif 
  160. struct switch_port *p; 
  161.  
  162. - if (!(ports & (1 << i))) 
  163. - continue; 
  164. +#if OK_PATCH 
  165. + if (!(port_mask & (1 << i))) 
  166. +#else 
  167. + if (!(ports & (1 << i))) 
  168. +#endif 
  169. + continue; 
  170.  
  171. p = &val->value.ports[val->len++]; 
  172. p->id = i; 
  173. - if (priv->vlan_tagged & (1 << i)) 
  174. +#if OK_PATCH 
  175. + if (tagged & BIT(i)) 
  176. +#else 
  177. + if (priv->vlan_tagged & (1 << i)) 
  178. +#endif 
  179. p->flags = (1 << SWITCH_PORT_FLAG_TAGGED); 
  180. else 
  181. p->flags = 0; 
  182. @@ -1840,17 +1906,42 @@ static int 
  183. ar8216_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
  184. { 
  185. struct ar8216_priv *priv = to_ar8216(dev); 
  186. - u8 *vt = &priv->vlan_table[val->port_vlan]; 
  187. + u8 *vt = &priv->vlan_table[val->port_vlan]; 
  188. +#if OK_PATCH 
  189. + u8 *tagged = &priv->vlan_tagged_8216; 
  190. +#endif 
  191. int i, j; 
  192.  
  193. *vt = 0; 
  194. for (i = 0; i < val->len; i++) { 
  195. struct switch_port *p = &val->value.ports[i]; 
  196.  
  197. +#if OK_PATCH 
  198. + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
  199. + 
  200. + /* if port was untagged before then 
  201. + * remove him from other vlans */ 
  202. + if(*tagged & BIT(p->id)){ 
  203. + for (j = 0; j < AR8X16_MAX_VLANS; j++) { 
  204. + if (j == val->port_vlan) 
  205. + continue; 
  206. + 
  207. + priv->vlan_table[j] &= ~(BIT(p->id)); 
  208. + } 
  209. + } 
  210. + 
  211. + *tagged |= BIT(p->id); 
  212. + 
  213. +#else 
  214. if (p->flags & (1 << SWITCH_PORT_FLAG_TAGGED)) { 
  215. priv->vlan_tagged |= (1 << p->id); 
  216. +#endif 
  217. } else { 
  218. - priv->vlan_tagged &= ~(1 << p->id); 
  219. +#if OK_PATCH 
  220. + *tagged &= ~(BIT(p->id)); 
  221. +#else 
  222. + priv->vlan_tagged &= ~(1 << p->id); 
  223. +#endif 
  224. priv->pvid[p->id] = val->port_vlan; 
  225.  
  226. /* make sure that an untagged port does not 
  227. @@ -1867,6 +1958,54 @@ ar8216_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
  228. return 0; 
  229. } 
  230.  
  231. +#if OK_PATCH 
  232. + static int 
  233. +ar8327_sw_set_ports(struct switch_dev *dev, struct switch_val *val) 
  234. +{ 
  235. + struct ar8216_priv *priv = to_ar8216(dev); 
  236. + u8 *vt = &priv->vlan_table[val->port_vlan]; 
  237. + u8 *vlan_tagged = priv->vlan_tagged_8327; 
  238. + u8 *tagged = &vlan_tagged[val->port_vlan]; 
  239. + 
  240. + int i; 
  241. + 
  242. + *vt = 0; 
  243. + *tagged = 0; 
  244. + for (i = 0; i < val->len; i++) { 
  245. + struct switch_port *p = &val->value.ports[i]; 
  246. + 
  247. + if (p->flags & BIT(SWITCH_PORT_FLAG_TAGGED)) { 
  248. + *tagged |= BIT(p->id); 
  249. + } else { 
  250. + priv->pvid[p->id] = val->port_vlan; 
  251. + } 
  252. + 
  253. + *vt |= BIT(p->id); 
  254. + } 
  255. + return 0; 
  256. +} 
  257. + static int 
  258. +ar8216_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_8216; 
  264. + 
  265. + return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
  266. +} 
  267. + static int 
  268. +ar8327_sw_get_ports(struct switch_dev *dev, struct switch_val *val) 
  269. +{ 
  270. + int ports = dev->ports; 
  271. + struct ar8216_priv *priv = to_ar8216(dev); 
  272. + u8 port_mask = priv->vlan_table[val->port_vlan]; 
  273. + u8 tagged = priv->vlan_tagged_8327[val->port_vlan]; 
  274. + 
  275. + return ar8xxx_sw_get_ports(val, ports, port_mask, tagged); 
  276. +} 
  277. +#endif 
  278. + 
  279. static int 
  280. ar8216_sw_hw_apply(struct switch_dev *dev) 
  281. { 
  282. @@ -1894,8 +2033,12 @@ ar8216_sw_hw_apply(struct switch_dev *dev) 
  283. portmask[i] |= vp & ~mask; 
  284. } 
  285.  
  286. - priv->chip->vtu_load_vlan(priv, priv->vlan_id[j], 
  287. - priv->vlan_table[j]); 
  288. +#if OK_PATCH 
  289. + priv->chip->vtu_load_vlan(priv, j); 
  290. +#else 
  291. + priv->chip->vtu_load_vlan(priv, priv->vlan_id[j], 
  292. + priv->vlan_table[j]); 
  293. +#endif 
  294. } 
  295. } else { 
  296. /* vlan disabled: 
  297. @@ -1916,7 +2059,11 @@ ar8216_sw_hw_apply(struct switch_dev *dev) 
  298.  
  299. if (priv->vlan) { 
  300. pvid = priv->vlan_id[priv->pvid[i]]; 
  301. +#if OK_PATCH 
  302. + if (priv->vlan_tagged_8216 & (1 << i)) 
  303. +#else 
  304. if (priv->vlan_tagged & (1 << i)) 
  305. +#endif 
  306. egress = AR8216_OUT_ADD_VLAN; 
  307. else 
  308. egress = AR8216_OUT_STRIP_VLAN; 
  309. @@ -2267,6 +2414,30 @@ static const struct switch_dev_ops ar8216_sw_ops = { 
  310. .set_reg_val = ar8216_sw_set_reg_val, 
  311. }; 
  312.  
  313. +#if OK_PATCH 
  314. +static const struct switch_dev_ops ar8327_sw_ops = { 
  315. + .attr_global = { 
  316. + .attr = ar8216_globals, 
  317. + .n_attr = ARRAY_SIZE(ar8216_globals), 
  318. + }, 
  319. + .attr_port = { 
  320. + .attr = ar8216_port, 
  321. + .n_attr = ARRAY_SIZE(ar8216_port), 
  322. + }, 
  323. + .attr_vlan = { 
  324. + .attr = ar8216_vlan, 
  325. + .n_attr = ARRAY_SIZE(ar8216_vlan), 
  326. + }, 
  327. + .get_port_pvid = ar8216_sw_get_pvid, 
  328. + .set_port_pvid = ar8216_sw_set_pvid, 
  329. + .get_vlan_ports = ar8327_sw_get_ports, 
  330. + .set_vlan_ports = ar8327_sw_set_ports, 
  331. + .apply_config = ar8216_sw_hw_apply, 
  332. + .reset_switch = ar8216_sw_reset_switch, 
  333. + .get_port_link = ar8216_sw_get_port_link, 
  334. +}; 
  335. +#endif 
  336. + 
  337. static int 
  338. ar8216_id_chip(struct ar8216_priv *priv) 
  339. { 
  340. @@ -2757,8 +2928,15 @@ ar8216_config_init(struct phy_device *pdev) 
  341. pdev->priv = priv; 
  342.  
  343. swdev = &priv->dev; 
  344. - swdev->cpu_port = AR8216_PORT_CPU; 
  345. + swdev->cpu_port = AR8216_PORT_CPU; 
  346. +#if OK_PATCH 
  347. + if(chip_is_ar8327(priv) || chip_is_ar8337(priv)) 
  348. + swdev->ops = &ar8327_sw_ops; 
  349. + else 
  350. + swdev->ops = &ar8216_sw_ops; 
  351. +#else 
  352. swdev->ops = &ar8216_sw_ops; 
  353. +#endif 
  354. swdev->ports = AR8216_NUM_PORTS; 
  355.  
  356. if (chip_is_ar8316(priv)) { 

nicephil@gmail.com 2017-3-23

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

导航