linux/drivers/net/dsa/mv88e6xxx/serdes.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * Marvell 88E6xxx SERDES manipulation, via SMI bus
   4 *
   5 * Copyright (c) 2008 Marvell Semiconductor
   6 *
   7 * Copyright (c) 2016 Andrew Lunn <andrew@lunn.ch>
   8 */
   9
  10#ifndef _MV88E6XXX_SERDES_H
  11#define _MV88E6XXX_SERDES_H
  12
  13#include "chip.h"
  14
  15#define MV88E6352_ADDR_SERDES           0x0f
  16#define MV88E6352_SERDES_PAGE_FIBER     0x01
  17#define MV88E6352_SERDES_IRQ            0x0b
  18#define MV88E6352_SERDES_INT_ENABLE     0x12
  19#define MV88E6352_SERDES_INT_SPEED_CHANGE       BIT(14)
  20#define MV88E6352_SERDES_INT_DUPLEX_CHANGE      BIT(13)
  21#define MV88E6352_SERDES_INT_PAGE_RX            BIT(12)
  22#define MV88E6352_SERDES_INT_AN_COMPLETE        BIT(11)
  23#define MV88E6352_SERDES_INT_LINK_CHANGE        BIT(10)
  24#define MV88E6352_SERDES_INT_SYMBOL_ERROR       BIT(9)
  25#define MV88E6352_SERDES_INT_FALSE_CARRIER      BIT(8)
  26#define MV88E6352_SERDES_INT_FIFO_OVER_UNDER    BIT(7)
  27#define MV88E6352_SERDES_INT_FIBRE_ENERGY       BIT(4)
  28#define MV88E6352_SERDES_INT_STATUS     0x13
  29
  30
  31#define MV88E6341_PORT5_LANE            0x15
  32
  33#define MV88E6390_PORT9_LANE0           0x09
  34#define MV88E6390_PORT9_LANE1           0x12
  35#define MV88E6390_PORT9_LANE2           0x13
  36#define MV88E6390_PORT9_LANE3           0x14
  37#define MV88E6390_PORT10_LANE0          0x0a
  38#define MV88E6390_PORT10_LANE1          0x15
  39#define MV88E6390_PORT10_LANE2          0x16
  40#define MV88E6390_PORT10_LANE3          0x17
  41
  42/* 10GBASE-R and 10GBASE-X4/X2 */
  43#define MV88E6390_10G_CTRL1             (0x1000 + MDIO_CTRL1)
  44#define MV88E6390_10G_STAT1             (0x1000 + MDIO_STAT1)
  45
  46/* 1000BASE-X and SGMII */
  47#define MV88E6390_SGMII_BMCR            (0x2000 + MII_BMCR)
  48#define MV88E6390_SGMII_BMSR            (0x2000 + MII_BMSR)
  49#define MV88E6390_SGMII_ADVERTISE       (0x2000 + MII_ADVERTISE)
  50#define MV88E6390_SGMII_LPA             (0x2000 + MII_LPA)
  51#define MV88E6390_SGMII_INT_ENABLE      0xa001
  52#define MV88E6390_SGMII_INT_SPEED_CHANGE        BIT(14)
  53#define MV88E6390_SGMII_INT_DUPLEX_CHANGE       BIT(13)
  54#define MV88E6390_SGMII_INT_PAGE_RX             BIT(12)
  55#define MV88E6390_SGMII_INT_AN_COMPLETE         BIT(11)
  56#define MV88E6390_SGMII_INT_LINK_DOWN           BIT(10)
  57#define MV88E6390_SGMII_INT_LINK_UP             BIT(9)
  58#define MV88E6390_SGMII_INT_SYMBOL_ERROR        BIT(8)
  59#define MV88E6390_SGMII_INT_FALSE_CARRIER       BIT(7)
  60#define MV88E6390_SGMII_INT_STATUS      0xa002
  61#define MV88E6390_SGMII_PHY_STATUS      0xa003
  62#define MV88E6390_SGMII_PHY_STATUS_SPEED_MASK   GENMASK(15, 14)
  63#define MV88E6390_SGMII_PHY_STATUS_SPEED_1000   0x8000
  64#define MV88E6390_SGMII_PHY_STATUS_SPEED_100    0x4000
  65#define MV88E6390_SGMII_PHY_STATUS_SPEED_10     0x0000
  66#define MV88E6390_SGMII_PHY_STATUS_DUPLEX_FULL  BIT(13)
  67#define MV88E6390_SGMII_PHY_STATUS_SPD_DPL_VALID BIT(11)
  68#define MV88E6390_SGMII_PHY_STATUS_LINK         BIT(10)
  69#define MV88E6390_SGMII_PHY_STATUS_TX_PAUSE     BIT(3)
  70#define MV88E6390_SGMII_PHY_STATUS_RX_PAUSE     BIT(2)
  71
  72/* Packet generator pad packet checker */
  73#define MV88E6390_PG_CONTROL            0xf010
  74#define MV88E6390_PG_CONTROL_ENABLE_PC          BIT(0)
  75
  76u8 mv88e6185_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
  77u8 mv88e6341_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
  78u8 mv88e6352_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
  79u8 mv88e6390_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
  80u8 mv88e6390x_serdes_get_lane(struct mv88e6xxx_chip *chip, int port);
  81int mv88e6352_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
  82                                u8 lane, unsigned int mode,
  83                                phy_interface_t interface,
  84                                const unsigned long *advertise);
  85int mv88e6390_serdes_pcs_config(struct mv88e6xxx_chip *chip, int port,
  86                                u8 lane, unsigned int mode,
  87                                phy_interface_t interface,
  88                                const unsigned long *advertise);
  89int mv88e6185_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
  90                                   u8 lane, struct phylink_link_state *state);
  91int mv88e6352_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
  92                                   u8 lane, struct phylink_link_state *state);
  93int mv88e6390_serdes_pcs_get_state(struct mv88e6xxx_chip *chip, int port,
  94                                   u8 lane, struct phylink_link_state *state);
  95int mv88e6352_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
  96                                    u8 lane);
  97int mv88e6390_serdes_pcs_an_restart(struct mv88e6xxx_chip *chip, int port,
  98                                    u8 lane);
  99int mv88e6352_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
 100                                 u8 lane, int speed, int duplex);
 101int mv88e6390_serdes_pcs_link_up(struct mv88e6xxx_chip *chip, int port,
 102                                 u8 lane, int speed, int duplex);
 103unsigned int mv88e6352_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
 104                                          int port);
 105unsigned int mv88e6390_serdes_irq_mapping(struct mv88e6xxx_chip *chip,
 106                                          int port);
 107int mv88e6185_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
 108                           bool up);
 109int mv88e6352_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
 110                           bool on);
 111int mv88e6390_serdes_power(struct mv88e6xxx_chip *chip, int port, u8 lane,
 112                           bool on);
 113int mv88e6097_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 114                                bool enable);
 115int mv88e6352_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 116                                bool enable);
 117int mv88e6390_serdes_irq_enable(struct mv88e6xxx_chip *chip, int port, u8 lane,
 118                                bool enable);
 119irqreturn_t mv88e6097_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 120                                        u8 lane);
 121irqreturn_t mv88e6352_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 122                                        u8 lane);
 123irqreturn_t mv88e6390_serdes_irq_status(struct mv88e6xxx_chip *chip, int port,
 124                                        u8 lane);
 125int mv88e6352_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
 126int mv88e6352_serdes_get_strings(struct mv88e6xxx_chip *chip,
 127                                 int port, uint8_t *data);
 128int mv88e6352_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 129                               uint64_t *data);
 130int mv88e6390_serdes_get_sset_count(struct mv88e6xxx_chip *chip, int port);
 131int mv88e6390_serdes_get_strings(struct mv88e6xxx_chip *chip,
 132                                 int port, uint8_t *data);
 133int mv88e6390_serdes_get_stats(struct mv88e6xxx_chip *chip, int port,
 134                               uint64_t *data);
 135
 136int mv88e6352_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
 137void mv88e6352_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
 138int mv88e6390_serdes_get_regs_len(struct mv88e6xxx_chip *chip, int port);
 139void mv88e6390_serdes_get_regs(struct mv88e6xxx_chip *chip, int port, void *_p);
 140
 141/* Return the (first) SERDES lane address a port is using, 0 otherwise. */
 142static inline u8 mv88e6xxx_serdes_get_lane(struct mv88e6xxx_chip *chip,
 143                                           int port)
 144{
 145        if (!chip->info->ops->serdes_get_lane)
 146                return 0;
 147
 148        return chip->info->ops->serdes_get_lane(chip, port);
 149}
 150
 151static inline int mv88e6xxx_serdes_power_up(struct mv88e6xxx_chip *chip,
 152                                            int port, u8 lane)
 153{
 154        if (!chip->info->ops->serdes_power)
 155                return -EOPNOTSUPP;
 156
 157        return chip->info->ops->serdes_power(chip, port, lane, true);
 158}
 159
 160static inline int mv88e6xxx_serdes_power_down(struct mv88e6xxx_chip *chip,
 161                                              int port, u8 lane)
 162{
 163        if (!chip->info->ops->serdes_power)
 164                return -EOPNOTSUPP;
 165
 166        return chip->info->ops->serdes_power(chip, port, lane, false);
 167}
 168
 169static inline unsigned int
 170mv88e6xxx_serdes_irq_mapping(struct mv88e6xxx_chip *chip, int port)
 171{
 172        if (!chip->info->ops->serdes_irq_mapping)
 173                return 0;
 174
 175        return chip->info->ops->serdes_irq_mapping(chip, port);
 176}
 177
 178static inline int mv88e6xxx_serdes_irq_enable(struct mv88e6xxx_chip *chip,
 179                                              int port, u8 lane)
 180{
 181        if (!chip->info->ops->serdes_irq_enable)
 182                return -EOPNOTSUPP;
 183
 184        return chip->info->ops->serdes_irq_enable(chip, port, lane, true);
 185}
 186
 187static inline int mv88e6xxx_serdes_irq_disable(struct mv88e6xxx_chip *chip,
 188                                               int port, u8 lane)
 189{
 190        if (!chip->info->ops->serdes_irq_enable)
 191                return -EOPNOTSUPP;
 192
 193        return chip->info->ops->serdes_irq_enable(chip, port, lane, false);
 194}
 195
 196static inline irqreturn_t
 197mv88e6xxx_serdes_irq_status(struct mv88e6xxx_chip *chip, int port, u8 lane)
 198{
 199        if (!chip->info->ops->serdes_irq_status)
 200                return IRQ_NONE;
 201
 202        return chip->info->ops->serdes_irq_status(chip, port, lane);
 203}
 204
 205#endif
 206