1*85764555SRussell King // SPDX-License-Identifier: GPL-2.0-or-later
2*85764555SRussell King /*
3*85764555SRussell King  * Marvell 88E6352 family SERDES PCS support
4*85764555SRussell King  *
5*85764555SRussell King  * Copyright (c) 2008 Marvell Semiconductor
6*85764555SRussell King  *
7*85764555SRussell King  * Copyright (c) 2017 Andrew Lunn <andrew@lunn.ch>
8*85764555SRussell King  */
9*85764555SRussell King #include <linux/phylink.h>
10*85764555SRussell King 
11*85764555SRussell King #include "global2.h"
12*85764555SRussell King #include "port.h"
13*85764555SRussell King #include "serdes.h"
14*85764555SRussell King 
15*85764555SRussell King /* Definitions from drivers/net/phy/marvell.c, which would be good to reuse. */
16*85764555SRussell King #define MII_M1011_PHY_STATUS		17
17*85764555SRussell King #define MII_M1011_IMASK			18
18*85764555SRussell King #define MII_M1011_IMASK_LINK_CHANGE	BIT(10)
19*85764555SRussell King #define MII_M1011_IEVENT		19
20*85764555SRussell King #define MII_M1011_IEVENT_LINK_CHANGE	BIT(10)
21*85764555SRussell King #define MII_MARVELL_PHY_PAGE		22
22*85764555SRussell King #define MII_MARVELL_FIBER_PAGE		1
23*85764555SRussell King 
24*85764555SRussell King struct marvell_c22_pcs {
25*85764555SRussell King 	struct mdio_device mdio;
26*85764555SRussell King 	struct phylink_pcs phylink_pcs;
27*85764555SRussell King 	unsigned int irq;
28*85764555SRussell King 	char name[64];
29*85764555SRussell King 	bool (*link_check)(struct marvell_c22_pcs *mpcs);
30*85764555SRussell King 	struct mv88e6xxx_port *port;
31*85764555SRussell King };
32*85764555SRussell King 
pcs_to_marvell_c22_pcs(struct phylink_pcs * pcs)33*85764555SRussell King static struct marvell_c22_pcs *pcs_to_marvell_c22_pcs(struct phylink_pcs *pcs)
34*85764555SRussell King {
35*85764555SRussell King 	return container_of(pcs, struct marvell_c22_pcs, phylink_pcs);
36*85764555SRussell King }
37*85764555SRussell King 
marvell_c22_pcs_set_fiber_page(struct marvell_c22_pcs * mpcs)38*85764555SRussell King static int marvell_c22_pcs_set_fiber_page(struct marvell_c22_pcs *mpcs)
39*85764555SRussell King {
40*85764555SRussell King 	u16 page;
41*85764555SRussell King 	int err;
42*85764555SRussell King 
43*85764555SRussell King 	mutex_lock(&mpcs->mdio.bus->mdio_lock);
44*85764555SRussell King 
45*85764555SRussell King 	err = __mdiodev_read(&mpcs->mdio, MII_MARVELL_PHY_PAGE);
46*85764555SRussell King 	if (err < 0) {
47*85764555SRussell King 		dev_err(mpcs->mdio.dev.parent,
48*85764555SRussell King 			"%s: can't read Serdes page register: %pe\n",
49*85764555SRussell King 			mpcs->name, ERR_PTR(err));
50*85764555SRussell King 		return err;
51*85764555SRussell King 	}
52*85764555SRussell King 
53*85764555SRussell King 	page = err;
54*85764555SRussell King 
55*85764555SRussell King 	err = __mdiodev_write(&mpcs->mdio, MII_MARVELL_PHY_PAGE,
56*85764555SRussell King 			      MII_MARVELL_FIBER_PAGE);
57*85764555SRussell King 	if (err) {
58*85764555SRussell King 		dev_err(mpcs->mdio.dev.parent,
59*85764555SRussell King 			"%s: can't set Serdes page register: %pe\n",
60*85764555SRussell King 			mpcs->name, ERR_PTR(err));
61*85764555SRussell King 		return err;
62*85764555SRussell King 	}
63*85764555SRussell King 
64*85764555SRussell King 	return page;
65*85764555SRussell King }
66*85764555SRussell King 
marvell_c22_pcs_restore_page(struct marvell_c22_pcs * mpcs,int oldpage,int ret)67*85764555SRussell King static int marvell_c22_pcs_restore_page(struct marvell_c22_pcs *mpcs,
68*85764555SRussell King 					int oldpage, int ret)
69*85764555SRussell King {
70*85764555SRussell King 	int err;
71*85764555SRussell King 
72*85764555SRussell King 	if (oldpage >= 0) {
73*85764555SRussell King 		err = __mdiodev_write(&mpcs->mdio, MII_MARVELL_PHY_PAGE,
74*85764555SRussell King 				      oldpage);
75*85764555SRussell King 		if (err)
76*85764555SRussell King 			dev_err(mpcs->mdio.dev.parent,
77*85764555SRussell King 				"%s: can't restore Serdes page register: %pe\n",
78*85764555SRussell King 				mpcs->name, ERR_PTR(err));
79*85764555SRussell King 		if (!err || ret < 0)
80*85764555SRussell King 			err = ret;
81*85764555SRussell King 	} else {
82*85764555SRussell King 		err = oldpage;
83*85764555SRussell King 	}
84*85764555SRussell King 	mutex_unlock(&mpcs->mdio.bus->mdio_lock);
85*85764555SRussell King 
86*85764555SRussell King 	return err;
87*85764555SRussell King }
88*85764555SRussell King 
marvell_c22_pcs_handle_irq(int irq,void * dev_id)89*85764555SRussell King static irqreturn_t marvell_c22_pcs_handle_irq(int irq, void *dev_id)
90*85764555SRussell King {
91*85764555SRussell King 	struct marvell_c22_pcs *mpcs = dev_id;
92*85764555SRussell King 	irqreturn_t status = IRQ_NONE;
93*85764555SRussell King 	int err, oldpage;
94*85764555SRussell King 
95*85764555SRussell King 	oldpage = marvell_c22_pcs_set_fiber_page(mpcs);
96*85764555SRussell King 	if (oldpage < 0)
97*85764555SRussell King 		goto fail;
98*85764555SRussell King 
99*85764555SRussell King 	err = __mdiodev_read(&mpcs->mdio, MII_M1011_IEVENT);
100*85764555SRussell King 	if (err >= 0 && err & MII_M1011_IEVENT_LINK_CHANGE) {
101*85764555SRussell King 		phylink_pcs_change(&mpcs->phylink_pcs, true);
102*85764555SRussell King 		status = IRQ_HANDLED;
103*85764555SRussell King 	}
104*85764555SRussell King 
105*85764555SRussell King fail:
106*85764555SRussell King 	marvell_c22_pcs_restore_page(mpcs, oldpage, 0);
107*85764555SRussell King 
108*85764555SRussell King 	return status;
109*85764555SRussell King }
110*85764555SRussell King 
marvell_c22_pcs_modify(struct marvell_c22_pcs * mpcs,u8 reg,u16 mask,u16 val)111*85764555SRussell King static int marvell_c22_pcs_modify(struct marvell_c22_pcs *mpcs, u8 reg,
112*85764555SRussell King 				  u16 mask, u16 val)
113*85764555SRussell King {
114*85764555SRussell King 	int oldpage, err = 0;
115*85764555SRussell King 
116*85764555SRussell King 	oldpage = marvell_c22_pcs_set_fiber_page(mpcs);
117*85764555SRussell King 	if (oldpage >= 0)
118*85764555SRussell King 		err = __mdiodev_modify(&mpcs->mdio, reg, mask, val);
119*85764555SRussell King 
120*85764555SRussell King 	return marvell_c22_pcs_restore_page(mpcs, oldpage, err);
121*85764555SRussell King }
122*85764555SRussell King 
marvell_c22_pcs_power(struct marvell_c22_pcs * mpcs,bool on)123*85764555SRussell King static int marvell_c22_pcs_power(struct marvell_c22_pcs *mpcs,
124*85764555SRussell King 				 bool on)
125*85764555SRussell King {
126*85764555SRussell King 	u16 val = on ? 0 : BMCR_PDOWN;
127*85764555SRussell King 
128*85764555SRussell King 	return marvell_c22_pcs_modify(mpcs, MII_BMCR, BMCR_PDOWN, val);
129*85764555SRussell King }
130*85764555SRussell King 
marvell_c22_pcs_control_irq(struct marvell_c22_pcs * mpcs,bool enable)131*85764555SRussell King static int marvell_c22_pcs_control_irq(struct marvell_c22_pcs *mpcs,
132*85764555SRussell King 				       bool enable)
133*85764555SRussell King {
134*85764555SRussell King 	u16 val = enable ? MII_M1011_IMASK_LINK_CHANGE : 0;
135*85764555SRussell King 
136*85764555SRussell King 	return marvell_c22_pcs_modify(mpcs, MII_M1011_IMASK,
137*85764555SRussell King 				      MII_M1011_IMASK_LINK_CHANGE, val);
138*85764555SRussell King }
139*85764555SRussell King 
marvell_c22_pcs_enable(struct phylink_pcs * pcs)140*85764555SRussell King static int marvell_c22_pcs_enable(struct phylink_pcs *pcs)
141*85764555SRussell King {
142*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
143*85764555SRussell King 	int err;
144*85764555SRussell King 
145*85764555SRussell King 	err = marvell_c22_pcs_power(mpcs, true);
146*85764555SRussell King 	if (err)
147*85764555SRussell King 		return err;
148*85764555SRussell King 
149*85764555SRussell King 	return marvell_c22_pcs_control_irq(mpcs, !!mpcs->irq);
150*85764555SRussell King }
151*85764555SRussell King 
marvell_c22_pcs_disable(struct phylink_pcs * pcs)152*85764555SRussell King static void marvell_c22_pcs_disable(struct phylink_pcs *pcs)
153*85764555SRussell King {
154*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
155*85764555SRussell King 
156*85764555SRussell King 	marvell_c22_pcs_control_irq(mpcs, false);
157*85764555SRussell King 	marvell_c22_pcs_power(mpcs, false);
158*85764555SRussell King }
159*85764555SRussell King 
marvell_c22_pcs_get_state(struct phylink_pcs * pcs,struct phylink_link_state * state)160*85764555SRussell King static void marvell_c22_pcs_get_state(struct phylink_pcs *pcs,
161*85764555SRussell King 				      struct phylink_link_state *state)
162*85764555SRussell King {
163*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
164*85764555SRussell King 	int oldpage, bmsr, lpa, status;
165*85764555SRussell King 
166*85764555SRussell King 	state->link = false;
167*85764555SRussell King 
168*85764555SRussell King 	if (mpcs->link_check && !mpcs->link_check(mpcs))
169*85764555SRussell King 		return;
170*85764555SRussell King 
171*85764555SRussell King 	oldpage = marvell_c22_pcs_set_fiber_page(mpcs);
172*85764555SRussell King 	if (oldpage >= 0) {
173*85764555SRussell King 		bmsr = __mdiodev_read(&mpcs->mdio, MII_BMSR);
174*85764555SRussell King 		lpa = __mdiodev_read(&mpcs->mdio, MII_LPA);
175*85764555SRussell King 		status = __mdiodev_read(&mpcs->mdio, MII_M1011_PHY_STATUS);
176*85764555SRussell King 	}
177*85764555SRussell King 
178*85764555SRussell King 	if (marvell_c22_pcs_restore_page(mpcs, oldpage, 0) >= 0 &&
179*85764555SRussell King 	    bmsr >= 0 && lpa >= 0 && status >= 0)
180*85764555SRussell King 		mv88e6xxx_pcs_decode_state(mpcs->mdio.dev.parent, bmsr, lpa,
181*85764555SRussell King 					   status, state);
182*85764555SRussell King }
183*85764555SRussell King 
marvell_c22_pcs_config(struct phylink_pcs * pcs,unsigned int neg_mode,phy_interface_t interface,const unsigned long * advertising,bool permit_pause_to_mac)184*85764555SRussell King static int marvell_c22_pcs_config(struct phylink_pcs *pcs,
185*85764555SRussell King 				  unsigned int neg_mode,
186*85764555SRussell King 				  phy_interface_t interface,
187*85764555SRussell King 				  const unsigned long *advertising,
188*85764555SRussell King 				  bool permit_pause_to_mac)
189*85764555SRussell King {
190*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
191*85764555SRussell King 	int oldpage, adv, err, ret = 0;
192*85764555SRussell King 	u16 bmcr;
193*85764555SRussell King 
194*85764555SRussell King 	adv = phylink_mii_c22_pcs_encode_advertisement(interface, advertising);
195*85764555SRussell King 	if (adv < 0)
196*85764555SRussell King 		return 0;
197*85764555SRussell King 
198*85764555SRussell King 	bmcr = neg_mode == PHYLINK_PCS_NEG_INBAND_ENABLED ? BMCR_ANENABLE : 0;
199*85764555SRussell King 
200*85764555SRussell King 	oldpage = marvell_c22_pcs_set_fiber_page(mpcs);
201*85764555SRussell King 	if (oldpage < 0)
202*85764555SRussell King 		goto restore;
203*85764555SRussell King 
204*85764555SRussell King 	err = __mdiodev_modify_changed(&mpcs->mdio, MII_ADVERTISE, 0xffff, adv);
205*85764555SRussell King 	ret = err;
206*85764555SRussell King 	if (err < 0)
207*85764555SRussell King 		goto restore;
208*85764555SRussell King 
209*85764555SRussell King 	err = __mdiodev_modify_changed(&mpcs->mdio, MII_BMCR, BMCR_ANENABLE,
210*85764555SRussell King 				       bmcr);
211*85764555SRussell King 	if (err < 0) {
212*85764555SRussell King 		ret = err;
213*85764555SRussell King 		goto restore;
214*85764555SRussell King 	}
215*85764555SRussell King 
216*85764555SRussell King 	/* If the ANENABLE bit was changed, the PHY will restart negotiation,
217*85764555SRussell King 	 * so we don't need to flag a change to trigger its own restart.
218*85764555SRussell King 	 */
219*85764555SRussell King 	if (err)
220*85764555SRussell King 		ret = 0;
221*85764555SRussell King 
222*85764555SRussell King restore:
223*85764555SRussell King 	return marvell_c22_pcs_restore_page(mpcs, oldpage, ret);
224*85764555SRussell King }
225*85764555SRussell King 
marvell_c22_pcs_an_restart(struct phylink_pcs * pcs)226*85764555SRussell King static void marvell_c22_pcs_an_restart(struct phylink_pcs *pcs)
227*85764555SRussell King {
228*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
229*85764555SRussell King 
230*85764555SRussell King 	marvell_c22_pcs_modify(mpcs, MII_BMCR, BMCR_ANRESTART, BMCR_ANRESTART);
231*85764555SRussell King }
232*85764555SRussell King 
marvell_c22_pcs_link_up(struct phylink_pcs * pcs,unsigned int mode,phy_interface_t interface,int speed,int duplex)233*85764555SRussell King static void marvell_c22_pcs_link_up(struct phylink_pcs *pcs, unsigned int mode,
234*85764555SRussell King 				    phy_interface_t interface, int speed,
235*85764555SRussell King 				    int duplex)
236*85764555SRussell King {
237*85764555SRussell King 	struct marvell_c22_pcs *mpcs = pcs_to_marvell_c22_pcs(pcs);
238*85764555SRussell King 	u16 bmcr;
239*85764555SRussell King 	int err;
240*85764555SRussell King 
241*85764555SRussell King 	if (phylink_autoneg_inband(mode))
242*85764555SRussell King 		return;
243*85764555SRussell King 
244*85764555SRussell King 	bmcr = mii_bmcr_encode_fixed(speed, duplex);
245*85764555SRussell King 
246*85764555SRussell King 	err = marvell_c22_pcs_modify(mpcs, MII_BMCR, BMCR_SPEED100 |
247*85764555SRussell King 				     BMCR_FULLDPLX | BMCR_SPEED1000, bmcr);
248*85764555SRussell King 	if (err)
249*85764555SRussell King 		dev_err(mpcs->mdio.dev.parent,
250*85764555SRussell King 			"%s: failed to configure mpcs: %pe\n", mpcs->name,
251*85764555SRussell King 			ERR_PTR(err));
252*85764555SRussell King }
253*85764555SRussell King 
254*85764555SRussell King static const struct phylink_pcs_ops marvell_c22_pcs_ops = {
255*85764555SRussell King 	.pcs_enable = marvell_c22_pcs_enable,
256*85764555SRussell King 	.pcs_disable = marvell_c22_pcs_disable,
257*85764555SRussell King 	.pcs_get_state = marvell_c22_pcs_get_state,
258*85764555SRussell King 	.pcs_config = marvell_c22_pcs_config,
259*85764555SRussell King 	.pcs_an_restart = marvell_c22_pcs_an_restart,
260*85764555SRussell King 	.pcs_link_up = marvell_c22_pcs_link_up,
261*85764555SRussell King };
262*85764555SRussell King 
marvell_c22_pcs_alloc(struct device * dev,struct mii_bus * bus,unsigned int addr)263*85764555SRussell King static struct marvell_c22_pcs *marvell_c22_pcs_alloc(struct device *dev,
264*85764555SRussell King 						     struct mii_bus *bus,
265*85764555SRussell King 						     unsigned int addr)
266*85764555SRussell King {
267*85764555SRussell King 	struct marvell_c22_pcs *mpcs;
268*85764555SRussell King 
269*85764555SRussell King 	mpcs = kzalloc(sizeof(*mpcs), GFP_KERNEL);
270*85764555SRussell King 	if (!mpcs)
271*85764555SRussell King 		return NULL;
272*85764555SRussell King 
273*85764555SRussell King 	mpcs->mdio.dev.parent = dev;
274*85764555SRussell King 	mpcs->mdio.bus = bus;
275*85764555SRussell King 	mpcs->mdio.addr = addr;
276*85764555SRussell King 	mpcs->phylink_pcs.ops = &marvell_c22_pcs_ops;
277*85764555SRussell King 	mpcs->phylink_pcs.neg_mode = true;
278*85764555SRussell King 
279*85764555SRussell King 	return mpcs;
280*85764555SRussell King }
281*85764555SRussell King 
marvell_c22_pcs_setup_irq(struct marvell_c22_pcs * mpcs,unsigned int irq)282*85764555SRussell King static int marvell_c22_pcs_setup_irq(struct marvell_c22_pcs *mpcs,
283*85764555SRussell King 				     unsigned int irq)
284*85764555SRussell King {
285*85764555SRussell King 	int err;
286*85764555SRussell King 
287*85764555SRussell King 	mpcs->phylink_pcs.poll = !irq;
288*85764555SRussell King 	mpcs->irq = irq;
289*85764555SRussell King 
290*85764555SRussell King 	if (irq) {
291*85764555SRussell King 		err = request_threaded_irq(irq, NULL,
292*85764555SRussell King 					   marvell_c22_pcs_handle_irq,
293*85764555SRussell King 					   IRQF_ONESHOT, mpcs->name, mpcs);
294*85764555SRussell King 		if (err)
295*85764555SRussell King 			return err;
296*85764555SRussell King 	}
297*85764555SRussell King 
298*85764555SRussell King 	return 0;
299*85764555SRussell King }
300*85764555SRussell King 
301*85764555SRussell King /* mv88e6352 specifics */
302*85764555SRussell King 
mv88e6352_pcs_link_check(struct marvell_c22_pcs * mpcs)303*85764555SRussell King static bool mv88e6352_pcs_link_check(struct marvell_c22_pcs *mpcs)
304*85764555SRussell King {
305*85764555SRussell King 	struct mv88e6xxx_port *port = mpcs->port;
306*85764555SRussell King 	struct mv88e6xxx_chip *chip = port->chip;
307*85764555SRussell King 	u8 cmode;
308*85764555SRussell King 
309*85764555SRussell King 	/* Port 4 can be in auto-media mode. Check that the port is
310*85764555SRussell King 	 * associated with the mpcs.
311*85764555SRussell King 	 */
312*85764555SRussell King 	mv88e6xxx_reg_lock(chip);
313*85764555SRussell King 	chip->info->ops->port_get_cmode(chip, port->port, &cmode);
314*85764555SRussell King 	mv88e6xxx_reg_unlock(chip);
315*85764555SRussell King 
316*85764555SRussell King 	return cmode == MV88E6XXX_PORT_STS_CMODE_100BASEX ||
317*85764555SRussell King 	       cmode == MV88E6XXX_PORT_STS_CMODE_1000BASEX ||
318*85764555SRussell King 	       cmode == MV88E6XXX_PORT_STS_CMODE_SGMII;
319*85764555SRussell King }
320*85764555SRussell King 
mv88e6352_pcs_init(struct mv88e6xxx_chip * chip,int port)321*85764555SRussell King static int mv88e6352_pcs_init(struct mv88e6xxx_chip *chip, int port)
322*85764555SRussell King {
323*85764555SRussell King 	struct marvell_c22_pcs *mpcs;
324*85764555SRussell King 	struct mii_bus *bus;
325*85764555SRussell King 	struct device *dev;
326*85764555SRussell King 	unsigned int irq;
327*85764555SRussell King 	int err;
328*85764555SRussell King 
329*85764555SRussell King 	mv88e6xxx_reg_lock(chip);
330*85764555SRussell King 	err = mv88e6352_g2_scratch_port_has_serdes(chip, port);
331*85764555SRussell King 	mv88e6xxx_reg_unlock(chip);
332*85764555SRussell King 	if (err <= 0)
333*85764555SRussell King 		return err;
334*85764555SRussell King 
335*85764555SRussell King 	irq = mv88e6xxx_serdes_irq_mapping(chip, port);
336*85764555SRussell King 	bus = mv88e6xxx_default_mdio_bus(chip);
337*85764555SRussell King 	dev = chip->dev;
338*85764555SRussell King 
339*85764555SRussell King 	mpcs = marvell_c22_pcs_alloc(dev, bus, MV88E6352_ADDR_SERDES);
340*85764555SRussell King 	if (!mpcs)
341*85764555SRussell King 		return -ENOMEM;
342*85764555SRussell King 
343*85764555SRussell King 	snprintf(mpcs->name, sizeof(mpcs->name),
344*85764555SRussell King 		 "mv88e6xxx-%s-serdes-%d", dev_name(dev), port);
345*85764555SRussell King 
346*85764555SRussell King 	mpcs->link_check = mv88e6352_pcs_link_check;
347*85764555SRussell King 	mpcs->port = &chip->ports[port];
348*85764555SRussell King 
349*85764555SRussell King 	err = marvell_c22_pcs_setup_irq(mpcs, irq);
350*85764555SRussell King 	if (err) {
351*85764555SRussell King 		kfree(mpcs);
352*85764555SRussell King 		return err;
353*85764555SRussell King 	}
354*85764555SRussell King 
355*85764555SRussell King 	chip->ports[port].pcs_private = &mpcs->phylink_pcs;
356*85764555SRussell King 
357*85764555SRussell King 	return 0;
358*85764555SRussell King }
359*85764555SRussell King 
mv88e6352_pcs_teardown(struct mv88e6xxx_chip * chip,int port)360*85764555SRussell King static void mv88e6352_pcs_teardown(struct mv88e6xxx_chip *chip, int port)
361*85764555SRussell King {
362*85764555SRussell King 	struct marvell_c22_pcs *mpcs;
363*85764555SRussell King 	struct phylink_pcs *pcs;
364*85764555SRussell King 
365*85764555SRussell King 	pcs = chip->ports[port].pcs_private;
366*85764555SRussell King 	if (!pcs)
367*85764555SRussell King 		return;
368*85764555SRussell King 
369*85764555SRussell King 	mpcs = pcs_to_marvell_c22_pcs(pcs);
370*85764555SRussell King 
371*85764555SRussell King 	if (mpcs->irq)
372*85764555SRussell King 		free_irq(mpcs->irq, mpcs);
373*85764555SRussell King 
374*85764555SRussell King 	kfree(mpcs);
375*85764555SRussell King 
376*85764555SRussell King 	chip->ports[port].pcs_private = NULL;
377*85764555SRussell King }
378*85764555SRussell King 
mv88e6352_pcs_select(struct mv88e6xxx_chip * chip,int port,phy_interface_t interface)379*85764555SRussell King static struct phylink_pcs *mv88e6352_pcs_select(struct mv88e6xxx_chip *chip,
380*85764555SRussell King 						int port,
381*85764555SRussell King 						phy_interface_t interface)
382*85764555SRussell King {
383*85764555SRussell King 	return chip->ports[port].pcs_private;
384*85764555SRussell King }
385*85764555SRussell King 
386*85764555SRussell King const struct mv88e6xxx_pcs_ops mv88e6352_pcs_ops = {
387*85764555SRussell King 	.pcs_init = mv88e6352_pcs_init,
388*85764555SRussell King 	.pcs_teardown = mv88e6352_pcs_teardown,
389*85764555SRussell King 	.pcs_select = mv88e6352_pcs_select,
390*85764555SRussell King };
391