Commit a8583901 authored by David S. Miller's avatar David S. Miller

Merge branch 'net-dsa-mv88e6xxx-prepare-Wait-Bit-operation'

Vivien Didelot says:

====================
net: dsa: mv88e6xxx: prepare Wait Bit operation

The Remote Management Interface has its own implementation of a Wait
Bit operation, which requires a bit number and a value to wait for.

In order to prepare the introduction of this implementation, rework the
code waiting for bits and masks in mv88e6xxx to match this signature.

This has the benefit to unify the implementation of wait routines while
removing obsolete wait and update functions and also reducing the code.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents eb2e7f09 eede2361
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
* Vivien Didelot <vivien.didelot@savoirfairelinux.com> * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
*/ */
#include <linux/bitfield.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/ethtool.h> #include <linux/ethtool.h>
...@@ -80,6 +81,36 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val) ...@@ -80,6 +81,36 @@ int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val)
return 0; return 0;
} }
int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 mask, u16 val)
{
u16 data;
int err;
int i;
/* There's no bus specific operation to wait for a mask */
for (i = 0; i < 16; i++) {
err = mv88e6xxx_read(chip, addr, reg, &data);
if (err)
return err;
if ((data & mask) == val)
return 0;
usleep_range(1000, 2000);
}
dev_err(chip->dev, "Timeout while waiting for switch\n");
return -ETIMEDOUT;
}
int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
int bit, int val)
{
return mv88e6xxx_wait_mask(chip, addr, reg, BIT(bit),
val ? BIT(bit) : 0x0000);
}
struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip) struct mii_bus *mv88e6xxx_default_mdio_bus(struct mv88e6xxx_chip *chip)
{ {
struct mv88e6xxx_mdio_bus *mdio_bus; struct mv88e6xxx_mdio_bus *mdio_bus;
...@@ -363,45 +394,6 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip) ...@@ -363,45 +394,6 @@ static void mv88e6xxx_irq_poll_free(struct mv88e6xxx_chip *chip)
mv88e6xxx_reg_unlock(chip); mv88e6xxx_reg_unlock(chip);
} }
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask)
{
int i;
for (i = 0; i < 16; i++) {
u16 val;
int err;
err = mv88e6xxx_read(chip, addr, reg, &val);
if (err)
return err;
if (!(val & mask))
return 0;
usleep_range(1000, 2000);
}
dev_err(chip->dev, "Timeout while waiting for switch\n");
return -ETIMEDOUT;
}
/* Indirect write to single pointer-data register with an Update bit */
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, u16 update)
{
u16 val;
int err;
/* Wait until the previous operation is completed */
err = mv88e6xxx_wait(chip, addr, reg, BIT(15));
if (err)
return err;
/* Set the Update bit to trigger a write operation */
val = BIT(15) | update;
return mv88e6xxx_write(chip, addr, reg, val);
}
int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link, int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
int speed, int duplex, int pause, int speed, int duplex, int pause,
phy_interface_t mode) phy_interface_t mode)
...@@ -2354,8 +2346,10 @@ static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port, ...@@ -2354,8 +2346,10 @@ static int mv88e6390_hidden_write(struct mv88e6xxx_chip *chip, int port,
static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip) static int mv88e6390_hidden_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_wait(chip, PORT_RESERVED_1A_CTRL_PORT, int bit = __bf_shf(PORT_RESERVED_1A_BUSY);
PORT_RESERVED_1A, PORT_RESERVED_1A_BUSY);
return mv88e6xxx_wait_bit(chip, PORT_RESERVED_1A_CTRL_PORT,
PORT_RESERVED_1A, bit, 0);
} }
......
...@@ -588,9 +588,10 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po ...@@ -588,9 +588,10 @@ static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int po
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val); int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val); int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg, int mv88e6xxx_wait_mask(struct mv88e6xxx_chip *chip, int addr, int reg,
u16 update); u16 mask, u16 val);
int mv88e6xxx_wait(struct mv88e6xxx_chip *chip, int addr, int reg, u16 mask); int mv88e6xxx_wait_bit(struct mv88e6xxx_chip *chip, int addr, int reg,
int bit, int val);
int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link, int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, int link,
int speed, int duplex, int pause, int speed, int duplex, int pause,
phy_interface_t mode); phy_interface_t mode);
......
...@@ -27,100 +27,52 @@ int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val) ...@@ -27,100 +27,52 @@ int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
return mv88e6xxx_write(chip, addr, reg, val); return mv88e6xxx_write(chip, addr, reg, val);
} }
int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask) int mv88e6xxx_g1_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
bit, int val)
{ {
return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask); return mv88e6xxx_wait_bit(chip, chip->info->global1_addr, reg,
bit, val);
}
int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
u16 mask, u16 val)
{
return mv88e6xxx_wait_mask(chip, chip->info->global1_addr, reg,
mask, val);
} }
/* Offset 0x00: Switch Global Status Register */ /* Offset 0x00: Switch Global Status Register */
static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip) static int mv88e6185_g1_wait_ppu_disabled(struct mv88e6xxx_chip *chip)
{ {
u16 state; return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
int i, err; MV88E6185_G1_STS_PPU_STATE_MASK,
MV88E6185_G1_STS_PPU_STATE_DISABLED);
for (i = 0; i < 16; i++) {
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
if (err)
return err;
/* Check the value of the PPUState bits 15:14 */
state &= MV88E6185_G1_STS_PPU_STATE_MASK;
if (state != MV88E6185_G1_STS_PPU_STATE_POLLING)
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
} }
static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) static int mv88e6185_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
{ {
u16 state; return mv88e6xxx_g1_wait_mask(chip, MV88E6XXX_G1_STS,
int i, err; MV88E6185_G1_STS_PPU_STATE_MASK,
MV88E6185_G1_STS_PPU_STATE_POLLING);
for (i = 0; i < 16; ++i) {
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
if (err)
return err;
/* Check the value of the PPUState bits 15:14 */
state &= MV88E6185_G1_STS_PPU_STATE_MASK;
if (state == MV88E6185_G1_STS_PPU_STATE_POLLING)
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
} }
static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip) static int mv88e6352_g1_wait_ppu_polling(struct mv88e6xxx_chip *chip)
{ {
u16 state; int bit = __bf_shf(MV88E6352_G1_STS_PPU_STATE);
int i, err;
for (i = 0; i < 16; ++i) { return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &state);
if (err)
return err;
/* Check the value of the PPUState (or InitState) bit 15 */
if (state & MV88E6352_G1_STS_PPU_STATE)
return 0;
usleep_range(1000, 2000);
}
return -ETIMEDOUT;
} }
static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g1_wait_init_ready(struct mv88e6xxx_chip *chip)
{ {
const unsigned long timeout = jiffies + 1 * HZ; int bit = __bf_shf(MV88E6XXX_G1_STS_INIT_READY);
u16 val;
int err;
/* Wait up to 1 second for the switch to be ready. The InitReady bit 11 /* Wait up to 1 second for the switch to be ready. The InitReady bit 11
* is set to a one when all units inside the device (ATU, VTU, etc.) * is set to a one when all units inside the device (ATU, VTU, etc.)
* have finished their initialization and are ready to accept frames. * have finished their initialization and are ready to accept frames.
*/ */
while (time_before(jiffies, timeout)) { return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STS, bit, 1);
err = mv88e6xxx_g1_read(chip, MV88E6XXX_G1_STS, &val);
if (err)
return err;
if (val & MV88E6XXX_G1_STS_INIT_READY)
break;
usleep_range(1000, 2000);
}
if (time_after(jiffies, timeout))
return -ETIMEDOUT;
return 0;
} }
/* Offset 0x01: Switch MAC Address Register Bytes 0 & 1 /* Offset 0x01: Switch MAC Address Register Bytes 0 & 1
...@@ -476,8 +428,9 @@ int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index) ...@@ -476,8 +428,9 @@ int mv88e6xxx_g1_set_device_number(struct mv88e6xxx_chip *chip, int index)
static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g1_stats_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_STATS_OP, int bit = __bf_shf(MV88E6XXX_G1_STATS_OP_BUSY);
MV88E6XXX_G1_STATS_OP_BUSY);
return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_STATS_OP, bit, 0);
} }
int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip) int mv88e6095_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
......
...@@ -249,7 +249,10 @@ ...@@ -249,7 +249,10 @@
int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val); int mv88e6xxx_g1_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val); int mv88e6xxx_g1_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask); int mv88e6xxx_g1_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
bit, int val);
int mv88e6xxx_g1_wait_mask(struct mv88e6xxx_chip *chip, int reg,
u16 mask, u16 val);
int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr); int mv88e6xxx_g1_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr);
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
* Copyright (c) 2008 Marvell Semiconductor * Copyright (c) 2008 Marvell Semiconductor
* Copyright (c) 2017 Savoir-faire Linux, Inc. * Copyright (c) 2017 Savoir-faire Linux, Inc.
*/ */
#include <linux/bitfield.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
...@@ -75,8 +77,9 @@ int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip, ...@@ -75,8 +77,9 @@ int mv88e6xxx_g1_atu_set_age_time(struct mv88e6xxx_chip *chip,
static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g1_atu_op_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_ATU_OP, int bit = __bf_shf(MV88E6XXX_G1_ATU_OP_BUSY);
MV88E6XXX_G1_ATU_OP_BUSY);
return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_ATU_OP, bit, 0);
} }
static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op) static int mv88e6xxx_g1_atu_op(struct mv88e6xxx_chip *chip, u16 fid, u16 op)
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
* Copyright (c) 2017 Savoir-faire Linux, Inc. * Copyright (c) 2017 Savoir-faire Linux, Inc.
*/ */
#include <linux/bitfield.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
...@@ -67,8 +68,9 @@ static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip, ...@@ -67,8 +68,9 @@ static int mv88e6xxx_g1_vtu_sid_write(struct mv88e6xxx_chip *chip,
static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g1_vtu_op_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g1_wait(chip, MV88E6XXX_G1_VTU_OP, int bit = __bf_shf(MV88E6XXX_G1_VTU_OP_BUSY);
MV88E6XXX_G1_VTU_OP_BUSY);
return mv88e6xxx_g1_wait_bit(chip, MV88E6XXX_G1_VTU_OP, bit, 0);
} }
static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op) static int mv88e6xxx_g1_vtu_op(struct mv88e6xxx_chip *chip, u16 op)
......
...@@ -26,14 +26,11 @@ int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val) ...@@ -26,14 +26,11 @@ int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val)
return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val); return mv88e6xxx_write(chip, chip->info->global2_addr, reg, val);
} }
int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update) int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg, int
bit, int val)
{ {
return mv88e6xxx_update(chip, chip->info->global2_addr, reg, update); return mv88e6xxx_wait_bit(chip, chip->info->global2_addr, reg,
} bit, val);
int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
{
return mv88e6xxx_wait(chip, chip->info->global2_addr, reg, mask);
} }
/* Offset 0x00: Interrupt Source Register */ /* Offset 0x00: Interrupt Source Register */
...@@ -123,7 +120,8 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target, ...@@ -123,7 +120,8 @@ int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
* but bit 4 is reserved on older chips, so it is safe to use. * but bit 4 is reserved on older chips, so it is safe to use.
*/ */
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_DEVICE_MAPPING, val); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_DEVICE_MAPPING,
MV88E6XXX_G2_DEVICE_MAPPING_UPDATE | val);
} }
/* Offset 0x07: Trunk Mask Table register */ /* Offset 0x07: Trunk Mask Table register */
...@@ -136,7 +134,8 @@ static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num, ...@@ -136,7 +134,8 @@ static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
if (hash) if (hash)
val |= MV88E6XXX_G2_TRUNK_MASK_HASH; val |= MV88E6XXX_G2_TRUNK_MASK_HASH;
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MASK, val); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MASK,
MV88E6XXX_G2_TRUNK_MASK_UPDATE | val);
} }
/* Offset 0x08: Trunk Mapping Table register */ /* Offset 0x08: Trunk Mapping Table register */
...@@ -147,7 +146,8 @@ static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id, ...@@ -147,7 +146,8 @@ static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1; const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
u16 val = (id << 11) | (map & port_mask); u16 val = (id << 11) | (map & port_mask);
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MAPPING, val); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_TRUNK_MAPPING,
MV88E6XXX_G2_TRUNK_MAPPING_UPDATE | val);
} }
int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip) int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
...@@ -178,8 +178,9 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip) ...@@ -178,8 +178,9 @@ int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g2_irl_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_IRL_CMD, int bit = __bf_shf(MV88E6XXX_G2_IRL_CMD_BUSY);
MV88E6XXX_G2_IRL_CMD_BUSY);
return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_IRL_CMD, bit, 0);
} }
static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port, static int mv88e6xxx_g2_irl_op(struct mv88e6xxx_chip *chip, u16 op, int port,
...@@ -214,8 +215,9 @@ int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port) ...@@ -214,8 +215,9 @@ int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port)
static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g2_pvt_op_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_PVT_ADDR, int bit = __bf_shf(MV88E6XXX_G2_PVT_ADDR_BUSY);
MV88E6XXX_G2_PVT_ADDR_BUSY);
return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_PVT_ADDR, bit, 0);
} }
static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev, static int mv88e6xxx_g2_pvt_op(struct mv88e6xxx_chip *chip, int src_dev,
...@@ -261,7 +263,8 @@ static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip, ...@@ -261,7 +263,8 @@ static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
{ {
u16 val = (pointer << 8) | data; u16 val = (pointer << 8) | data;
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SWITCH_MAC, val); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MAC,
MV88E6XXX_G2_SWITCH_MAC_UPDATE | val);
} }
int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr) int mv88e6xxx_g2_set_switch_mac(struct mv88e6xxx_chip *chip, u8 *addr)
...@@ -284,7 +287,8 @@ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer, ...@@ -284,7 +287,8 @@ static int mv88e6xxx_g2_pot_write(struct mv88e6xxx_chip *chip, int pointer,
{ {
u16 val = (pointer << 8) | (data & 0x7); u16 val = (pointer << 8) | (data & 0x7);
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_PRIO_OVERRIDE, val); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_PRIO_OVERRIDE,
MV88E6XXX_G2_PRIO_OVERRIDE_UPDATE | val);
} }
int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip) int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
...@@ -308,9 +312,16 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip) ...@@ -308,9 +312,16 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip)
static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g2_eeprom_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_EEPROM_CMD, int bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_BUSY);
MV88E6XXX_G2_EEPROM_CMD_BUSY | int err;
MV88E6XXX_G2_EEPROM_CMD_RUNNING);
err = mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
if (err)
return err;
bit = __bf_shf(MV88E6XXX_G2_EEPROM_CMD_RUNNING);
return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_EEPROM_CMD, bit, 0);
} }
static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd) static int mv88e6xxx_g2_eeprom_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
...@@ -572,8 +583,9 @@ int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip, ...@@ -572,8 +583,9 @@ int mv88e6xxx_g2_set_eeprom16(struct mv88e6xxx_chip *chip,
static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip) static int mv88e6xxx_g2_smi_phy_wait(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g2_wait(chip, MV88E6XXX_G2_SMI_PHY_CMD, int bit = __bf_shf(MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
MV88E6XXX_G2_SMI_PHY_CMD_BUSY);
return mv88e6xxx_g2_wait_bit(chip, MV88E6XXX_G2_SMI_PHY_CMD, bit, 0);
} }
static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd) static int mv88e6xxx_g2_smi_phy_cmd(struct mv88e6xxx_chip *chip, u16 cmd)
...@@ -840,12 +852,13 @@ const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = { ...@@ -840,12 +852,13 @@ const struct mv88e6xxx_irq_ops mv88e6250_watchdog_ops = {
static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip) static int mv88e6390_watchdog_setup(struct mv88e6xxx_chip *chip)
{ {
return mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL, return mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE | MV88E6390_G2_WDOG_CTL_UPDATE |
MV88E6390_G2_WDOG_CTL_CUT_THROUGH | MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE |
MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER | MV88E6390_G2_WDOG_CTL_CUT_THROUGH |
MV88E6390_G2_WDOG_CTL_EGRESS | MV88E6390_G2_WDOG_CTL_QUEUE_CONTROLLER |
MV88E6390_G2_WDOG_CTL_FORCE_IRQ); MV88E6390_G2_WDOG_CTL_EGRESS |
MV88E6390_G2_WDOG_CTL_FORCE_IRQ);
} }
static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq) static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
...@@ -878,8 +891,9 @@ static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq) ...@@ -878,8 +891,9 @@ static int mv88e6390_watchdog_action(struct mv88e6xxx_chip *chip, int irq)
static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip) static void mv88e6390_watchdog_free(struct mv88e6xxx_chip *chip)
{ {
mv88e6xxx_g2_update(chip, MV88E6390_G2_WDOG_CTL, mv88e6xxx_g2_write(chip, MV88E6390_G2_WDOG_CTL,
MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE); MV88E6390_G2_WDOG_CTL_UPDATE |
MV88E6390_G2_WDOG_CTL_PTR_INT_ENABLE);
} }
const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = { const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops = {
......
...@@ -295,8 +295,8 @@ static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip) ...@@ -295,8 +295,8 @@ static inline int mv88e6xxx_g2_require(struct mv88e6xxx_chip *chip)
int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val); int mv88e6xxx_g2_read(struct mv88e6xxx_chip *chip, int reg, u16 *val);
int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val); int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 val);
int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update); int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip, int reg,
int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask); int bit, int val);
int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port); int mv88e6352_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port); int mv88e6390_g2_irl_init_all(struct mv88e6xxx_chip *chip, int port);
...@@ -376,12 +376,8 @@ static inline int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 v ...@@ -376,12 +376,8 @@ static inline int mv88e6xxx_g2_write(struct mv88e6xxx_chip *chip, int reg, u16 v
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int mv88e6xxx_g2_update(struct mv88e6xxx_chip *chip, int reg, u16 update) static inline int mv88e6xxx_g2_wait_bit(struct mv88e6xxx_chip *chip,
{ int reg, int bit, int val)
return -EOPNOTSUPP;
}
static inline int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
* Brandon Streiff <brandon.streiff@ni.com> * Brandon Streiff <brandon.streiff@ni.com>
*/ */
#include <linux/bitfield.h>
#include "global2.h" #include "global2.h"
/* Offset 0x16: AVB Command Register /* Offset 0x16: AVB Command Register
...@@ -27,17 +29,33 @@ ...@@ -27,17 +29,33 @@
/* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words. /* mv88e6xxx_g2_avb_read -- Read one or multiple 16-bit words.
* The hardware supports snapshotting up to four contiguous registers. * The hardware supports snapshotting up to four contiguous registers.
*/ */
static int mv88e6xxx_g2_avb_wait(struct mv88e6xxx_chip *chip)
{
int bit = __bf_shf(MV88E6352_G2_AVB_CMD_BUSY);
return mv88e6xxx_g2_wait_bit(chip, MV88E6352_G2_AVB_CMD, bit, 0);
}
static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop, static int mv88e6xxx_g2_avb_read(struct mv88e6xxx_chip *chip, u16 readop,
u16 *data, int len) u16 *data, int len)
{ {
int err; int err;
int i; int i;
err = mv88e6xxx_g2_avb_wait(chip);
if (err)
return err;
/* Hardware can only snapshot four words. */ /* Hardware can only snapshot four words. */
if (len > 4) if (len > 4)
return -E2BIG; return -E2BIG;
err = mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, readop); err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
MV88E6352_G2_AVB_CMD_BUSY | readop);
if (err)
return err;
err = mv88e6xxx_g2_avb_wait(chip);
if (err) if (err)
return err; return err;
...@@ -57,11 +75,18 @@ static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop, ...@@ -57,11 +75,18 @@ static int mv88e6xxx_g2_avb_write(struct mv88e6xxx_chip *chip, u16 writeop,
{ {
int err; int err;
err = mv88e6xxx_g2_avb_wait(chip);
if (err)
return err;
err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data); err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_DATA, data);
if (err) if (err)
return err; return err;
return mv88e6xxx_g2_update(chip, MV88E6352_G2_AVB_CMD, writeop); err = mv88e6xxx_g2_write(chip, MV88E6352_G2_AVB_CMD,
MV88E6352_G2_AVB_CMD_BUSY | writeop);
return mv88e6xxx_g2_avb_wait(chip);
} }
static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip, static int mv88e6352_g2_avb_port_ptp_read(struct mv88e6xxx_chip *chip,
......
...@@ -37,7 +37,8 @@ static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg, ...@@ -37,7 +37,8 @@ static int mv88e6xxx_g2_scratch_write(struct mv88e6xxx_chip *chip, int reg,
{ {
u16 value = (reg << 8) | data; u16 value = (reg << 8) | data;
return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC, value); return mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SCRATCH_MISC_MISC,
MV88E6XXX_G2_SCRATCH_MISC_UPDATE | value);
} }
/** /**
......
...@@ -64,8 +64,10 @@ static int mv88e6xxx_smi_direct_wait(struct mv88e6xxx_chip *chip, ...@@ -64,8 +64,10 @@ static int mv88e6xxx_smi_direct_wait(struct mv88e6xxx_chip *chip,
if (err) if (err)
return err; return err;
if (!!(data >> bit) == !!val) if (!!(data & BIT(bit)) == !!val)
return 0; return 0;
usleep_range(1000, 2000);
} }
return -ETIMEDOUT; return -ETIMEDOUT;
......
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