Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / drivers / net / ethernet / meta / fbnic / fbnic_phylink.c
blob1a5e1e719b3096f90e5ca49d77574bf8970219a1
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
4 #include <linux/phy.h>
5 #include <linux/phylink.h>
7 #include "fbnic.h"
8 #include "fbnic_mac.h"
9 #include "fbnic_netdev.h"
11 static struct fbnic_net *
12 fbnic_pcs_to_net(struct phylink_pcs *pcs)
14 return container_of(pcs, struct fbnic_net, phylink_pcs);
17 static void
18 fbnic_phylink_pcs_get_state(struct phylink_pcs *pcs,
19 struct phylink_link_state *state)
21 struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);
22 struct fbnic_dev *fbd = fbn->fbd;
24 /* For now we use hard-coded defaults and FW config to determine
25 * the current values. In future patches we will add support for
26 * reconfiguring these values and changing link settings.
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;
43 state->duplex = DUPLEX_FULL;
45 state->link = fbd->mac->pcs_get_link(fbd);
48 static int
49 fbnic_phylink_pcs_enable(struct phylink_pcs *pcs)
51 struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);
52 struct fbnic_dev *fbd = fbn->fbd;
54 return fbd->mac->pcs_enable(fbd);
57 static void
58 fbnic_phylink_pcs_disable(struct phylink_pcs *pcs)
60 struct fbnic_net *fbn = fbnic_pcs_to_net(pcs);
61 struct fbnic_dev *fbd = fbn->fbd;
63 return fbd->mac->pcs_disable(fbd);
66 static int
67 fbnic_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)
72 return 0;
75 static 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,
82 static struct phylink_pcs *
83 fbnic_phylink_mac_select_pcs(struct phylink_config *config,
84 phy_interface_t interface)
86 struct net_device *netdev = to_net_dev(config->dev);
87 struct fbnic_net *fbn = netdev_priv(netdev);
89 return &fbn->phylink_pcs;
92 static void
93 fbnic_phylink_mac_config(struct phylink_config *config, unsigned int mode,
94 const struct phylink_link_state *state)
98 static void
99 fbnic_phylink_mac_link_down(struct phylink_config *config, unsigned int mode,
100 phy_interface_t interface)
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;
106 fbd->mac->link_down(fbd);
108 fbn->link_down_events++;
111 static void
112 fbnic_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)
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;
121 fbd->mac->link_up(fbd, tx_pause, rx_pause);
124 static 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,
131 int fbnic_phylink_init(struct net_device *netdev)
133 struct fbnic_net *fbn = netdev_priv(netdev);
134 struct phylink *phylink;
136 fbn->phylink_pcs.neg_mode = true;
137 fbn->phylink_pcs.ops = &fbnic_phylink_pcs_ops;
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;
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);
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);
158 fbn->phylink = phylink;
160 return 0;