1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright Sunplus Technology Co., Ltd.
6 #include <linux/platform_device.h>
7 #include <linux/nvmem-consumer.h>
8 #include <linux/etherdevice.h>
9 #include <linux/netdevice.h>
10 #include <linux/spinlock.h>
11 #include <linux/of_net.h>
12 #include <linux/reset.h>
13 #include <linux/clk.h>
16 #include "spl2sw_register.h"
17 #include "spl2sw_define.h"
18 #include "spl2sw_desc.h"
19 #include "spl2sw_mdio.h"
20 #include "spl2sw_phy.h"
21 #include "spl2sw_int.h"
22 #include "spl2sw_mac.h"
24 /* net device operations */
25 static int spl2sw_ethernet_open(struct net_device *ndev)
27 struct spl2sw_mac *mac = netdev_priv(ndev);
28 struct spl2sw_common *comm = mac->comm;
31 netdev_dbg(ndev, "Open port = %x\n", mac->lan_port);
33 comm->enable |= mac->lan_port;
35 spl2sw_mac_hw_start(comm);
37 /* Enable TX and RX interrupts */
38 mask = readl(comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);
39 mask &= ~(MAC_INT_TX | MAC_INT_RX);
40 writel(mask, comm->l2sw_reg_base + L2SW_SW_INT_MASK_0);
42 phy_start(ndev->phydev);
44 netif_start_queue(ndev);
49 static int spl2sw_ethernet_stop(struct net_device *ndev)
51 struct spl2sw_mac *mac = netdev_priv(ndev);
52 struct spl2sw_common *comm = mac->comm;
54 netif_stop_queue(ndev);
56 comm->enable &= ~mac->lan_port;
58 phy_stop(ndev->phydev);
60 spl2sw_mac_hw_stop(comm);
65 static netdev_tx_t spl2sw_ethernet_start_xmit(struct sk_buff *skb,
66 struct net_device *ndev)
68 struct spl2sw_mac *mac = netdev_priv(ndev);
69 struct spl2sw_common *comm = mac->comm;
70 struct spl2sw_skb_info *skbinfo;
71 struct spl2sw_mac_desc *txdesc;
78 if (unlikely(comm->tx_desc_full == 1)) {
79 /* No TX descriptors left. Wait for tx interrupt. */
80 netdev_dbg(ndev, "TX descriptor queue full when xmit!\n");
81 return NETDEV_TX_BUSY;
84 /* If skb size is shorter than ETH_ZLEN (60), pad it with 0. */
85 if (unlikely(skb->len < ETH_ZLEN)) {
86 if (skb_padto(skb, ETH_ZLEN))
89 skb_put(skb, ETH_ZLEN - skb->len);
92 mapping = dma_map_single(&comm->pdev->dev, skb->data,
93 skb->len, DMA_TO_DEVICE);
94 if (dma_mapping_error(&comm->pdev->dev, mapping)) {
95 ndev->stats.tx_errors++;
100 spin_lock_irqsave(&comm->tx_lock, flags);
102 tx_pos = comm->tx_pos;
103 txdesc = &comm->tx_desc[tx_pos];
104 skbinfo = &comm->tx_temp_skb_info[tx_pos];
105 skbinfo->mapping = mapping;
106 skbinfo->len = skb->len;
109 /* Set up a TX descriptor */
110 cmd1 = TXD_OWN | TXD_SOP | TXD_EOP | (mac->to_vlan << 12) |
111 (skb->len & TXD_PKT_LEN);
112 cmd2 = skb->len & TXD_BUF_LEN1;
114 if (tx_pos == (TX_DESC_NUM - 1))
117 txdesc->addr1 = skbinfo->mapping;
119 wmb(); /* Set TXD_OWN after other fields are effective. */
122 /* Move tx_pos to next position */
123 tx_pos = ((tx_pos + 1) == TX_DESC_NUM) ? 0 : tx_pos + 1;
125 if (unlikely(tx_pos == comm->tx_done_pos)) {
126 netif_stop_queue(ndev);
127 comm->tx_desc_full = 1;
129 comm->tx_pos = tx_pos;
130 wmb(); /* make sure settings are effective. */
132 /* Trigger mac to transmit */
133 writel(MAC_TRIG_L_SOC0, comm->l2sw_reg_base + L2SW_CPU_TX_TRIG);
135 spin_unlock_irqrestore(&comm->tx_lock, flags);
139 static void spl2sw_ethernet_set_rx_mode(struct net_device *ndev)
141 struct spl2sw_mac *mac = netdev_priv(ndev);
143 spl2sw_mac_rx_mode_set(mac);
146 static int spl2sw_ethernet_set_mac_address(struct net_device *ndev, void *addr)
148 struct spl2sw_mac *mac = netdev_priv(ndev);
151 err = eth_mac_addr(ndev, addr);
155 /* Delete the old MAC address */
156 netdev_dbg(ndev, "Old Ethernet (MAC) address = %pM\n", mac->mac_addr);
157 if (is_valid_ether_addr(mac->mac_addr)) {
158 err = spl2sw_mac_addr_del(mac);
163 /* Set the MAC address */
164 ether_addr_copy(mac->mac_addr, ndev->dev_addr);
165 return spl2sw_mac_addr_add(mac);
168 static void spl2sw_ethernet_tx_timeout(struct net_device *ndev, unsigned int txqueue)
170 struct spl2sw_mac *mac = netdev_priv(ndev);
171 struct spl2sw_common *comm = mac->comm;
175 netdev_err(ndev, "TX timed out!\n");
176 ndev->stats.tx_errors++;
178 spin_lock_irqsave(&comm->tx_lock, flags);
180 for (i = 0; i < MAX_NETDEV_NUM; i++)
182 netif_stop_queue(comm->ndev[i]);
184 spl2sw_mac_soft_reset(comm);
186 /* Accept TX packets again. */
187 for (i = 0; i < MAX_NETDEV_NUM; i++)
189 netif_trans_update(comm->ndev[i]);
190 netif_wake_queue(comm->ndev[i]);
193 spin_unlock_irqrestore(&comm->tx_lock, flags);
196 static const struct net_device_ops netdev_ops = {
197 .ndo_open = spl2sw_ethernet_open,
198 .ndo_stop = spl2sw_ethernet_stop,
199 .ndo_start_xmit = spl2sw_ethernet_start_xmit,
200 .ndo_set_rx_mode = spl2sw_ethernet_set_rx_mode,
201 .ndo_set_mac_address = spl2sw_ethernet_set_mac_address,
202 .ndo_do_ioctl = phy_do_ioctl,
203 .ndo_tx_timeout = spl2sw_ethernet_tx_timeout,
206 static void spl2sw_check_mac_vendor_id_and_convert(u8 *mac_addr)
208 /* Byte order of MAC address of some samples are reversed.
209 * Check vendor id and convert byte order if it is wrong.
210 * OUI of Sunplus: fc:4b:bc
212 if (mac_addr[5] == 0xfc && mac_addr[4] == 0x4b && mac_addr[3] == 0xbc &&
213 (mac_addr[0] != 0xfc || mac_addr[1] != 0x4b || mac_addr[2] != 0xbc)) {
215 swap(mac_addr[0], mac_addr[5]);
216 swap(mac_addr[1], mac_addr[4]);
217 swap(mac_addr[2], mac_addr[3]);
221 static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node *np,
224 struct nvmem_cell *cell;
228 /* Get nvmem cell of mac-address from dts. */
229 cell = of_nvmem_cell_get(np, "mac-address");
231 return PTR_ERR(cell);
233 /* Read mac address from nvmem cell. */
234 mac = nvmem_cell_read(cell, &len);
235 nvmem_cell_put(cell);
239 if (len != ETH_ALEN) {
241 dev_info(dev, "Invalid length of mac address in nvmem!\n");
245 /* Byte order of some samples are reversed.
246 * Convert byte order here.
248 spl2sw_check_mac_vendor_id_and_convert(mac);
250 /* Check if mac address is valid */
251 if (!is_valid_ether_addr(mac)) {
252 dev_info(dev, "Invalid mac address in nvmem (%pM)!\n", mac);
257 ether_addr_copy(addrbuf, mac);
262 static u32 spl2sw_init_netdev(struct platform_device *pdev, u8 *mac_addr,
263 struct net_device **r_ndev)
265 struct net_device *ndev;
266 struct spl2sw_mac *mac;
269 /* Allocate the devices, and also allocate spl2sw_mac,
270 * we can get it by netdev_priv().
272 ndev = devm_alloc_etherdev(&pdev->dev, sizeof(*mac));
277 SET_NETDEV_DEV(ndev, &pdev->dev);
278 ndev->netdev_ops = &netdev_ops;
279 mac = netdev_priv(ndev);
281 ether_addr_copy(mac->mac_addr, mac_addr);
283 eth_hw_addr_set(ndev, mac_addr);
284 dev_info(&pdev->dev, "Ethernet (MAC) address = %pM\n", mac_addr);
286 ret = register_netdev(ndev);
288 dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n",
294 netdev_dbg(ndev, "Registered net device \"%s\" successfully.\n", ndev->name);
300 static struct device_node *spl2sw_get_eth_child_node(struct device_node *ether_np, int id)
302 struct device_node *port_np;
305 for_each_child_of_node(ether_np, port_np) {
306 /* It is not a 'port' node, continue. */
307 if (strcmp(port_np->name, "port"))
310 if (of_property_read_u32(port_np, "reg", &port_id) < 0)
321 static int spl2sw_probe(struct platform_device *pdev)
323 struct device_node *eth_ports_np;
324 struct device_node *port_np;
325 struct spl2sw_common *comm;
326 struct device_node *phy_np;
327 phy_interface_t phy_mode;
328 struct net_device *ndev;
329 struct spl2sw_mac *mac;
330 u8 mac_addr[ETH_ALEN];
333 if (platform_get_drvdata(pdev))
336 /* Allocate memory for 'spl2sw_common' area. */
337 comm = devm_kzalloc(&pdev->dev, sizeof(*comm), GFP_KERNEL);
342 platform_set_drvdata(pdev, comm);
344 spin_lock_init(&comm->tx_lock);
345 spin_lock_init(&comm->mdio_lock);
346 spin_lock_init(&comm->int_mask_lock);
348 /* Get memory resource 0 from dts. */
349 comm->l2sw_reg_base = devm_platform_ioremap_resource(pdev, 0);
350 if (IS_ERR(comm->l2sw_reg_base))
351 return PTR_ERR(comm->l2sw_reg_base);
353 /* Get irq resource from dts. */
354 ret = platform_get_irq(pdev, 0);
359 /* Get clock controller. */
360 comm->clk = devm_clk_get(&pdev->dev, NULL);
361 if (IS_ERR(comm->clk)) {
362 dev_err_probe(&pdev->dev, PTR_ERR(comm->clk),
363 "Failed to retrieve clock controller!\n");
364 return PTR_ERR(comm->clk);
367 /* Get reset controller. */
368 comm->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
369 if (IS_ERR(comm->rstc)) {
370 dev_err_probe(&pdev->dev, PTR_ERR(comm->rstc),
371 "Failed to retrieve reset controller!\n");
372 return PTR_ERR(comm->rstc);
376 ret = clk_prepare_enable(comm->clk);
382 reset_control_assert(comm->rstc);
384 reset_control_deassert(comm->rstc);
385 usleep_range(1000, 2000);
388 ret = devm_request_irq(&pdev->dev, irq, spl2sw_ethernet_interrupt, 0,
389 dev_name(&pdev->dev), comm);
391 dev_err(&pdev->dev, "Failed to request irq #%d!\n", irq);
392 goto out_clk_disable;
395 /* Initialize TX and RX descriptors. */
396 ret = spl2sw_descs_init(comm);
398 dev_err(&pdev->dev, "Fail to initialize mac descriptors!\n");
399 spl2sw_descs_free(comm);
400 goto out_clk_disable;
403 /* Initialize MAC. */
404 spl2sw_mac_init(comm);
406 /* Initialize mdio bus */
407 ret = spl2sw_mdio_init(comm);
409 dev_err(&pdev->dev, "Failed to initialize mdio bus!\n");
410 goto out_clk_disable;
413 /* Get child node ethernet-ports. */
414 eth_ports_np = of_get_child_by_name(pdev->dev.of_node, "ethernet-ports");
416 dev_err(&pdev->dev, "No ethernet-ports child node found!\n");
421 for (i = 0; i < MAX_NETDEV_NUM; i++) {
422 /* Get port@i of node ethernet-ports. */
423 port_np = spl2sw_get_eth_child_node(eth_ports_np, i);
428 if (of_get_phy_mode(port_np, &phy_mode)) {
429 dev_err(&pdev->dev, "Failed to get phy-mode property of port@%d!\n",
434 /* Get phy-handle. */
435 phy_np = of_parse_phandle(port_np, "phy-handle", 0);
437 dev_err(&pdev->dev, "Failed to get phy-handle property of port@%d!\n",
442 /* Get mac-address from nvmem. */
443 ret = spl2sw_nvmem_get_mac_address(&pdev->dev, port_np, mac_addr);
444 if (ret == -EPROBE_DEFER) {
445 goto out_unregister_dev;
447 dev_info(&pdev->dev, "Generate a random mac address!\n");
448 eth_random_addr(mac_addr);
451 /* Initialize the net device. */
452 ret = spl2sw_init_netdev(pdev, mac_addr, &ndev);
454 goto out_unregister_dev;
457 comm->ndev[i] = ndev;
458 mac = netdev_priv(ndev);
459 mac->phy_node = phy_np;
460 mac->phy_mode = phy_mode;
463 mac->lan_port = 0x1 << i; /* forward to port i */
464 mac->to_vlan = 0x1 << i; /* vlan group: i */
465 mac->vlan_id = i; /* vlan group: i */
467 /* Set MAC address */
468 ret = spl2sw_mac_addr_add(mac);
470 goto out_unregister_dev;
472 spl2sw_mac_rx_mode_set(mac);
475 /* Find first valid net device. */
476 for (i = 0; i < MAX_NETDEV_NUM; i++) {
480 if (i >= MAX_NETDEV_NUM) {
481 dev_err(&pdev->dev, "No valid ethernet port!\n");
486 /* Save first valid net device */
487 ndev = comm->ndev[i];
489 ret = spl2sw_phy_connect(comm);
491 netdev_err(ndev, "Failed to connect phy!\n");
492 goto out_unregister_dev;
495 /* Add and enable napi. */
496 netif_napi_add(ndev, &comm->rx_napi, spl2sw_rx_poll);
497 napi_enable(&comm->rx_napi);
498 netif_napi_add_tx(ndev, &comm->tx_napi, spl2sw_tx_poll);
499 napi_enable(&comm->tx_napi);
503 for (i = 0; i < MAX_NETDEV_NUM; i++)
505 unregister_netdev(comm->ndev[i]);
508 spl2sw_mdio_remove(comm);
511 clk_disable_unprepare(comm->clk);
515 static int spl2sw_remove(struct platform_device *pdev)
517 struct spl2sw_common *comm;
520 comm = platform_get_drvdata(pdev);
522 spl2sw_phy_remove(comm);
524 /* Unregister and free net device. */
525 for (i = 0; i < MAX_NETDEV_NUM; i++)
527 unregister_netdev(comm->ndev[i]);
530 spl2sw_mac_hw_stop(comm);
531 spl2sw_descs_free(comm);
533 /* Disable and delete napi. */
534 napi_disable(&comm->rx_napi);
535 netif_napi_del(&comm->rx_napi);
536 napi_disable(&comm->tx_napi);
537 netif_napi_del(&comm->tx_napi);
539 spl2sw_mdio_remove(comm);
541 clk_disable_unprepare(comm->clk);
546 static const struct of_device_id spl2sw_of_match[] = {
547 {.compatible = "sunplus,sp7021-emac"},
551 MODULE_DEVICE_TABLE(of, spl2sw_of_match);
553 static struct platform_driver spl2sw_driver = {
554 .probe = spl2sw_probe,
555 .remove = spl2sw_remove,
557 .name = "sp7021_emac",
558 .of_match_table = spl2sw_of_match,
562 module_platform_driver(spl2sw_driver);
564 MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>");
565 MODULE_DESCRIPTION("Sunplus Dual 10M/100M Ethernet driver");
566 MODULE_LICENSE("GPL");