brintos

brintos / linux-shallow public Read only

0
0
Text · 4.1 KiB · 1a5e1e7 Raw
162 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) Meta Platforms, Inc. and affiliates. */3 4#include <linux/phy.h>5#include <linux/phylink.h>6 7#include "fbnic.h"8#include "fbnic_mac.h"9#include "fbnic_netdev.h"10 11static struct fbnic_net *12fbnic_pcs_to_net(struct phylink_pcs *pcs)13{14	return container_of(pcs, struct fbnic_net, phylink_pcs);15}16 17static void18fbnic_phylink_pcs_get_state(struct phylink_pcs *pcs,19			    struct phylink_link_state *state)20{21	struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);22	struct fbnic_dev *fbd = fbn->fbd;23 24	/* For now we use hard-coded defaults and FW config to determine25	 * the current values. In future patches we will add support for26	 * reconfiguring these values and changing link settings.27	 */28	switch (fbd->fw_cap.link_speed) {29	case FBNIC_FW_LINK_SPEED_25R1:30		state->speed = SPEED_25000;31		break;32	case FBNIC_FW_LINK_SPEED_50R2:33		state->speed = SPEED_50000;34		break;35	case FBNIC_FW_LINK_SPEED_100R2:36		state->speed = SPEED_100000;37		break;38	default:39		state->speed = SPEED_UNKNOWN;40		break;41	}42 43	state->duplex = DUPLEX_FULL;44 45	state->link = fbd->mac->pcs_get_link(fbd);46}47 48static int49fbnic_phylink_pcs_enable(struct phylink_pcs *pcs)50{51	struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);52	struct fbnic_dev *fbd = fbn->fbd;53 54	return fbd->mac->pcs_enable(fbd);55}56 57static void58fbnic_phylink_pcs_disable(struct phylink_pcs *pcs)59{60	struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);61	struct fbnic_dev *fbd = fbn->fbd;62 63	return fbd->mac->pcs_disable(fbd);64}65 66static int67fbnic_phylink_pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode,68			 phy_interface_t interface,69			 const unsigned long *advertising,70			 bool permit_pause_to_mac)71{72	return 0;73}74 75static const struct phylink_pcs_ops fbnic_phylink_pcs_ops = {76	.pcs_config = fbnic_phylink_pcs_config,77	.pcs_enable = fbnic_phylink_pcs_enable,78	.pcs_disable = fbnic_phylink_pcs_disable,79	.pcs_get_state = fbnic_phylink_pcs_get_state,80};81 82static struct phylink_pcs *83fbnic_phylink_mac_select_pcs(struct phylink_config *config,84			     phy_interface_t interface)85{86	struct net_device *netdev = to_net_dev(config->dev);87	struct fbnic_net *fbn = netdev_priv(netdev);88 89	return &fbn->phylink_pcs;90}91 92static void93fbnic_phylink_mac_config(struct phylink_config *config, unsigned int mode,94			 const struct phylink_link_state *state)95{96}97 98static void99fbnic_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,100			    phy_interface_t interface)101{102	struct net_device *netdev = to_net_dev(config->dev);103	struct fbnic_net *fbn = netdev_priv(netdev);104	struct fbnic_dev *fbd = fbn->fbd;105 106	fbd->mac->link_down(fbd);107 108	fbn->link_down_events++;109}110 111static void112fbnic_phylink_mac_link_up(struct phylink_config *config,113			  struct phy_device *phy, unsigned int mode,114			  phy_interface_t interface, int speed, int duplex,115			  bool tx_pause, bool rx_pause)116{117	struct net_device *netdev = to_net_dev(config->dev);118	struct fbnic_net *fbn = netdev_priv(netdev);119	struct fbnic_dev *fbd = fbn->fbd;120 121	fbd->mac->link_up(fbd, tx_pause, rx_pause);122}123 124static const struct phylink_mac_ops fbnic_phylink_mac_ops = {125	.mac_select_pcs = fbnic_phylink_mac_select_pcs,126	.mac_config = fbnic_phylink_mac_config,127	.mac_link_down = fbnic_phylink_mac_link_down,128	.mac_link_up = fbnic_phylink_mac_link_up,129};130 131int fbnic_phylink_init(struct net_device *netdev)132{133	struct fbnic_net *fbn = netdev_priv(netdev);134	struct phylink *phylink;135 136	fbn->phylink_pcs.neg_mode = true;137	fbn->phylink_pcs.ops = &fbnic_phylink_pcs_ops;138 139	fbn->phylink_config.dev = &netdev->dev;140	fbn->phylink_config.type = PHYLINK_NETDEV;141	fbn->phylink_config.mac_capabilities = MAC_SYM_PAUSE | MAC_ASYM_PAUSE |142					       MAC_10000FD | MAC_25000FD |143					       MAC_40000FD | MAC_50000FD |144					       MAC_100000FD;145	fbn->phylink_config.default_an_inband = true;146 147	__set_bit(PHY_INTERFACE_MODE_XGMII,148		  fbn->phylink_config.supported_interfaces);149	__set_bit(PHY_INTERFACE_MODE_XLGMII,150		  fbn->phylink_config.supported_interfaces);151 152	phylink = phylink_create(&fbn->phylink_config, NULL,153				 PHY_INTERFACE_MODE_XLGMII,154				 &fbnic_phylink_mac_ops);155	if (IS_ERR(phylink))156		return PTR_ERR(phylink);157 158	fbn->phylink = phylink;159 160	return 0;161}162