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

Merge branch 'mv88e6390-batch-three'

Andrew Lunn says:

====================
mv88e6390 batch 3

More patches to support the MV88e6390. This is mostly refactoring
existing code and adding implementations for the mv88e6390.  This
patchset set which reserved frames are sent to the cpu, the size of
jumbo frames that will be accepted, turn off egress rate limiting, and
configuration of pause frames.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 7a6c5cb9 3ce0e65e
This diff is collapsed.
......@@ -102,6 +102,33 @@ int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
port);
}
int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
int err;
/* 01:c2:80:00:00:00:00-01:c2:80:00:00:00:07 are Management */
err = mv88e6390_g1_monitor_write(
chip, GLOBAL_MONITOR_CONTROL_0180C280000000XLO, 0xff);
if (err)
return err;
/* 01:c2:80:00:00:00:08-01:c2:80:00:00:00:0f are Management */
err = mv88e6390_g1_monitor_write(
chip, GLOBAL_MONITOR_CONTROL_0180C280000000XHI, 0xff);
if (err)
return err;
/* 01:c2:80:00:00:00:20-01:c2:80:00:00:00:27 are Management */
err = mv88e6390_g1_monitor_write(
chip, GLOBAL_MONITOR_CONTROL_0180C280000002XLO, 0xff);
if (err)
return err;
/* 01:c2:80:00:00:00:28-01:c2:80:00:00:00:2f are Management */
return mv88e6390_g1_monitor_write(
chip, GLOBAL_MONITOR_CONTROL_0180C280000002XHI, 0xff);
}
/* Offset 0x1c: Global Control 2 */
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
......
......@@ -29,5 +29,6 @@ int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port);
int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
#endif /* _MV88E6XXX_GLOBAL1_H */
......@@ -38,6 +38,31 @@ static int mv88e6xxx_g2_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
return mv88e6xxx_wait(chip, ADDR_GLOBAL2, reg, mask);
}
/* Offset 0x02: Management Enable 2x */
/* Offset 0x03: Management Enable 0x */
int mv88e6095_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.
*/
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_2X, 0xffff);
if (err)
return err;
}
/* Consider the frames with reserved multicast destination
* addresses matching 01:80:c2:00:00:0x as MGMT.
*/
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X))
return mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_0X, 0xffff);
return 0;
}
/* Offset 0x06: Device Mapping Table register */
static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
......@@ -567,24 +592,6 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
u16 reg;
int err;
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
/* Consider the frames with reserved multicast destination
* addresses matching 01:80:c2:00:00:2x as MGMT.
*/
err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_2X, 0xffff);
if (err)
return err;
}
if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_0X)) {
/* Consider the frames with reserved multicast destination
* addresses matching 01:80:c2:00:00:0x as MGMT.
*/
err = mv88e6xxx_g2_write(chip, GLOBAL2_MGMT_EN_0X, 0xffff);
if (err)
return err;
}
/* Ignore removed tag data on doubly tagged packets, disable
* flow control messages, force flow control priority to the
* highest, and send all special multicast frames to the CPU
......
......@@ -35,6 +35,7 @@ int mv88e6xxx_g2_set_eeprom16(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);
#else /* !CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
......@@ -94,6 +95,11 @@ static inline void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip)
{
}
static inline int mv88e6095_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
{
return -EOPNOTSUPP;
}
#endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
#endif /* _MV88E6XXX_GLOBAL2_H */
......@@ -78,6 +78,8 @@
#define PORT_PCS_CTRL_SPEED_10000 (0x03) /* 6390X */
#define PORT_PCS_CTRL_SPEED_UNFORCED (0x03)
#define PORT_PAUSE_CTRL 0x02
#define PORT_FLOW_CTRL_LIMIT_IN ((0x00 << 8) | BIT(15))
#define PORT_FLOW_CTRL_LIMIT_OUT ((0x01 << 8) | BIT(15))
#define PORT_SWITCH_ID 0x03
#define PORT_SWITCH_ID_PROD_NUM_6085 0x04a
#define PORT_SWITCH_ID_PROD_NUM_6095 0x095
......@@ -833,6 +835,10 @@ struct mv88e6xxx_ops {
bool on);
int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
u16 etype);
int (*port_jumbo_config)(struct mv88e6xxx_chip *chip, int port);
int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
int (*port_pause_config)(struct mv88e6xxx_chip *chip, int port);
/* Snapshot the statistics for a port. The statistics can then
* be read back a leisure but still with a consistent view.
......@@ -851,6 +857,9 @@ struct mv88e6xxx_ops {
uint64_t *data);
int (*g1_set_cpu_port)(struct mv88e6xxx_chip *chip, int port);
int (*g1_set_egress_port)(struct mv88e6xxx_chip *chip, int port);
/* Can be either in g1 or g2, so don't use a prefix */
int (*mgmt_rsvd2cpu)(struct mv88e6xxx_chip *chip);
};
#define STATS_TYPE_PORT BIT(0)
......
......@@ -304,6 +304,30 @@ int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
}
/* Offset 0x02: Pause Control
*
* Do not limit the period of time that this port can be paused for by
* the remote end or the period of time that this port can pause the
* remote end.
*/
int mv88e6097_port_pause_config(struct mv88e6xxx_chip *chip, int port)
{
return mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
}
int mv88e6390_port_pause_config(struct mv88e6xxx_chip *chip, int port)
{
int err;
err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL,
PORT_FLOW_CTRL_LIMIT_IN | 0);
if (err)
return err;
return mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL,
PORT_FLOW_CTRL_LIMIT_OUT | 0);
}
/* Offset 0x04: Port Control Register */
static const char * const mv88e6xxx_port_state_names[] = {
......@@ -607,6 +631,32 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
return 0;
}
int mv88e6165_port_jumbo_config(struct mv88e6xxx_chip *chip, int port)
{
u16 reg;
int err;
err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg);
if (err)
return err;
reg |= PORT_CONTROL_2_JUMBO_10240;
return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
}
/* Offset 0x09: Port Rate Control */
int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
{
return mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL, 0x0000);
}
int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port)
{
return mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL, 0x0001);
}
/* Offset 0x0f: Port Ether type */
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
......
......@@ -62,6 +62,10 @@ int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
bool on);
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
u16 etype);
int mv88e6165_port_jumbo_config(struct mv88e6xxx_chip *chip, int port);
int mv88e6095_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
int mv88e6097_port_egress_rate_limiting(struct mv88e6xxx_chip *chip, int port);
int mv88e6097_port_pause_config(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_port_pause_config(struct mv88e6xxx_chip *chip, int port);
#endif /* _MV88E6XXX_PORT_H */
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