brintos

brintos / linux-shallow public Read only

0
0
Text · 2.0 KiB · 6f899e4 Raw
91 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright Sunplus Technology Co., Ltd.3 *       All rights reserved.4 */5 6#include <linux/netdevice.h>7#include <linux/bitfield.h>8#include <linux/of_mdio.h>9 10#include "spl2sw_register.h"11#include "spl2sw_define.h"12#include "spl2sw_phy.h"13 14static void spl2sw_mii_link_change(struct net_device *ndev)15{16	struct spl2sw_mac *mac = netdev_priv(ndev);17	struct phy_device *phydev = ndev->phydev;18	struct spl2sw_common *comm = mac->comm;19	u32 reg;20 21	reg = readl(comm->l2sw_reg_base + L2SW_MAC_FORCE_MODE);22 23	if (phydev->link) {24		reg |= FIELD_PREP(MAC_FORCE_RMII_LINK, mac->lan_port);25 26		if (phydev->speed == 100) {27			reg |= FIELD_PREP(MAC_FORCE_RMII_SPD, mac->lan_port);28		} else {29			reg &= FIELD_PREP(MAC_FORCE_RMII_SPD, ~mac->lan_port) |30			       ~MAC_FORCE_RMII_SPD;31		}32 33		if (phydev->duplex) {34			reg |= FIELD_PREP(MAC_FORCE_RMII_DPX, mac->lan_port);35		} else {36			reg &= FIELD_PREP(MAC_FORCE_RMII_DPX, ~mac->lan_port) |37			       ~MAC_FORCE_RMII_DPX;38		}39 40		if (phydev->pause) {41			reg |= FIELD_PREP(MAC_FORCE_RMII_FC, mac->lan_port);42		} else {43			reg &= FIELD_PREP(MAC_FORCE_RMII_FC, ~mac->lan_port) |44			       ~MAC_FORCE_RMII_FC;45		}46	} else {47		reg &= FIELD_PREP(MAC_FORCE_RMII_LINK, ~mac->lan_port) |48		       ~MAC_FORCE_RMII_LINK;49	}50 51	writel(reg, comm->l2sw_reg_base + L2SW_MAC_FORCE_MODE);52 53	phy_print_status(phydev);54}55 56int spl2sw_phy_connect(struct spl2sw_common *comm)57{58	struct phy_device *phydev;59	struct net_device *ndev;60	struct spl2sw_mac *mac;61	int i;62 63	for (i = 0; i < MAX_NETDEV_NUM; i++)64		if (comm->ndev[i]) {65			ndev = comm->ndev[i];66			mac = netdev_priv(ndev);67			phydev = of_phy_connect(ndev, mac->phy_node, spl2sw_mii_link_change,68						0, mac->phy_mode);69			if (!phydev)70				return -ENODEV;71 72			phy_support_asym_pause(phydev);73			phy_attached_info(phydev);74		}75 76	return 0;77}78 79void spl2sw_phy_remove(struct spl2sw_common *comm)80{81	struct net_device *ndev;82	int i;83 84	for (i = 0; i < MAX_NETDEV_NUM; i++)85		if (comm->ndev[i]) {86			ndev = comm->ndev[i];87			if (ndev)88				phy_disconnect(ndev->phydev);89		}90}91