Commit 6ddb4fdf authored by David S. Miller's avatar David S. Miller

Merge branch 'dsa-mv88e6xxx-cleanup-capabilities'

Vivien Didelot says:

====================
net: dsa: mv88e6xxx: cleanup capabilities

This patch series removes the remaining capabilities as well as the
flags bitmap in the info structures. Most of them are turned into ops,
or new info members.

There is no mv88e6xxx_cap enum or bitmap flags anymore, only
mv88e6xxx_info and mv88e6xxx_ops structures.

While reviewing and documenting the related G2 registers, fix a few
inconsistencies: 88E6185 has no interrupt in G2 and 88E6390 has a POT.

Except these two adjustments, there is no functional changes.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 46f55cff b3e05aa1
This diff is collapsed.
......@@ -97,133 +97,6 @@ enum mv88e6xxx_family {
MV88E6XXX_FAMILY_6390, /* 6190 6190X 6191 6290 6390 6390X */
};
enum mv88e6xxx_cap {
/* Energy Efficient Ethernet.
*/
MV88E6XXX_CAP_EEE,
/* Multi-chip Addressing Mode.
* Some chips respond to only 2 registers of its own SMI device address
* when it is non-zero, and use indirect access to internal registers.
*/
MV88E6XXX_CAP_SMI_CMD, /* (0x00) SMI Command */
MV88E6XXX_CAP_SMI_DATA, /* (0x01) SMI Data */
/* Switch Global (1) Registers.
*/
MV88E6XXX_CAP_G1_ATU_FID, /* (0x01) ATU FID Register */
MV88E6XXX_CAP_G1_VTU_FID, /* (0x02) VTU FID Register */
/* Switch Global 2 Registers.
* The device contains a second set of global 16-bit registers.
*/
MV88E6XXX_CAP_GLOBAL2,
MV88E6XXX_CAP_G2_INT, /* (0x00) Interrupt Status */
MV88E6XXX_CAP_G2_MGMT_EN_2X, /* (0x02) MGMT Enable Register 2x */
MV88E6XXX_CAP_G2_MGMT_EN_0X, /* (0x03) MGMT Enable Register 0x */
MV88E6XXX_CAP_G2_POT, /* (0x0f) Priority Override Table */
/* Per VLAN Spanning Tree Unit (STU).
* The Port State database, if present, is accessed through VTU
* operations and dedicated SID registers. See MV88E6352_G1_VTU_SID.
*/
MV88E6XXX_CAP_STU,
/* VLAN Table Unit.
* The VTU is used to program 802.1Q VLANs. See MV88E6XXX_G1_VTU_OP.
*/
MV88E6XXX_CAP_VTU,
};
/* Bitmask of capabilities */
#define MV88E6XXX_FLAG_EEE BIT_ULL(MV88E6XXX_CAP_EEE)
#define MV88E6XXX_FLAG_SMI_CMD BIT_ULL(MV88E6XXX_CAP_SMI_CMD)
#define MV88E6XXX_FLAG_SMI_DATA BIT_ULL(MV88E6XXX_CAP_SMI_DATA)
#define MV88E6XXX_FLAG_G1_VTU_FID BIT_ULL(MV88E6XXX_CAP_G1_VTU_FID)
#define MV88E6XXX_FLAG_GLOBAL2 BIT_ULL(MV88E6XXX_CAP_GLOBAL2)
#define MV88E6XXX_FLAG_G2_INT BIT_ULL(MV88E6XXX_CAP_G2_INT)
#define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_2X)
#define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT_ULL(MV88E6XXX_CAP_G2_MGMT_EN_0X)
#define MV88E6XXX_FLAG_G2_POT BIT_ULL(MV88E6XXX_CAP_G2_POT)
/* Multi-chip Addressing Mode */
#define MV88E6XXX_FLAGS_MULTI_CHIP \
(MV88E6XXX_FLAG_SMI_CMD | \
MV88E6XXX_FLAG_SMI_DATA)
#define MV88E6XXX_FLAGS_FAMILY_6095 \
(MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6097 \
(MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6165 \
(MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6185 \
(MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6320 \
(MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6341 \
(MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6351 \
(MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6352 \
(MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
MV88E6XXX_FLAG_G2_POT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
#define MV88E6XXX_FLAGS_FAMILY_6390 \
(MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
MV88E6XXX_FLAGS_MULTI_CHIP)
struct mv88e6xxx_ops;
struct mv88e6xxx_info {
......@@ -235,11 +108,18 @@ struct mv88e6xxx_info {
unsigned int max_vid;
unsigned int port_base_addr;
unsigned int global1_addr;
unsigned int global2_addr;
unsigned int age_time_coeff;
unsigned int g1_irqs;
unsigned int g2_irqs;
bool pvt;
/* Multi-chip Addressing Mode.
* Some chips respond to only 2 registers of its own SMI device address
* when it is non-zero, and use indirect access to internal registers.
*/
bool multi_chip;
enum dsa_tag_protocol tag_protocol;
unsigned long long flags;
/* Mask for FromPort and ToPort value of PortVec used in ATU Move
* operation. 0 means that the ATU Move operation is not supported.
......@@ -359,6 +239,15 @@ struct mv88e6xxx_ops {
struct mii_bus *bus,
int addr, int reg, u16 val);
/* Copper Energy Detect operations */
int (*phy_energy_detect_read)(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int (*phy_energy_detect_write)(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
/* Priority Override Table operations */
int (*pot_clear)(struct mv88e6xxx_chip *chip);
/* PHY Polling Unit (PPU) operations */
int (*ppu_enable)(struct mv88e6xxx_chip *chip);
int (*ppu_disable)(struct mv88e6xxx_chip *chip);
......@@ -449,7 +338,6 @@ struct mv88e6xxx_ops {
int (*set_egress_port)(struct mv88e6xxx_chip *chip, int port);
const struct mv88e6xxx_irq_ops *watchdog_ops;
/* Can be either in g1 or g2, so don't use a prefix */
int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
/* Power on/off a SERDES interface */
......@@ -482,12 +370,6 @@ struct mv88e6xxx_hw_stat {
int type;
};
static inline bool mv88e6xxx_has(struct mv88e6xxx_chip *chip,
unsigned long flags)
{
return (chip->info->flags & flags) == flags;
}
static inline bool mv88e6xxx_has_pvt(struct mv88e6xxx_chip *chip)
{
return chip->info->pvt;
......
......@@ -22,48 +22,99 @@
static int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val)
{
return mv88e6xxx_read(chip, MV88E6XXX_G2, reg, val);
return mv88e6xxx_read(chip, chip->info->global2_addr, reg, val);
}
static int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
{
return mv88e6xxx_write(chip, MV88E6XXX_G2, reg, val);
return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
}
static int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update)
{
return mv88e6xxx_update(chip, MV88E6XXX_G2, reg, update);
return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update);
}
static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
{
return mv88e6xxx_wait(chip, MV88E6XXX_G2, reg, mask);
return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
}
/* Offset 0x00: Interrupt Source Register */
static int mv88e6xxx_g2_int_source(struct mv88e6xxx_chip *chip, u16 *src)
{
/* Read (and clear most of) the Interrupt Source bits */
return mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SRC, src);
}
/* Offset 0x01: Interrupt Mask Register */
static int mv88e6xxx_g2_int_mask(struct mv88e6xxx_chip *chip, u16 mask)
{
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, mask);
}
/* Offset 0x02: Management Enable 2x */
static int mv88e6xxx_g2_mgmt_enable_2x(struct mv88e6xxx_chip *chip, u16 en2x)
{
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, en2x);
}
/* Offset 0x03: Management Enable 0x */
int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
static int mv88e6xxx_g2_mgmt_enable_0x(struct mv88e6xxx_chip *chip, u16 en0x)
{
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X, en0x);
}
/* Offset 0x05: Switch Management Register */
static int mv88e6xxx_g2_switch_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip,
bool enable)
{
u16 val;
int err;
err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_SWITCH_MGMT, &val);
if (err)
return err;
if (enable)
val |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
else
val &= ~MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU;
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, val);
}
int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
int err;
/* Consider the frames with reserved multicast destination
* addresses matching 01:80:c2:00:00:2x as MGMT.
* addresses matching 01:80:c2:00:00:0x as MGMT.
*/
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_2X, 0xffff);
if (err)
return err;
}
err = mv88e6xxx_g2_mgmt_enable_0x(chip, 0xffff);
if (err)
return err;
return mv88e6xxx_g2_switch_mgmt_rsvd2cpu(chip, true);
}
int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
int err;
/* Consider the frames with reserved multicast destination
* addresses matching 01:80:c2:00:00:0x as MGMT.
* addresses matching 01:80:c2:00:00:2x as MGMT.
*/
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X))
return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_MGMT_EN_0X,
0xffff);
err = mv88e6xxx_g2_mgmt_enable_2x(chip, 0xffff);
if (err)
return err;
return 0;
return mv88e6185_g2_mgmt_rsvd2cpu(chip);
}
/* Offset 0x06: Device Mapping Table register */
......@@ -260,7 +311,7 @@ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_PRIO_OVERRIDE, val);
}
static int mv88e6xxx_g2_clear_pot(struct mv88e6xxx_chip *chip)
int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
{
int i, err;
......@@ -933,7 +984,7 @@ static irqreturn_t mv88e6xxx_g2_irq_thread_fn(int irq, void *dev_id)
u16 reg;
mutex_lock(&chip->reg_lock);
err = mv88e6xxx_g2_read(chip, MV88E6XXX_G2_INT_SOURCE, &reg);
err = mv88e6xxx_g2_int_source(chip, &reg);
mutex_unlock(&chip->reg_lock);
if (err)
goto out;
......@@ -959,8 +1010,11 @@ static void mv88e6xxx_g2_irq_bus_lock(struct irq_data *d)
static void mv88e6xxx_g2_irq_bus_sync_unlock(struct irq_data *d)
{
struct mv88e6xxx_chip *chip = irq_data_get_irq_chip_data(d);
int err;
mv88e6xxx_g2_write(chip, MV88E6XXX_G2_INT_MASK, ~chip->g2_irq.masked);
err = mv88e6xxx_g2_int_mask(chip, ~chip->g2_irq.masked);
if (err)
dev_err(chip->dev, "failed to mask interrupts\n");
mutex_unlock(&chip->reg_lock);
}
......@@ -1063,9 +1117,6 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
* port at the highest priority.
*/
reg = MV88E6XXX_G2_SWITCH_MGMT_FORCE_FLOW_CTL_PRI | (0x7 << 4);
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X) ||
mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X))
reg |= MV88E6XXX_G2_SWITCH_MGMT_RSVD2CPU | 0x7;
err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, reg);
if (err)
return err;
......@@ -1080,12 +1131,5 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
if (err)
return err;
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_POT)) {
/* Clear the priority override table. */
err = mv88e6xxx_g2_clear_pot(chip);
if (err)
return err;
}
return 0;
}
......@@ -17,14 +17,27 @@
#include "chip.h"
#define MV88E6XXX_G2 0x1c
/* Offset 0x00: Interrupt Source Register */
#define MV88E6XXX_G2_INT_SOURCE 0x00
#define MV88E6XXX_G2_INT_SRC 0x00
#define MV88E6XXX_G2_INT_SRC_WDOG 0x8000
#define MV88E6XXX_G2_INT_SRC_JAM_LIMIT 0x4000
#define MV88E6XXX_G2_INT_SRC_DUPLEX_MISMATCH 0x2000
#define MV88E6XXX_G2_INT_SRC_WAKE_EVENT 0x1000
#define MV88E6352_G2_INT_SRC_SERDES 0x0800
#define MV88E6352_G2_INT_SRC_PHY 0x001f
#define MV88E6390_G2_INT_SRC_PHY 0x07fe
#define MV88E6XXX_G2_INT_SOURCE_WATCHDOG 15
/* Offset 0x01: Interrupt Mask Register */
#define MV88E6XXX_G2_INT_MASK 0x01
#define MV88E6XXX_G2_INT_MASK 0x01
#define MV88E6XXX_G2_INT_MASK_WDOG 0x8000
#define MV88E6XXX_G2_INT_MASK_JAM_LIMIT 0x4000
#define MV88E6XXX_G2_INT_MASK_DUPLEX_MISMATCH 0x2000
#define MV88E6XXX_G2_INT_MASK_WAKE_EVENT 0x1000
#define MV88E6352_G2_INT_MASK_SERDES 0x0800
#define MV88E6352_G2_INT_MASK_PHY 0x001f
#define MV88E6390_G2_INT_MASK_PHY 0x07fe
/* Offset 0x02: MGMT Enable Register 2x */
#define MV88E6XXX_G2_MGMT_EN_2X 0x02
......@@ -245,7 +258,11 @@ int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip);
void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip);
extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
......@@ -254,7 +271,7 @@ extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
{
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_GLOBAL2)) {
if (chip->info->global2_addr) {
dev_err(chip->dev, "this chip requires CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 enabled\n");
return -EOPNOTSUPP;
}
......@@ -347,7 +364,17 @@ static inline void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
{
}
static inline int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
static inline int mv88e6185_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
return -EOPNOTSUPP;
}
static inline int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
return -EOPNOTSUPP;
}
static inline int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
{
return -EOPNOTSUPP;
}
......
......@@ -13,7 +13,6 @@
#include <linux/mdio.h>
#include <linux/module.h>
#include <net/dsa.h>
#include "chip.h"
#include "phy.h"
......@@ -247,3 +246,99 @@ int mv88e6xxx_phy_setup(struct mv88e6xxx_chip *chip)
{
return mv88e6xxx_phy_ppu_enable(chip);
}
/* Page 0, Register 16: Copper Specific Control Register 1 */
int mv88e6352_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK;
eee->eee_enabled = false;
eee->tx_lpi_enabled = false;
switch (val) {
case MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP:
eee->tx_lpi_enabled = true;
/* fall through... */
case MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV:
eee->eee_enabled = true;
}
return 0;
}
int mv88e6352_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= ~MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK;
if (eee->eee_enabled)
val |= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV;
if (eee->tx_lpi_enabled)
val |= MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP;
return mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_CSCTL1, val);
}
int mv88e6390_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK;
eee->eee_enabled = false;
eee->tx_lpi_enabled = false;
switch (val) {
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO:
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_SW:
eee->tx_lpi_enabled = true;
/* fall through... */
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO:
case MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_SW:
eee->eee_enabled = true;
}
return 0;
}
int mv88e6390_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_phy_read(chip, phy, MV88E6XXX_PHY_CSCTL1, &val);
if (err)
return err;
val &= ~MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK;
if (eee->eee_enabled)
val |= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO;
if (eee->tx_lpi_enabled)
val |= MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO;
return mv88e6xxx_phy_write(chip, phy, MV88E6XXX_PHY_CSCTL1, val);
}
......@@ -17,6 +17,19 @@
#define MV88E6XXX_PHY_PAGE 0x16
#define MV88E6XXX_PHY_PAGE_COPPER 0x00
/* Page 0, Register 16: Copper Specific Control Register 1 */
#define MV88E6XXX_PHY_CSCTL1 16
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_MASK 0x0300
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_OFF_MASK 0x0100 /* 0x */
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV 0x0200
#define MV88E6352_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP 0x0300
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_MASK 0x0380
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_OFF_MASK 0x0180 /* 0xx */
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_AUTO 0x0200
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_RCV_SW 0x0280
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_AUTO 0x0300
#define MV88E6390_PHY_CSCTL1_ENERGY_DETECT_SENSE_NLP_SW 0x0380
/* PHY Registers accesses implementations */
int mv88e6165_phy_read(struct mv88e6xxx_chip *chip, struct mii_bus *bus,
int addr, int reg, u16 *val);
......@@ -40,4 +53,13 @@ void mv88e6xxx_phy_init(struct mv88e6xxx_chip *chip);
void mv88e6xxx_phy_destroy(struct mv88e6xxx_chip *chip);
int mv88e6xxx_phy_setup(struct mv88e6xxx_chip *chip);
int mv88e6352_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6352_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6390_phy_energy_detect_read(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
int mv88e6390_phy_energy_detect_write(struct mv88e6xxx_chip *chip, int phy,
struct ethtool_eee *eee);
#endif /*_MV88E6XXX_PHY_H */
......@@ -35,6 +35,23 @@ int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
return mv88e6xxx_write(chip, addr, reg, val);
}
/* Offset 0x00: Port Status Register */
int mv88e6xxx_port_status_eee(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee)
{
u16 val;
int err;
err = mv88e6xxx_port_read(chip, port, MV88E6XXX_PORT_STS, &val);
if (err)
return err;
eee->eee_active = !!(val & MV88E6352_PORT_STS_EEE);
return 0;
}
/* Offset 0x01: MAC (or PCS or Physical) Control Register
*
* Link, Duplex and Flow Control have one force bit, one value bit.
......
......@@ -216,9 +216,6 @@
/* Offset 0x13: OutFiltered Counter */
#define MV88E6XXX_PORT_OUT_FILTERED 0x13
/* Offset 0x16: LED Control */
#define MV88E6XXX_PORT_LED_CONTROL 0x16
/* Offset 0x18: IEEE Priority Mapping Table */
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE 0x18
#define MV88E6390_PORT_IEEE_PRIO_MAP_TABLE_UPDATE 0x8000
......@@ -244,6 +241,9 @@ int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg,
int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg,
u16 val);
int mv88e6xxx_port_status_eee(struct mv88e6xxx_chip *chip, int port,
struct ethtool_eee *eee);
int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
phy_interface_t mode);
int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment