1*fd3040b9SWells Lu // SPDX-License-Identifier: GPL-2.0 2*fd3040b9SWells Lu /* Copyright Sunplus Technology Co., Ltd. 3*fd3040b9SWells Lu * All rights reserved. 4*fd3040b9SWells Lu */ 5*fd3040b9SWells Lu 6*fd3040b9SWells Lu #include <linux/platform_device.h> 7*fd3040b9SWells Lu #include <linux/nvmem-consumer.h> 8*fd3040b9SWells Lu #include <linux/etherdevice.h> 9*fd3040b9SWells Lu #include <linux/netdevice.h> 10*fd3040b9SWells Lu #include <linux/spinlock.h> 11*fd3040b9SWells Lu #include <linux/of_net.h> 12*fd3040b9SWells Lu #include <linux/reset.h> 13*fd3040b9SWells Lu #include <linux/clk.h> 14*fd3040b9SWells Lu #include <linux/of.h> 15*fd3040b9SWells Lu 16*fd3040b9SWells Lu #include "spl2sw_register.h" 17*fd3040b9SWells Lu #include "spl2sw_define.h" 18*fd3040b9SWells Lu #include "spl2sw_desc.h" 19*fd3040b9SWells Lu #include "spl2sw_mdio.h" 20*fd3040b9SWells Lu #include "spl2sw_phy.h" 21*fd3040b9SWells Lu #include "spl2sw_int.h" 22*fd3040b9SWells Lu #include "spl2sw_mac.h" 23*fd3040b9SWells Lu 24*fd3040b9SWells Lu /* net device operations */ 25*fd3040b9SWells Lu static int spl2sw_ethernet_open(struct net_device *ndev) 26*fd3040b9SWells Lu { 27*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 28*fd3040b9SWells Lu struct spl2sw_common *comm = mac->comm; 29*fd3040b9SWells Lu u32 mask; 30*fd3040b9SWells Lu 31*fd3040b9SWells Lu netdev_dbg(ndev, "Open port = %x\n", mac->lan_port); 32*fd3040b9SWells Lu 33*fd3040b9SWells Lu comm->enable |= mac->lan_port; 34*fd3040b9SWells Lu 35*fd3040b9SWells Lu spl2sw_mac_hw_start(comm); 36*fd3040b9SWells Lu 37*fd3040b9SWells Lu /* Enable TX and RX interrupts */ 38*fd3040b9SWells Lu mask = readl(comm->l2sw_reg_base + L2SW_SW_INT_MASK_0); 39*fd3040b9SWells Lu mask &= ~(MAC_INT_TX | MAC_INT_RX); 40*fd3040b9SWells Lu writel(mask, comm->l2sw_reg_base + L2SW_SW_INT_MASK_0); 41*fd3040b9SWells Lu 42*fd3040b9SWells Lu phy_start(ndev->phydev); 43*fd3040b9SWells Lu 44*fd3040b9SWells Lu netif_start_queue(ndev); 45*fd3040b9SWells Lu 46*fd3040b9SWells Lu return 0; 47*fd3040b9SWells Lu } 48*fd3040b9SWells Lu 49*fd3040b9SWells Lu static int spl2sw_ethernet_stop(struct net_device *ndev) 50*fd3040b9SWells Lu { 51*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 52*fd3040b9SWells Lu struct spl2sw_common *comm = mac->comm; 53*fd3040b9SWells Lu 54*fd3040b9SWells Lu netif_stop_queue(ndev); 55*fd3040b9SWells Lu 56*fd3040b9SWells Lu comm->enable &= ~mac->lan_port; 57*fd3040b9SWells Lu 58*fd3040b9SWells Lu phy_stop(ndev->phydev); 59*fd3040b9SWells Lu 60*fd3040b9SWells Lu spl2sw_mac_hw_stop(comm); 61*fd3040b9SWells Lu 62*fd3040b9SWells Lu return 0; 63*fd3040b9SWells Lu } 64*fd3040b9SWells Lu 65*fd3040b9SWells Lu static int spl2sw_ethernet_start_xmit(struct sk_buff *skb, struct net_device *ndev) 66*fd3040b9SWells Lu { 67*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 68*fd3040b9SWells Lu struct spl2sw_common *comm = mac->comm; 69*fd3040b9SWells Lu struct spl2sw_skb_info *skbinfo; 70*fd3040b9SWells Lu struct spl2sw_mac_desc *txdesc; 71*fd3040b9SWells Lu unsigned long flags; 72*fd3040b9SWells Lu u32 mapping; 73*fd3040b9SWells Lu u32 tx_pos; 74*fd3040b9SWells Lu u32 cmd1; 75*fd3040b9SWells Lu u32 cmd2; 76*fd3040b9SWells Lu 77*fd3040b9SWells Lu if (unlikely(comm->tx_desc_full == 1)) { 78*fd3040b9SWells Lu /* No TX descriptors left. Wait for tx interrupt. */ 79*fd3040b9SWells Lu netdev_dbg(ndev, "TX descriptor queue full when xmit!\n"); 80*fd3040b9SWells Lu return NETDEV_TX_BUSY; 81*fd3040b9SWells Lu } 82*fd3040b9SWells Lu 83*fd3040b9SWells Lu /* If skb size is shorter than ETH_ZLEN (60), pad it with 0. */ 84*fd3040b9SWells Lu if (unlikely(skb->len < ETH_ZLEN)) { 85*fd3040b9SWells Lu if (skb_padto(skb, ETH_ZLEN)) 86*fd3040b9SWells Lu return NETDEV_TX_OK; 87*fd3040b9SWells Lu 88*fd3040b9SWells Lu skb_put(skb, ETH_ZLEN - skb->len); 89*fd3040b9SWells Lu } 90*fd3040b9SWells Lu 91*fd3040b9SWells Lu mapping = dma_map_single(&comm->pdev->dev, skb->data, 92*fd3040b9SWells Lu skb->len, DMA_TO_DEVICE); 93*fd3040b9SWells Lu if (dma_mapping_error(&comm->pdev->dev, mapping)) { 94*fd3040b9SWells Lu ndev->stats.tx_errors++; 95*fd3040b9SWells Lu dev_kfree_skb(skb); 96*fd3040b9SWells Lu return NETDEV_TX_OK; 97*fd3040b9SWells Lu } 98*fd3040b9SWells Lu 99*fd3040b9SWells Lu spin_lock_irqsave(&comm->tx_lock, flags); 100*fd3040b9SWells Lu 101*fd3040b9SWells Lu tx_pos = comm->tx_pos; 102*fd3040b9SWells Lu txdesc = &comm->tx_desc[tx_pos]; 103*fd3040b9SWells Lu skbinfo = &comm->tx_temp_skb_info[tx_pos]; 104*fd3040b9SWells Lu skbinfo->mapping = mapping; 105*fd3040b9SWells Lu skbinfo->len = skb->len; 106*fd3040b9SWells Lu skbinfo->skb = skb; 107*fd3040b9SWells Lu 108*fd3040b9SWells Lu /* Set up a TX descriptor */ 109*fd3040b9SWells Lu cmd1 = TXD_OWN | TXD_SOP | TXD_EOP | (mac->to_vlan << 12) | 110*fd3040b9SWells Lu (skb->len & TXD_PKT_LEN); 111*fd3040b9SWells Lu cmd2 = skb->len & TXD_BUF_LEN1; 112*fd3040b9SWells Lu 113*fd3040b9SWells Lu if (tx_pos == (TX_DESC_NUM - 1)) 114*fd3040b9SWells Lu cmd2 |= TXD_EOR; 115*fd3040b9SWells Lu 116*fd3040b9SWells Lu txdesc->addr1 = skbinfo->mapping; 117*fd3040b9SWells Lu txdesc->cmd2 = cmd2; 118*fd3040b9SWells Lu wmb(); /* Set TXD_OWN after other fields are effective. */ 119*fd3040b9SWells Lu txdesc->cmd1 = cmd1; 120*fd3040b9SWells Lu 121*fd3040b9SWells Lu /* Move tx_pos to next position */ 122*fd3040b9SWells Lu tx_pos = ((tx_pos + 1) == TX_DESC_NUM) ? 0 : tx_pos + 1; 123*fd3040b9SWells Lu 124*fd3040b9SWells Lu if (unlikely(tx_pos == comm->tx_done_pos)) { 125*fd3040b9SWells Lu netif_stop_queue(ndev); 126*fd3040b9SWells Lu comm->tx_desc_full = 1; 127*fd3040b9SWells Lu } 128*fd3040b9SWells Lu comm->tx_pos = tx_pos; 129*fd3040b9SWells Lu wmb(); /* make sure settings are effective. */ 130*fd3040b9SWells Lu 131*fd3040b9SWells Lu /* Trigger mac to transmit */ 132*fd3040b9SWells Lu writel(MAC_TRIG_L_SOC0, comm->l2sw_reg_base + L2SW_CPU_TX_TRIG); 133*fd3040b9SWells Lu 134*fd3040b9SWells Lu spin_unlock_irqrestore(&comm->tx_lock, flags); 135*fd3040b9SWells Lu return NETDEV_TX_OK; 136*fd3040b9SWells Lu } 137*fd3040b9SWells Lu 138*fd3040b9SWells Lu static void spl2sw_ethernet_set_rx_mode(struct net_device *ndev) 139*fd3040b9SWells Lu { 140*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 141*fd3040b9SWells Lu 142*fd3040b9SWells Lu spl2sw_mac_rx_mode_set(mac); 143*fd3040b9SWells Lu } 144*fd3040b9SWells Lu 145*fd3040b9SWells Lu static int spl2sw_ethernet_set_mac_address(struct net_device *ndev, void *addr) 146*fd3040b9SWells Lu { 147*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 148*fd3040b9SWells Lu int err; 149*fd3040b9SWells Lu 150*fd3040b9SWells Lu err = eth_mac_addr(ndev, addr); 151*fd3040b9SWells Lu if (err) 152*fd3040b9SWells Lu return err; 153*fd3040b9SWells Lu 154*fd3040b9SWells Lu /* Delete the old MAC address */ 155*fd3040b9SWells Lu netdev_dbg(ndev, "Old Ethernet (MAC) address = %pM\n", mac->mac_addr); 156*fd3040b9SWells Lu if (is_valid_ether_addr(mac->mac_addr)) { 157*fd3040b9SWells Lu err = spl2sw_mac_addr_del(mac); 158*fd3040b9SWells Lu if (err) 159*fd3040b9SWells Lu return err; 160*fd3040b9SWells Lu } 161*fd3040b9SWells Lu 162*fd3040b9SWells Lu /* Set the MAC address */ 163*fd3040b9SWells Lu ether_addr_copy(mac->mac_addr, ndev->dev_addr); 164*fd3040b9SWells Lu return spl2sw_mac_addr_add(mac); 165*fd3040b9SWells Lu } 166*fd3040b9SWells Lu 167*fd3040b9SWells Lu static void spl2sw_ethernet_tx_timeout(struct net_device *ndev, unsigned int txqueue) 168*fd3040b9SWells Lu { 169*fd3040b9SWells Lu struct spl2sw_mac *mac = netdev_priv(ndev); 170*fd3040b9SWells Lu struct spl2sw_common *comm = mac->comm; 171*fd3040b9SWells Lu unsigned long flags; 172*fd3040b9SWells Lu int i; 173*fd3040b9SWells Lu 174*fd3040b9SWells Lu netdev_err(ndev, "TX timed out!\n"); 175*fd3040b9SWells Lu ndev->stats.tx_errors++; 176*fd3040b9SWells Lu 177*fd3040b9SWells Lu spin_lock_irqsave(&comm->tx_lock, flags); 178*fd3040b9SWells Lu 179*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) 180*fd3040b9SWells Lu if (comm->ndev[i]) 181*fd3040b9SWells Lu netif_stop_queue(comm->ndev[i]); 182*fd3040b9SWells Lu 183*fd3040b9SWells Lu spl2sw_mac_soft_reset(comm); 184*fd3040b9SWells Lu 185*fd3040b9SWells Lu /* Accept TX packets again. */ 186*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) 187*fd3040b9SWells Lu if (comm->ndev[i]) { 188*fd3040b9SWells Lu netif_trans_update(comm->ndev[i]); 189*fd3040b9SWells Lu netif_wake_queue(comm->ndev[i]); 190*fd3040b9SWells Lu } 191*fd3040b9SWells Lu 192*fd3040b9SWells Lu spin_unlock_irqrestore(&comm->tx_lock, flags); 193*fd3040b9SWells Lu } 194*fd3040b9SWells Lu 195*fd3040b9SWells Lu static const struct net_device_ops netdev_ops = { 196*fd3040b9SWells Lu .ndo_open = spl2sw_ethernet_open, 197*fd3040b9SWells Lu .ndo_stop = spl2sw_ethernet_stop, 198*fd3040b9SWells Lu .ndo_start_xmit = spl2sw_ethernet_start_xmit, 199*fd3040b9SWells Lu .ndo_set_rx_mode = spl2sw_ethernet_set_rx_mode, 200*fd3040b9SWells Lu .ndo_set_mac_address = spl2sw_ethernet_set_mac_address, 201*fd3040b9SWells Lu .ndo_do_ioctl = phy_do_ioctl, 202*fd3040b9SWells Lu .ndo_tx_timeout = spl2sw_ethernet_tx_timeout, 203*fd3040b9SWells Lu }; 204*fd3040b9SWells Lu 205*fd3040b9SWells Lu static void spl2sw_check_mac_vendor_id_and_convert(u8 *mac_addr) 206*fd3040b9SWells Lu { 207*fd3040b9SWells Lu u8 tmp; 208*fd3040b9SWells Lu 209*fd3040b9SWells Lu /* Byte order of MAC address of some samples are reversed. 210*fd3040b9SWells Lu * Check vendor id and convert byte order if it is wrong. 211*fd3040b9SWells Lu * OUI of Sunplus: fc:4b:bc 212*fd3040b9SWells Lu */ 213*fd3040b9SWells Lu if (mac_addr[5] == 0xfc && mac_addr[4] == 0x4b && mac_addr[3] == 0xbc && 214*fd3040b9SWells Lu (mac_addr[0] != 0xfc || mac_addr[1] != 0x4b || mac_addr[2] != 0xbc)) { 215*fd3040b9SWells Lu /* Swap mac_addr[0] and mac_addr[5] */ 216*fd3040b9SWells Lu tmp = mac_addr[0]; 217*fd3040b9SWells Lu mac_addr[0] = mac_addr[5]; 218*fd3040b9SWells Lu mac_addr[5] = tmp; 219*fd3040b9SWells Lu 220*fd3040b9SWells Lu /* Swap mac_addr[1] and mac_addr[4] */ 221*fd3040b9SWells Lu tmp = mac_addr[1]; 222*fd3040b9SWells Lu mac_addr[1] = mac_addr[4]; 223*fd3040b9SWells Lu mac_addr[4] = tmp; 224*fd3040b9SWells Lu 225*fd3040b9SWells Lu /* Swap mac_addr[2] and mac_addr[3] */ 226*fd3040b9SWells Lu tmp = mac_addr[2]; 227*fd3040b9SWells Lu mac_addr[2] = mac_addr[3]; 228*fd3040b9SWells Lu mac_addr[3] = tmp; 229*fd3040b9SWells Lu } 230*fd3040b9SWells Lu } 231*fd3040b9SWells Lu 232*fd3040b9SWells Lu static int spl2sw_nvmem_get_mac_address(struct device *dev, struct device_node *np, 233*fd3040b9SWells Lu void *addrbuf) 234*fd3040b9SWells Lu { 235*fd3040b9SWells Lu struct nvmem_cell *cell; 236*fd3040b9SWells Lu ssize_t len; 237*fd3040b9SWells Lu u8 *mac; 238*fd3040b9SWells Lu 239*fd3040b9SWells Lu /* Get nvmem cell of mac-address from dts. */ 240*fd3040b9SWells Lu cell = of_nvmem_cell_get(np, "mac-address"); 241*fd3040b9SWells Lu if (IS_ERR(cell)) 242*fd3040b9SWells Lu return PTR_ERR(cell); 243*fd3040b9SWells Lu 244*fd3040b9SWells Lu /* Read mac address from nvmem cell. */ 245*fd3040b9SWells Lu mac = nvmem_cell_read(cell, &len); 246*fd3040b9SWells Lu nvmem_cell_put(cell); 247*fd3040b9SWells Lu if (IS_ERR(mac)) 248*fd3040b9SWells Lu return PTR_ERR(mac); 249*fd3040b9SWells Lu 250*fd3040b9SWells Lu if (len != ETH_ALEN) { 251*fd3040b9SWells Lu kfree(mac); 252*fd3040b9SWells Lu dev_info(dev, "Invalid length of mac address in nvmem!\n"); 253*fd3040b9SWells Lu return -EINVAL; 254*fd3040b9SWells Lu } 255*fd3040b9SWells Lu 256*fd3040b9SWells Lu /* Byte order of some samples are reversed. 257*fd3040b9SWells Lu * Convert byte order here. 258*fd3040b9SWells Lu */ 259*fd3040b9SWells Lu spl2sw_check_mac_vendor_id_and_convert(mac); 260*fd3040b9SWells Lu 261*fd3040b9SWells Lu /* Check if mac address is valid */ 262*fd3040b9SWells Lu if (!is_valid_ether_addr(mac)) { 263*fd3040b9SWells Lu kfree(mac); 264*fd3040b9SWells Lu dev_info(dev, "Invalid mac address in nvmem (%pM)!\n", mac); 265*fd3040b9SWells Lu return -EINVAL; 266*fd3040b9SWells Lu } 267*fd3040b9SWells Lu 268*fd3040b9SWells Lu ether_addr_copy(addrbuf, mac); 269*fd3040b9SWells Lu kfree(mac); 270*fd3040b9SWells Lu return 0; 271*fd3040b9SWells Lu } 272*fd3040b9SWells Lu 273*fd3040b9SWells Lu static u32 spl2sw_init_netdev(struct platform_device *pdev, u8 *mac_addr, 274*fd3040b9SWells Lu struct net_device **r_ndev) 275*fd3040b9SWells Lu { 276*fd3040b9SWells Lu struct net_device *ndev; 277*fd3040b9SWells Lu struct spl2sw_mac *mac; 278*fd3040b9SWells Lu int ret; 279*fd3040b9SWells Lu 280*fd3040b9SWells Lu /* Allocate the devices, and also allocate spl2sw_mac, 281*fd3040b9SWells Lu * we can get it by netdev_priv(). 282*fd3040b9SWells Lu */ 283*fd3040b9SWells Lu ndev = devm_alloc_etherdev(&pdev->dev, sizeof(*mac)); 284*fd3040b9SWells Lu if (!ndev) { 285*fd3040b9SWells Lu *r_ndev = NULL; 286*fd3040b9SWells Lu return -ENOMEM; 287*fd3040b9SWells Lu } 288*fd3040b9SWells Lu SET_NETDEV_DEV(ndev, &pdev->dev); 289*fd3040b9SWells Lu ndev->netdev_ops = &netdev_ops; 290*fd3040b9SWells Lu mac = netdev_priv(ndev); 291*fd3040b9SWells Lu mac->ndev = ndev; 292*fd3040b9SWells Lu ether_addr_copy(mac->mac_addr, mac_addr); 293*fd3040b9SWells Lu 294*fd3040b9SWells Lu eth_hw_addr_set(ndev, mac_addr); 295*fd3040b9SWells Lu dev_info(&pdev->dev, "Ethernet (MAC) address = %pM\n", mac_addr); 296*fd3040b9SWells Lu 297*fd3040b9SWells Lu ret = register_netdev(ndev); 298*fd3040b9SWells Lu if (ret) { 299*fd3040b9SWells Lu dev_err(&pdev->dev, "Failed to register net device \"%s\"!\n", 300*fd3040b9SWells Lu ndev->name); 301*fd3040b9SWells Lu free_netdev(ndev); 302*fd3040b9SWells Lu *r_ndev = NULL; 303*fd3040b9SWells Lu return ret; 304*fd3040b9SWells Lu } 305*fd3040b9SWells Lu netdev_dbg(ndev, "Registered net device \"%s\" successfully.\n", ndev->name); 306*fd3040b9SWells Lu 307*fd3040b9SWells Lu *r_ndev = ndev; 308*fd3040b9SWells Lu return 0; 309*fd3040b9SWells Lu } 310*fd3040b9SWells Lu 311*fd3040b9SWells Lu static struct device_node *spl2sw_get_eth_child_node(struct device_node *ether_np, int id) 312*fd3040b9SWells Lu { 313*fd3040b9SWells Lu struct device_node *port_np; 314*fd3040b9SWells Lu int port_id; 315*fd3040b9SWells Lu 316*fd3040b9SWells Lu for_each_child_of_node(ether_np, port_np) { 317*fd3040b9SWells Lu /* It is not a 'port' node, continue. */ 318*fd3040b9SWells Lu if (strcmp(port_np->name, "port")) 319*fd3040b9SWells Lu continue; 320*fd3040b9SWells Lu 321*fd3040b9SWells Lu if (of_property_read_u32(port_np, "reg", &port_id) < 0) 322*fd3040b9SWells Lu continue; 323*fd3040b9SWells Lu 324*fd3040b9SWells Lu if (port_id == id) 325*fd3040b9SWells Lu return port_np; 326*fd3040b9SWells Lu } 327*fd3040b9SWells Lu 328*fd3040b9SWells Lu /* Not found! */ 329*fd3040b9SWells Lu return NULL; 330*fd3040b9SWells Lu } 331*fd3040b9SWells Lu 332*fd3040b9SWells Lu static int spl2sw_probe(struct platform_device *pdev) 333*fd3040b9SWells Lu { 334*fd3040b9SWells Lu struct device_node *eth_ports_np; 335*fd3040b9SWells Lu struct device_node *port_np; 336*fd3040b9SWells Lu struct spl2sw_common *comm; 337*fd3040b9SWells Lu struct device_node *phy_np; 338*fd3040b9SWells Lu phy_interface_t phy_mode; 339*fd3040b9SWells Lu struct net_device *ndev; 340*fd3040b9SWells Lu struct spl2sw_mac *mac; 341*fd3040b9SWells Lu u8 mac_addr[ETH_ALEN]; 342*fd3040b9SWells Lu int irq, i, ret; 343*fd3040b9SWells Lu 344*fd3040b9SWells Lu if (platform_get_drvdata(pdev)) 345*fd3040b9SWells Lu return -ENODEV; 346*fd3040b9SWells Lu 347*fd3040b9SWells Lu /* Allocate memory for 'spl2sw_common' area. */ 348*fd3040b9SWells Lu comm = devm_kzalloc(&pdev->dev, sizeof(*comm), GFP_KERNEL); 349*fd3040b9SWells Lu if (!comm) 350*fd3040b9SWells Lu return -ENOMEM; 351*fd3040b9SWells Lu 352*fd3040b9SWells Lu comm->pdev = pdev; 353*fd3040b9SWells Lu platform_set_drvdata(pdev, comm); 354*fd3040b9SWells Lu 355*fd3040b9SWells Lu spin_lock_init(&comm->tx_lock); 356*fd3040b9SWells Lu spin_lock_init(&comm->mdio_lock); 357*fd3040b9SWells Lu spin_lock_init(&comm->int_mask_lock); 358*fd3040b9SWells Lu 359*fd3040b9SWells Lu /* Get memory resource 0 from dts. */ 360*fd3040b9SWells Lu comm->l2sw_reg_base = devm_platform_ioremap_resource(pdev, 0); 361*fd3040b9SWells Lu if (IS_ERR(comm->l2sw_reg_base)) 362*fd3040b9SWells Lu return PTR_ERR(comm->l2sw_reg_base); 363*fd3040b9SWells Lu 364*fd3040b9SWells Lu /* Get irq resource from dts. */ 365*fd3040b9SWells Lu ret = platform_get_irq(pdev, 0); 366*fd3040b9SWells Lu if (ret < 0) 367*fd3040b9SWells Lu return ret; 368*fd3040b9SWells Lu irq = ret; 369*fd3040b9SWells Lu 370*fd3040b9SWells Lu /* Get clock controller. */ 371*fd3040b9SWells Lu comm->clk = devm_clk_get(&pdev->dev, NULL); 372*fd3040b9SWells Lu if (IS_ERR(comm->clk)) { 373*fd3040b9SWells Lu dev_err_probe(&pdev->dev, PTR_ERR(comm->clk), 374*fd3040b9SWells Lu "Failed to retrieve clock controller!\n"); 375*fd3040b9SWells Lu return PTR_ERR(comm->clk); 376*fd3040b9SWells Lu } 377*fd3040b9SWells Lu 378*fd3040b9SWells Lu /* Get reset controller. */ 379*fd3040b9SWells Lu comm->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); 380*fd3040b9SWells Lu if (IS_ERR(comm->rstc)) { 381*fd3040b9SWells Lu dev_err_probe(&pdev->dev, PTR_ERR(comm->rstc), 382*fd3040b9SWells Lu "Failed to retrieve reset controller!\n"); 383*fd3040b9SWells Lu return PTR_ERR(comm->rstc); 384*fd3040b9SWells Lu } 385*fd3040b9SWells Lu 386*fd3040b9SWells Lu /* Enable clock. */ 387*fd3040b9SWells Lu ret = clk_prepare_enable(comm->clk); 388*fd3040b9SWells Lu if (ret) 389*fd3040b9SWells Lu return ret; 390*fd3040b9SWells Lu udelay(1); 391*fd3040b9SWells Lu 392*fd3040b9SWells Lu /* Reset MAC */ 393*fd3040b9SWells Lu reset_control_assert(comm->rstc); 394*fd3040b9SWells Lu udelay(1); 395*fd3040b9SWells Lu reset_control_deassert(comm->rstc); 396*fd3040b9SWells Lu usleep_range(1000, 2000); 397*fd3040b9SWells Lu 398*fd3040b9SWells Lu /* Request irq. */ 399*fd3040b9SWells Lu ret = devm_request_irq(&pdev->dev, irq, spl2sw_ethernet_interrupt, 0, 400*fd3040b9SWells Lu dev_name(&pdev->dev), comm); 401*fd3040b9SWells Lu if (ret) { 402*fd3040b9SWells Lu dev_err(&pdev->dev, "Failed to request irq #%d!\n", irq); 403*fd3040b9SWells Lu goto out_clk_disable; 404*fd3040b9SWells Lu } 405*fd3040b9SWells Lu 406*fd3040b9SWells Lu /* Initialize TX and RX descriptors. */ 407*fd3040b9SWells Lu ret = spl2sw_descs_init(comm); 408*fd3040b9SWells Lu if (ret) { 409*fd3040b9SWells Lu dev_err(&pdev->dev, "Fail to initialize mac descriptors!\n"); 410*fd3040b9SWells Lu spl2sw_descs_free(comm); 411*fd3040b9SWells Lu goto out_clk_disable; 412*fd3040b9SWells Lu } 413*fd3040b9SWells Lu 414*fd3040b9SWells Lu /* Initialize MAC. */ 415*fd3040b9SWells Lu spl2sw_mac_init(comm); 416*fd3040b9SWells Lu 417*fd3040b9SWells Lu /* Initialize mdio bus */ 418*fd3040b9SWells Lu ret = spl2sw_mdio_init(comm); 419*fd3040b9SWells Lu if (ret) { 420*fd3040b9SWells Lu dev_err(&pdev->dev, "Failed to initialize mdio bus!\n"); 421*fd3040b9SWells Lu goto out_clk_disable; 422*fd3040b9SWells Lu } 423*fd3040b9SWells Lu 424*fd3040b9SWells Lu /* Get child node ethernet-ports. */ 425*fd3040b9SWells Lu eth_ports_np = of_get_child_by_name(pdev->dev.of_node, "ethernet-ports"); 426*fd3040b9SWells Lu if (!eth_ports_np) { 427*fd3040b9SWells Lu dev_err(&pdev->dev, "No ethernet-ports child node found!\n"); 428*fd3040b9SWells Lu ret = -ENODEV; 429*fd3040b9SWells Lu goto out_free_mdio; 430*fd3040b9SWells Lu } 431*fd3040b9SWells Lu 432*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) { 433*fd3040b9SWells Lu /* Get port@i of node ethernet-ports. */ 434*fd3040b9SWells Lu port_np = spl2sw_get_eth_child_node(eth_ports_np, i); 435*fd3040b9SWells Lu if (!port_np) 436*fd3040b9SWells Lu continue; 437*fd3040b9SWells Lu 438*fd3040b9SWells Lu /* Get phy-mode. */ 439*fd3040b9SWells Lu if (of_get_phy_mode(port_np, &phy_mode)) { 440*fd3040b9SWells Lu dev_err(&pdev->dev, "Failed to get phy-mode property of port@%d!\n", 441*fd3040b9SWells Lu i); 442*fd3040b9SWells Lu continue; 443*fd3040b9SWells Lu } 444*fd3040b9SWells Lu 445*fd3040b9SWells Lu /* Get phy-handle. */ 446*fd3040b9SWells Lu phy_np = of_parse_phandle(port_np, "phy-handle", 0); 447*fd3040b9SWells Lu if (!phy_np) { 448*fd3040b9SWells Lu dev_err(&pdev->dev, "Failed to get phy-handle property of port@%d!\n", 449*fd3040b9SWells Lu i); 450*fd3040b9SWells Lu continue; 451*fd3040b9SWells Lu } 452*fd3040b9SWells Lu 453*fd3040b9SWells Lu /* Get mac-address from nvmem. */ 454*fd3040b9SWells Lu ret = spl2sw_nvmem_get_mac_address(&pdev->dev, port_np, mac_addr); 455*fd3040b9SWells Lu if (ret == -EPROBE_DEFER) { 456*fd3040b9SWells Lu goto out_unregister_dev; 457*fd3040b9SWells Lu } else if (ret) { 458*fd3040b9SWells Lu dev_info(&pdev->dev, "Generate a random mac address!\n"); 459*fd3040b9SWells Lu eth_random_addr(mac_addr); 460*fd3040b9SWells Lu } 461*fd3040b9SWells Lu 462*fd3040b9SWells Lu /* Initialize the net device. */ 463*fd3040b9SWells Lu ret = spl2sw_init_netdev(pdev, mac_addr, &ndev); 464*fd3040b9SWells Lu if (ret) 465*fd3040b9SWells Lu goto out_unregister_dev; 466*fd3040b9SWells Lu 467*fd3040b9SWells Lu ndev->irq = irq; 468*fd3040b9SWells Lu comm->ndev[i] = ndev; 469*fd3040b9SWells Lu mac = netdev_priv(ndev); 470*fd3040b9SWells Lu mac->phy_node = phy_np; 471*fd3040b9SWells Lu mac->phy_mode = phy_mode; 472*fd3040b9SWells Lu mac->comm = comm; 473*fd3040b9SWells Lu 474*fd3040b9SWells Lu mac->lan_port = 0x1 << i; /* forward to port i */ 475*fd3040b9SWells Lu mac->to_vlan = 0x1 << i; /* vlan group: i */ 476*fd3040b9SWells Lu mac->vlan_id = i; /* vlan group: i */ 477*fd3040b9SWells Lu 478*fd3040b9SWells Lu /* Set MAC address */ 479*fd3040b9SWells Lu ret = spl2sw_mac_addr_add(mac); 480*fd3040b9SWells Lu if (ret) 481*fd3040b9SWells Lu goto out_unregister_dev; 482*fd3040b9SWells Lu 483*fd3040b9SWells Lu spl2sw_mac_rx_mode_set(mac); 484*fd3040b9SWells Lu } 485*fd3040b9SWells Lu 486*fd3040b9SWells Lu /* Find first valid net device. */ 487*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) { 488*fd3040b9SWells Lu if (comm->ndev[i]) 489*fd3040b9SWells Lu break; 490*fd3040b9SWells Lu } 491*fd3040b9SWells Lu if (i >= MAX_NETDEV_NUM) { 492*fd3040b9SWells Lu dev_err(&pdev->dev, "No valid ethernet port!\n"); 493*fd3040b9SWells Lu ret = -ENODEV; 494*fd3040b9SWells Lu goto out_free_mdio; 495*fd3040b9SWells Lu } 496*fd3040b9SWells Lu 497*fd3040b9SWells Lu /* Save first valid net device */ 498*fd3040b9SWells Lu ndev = comm->ndev[i]; 499*fd3040b9SWells Lu 500*fd3040b9SWells Lu ret = spl2sw_phy_connect(comm); 501*fd3040b9SWells Lu if (ret) { 502*fd3040b9SWells Lu netdev_err(ndev, "Failed to connect phy!\n"); 503*fd3040b9SWells Lu goto out_unregister_dev; 504*fd3040b9SWells Lu } 505*fd3040b9SWells Lu 506*fd3040b9SWells Lu /* Add and enable napi. */ 507*fd3040b9SWells Lu netif_napi_add(ndev, &comm->rx_napi, spl2sw_rx_poll, NAPI_POLL_WEIGHT); 508*fd3040b9SWells Lu napi_enable(&comm->rx_napi); 509*fd3040b9SWells Lu netif_napi_add(ndev, &comm->tx_napi, spl2sw_tx_poll, NAPI_POLL_WEIGHT); 510*fd3040b9SWells Lu napi_enable(&comm->tx_napi); 511*fd3040b9SWells Lu return 0; 512*fd3040b9SWells Lu 513*fd3040b9SWells Lu out_unregister_dev: 514*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) 515*fd3040b9SWells Lu if (comm->ndev[i]) 516*fd3040b9SWells Lu unregister_netdev(comm->ndev[i]); 517*fd3040b9SWells Lu 518*fd3040b9SWells Lu out_free_mdio: 519*fd3040b9SWells Lu spl2sw_mdio_remove(comm); 520*fd3040b9SWells Lu 521*fd3040b9SWells Lu out_clk_disable: 522*fd3040b9SWells Lu clk_disable_unprepare(comm->clk); 523*fd3040b9SWells Lu return ret; 524*fd3040b9SWells Lu } 525*fd3040b9SWells Lu 526*fd3040b9SWells Lu static int spl2sw_remove(struct platform_device *pdev) 527*fd3040b9SWells Lu { 528*fd3040b9SWells Lu struct spl2sw_common *comm; 529*fd3040b9SWells Lu int i; 530*fd3040b9SWells Lu 531*fd3040b9SWells Lu comm = platform_get_drvdata(pdev); 532*fd3040b9SWells Lu 533*fd3040b9SWells Lu spl2sw_phy_remove(comm); 534*fd3040b9SWells Lu 535*fd3040b9SWells Lu /* Unregister and free net device. */ 536*fd3040b9SWells Lu for (i = 0; i < MAX_NETDEV_NUM; i++) 537*fd3040b9SWells Lu if (comm->ndev[i]) 538*fd3040b9SWells Lu unregister_netdev(comm->ndev[i]); 539*fd3040b9SWells Lu 540*fd3040b9SWells Lu comm->enable = 0; 541*fd3040b9SWells Lu spl2sw_mac_hw_stop(comm); 542*fd3040b9SWells Lu spl2sw_descs_free(comm); 543*fd3040b9SWells Lu 544*fd3040b9SWells Lu /* Disable and delete napi. */ 545*fd3040b9SWells Lu napi_disable(&comm->rx_napi); 546*fd3040b9SWells Lu netif_napi_del(&comm->rx_napi); 547*fd3040b9SWells Lu napi_disable(&comm->tx_napi); 548*fd3040b9SWells Lu netif_napi_del(&comm->tx_napi); 549*fd3040b9SWells Lu 550*fd3040b9SWells Lu spl2sw_mdio_remove(comm); 551*fd3040b9SWells Lu 552*fd3040b9SWells Lu clk_disable_unprepare(comm->clk); 553*fd3040b9SWells Lu 554*fd3040b9SWells Lu return 0; 555*fd3040b9SWells Lu } 556*fd3040b9SWells Lu 557*fd3040b9SWells Lu static const struct of_device_id spl2sw_of_match[] = { 558*fd3040b9SWells Lu {.compatible = "sunplus,sp7021-emac"}, 559*fd3040b9SWells Lu { /* sentinel */ } 560*fd3040b9SWells Lu }; 561*fd3040b9SWells Lu 562*fd3040b9SWells Lu MODULE_DEVICE_TABLE(of, spl2sw_of_match); 563*fd3040b9SWells Lu 564*fd3040b9SWells Lu static struct platform_driver spl2sw_driver = { 565*fd3040b9SWells Lu .probe = spl2sw_probe, 566*fd3040b9SWells Lu .remove = spl2sw_remove, 567*fd3040b9SWells Lu .driver = { 568*fd3040b9SWells Lu .name = "sp7021_emac", 569*fd3040b9SWells Lu .owner = THIS_MODULE, 570*fd3040b9SWells Lu .of_match_table = spl2sw_of_match, 571*fd3040b9SWells Lu }, 572*fd3040b9SWells Lu }; 573*fd3040b9SWells Lu 574*fd3040b9SWells Lu module_platform_driver(spl2sw_driver); 575*fd3040b9SWells Lu 576*fd3040b9SWells Lu MODULE_AUTHOR("Wells Lu <wellslutw@gmail.com>"); 577*fd3040b9SWells Lu MODULE_DESCRIPTION("Sunplus Dual 10M/100M Ethernet driver"); 578*fd3040b9SWells Lu MODULE_LICENSE("GPL"); 579