* [PATCH v3 net-next 3/4] net: dsa: mv88e6xxx: Move the tagging protocol into info
From: Andrew Lunn @ 2016-12-03 3:35 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736119-12195-1-git-send-email-andrew@lunn.ch>
Older chips support a single tagging protocol, DSA. New chips support
both DSA and EDSA, an enhanced version. Having both as an option
changes the register layouts. Up until now, it has been assumed that
if EDSA is supported, it will be used. Hence the register layout has
been determined by which protocol should be used. However, mv88e6390
has a different implementation of EDSA, which requires we need to use
the DSA tagging. Hence separate the selection of the protocol from the
register layout.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
drivers/net/dsa/mv88e6xxx/chip.c | 33 +++++++++++++++++++++++++++------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 17 ++++-------------
2 files changed, 31 insertions(+), 19 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 6e981bedd028..80efee6f5e16 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2482,7 +2482,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
PORT_CONTROL_STATE_FORWARDING;
if (dsa_is_cpu_port(ds, port)) {
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
+ if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
PORT_CONTROL_FORWARD_UNKNOWN_MC;
else
@@ -2611,7 +2611,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
/* Port Ethertype: use the Ethertype DSA Ethertype
* value.
*/
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA)) {
+ if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA) {
err = mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE,
ETH_P_EDSA);
if (err)
@@ -3637,6 +3637,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 8,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6097,
.ops = &mv88e6085_ops,
},
@@ -3651,6 +3652,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 8,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6095,
.ops = &mv88e6095_ops,
},
@@ -3679,6 +3681,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6165,
.ops = &mv88e6123_ops,
},
@@ -3693,6 +3696,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6185,
.ops = &mv88e6131_ops,
},
@@ -3707,6 +3711,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6165,
.ops = &mv88e6161_ops,
},
@@ -3721,6 +3726,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6165,
.ops = &mv88e6165_ops,
},
@@ -3735,6 +3741,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6351,
.ops = &mv88e6171_ops,
},
@@ -3749,6 +3756,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6352,
.ops = &mv88e6172_ops,
},
@@ -3763,6 +3771,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6351,
.ops = &mv88e6175_ops,
},
@@ -3777,6 +3786,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6352,
.ops = &mv88e6176_ops,
},
@@ -3791,6 +3801,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 8,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6185,
.ops = &mv88e6185_ops,
},
@@ -3803,6 +3814,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.num_ports = 11, /* 10 + Z80 */
.port_base_addr = 0x0,
.global1_addr = 0x1b,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.age_time_coeff = 15000,
.g1_irqs = 9,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
@@ -3819,6 +3831,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
.ops = &mv88e6190x_ops,
},
@@ -3832,6 +3845,8 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.port_base_addr = 0x0,
.global1_addr = 0x1b,
.age_time_coeff = 15000,
+ .g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
.ops = &mv88e6391_ops,
},
@@ -3846,6 +3861,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6352,
.ops = &mv88e6240_ops,
},
@@ -3860,6 +3876,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
.ops = &mv88e6290_ops,
},
@@ -3874,6 +3891,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 8,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6320,
.ops = &mv88e6320_ops,
},
@@ -3888,6 +3906,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 8,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6320,
.ops = &mv88e6321_ops,
},
@@ -3902,6 +3921,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6351,
.ops = &mv88e6350_ops,
},
@@ -3916,6 +3936,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6351,
.ops = &mv88e6351_ops,
},
@@ -3930,6 +3951,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_EDSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6352,
.ops = &mv88e6352_ops,
},
@@ -3943,6 +3965,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
.ops = &mv88e6390_ops,
},
@@ -3956,6 +3979,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
.global1_addr = 0x1b,
.age_time_coeff = 15000,
.g1_irqs = 9,
+ .tag_protocol = DSA_TAG_PROTO_DSA,
.flags = MV88E6XXX_FLAGS_FAMILY_6390,
.ops = &mv88e6390x_ops,
},
@@ -4056,10 +4080,7 @@ static enum dsa_tag_protocol mv88e6xxx_get_tag_protocol(struct dsa_switch *ds)
{
struct mv88e6xxx_chip *chip = ds->priv;
- if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_EDSA))
- return DSA_TAG_PROTO_EDSA;
-
- return DSA_TAG_PROTO_DSA;
+ return chip->info->tag_protocol;
}
static const char *mv88e6xxx_drv_probe(struct device *dsa_dev,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index a6dd192652e8..2c51e3a8a890 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -438,12 +438,6 @@ enum mv88e6xxx_family {
};
enum mv88e6xxx_cap {
- /* Two different tag protocols can be used by the driver. All
- * switches support DSA, but only later generations support
- * EDSA.
- */
- MV88E6XXX_CAP_EDSA,
-
/* Energy Efficient Ethernet.
*/
MV88E6XXX_CAP_EEE,
@@ -506,7 +500,6 @@ enum mv88e6xxx_cap {
};
/* Bitmask of capabilities */
-#define MV88E6XXX_FLAG_EDSA BIT_ULL(MV88E6XXX_CAP_EDSA)
#define MV88E6XXX_FLAG_EEE BIT_ULL(MV88E6XXX_CAP_EEE)
#define MV88E6XXX_FLAG_SMI_CMD BIT_ULL(MV88E6XXX_CAP_SMI_CMD)
@@ -601,8 +594,7 @@ enum mv88e6xxx_cap {
MV88E6XXX_FLAG_VTU)
#define MV88E6XXX_FLAGS_FAMILY_6320 \
- (MV88E6XXX_FLAG_EDSA | \
- MV88E6XXX_FLAG_EEE | \
+ (MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_MGMT_EN_2X | \
MV88E6XXX_FLAG_G2_MGMT_EN_0X | \
@@ -616,8 +608,7 @@ enum mv88e6xxx_cap {
MV88E6XXX_FLAGS_PVT)
#define MV88E6XXX_FLAGS_FAMILY_6351 \
- (MV88E6XXX_FLAG_EDSA | \
- MV88E6XXX_FLAG_G1_ATU_FID | \
+ (MV88E6XXX_FLAG_G1_ATU_FID | \
MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
MV88E6XXX_FLAG_G2_INT | \
@@ -633,8 +624,7 @@ enum mv88e6xxx_cap {
MV88E6XXX_FLAGS_PVT)
#define MV88E6XXX_FLAGS_FAMILY_6352 \
- (MV88E6XXX_FLAG_EDSA | \
- MV88E6XXX_FLAG_EEE | \
+ (MV88E6XXX_FLAG_EEE | \
MV88E6XXX_FLAG_G1_ATU_FID | \
MV88E6XXX_FLAG_G1_VTU_FID | \
MV88E6XXX_FLAG_GLOBAL2 | \
@@ -676,6 +666,7 @@ struct mv88e6xxx_info {
unsigned int global1_addr;
unsigned int age_time_coeff;
unsigned int g1_irqs;
+ enum dsa_tag_protocol tag_protocol;
unsigned long long flags;
const struct mv88e6xxx_ops *ops;
};
--
2.10.2
^ permalink raw reply related
* [PATCH v3 net-next 4/4] net: dsa: mv88e6xxx: Refactor CPU and DSA port setup
From: Andrew Lunn @ 2016-12-03 3:35 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736119-12195-1-git-send-email-andrew@lunn.ch>
Older chips only support DSA tagging. Newer chips have both DSA and
EDSA tagging. Refactor the code by adding port functions for setting the
frame mode, egress mode, and if to forward unknown frames.
This results in the helper mv88e6xxx_6065_family() becoming unused, so
remove it.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
v3:
Verify mandatory ops for port setup
Don't set ether type for DSA port.
---
drivers/net/dsa/mv88e6xxx/chip.c | 217 ++++++++++++++++++++++++++--------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 20 ++++
drivers/net/dsa/mv88e6xxx/port.c | 118 ++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 13 ++
4 files changed, 319 insertions(+), 49 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 80efee6f5e16..9c14aaad5103 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -677,11 +677,6 @@ static int mv88e6xxx_phy_ppu_write(struct mv88e6xxx_chip *chip, int addr,
return err;
}
-static bool mv88e6xxx_6065_family(struct mv88e6xxx_chip *chip)
-{
- return chip->info->family == MV88E6XXX_FAMILY_6065;
-}
-
static bool mv88e6xxx_6095_family(struct mv88e6xxx_chip *chip)
{
return chip->info->family == MV88E6XXX_FAMILY_6095;
@@ -2438,6 +2433,72 @@ static int mv88e6xxx_serdes_power_on(struct mv88e6xxx_chip *chip)
return err;
}
+static int mv88e6xxx_setup_port_dsa(struct mv88e6xxx_chip *chip, int port,
+ int upstream_port)
+{
+ int err;
+
+ err = chip->info->ops->port_set_frame_mode(
+ chip, port, MV88E6XXX_FRAME_MODE_DSA);
+ if (err)
+ return err;
+
+ return chip->info->ops->port_set_egress_unknowns(
+ chip, port, port == upstream_port);
+}
+
+static int mv88e6xxx_setup_port_cpu(struct mv88e6xxx_chip *chip, int port)
+{
+ int err;
+
+ switch (chip->info->tag_protocol) {
+ case DSA_TAG_PROTO_EDSA:
+ err = chip->info->ops->port_set_frame_mode(
+ chip, port, MV88E6XXX_FRAME_MODE_ETHERTYPE);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_port_set_egress_mode(
+ chip, port, PORT_CONTROL_EGRESS_ADD_TAG);
+ if (err)
+ return err;
+
+ if (chip->info->ops->port_set_ether_type)
+ err = chip->info->ops->port_set_ether_type(
+ chip, port, ETH_P_EDSA);
+ break;
+
+ case DSA_TAG_PROTO_DSA:
+ err = chip->info->ops->port_set_frame_mode(
+ chip, port, MV88E6XXX_FRAME_MODE_DSA);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_port_set_egress_mode(
+ chip, port, PORT_CONTROL_EGRESS_UNMODIFIED);
+ break;
+ default:
+ err = -EINVAL;
+ }
+
+ if (err)
+ return err;
+
+ return chip->info->ops->port_set_egress_unknowns(chip, port, true);
+}
+
+static int mv88e6xxx_setup_port_normal(struct mv88e6xxx_chip *chip, int port)
+{
+ int err;
+
+ err = chip->info->ops->port_set_frame_mode(
+ chip, port, MV88E6XXX_FRAME_MODE_NORMAL);
+ if (err)
+ return err;
+
+ return chip->info->ops->port_set_egress_unknowns(chip, port, false);
+}
+
static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
{
struct dsa_switch *ds = chip->ds;
@@ -2473,44 +2534,23 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
* If this is the upstream port for this switch, enable
* forwarding of unknown unicasts and multicasts.
*/
- reg = 0;
- if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
- mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
- mv88e6xxx_6095_family(chip) || mv88e6xxx_6065_family(chip) ||
- mv88e6xxx_6185_family(chip) || mv88e6xxx_6320_family(chip))
- reg = PORT_CONTROL_IGMP_MLD_SNOOP |
+ reg = PORT_CONTROL_IGMP_MLD_SNOOP |
PORT_CONTROL_USE_TAG | PORT_CONTROL_USE_IP |
PORT_CONTROL_STATE_FORWARDING;
- if (dsa_is_cpu_port(ds, port)) {
- if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA)
- reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA |
- PORT_CONTROL_FORWARD_UNKNOWN_MC;
- else
- reg |= PORT_CONTROL_DSA_TAG;
- reg |= PORT_CONTROL_EGRESS_ADD_TAG |
- PORT_CONTROL_FORWARD_UNKNOWN;
- }
- if (dsa_is_dsa_port(ds, port)) {
- if (mv88e6xxx_6095_family(chip) ||
- mv88e6xxx_6185_family(chip))
- reg |= PORT_CONTROL_DSA_TAG;
- if (mv88e6xxx_6352_family(chip) ||
- mv88e6xxx_6351_family(chip) ||
- mv88e6xxx_6165_family(chip) ||
- mv88e6xxx_6097_family(chip) ||
- mv88e6xxx_6320_family(chip)) {
- reg |= PORT_CONTROL_FRAME_MODE_DSA;
- }
+ err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+ if (err)
+ return err;
- if (port == dsa_upstream_port(ds))
- reg |= PORT_CONTROL_FORWARD_UNKNOWN |
- PORT_CONTROL_FORWARD_UNKNOWN_MC;
- }
- if (reg) {
- err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
- if (err)
- return err;
+ if (dsa_is_cpu_port(ds, port)) {
+ err = mv88e6xxx_setup_port_cpu(chip, port);
+ } else if (dsa_is_dsa_port(ds, port)) {
+ err = mv88e6xxx_setup_port_dsa(chip, port,
+ dsa_upstream_port(ds));
+ } else {
+ err = mv88e6xxx_setup_port_normal(chip, port);
}
+ if (err)
+ return err;
/* If this port is connected to a SerDes, make sure the SerDes is not
* powered down.
@@ -2607,16 +2647,6 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
0x0000);
if (err)
return err;
-
- /* Port Ethertype: use the Ethertype DSA Ethertype
- * value.
- */
- if (chip->info->tag_protocol == DSA_TAG_PROTO_EDSA) {
- err = mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE,
- ETH_P_EDSA);
- if (err)
- return err;
- }
}
if (chip->info->ops->port_tag_remap) {
@@ -3182,6 +3212,9 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3198,6 +3231,8 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_set_frame_mode = mv88e6085_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6085_port_set_egress_unknowns,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3213,6 +3248,9 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3229,6 +3267,8 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_set_frame_mode = mv88e6085_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6085_port_set_egress_unknowns,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3246,6 +3286,9 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3263,6 +3306,9 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3297,6 +3343,9 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3317,6 +3366,9 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3335,6 +3387,9 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3355,6 +3410,9 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3371,6 +3429,8 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_set_frame_mode = mv88e6085_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6085_port_set_egress_unknowns,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3389,6 +3449,9 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3408,6 +3471,9 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390x_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3427,6 +3493,9 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3448,6 +3517,9 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3466,6 +3538,9 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3486,6 +3561,9 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3505,6 +3583,9 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3523,6 +3604,9 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3541,6 +3625,9 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3561,6 +3648,9 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
.port_tag_remap = mv88e6095_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3579,6 +3669,9 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3598,6 +3691,9 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390x_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3617,6 +3713,9 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
.port_tag_remap = mv88e6390_port_tag_remap,
+ .port_set_frame_mode = mv88e6351_port_set_frame_mode,
+ .port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
+ .port_set_ether_type = mv88e6351_port_set_ether_type,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3626,6 +3725,22 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
+static int mv88e6xxx_verify_madatory_ops(struct mv88e6xxx_chip *chip,
+ const struct mv88e6xxx_ops *ops)
+{
+ if (!ops->port_set_frame_mode) {
+ dev_err(chip->dev, "Missing port_set_frame_mode");
+ return -EINVAL;
+ }
+
+ if (!ops->port_set_egress_unknowns) {
+ dev_err(chip->dev, "Missing port_set_egress_mode");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
[MV88E6085] = {
.prod_num = PORT_SWITCH_ID_PROD_NUM_6085,
@@ -4268,6 +4383,10 @@ static int mv88e6xxx_probe(struct mdio_device *mdiodev)
chip->info = compat_info;
+ err = mv88e6xxx_verify_madatory_ops(chip, chip->info->ops);
+ if (err)
+ return err;
+
err = mv88e6xxx_smi_init(chip, mdiodev->bus, mdiodev->addr);
if (err)
return err;
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 2c51e3a8a890..9dd94d7f58d6 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -110,6 +110,7 @@
#define PORT_CONTROL_EGRESS_UNTAGGED (0x1 << 12)
#define PORT_CONTROL_EGRESS_TAGGED (0x2 << 12)
#define PORT_CONTROL_EGRESS_ADD_TAG (0x3 << 12)
+#define PORT_CONTROL_EGRESS_MASK (0x3 << 12)
#define PORT_CONTROL_HEADER BIT(11)
#define PORT_CONTROL_IGMP_MLD_SNOOP BIT(10)
#define PORT_CONTROL_DOUBLE_TAG BIT(9)
@@ -117,6 +118,7 @@
#define PORT_CONTROL_FRAME_MODE_DSA (0x1 << 8)
#define PORT_CONTROL_FRAME_MODE_PROVIDER (0x2 << 8)
#define PORT_CONTROL_FRAME_ETHER_TYPE_DSA (0x3 << 8)
+#define PORT_CONTROL_FRAME_MASK (0x3 << 8)
#define PORT_CONTROL_DSA_TAG BIT(8)
#define PORT_CONTROL_VLAN_TUNNEL BIT(7)
#define PORT_CONTROL_TAG_IF_BOTH BIT(6)
@@ -124,6 +126,10 @@
#define PORT_CONTROL_USE_TAG BIT(4)
#define PORT_CONTROL_FORWARD_UNKNOWN_MC BIT(3)
#define PORT_CONTROL_FORWARD_UNKNOWN BIT(2)
+#define PORT_CONTROL_NOT_EGRESS_UNKNOWN_DA (0x0 << 2)
+#define PORT_CONTROL_NOT_EGRESS_UNKNOWN_MULTICAST_DA (0x1 << 2)
+#define PORT_CONTROL_NOT_EGRESS_UNKNOWN_UNITCAST_DA (0x2 << 2)
+#define PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA (0x3 << 2)
#define PORT_CONTROL_STATE_MASK 0x03
#define PORT_CONTROL_STATE_DISABLED 0x00
#define PORT_CONTROL_STATE_BLOCKING 0x01
@@ -396,6 +402,13 @@
#define MV88E6XXX_N_FID 4096
+enum mv88e6xxx_frame_mode {
+ MV88E6XXX_FRAME_MODE_NORMAL,
+ MV88E6XXX_FRAME_MODE_DSA,
+ MV88E6XXX_FRAME_MODE_PROVIDER,
+ MV88E6XXX_FRAME_MODE_ETHERTYPE,
+};
+
/* List of supported models */
enum mv88e6xxx_model {
MV88E6085,
@@ -814,6 +827,13 @@ struct mv88e6xxx_ops {
int (*port_tag_remap)(struct mv88e6xxx_chip *chip, int port);
+ int (*port_set_frame_mode)(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode);
+ int (*port_set_egress_unknowns)(struct mv88e6xxx_chip *chip, int port,
+ bool on);
+ int (*port_set_ether_type)(struct mv88e6xxx_chip *chip, int port,
+ u16 etype);
+
/* Snapshot the statistics for a port. The statistics can then
* be read back a leisure but still with a consistent view.
*/
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 3d03ea3a2c0d..cf6674911abf 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -335,6 +335,116 @@ int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state)
return 0;
}
+int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
+ u16 mode)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, ®);
+ if (err)
+ return err;
+
+ reg &= ~PORT_CONTROL_EGRESS_MASK;
+ reg |= mode;
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+}
+
+int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, ®);
+ if (err)
+ return err;
+
+ reg &= ~PORT_CONTROL_FRAME_MODE_DSA;
+
+ switch (mode) {
+ case MV88E6XXX_FRAME_MODE_NORMAL:
+ reg |= PORT_CONTROL_FRAME_MODE_NORMAL;
+ break;
+ case MV88E6XXX_FRAME_MODE_DSA:
+ reg |= PORT_CONTROL_FRAME_MODE_DSA;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+}
+
+int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, ®);
+ if (err)
+ return err;
+
+ reg &= ~PORT_CONTROL_FRAME_MASK;
+
+ switch (mode) {
+ case MV88E6XXX_FRAME_MODE_NORMAL:
+ reg |= PORT_CONTROL_FRAME_MODE_NORMAL;
+ break;
+ case MV88E6XXX_FRAME_MODE_DSA:
+ reg |= PORT_CONTROL_FRAME_MODE_DSA;
+ break;
+ case MV88E6XXX_FRAME_MODE_PROVIDER:
+ reg |= PORT_CONTROL_FRAME_MODE_PROVIDER;
+ break;
+ case MV88E6XXX_FRAME_MODE_ETHERTYPE:
+ reg |= PORT_CONTROL_FRAME_ETHER_TYPE_DSA;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+}
+
+int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
+ bool on)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, ®);
+ if (err)
+ return err;
+
+ if (on)
+ reg |= PORT_CONTROL_FORWARD_UNKNOWN;
+ else
+ reg &= ~PORT_CONTROL_FORWARD_UNKNOWN;
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+}
+
+int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
+ bool on)
+{
+ int err;
+ u16 reg;
+
+ err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, ®);
+ if (err)
+ return err;
+
+ if (on)
+ reg |= PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA;
+ else
+ reg &= ~PORT_CONTROL_EGRESS_ALL_UNKNOWN_DA;
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg);
+}
+
/* Offset 0x05: Port Control 1 */
/* Offset 0x06: Port Based VLAN Map */
@@ -497,6 +607,14 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
return 0;
}
+/* Offset 0x0f: Port Ether type */
+
+int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
+ u16 etype)
+{
+ return mv88e6xxx_port_write(chip, port, PORT_ETH_TYPE, etype);
+}
+
/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
* Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
*/
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 5fab4606662b..83cb3440e067 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -50,5 +50,18 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
u16 mode);
int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
+int mv88e6xxx_port_set_egress_mode(struct mv88e6xxx_chip *chip, int port,
+ u16 mode);
+int mv88e6085_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode);
+int mv88e6351_port_set_frame_mode(struct mv88e6xxx_chip *chip, int port,
+ enum mv88e6xxx_frame_mode mode);
+int mv88e6085_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
+ bool on);
+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);
+
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* [PATCH v3 net-next 2/4] net: dsa: mv88e6xxx: Monitor and Management tables
From: Andrew Lunn @ 2016-12-03 3:35 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736119-12195-1-git-send-email-andrew@lunn.ch>
The mv88e6390 changes the monitor control register into the Monitor
and Management control, which is an indirection register to various
registers.
Add ops to set the CPU port and the ingress/egress port for both
register layouts, to global1
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 68 +++++++++++++++++++++++++++++-----
drivers/net/dsa/mv88e6xxx/global1.c | 69 +++++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/global1.h | 4 ++
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 13 +++++++
4 files changed, 145 insertions(+), 9 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ff4bd2f74357..6e981bedd028 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2747,15 +2747,17 @@ static int mv88e6xxx_g1_setup(struct mv88e6xxx_chip *chip)
if (err)
return err;
- /* Configure the upstream port, and configure it as the port to which
- * ingress and egress and ARP monitor frames are to be sent.
- */
- reg = upstream_port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
- upstream_port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT |
- upstream_port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
- err = mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
- if (err)
- return err;
+ if (chip->info->ops->g1_set_cpu_port) {
+ err = chip->info->ops->g1_set_cpu_port(chip, upstream_port);
+ if (err)
+ return err;
+ }
+
+ if (chip->info->ops->g1_set_egress_port) {
+ err = chip->info->ops->g1_set_egress_port(chip, upstream_port);
+ if (err)
+ return err;
+ }
/* Disable remote management, and set the switch's DSA device number. */
err = mv88e6xxx_g1_write(chip, GLOBAL_CONTROL_2,
@@ -3184,6 +3186,8 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3213,6 +3217,8 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
@@ -3227,6 +3233,8 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3242,6 +3250,8 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -3257,6 +3267,8 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -3271,6 +3283,8 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6171_ops = {
@@ -3287,6 +3301,8 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -3305,6 +3321,8 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -3321,6 +3339,8 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -3339,6 +3359,8 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -3353,6 +3375,8 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6190_ops = {
@@ -3370,6 +3394,8 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -3387,6 +3413,8 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -3404,6 +3432,8 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -3422,6 +3452,8 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -3439,6 +3471,8 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -3456,6 +3490,8 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -3473,6 +3509,8 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6320_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6350_ops = {
@@ -3489,6 +3527,8 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
@@ -3505,6 +3545,8 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3523,6 +3565,8 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6095_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3540,6 +3584,8 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3557,6 +3603,8 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_ops mv88e6391_ops = {
@@ -3574,6 +3622,8 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
.stats_get_stats = mv88e6390_stats_get_stats,
+ .g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
+ .g1_set_egress_port = mv88e6390_g1_set_egress_port,
};
static const struct mv88e6xxx_info mv88e6xxx_table[] = {
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index 5fcf23dbf04b..688547026e15 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -33,6 +33,75 @@ int mv88e6xxx_g1_wait(struct mv88e6xxx_chip *chip, int reg, u16 mask)
return mv88e6xxx_wait(chip, chip->info->global1_addr, reg, mask);
}
+/* Offset 0x1a: Monitor Control */
+/* Offset 0x1a: Monitor & MGMT Control on some devices */
+
+int mv88e6095_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_g1_read(chip, GLOBAL_MONITOR_CONTROL, ®);
+ if (err)
+ return err;
+
+ reg &= ~(GLOBAL_MONITOR_CONTROL_INGRESS_MASK |
+ GLOBAL_MONITOR_CONTROL_EGRESS_MASK);
+
+ reg |= port << GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT |
+ port << GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT;
+
+ return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+}
+
+/* Older generations also call this the ARP destination. It has been
+ * generalized in more modern devices such that more than ARP can
+ * egress it
+ */
+int mv88e6095_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
+{
+ u16 reg;
+ int err;
+
+ err = mv88e6xxx_g1_read(chip, GLOBAL_MONITOR_CONTROL, ®);
+ if (err)
+ return err;
+
+ reg &= ~GLOBAL_MONITOR_CONTROL_ARP_MASK;
+ reg |= port << GLOBAL_MONITOR_CONTROL_ARP_SHIFT;
+
+ return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+}
+
+static int mv88e6390_g1_monitor_write(struct mv88e6xxx_chip *chip,
+ u16 pointer, u8 data)
+{
+ u16 reg;
+
+ reg = GLOBAL_MONITOR_CONTROL_UPDATE | pointer | data;
+
+ return mv88e6xxx_g1_write(chip, GLOBAL_MONITOR_CONTROL, reg);
+}
+
+int mv88e6390_g1_set_egress_port(struct mv88e6xxx_chip *chip, int port)
+{
+ int err;
+
+ err = mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_INGRESS,
+ port);
+ if (err)
+ return err;
+
+ return mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_EGRESS,
+ port);
+}
+
+int mv88e6390_g1_set_cpu_port(struct mv88e6xxx_chip *chip, int port)
+{
+ return mv88e6390_g1_monitor_write(chip, GLOBAL_MONITOR_CONTROL_CPU_DEST,
+ port);
+}
+
/* Offset 0x1c: Global Control 2 */
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index df3794cdbfb9..0c979550052f 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -25,5 +25,9 @@ int mv88e6320_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_stats_snapshot(struct mv88e6xxx_chip *chip, int port);
int mv88e6390_g1_stats_set_histogram(struct mv88e6xxx_chip *chip);
void mv88e6xxx_g1_stats_read(struct mv88e6xxx_chip *chip, int stat, u32 *val);
+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);
#endif /* _MV88E6XXX_GLOBAL1_H */
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index a6e9dba665c1..a6dd192652e8 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -287,10 +287,21 @@
#define GLOBAL_CORE_TAG_TYPE 0x19
#define GLOBAL_MONITOR_CONTROL 0x1a
#define GLOBAL_MONITOR_CONTROL_INGRESS_SHIFT 12
+#define GLOBAL_MONITOR_CONTROL_INGRESS_MASK (0xf << 12)
#define GLOBAL_MONITOR_CONTROL_EGRESS_SHIFT 8
+#define GLOBAL_MONITOR_CONTROL_EGRESS_MASK (0xf << 8)
#define GLOBAL_MONITOR_CONTROL_ARP_SHIFT 4
+#define GLOBAL_MONITOR_CONTROL_ARP_MASK (0xf << 4)
#define GLOBAL_MONITOR_CONTROL_MIRROR_SHIFT 0
#define GLOBAL_MONITOR_CONTROL_ARP_DISABLED (0xf0)
+#define GLOBAL_MONITOR_CONTROL_UPDATE BIT(15)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XLO (0x00 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000000XHI (0x01 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XLO (0x02 << 8)
+#define GLOBAL_MONITOR_CONTROL_0180C280000002XHI (0x03 << 8)
+#define GLOBAL_MONITOR_CONTROL_INGRESS (0x20 << 8)
+#define GLOBAL_MONITOR_CONTROL_EGRESS (0x21 << 8)
+#define GLOBAL_MONITOR_CONTROL_CPU_DEST (0x30 << 8)
#define GLOBAL_CONTROL_2 0x1c
#define GLOBAL_CONTROL_2_NO_CASCADE 0xe000
#define GLOBAL_CONTROL_2_MULTIPLE_CASCADE 0xf000
@@ -827,6 +838,8 @@ struct mv88e6xxx_ops {
void (*stats_get_strings)(struct mv88e6xxx_chip *chip, uint8_t *data);
void (*stats_get_stats)(struct mv88e6xxx_chip *chip, int port,
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);
};
#define STATS_TYPE_PORT BIT(0)
--
2.10.2
^ permalink raw reply related
* [PATCH v3 net-next 1/4] net: dsa: mv88e6xxx: Implement mv88e6390 tag remap
From: Andrew Lunn @ 2016-12-03 3:35 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736119-12195-1-git-send-email-andrew@lunn.ch>
The mv88e6390 does not have the two registers to set the frame
priority map. Instead it has an indirection registers for setting a
number of different priority maps. Refactor the old code into an
function, implement the mv88e6390 version, and use an op to call the
right one.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Reviewed-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
v2:
Add port prefix
Add helper function for 6390
Add _IEEE_ into #defines
---
drivers/net/dsa/mv88e6xxx/chip.c | 37 ++++++++++++--------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 12 +++++++
drivers/net/dsa/mv88e6xxx/port.c | 63 +++++++++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 2 ++
4 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index ce2f7ff8066e..ff4bd2f74357 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2617,20 +2617,10 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
if (err)
return err;
}
+ }
- /* Tag Remap: use an identity 802.1p prio -> switch
- * prio mapping.
- */
- err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123,
- 0x3210);
- if (err)
- return err;
-
- /* Tag Remap 2: use an identity 802.1p prio -> switch
- * prio mapping.
- */
- err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567,
- 0x7654);
+ if (chip->info->ops->port_tag_remap) {
+ err = chip->info->ops->port_tag_remap(chip, port);
if (err)
return err;
}
@@ -3189,6 +3179,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3217,6 +3208,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3245,6 +3237,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3259,6 +3252,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3288,6 +3282,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3305,6 +3300,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3320,6 +3316,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3337,6 +3334,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3366,6 +3364,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3382,6 +3381,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390x_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3398,6 +3398,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3416,6 +3417,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3431,6 +3433,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3448,6 +3451,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3464,6 +3468,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_set_link = mv88e6xxx_port_set_link,
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3479,6 +3484,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3494,6 +3500,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6185_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3511,6 +3518,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay,
.port_set_speed = mv88e6352_port_set_speed,
+ .port_tag_remap = mv88e6095_port_tag_remap,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3526,6 +3534,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3542,6 +3551,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390x_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3558,6 +3568,7 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.port_set_duplex = mv88e6xxx_port_set_duplex,
.port_set_rgmii_delay = mv88e6390_port_set_rgmii_delay,
.port_set_speed = mv88e6390_port_set_speed,
+ .port_tag_remap = mv88e6390_port_tag_remap,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index ab52c3772c78..a6e9dba665c1 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -172,6 +172,16 @@
#define PORT_OUT_FILTERED 0x13
#define PORT_TAG_REGMAP_0123 0x18
#define PORT_TAG_REGMAP_4567 0x19
+#define PORT_IEEE_PRIO_MAP_TABLE 0x18 /* 6390 */
+#define PORT_IEEE_PRIO_MAP_TABLE_UPDATE BIT(15)
+#define PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP (0x0 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP (0x1 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP (0x2 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP (0x3 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_DSCP (0x5 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_DSCP (0x6 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_DSCP (0x7 << 12)
+#define PORT_IEEE_PRIO_MAP_TABLE_POINTER_SHIFT 9
#define GLOBAL_STATUS 0x00
#define GLOBAL_STATUS_PPU_STATE BIT(15) /* 6351 and 6171 */
@@ -800,6 +810,8 @@ struct mv88e6xxx_ops {
*/
int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed);
+ int (*port_tag_remap)(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.
*/
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index af4772d86086..3d03ea3a2c0d 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -496,3 +496,66 @@ int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
return 0;
}
+
+/* Offset 0x18: Port IEEE Priority Remapping Registers [0-3]
+ * Offset 0x19: Port IEEE Priority Remapping Registers [4-7]
+ */
+
+int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
+{
+ int err;
+
+ /* Use a direct priority mapping for all IEEE tagged frames */
+ err = mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_0123, 0x3210);
+ if (err)
+ return err;
+
+ return mv88e6xxx_port_write(chip, port, PORT_TAG_REGMAP_4567, 0x7654);
+}
+
+static int mv88e6xxx_port_ieeepmt_write(struct mv88e6xxx_chip *chip,
+ int port, u16 table,
+ u8 pointer, u16 data)
+{
+ u16 reg;
+
+ reg = PORT_IEEE_PRIO_MAP_TABLE_UPDATE |
+ table |
+ (pointer << PORT_IEEE_PRIO_MAP_TABLE_POINTER_SHIFT) |
+ data;
+
+ return mv88e6xxx_port_write(chip, port, PORT_IEEE_PRIO_MAP_TABLE, reg);
+}
+
+int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port)
+{
+ int err, i;
+
+ for (i = 0; i <= 7; i++) {
+ err = mv88e6xxx_port_ieeepmt_write(
+ chip, port, PORT_IEEE_PRIO_MAP_TABLE_INGRESS_PCP,
+ i, (i | i << 4));
+ if (err)
+ return err;
+
+ err = mv88e6xxx_port_ieeepmt_write(
+ chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_GREEN_PCP,
+ i, i);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_port_ieeepmt_write(
+ chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_YELLOW_PCP,
+ i, i);
+ if (err)
+ return err;
+
+ err = mv88e6xxx_port_ieeepmt_write(
+ chip, port, PORT_IEEE_PRIO_MAP_TABLE_EGRESS_AVB_PCP,
+ i, i);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 499129c1489c..5fab4606662b 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -48,5 +48,7 @@ int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid);
int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port,
u16 mode);
+int mv88e6095_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
+int mv88e6390_port_tag_remap(struct mv88e6xxx_chip *chip, int port);
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* Re: [PATCH net-next 2/4] mlx4: xdp: Allow raising MTU up to one page minus eth and vlan hdrs
From: Martin KaFai Lau @ 2016-12-03 3:42 UTC (permalink / raw)
To: Eric Dumazet
Cc: Alexei Starovoitov, netdev, Brenden Blanco, Daniel Borkmann,
David Miller, Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <1480731326.18162.397.camel@edumazet-glaptop3.roam.corp.google.com>
On Fri, Dec 02, 2016 at 06:15:26PM -0800, Eric Dumazet wrote:
> On Fri, 2016-12-02 at 16:53 -0800, Alexei Starovoitov wrote:
> > On 12/2/16 4:38 PM, Eric Dumazet wrote:
> > > On Fri, 2016-12-02 at 15:23 -0800, Martin KaFai Lau wrote:
> > >> When XDP prog is attached, it is currently limiting
> > >> MTU to be FRAG_SZ0 - ETH_HLEN - (2 * VLAN_HLEN) which is 1514
> > >> in x86.
> > >>
> > >> AFAICT, since mlx4 is doing one page per packet for XDP,
> > >> we can at least raise the MTU limitation up to
> > >> PAGE_SIZE - ETH_HLEN - (2 * VLAN_HLEN) which this patch is
> > >> doing. It will be useful in the next patch which allows
> > >> XDP program to extend the packet by adding new header(s).
> > >>
> > >> Signed-off-by: Martin KaFai Lau <kafai@fb.com>
> > >> ---
> > >
> > > Have you tested your patch on a host with PAGE_SIZE = 64 KB ?
> > >
> > > Looks XDP really kills arches with bigger pages :(
> >
> > I'm afraid xdp mlx[45] support was not tested on arches
> > with 64k pages at all. Not just this patch.
> > I think people who care about such archs should test?
> > Note page per packet is not a hard requirement for all drivers
> > and all archs. For mlx[45] it was the easiest and the most
> > convenient way to achieve desired performance.
> > If there are ways to do the same performance differently,
> > I'm all ears :)
> >
>
> My question was more like :
>
> Can we double check all these patches wont break mlx4 driver (non XDP
> path) on arches with PAGE_SIZE=64KB.
The page/pkt requirement is not added by this patch. The earlier
XDP patch series has already ensured this page/pkt requirement
is effective only when XDP prog is attached.
In the earlier XDP patches, MTU is limited to 1514 when
XDP is ative. This patch is to allow fully use of the
page for a packet (and also only matter when XDP is active).
^ permalink raw reply
* Re: [PATCH net-next 1/4] bpf: xdp: Allow head adjustment in XDP prog
From: Martin KaFai Lau @ 2016-12-03 3:43 UTC (permalink / raw)
To: Daniel Borkmann
Cc: netdev, Alexei Starovoitov, Brenden Blanco, David Miller,
Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <5842102D.4000903@iogearbox.net>
On Sat, Dec 03, 2016 at 01:22:05AM +0100, Daniel Borkmann wrote:
> On 12/03/2016 12:23 AM, Martin KaFai Lau wrote:
> >This patch allows XDP prog to extend/remove the packet
> >data at the head (like adding or removing header). It is
> >done by adding a new XDP helper bpf_xdp_adjust_head().
> >
> >It also renames bpf_helper_changes_skb_data() to
> >bpf_helper_changes_pkt_data() to better reflect
> >that XDP prog does not work on skb.
> >
> >Signed-off-by: Martin KaFai Lau <kafai@fb.com>
> [...]
> >diff --git a/net/core/filter.c b/net/core/filter.c
> >index 56b43587d200..6902e2f73e38 100644
> >--- a/net/core/filter.c
> >+++ b/net/core/filter.c
> >@@ -2234,7 +2234,34 @@ static const struct bpf_func_proto bpf_skb_change_head_proto = {
> > .arg3_type = ARG_ANYTHING,
> > };
> >
> >-bool bpf_helper_changes_skb_data(void *func)
> >+BPF_CALL_2(bpf_xdp_adjust_head, struct xdp_buff *, xdp, int, offset)
> >+{
> >+ /* Both mlx4 and mlx5 driver align each packet to PAGE_SIZE when
> >+ * XDP prog is set.
> >+ * If the above is not true for the other drivers to support
> >+ * bpf_xdp_adjust_head, struct xdp_buff can be extended.
> >+ */
> >+ void *head = (void *)((unsigned long)xdp->data & PAGE_MASK);
> >+ void *new_data = xdp->data + offset;
> >+
> >+ if (new_data < head || new_data >= xdp->data_end)
> >+ /* The packet length must be >=1 */
>
> Patch looks generally good to me. Should the min pkt len here be
> limited to ETH_HLEN instead of 1?
Make sense. Will make the change.
>
> >+ return -EINVAL;
> >+
> >+ xdp->data = new_data;
> >+
> >+ return 0;
> >+}
> >+
> >+static const struct bpf_func_proto bpf_xdp_adjust_head_proto = {
> >+ .func = bpf_xdp_adjust_head,
> >+ .gpl_only = false,
> >+ .ret_type = RET_INTEGER,
> >+ .arg1_type = ARG_PTR_TO_CTX,
> >+ .arg2_type = ARG_ANYTHING,
> >+};
> >+
> >+bool bpf_helper_changes_pkt_data(void *func)
> > {
> > if (func == bpf_skb_vlan_push ||
> > func == bpf_skb_vlan_pop ||
> [...]
^ permalink raw reply
* [PATCH v1 net-next 5/5] net: dsa: mv88e6xxx: Implement mv88e6390 pause control
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736720-12608-1-git-send-email-andrew@lunn.ch>
The mv88e6390 has a number flow control registers accessed via the
Flow Control register. Use these to set the pause control.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 7 +++++++
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 2 ++
drivers/net/dsa/mv88e6xxx/port.c | 13 +++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 1 +
4 files changed, 23 insertions(+)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 3ddb1f79e709..ca453f3243cd 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3490,6 +3490,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3513,6 +3514,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3536,6 +3538,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3586,6 +3589,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3739,6 +3743,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3764,6 +3769,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3787,6 +3793,7 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_pause_config = mv88e6390_port_pause_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 3b1f3ab490b9..13c7cc443454 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.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
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index 8d14833b2e49..0db7fa0373ae 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -315,6 +315,19 @@ 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[] = {
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 8c964cfd9032..7b3bacaacbfe 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -66,5 +66,6 @@ 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 */
--
2.10.2
^ permalink raw reply related
* [PATCH v1 net-next 3/5] net: dsa: mv88e6xxx: Refactor egress rate limiting
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736720-12608-1-git-send-email-andrew@lunn.ch>
There are two different rate limiting configurations, depending on the
switch generation. Refactor this into ops.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 31 +++++++++++++++++++------------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 2 ++
drivers/net/dsa/mv88e6xxx/port.c | 12 ++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 2 ++
4 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index db1542e05e62..1b0917e44809 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2657,18 +2657,8 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
return err;
}
- /* Rate Control: disable ingress rate limiting. */
- if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
- mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
- mv88e6xxx_6320_family(chip)) {
- err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
- 0x0001);
- if (err)
- return err;
-
- } else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) {
- err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
- 0x0000);
+ if (chip->info->ops->port_egress_rate_limiting) {
+ err = chip->info->ops->port_egress_rate_limiting(chip, port);
if (err)
return err;
}
@@ -3229,6 +3219,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3268,6 +3259,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3309,6 +3301,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3331,6 +3324,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3371,6 +3365,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3396,6 +3391,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3419,6 +3415,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3444,6 +3441,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3463,6 +3461,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.port_set_speed = mv88e6185_port_set_speed,
.port_set_frame_mode = mv88e6085_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6085_port_set_egress_unknowns,
+ .port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3557,6 +3556,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3604,6 +3604,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3628,6 +3629,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3650,6 +3652,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3673,6 +3676,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3698,6 +3702,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3721,6 +3726,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3745,6 +3751,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
+ .port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index d4f18b8209ec..65aa564daf82 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -835,6 +835,8 @@ struct mv88e6xxx_ops {
u16 etype);
int (*port_jumbo_config)(struct mv88e6xxx_chip *chip, int port);
+ int (*port_egress_rate_limiting)(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.
*/
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index a739129ce5e5..d22c7b0e0f76 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -621,6 +621,18 @@ int mv88e6165_port_jumbo_config(struct mv88e6xxx_chip *chip, int port)
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,
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 9e25735c287e..9bad597280d6 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -63,5 +63,7 @@ int mv88e6351_port_set_egress_unknowns(struct mv88e6xxx_chip *chip, int port,
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);
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* [PATCH v1 net-next 2/5] net: dsa: mv88e6xxx: Refactor setting of jumbo frames
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736720-12608-1-git-send-email-andrew@lunn.ch>
Some switches support jumbo frames. Refactor this code into operations
in the ops structure.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 26 ++++++++++++++++++++++----
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 1 +
drivers/net/dsa/mv88e6xxx/port.c | 14 ++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 2 +-
4 files changed, 38 insertions(+), 5 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index b2b6fe3ef4bf..db1542e05e62 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2582,10 +2582,6 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
mv88e6xxx_6185_family(chip))
reg = PORT_CONTROL_2_MAP_DA;
- if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
- mv88e6xxx_6165_family(chip) || mv88e6xxx_6320_family(chip))
- reg |= PORT_CONTROL_2_JUMBO_10240;
-
if (mv88e6xxx_6095_family(chip) || mv88e6xxx_6185_family(chip)) {
/* Set the upstream port this port should use */
reg |= dsa_upstream_port(ds);
@@ -2604,6 +2600,12 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
return err;
}
+ if (chip->info->ops->port_jumbo_config) {
+ err = chip->info->ops->port_jumbo_config(chip, port);
+ if (err)
+ return err;
+ }
+
/* Port Association Vector: when learning source addresses
* of packets, add the address to the address database using
* a port bitmap that has only the bit for this port set and
@@ -2663,6 +2665,7 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
0x0001);
if (err)
return err;
+
} else if (mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip)) {
err = mv88e6xxx_port_write(chip, port, PORT_RATE_CONTROL,
0x0000);
@@ -3264,6 +3267,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3304,6 +3308,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3325,6 +3330,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3364,6 +3370,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3388,6 +3395,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3410,6 +3418,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3434,6 +3443,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3546,6 +3556,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3592,6 +3603,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3615,6 +3627,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3636,6 +3649,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3658,6 +3672,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3682,6 +3697,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3704,6 +3720,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
@@ -3727,6 +3744,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.port_set_frame_mode = mv88e6351_port_set_frame_mode,
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
+ .port_jumbo_config = mv88e6165_port_jumbo_config,
.stats_snapshot = mv88e6390_g1_stats_snapshot,
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index d9ffa96fe875..d4f18b8209ec 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -833,6 +833,7 @@ 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);
/* Snapshot the statistics for a port. The statistics can then
* be read back a leisure but still with a consistent view.
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index cf6674911abf..a739129ce5e5 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -607,6 +607,20 @@ 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, ®);
+ if (err)
+ return err;
+
+ reg |= PORT_CONTROL_2_JUMBO_10240;
+
+ return mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg);
+}
+
/* Offset 0x0f: Port Ether type */
int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 83cb3440e067..9e25735c287e 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -62,6 +62,6 @@ 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);
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* [PATCH v1 net-next 4/5] net: dsa: mv88e6xxx: Refactor pause configuration
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736720-12608-1-git-send-email-andrew@lunn.ch>
The mv88e6390 has a different mechanism for configuring pause.
Refactor the code into an ops function, and for the moment, don't add
any mv88e6390 code yet.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 28 ++++++++++++++++++++--------
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 1 +
drivers/net/dsa/mv88e6xxx/port.c | 11 +++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 1 +
4 files changed, 33 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 1b0917e44809..3ddb1f79e709 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2625,17 +2625,15 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
if (err)
return err;
- if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
- mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
- mv88e6xxx_6320_family(chip)) {
- /* 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.
- */
- err = mv88e6xxx_port_write(chip, port, PORT_PAUSE_CTRL, 0x0000);
+ if (chip->info->ops->port_pause_config) {
+ err = chip->info->ops->port_pause_config(chip, port);
if (err)
return err;
+ }
+ if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
+ mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
+ mv88e6xxx_6320_family(chip)) {
/* Port ATU control: disable limiting the number of
* address database entries that this port is allowed
* to use.
@@ -3220,6 +3218,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.port_set_egress_unknowns = mv88e6351_port_set_egress_unknowns,
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3260,6 +3259,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6095_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3302,6 +3302,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3325,6 +3326,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3366,6 +3368,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3392,6 +3395,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3416,6 +3420,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3442,6 +3447,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3557,6 +3563,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3605,6 +3612,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3630,6 +3638,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
.stats_get_strings = mv88e6320_stats_get_strings,
@@ -3653,6 +3662,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3677,6 +3687,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
@@ -3703,6 +3714,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.port_set_ether_type = mv88e6351_port_set_ether_type,
.port_jumbo_config = mv88e6165_port_jumbo_config,
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
+ .port_pause_config = mv88e6097_port_pause_config,
.stats_snapshot = mv88e6320_g1_stats_snapshot,
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 65aa564daf82..3b1f3ab490b9 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -836,6 +836,7 @@ struct mv88e6xxx_ops {
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.
diff --git a/drivers/net/dsa/mv88e6xxx/port.c b/drivers/net/dsa/mv88e6xxx/port.c
index d22c7b0e0f76..8d14833b2e49 100644
--- a/drivers/net/dsa/mv88e6xxx/port.c
+++ b/drivers/net/dsa/mv88e6xxx/port.c
@@ -304,6 +304,17 @@ 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);
+}
+
/* Offset 0x04: Port Control Register */
static const char * const mv88e6xxx_port_state_names[] = {
diff --git a/drivers/net/dsa/mv88e6xxx/port.h b/drivers/net/dsa/mv88e6xxx/port.h
index 9bad597280d6..8c964cfd9032 100644
--- a/drivers/net/dsa/mv88e6xxx/port.h
+++ b/drivers/net/dsa/mv88e6xxx/port.h
@@ -65,5 +65,6 @@ int mv88e6351_port_set_ether_type(struct mv88e6xxx_chip *chip, int port,
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);
#endif /* _MV88E6XXX_PORT_H */
--
2.10.2
^ permalink raw reply related
* [PATCH v1 net-next 1/5] net: dsa: mv88e6xxx: Reserved Management frames to CPU
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
In-Reply-To: <1480736720-12608-1-git-send-email-andrew@lunn.ch>
Older devices have a couple of registers in global2. The mv88e6390
family has a single register in global1 behind which hides similar
configuration. Implement and op for this.
Signed-off-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/dsa/mv88e6xxx/chip.c | 35 ++++++++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/global1.c | 27 ++++++++++++++++++++++
drivers/net/dsa/mv88e6xxx/global1.h | 1 +
drivers/net/dsa/mv88e6xxx/global2.c | 43 ++++++++++++++++++++---------------
drivers/net/dsa/mv88e6xxx/global2.h | 6 +++++
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 3 +++
6 files changed, 97 insertions(+), 18 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 9c14aaad5103..b2b6fe3ef4bf 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2899,6 +2899,17 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
goto unlock;
}
+ /* Some generations have the configuration of sending reserved
+ * management frames to the CPU in global2, others in
+ * global1. Hence it does not fit the two setup functions
+ * above.
+ */
+ if (chip->info->ops->mgmt_rsvd2cpu) {
+ err = chip->info->ops->mgmt_rsvd2cpu(chip);
+ if (err)
+ goto unlock;
+ }
+
unlock:
mutex_unlock(&chip->reg_lock);
@@ -3221,6 +3232,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6095_ops = {
@@ -3237,6 +3249,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
.stats_get_strings = mv88e6095_stats_get_strings,
.stats_get_stats = mv88e6095_stats_get_stats,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6097_ops = {
@@ -3257,6 +3270,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6123_ops = {
@@ -3275,6 +3289,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6131_ops = {
@@ -3295,6 +3310,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6161_ops = {
@@ -3315,6 +3331,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6165_ops = {
@@ -3331,6 +3348,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6171_ops = {
@@ -3352,6 +3370,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6172_ops = {
@@ -3375,6 +3394,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6175_ops = {
@@ -3396,6 +3416,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6176_ops = {
@@ -3419,6 +3440,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6185_ops = {
@@ -3437,6 +3459,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6190_ops = {
@@ -3459,6 +3482,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6190x_ops = {
@@ -3481,6 +3505,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6191_ops = {
@@ -3503,6 +3528,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6240_ops = {
@@ -3526,6 +3552,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6290_ops = {
@@ -3548,6 +3575,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6320_ops = {
@@ -3570,6 +3598,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
.stats_get_stats = mv88e6320_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6321_ops = {
@@ -3613,6 +3642,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6351_ops = {
@@ -3634,6 +3664,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6352_ops = {
@@ -3657,6 +3688,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
.stats_get_stats = mv88e6095_stats_get_stats,
.g1_set_cpu_port = mv88e6095_g1_set_cpu_port,
.g1_set_egress_port = mv88e6095_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6095_g2_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6390_ops = {
@@ -3679,6 +3711,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6390x_ops = {
@@ -3701,6 +3734,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static const struct mv88e6xxx_ops mv88e6391_ops = {
@@ -3723,6 +3757,7 @@ static const struct mv88e6xxx_ops mv88e6391_ops = {
.stats_get_stats = mv88e6390_stats_get_stats,
.g1_set_cpu_port = mv88e6390_g1_set_cpu_port,
.g1_set_egress_port = mv88e6390_g1_set_egress_port,
+ .mgmt_rsvd2cpu = mv88e6390_g1_mgmt_rsvd2cpu,
};
static int mv88e6xxx_verify_madatory_ops(struct mv88e6xxx_chip *chip,
diff --git a/drivers/net/dsa/mv88e6xxx/global1.c b/drivers/net/dsa/mv88e6xxx/global1.c
index 688547026e15..44136ee015c3 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.c
+++ b/drivers/net/dsa/mv88e6xxx/global1.c
@@ -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)
diff --git a/drivers/net/dsa/mv88e6xxx/global1.h b/drivers/net/dsa/mv88e6xxx/global1.h
index 0c979550052f..cb61378829e6 100644
--- a/drivers/net/dsa/mv88e6xxx/global1.h
+++ b/drivers/net/dsa/mv88e6xxx/global1.h
@@ -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 */
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 536a27c9735f..3e77071949ab 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -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
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 1eb3ddd21551..9aefb7d8b0ad 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -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 */
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 9dd94d7f58d6..d9ffa96fe875 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -851,6 +851,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)
--
2.10.2
^ permalink raw reply related
* [PATCH v1 net-next 0/5] mv88e6390 batch 3
From: Andrew Lunn @ 2016-12-03 3:45 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
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.
Andrew Lunn (5):
net: dsa: mv88e6xxx: Reserved Management frames to CPU
net: dsa: mv88e6xxx: Refactor setting of jumbo frames
net: dsa: mv88e6xxx: Refactor egress rate limiting
net: dsa: mv88e6xxx: Refactor pause configuration
net: dsa: mv88e6xxx: Implement mv88e6390 pause control
drivers/net/dsa/mv88e6xxx/chip.c | 125 +++++++++++++++++++++++++++-------
drivers/net/dsa/mv88e6xxx/global1.c | 27 ++++++++
drivers/net/dsa/mv88e6xxx/global1.h | 1 +
drivers/net/dsa/mv88e6xxx/global2.c | 43 +++++++-----
drivers/net/dsa/mv88e6xxx/global2.h | 6 ++
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 9 +++
drivers/net/dsa/mv88e6xxx/port.c | 50 ++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 6 +-
8 files changed, 225 insertions(+), 42 deletions(-)
--
2.10.2
^ permalink raw reply
* Re: [PATCH net-next 2/4] mlx4: xdp: Allow raising MTU up to one page minus eth and vlan hdrs
From: Eric Dumazet @ 2016-12-03 3:59 UTC (permalink / raw)
To: Martin KaFai Lau
Cc: Alexei Starovoitov, netdev, Brenden Blanco, Daniel Borkmann,
David Miller, Saeed Mahameed, Tariq Toukan, Kernel Team
In-Reply-To: <20161203034232.GA70461@kafai-mba.local>
On Fri, 2016-12-02 at 19:42 -0800, Martin KaFai Lau wrote:
> On Fri, Dec 02, 2016 at 06:15:26PM -0800, Eric Dumazet wrote:
> > My question was more like :
> >
> > Can we double check all these patches wont break mlx4 driver (non XDP
> > path) on arches with PAGE_SIZE=64KB.
> The page/pkt requirement is not added by this patch. The earlier
> XDP patch series has already ensured this page/pkt requirement
> is effective only when XDP prog is attached.
>
> In the earlier XDP patches, MTU is limited to 1514 when
> XDP is ative. This patch is to allow fully use of the
> page for a packet (and also only matter when XDP is active).
OK, thanks for the clarification.
^ permalink raw reply
* [PATCHv2 net-next 0/4] MV88E6390 batch two
From: Andrew Lunn @ 2016-12-03 3:35 UTC (permalink / raw)
To: David Miller; +Cc: Vivien Didelot, netdev, Andrew Lunn
This is the second batch of patches adding support for the
MV88e6390. They are not sufficient to make it work properly.
The mv88e6390 has a much expanded set of priority maps. Refactor the
existing code, and implement basic support for the new device.
Similarly, the monitor control register has been reworked.
The mv88e6390 has something odd in its EDSA tagging implementation,
which means it is not possible to use it. So we need to use DSA
tagging. This is the first device with EDSA support where we need to
use DSA, and the code does not support this. So two patches refactor
the existing code. The two different register definitions are
separated out, and using DSA on an EDSA capable device is added.
v2:
Add port prefix
Add helper function for 6390
Add _IEEE_ into #defines
Split monitor_ctrl into a number of separate ops.
Remove 6390 code which is management, used in a later patch
s/EGREES/EGRESS/.
Broke up setup_port_dsa() and set_port_dsa() into a number of ops
v3:
Verify mandatory ops for port setup
Don't set ether type for DSA port.
Andrew Lunn (4):
net: dsa: mv88e6xxx: Implement mv88e6390 tag remap
net: dsa: mv88e6xxx: Monitor and Management tables
net: dsa: mv88e6xxx: Move the tagging protocol into info
net: dsa: mv88e6xxx: Refactor CPU and DSA port setup
drivers/net/dsa/mv88e6xxx/chip.c | 339 ++++++++++++++++++++++++++--------
drivers/net/dsa/mv88e6xxx/global1.c | 69 +++++++
drivers/net/dsa/mv88e6xxx/global1.h | 4 +
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 62 +++++--
drivers/net/dsa/mv88e6xxx/port.c | 181 ++++++++++++++++++
drivers/net/dsa/mv88e6xxx/port.h | 15 ++
6 files changed, 583 insertions(+), 87 deletions(-)
--
2.10.2
^ permalink raw reply
* [PATCH] net: af_mpls.c add space before open parenthesis
From: Suraj Deshmukh @ 2016-12-03 7:59 UTC (permalink / raw)
To: davem; +Cc: netdev, linux-kernel, Suraj Deshmukh
Adding space after switch keyword before open
parenthesis for readability purpose.
This patch fixes the checkpatch.pl warning:
space required before the open parenthesis '('
Signed-off-by: Suraj Deshmukh <surajssd009005@gmail.com>
---
net/mpls/af_mpls.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 0e4334c..15fe976 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -1252,7 +1252,7 @@ static int rtm_to_route_config(struct sk_buff *skb, struct nlmsghdr *nlh,
if (!nla)
continue;
- switch(index) {
+ switch (index) {
case RTA_OIF:
cfg->rc_ifindex = nla_get_u32(nla);
break;
--
2.9.3
^ permalink raw reply related
* Re: [PATCH iproute2/net-next] ss: initialise variables outside of for loop
From: Simon Horman @ 2016-12-03 8:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20161202141817.7341a497@xeon-e3>
On Fri, Dec 02, 2016 at 02:18:17PM -0800, Stephen Hemminger wrote:
> On Fri, 2 Dec 2016 12:56:05 +0100
> Simon Horman <simon.horman@netronome.com> wrote:
>
> > Initialise for loops outside of for loops. GCC flags this as being
> > out of spec unless C99 or C11 mode is used.
> >
> > With this change the entire tree appears to compile cleanly with -Wall.
> >
> > $ gcc --version
> > gcc (Debian 4.9.2-10) 4.9.2
> > ...
> > $ make
> > ...
> > ss.c: In function ‘unix_show_sock’:
> > ss.c:3128:4: error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
> > ...
> >
> > Signed-off-by: Simon Horman <simon.horman@netronome.com>
>
> Applied.
Thanks.
> Note, I used to have -Wall in Makefile but old GCC were broken and would give
> aliasing warnings.
Thanks, good to know.
^ permalink raw reply
* [PATCH iproute2/net-next v3 1/3] tc: flower: document SCTP ip_proto
From: Simon Horman @ 2016-12-03 8:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Simon Horman
In-Reply-To: <1480755160-27768-1-git-send-email-simon.horman@netronome.com>
Add SCTP ip_proto to help text and man page.
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
man/man8/tc-flower.8 | 14 +++++++-------
tc/f_flower.c | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/man/man8/tc-flower.8 b/man/man8/tc-flower.8
index 11cf774dd7de..744c450b4531 100644
--- a/man/man8/tc-flower.8
+++ b/man/man8/tc-flower.8
@@ -29,7 +29,7 @@ flower \- flow based traffic control filter
.IR PRIORITY " | "
.BR vlan_eth_type " { " ipv4 " | " ipv6 " | "
.IR ETH_TYPE " } | "
-.BR ip_proto " { " tcp " | " udp " | "
+.BR ip_proto " { " tcp " | " udp " | " sctp " | "
.IR IP_PROTO " } | { "
.BR dst_ip " | " src_ip " } { "
.IR ipv4_address " | " ipv6_address " } | { "
@@ -97,8 +97,8 @@ or an unsigned 16bit value in hexadecimal format.
.BI ip_proto " IP_PROTO"
Match on layer four protocol.
.I IP_PROTO
-may be either
-.BR tcp , udp
+may be
+.BR tcp ", " udp ", " sctp
or an unsigned 8bit value in hexadecimal format.
.TP
.BI dst_ip " ADDRESS"
@@ -114,8 +114,8 @@ option of tc filter.
.TQ
.BI src_port " NUMBER"
Match on layer 4 protocol source or destination port number. Only available for
-.BR ip_proto " values " udp " and " tcp ,
-which has to be specified in beforehand.
+.BR ip_proto " values " udp ", " tcp " and " sctp
+which have to be specified in beforehand.
.TP
.BI enc_key_id " NUMBER"
.TQ
@@ -140,8 +140,8 @@ and finally layer four matches
(\fBdst_port\fR and \fBsrc_port\fR)
depend on
.B ip_proto
-being set to either
-.BR tcp " or " udp .
+being set to
+.BR tcp ", " udp " or " sctp.
.P
There can be only used one mask per one prio. If user needs to specify different
mask, he has to use different prio.
diff --git a/tc/f_flower.c b/tc/f_flower.c
index 7e7f4c92a947..f04c594d06ae 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -37,7 +37,7 @@ static void explain(void)
" vlan_ethtype [ ipv4 | ipv6 | ETH-TYPE ] |\n"
" dst_mac MAC-ADDR |\n"
" src_mac MAC-ADDR |\n"
- " ip_proto [tcp | udp | IP-PROTO ] |\n"
+ " ip_proto [tcp | udp | sctp | IP-PROTO ] |\n"
" dst_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" src_ip [ IPV4-ADDR | IPV6-ADDR ] |\n"
" dst_port PORT-NUMBER |\n"
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH iproute2/net-next v3 3/3] tc: flower: make use of flower_port_attr_type() safe and silent
From: Simon Horman @ 2016-12-03 8:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Simon Horman
In-Reply-To: <1480755160-27768-1-git-send-email-simon.horman@netronome.com>
Make use of flower_port_attr_type() safe:
* flower_port_attr_type() may return a valid index into tb[] or -1.
Only access tb[] in the case of the former.
* Do not access null entries in tb[]
Also make usage silent - it is valid for ip_proto to be invalid,
for example if it is not specified as part of the filter.
Fixes: a1fb0d484237 ("tc: flower: Support matching on SCTP ports")
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
tc/f_flower.c | 24 +++++++++++++-----------
1 file changed, 13 insertions(+), 11 deletions(-)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index d2e8d0462dde..ff61c8e7f19a 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -168,19 +168,17 @@ static int flower_parse_ip_addr(char *str, __be16 eth_type,
static int flower_port_attr_type(__u8 ip_proto, bool is_src)
{
- if (ip_proto == IPPROTO_TCP) {
+ if (ip_proto == IPPROTO_TCP)
return is_src ? TCA_FLOWER_KEY_TCP_SRC :
TCA_FLOWER_KEY_TCP_DST;
- } else if (ip_proto == IPPROTO_UDP) {
+ else if (ip_proto == IPPROTO_UDP)
return is_src ? TCA_FLOWER_KEY_UDP_SRC :
TCA_FLOWER_KEY_UDP_DST;
- } else if (ip_proto == IPPROTO_SCTP) {
+ else if (ip_proto == IPPROTO_SCTP)
return is_src ? TCA_FLOWER_KEY_SCTP_SRC :
TCA_FLOWER_KEY_SCTP_DST;
- } else {
- fprintf(stderr, "Illegal \"ip_proto\" for port\n");
+ else
return -1;
- }
}
static int flower_parse_port(char *str, __u8 ip_proto, bool is_src,
@@ -561,7 +559,8 @@ static void flower_print_ip_addr(FILE *f, char *name, __be16 eth_type,
static void flower_print_port(FILE *f, char *name, struct rtattr *attr)
{
- fprintf(f, "\n %s %d", name, rta_getattr_be16(attr));
+ if (attr)
+ fprintf(f, "\n %s %d", name, rta_getattr_be16(attr));
}
static void flower_print_key_id(FILE *f, const char *name,
@@ -577,6 +576,7 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
struct rtattr *tb[TCA_FLOWER_MAX + 1];
__be16 eth_type = 0;
__u8 ip_proto = 0xff;
+ int nl_type;
if (!opt)
return 0;
@@ -631,10 +631,12 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
tb[TCA_FLOWER_KEY_IPV6_SRC],
tb[TCA_FLOWER_KEY_IPV6_SRC_MASK]);
- flower_print_port(f, "dst_port",
- tb[flower_port_attr_type(ip_proto, false)]);
- flower_print_port(f, "src_port",
- tb[flower_port_attr_type(ip_proto, true)]);
+ nl_type = flower_port_attr_type(ip_proto, false);
+ if (nl_type >= 0)
+ flower_print_port(f, "dst_port", tb[nl_type]);
+ nl_type = flower_port_attr_type(ip_proto, true);
+ if (nl_type >= 0)
+ flower_print_port(f, "src_port", tb[nl_type]);
flower_print_ip_addr(f, "enc_dst_ip",
tb[TCA_FLOWER_KEY_ENC_IPV4_DST_MASK] ?
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH iproute2/net-next v3 2/3] tc: flower: correct name of ip_proto parameter to flower_parse_port()
From: Simon Horman @ 2016-12-03 8:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Simon Horman
In-Reply-To: <1480755160-27768-1-git-send-email-simon.horman@netronome.com>
This corrects a typo.
Fixes: a1fb0d484237 ("tc: flower: Support matching on SCTP ports")
Signed-off-by: Simon Horman <simon.horman@netronome.com>
---
tc/f_flower.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/tc/f_flower.c b/tc/f_flower.c
index f04c594d06ae..d2e8d0462dde 100644
--- a/tc/f_flower.c
+++ b/tc/f_flower.c
@@ -166,15 +166,15 @@ static int flower_parse_ip_addr(char *str, __be16 eth_type,
return 0;
}
-static int flower_port_attr_type(__u8 ip_port, bool is_src)
+static int flower_port_attr_type(__u8 ip_proto, bool is_src)
{
- if (ip_port == IPPROTO_TCP) {
+ if (ip_proto == IPPROTO_TCP) {
return is_src ? TCA_FLOWER_KEY_TCP_SRC :
TCA_FLOWER_KEY_TCP_DST;
- } else if (ip_port == IPPROTO_UDP) {
+ } else if (ip_proto == IPPROTO_UDP) {
return is_src ? TCA_FLOWER_KEY_UDP_SRC :
TCA_FLOWER_KEY_UDP_DST;
- } else if (ip_port == IPPROTO_SCTP) {
+ } else if (ip_proto == IPPROTO_SCTP) {
return is_src ? TCA_FLOWER_KEY_SCTP_SRC :
TCA_FLOWER_KEY_SCTP_DST;
} else {
@@ -183,14 +183,14 @@ static int flower_port_attr_type(__u8 ip_port, bool is_src)
}
}
-static int flower_parse_port(char *str, __u8 ip_port, bool is_src,
+static int flower_parse_port(char *str, __u8 ip_proto, bool is_src,
struct nlmsghdr *n)
{
int ret;
int type;
__be16 port;
- type = flower_port_attr_type(ip_port, is_src);
+ type = flower_port_attr_type(ip_proto, is_src);
if (type < 0)
return -1;
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply related
* [PATCH iproute2/net-next v3 0/3] tc: flower: SCTP and other port fixes
From: Simon Horman @ 2016-12-03 8:52 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, Simon Horman
Hi Stephen,
this short series:
* Makes some improvements to the documentation of flower;
A follow-up to recent work by Paul Blakey and myself.
* Corrects some errors introduced when SCTP port matching support was
recently added.
Changes v2->v3:
* Rebase
* Dropped merged patch
Changes v1->v2:
* Rebase
Simon Horman (3):
tc: flower: document SCTP ip_proto
tc: flower: correct name of ip_proto parameter to flower_parse_port()
tc: flower: make use of flower_port_attr_type() safe and silent
man/man8/tc-flower.8 | 14 +++++++-------
tc/f_flower.c | 32 +++++++++++++++++---------------
2 files changed, 24 insertions(+), 22 deletions(-)
--
2.7.0.rc3.207.g0ac5344
^ permalink raw reply
* Re: [[PATCH iproute2/net-next v2] 2/4] tc: flower: document SCTP ip_proto
From: Simon Horman @ 2016-12-03 8:53 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20161202150608.746eb843@xeon-e3>
On Fri, Dec 02, 2016 at 03:06:08PM -0800, Stephen Hemminger wrote:
> On Fri, 2 Dec 2016 09:45:19 +0100
> Simon Horman <simon.horman@netronome.com> wrote:
>
> > Add SCTP ip_proto to help text and man page.
> >
> > Signed-off-by: Simon Horman <simon.horman@netronome.com>
>
> This doesn't apply cleanly to current net-next git.
> Probably some of the other man page changes caused reject.
Thanks, rebased and posted v3.
^ permalink raw reply
* [net-next 14/18] i40evf: protect against NULL msix_entries and q_vectors pointers
From: Jeff Kirsher @ 2016-12-03 9:19 UTC (permalink / raw)
To: davem
Cc: Jacob Keller, netdev, nhorman, sassmann, jogreene,
guru.anbalagane, Jeff Kirsher
In-Reply-To: <20161203091930.14268-1-jeffrey.t.kirsher@intel.com>
From: Jacob Keller <jacob.e.keller@intel.com>
Update the functions which free msix_entries and q_vectors so that they
are safe against NULL values. This allows calling code to not care
whether these have already been freed when disabling and freeing them.
Change-ID: I31bfd1c0da18023d971b618edc6fb049721f3298
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 420e545..ca85021 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -207,6 +207,9 @@ static void i40evf_misc_irq_disable(struct i40evf_adapter *adapter)
{
struct i40e_hw *hw = &adapter->hw;
+ if (!adapter->msix_entries)
+ return;
+
wr32(hw, I40E_VFINT_DYN_CTL01, 0);
/* read flush */
@@ -654,6 +657,9 @@ static void i40evf_free_misc_irq(struct i40evf_adapter *adapter)
{
struct net_device *netdev = adapter->netdev;
+ if (!adapter->msix_entries)
+ return;
+
free_irq(adapter->msix_entries[0].vector, netdev);
}
@@ -1428,6 +1434,9 @@ static void i40evf_free_q_vectors(struct i40evf_adapter *adapter)
int q_idx, num_q_vectors;
int napi_vectors;
+ if (!adapter->q_vectors)
+ return;
+
num_q_vectors = adapter->num_msix_vectors - NONQ_VECS;
napi_vectors = adapter->num_active_queues;
@@ -1437,6 +1446,7 @@ static void i40evf_free_q_vectors(struct i40evf_adapter *adapter)
netif_napi_del(&q_vector->napi);
}
kfree(adapter->q_vectors);
+ adapter->q_vectors = NULL;
}
/**
@@ -2862,12 +2872,10 @@ static void i40evf_remove(struct pci_dev *pdev)
msleep(50);
}
- if (adapter->msix_entries) {
- i40evf_misc_irq_disable(adapter);
- i40evf_free_misc_irq(adapter);
- i40evf_reset_interrupt_capability(adapter);
- i40evf_free_q_vectors(adapter);
- }
+ i40evf_misc_irq_disable(adapter);
+ i40evf_free_misc_irq(adapter);
+ i40evf_reset_interrupt_capability(adapter);
+ i40evf_free_q_vectors(adapter);
if (adapter->watchdog_timer.function)
del_timer_sync(&adapter->watchdog_timer);
--
2.9.3
^ permalink raw reply related
* [net-next 01/18] i40e: Be much more verbose about what we can and cannot offload
From: Jeff Kirsher @ 2016-12-03 9:19 UTC (permalink / raw)
To: davem; +Cc: Alexander Duyck, netdev, nhorman, sassmann, jogreene,
guru.anbalagane
In-Reply-To: <20161203091930.14268-1-jeffrey.t.kirsher@intel.com>
From: Alexander Duyck <alexander.h.duyck@intel.com>
This change makes it so that we are much more robust about defining what we
can and cannot offload. Previously we were just checking for the L4 tunnel
header length, however there are other fields we should be verifying as
there are multiple scenarios in which we cannot perform hardware offloads.
In addition the device only supports GSO as long as the MSS is 64 or
greater. We were not checking this so an MSS less than that was resulting
in Tx hangs.
Change-ID: I5e2fd5f3075c73601b4b36327b771c64fcb6c31b
Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_main.c | 52 ++++++++++++++++++++++++-----
1 file changed, 44 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 5c6a5ce..2d91274 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -9070,10 +9070,6 @@ static int i40e_ndo_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
0, 0, nlflags, filter_mask, NULL);
}
-/* Hardware supports L4 tunnel length of 128B (=2^7) which includes
- * inner mac plus all inner ethertypes.
- */
-#define I40E_MAX_TUNNEL_HDR_LEN 128
/**
* i40e_features_check - Validate encapsulated packet conforms to limits
* @skb: skb buff
@@ -9084,12 +9080,52 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb,
struct net_device *dev,
netdev_features_t features)
{
- if (skb->encapsulation &&
- ((skb_inner_network_header(skb) - skb_transport_header(skb)) >
- I40E_MAX_TUNNEL_HDR_LEN))
- return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
+ size_t len;
+
+ /* No point in doing any of this if neither checksum nor GSO are
+ * being requested for this frame. We can rule out both by just
+ * checking for CHECKSUM_PARTIAL
+ */
+ if (skb->ip_summed != CHECKSUM_PARTIAL)
+ return features;
+
+ /* We cannot support GSO if the MSS is going to be less than
+ * 64 bytes. If it is then we need to drop support for GSO.
+ */
+ if (skb_is_gso(skb) && (skb_shinfo(skb)->gso_size < 64))
+ features &= ~NETIF_F_GSO_MASK;
+
+ /* MACLEN can support at most 63 words */
+ len = skb_network_header(skb) - skb->data;
+ if (len & ~(63 * 2))
+ goto out_err;
+
+ /* IPLEN and EIPLEN can support at most 127 dwords */
+ len = skb_transport_header(skb) - skb_network_header(skb);
+ if (len & ~(127 * 4))
+ goto out_err;
+
+ if (skb->encapsulation) {
+ /* L4TUNLEN can support 127 words */
+ len = skb_inner_network_header(skb) - skb_transport_header(skb);
+ if (len & ~(127 * 2))
+ goto out_err;
+
+ /* IPLEN can support at most 127 dwords */
+ len = skb_inner_transport_header(skb) -
+ skb_inner_network_header(skb);
+ if (len & ~(127 * 4))
+ goto out_err;
+ }
+
+ /* No need to validate L4LEN as TCP is the only protocol with a
+ * a flexible value and we support all possible values supported
+ * by TCP, which is at most 15 dwords
+ */
return features;
+out_err:
+ return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
static const struct net_device_ops i40e_netdev_ops = {
--
2.9.3
^ permalink raw reply related
* [net-next 00/18][pull request] 40GbE Intel Wired LAN Driver Updates 2016-12-02
From: Jeff Kirsher @ 2016-12-03 9:19 UTC (permalink / raw)
To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene,
guru.anbalagane
This series contains updates to i40e and i40evf only.
Alex provides changes so that we are much more robust about defining what
we can and cannot offload in i40e and i40evf by doing additional checks
other than L4 tunnel header length.
Jake provides several fixes/changes, first cleaning up a label that is
unnecessary, as well as cleaned up the use of a "magic number". Clarified
the code by separating the global private flags and the regular private
flags per interface into two arrays, so that future additions will not
produce duplication and buggy code. Adds additional checks to protect
against NULL values for msix_entries and q_vectors pointers.
Michal adds Clause22 method for accessing registers for some external
PHYs.
Piotr adds additional protocol support for the admin queue discover
capabilities function.
Tushar Dave fixes a panic seen on SPARC, where writel() should not be
used to write directly to a memory address but only to a memory mapped
I/O address otherwise it causes data access exceptions.
Joe Perches separates out a section of code into its own function, to
help reduce i40evf_reset_task() a bit.
Alan fixes an issue by checking for NULL before dereferencing msix_entries
and returning early in the case where it is NULL within the i40evf_close()
code path.
Henry provides code cleanup to remove unreachable and redundant sections
of code. Fixed up an issue where new NICs were not identifying "unknown
PHYs" correctly.
Harshitha fixes a issue where the ethtool "Supported Link" modes list
backplane interfaces on X722 devices for 10 GbE with SFP+ and Cortina
retimer, where these interfaces should not be visible to the user since
they cannot use them.
Carolyn changes an X722 informational message so that it only appears
when extra messages are desired.
The following are changes since commit ab17cb1fea82b346bdecd4f2d7f0e84e80f847af:
Merge tag 'wireless-drivers-next-for-davem-2016-12-01' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
and are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue 40GbE
Alan Brady (1):
i40evf: check for msix_entries null dereference
Alexander Duyck (2):
i40e: Be much more verbose about what we can and cannot offload
i40evf: Be much more verbose about what we can and cannot offload
Carolyn Wyborny (1):
i40e: change message to only appear when extra debug info is wanted
Harshitha Ramamurthy (1):
i40e: Fix for ethtool Supported link modes
Henry Tieman (2):
i40e: Remove unreachable code
i40e: Pass unknown PHY type for unknown PHYs
Jacob Keller (7):
i40e: remove error_param_int label from
i40e_vc_config_promiscuous_mode_msg
i40e: remove second check of VLAN_N_VID in i40e_vlan_rx_add_vid
i40e: avoid duplicate private flags definitions
i40e: fix trivial typo in naming of i40e_sync_filters_subtask
i40evf: protect against NULL msix_entries and q_vectors pointers
i40e: set broadcast promiscuous mode for each active VLAN
i40e/i40evf: replace for memcpy with single memcpy call in ethtool
Joe Perches (1):
i40evf: Move some i40evf_reset_task code to separate function
Michal Kosiarz (1):
i40e: Add Clause22 implementation
Piotr Raczynski (1):
i40e: Add protocols over MCTP to i40e_aq_discover_capabilities
Tushar Dave (1):
i40e: fix panic on SPARC while changing num of desc
drivers/net/ethernet/intel/i40e/i40e.h | 1 +
drivers/net/ethernet/intel/i40e/i40e_common.c | 218 ++++++++++++++++-----
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 78 ++++----
drivers/net/ethernet/intel/i40e/i40e_main.c | 171 ++++++++++++----
drivers/net/ethernet/intel/i40e/i40e_prototype.h | 15 +-
drivers/net/ethernet/intel/i40e/i40e_type.h | 23 ++-
drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 14 +-
drivers/net/ethernet/intel/i40evf/i40e_type.h | 4 +
drivers/net/ethernet/intel/i40evf/i40evf_main.c | 171 +++++++++++-----
9 files changed, 511 insertions(+), 184 deletions(-)
--
2.9.3
^ permalink raw reply
* [net-next 13/18] i40e: Pass unknown PHY type for unknown PHYs
From: Jeff Kirsher @ 2016-12-03 9:19 UTC (permalink / raw)
To: davem
Cc: Henry Tieman, netdev, nhorman, sassmann, jogreene,
guru.anbalagane, Jeff Kirsher
In-Reply-To: <20161203091930.14268-1-jeffrey.t.kirsher@intel.com>
From: Henry Tieman <henry.w.tieman@intel.com>
The PHY type value for unrecognized PHYs and cables was changed
based on firmware version number. Newer hardware use lower firmware
version numbers and this was causing some PHYs to be identified
as type 0x16 instead of 0xe (unknown).
Without this patch, newer card will incorrectly identify unknown
PHYs and cables.
This change adds hardware type to the check for firmware version
so the PHY type is reported correctly.
Change-ID: I0723cbfd263c76fc73ff1a5275d1639051376c9a
Signed-off-by: Henry Tieman <henry.w.tieman@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e_common.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index fc7ce02..f6fee79 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1854,7 +1854,8 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
else
hw_link_info->lse_enable = false;
- if ((hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
+ if ((hw->mac.type == I40E_MAC_XL710) &&
+ (hw->aq.fw_maj_ver < 4 || (hw->aq.fw_maj_ver == 4 &&
hw->aq.fw_min_ver < 40)) && hw_link_info->phy_type == 0xE)
hw_link_info->phy_type = I40E_PHY_TYPE_10GBASE_SFPP_CU;
--
2.9.3
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox