130824122SFUJITA Tomonori // SPDX-License-Identifier: GPL-2.0+
230824122SFUJITA Tomonori /* Copyright (c) Tehuti Networks Ltd. */
330824122SFUJITA Tomonori
430824122SFUJITA Tomonori #include <linux/netdevice.h>
530824122SFUJITA Tomonori #include <linux/pci.h>
630824122SFUJITA Tomonori #include <linux/phylink.h>
730824122SFUJITA Tomonori
830824122SFUJITA Tomonori #include "tn40.h"
930824122SFUJITA Tomonori
tn40_config_to_priv(struct phylink_config * config)1030824122SFUJITA Tomonori static struct tn40_priv *tn40_config_to_priv(struct phylink_config *config)
1130824122SFUJITA Tomonori {
1230824122SFUJITA Tomonori return container_of(config, struct tn40_priv, phylink_config);
1330824122SFUJITA Tomonori }
1430824122SFUJITA Tomonori
tn40_link_up(struct phylink_config * config,struct phy_device * phy,unsigned int mode,phy_interface_t interface,int speed,int duplex,bool tx_pause,bool rx_pause)1530824122SFUJITA Tomonori static void tn40_link_up(struct phylink_config *config, struct phy_device *phy,
1630824122SFUJITA Tomonori unsigned int mode, phy_interface_t interface,
1730824122SFUJITA Tomonori int speed, int duplex, bool tx_pause, bool rx_pause)
1830824122SFUJITA Tomonori {
1930824122SFUJITA Tomonori struct tn40_priv *priv = tn40_config_to_priv(config);
2030824122SFUJITA Tomonori
2130824122SFUJITA Tomonori tn40_set_link_speed(priv, speed);
2230824122SFUJITA Tomonori netif_wake_queue(priv->ndev);
2330824122SFUJITA Tomonori }
2430824122SFUJITA Tomonori
tn40_link_down(struct phylink_config * config,unsigned int mode,phy_interface_t interface)2530824122SFUJITA Tomonori static void tn40_link_down(struct phylink_config *config, unsigned int mode,
2630824122SFUJITA Tomonori phy_interface_t interface)
2730824122SFUJITA Tomonori {
2830824122SFUJITA Tomonori struct tn40_priv *priv = tn40_config_to_priv(config);
2930824122SFUJITA Tomonori
3030824122SFUJITA Tomonori netif_stop_queue(priv->ndev);
3130824122SFUJITA Tomonori tn40_set_link_speed(priv, 0);
3230824122SFUJITA Tomonori }
3330824122SFUJITA Tomonori
tn40_mac_config(struct phylink_config * config,unsigned int mode,const struct phylink_link_state * state)3430824122SFUJITA Tomonori static void tn40_mac_config(struct phylink_config *config, unsigned int mode,
3530824122SFUJITA Tomonori const struct phylink_link_state *state)
3630824122SFUJITA Tomonori {
3730824122SFUJITA Tomonori }
3830824122SFUJITA Tomonori
3930824122SFUJITA Tomonori static const struct phylink_mac_ops tn40_mac_ops = {
4030824122SFUJITA Tomonori .mac_config = tn40_mac_config,
4130824122SFUJITA Tomonori .mac_link_up = tn40_link_up,
4230824122SFUJITA Tomonori .mac_link_down = tn40_link_down,
4330824122SFUJITA Tomonori };
4430824122SFUJITA Tomonori
tn40_phy_register(struct tn40_priv * priv)4530824122SFUJITA Tomonori int tn40_phy_register(struct tn40_priv *priv)
4630824122SFUJITA Tomonori {
4730824122SFUJITA Tomonori struct phylink_config *config;
4830824122SFUJITA Tomonori struct phy_device *phydev;
4930824122SFUJITA Tomonori struct phylink *phylink;
5030824122SFUJITA Tomonori
5130824122SFUJITA Tomonori phydev = phy_find_first(priv->mdio);
5230824122SFUJITA Tomonori if (!phydev) {
5330824122SFUJITA Tomonori dev_err(&priv->pdev->dev, "PHY isn't found\n");
5430824122SFUJITA Tomonori return -ENODEV;
5530824122SFUJITA Tomonori }
5630824122SFUJITA Tomonori
5730824122SFUJITA Tomonori config = &priv->phylink_config;
5830824122SFUJITA Tomonori config->dev = &priv->ndev->dev;
5930824122SFUJITA Tomonori config->type = PHYLINK_NETDEV;
6030824122SFUJITA Tomonori config->mac_capabilities = MAC_10000FD;
6130824122SFUJITA Tomonori __set_bit(PHY_INTERFACE_MODE_XAUI, config->supported_interfaces);
6230824122SFUJITA Tomonori
6330824122SFUJITA Tomonori phylink = phylink_create(config, NULL, PHY_INTERFACE_MODE_XAUI,
6430824122SFUJITA Tomonori &tn40_mac_ops);
6530824122SFUJITA Tomonori if (IS_ERR(phylink))
6630824122SFUJITA Tomonori return PTR_ERR(phylink);
6730824122SFUJITA Tomonori
6830824122SFUJITA Tomonori priv->phydev = phydev;
6930824122SFUJITA Tomonori priv->phylink = phylink;
7030824122SFUJITA Tomonori return 0;
7130824122SFUJITA Tomonori }
7230824122SFUJITA Tomonori
tn40_phy_unregister(struct tn40_priv * priv)7330824122SFUJITA Tomonori void tn40_phy_unregister(struct tn40_priv *priv)
7430824122SFUJITA Tomonori {
7530824122SFUJITA Tomonori phylink_destroy(priv->phylink);
7630824122SFUJITA Tomonori }
77