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))
        .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,
        .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,
 
 #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)
        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.
         */
 
  * (at your option) any later version.
  */
 
+#include <linux/phy.h>
 #include "mv88e6xxx.h"
 #include "port.h"
 
        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
 
 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 */