@@ -238,6 +238,74 @@ static int mv88e6xxx_phy_write(struct mv88e6xxx_chip *chip, int phy,
238
238
return chip -> phy_ops -> write (chip , addr , reg , val );
239
239
}
240
240
241
+ static int mv88e6xxx_phy_page_get (struct mv88e6xxx_chip * chip , int phy , u8 page )
242
+ {
243
+ if (!mv88e6xxx_has (chip , MV88E6XXX_FLAG_PHY_PAGE ))
244
+ return - EOPNOTSUPP ;
245
+
246
+ return mv88e6xxx_phy_write (chip , phy , PHY_PAGE , page );
247
+ }
248
+
249
+ static void mv88e6xxx_phy_page_put (struct mv88e6xxx_chip * chip , int phy )
250
+ {
251
+ int err ;
252
+
253
+ /* Restore PHY page Copper 0x0 for access via the registered MDIO bus */
254
+ err = mv88e6xxx_phy_write (chip , phy , PHY_PAGE , PHY_PAGE_COPPER );
255
+ if (unlikely (err )) {
256
+ dev_err (chip -> dev , "failed to restore PHY %d page Copper (%d)\n" ,
257
+ phy , err );
258
+ }
259
+ }
260
+
261
+ static int mv88e6xxx_phy_page_read (struct mv88e6xxx_chip * chip , int phy ,
262
+ u8 page , int reg , u16 * val )
263
+ {
264
+ int err ;
265
+
266
+ /* There is no paging for registers 22 */
267
+ if (reg == PHY_PAGE )
268
+ return - EINVAL ;
269
+
270
+ err = mv88e6xxx_phy_page_get (chip , phy , page );
271
+ if (!err ) {
272
+ err = mv88e6xxx_phy_read (chip , phy , reg , val );
273
+ mv88e6xxx_phy_page_put (chip , phy );
274
+ }
275
+
276
+ return err ;
277
+ }
278
+
279
+ static int mv88e6xxx_phy_page_write (struct mv88e6xxx_chip * chip , int phy ,
280
+ u8 page , int reg , u16 val )
281
+ {
282
+ int err ;
283
+
284
+ /* There is no paging for registers 22 */
285
+ if (reg == PHY_PAGE )
286
+ return - EINVAL ;
287
+
288
+ err = mv88e6xxx_phy_page_get (chip , phy , page );
289
+ if (!err ) {
290
+ err = mv88e6xxx_phy_write (chip , phy , PHY_PAGE , page );
291
+ mv88e6xxx_phy_page_put (chip , phy );
292
+ }
293
+
294
+ return err ;
295
+ }
296
+
297
+ static int mv88e6xxx_serdes_read (struct mv88e6xxx_chip * chip , int reg , u16 * val )
298
+ {
299
+ return mv88e6xxx_phy_page_read (chip , ADDR_SERDES , SERDES_PAGE_FIBER ,
300
+ reg , val );
301
+ }
302
+
303
+ static int mv88e6xxx_serdes_write (struct mv88e6xxx_chip * chip , int reg , u16 val )
304
+ {
305
+ return mv88e6xxx_phy_page_write (chip , ADDR_SERDES , SERDES_PAGE_FIBER ,
306
+ reg , val );
307
+ }
308
+
241
309
static int mv88e6xxx_wait (struct mv88e6xxx_chip * chip , int addr , int reg ,
242
310
u16 mask )
243
311
{
@@ -2408,23 +2476,22 @@ static int mv88e6xxx_switch_reset(struct mv88e6xxx_chip *chip)
2408
2476
return ret ;
2409
2477
}
2410
2478
2411
- static int mv88e6xxx_power_on_serdes (struct mv88e6xxx_chip * chip )
2479
+ static int mv88e6xxx_serdes_power_on (struct mv88e6xxx_chip * chip )
2412
2480
{
2413
- int ret ;
2481
+ u16 val ;
2482
+ int err ;
2414
2483
2415
- ret = _mv88e6xxx_mdio_page_read ( chip , REG_FIBER_SERDES ,
2416
- PAGE_FIBER_SERDES , MII_BMCR );
2417
- if (ret < 0 )
2418
- return ret ;
2484
+ /* Clear Power Down bit */
2485
+ err = mv88e6xxx_serdes_read ( chip , MII_BMCR , & val );
2486
+ if (err )
2487
+ return err ;
2419
2488
2420
- if (ret & BMCR_PDOWN ) {
2421
- ret &= ~BMCR_PDOWN ;
2422
- ret = _mv88e6xxx_mdio_page_write (chip , REG_FIBER_SERDES ,
2423
- PAGE_FIBER_SERDES , MII_BMCR ,
2424
- ret );
2489
+ if (val & BMCR_PDOWN ) {
2490
+ val &= ~BMCR_PDOWN ;
2491
+ err = mv88e6xxx_serdes_write (chip , MII_BMCR , val );
2425
2492
}
2426
2493
2427
- return ret ;
2494
+ return err ;
2428
2495
}
2429
2496
2430
2497
static int mv88e6xxx_port_read (struct mv88e6xxx_chip * chip , int port ,
@@ -2547,15 +2614,15 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
2547
2614
/* If this port is connected to a SerDes, make sure the SerDes is not
2548
2615
* powered down.
2549
2616
*/
2550
- if (mv88e6xxx_6352_family (chip )) {
2617
+ if (mv88e6xxx_has (chip , MV88E6XXX_FLAGS_SERDES )) {
2551
2618
ret = _mv88e6xxx_reg_read (chip , REG_PORT (port ), PORT_STATUS );
2552
2619
if (ret < 0 )
2553
2620
return ret ;
2554
2621
ret &= PORT_STATUS_CMODE_MASK ;
2555
2622
if ((ret == PORT_STATUS_CMODE_100BASE_X ) ||
2556
2623
(ret == PORT_STATUS_CMODE_1000BASE_X ) ||
2557
2624
(ret == PORT_STATUS_CMODE_SGMII )) {
2558
- ret = mv88e6xxx_power_on_serdes (chip );
2625
+ ret = mv88e6xxx_serdes_power_on (chip );
2559
2626
if (ret < 0 )
2560
2627
return ret ;
2561
2628
}
0 commit comments