Merge branch 'mv88e6390-CMODE'
Andrew Lunn says: ==================== Set the CMODE for mv88e6390 ports The mv88e6390 ports 9 & 10 allow there CMODE to be set. CMODE is part of what linux defines as phy-mode. Add the needed phy-modes to linux, and add code which will act upon the phy-mode property to configure the switch port. These patches have been posted before as part of a bigger patchset which has now been broken up. I've added the received reviewed by tags, and added device tree documentation. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
8661a631e1
|
@ -29,6 +29,9 @@ The following properties are common to the Ethernet controllers:
|
|||
* "smii"
|
||||
* "xgmii"
|
||||
* "trgmii"
|
||||
* "2000base-x",
|
||||
* "2500base-x",
|
||||
* "rxaui"
|
||||
- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
|
||||
- phy-handle: phandle, specifies a reference to a node representing a PHY
|
||||
device; this property is described in ePAPR and so preferred;
|
||||
|
|
|
@ -749,6 +749,12 @@ static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port,
|
|||
goto restore_link;
|
||||
}
|
||||
|
||||
if (chip->info->ops->port_set_cmode) {
|
||||
err = chip->info->ops->port_set_cmode(chip, port, mode);
|
||||
if (err && err != -EOPNOTSUPP)
|
||||
goto restore_link;
|
||||
}
|
||||
|
||||
err = 0;
|
||||
restore_link:
|
||||
if (chip->info->ops->port_set_link(chip, port, link))
|
||||
|
@ -3520,6 +3526,7 @@ static const struct mv88e6xxx_ops mv88e6290_ops = {
|
|||
.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,
|
||||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
@ -3738,6 +3745,7 @@ static const struct mv88e6xxx_ops mv88e6390_ops = {
|
|||
.port_jumbo_config = mv88e6165_port_jumbo_config,
|
||||
.port_egress_rate_limiting = mv88e6097_port_egress_rate_limiting,
|
||||
.port_pause_config = mv88e6390_port_pause_config,
|
||||
.port_set_cmode = mv88e6390x_port_set_cmode,
|
||||
.stats_snapshot = mv88e6390_g1_stats_snapshot,
|
||||
.stats_set_histogram = mv88e6390_g1_stats_set_histogram,
|
||||
.stats_get_sset_count = mv88e6320_stats_get_sset_count,
|
||||
|
|
|
@ -58,6 +58,9 @@
|
|||
#define PORT_STATUS_CMODE_100BASE_X 0x8
|
||||
#define PORT_STATUS_CMODE_1000BASE_X 0x9
|
||||
#define PORT_STATUS_CMODE_SGMII 0xa
|
||||
#define PORT_STATUS_CMODE_2500BASEX 0xb
|
||||
#define PORT_STATUS_CMODE_XAUI 0xc
|
||||
#define PORT_STATUS_CMODE_RXAUI 0xd
|
||||
#define PORT_PCS_CTRL 0x01
|
||||
#define PORT_PCS_CTRL_RGMII_DELAY_RXCLK BIT(15)
|
||||
#define PORT_PCS_CTRL_RGMII_DELAY_TXCLK BIT(14)
|
||||
|
@ -838,6 +841,12 @@ struct mv88e6xxx_ops {
|
|||
int (*port_egress_rate_limiting)(struct mv88e6xxx_chip *chip, int port);
|
||||
int (*port_pause_config)(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.
|
||||
*/
|
||||
int (*port_set_cmode)(struct mv88e6xxx_chip *chip, int port,
|
||||
phy_interface_t mode);
|
||||
|
||||
/* Snapshot the statistics for a port. The statistics can then
|
||||
* be read back a leisure but still with a consistent view.
|
||||
*/
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/phy.h>
|
||||
#include "mv88e6xxx.h"
|
||||
#include "port.h"
|
||||
|
||||
|
@ -304,6 +305,69 @@ int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed)
|
|||
return mv88e6xxx_port_set_speed(chip, port, speed, true, true);
|
||||
}
|
||||
|
||||
int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
||||
phy_interface_t mode)
|
||||
{
|
||||
u16 reg;
|
||||
u16 cmode;
|
||||
int err;
|
||||
|
||||
if (mode == PHY_INTERFACE_MODE_NA)
|
||||
return 0;
|
||||
|
||||
if (port != 9 && port != 10)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
switch (mode) {
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
cmode = PORT_STATUS_CMODE_1000BASE_X;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_SGMII:
|
||||
cmode = PORT_STATUS_CMODE_SGMII;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
cmode = PORT_STATUS_CMODE_2500BASEX;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_XGMII:
|
||||
cmode = PORT_STATUS_CMODE_XAUI;
|
||||
break;
|
||||
case PHY_INTERFACE_MODE_RXAUI:
|
||||
cmode = PORT_STATUS_CMODE_RXAUI;
|
||||
break;
|
||||
default:
|
||||
cmode = 0;
|
||||
}
|
||||
|
||||
if (cmode) {
|
||||
err = mv88e6xxx_port_read(chip, port, PORT_STATUS, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
reg &= ~PORT_STATUS_CMODE_MASK;
|
||||
reg |= cmode;
|
||||
|
||||
err = mv88e6xxx_port_write(chip, port, PORT_STATUS, reg);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode)
|
||||
{
|
||||
int err;
|
||||
u16 reg;
|
||||
|
||||
err = mv88e6xxx_port_read(chip, port, PORT_STATUS, ®);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*cmode = reg & PORT_STATUS_CMODE_MASK;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Offset 0x02: Pause Control
|
||||
*
|
||||
* Do not limit the period of time that this port can be paused for by
|
||||
|
|
|
@ -67,5 +67,8 @@ 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);
|
||||
int mv88e6390x_port_set_cmode(struct mv88e6xxx_chip *chip, int port,
|
||||
phy_interface_t mode);
|
||||
int mv88e6xxx_port_get_cmode(struct mv88e6xxx_chip *chip, int port, u8 *cmode);
|
||||
|
||||
#endif /* _MV88E6XXX_PORT_H */
|
||||
|
|
|
@ -81,6 +81,9 @@ typedef enum {
|
|||
PHY_INTERFACE_MODE_MOCA,
|
||||
PHY_INTERFACE_MODE_QSGMII,
|
||||
PHY_INTERFACE_MODE_TRGMII,
|
||||
PHY_INTERFACE_MODE_1000BASEX,
|
||||
PHY_INTERFACE_MODE_2500BASEX,
|
||||
PHY_INTERFACE_MODE_RXAUI,
|
||||
PHY_INTERFACE_MODE_MAX,
|
||||
} phy_interface_t;
|
||||
|
||||
|
@ -141,6 +144,12 @@ static inline const char *phy_modes(phy_interface_t interface)
|
|||
return "qsgmii";
|
||||
case PHY_INTERFACE_MODE_TRGMII:
|
||||
return "trgmii";
|
||||
case PHY_INTERFACE_MODE_1000BASEX:
|
||||
return "1000base-x";
|
||||
case PHY_INTERFACE_MODE_2500BASEX:
|
||||
return "2500base-x";
|
||||
case PHY_INTERFACE_MODE_RXAUI:
|
||||
return "rxaui";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче