rzn1_a5psw.c 34 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2022 Schneider-Electric
  4. *
  5. * Clément Léger <clement.leger@bootlin.com>
  6. */
  7. #include <linux/clk.h>
  8. #include <linux/etherdevice.h>
  9. #include <linux/if_bridge.h>
  10. #include <linux/if_ether.h>
  11. #include <linux/kernel.h>
  12. #include <linux/module.h>
  13. #include <linux/of.h>
  14. #include <linux/of_mdio.h>
  15. #include <net/dsa.h>
  16. #include "rzn1_a5psw.h"
  17. struct a5psw_stats {
  18. u16 offset;
  19. const char name[ETH_GSTRING_LEN];
  20. };
  21. #define STAT_DESC(_offset) { \
  22. .offset = A5PSW_##_offset, \
  23. .name = __stringify(_offset), \
  24. }
  25. static const struct a5psw_stats a5psw_stats[] = {
  26. STAT_DESC(aFramesTransmittedOK),
  27. STAT_DESC(aFramesReceivedOK),
  28. STAT_DESC(aFrameCheckSequenceErrors),
  29. STAT_DESC(aAlignmentErrors),
  30. STAT_DESC(aOctetsTransmittedOK),
  31. STAT_DESC(aOctetsReceivedOK),
  32. STAT_DESC(aTxPAUSEMACCtrlFrames),
  33. STAT_DESC(aRxPAUSEMACCtrlFrames),
  34. STAT_DESC(ifInErrors),
  35. STAT_DESC(ifOutErrors),
  36. STAT_DESC(ifInUcastPkts),
  37. STAT_DESC(ifInMulticastPkts),
  38. STAT_DESC(ifInBroadcastPkts),
  39. STAT_DESC(ifOutDiscards),
  40. STAT_DESC(ifOutUcastPkts),
  41. STAT_DESC(ifOutMulticastPkts),
  42. STAT_DESC(ifOutBroadcastPkts),
  43. STAT_DESC(etherStatsDropEvents),
  44. STAT_DESC(etherStatsOctets),
  45. STAT_DESC(etherStatsPkts),
  46. STAT_DESC(etherStatsUndersizePkts),
  47. STAT_DESC(etherStatsOversizePkts),
  48. STAT_DESC(etherStatsPkts64Octets),
  49. STAT_DESC(etherStatsPkts65to127Octets),
  50. STAT_DESC(etherStatsPkts128to255Octets),
  51. STAT_DESC(etherStatsPkts256to511Octets),
  52. STAT_DESC(etherStatsPkts1024to1518Octets),
  53. STAT_DESC(etherStatsPkts1519toXOctets),
  54. STAT_DESC(etherStatsJabbers),
  55. STAT_DESC(etherStatsFragments),
  56. STAT_DESC(VLANReceived),
  57. STAT_DESC(VLANTransmitted),
  58. STAT_DESC(aDeferred),
  59. STAT_DESC(aMultipleCollisions),
  60. STAT_DESC(aSingleCollisions),
  61. STAT_DESC(aLateCollisions),
  62. STAT_DESC(aExcessiveCollisions),
  63. STAT_DESC(aCarrierSenseErrors),
  64. };
  65. static void a5psw_reg_writel(struct a5psw *a5psw, int offset, u32 value)
  66. {
  67. writel(value, a5psw->base + offset);
  68. }
  69. static u32 a5psw_reg_readl(struct a5psw *a5psw, int offset)
  70. {
  71. return readl(a5psw->base + offset);
  72. }
  73. static void a5psw_reg_rmw(struct a5psw *a5psw, int offset, u32 mask, u32 val)
  74. {
  75. u32 reg;
  76. spin_lock(&a5psw->reg_lock);
  77. reg = a5psw_reg_readl(a5psw, offset);
  78. reg &= ~mask;
  79. reg |= val;
  80. a5psw_reg_writel(a5psw, offset, reg);
  81. spin_unlock(&a5psw->reg_lock);
  82. }
  83. static enum dsa_tag_protocol a5psw_get_tag_protocol(struct dsa_switch *ds,
  84. int port,
  85. enum dsa_tag_protocol mp)
  86. {
  87. return DSA_TAG_PROTO_RZN1_A5PSW;
  88. }
  89. static void a5psw_port_pattern_set(struct a5psw *a5psw, int port, int pattern,
  90. bool enable)
  91. {
  92. u32 rx_match = 0;
  93. if (enable)
  94. rx_match |= A5PSW_RXMATCH_CONFIG_PATTERN(pattern);
  95. a5psw_reg_rmw(a5psw, A5PSW_RXMATCH_CONFIG(port),
  96. A5PSW_RXMATCH_CONFIG_PATTERN(pattern), rx_match);
  97. }
  98. static void a5psw_port_mgmtfwd_set(struct a5psw *a5psw, int port, bool enable)
  99. {
  100. /* Enable "management forward" pattern matching, this will forward
  101. * packets from this port only towards the management port and thus
  102. * isolate the port.
  103. */
  104. a5psw_port_pattern_set(a5psw, port, A5PSW_PATTERN_MGMTFWD, enable);
  105. }
  106. static void a5psw_port_tx_enable(struct a5psw *a5psw, int port, bool enable)
  107. {
  108. u32 mask = A5PSW_PORT_ENA_TX(port);
  109. u32 reg = enable ? mask : 0;
  110. /* Even though the port TX is disabled through TXENA bit in the
  111. * PORT_ENA register, it can still send BPDUs. This depends on the tag
  112. * configuration added when sending packets from the CPU port to the
  113. * switch port. Indeed, when using forced forwarding without filtering,
  114. * even disabled ports will be able to send packets that are tagged.
  115. * This allows to implement STP support when ports are in a state where
  116. * forwarding traffic should be stopped but BPDUs should still be sent.
  117. */
  118. a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, mask, reg);
  119. }
  120. static void a5psw_port_enable_set(struct a5psw *a5psw, int port, bool enable)
  121. {
  122. u32 port_ena = 0;
  123. if (enable)
  124. port_ena |= A5PSW_PORT_ENA_TX_RX(port);
  125. a5psw_reg_rmw(a5psw, A5PSW_PORT_ENA, A5PSW_PORT_ENA_TX_RX(port),
  126. port_ena);
  127. }
  128. static int a5psw_lk_execute_ctrl(struct a5psw *a5psw, u32 *ctrl)
  129. {
  130. int ret;
  131. a5psw_reg_writel(a5psw, A5PSW_LK_ADDR_CTRL, *ctrl);
  132. ret = readl_poll_timeout(a5psw->base + A5PSW_LK_ADDR_CTRL, *ctrl,
  133. !(*ctrl & A5PSW_LK_ADDR_CTRL_BUSY),
  134. A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
  135. if (ret)
  136. dev_err(a5psw->dev, "LK_CTRL timeout waiting for BUSY bit\n");
  137. return ret;
  138. }
  139. static void a5psw_port_fdb_flush(struct a5psw *a5psw, int port)
  140. {
  141. u32 ctrl = A5PSW_LK_ADDR_CTRL_DELETE_PORT | BIT(port);
  142. mutex_lock(&a5psw->lk_lock);
  143. a5psw_lk_execute_ctrl(a5psw, &ctrl);
  144. mutex_unlock(&a5psw->lk_lock);
  145. }
  146. static void a5psw_port_authorize_set(struct a5psw *a5psw, int port,
  147. bool authorize)
  148. {
  149. u32 reg = a5psw_reg_readl(a5psw, A5PSW_AUTH_PORT(port));
  150. if (authorize)
  151. reg |= A5PSW_AUTH_PORT_AUTHORIZED;
  152. else
  153. reg &= ~A5PSW_AUTH_PORT_AUTHORIZED;
  154. a5psw_reg_writel(a5psw, A5PSW_AUTH_PORT(port), reg);
  155. }
  156. static void a5psw_port_disable(struct dsa_switch *ds, int port)
  157. {
  158. struct a5psw *a5psw = ds->priv;
  159. a5psw_port_authorize_set(a5psw, port, false);
  160. a5psw_port_enable_set(a5psw, port, false);
  161. }
  162. static int a5psw_port_enable(struct dsa_switch *ds, int port,
  163. struct phy_device *phy)
  164. {
  165. struct a5psw *a5psw = ds->priv;
  166. a5psw_port_authorize_set(a5psw, port, true);
  167. a5psw_port_enable_set(a5psw, port, true);
  168. return 0;
  169. }
  170. static int a5psw_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
  171. {
  172. struct a5psw *a5psw = ds->priv;
  173. new_mtu += ETH_HLEN + A5PSW_EXTRA_MTU_LEN + ETH_FCS_LEN;
  174. a5psw_reg_writel(a5psw, A5PSW_FRM_LENGTH(port), new_mtu);
  175. return 0;
  176. }
  177. static int a5psw_port_max_mtu(struct dsa_switch *ds, int port)
  178. {
  179. return A5PSW_MAX_MTU;
  180. }
  181. static void a5psw_phylink_get_caps(struct dsa_switch *ds, int port,
  182. struct phylink_config *config)
  183. {
  184. unsigned long *intf = config->supported_interfaces;
  185. config->mac_capabilities = MAC_1000FD;
  186. if (dsa_is_cpu_port(ds, port)) {
  187. /* GMII is used internally and GMAC2 is connected to the switch
  188. * using 1000Mbps Full-Duplex mode only (cf ethernet manual)
  189. */
  190. __set_bit(PHY_INTERFACE_MODE_GMII, intf);
  191. } else {
  192. config->mac_capabilities |= MAC_100 | MAC_10;
  193. phy_interface_set_rgmii(intf);
  194. __set_bit(PHY_INTERFACE_MODE_RMII, intf);
  195. __set_bit(PHY_INTERFACE_MODE_MII, intf);
  196. }
  197. }
  198. static struct phylink_pcs *
  199. a5psw_phylink_mac_select_pcs(struct phylink_config *config,
  200. phy_interface_t interface)
  201. {
  202. struct dsa_port *dp = dsa_phylink_to_port(config);
  203. struct a5psw *a5psw = dp->ds->priv;
  204. if (dsa_port_is_cpu(dp))
  205. return NULL;
  206. return a5psw->pcs[dp->index];
  207. }
  208. static void a5psw_phylink_mac_config(struct phylink_config *config,
  209. unsigned int mode,
  210. const struct phylink_link_state *state)
  211. {
  212. }
  213. static void a5psw_phylink_mac_link_down(struct phylink_config *config,
  214. unsigned int mode,
  215. phy_interface_t interface)
  216. {
  217. struct dsa_port *dp = dsa_phylink_to_port(config);
  218. struct a5psw *a5psw = dp->ds->priv;
  219. int port = dp->index;
  220. u32 cmd_cfg;
  221. cmd_cfg = a5psw_reg_readl(a5psw, A5PSW_CMD_CFG(port));
  222. cmd_cfg &= ~(A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA);
  223. a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port), cmd_cfg);
  224. }
  225. static void a5psw_phylink_mac_link_up(struct phylink_config *config,
  226. struct phy_device *phydev,
  227. unsigned int mode,
  228. phy_interface_t interface,
  229. int speed, int duplex, bool tx_pause,
  230. bool rx_pause)
  231. {
  232. u32 cmd_cfg = A5PSW_CMD_CFG_RX_ENA | A5PSW_CMD_CFG_TX_ENA |
  233. A5PSW_CMD_CFG_TX_CRC_APPEND;
  234. struct dsa_port *dp = dsa_phylink_to_port(config);
  235. struct a5psw *a5psw = dp->ds->priv;
  236. if (speed == SPEED_1000)
  237. cmd_cfg |= A5PSW_CMD_CFG_ETH_SPEED;
  238. if (duplex == DUPLEX_HALF)
  239. cmd_cfg |= A5PSW_CMD_CFG_HD_ENA;
  240. cmd_cfg |= A5PSW_CMD_CFG_CNTL_FRM_ENA;
  241. if (!rx_pause)
  242. cmd_cfg &= ~A5PSW_CMD_CFG_PAUSE_IGNORE;
  243. a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(dp->index), cmd_cfg);
  244. }
  245. static int a5psw_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
  246. {
  247. struct a5psw *a5psw = ds->priv;
  248. unsigned long rate;
  249. u64 max, tmp;
  250. u32 agetime;
  251. rate = clk_get_rate(a5psw->clk);
  252. max = div64_ul(((u64)A5PSW_LK_AGETIME_MASK * A5PSW_TABLE_ENTRIES * 1024),
  253. rate) * 1000;
  254. if (msecs > max)
  255. return -EINVAL;
  256. tmp = div_u64(rate, MSEC_PER_SEC);
  257. agetime = div_u64(msecs * tmp, 1024 * A5PSW_TABLE_ENTRIES);
  258. a5psw_reg_writel(a5psw, A5PSW_LK_AGETIME, agetime);
  259. return 0;
  260. }
  261. static void a5psw_port_learning_set(struct a5psw *a5psw, int port, bool learn)
  262. {
  263. u32 mask = A5PSW_INPUT_LEARN_DIS(port);
  264. u32 reg = !learn ? mask : 0;
  265. a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
  266. }
  267. static void a5psw_port_rx_block_set(struct a5psw *a5psw, int port, bool block)
  268. {
  269. u32 mask = A5PSW_INPUT_LEARN_BLOCK(port);
  270. u32 reg = block ? mask : 0;
  271. a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN, mask, reg);
  272. }
  273. static void a5psw_flooding_set_resolution(struct a5psw *a5psw, int port,
  274. bool set)
  275. {
  276. u8 offsets[] = {A5PSW_UCAST_DEF_MASK, A5PSW_BCAST_DEF_MASK,
  277. A5PSW_MCAST_DEF_MASK};
  278. int i;
  279. for (i = 0; i < ARRAY_SIZE(offsets); i++)
  280. a5psw_reg_rmw(a5psw, offsets[i], BIT(port),
  281. set ? BIT(port) : 0);
  282. }
  283. static void a5psw_port_set_standalone(struct a5psw *a5psw, int port,
  284. bool standalone)
  285. {
  286. a5psw_port_learning_set(a5psw, port, !standalone);
  287. a5psw_flooding_set_resolution(a5psw, port, !standalone);
  288. a5psw_port_mgmtfwd_set(a5psw, port, standalone);
  289. }
  290. static int a5psw_port_bridge_join(struct dsa_switch *ds, int port,
  291. struct dsa_bridge bridge,
  292. bool *tx_fwd_offload,
  293. struct netlink_ext_ack *extack)
  294. {
  295. struct a5psw *a5psw = ds->priv;
  296. /* We only support 1 bridge device */
  297. if (a5psw->br_dev && bridge.dev != a5psw->br_dev) {
  298. NL_SET_ERR_MSG_MOD(extack,
  299. "Forwarding offload supported for a single bridge");
  300. return -EOPNOTSUPP;
  301. }
  302. a5psw->br_dev = bridge.dev;
  303. a5psw_port_set_standalone(a5psw, port, false);
  304. a5psw->bridged_ports |= BIT(port);
  305. return 0;
  306. }
  307. static void a5psw_port_bridge_leave(struct dsa_switch *ds, int port,
  308. struct dsa_bridge bridge)
  309. {
  310. struct a5psw *a5psw = ds->priv;
  311. a5psw->bridged_ports &= ~BIT(port);
  312. a5psw_port_set_standalone(a5psw, port, true);
  313. /* No more ports bridged */
  314. if (a5psw->bridged_ports == BIT(A5PSW_CPU_PORT))
  315. a5psw->br_dev = NULL;
  316. }
  317. static int a5psw_port_pre_bridge_flags(struct dsa_switch *ds, int port,
  318. struct switchdev_brport_flags flags,
  319. struct netlink_ext_ack *extack)
  320. {
  321. if (flags.mask & ~(BR_LEARNING | BR_FLOOD | BR_MCAST_FLOOD |
  322. BR_BCAST_FLOOD))
  323. return -EINVAL;
  324. return 0;
  325. }
  326. static int
  327. a5psw_port_bridge_flags(struct dsa_switch *ds, int port,
  328. struct switchdev_brport_flags flags,
  329. struct netlink_ext_ack *extack)
  330. {
  331. struct a5psw *a5psw = ds->priv;
  332. u32 val;
  333. /* If a port is set as standalone, we do not want to be able to
  334. * configure flooding nor learning which would result in joining the
  335. * unique bridge. This can happen when a port leaves the bridge, in
  336. * which case the DSA core will try to "clear" all flags for the
  337. * standalone port (ie enable flooding, disable learning). In that case
  338. * do not fail but do not apply the flags.
  339. */
  340. if (!(a5psw->bridged_ports & BIT(port)))
  341. return 0;
  342. if (flags.mask & BR_LEARNING) {
  343. val = flags.val & BR_LEARNING ? 0 : A5PSW_INPUT_LEARN_DIS(port);
  344. a5psw_reg_rmw(a5psw, A5PSW_INPUT_LEARN,
  345. A5PSW_INPUT_LEARN_DIS(port), val);
  346. }
  347. if (flags.mask & BR_FLOOD) {
  348. val = flags.val & BR_FLOOD ? BIT(port) : 0;
  349. a5psw_reg_rmw(a5psw, A5PSW_UCAST_DEF_MASK, BIT(port), val);
  350. }
  351. if (flags.mask & BR_MCAST_FLOOD) {
  352. val = flags.val & BR_MCAST_FLOOD ? BIT(port) : 0;
  353. a5psw_reg_rmw(a5psw, A5PSW_MCAST_DEF_MASK, BIT(port), val);
  354. }
  355. if (flags.mask & BR_BCAST_FLOOD) {
  356. val = flags.val & BR_BCAST_FLOOD ? BIT(port) : 0;
  357. a5psw_reg_rmw(a5psw, A5PSW_BCAST_DEF_MASK, BIT(port), val);
  358. }
  359. return 0;
  360. }
  361. static void a5psw_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
  362. {
  363. bool learning_enabled, rx_enabled, tx_enabled;
  364. struct dsa_port *dp = dsa_to_port(ds, port);
  365. struct a5psw *a5psw = ds->priv;
  366. switch (state) {
  367. case BR_STATE_DISABLED:
  368. case BR_STATE_BLOCKING:
  369. case BR_STATE_LISTENING:
  370. rx_enabled = false;
  371. tx_enabled = false;
  372. learning_enabled = false;
  373. break;
  374. case BR_STATE_LEARNING:
  375. rx_enabled = false;
  376. tx_enabled = false;
  377. learning_enabled = dp->learning;
  378. break;
  379. case BR_STATE_FORWARDING:
  380. rx_enabled = true;
  381. tx_enabled = true;
  382. learning_enabled = dp->learning;
  383. break;
  384. default:
  385. dev_err(ds->dev, "invalid STP state: %d\n", state);
  386. return;
  387. }
  388. a5psw_port_learning_set(a5psw, port, learning_enabled);
  389. a5psw_port_rx_block_set(a5psw, port, !rx_enabled);
  390. a5psw_port_tx_enable(a5psw, port, tx_enabled);
  391. }
  392. static void a5psw_port_fast_age(struct dsa_switch *ds, int port)
  393. {
  394. struct a5psw *a5psw = ds->priv;
  395. a5psw_port_fdb_flush(a5psw, port);
  396. }
  397. static int a5psw_lk_execute_lookup(struct a5psw *a5psw, union lk_data *lk_data,
  398. u16 *entry)
  399. {
  400. u32 ctrl;
  401. int ret;
  402. a5psw_reg_writel(a5psw, A5PSW_LK_DATA_LO, lk_data->lo);
  403. a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data->hi);
  404. ctrl = A5PSW_LK_ADDR_CTRL_LOOKUP;
  405. ret = a5psw_lk_execute_ctrl(a5psw, &ctrl);
  406. if (ret)
  407. return ret;
  408. *entry = ctrl & A5PSW_LK_ADDR_CTRL_ADDRESS;
  409. return 0;
  410. }
  411. static int a5psw_port_fdb_add(struct dsa_switch *ds, int port,
  412. const unsigned char *addr, u16 vid,
  413. struct dsa_db db)
  414. {
  415. struct a5psw *a5psw = ds->priv;
  416. union lk_data lk_data = {0};
  417. bool inc_learncount = false;
  418. int ret = 0;
  419. u16 entry;
  420. u32 reg;
  421. ether_addr_copy(lk_data.entry.mac, addr);
  422. lk_data.entry.port_mask = BIT(port);
  423. mutex_lock(&a5psw->lk_lock);
  424. /* Set the value to be written in the lookup table */
  425. ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
  426. if (ret)
  427. goto lk_unlock;
  428. lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
  429. if (!lk_data.entry.valid) {
  430. inc_learncount = true;
  431. /* port_mask set to 0x1f when entry is not valid, clear it */
  432. lk_data.entry.port_mask = 0;
  433. lk_data.entry.prio = 0;
  434. }
  435. lk_data.entry.port_mask |= BIT(port);
  436. lk_data.entry.is_static = 1;
  437. lk_data.entry.valid = 1;
  438. a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
  439. reg = A5PSW_LK_ADDR_CTRL_WRITE | entry;
  440. ret = a5psw_lk_execute_ctrl(a5psw, &reg);
  441. if (ret)
  442. goto lk_unlock;
  443. if (inc_learncount) {
  444. reg = A5PSW_LK_LEARNCOUNT_MODE_INC;
  445. a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
  446. }
  447. lk_unlock:
  448. mutex_unlock(&a5psw->lk_lock);
  449. return ret;
  450. }
  451. static int a5psw_port_fdb_del(struct dsa_switch *ds, int port,
  452. const unsigned char *addr, u16 vid,
  453. struct dsa_db db)
  454. {
  455. struct a5psw *a5psw = ds->priv;
  456. union lk_data lk_data = {0};
  457. bool clear = false;
  458. u16 entry;
  459. u32 reg;
  460. int ret;
  461. ether_addr_copy(lk_data.entry.mac, addr);
  462. mutex_lock(&a5psw->lk_lock);
  463. ret = a5psw_lk_execute_lookup(a5psw, &lk_data, &entry);
  464. if (ret)
  465. goto lk_unlock;
  466. lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
  467. /* Our hardware does not associate any VID to the FDB entries so this
  468. * means that if two entries were added for the same mac but for
  469. * different VID, then, on the deletion of the first one, we would also
  470. * delete the second one. Since there is unfortunately nothing we can do
  471. * about that, do not return an error...
  472. */
  473. if (!lk_data.entry.valid)
  474. goto lk_unlock;
  475. lk_data.entry.port_mask &= ~BIT(port);
  476. /* If there is no more port in the mask, clear the entry */
  477. if (lk_data.entry.port_mask == 0)
  478. clear = true;
  479. a5psw_reg_writel(a5psw, A5PSW_LK_DATA_HI, lk_data.hi);
  480. reg = entry;
  481. if (clear)
  482. reg |= A5PSW_LK_ADDR_CTRL_CLEAR;
  483. else
  484. reg |= A5PSW_LK_ADDR_CTRL_WRITE;
  485. ret = a5psw_lk_execute_ctrl(a5psw, &reg);
  486. if (ret)
  487. goto lk_unlock;
  488. /* Decrement LEARNCOUNT */
  489. if (clear) {
  490. reg = A5PSW_LK_LEARNCOUNT_MODE_DEC;
  491. a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
  492. }
  493. lk_unlock:
  494. mutex_unlock(&a5psw->lk_lock);
  495. return ret;
  496. }
  497. static int a5psw_port_fdb_dump(struct dsa_switch *ds, int port,
  498. dsa_fdb_dump_cb_t *cb, void *data)
  499. {
  500. struct a5psw *a5psw = ds->priv;
  501. union lk_data lk_data;
  502. int i = 0, ret = 0;
  503. u32 reg;
  504. mutex_lock(&a5psw->lk_lock);
  505. for (i = 0; i < A5PSW_TABLE_ENTRIES; i++) {
  506. reg = A5PSW_LK_ADDR_CTRL_READ | A5PSW_LK_ADDR_CTRL_WAIT | i;
  507. ret = a5psw_lk_execute_ctrl(a5psw, &reg);
  508. if (ret)
  509. goto out_unlock;
  510. lk_data.hi = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_HI);
  511. /* If entry is not valid or does not contain the port, skip */
  512. if (!lk_data.entry.valid ||
  513. !(lk_data.entry.port_mask & BIT(port)))
  514. continue;
  515. lk_data.lo = a5psw_reg_readl(a5psw, A5PSW_LK_DATA_LO);
  516. ret = cb(lk_data.entry.mac, 0, lk_data.entry.is_static, data);
  517. if (ret)
  518. goto out_unlock;
  519. }
  520. out_unlock:
  521. mutex_unlock(&a5psw->lk_lock);
  522. return ret;
  523. }
  524. static int a5psw_port_vlan_filtering(struct dsa_switch *ds, int port,
  525. bool vlan_filtering,
  526. struct netlink_ext_ack *extack)
  527. {
  528. u32 mask = BIT(port + A5PSW_VLAN_VERI_SHIFT) |
  529. BIT(port + A5PSW_VLAN_DISC_SHIFT);
  530. u32 val = vlan_filtering ? mask : 0;
  531. struct a5psw *a5psw = ds->priv;
  532. /* Disable/enable vlan tagging */
  533. a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE_ENA, BIT(port),
  534. vlan_filtering ? BIT(port) : 0);
  535. /* Disable/enable vlan input filtering */
  536. a5psw_reg_rmw(a5psw, A5PSW_VLAN_VERIFY, mask, val);
  537. return 0;
  538. }
  539. static int a5psw_find_vlan_entry(struct a5psw *a5psw, u16 vid)
  540. {
  541. u32 vlan_res;
  542. int i;
  543. /* Find vlan for this port */
  544. for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
  545. vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
  546. if (FIELD_GET(A5PSW_VLAN_RES_VLANID, vlan_res) == vid)
  547. return i;
  548. }
  549. return -1;
  550. }
  551. static int a5psw_new_vlan_res_entry(struct a5psw *a5psw, u16 newvid)
  552. {
  553. u32 vlan_res;
  554. int i;
  555. /* Find a free VLAN entry */
  556. for (i = 0; i < A5PSW_VLAN_COUNT; i++) {
  557. vlan_res = a5psw_reg_readl(a5psw, A5PSW_VLAN_RES(i));
  558. if (!(FIELD_GET(A5PSW_VLAN_RES_PORTMASK, vlan_res))) {
  559. vlan_res = FIELD_PREP(A5PSW_VLAN_RES_VLANID, newvid);
  560. a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(i), vlan_res);
  561. return i;
  562. }
  563. }
  564. return -1;
  565. }
  566. static void a5psw_port_vlan_tagged_cfg(struct a5psw *a5psw,
  567. unsigned int vlan_res_id, int port,
  568. bool set)
  569. {
  570. u32 mask = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_RD_TAGMASK |
  571. BIT(port);
  572. u32 vlan_res_off = A5PSW_VLAN_RES(vlan_res_id);
  573. u32 val = A5PSW_VLAN_RES_WR_TAGMASK, reg;
  574. if (set)
  575. val |= BIT(port);
  576. /* Toggle tag mask read */
  577. a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
  578. reg = a5psw_reg_readl(a5psw, vlan_res_off);
  579. a5psw_reg_writel(a5psw, vlan_res_off, A5PSW_VLAN_RES_RD_TAGMASK);
  580. reg &= ~mask;
  581. reg |= val;
  582. a5psw_reg_writel(a5psw, vlan_res_off, reg);
  583. }
  584. static void a5psw_port_vlan_cfg(struct a5psw *a5psw, unsigned int vlan_res_id,
  585. int port, bool set)
  586. {
  587. u32 mask = A5PSW_VLAN_RES_WR_TAGMASK | BIT(port);
  588. u32 reg = A5PSW_VLAN_RES_WR_PORTMASK;
  589. if (set)
  590. reg |= BIT(port);
  591. a5psw_reg_rmw(a5psw, A5PSW_VLAN_RES(vlan_res_id), mask, reg);
  592. }
  593. static int a5psw_port_vlan_add(struct dsa_switch *ds, int port,
  594. const struct switchdev_obj_port_vlan *vlan,
  595. struct netlink_ext_ack *extack)
  596. {
  597. bool tagged = !(vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED);
  598. bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
  599. struct a5psw *a5psw = ds->priv;
  600. u16 vid = vlan->vid;
  601. int vlan_res_id;
  602. vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
  603. if (vlan_res_id < 0) {
  604. vlan_res_id = a5psw_new_vlan_res_entry(a5psw, vid);
  605. if (vlan_res_id < 0)
  606. return -ENOSPC;
  607. }
  608. a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, true);
  609. if (tagged)
  610. a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, true);
  611. /* Configure port to tag with corresponding VID, but do not enable it
  612. * yet: wait for vlan filtering to be enabled to enable vlan port
  613. * tagging
  614. */
  615. if (pvid)
  616. a5psw_reg_writel(a5psw, A5PSW_SYSTEM_TAGINFO(port), vid);
  617. return 0;
  618. }
  619. static int a5psw_port_vlan_del(struct dsa_switch *ds, int port,
  620. const struct switchdev_obj_port_vlan *vlan)
  621. {
  622. struct a5psw *a5psw = ds->priv;
  623. u16 vid = vlan->vid;
  624. int vlan_res_id;
  625. vlan_res_id = a5psw_find_vlan_entry(a5psw, vid);
  626. if (vlan_res_id < 0)
  627. return -EINVAL;
  628. a5psw_port_vlan_cfg(a5psw, vlan_res_id, port, false);
  629. a5psw_port_vlan_tagged_cfg(a5psw, vlan_res_id, port, false);
  630. return 0;
  631. }
  632. static u64 a5psw_read_stat(struct a5psw *a5psw, u32 offset, int port)
  633. {
  634. u32 reg_lo, reg_hi;
  635. reg_lo = a5psw_reg_readl(a5psw, offset + A5PSW_PORT_OFFSET(port));
  636. /* A5PSW_STATS_HIWORD is latched on stat read */
  637. reg_hi = a5psw_reg_readl(a5psw, A5PSW_STATS_HIWORD);
  638. return ((u64)reg_hi << 32) | reg_lo;
  639. }
  640. static void a5psw_get_strings(struct dsa_switch *ds, int port, u32 stringset,
  641. uint8_t *data)
  642. {
  643. unsigned int u;
  644. if (stringset != ETH_SS_STATS)
  645. return;
  646. for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++) {
  647. memcpy(data + u * ETH_GSTRING_LEN, a5psw_stats[u].name,
  648. ETH_GSTRING_LEN);
  649. }
  650. }
  651. static void a5psw_get_ethtool_stats(struct dsa_switch *ds, int port,
  652. uint64_t *data)
  653. {
  654. struct a5psw *a5psw = ds->priv;
  655. unsigned int u;
  656. for (u = 0; u < ARRAY_SIZE(a5psw_stats); u++)
  657. data[u] = a5psw_read_stat(a5psw, a5psw_stats[u].offset, port);
  658. }
  659. static int a5psw_get_sset_count(struct dsa_switch *ds, int port, int sset)
  660. {
  661. if (sset != ETH_SS_STATS)
  662. return 0;
  663. return ARRAY_SIZE(a5psw_stats);
  664. }
  665. static void a5psw_get_eth_mac_stats(struct dsa_switch *ds, int port,
  666. struct ethtool_eth_mac_stats *mac_stats)
  667. {
  668. struct a5psw *a5psw = ds->priv;
  669. #define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
  670. mac_stats->FramesTransmittedOK = RD(aFramesTransmittedOK);
  671. mac_stats->SingleCollisionFrames = RD(aSingleCollisions);
  672. mac_stats->MultipleCollisionFrames = RD(aMultipleCollisions);
  673. mac_stats->FramesReceivedOK = RD(aFramesReceivedOK);
  674. mac_stats->FrameCheckSequenceErrors = RD(aFrameCheckSequenceErrors);
  675. mac_stats->AlignmentErrors = RD(aAlignmentErrors);
  676. mac_stats->OctetsTransmittedOK = RD(aOctetsTransmittedOK);
  677. mac_stats->FramesWithDeferredXmissions = RD(aDeferred);
  678. mac_stats->LateCollisions = RD(aLateCollisions);
  679. mac_stats->FramesAbortedDueToXSColls = RD(aExcessiveCollisions);
  680. mac_stats->FramesLostDueToIntMACXmitError = RD(ifOutErrors);
  681. mac_stats->CarrierSenseErrors = RD(aCarrierSenseErrors);
  682. mac_stats->OctetsReceivedOK = RD(aOctetsReceivedOK);
  683. mac_stats->FramesLostDueToIntMACRcvError = RD(ifInErrors);
  684. mac_stats->MulticastFramesXmittedOK = RD(ifOutMulticastPkts);
  685. mac_stats->BroadcastFramesXmittedOK = RD(ifOutBroadcastPkts);
  686. mac_stats->FramesWithExcessiveDeferral = RD(aDeferred);
  687. mac_stats->MulticastFramesReceivedOK = RD(ifInMulticastPkts);
  688. mac_stats->BroadcastFramesReceivedOK = RD(ifInBroadcastPkts);
  689. #undef RD
  690. }
  691. static const struct ethtool_rmon_hist_range a5psw_rmon_ranges[] = {
  692. { 0, 64 },
  693. { 65, 127 },
  694. { 128, 255 },
  695. { 256, 511 },
  696. { 512, 1023 },
  697. { 1024, 1518 },
  698. { 1519, A5PSW_MAX_MTU },
  699. {}
  700. };
  701. static void a5psw_get_rmon_stats(struct dsa_switch *ds, int port,
  702. struct ethtool_rmon_stats *rmon_stats,
  703. const struct ethtool_rmon_hist_range **ranges)
  704. {
  705. struct a5psw *a5psw = ds->priv;
  706. #define RD(name) a5psw_read_stat(a5psw, A5PSW_##name, port)
  707. rmon_stats->undersize_pkts = RD(etherStatsUndersizePkts);
  708. rmon_stats->oversize_pkts = RD(etherStatsOversizePkts);
  709. rmon_stats->fragments = RD(etherStatsFragments);
  710. rmon_stats->jabbers = RD(etherStatsJabbers);
  711. rmon_stats->hist[0] = RD(etherStatsPkts64Octets);
  712. rmon_stats->hist[1] = RD(etherStatsPkts65to127Octets);
  713. rmon_stats->hist[2] = RD(etherStatsPkts128to255Octets);
  714. rmon_stats->hist[3] = RD(etherStatsPkts256to511Octets);
  715. rmon_stats->hist[4] = RD(etherStatsPkts512to1023Octets);
  716. rmon_stats->hist[5] = RD(etherStatsPkts1024to1518Octets);
  717. rmon_stats->hist[6] = RD(etherStatsPkts1519toXOctets);
  718. #undef RD
  719. *ranges = a5psw_rmon_ranges;
  720. }
  721. static void a5psw_get_eth_ctrl_stats(struct dsa_switch *ds, int port,
  722. struct ethtool_eth_ctrl_stats *ctrl_stats)
  723. {
  724. struct a5psw *a5psw = ds->priv;
  725. u64 stat;
  726. stat = a5psw_read_stat(a5psw, A5PSW_aTxPAUSEMACCtrlFrames, port);
  727. ctrl_stats->MACControlFramesTransmitted = stat;
  728. stat = a5psw_read_stat(a5psw, A5PSW_aRxPAUSEMACCtrlFrames, port);
  729. ctrl_stats->MACControlFramesReceived = stat;
  730. }
  731. static void a5psw_vlan_setup(struct a5psw *a5psw, int port)
  732. {
  733. u32 reg;
  734. /* Enable TAG always mode for the port, this is actually controlled
  735. * by VLAN_IN_MODE_ENA field which will be used for PVID insertion
  736. */
  737. reg = A5PSW_VLAN_IN_MODE_TAG_ALWAYS;
  738. reg <<= A5PSW_VLAN_IN_MODE_PORT_SHIFT(port);
  739. a5psw_reg_rmw(a5psw, A5PSW_VLAN_IN_MODE, A5PSW_VLAN_IN_MODE_PORT(port),
  740. reg);
  741. /* Set transparent mode for output frame manipulation, this will depend
  742. * on the VLAN_RES configuration mode
  743. */
  744. reg = A5PSW_VLAN_OUT_MODE_TRANSPARENT;
  745. reg <<= A5PSW_VLAN_OUT_MODE_PORT_SHIFT(port);
  746. a5psw_reg_rmw(a5psw, A5PSW_VLAN_OUT_MODE,
  747. A5PSW_VLAN_OUT_MODE_PORT(port), reg);
  748. }
  749. static int a5psw_setup(struct dsa_switch *ds)
  750. {
  751. struct a5psw *a5psw = ds->priv;
  752. int port, vlan, ret;
  753. struct dsa_port *dp;
  754. u32 reg;
  755. /* Validate that there is only 1 CPU port with index A5PSW_CPU_PORT */
  756. dsa_switch_for_each_cpu_port(dp, ds) {
  757. if (dp->index != A5PSW_CPU_PORT) {
  758. dev_err(a5psw->dev, "Invalid CPU port\n");
  759. return -EINVAL;
  760. }
  761. }
  762. /* Configure management port */
  763. reg = A5PSW_CPU_PORT | A5PSW_MGMT_CFG_ENABLE;
  764. a5psw_reg_writel(a5psw, A5PSW_MGMT_CFG, reg);
  765. /* Set pattern 0 to forward all frame to mgmt port */
  766. a5psw_reg_writel(a5psw, A5PSW_PATTERN_CTRL(A5PSW_PATTERN_MGMTFWD),
  767. A5PSW_PATTERN_CTRL_MGMTFWD);
  768. /* Enable port tagging */
  769. reg = FIELD_PREP(A5PSW_MGMT_TAG_CFG_TAGFIELD, ETH_P_DSA_A5PSW);
  770. reg |= A5PSW_MGMT_TAG_CFG_ENABLE | A5PSW_MGMT_TAG_CFG_ALL_FRAMES;
  771. a5psw_reg_writel(a5psw, A5PSW_MGMT_TAG_CFG, reg);
  772. /* Enable normal switch operation */
  773. reg = A5PSW_LK_ADDR_CTRL_BLOCKING | A5PSW_LK_ADDR_CTRL_LEARNING |
  774. A5PSW_LK_ADDR_CTRL_AGEING | A5PSW_LK_ADDR_CTRL_ALLOW_MIGR |
  775. A5PSW_LK_ADDR_CTRL_CLEAR_TABLE;
  776. a5psw_reg_writel(a5psw, A5PSW_LK_CTRL, reg);
  777. ret = readl_poll_timeout(a5psw->base + A5PSW_LK_CTRL, reg,
  778. !(reg & A5PSW_LK_ADDR_CTRL_CLEAR_TABLE),
  779. A5PSW_LK_BUSY_USEC_POLL, A5PSW_CTRL_TIMEOUT);
  780. if (ret) {
  781. dev_err(a5psw->dev, "Failed to clear lookup table\n");
  782. return ret;
  783. }
  784. /* Reset learn count to 0 */
  785. reg = A5PSW_LK_LEARNCOUNT_MODE_SET;
  786. a5psw_reg_writel(a5psw, A5PSW_LK_LEARNCOUNT, reg);
  787. /* Clear VLAN resource table */
  788. reg = A5PSW_VLAN_RES_WR_PORTMASK | A5PSW_VLAN_RES_WR_TAGMASK;
  789. for (vlan = 0; vlan < A5PSW_VLAN_COUNT; vlan++)
  790. a5psw_reg_writel(a5psw, A5PSW_VLAN_RES(vlan), reg);
  791. /* Reset all ports */
  792. dsa_switch_for_each_port(dp, ds) {
  793. port = dp->index;
  794. /* Reset the port */
  795. a5psw_reg_writel(a5psw, A5PSW_CMD_CFG(port),
  796. A5PSW_CMD_CFG_SW_RESET);
  797. /* Enable only CPU port */
  798. a5psw_port_enable_set(a5psw, port, dsa_port_is_cpu(dp));
  799. if (dsa_port_is_unused(dp))
  800. continue;
  801. /* Enable egress flooding and learning for CPU port */
  802. if (dsa_port_is_cpu(dp)) {
  803. a5psw_flooding_set_resolution(a5psw, port, true);
  804. a5psw_port_learning_set(a5psw, port, true);
  805. }
  806. /* Enable standalone mode for user ports */
  807. if (dsa_port_is_user(dp))
  808. a5psw_port_set_standalone(a5psw, port, true);
  809. a5psw_vlan_setup(a5psw, port);
  810. }
  811. return 0;
  812. }
  813. static const struct phylink_mac_ops a5psw_phylink_mac_ops = {
  814. .mac_select_pcs = a5psw_phylink_mac_select_pcs,
  815. .mac_config = a5psw_phylink_mac_config,
  816. .mac_link_down = a5psw_phylink_mac_link_down,
  817. .mac_link_up = a5psw_phylink_mac_link_up,
  818. };
  819. static const struct dsa_switch_ops a5psw_switch_ops = {
  820. .get_tag_protocol = a5psw_get_tag_protocol,
  821. .setup = a5psw_setup,
  822. .port_disable = a5psw_port_disable,
  823. .port_enable = a5psw_port_enable,
  824. .phylink_get_caps = a5psw_phylink_get_caps,
  825. .port_change_mtu = a5psw_port_change_mtu,
  826. .port_max_mtu = a5psw_port_max_mtu,
  827. .get_sset_count = a5psw_get_sset_count,
  828. .get_strings = a5psw_get_strings,
  829. .get_ethtool_stats = a5psw_get_ethtool_stats,
  830. .get_eth_mac_stats = a5psw_get_eth_mac_stats,
  831. .get_eth_ctrl_stats = a5psw_get_eth_ctrl_stats,
  832. .get_rmon_stats = a5psw_get_rmon_stats,
  833. .set_ageing_time = a5psw_set_ageing_time,
  834. .port_bridge_join = a5psw_port_bridge_join,
  835. .port_bridge_leave = a5psw_port_bridge_leave,
  836. .port_pre_bridge_flags = a5psw_port_pre_bridge_flags,
  837. .port_bridge_flags = a5psw_port_bridge_flags,
  838. .port_stp_state_set = a5psw_port_stp_state_set,
  839. .port_fast_age = a5psw_port_fast_age,
  840. .port_vlan_filtering = a5psw_port_vlan_filtering,
  841. .port_vlan_add = a5psw_port_vlan_add,
  842. .port_vlan_del = a5psw_port_vlan_del,
  843. .port_fdb_add = a5psw_port_fdb_add,
  844. .port_fdb_del = a5psw_port_fdb_del,
  845. .port_fdb_dump = a5psw_port_fdb_dump,
  846. };
  847. static int a5psw_mdio_wait_busy(struct a5psw *a5psw)
  848. {
  849. u32 status;
  850. int err;
  851. err = readl_poll_timeout(a5psw->base + A5PSW_MDIO_CFG_STATUS, status,
  852. !(status & A5PSW_MDIO_CFG_STATUS_BUSY), 10,
  853. 1000 * USEC_PER_MSEC);
  854. if (err)
  855. dev_err(a5psw->dev, "MDIO command timeout\n");
  856. return err;
  857. }
  858. static int a5psw_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
  859. {
  860. struct a5psw *a5psw = bus->priv;
  861. u32 cmd, status;
  862. int ret;
  863. cmd = A5PSW_MDIO_COMMAND_READ;
  864. cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
  865. cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
  866. a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
  867. ret = a5psw_mdio_wait_busy(a5psw);
  868. if (ret)
  869. return ret;
  870. ret = a5psw_reg_readl(a5psw, A5PSW_MDIO_DATA) & A5PSW_MDIO_DATA_MASK;
  871. status = a5psw_reg_readl(a5psw, A5PSW_MDIO_CFG_STATUS);
  872. if (status & A5PSW_MDIO_CFG_STATUS_READERR)
  873. return -EIO;
  874. return ret;
  875. }
  876. static int a5psw_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
  877. u16 phy_data)
  878. {
  879. struct a5psw *a5psw = bus->priv;
  880. u32 cmd;
  881. cmd = FIELD_PREP(A5PSW_MDIO_COMMAND_REG_ADDR, phy_reg);
  882. cmd |= FIELD_PREP(A5PSW_MDIO_COMMAND_PHY_ADDR, phy_id);
  883. a5psw_reg_writel(a5psw, A5PSW_MDIO_COMMAND, cmd);
  884. a5psw_reg_writel(a5psw, A5PSW_MDIO_DATA, phy_data);
  885. return a5psw_mdio_wait_busy(a5psw);
  886. }
  887. static int a5psw_mdio_config(struct a5psw *a5psw, u32 mdio_freq)
  888. {
  889. unsigned long rate;
  890. unsigned long div;
  891. u32 cfgstatus;
  892. rate = clk_get_rate(a5psw->hclk);
  893. div = ((rate / mdio_freq) / 2);
  894. if (div > FIELD_MAX(A5PSW_MDIO_CFG_STATUS_CLKDIV) ||
  895. div < A5PSW_MDIO_CLK_DIV_MIN) {
  896. dev_err(a5psw->dev, "MDIO clock div %ld out of range\n", div);
  897. return -ERANGE;
  898. }
  899. cfgstatus = FIELD_PREP(A5PSW_MDIO_CFG_STATUS_CLKDIV, div);
  900. a5psw_reg_writel(a5psw, A5PSW_MDIO_CFG_STATUS, cfgstatus);
  901. return 0;
  902. }
  903. static int a5psw_probe_mdio(struct a5psw *a5psw, struct device_node *node)
  904. {
  905. struct device *dev = a5psw->dev;
  906. struct mii_bus *bus;
  907. u32 mdio_freq;
  908. int ret;
  909. if (of_property_read_u32(node, "clock-frequency", &mdio_freq))
  910. mdio_freq = A5PSW_MDIO_DEF_FREQ;
  911. ret = a5psw_mdio_config(a5psw, mdio_freq);
  912. if (ret)
  913. return ret;
  914. bus = devm_mdiobus_alloc(dev);
  915. if (!bus)
  916. return -ENOMEM;
  917. bus->name = "a5psw_mdio";
  918. bus->read = a5psw_mdio_read;
  919. bus->write = a5psw_mdio_write;
  920. bus->priv = a5psw;
  921. bus->parent = dev;
  922. snprintf(bus->id, MII_BUS_ID_SIZE, "%s", dev_name(dev));
  923. a5psw->mii_bus = bus;
  924. return devm_of_mdiobus_register(dev, bus, node);
  925. }
  926. static void a5psw_pcs_free(struct a5psw *a5psw)
  927. {
  928. int i;
  929. for (i = 0; i < ARRAY_SIZE(a5psw->pcs); i++) {
  930. if (a5psw->pcs[i])
  931. miic_destroy(a5psw->pcs[i]);
  932. }
  933. }
  934. static int a5psw_pcs_get(struct a5psw *a5psw)
  935. {
  936. struct device_node *ports, *port, *pcs_node;
  937. struct phylink_pcs *pcs;
  938. int ret;
  939. u32 reg;
  940. ports = of_get_child_by_name(a5psw->dev->of_node, "ethernet-ports");
  941. if (!ports)
  942. return -EINVAL;
  943. for_each_available_child_of_node(ports, port) {
  944. pcs_node = of_parse_phandle(port, "pcs-handle", 0);
  945. if (!pcs_node)
  946. continue;
  947. if (of_property_read_u32(port, "reg", &reg)) {
  948. ret = -EINVAL;
  949. goto free_pcs;
  950. }
  951. if (reg >= ARRAY_SIZE(a5psw->pcs)) {
  952. ret = -ENODEV;
  953. goto free_pcs;
  954. }
  955. pcs = miic_create(a5psw->dev, pcs_node);
  956. if (IS_ERR(pcs)) {
  957. dev_err(a5psw->dev, "Failed to create PCS for port %d\n",
  958. reg);
  959. ret = PTR_ERR(pcs);
  960. goto free_pcs;
  961. }
  962. a5psw->pcs[reg] = pcs;
  963. of_node_put(pcs_node);
  964. }
  965. of_node_put(ports);
  966. return 0;
  967. free_pcs:
  968. of_node_put(pcs_node);
  969. of_node_put(port);
  970. of_node_put(ports);
  971. a5psw_pcs_free(a5psw);
  972. return ret;
  973. }
  974. static int a5psw_probe(struct platform_device *pdev)
  975. {
  976. struct device *dev = &pdev->dev;
  977. struct device_node *mdio;
  978. struct dsa_switch *ds;
  979. struct a5psw *a5psw;
  980. int ret;
  981. a5psw = devm_kzalloc(dev, sizeof(*a5psw), GFP_KERNEL);
  982. if (!a5psw)
  983. return -ENOMEM;
  984. a5psw->dev = dev;
  985. mutex_init(&a5psw->lk_lock);
  986. spin_lock_init(&a5psw->reg_lock);
  987. a5psw->base = devm_platform_ioremap_resource(pdev, 0);
  988. if (IS_ERR(a5psw->base))
  989. return PTR_ERR(a5psw->base);
  990. a5psw->bridged_ports = BIT(A5PSW_CPU_PORT);
  991. ret = a5psw_pcs_get(a5psw);
  992. if (ret)
  993. return ret;
  994. a5psw->hclk = devm_clk_get(dev, "hclk");
  995. if (IS_ERR(a5psw->hclk)) {
  996. dev_err(dev, "failed get hclk clock\n");
  997. ret = PTR_ERR(a5psw->hclk);
  998. goto free_pcs;
  999. }
  1000. a5psw->clk = devm_clk_get(dev, "clk");
  1001. if (IS_ERR(a5psw->clk)) {
  1002. dev_err(dev, "failed get clk_switch clock\n");
  1003. ret = PTR_ERR(a5psw->clk);
  1004. goto free_pcs;
  1005. }
  1006. ret = clk_prepare_enable(a5psw->clk);
  1007. if (ret)
  1008. goto free_pcs;
  1009. ret = clk_prepare_enable(a5psw->hclk);
  1010. if (ret)
  1011. goto clk_disable;
  1012. mdio = of_get_child_by_name(dev->of_node, "mdio");
  1013. if (of_device_is_available(mdio)) {
  1014. ret = a5psw_probe_mdio(a5psw, mdio);
  1015. if (ret) {
  1016. of_node_put(mdio);
  1017. dev_err(dev, "Failed to register MDIO: %d\n", ret);
  1018. goto hclk_disable;
  1019. }
  1020. }
  1021. of_node_put(mdio);
  1022. ds = &a5psw->ds;
  1023. ds->dev = dev;
  1024. ds->num_ports = A5PSW_PORTS_NUM;
  1025. ds->ops = &a5psw_switch_ops;
  1026. ds->phylink_mac_ops = &a5psw_phylink_mac_ops;
  1027. ds->priv = a5psw;
  1028. ret = dsa_register_switch(ds);
  1029. if (ret) {
  1030. dev_err(dev, "Failed to register DSA switch: %d\n", ret);
  1031. goto hclk_disable;
  1032. }
  1033. return 0;
  1034. hclk_disable:
  1035. clk_disable_unprepare(a5psw->hclk);
  1036. clk_disable:
  1037. clk_disable_unprepare(a5psw->clk);
  1038. free_pcs:
  1039. a5psw_pcs_free(a5psw);
  1040. return ret;
  1041. }
  1042. static void a5psw_remove(struct platform_device *pdev)
  1043. {
  1044. struct a5psw *a5psw = platform_get_drvdata(pdev);
  1045. if (!a5psw)
  1046. return;
  1047. dsa_unregister_switch(&a5psw->ds);
  1048. a5psw_pcs_free(a5psw);
  1049. clk_disable_unprepare(a5psw->hclk);
  1050. clk_disable_unprepare(a5psw->clk);
  1051. }
  1052. static void a5psw_shutdown(struct platform_device *pdev)
  1053. {
  1054. struct a5psw *a5psw = platform_get_drvdata(pdev);
  1055. if (!a5psw)
  1056. return;
  1057. dsa_switch_shutdown(&a5psw->ds);
  1058. platform_set_drvdata(pdev, NULL);
  1059. }
  1060. static const struct of_device_id a5psw_of_mtable[] = {
  1061. { .compatible = "renesas,rzn1-a5psw", },
  1062. { /* sentinel */ },
  1063. };
  1064. MODULE_DEVICE_TABLE(of, a5psw_of_mtable);
  1065. static struct platform_driver a5psw_driver = {
  1066. .driver = {
  1067. .name = "rzn1_a5psw",
  1068. .of_match_table = a5psw_of_mtable,
  1069. },
  1070. .probe = a5psw_probe,
  1071. .remove_new = a5psw_remove,
  1072. .shutdown = a5psw_shutdown,
  1073. };
  1074. module_platform_driver(a5psw_driver);
  1075. MODULE_LICENSE("GPL");
  1076. MODULE_DESCRIPTION("Renesas RZ/N1 Advanced 5-port Switch driver");
  1077. MODULE_AUTHOR("Clément Léger <clement.leger@bootlin.com>");