cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spl2sw_driver.c (13658B)


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