mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-27 19:29:37 +00:00
Merge branch 'net-dsa-mv88e6xxx-add-support-for-MV88E6220'
Hubert Feurstein says: ==================== net: dsa: mv88e6xxx: add support for MV88E6220 This patch series adds support for the MV88E6220 chip to the mv88e6xxx driver. The MV88E6220 is almost the same as MV88E6250 except that the ports 2-4 are not routed to pins. Furthermore, PTP support is added to the MV88E6250 family. v2: - insert all 6220 entries in correct numerical order - introduce invalid_port_mask - move ptp_cc_mult* to ptp_ops and restored original ptp_adjfine code - added Andrews Reviewed-By to patch 2 and 4 ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4a9866179d
6 changed files with 176 additions and 34 deletions
|
@ -22,7 +22,7 @@ which is at a different MDIO base address in different switch families.
|
|||
- "marvell,mv88e6190" : Switch has base address 0x00. Use with models:
|
||||
6190, 6190X, 6191, 6290, 6390, 6390X
|
||||
- "marvell,mv88e6250" : Switch has base address 0x08 or 0x18. Use with model:
|
||||
6250
|
||||
6220, 6250
|
||||
|
||||
Required properties:
|
||||
- compatible : Should be one of "marvell,mv88e6085",
|
||||
|
|
|
@ -2268,9 +2268,11 @@ static int mv88e6xxx_setup_port(struct mv88e6xxx_chip *chip, int port)
|
|||
return err;
|
||||
}
|
||||
|
||||
err = mv88e6xxx_setup_message_port(chip, port);
|
||||
if (err)
|
||||
return err;
|
||||
if (chip->info->ops->port_setup_message_port) {
|
||||
err = chip->info->ops->port_setup_message_port(chip, port);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Port based VLAN map: give each port the same default address
|
||||
* database, and allow bidirectional communication between the
|
||||
|
@ -2485,6 +2487,14 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
|
|||
|
||||
/* Setup Switch Port Registers */
|
||||
for (i = 0; i < mv88e6xxx_num_ports(chip); i++) {
|
||||
/* Prevent the use of an invalid port. */
|
||||
if (mv88e6xxx_is_invalid_port(chip, i) &&
|
||||
!dsa_is_unused_port(ds, i)) {
|
||||
dev_err(chip->dev, "port %d is invalid\n", i);
|
||||
err = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (dsa_is_unused_port(ds, i)) {
|
||||
err = mv88e6xxx_port_set_state(chip, i,
|
||||
BR_STATE_DISABLED);
|
||||
|
@ -2813,6 +2823,7 @@ static const struct mv88e6xxx_ops mv88e6085_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2847,6 +2858,7 @@ static const struct mv88e6xxx_ops mv88e6095_ops = {
|
|||
.port_set_upstream_port = mv88e6095_port_set_upstream_port,
|
||||
.port_link_state = mv88e6185_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2883,6 +2895,7 @@ static const struct mv88e6xxx_ops mv88e6097_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2917,6 +2930,7 @@ static const struct mv88e6xxx_ops mv88e6123_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2954,6 +2968,7 @@ static const struct mv88e6xxx_ops mv88e6131_ops = {
|
|||
.port_set_pause = mv88e6185_port_set_pause,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -2998,6 +3013,7 @@ static const struct mv88e6xxx_ops mv88e6141_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3038,6 +3054,7 @@ static const struct mv88e6xxx_ops mv88e6161_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3071,6 +3088,7 @@ static const struct mv88e6xxx_ops mv88e6165_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3112,6 +3130,7 @@ static const struct mv88e6xxx_ops mv88e6171_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3153,6 +3172,7 @@ static const struct mv88e6xxx_ops mv88e6172_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3195,6 +3215,7 @@ static const struct mv88e6xxx_ops mv88e6175_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3236,6 +3257,7 @@ static const struct mv88e6xxx_ops mv88e6176_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3274,6 +3296,7 @@ static const struct mv88e6xxx_ops mv88e6185_ops = {
|
|||
.port_set_pause = mv88e6185_port_set_pause,
|
||||
.port_link_state = mv88e6185_port_link_state,
|
||||
.port_get_cmode = mv88e6185_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6xxx_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3316,6 +3339,7 @@ static const struct mv88e6xxx_ops mv88e6190_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3361,6 +3385,7 @@ static const struct mv88e6xxx_ops mv88e6190x_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3406,6 +3431,7 @@ static const struct mv88e6xxx_ops mv88e6191_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3453,6 +3479,7 @@ static const struct mv88e6xxx_ops mv88e6240_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3511,6 +3538,8 @@ static const struct mv88e6xxx_ops mv88e6250_ops = {
|
|||
.reset = mv88e6250_g1_reset,
|
||||
.vtu_getnext = mv88e6250_g1_vtu_getnext,
|
||||
.vtu_loadpurge = mv88e6250_g1_vtu_loadpurge,
|
||||
.avb_ops = &mv88e6352_avb_ops,
|
||||
.ptp_ops = &mv88e6250_ptp_ops,
|
||||
.phylink_validate = mv88e6065_phylink_validate,
|
||||
};
|
||||
|
||||
|
@ -3538,6 +3567,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3585,6 +3615,7 @@ static const struct mv88e6xxx_ops mv88e6320_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3628,6 +3659,7 @@ static const struct mv88e6xxx_ops mv88e6321_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3671,6 +3703,7 @@ static const struct mv88e6xxx_ops mv88e6341_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3714,6 +3747,7 @@ static const struct mv88e6xxx_ops mv88e6350_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3753,6 +3787,7 @@ static const struct mv88e6xxx_ops mv88e6351_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3796,6 +3831,7 @@ static const struct mv88e6xxx_ops mv88e6352_ops = {
|
|||
.port_disable_pri_override = mv88e6xxx_port_disable_pri_override,
|
||||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6320_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6095_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6095_stats_get_sset_count,
|
||||
|
@ -3848,6 +3884,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3897,6 +3934,7 @@ static const struct mv88e6xxx_ops mv88e6390x_ops = {
|
|||
.port_link_state = mv88e6352_port_link_state,
|
||||
.port_get_cmode = mv88e6352_port_get_cmode,
|
||||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.port_setup_message_port = mv88e6xxx_setup_message_port,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -4275,6 +4313,33 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||
.ops = &mv88e6191_ops,
|
||||
},
|
||||
|
||||
[MV88E6220] = {
|
||||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6220,
|
||||
.family = MV88E6XXX_FAMILY_6250,
|
||||
.name = "Marvell 88E6220",
|
||||
.num_databases = 64,
|
||||
|
||||
/* Ports 2-4 are not routed to pins
|
||||
* => usable ports 0, 1, 5, 6
|
||||
*/
|
||||
.num_ports = 7,
|
||||
.num_internal_phys = 2,
|
||||
.invalid_port_mask = BIT(2) | BIT(3) | BIT(4),
|
||||
.max_vid = 4095,
|
||||
.port_base_addr = 0x08,
|
||||
.phy_base_addr = 0x00,
|
||||
.global1_addr = 0x0f,
|
||||
.global2_addr = 0x07,
|
||||
.age_time_coeff = 15000,
|
||||
.g1_irqs = 9,
|
||||
.g2_irqs = 10,
|
||||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.tag_protocol = DSA_TAG_PROTO_DSA,
|
||||
.ptp_support = true,
|
||||
.ops = &mv88e6250_ops,
|
||||
},
|
||||
|
||||
[MV88E6240] = {
|
||||
.prod_num = MV88E6XXX_PORT_SWITCH_ID_PROD_6240,
|
||||
.family = MV88E6XXX_FAMILY_6352,
|
||||
|
@ -4317,6 +4382,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = {
|
|||
.atu_move_port_mask = 0xf,
|
||||
.dual_chip = true,
|
||||
.tag_protocol = DSA_TAG_PROTO_DSA,
|
||||
.ptp_support = true,
|
||||
.ops = &mv88e6250_ops,
|
||||
},
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ enum mv88e6xxx_model {
|
|||
MV88E6190,
|
||||
MV88E6190X,
|
||||
MV88E6191,
|
||||
MV88E6220,
|
||||
MV88E6240,
|
||||
MV88E6250,
|
||||
MV88E6290,
|
||||
|
@ -77,7 +78,7 @@ enum mv88e6xxx_family {
|
|||
MV88E6XXX_FAMILY_6097, /* 6046 6085 6096 6097 */
|
||||
MV88E6XXX_FAMILY_6165, /* 6123 6161 6165 */
|
||||
MV88E6XXX_FAMILY_6185, /* 6108 6121 6122 6131 6152 6155 6182 6185 */
|
||||
MV88E6XXX_FAMILY_6250, /* 6250 */
|
||||
MV88E6XXX_FAMILY_6250, /* 6220 6250 */
|
||||
MV88E6XXX_FAMILY_6320, /* 6320 6321 */
|
||||
MV88E6XXX_FAMILY_6341, /* 6141 6341 */
|
||||
MV88E6XXX_FAMILY_6351, /* 6171 6175 6350 6351 */
|
||||
|
@ -105,6 +106,11 @@ struct mv88e6xxx_info {
|
|||
unsigned int g2_irqs;
|
||||
bool pvt;
|
||||
|
||||
/* Mark certain ports as invalid. This is required for example for the
|
||||
* MV88E6220 (which is in general a MV88E6250 with 7 ports) but the
|
||||
* ports 2-4 are not routet to pins.
|
||||
*/
|
||||
unsigned int invalid_port_mask;
|
||||
/* Multi-chip Addressing Mode.
|
||||
* Some chips respond to only 2 registers of its own SMI device address
|
||||
* when it is non-zero, and use indirect access to internal registers.
|
||||
|
@ -389,6 +395,7 @@ struct mv88e6xxx_ops {
|
|||
u8 out);
|
||||
int (*port_disable_learn_limit)(struct mv88e6xxx_chip *chip, int port);
|
||||
int (*port_disable_pri_override)(struct mv88e6xxx_chip *chip, int port);
|
||||
int (*port_setup_message_port)(struct mv88e6xxx_chip *chip, int port);
|
||||
|
||||
/* CMODE control what PHY mode the MAC will use, eg. SGMII, RGMII, etc.
|
||||
* Some chips allow this to be configured on specific ports.
|
||||
|
@ -532,6 +539,10 @@ struct mv88e6xxx_ptp_ops {
|
|||
int arr1_sts_reg;
|
||||
int dep_sts_reg;
|
||||
u32 rx_filters;
|
||||
u32 cc_shift;
|
||||
u32 cc_mult;
|
||||
u32 cc_mult_num;
|
||||
u32 cc_mult_dem;
|
||||
};
|
||||
|
||||
#define STATS_TYPE_PORT BIT(0)
|
||||
|
@ -570,6 +581,11 @@ static inline unsigned int mv88e6xxx_num_gpio(struct mv88e6xxx_chip *chip)
|
|||
return chip->info->num_gpio;
|
||||
}
|
||||
|
||||
static inline bool mv88e6xxx_is_invalid_port(struct mv88e6xxx_chip *chip, int port)
|
||||
{
|
||||
return (chip->info->invalid_port_mask & BIT(port)) != 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_read(struct mv88e6xxx_chip *chip, int addr, int reg, u16 *val);
|
||||
int mv88e6xxx_write(struct mv88e6xxx_chip *chip, int addr, int reg, u16 val);
|
||||
int mv88e6xxx_update(struct mv88e6xxx_chip *chip, int addr, int reg,
|
||||
|
|
|
@ -117,6 +117,7 @@
|
|||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6190 0x1900
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6191 0x1910
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6185 0x1a70
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6220 0x2200
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6240 0x2400
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6250 0x2500
|
||||
#define MV88E6XXX_PORT_SWITCH_ID_PROD_6290 0x2900
|
||||
|
|
|
@ -15,11 +15,31 @@
|
|||
#include "hwtstamp.h"
|
||||
#include "ptp.h"
|
||||
|
||||
/* Raw timestamps are in units of 8-ns clock periods. */
|
||||
#define CC_SHIFT 28
|
||||
#define CC_MULT (8 << CC_SHIFT)
|
||||
#define CC_MULT_NUM (1 << 9)
|
||||
#define CC_MULT_DEM 15625ULL
|
||||
#define MV88E6XXX_MAX_ADJ_PPB 1000000
|
||||
|
||||
/* Family MV88E6250:
|
||||
* Raw timestamps are in units of 10-ns clock periods.
|
||||
*
|
||||
* clkadj = scaled_ppm * 10*2^28 / (10^6 * 2^16)
|
||||
* simplifies to
|
||||
* clkadj = scaled_ppm * 2^7 / 5^5
|
||||
*/
|
||||
#define MV88E6250_CC_SHIFT 28
|
||||
#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT)
|
||||
#define MV88E6250_CC_MULT_NUM (1 << 7)
|
||||
#define MV88E6250_CC_MULT_DEM 3125ULL
|
||||
|
||||
/* Other families:
|
||||
* Raw timestamps are in units of 8-ns clock periods.
|
||||
*
|
||||
* clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16)
|
||||
* simplifies to
|
||||
* clkadj = scaled_ppm * 2^9 / 5^6
|
||||
*/
|
||||
#define MV88E6XXX_CC_SHIFT 28
|
||||
#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT)
|
||||
#define MV88E6XXX_CC_MULT_NUM (1 << 9)
|
||||
#define MV88E6XXX_CC_MULT_DEM 15625ULL
|
||||
|
||||
#define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100)
|
||||
|
||||
|
@ -179,6 +199,7 @@ static void mv88e6352_tai_event_work(struct work_struct *ugly)
|
|||
static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
||||
{
|
||||
struct mv88e6xxx_chip *chip = ptp_to_chip(ptp);
|
||||
const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops;
|
||||
int neg_adj = 0;
|
||||
u32 diff, mult;
|
||||
u64 adj;
|
||||
|
@ -187,10 +208,11 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm)
|
|||
neg_adj = 1;
|
||||
scaled_ppm = -scaled_ppm;
|
||||
}
|
||||
mult = CC_MULT;
|
||||
adj = CC_MULT_NUM;
|
||||
|
||||
mult = ptp_ops->cc_mult;
|
||||
adj = ptp_ops->cc_mult_num;
|
||||
adj *= scaled_ppm;
|
||||
diff = div_u64(adj, CC_MULT_DEM);
|
||||
diff = div_u64(adj, ptp_ops->cc_mult_dem);
|
||||
|
||||
mv88e6xxx_reg_lock(chip);
|
||||
|
||||
|
@ -310,6 +332,53 @@ static int mv88e6352_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
|
|||
return 0;
|
||||
}
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
|
||||
.clock_read = mv88e6165_ptp_clock_read,
|
||||
.global_enable = mv88e6165_global_enable,
|
||||
.global_disable = mv88e6165_global_disable,
|
||||
.arr0_sts_reg = MV88E6165_PORT_PTP_ARR0_STS,
|
||||
.arr1_sts_reg = MV88E6165_PORT_PTP_ARR1_STS,
|
||||
.dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
|
||||
.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
|
||||
.cc_shift = MV88E6XXX_CC_SHIFT,
|
||||
.cc_mult = MV88E6XXX_CC_MULT,
|
||||
.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
|
||||
.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
|
||||
};
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {
|
||||
.clock_read = mv88e6352_ptp_clock_read,
|
||||
.ptp_enable = mv88e6352_ptp_enable,
|
||||
.ptp_verify = mv88e6352_ptp_verify,
|
||||
.event_work = mv88e6352_tai_event_work,
|
||||
.port_enable = mv88e6352_hwtstamp_port_enable,
|
||||
.port_disable = mv88e6352_hwtstamp_port_disable,
|
||||
.n_ext_ts = 1,
|
||||
.arr0_sts_reg = MV88E6XXX_PORT_PTP_ARR0_STS,
|
||||
.arr1_sts_reg = MV88E6XXX_PORT_PTP_ARR1_STS,
|
||||
.dep_sts_reg = MV88E6XXX_PORT_PTP_DEP_STS,
|
||||
.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
|
||||
.cc_shift = MV88E6250_CC_SHIFT,
|
||||
.cc_mult = MV88E6250_CC_MULT,
|
||||
.cc_mult_num = MV88E6250_CC_MULT_NUM,
|
||||
.cc_mult_dem = MV88E6250_CC_MULT_DEM,
|
||||
};
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
|
||||
.clock_read = mv88e6352_ptp_clock_read,
|
||||
.ptp_enable = mv88e6352_ptp_enable,
|
||||
|
@ -331,22 +400,10 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {
|
|||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
|
||||
};
|
||||
|
||||
const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {
|
||||
.clock_read = mv88e6165_ptp_clock_read,
|
||||
.global_enable = mv88e6165_global_enable,
|
||||
.global_disable = mv88e6165_global_disable,
|
||||
.arr0_sts_reg = MV88E6165_PORT_PTP_ARR0_STS,
|
||||
.arr1_sts_reg = MV88E6165_PORT_PTP_ARR1_STS,
|
||||
.dep_sts_reg = MV88E6165_PORT_PTP_DEP_STS,
|
||||
.rx_filters = (1 << HWTSTAMP_FILTER_NONE) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
|
||||
(1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ),
|
||||
.cc_shift = MV88E6XXX_CC_SHIFT,
|
||||
.cc_mult = MV88E6XXX_CC_MULT,
|
||||
.cc_mult_num = MV88E6XXX_CC_MULT_NUM,
|
||||
.cc_mult_dem = MV88E6XXX_CC_MULT_DEM,
|
||||
};
|
||||
|
||||
static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc)
|
||||
|
@ -384,8 +441,8 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
|||
memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc));
|
||||
chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read;
|
||||
chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32);
|
||||
chip->tstamp_cc.mult = CC_MULT;
|
||||
chip->tstamp_cc.shift = CC_SHIFT;
|
||||
chip->tstamp_cc.mult = ptp_ops->cc_mult;
|
||||
chip->tstamp_cc.shift = ptp_ops->cc_shift;
|
||||
|
||||
timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc,
|
||||
ktime_to_ns(ktime_get_real()));
|
||||
|
@ -397,7 +454,6 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
|||
chip->ptp_clock_info.owner = THIS_MODULE;
|
||||
snprintf(chip->ptp_clock_info.name, sizeof(chip->ptp_clock_info.name),
|
||||
"%s", dev_name(chip->dev));
|
||||
chip->ptp_clock_info.max_adj = 1000000;
|
||||
|
||||
chip->ptp_clock_info.n_ext_ts = ptp_ops->n_ext_ts;
|
||||
chip->ptp_clock_info.n_per_out = 0;
|
||||
|
@ -413,6 +469,7 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip)
|
|||
}
|
||||
chip->ptp_clock_info.pin_config = chip->pin_config;
|
||||
|
||||
chip->ptp_clock_info.max_adj = MV88E6XXX_MAX_ADJ_PPB;
|
||||
chip->ptp_clock_info.adjfine = mv88e6xxx_ptp_adjfine;
|
||||
chip->ptp_clock_info.adjtime = mv88e6xxx_ptp_adjtime;
|
||||
chip->ptp_clock_info.gettime64 = mv88e6xxx_ptp_gettime;
|
||||
|
|
|
@ -148,8 +148,9 @@ void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip);
|
|||
#define ptp_to_chip(ptp) container_of(ptp, struct mv88e6xxx_chip, \
|
||||
ptp_clock_info)
|
||||
|
||||
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
|
||||
extern const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops;
|
||||
extern const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops;
|
||||
extern const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops;
|
||||
|
||||
#else /* !CONFIG_NET_DSA_MV88E6XXX_PTP */
|
||||
|
||||
|
@ -167,8 +168,9 @@ static inline void mv88e6xxx_ptp_free(struct mv88e6xxx_chip *chip)
|
|||
{
|
||||
}
|
||||
|
||||
static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
|
||||
static const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = {};
|
||||
static const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = {};
|
||||
static const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = {};
|
||||
|
||||
#endif /* CONFIG_NET_DSA_MV88E6XXX_PTP */
|
||||
|
||||
|
|
Loading…
Reference in a new issue