12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 26d91782fSAndrew Lunn /* 36d91782fSAndrew Lunn * Marvell 88E6xxx SERDES manipulation, via SMI bus 46d91782fSAndrew Lunn * 56d91782fSAndrew Lunn * Copyright (c) 2008 Marvell Semiconductor 66d91782fSAndrew Lunn * 76d91782fSAndrew Lunn * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch> 86d91782fSAndrew Lunn */ 96d91782fSAndrew Lunn 106d91782fSAndrew Lunn #ifndef _MV88E6XXX_SERDES_H 116d91782fSAndrew Lunn #define _MV88E6XXX_SERDES_H 126d91782fSAndrew Lunn 134d5f2ba7SVivien Didelot #include "chip.h" 146d91782fSAndrew Lunn 156d91782fSAndrew Lunn #define MV88E6352_ADDR_SERDES 0x0f 166d91782fSAndrew Lunn #define MV88E6352_SERDES_PAGE_FIBER 0x01 174382172fSAndrew Lunn #define MV88E6352_SERDES_IRQ 0x0b 184382172fSAndrew Lunn #define MV88E6352_SERDES_INT_ENABLE 0x12 194382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SPEED_CHANGE BIT(14) 204382172fSAndrew Lunn #define MV88E6352_SERDES_INT_DUPLEX_CHANGE BIT(13) 214382172fSAndrew Lunn #define MV88E6352_SERDES_INT_PAGE_RX BIT(12) 224382172fSAndrew Lunn #define MV88E6352_SERDES_INT_AN_COMPLETE BIT(11) 234382172fSAndrew Lunn #define MV88E6352_SERDES_INT_LINK_CHANGE BIT(10) 244382172fSAndrew Lunn #define MV88E6352_SERDES_INT_SYMBOL_ERROR BIT(9) 254382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FALSE_CARRIER BIT(8) 264382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIFO_OVER_UNDER BIT(7) 274382172fSAndrew Lunn #define MV88E6352_SERDES_INT_FIBRE_ENERGY BIT(4) 284382172fSAndrew Lunn #define MV88E6352_SERDES_INT_STATUS 0x13 294382172fSAndrew Lunn 306d91782fSAndrew Lunn 31d3cf7d8fSMarek Behún #define MV88E6341_PORT5_LANE 0x15 325bafeb6eSMarek Behún 336335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE0 0x09 346335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE1 0x12 356335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE2 0x13 366335e9f2SAndrew Lunn #define MV88E6390_PORT9_LANE3 0x14 376335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE0 0x0a 386335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE1 0x15 396335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE2 0x16 406335e9f2SAndrew Lunn #define MV88E6390_PORT10_LANE3 0x17 416335e9f2SAndrew Lunn 426335e9f2SAndrew Lunn /* 10GBASE-R and 10GBASE-X4/X2 */ 436335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1 0x1000 446335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_RESET BIT(15) 456335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_LOOPBACK BIT(14) 466335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_SPEED BIT(13) 476335e9f2SAndrew Lunn #define MV88E6390_PCS_CONTROL_1_PDOWN BIT(11) 486335e9f2SAndrew Lunn 496335e9f2SAndrew Lunn /* 1000BASE-X and SGMII */ 506335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL 0x2000 516335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_RESET BIT(15) 526335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_LOOPBACK BIT(14) 536335e9f2SAndrew Lunn #define MV88E6390_SGMII_CONTROL_PDOWN BIT(11) 54efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS 0x2001 55efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_AN_DONE BIT(5) 56efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_REMOTE_FAULT BIT(4) 57efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_STATUS_LINK BIT(2) 58efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_ENABLE 0xa001 59efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SPEED_CHANGE BIT(14) 60efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_DUPLEX_CHANGE BIT(13) 61efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_PAGE_RX BIT(12) 62efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_AN_COMPLETE BIT(11) 63efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_DOWN BIT(10) 64efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_LINK_UP BIT(9) 65efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_SYMBOL_ERROR BIT(8) 66efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_FALSE_CARRIER BIT(7) 67efd1ba6aSAndrew Lunn #define MV88E6390_SGMII_INT_STATUS 0xa002 6872d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS 0xa003 6972d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK GENMASK(15, 14) 7072d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_1000 0x8000 7172d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_100 0x4000 7272d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPEED_10 0x0000 7372d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL BIT(13) 7472d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11) 7572d8b4fdSHeiner Kallweit #define MV88E6390_SGMII_PHY_STATUS_LINK BIT(10) 766335e9f2SAndrew Lunn 7717deaf5cSMarek Behún /* Put the SERDES lane address a port is using into *lane. If a port has 7817deaf5cSMarek Behún * multiple lanes, should put the first lane the port is using. If a port does 7917deaf5cSMarek Behún * not have a lane, return -ENODEV. 8017deaf5cSMarek Behún */ 8117deaf5cSMarek Behún static inline int mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip, 8217deaf5cSMarek Behún int port, u8 *lane) 8317deaf5cSMarek Behún { 8417deaf5cSMarek Behún if (!chip->info->ops->serdes_get_lane) 8517deaf5cSMarek Behún return -EOPNOTSUPP; 8617deaf5cSMarek Behún 8717deaf5cSMarek Behún return chip->info->ops->serdes_get_lane(chip, port, lane); 8817deaf5cSMarek Behún } 8917deaf5cSMarek Behún 90d3cf7d8fSMarek Behún int mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); 9117deaf5cSMarek Behún int mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); 9217deaf5cSMarek Behún int mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port, u8 *lane); 934241ef52SVivien Didelot unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip, 944241ef52SVivien Didelot int port); 954241ef52SVivien Didelot unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip, 964241ef52SVivien Didelot int port); 976d91782fSAndrew Lunn int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 986335e9f2SAndrew Lunn int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, bool on); 99efd1ba6aSAndrew Lunn int mv88e6390_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); 100efd1ba6aSAndrew Lunn void mv88e6390_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); 101cda9f4aaSAndrew Lunn int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port); 10265f60e45SAndrew Lunn int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip, 103cda9f4aaSAndrew Lunn int port, uint8_t *data); 10465f60e45SAndrew Lunn int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port, 105cda9f4aaSAndrew Lunn uint64_t *data); 106734447d4SAndrew Lunn int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, 10717deaf5cSMarek Behún u8 lane); 108734447d4SAndrew Lunn int mv88e6390_serdes_irq_disable(struct mv88e6xxx_chip *chip, int port, 10917deaf5cSMarek Behún u8 lane); 1104382172fSAndrew Lunn int mv88e6352_serdes_irq_setup(struct mv88e6xxx_chip *chip, int port); 1114382172fSAndrew Lunn void mv88e6352_serdes_irq_free(struct mv88e6xxx_chip *chip, int port); 1124382172fSAndrew Lunn 1134241ef52SVivien Didelot static inline unsigned int 1144241ef52SVivien Didelot mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port) 1154241ef52SVivien Didelot { 1164241ef52SVivien Didelot if (!chip->info->ops->serdes_irq_mapping) 1174241ef52SVivien Didelot return 0; 1184241ef52SVivien Didelot 1194241ef52SVivien Didelot return chip->info->ops->serdes_irq_mapping(chip, port); 1204241ef52SVivien Didelot } 121734447d4SAndrew Lunn 1226d91782fSAndrew Lunn #endif 123