Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'dsa-mv88e6xxx-port-operation-refine'

Vivien Didelot says:

====================
net: dsa: mv88e6xxx: refine port operations

The Marvell chips have one internal SMI device per port, containing a
set of registers used to configure a port's link, STP state, default
VLAN or addresses database, etc.

This patchset creates port files to implement the port operations as
described in datasheets, and extend the chip ops structure with them.

Patches 1 to 6 implement accessors for port's STP state, port based VLAN
map, default FID, default VID, and 802.1Q mode.

Patches 7 to 11 implement the port's MAC setup of link state, duplex
mode, RGMII delay and speed, all accessed through port's register 0x01.

The new port's MAC setup code is used to re-implement the adjust_link
code and correctly force the link down before changing any of the MAC
settings, as requested by the datasheets.

The port's MAC accessors use values compatible with struct phy_device
(e.g. DUPLEX_FULL) and extend them when needed (e.g. SPEED_MAX).

Changes in v2:

- Strictly use new _UNFORCED values instead of re-using _UNKNOWN ones.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+727 -308
+1
drivers/net/dsa/mv88e6xxx/Makefile
··· 2 2 mv88e6xxx-objs := chip.o 3 3 mv88e6xxx-objs += global1.o 4 4 mv88e6xxx-$(CONFIG_NET_DSA_MV88E6XXX_GLOBAL2) += global2.o 5 + mv88e6xxx-objs += port.o
+132 -304
drivers/net/dsa/mv88e6xxx/chip.c
··· 37 37 #include "mv88e6xxx.h" 38 38 #include "global1.h" 39 39 #include "global2.h" 40 + #include "port.h" 40 41 41 42 static void assert_reg_lock(struct mv88e6xxx_chip *chip) 42 43 { ··· 220 219 addr, reg, val); 221 220 222 221 return 0; 223 - } 224 - 225 - static int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 226 - u16 *val) 227 - { 228 - int addr = chip->info->port_base_addr + port; 229 - 230 - return mv88e6xxx_read(chip, addr, reg, val); 231 - } 232 - 233 - static int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 234 - u16 val) 235 - { 236 - int addr = chip->info->port_base_addr + port; 237 - 238 - return mv88e6xxx_write(chip, addr, reg, val); 239 222 } 240 223 241 224 static int mv88e6xxx_phy_read(struct mv88e6xxx_chip *chip, int phy, ··· 701 716 return chip->info->family == MV88E6XXX_FAMILY_6352; 702 717 } 703 718 719 + static int mv88e6xxx_port_setup_mac(struct mv88e6xxx_chip *chip, int port, 720 + int link, int speed, int duplex, 721 + phy_interface_t mode) 722 + { 723 + int err; 724 + 725 + if (!chip->info->ops->port_set_link) 726 + return 0; 727 + 728 + /* Port's MAC control must not be changed unless the link is down */ 729 + err = chip->info->ops->port_set_link(chip, port, 0); 730 + if (err) 731 + return err; 732 + 733 + if (chip->info->ops->port_set_speed) { 734 + err = chip->info->ops->port_set_speed(chip, port, speed); 735 + if (err && err != -EOPNOTSUPP) 736 + goto restore_link; 737 + } 738 + 739 + if (chip->info->ops->port_set_duplex) { 740 + err = chip->info->ops->port_set_duplex(chip, port, duplex); 741 + if (err && err != -EOPNOTSUPP) 742 + goto restore_link; 743 + } 744 + 745 + if (chip->info->ops->port_set_rgmii_delay) { 746 + err = chip->info->ops->port_set_rgmii_delay(chip, port, mode); 747 + if (err && err != -EOPNOTSUPP) 748 + goto restore_link; 749 + } 750 + 751 + err = 0; 752 + restore_link: 753 + if (chip->info->ops->port_set_link(chip, port, link)) 754 + netdev_err(chip->ds->ports[port].netdev, 755 + "failed to restore MAC's link\n"); 756 + 757 + return err; 758 + } 759 + 704 760 /* We expect the switch to perform auto negotiation if there is a real 705 761 * phy. However, in the case of a fixed link phy, we force the port 706 762 * settings from the fixed link settings. ··· 750 724 struct phy_device *phydev) 751 725 { 752 726 struct mv88e6xxx_chip *chip = ds->priv; 753 - u16 reg; 754 727 int err; 755 728 756 729 if (!phy_is_pseudo_fixed_link(phydev)) 757 730 return; 758 731 759 732 mutex_lock(&chip->reg_lock); 760 - 761 - err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 762 - if (err) 763 - goto out; 764 - 765 - reg &= ~(PORT_PCS_CTRL_LINK_UP | 766 - PORT_PCS_CTRL_FORCE_LINK | 767 - PORT_PCS_CTRL_DUPLEX_FULL | 768 - PORT_PCS_CTRL_FORCE_DUPLEX | 769 - PORT_PCS_CTRL_UNFORCED); 770 - 771 - reg |= PORT_PCS_CTRL_FORCE_LINK; 772 - if (phydev->link) 773 - reg |= PORT_PCS_CTRL_LINK_UP; 774 - 775 - if (mv88e6xxx_6065_family(chip) && phydev->speed > SPEED_100) 776 - goto out; 777 - 778 - switch (phydev->speed) { 779 - case SPEED_1000: 780 - reg |= PORT_PCS_CTRL_1000; 781 - break; 782 - case SPEED_100: 783 - reg |= PORT_PCS_CTRL_100; 784 - break; 785 - case SPEED_10: 786 - reg |= PORT_PCS_CTRL_10; 787 - break; 788 - default: 789 - pr_info("Unknown speed"); 790 - goto out; 791 - } 792 - 793 - reg |= PORT_PCS_CTRL_FORCE_DUPLEX; 794 - if (phydev->duplex == DUPLEX_FULL) 795 - reg |= PORT_PCS_CTRL_DUPLEX_FULL; 796 - 797 - if ((mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip)) && 798 - (port >= mv88e6xxx_num_ports(chip) - 2)) { 799 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) 800 - reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; 801 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) 802 - reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK; 803 - if (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) 804 - reg |= (PORT_PCS_CTRL_RGMII_DELAY_RXCLK | 805 - PORT_PCS_CTRL_RGMII_DELAY_TXCLK); 806 - } 807 - mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 808 - 809 - out: 733 + err = mv88e6xxx_port_setup_mac(chip, port, phydev->link, phydev->speed, 734 + phydev->duplex, phydev->interface); 810 735 mutex_unlock(&chip->reg_lock); 736 + 737 + if (err && err != -EOPNOTSUPP) 738 + netdev_err(ds->ports[port].netdev, "failed to configure MAC\n"); 811 739 } 812 740 813 741 static int _mv88e6xxx_stats_wait(struct mv88e6xxx_chip *chip) ··· 1210 1230 return _mv88e6xxx_atu_move(chip, fid, port, 0x0f, static_too); 1211 1231 } 1212 1232 1213 - static const char * const mv88e6xxx_port_state_names[] = { 1214 - [PORT_CONTROL_STATE_DISABLED] = "Disabled", 1215 - [PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening", 1216 - [PORT_CONTROL_STATE_LEARNING] = "Learning", 1217 - [PORT_CONTROL_STATE_FORWARDING] = "Forwarding", 1218 - }; 1219 - 1220 - static int _mv88e6xxx_port_state(struct mv88e6xxx_chip *chip, int port, 1221 - u8 state) 1222 - { 1223 - struct dsa_switch *ds = chip->ds; 1224 - u16 reg; 1225 - int err; 1226 - u8 oldstate; 1227 - 1228 - err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg); 1229 - if (err) 1230 - return err; 1231 - 1232 - oldstate = reg & PORT_CONTROL_STATE_MASK; 1233 - 1234 - reg &= ~PORT_CONTROL_STATE_MASK; 1235 - reg |= state; 1236 - 1237 - err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg); 1238 - if (err) 1239 - return err; 1240 - 1241 - netdev_dbg(ds->ports[port].netdev, "PortState %s (was %s)\n", 1242 - mv88e6xxx_port_state_names[state], 1243 - mv88e6xxx_port_state_names[oldstate]); 1244 - 1245 - return 0; 1246 - } 1247 - 1248 1233 static int _mv88e6xxx_port_based_vlan_map(struct mv88e6xxx_chip *chip, int port) 1249 1234 { 1250 1235 struct net_device *bridge = chip->ports[port].bridge_dev; 1251 - const u16 mask = (1 << mv88e6xxx_num_ports(chip)) - 1; 1252 1236 struct dsa_switch *ds = chip->ds; 1253 1237 u16 output_ports = 0; 1254 - u16 reg; 1255 - int err; 1256 1238 int i; 1257 1239 1258 1240 /* allow CPU port or DSA link(s) to send frames to every port */ 1259 1241 if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { 1260 - output_ports = mask; 1242 + output_ports = ~0; 1261 1243 } else { 1262 1244 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 1263 1245 /* allow sending frames to every group member */ ··· 1235 1293 /* prevent frames from going back out of the port they came in on */ 1236 1294 output_ports &= ~BIT(port); 1237 1295 1238 - err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); 1239 - if (err) 1240 - return err; 1241 - 1242 - reg &= ~mask; 1243 - reg |= output_ports & mask; 1244 - 1245 - return mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg); 1296 + return mv88e6xxx_port_set_vlan_map(chip, port, output_ports); 1246 1297 } 1247 1298 1248 1299 static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port, ··· 1263 1328 } 1264 1329 1265 1330 mutex_lock(&chip->reg_lock); 1266 - err = _mv88e6xxx_port_state(chip, port, stp_state); 1331 + err = mv88e6xxx_port_set_state(chip, port, stp_state); 1267 1332 mutex_unlock(&chip->reg_lock); 1268 1333 1269 1334 if (err) 1270 - netdev_err(ds->ports[port].netdev, 1271 - "failed to update state to %s\n", 1272 - mv88e6xxx_port_state_names[stp_state]); 1335 + netdev_err(ds->ports[port].netdev, "failed to update state\n"); 1273 1336 } 1274 1337 1275 1338 static void mv88e6xxx_port_fast_age(struct dsa_switch *ds, int port) ··· 1281 1348 1282 1349 if (err) 1283 1350 netdev_err(ds->ports[port].netdev, "failed to flush ATU\n"); 1284 - } 1285 - 1286 - static int _mv88e6xxx_port_pvid(struct mv88e6xxx_chip *chip, int port, 1287 - u16 *new, u16 *old) 1288 - { 1289 - struct dsa_switch *ds = chip->ds; 1290 - u16 pvid, reg; 1291 - int err; 1292 - 1293 - err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg); 1294 - if (err) 1295 - return err; 1296 - 1297 - pvid = reg & PORT_DEFAULT_VLAN_MASK; 1298 - 1299 - if (new) { 1300 - reg &= ~PORT_DEFAULT_VLAN_MASK; 1301 - reg |= *new & PORT_DEFAULT_VLAN_MASK; 1302 - 1303 - err = mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, reg); 1304 - if (err) 1305 - return err; 1306 - 1307 - netdev_dbg(ds->ports[port].netdev, 1308 - "DefaultVID %d (was %d)\n", *new, pvid); 1309 - } 1310 - 1311 - if (old) 1312 - *old = pvid; 1313 - 1314 - return 0; 1315 - } 1316 - 1317 - static int _mv88e6xxx_port_pvid_get(struct mv88e6xxx_chip *chip, 1318 - int port, u16 *pvid) 1319 - { 1320 - return _mv88e6xxx_port_pvid(chip, port, NULL, pvid); 1321 - } 1322 - 1323 - static int _mv88e6xxx_port_pvid_set(struct mv88e6xxx_chip *chip, 1324 - int port, u16 pvid) 1325 - { 1326 - return _mv88e6xxx_port_pvid(chip, port, &pvid, NULL); 1327 1351 } 1328 1352 1329 1353 static int _mv88e6xxx_vtu_wait(struct mv88e6xxx_chip *chip) ··· 1462 1572 1463 1573 mutex_lock(&chip->reg_lock); 1464 1574 1465 - err = _mv88e6xxx_port_pvid_get(chip, port, &pvid); 1575 + err = mv88e6xxx_port_get_pvid(chip, port, &pvid); 1466 1576 if (err) 1467 1577 goto unlock; 1468 1578 ··· 1626 1736 return _mv88e6xxx_vtu_cmd(chip, GLOBAL_VTU_OP_STU_LOAD_PURGE); 1627 1737 } 1628 1738 1629 - static int _mv88e6xxx_port_fid(struct mv88e6xxx_chip *chip, int port, 1630 - u16 *new, u16 *old) 1631 - { 1632 - struct dsa_switch *ds = chip->ds; 1633 - u16 upper_mask; 1634 - u16 fid; 1635 - u16 reg; 1636 - int err; 1637 - 1638 - if (mv88e6xxx_num_databases(chip) == 4096) 1639 - upper_mask = 0xff; 1640 - else if (mv88e6xxx_num_databases(chip) == 256) 1641 - upper_mask = 0xf; 1642 - else 1643 - return -EOPNOTSUPP; 1644 - 1645 - /* Port's default FID bits 3:0 are located in reg 0x06, offset 12 */ 1646 - err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); 1647 - if (err) 1648 - return err; 1649 - 1650 - fid = (reg & PORT_BASE_VLAN_FID_3_0_MASK) >> 12; 1651 - 1652 - if (new) { 1653 - reg &= ~PORT_BASE_VLAN_FID_3_0_MASK; 1654 - reg |= (*new << 12) & PORT_BASE_VLAN_FID_3_0_MASK; 1655 - 1656 - err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg); 1657 - if (err) 1658 - return err; 1659 - } 1660 - 1661 - /* Port's default FID bits 11:4 are located in reg 0x05, offset 0 */ 1662 - err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg); 1663 - if (err) 1664 - return err; 1665 - 1666 - fid |= (reg & upper_mask) << 4; 1667 - 1668 - if (new) { 1669 - reg &= ~upper_mask; 1670 - reg |= (*new >> 4) & upper_mask; 1671 - 1672 - err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, reg); 1673 - if (err) 1674 - return err; 1675 - 1676 - netdev_dbg(ds->ports[port].netdev, 1677 - "FID %d (was %d)\n", *new, fid); 1678 - } 1679 - 1680 - if (old) 1681 - *old = fid; 1682 - 1683 - return 0; 1684 - } 1685 - 1686 - static int _mv88e6xxx_port_fid_get(struct mv88e6xxx_chip *chip, 1687 - int port, u16 *fid) 1688 - { 1689 - return _mv88e6xxx_port_fid(chip, port, NULL, fid); 1690 - } 1691 - 1692 - static int _mv88e6xxx_port_fid_set(struct mv88e6xxx_chip *chip, 1693 - int port, u16 fid) 1694 - { 1695 - return _mv88e6xxx_port_fid(chip, port, &fid, NULL); 1696 - } 1697 - 1698 1739 static int _mv88e6xxx_fid_new(struct mv88e6xxx_chip *chip, u16 *fid) 1699 1740 { 1700 1741 DECLARE_BITMAP(fid_bitmap, MV88E6XXX_N_FID); ··· 1636 1815 1637 1816 /* Set every FID bit used by the (un)bridged ports */ 1638 1817 for (i = 0; i < mv88e6xxx_num_ports(chip); ++i) { 1639 - err = _mv88e6xxx_port_fid_get(chip, i, fid); 1818 + err = mv88e6xxx_port_get_fid(chip, i, fid); 1640 1819 if (err) 1641 1820 return err; 1642 1821 ··· 1801 1980 return err; 1802 1981 } 1803 1982 1804 - static const char * const mv88e6xxx_port_8021q_mode_names[] = { 1805 - [PORT_CONTROL_2_8021Q_DISABLED] = "Disabled", 1806 - [PORT_CONTROL_2_8021Q_FALLBACK] = "Fallback", 1807 - [PORT_CONTROL_2_8021Q_CHECK] = "Check", 1808 - [PORT_CONTROL_2_8021Q_SECURE] = "Secure", 1809 - }; 1810 - 1811 1983 static int mv88e6xxx_port_vlan_filtering(struct dsa_switch *ds, int port, 1812 1984 bool vlan_filtering) 1813 1985 { 1814 1986 struct mv88e6xxx_chip *chip = ds->priv; 1815 - u16 old, new = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE : 1987 + u16 mode = vlan_filtering ? PORT_CONTROL_2_8021Q_SECURE : 1816 1988 PORT_CONTROL_2_8021Q_DISABLED; 1817 - u16 reg; 1818 1989 int err; 1819 1990 1820 1991 if (!mv88e6xxx_has(chip, MV88E6XXX_FLAG_VTU)) 1821 1992 return -EOPNOTSUPP; 1822 1993 1823 1994 mutex_lock(&chip->reg_lock); 1824 - 1825 - err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg); 1826 - if (err) 1827 - goto unlock; 1828 - 1829 - old = reg & PORT_CONTROL_2_8021Q_MASK; 1830 - 1831 - if (new != old) { 1832 - reg &= ~PORT_CONTROL_2_8021Q_MASK; 1833 - reg |= new & PORT_CONTROL_2_8021Q_MASK; 1834 - 1835 - err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg); 1836 - if (err) 1837 - goto unlock; 1838 - 1839 - netdev_dbg(ds->ports[port].netdev, "802.1Q Mode %s (was %s)\n", 1840 - mv88e6xxx_port_8021q_mode_names[new], 1841 - mv88e6xxx_port_8021q_mode_names[old]); 1842 - } 1843 - 1844 - err = 0; 1845 - unlock: 1995 + err = mv88e6xxx_port_set_8021q_mode(chip, port, mode); 1846 1996 mutex_unlock(&chip->reg_lock); 1847 1997 1848 1998 return err; ··· 1881 2089 "failed to add VLAN %d%c\n", 1882 2090 vid, untagged ? 'u' : 't'); 1883 2091 1884 - if (pvid && _mv88e6xxx_port_pvid_set(chip, port, vlan->vid_end)) 2092 + if (pvid && mv88e6xxx_port_set_pvid(chip, port, vlan->vid_end)) 1885 2093 netdev_err(ds->ports[port].netdev, "failed to set PVID %d\n", 1886 2094 vlan->vid_end); 1887 2095 ··· 1936 2144 1937 2145 mutex_lock(&chip->reg_lock); 1938 2146 1939 - err = _mv88e6xxx_port_pvid_get(chip, port, &pvid); 2147 + err = mv88e6xxx_port_get_pvid(chip, port, &pvid); 1940 2148 if (err) 1941 2149 goto unlock; 1942 2150 ··· 1946 2154 goto unlock; 1947 2155 1948 2156 if (vid == pvid) { 1949 - err = _mv88e6xxx_port_pvid_set(chip, port, 0); 2157 + err = mv88e6xxx_port_set_pvid(chip, port, 0); 1950 2158 if (err) 1951 2159 goto unlock; 1952 2160 } ··· 2057 2265 2058 2266 /* Null VLAN ID corresponds to the port private database */ 2059 2267 if (vid == 0) 2060 - err = _mv88e6xxx_port_fid_get(chip, port, &vlan.fid); 2268 + err = mv88e6xxx_port_get_fid(chip, port, &vlan.fid); 2061 2269 else 2062 2270 err = _mv88e6xxx_vtu_get(chip, vid, &vlan, false); 2063 2271 if (err) ··· 2233 2441 int err; 2234 2442 2235 2443 /* Dump port's default Filtering Information Database (VLAN ID 0) */ 2236 - err = _mv88e6xxx_port_fid_get(chip, port, &fid); 2444 + err = mv88e6xxx_port_get_fid(chip, port, &fid); 2237 2445 if (err) 2238 2446 return err; 2239 2447 ··· 2333 2541 2334 2542 /* Set all ports to the disabled state. */ 2335 2543 for (i = 0; i < mv88e6xxx_num_ports(chip); i++) { 2336 - err = mv88e6xxx_port_read(chip, i, PORT_CONTROL, &reg); 2337 - if (err) 2338 - return err; 2339 - 2340 - err = mv88e6xxx_port_write(chip, i, PORT_CONTROL, 2341 - reg & 0xfffc); 2544 + err = mv88e6xxx_port_set_state(chip, i, 2545 + PORT_CONTROL_STATE_DISABLED); 2342 2546 if (err) 2343 2547 return err; 2344 2548 } ··· 2404 2616 int err; 2405 2617 u16 reg; 2406 2618 2407 - if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) || 2408 - mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) || 2409 - mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip) || 2410 - mv88e6xxx_6065_family(chip) || mv88e6xxx_6320_family(chip)) { 2411 - /* MAC Forcing register: don't force link, speed, 2412 - * duplex or flow control state to any particular 2413 - * values on physical ports, but force the CPU port 2414 - * and all DSA ports to their maximum bandwidth and 2415 - * full duplex. 2416 - */ 2417 - err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 2418 - if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) { 2419 - reg &= ~PORT_PCS_CTRL_UNFORCED; 2420 - reg |= PORT_PCS_CTRL_FORCE_LINK | 2421 - PORT_PCS_CTRL_LINK_UP | 2422 - PORT_PCS_CTRL_DUPLEX_FULL | 2423 - PORT_PCS_CTRL_FORCE_DUPLEX; 2424 - if (mv88e6xxx_6065_family(chip)) 2425 - reg |= PORT_PCS_CTRL_100; 2426 - else 2427 - reg |= PORT_PCS_CTRL_1000; 2428 - } else { 2429 - reg |= PORT_PCS_CTRL_UNFORCED; 2430 - } 2431 - 2432 - err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 2433 - if (err) 2434 - return err; 2435 - } 2619 + /* MAC Forcing register: don't force link, speed, duplex or flow control 2620 + * state to any particular values on physical ports, but force the CPU 2621 + * port and all DSA ports to their maximum bandwidth and full duplex. 2622 + */ 2623 + if (dsa_is_cpu_port(ds, port) || dsa_is_dsa_port(ds, port)) 2624 + err = mv88e6xxx_port_setup_mac(chip, port, LINK_FORCED_UP, 2625 + SPEED_MAX, DUPLEX_FULL, 2626 + PHY_INTERFACE_MODE_NA); 2627 + else 2628 + err = mv88e6xxx_port_setup_mac(chip, port, LINK_UNFORCED, 2629 + SPEED_UNFORCED, DUPLEX_UNFORCED, 2630 + PHY_INTERFACE_MODE_NA); 2631 + if (err) 2632 + return err; 2436 2633 2437 2634 /* Port Control: disable Drop-on-Unlock, disable Drop-on-Lock, 2438 2635 * disable Header mode, enable IGMP/MLD snooping, disable VLAN ··· 2621 2848 * database, and allow bidirectional communication between the 2622 2849 * CPU and DSA port(s), and the other ports. 2623 2850 */ 2624 - err = _mv88e6xxx_port_fid_set(chip, port, 0); 2851 + err = mv88e6xxx_port_set_fid(chip, port, 0); 2625 2852 if (err) 2626 2853 return err; 2627 2854 ··· 3140 3367 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 3141 3368 .phy_read = mv88e6xxx_phy_ppu_read, 3142 3369 .phy_write = mv88e6xxx_phy_ppu_write, 3370 + .port_set_link = mv88e6xxx_port_set_link, 3371 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3372 + .port_set_speed = mv88e6185_port_set_speed, 3143 3373 }; 3144 3374 3145 3375 static const struct mv88e6xxx_ops mv88e6095_ops = { 3146 3376 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 3147 3377 .phy_read = mv88e6xxx_phy_ppu_read, 3148 3378 .phy_write = mv88e6xxx_phy_ppu_write, 3379 + .port_set_link = mv88e6xxx_port_set_link, 3380 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3381 + .port_set_speed = mv88e6185_port_set_speed, 3149 3382 }; 3150 3383 3151 3384 static const struct mv88e6xxx_ops mv88e6123_ops = { 3152 3385 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3153 3386 .phy_read = mv88e6xxx_read, 3154 3387 .phy_write = mv88e6xxx_write, 3388 + .port_set_link = mv88e6xxx_port_set_link, 3389 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3390 + .port_set_speed = mv88e6185_port_set_speed, 3155 3391 }; 3156 3392 3157 3393 static const struct mv88e6xxx_ops mv88e6131_ops = { 3158 3394 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 3159 3395 .phy_read = mv88e6xxx_phy_ppu_read, 3160 3396 .phy_write = mv88e6xxx_phy_ppu_write, 3397 + .port_set_link = mv88e6xxx_port_set_link, 3398 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3399 + .port_set_speed = mv88e6185_port_set_speed, 3161 3400 }; 3162 3401 3163 3402 static const struct mv88e6xxx_ops mv88e6161_ops = { 3164 3403 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3165 3404 .phy_read = mv88e6xxx_read, 3166 3405 .phy_write = mv88e6xxx_write, 3406 + .port_set_link = mv88e6xxx_port_set_link, 3407 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3408 + .port_set_speed = mv88e6185_port_set_speed, 3167 3409 }; 3168 3410 3169 3411 static const struct mv88e6xxx_ops mv88e6165_ops = { 3170 3412 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3171 3413 .phy_read = mv88e6xxx_read, 3172 3414 .phy_write = mv88e6xxx_write, 3415 + .port_set_link = mv88e6xxx_port_set_link, 3416 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3417 + .port_set_speed = mv88e6185_port_set_speed, 3173 3418 }; 3174 3419 3175 3420 static const struct mv88e6xxx_ops mv88e6171_ops = { 3176 3421 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3177 3422 .phy_read = mv88e6xxx_g2_smi_phy_read, 3178 3423 .phy_write = mv88e6xxx_g2_smi_phy_write, 3424 + .port_set_link = mv88e6xxx_port_set_link, 3425 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3426 + .port_set_speed = mv88e6185_port_set_speed, 3179 3427 }; 3180 3428 3181 3429 static const struct mv88e6xxx_ops mv88e6172_ops = { ··· 3205 3411 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3206 3412 .phy_read = mv88e6xxx_g2_smi_phy_read, 3207 3413 .phy_write = mv88e6xxx_g2_smi_phy_write, 3414 + .port_set_link = mv88e6xxx_port_set_link, 3415 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3416 + .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 3417 + .port_set_speed = mv88e6352_port_set_speed, 3208 3418 }; 3209 3419 3210 3420 static const struct mv88e6xxx_ops mv88e6175_ops = { 3211 3421 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3212 3422 .phy_read = mv88e6xxx_g2_smi_phy_read, 3213 3423 .phy_write = mv88e6xxx_g2_smi_phy_write, 3424 + .port_set_link = mv88e6xxx_port_set_link, 3425 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3426 + .port_set_speed = mv88e6185_port_set_speed, 3214 3427 }; 3215 3428 3216 3429 static const struct mv88e6xxx_ops mv88e6176_ops = { ··· 3226 3425 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3227 3426 .phy_read = mv88e6xxx_g2_smi_phy_read, 3228 3427 .phy_write = mv88e6xxx_g2_smi_phy_write, 3428 + .port_set_link = mv88e6xxx_port_set_link, 3429 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3430 + .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 3431 + .port_set_speed = mv88e6352_port_set_speed, 3229 3432 }; 3230 3433 3231 3434 static const struct mv88e6xxx_ops mv88e6185_ops = { 3232 3435 .set_switch_mac = mv88e6xxx_g1_set_switch_mac, 3233 3436 .phy_read = mv88e6xxx_phy_ppu_read, 3234 3437 .phy_write = mv88e6xxx_phy_ppu_write, 3438 + .port_set_link = mv88e6xxx_port_set_link, 3439 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3440 + .port_set_speed = mv88e6185_port_set_speed, 3235 3441 }; 3236 3442 3237 3443 static const struct mv88e6xxx_ops mv88e6240_ops = { ··· 3247 3439 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3248 3440 .phy_read = mv88e6xxx_g2_smi_phy_read, 3249 3441 .phy_write = mv88e6xxx_g2_smi_phy_write, 3442 + .port_set_link = mv88e6xxx_port_set_link, 3443 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3444 + .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 3445 + .port_set_speed = mv88e6352_port_set_speed, 3250 3446 }; 3251 3447 3252 3448 static const struct mv88e6xxx_ops mv88e6320_ops = { ··· 3259 3447 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3260 3448 .phy_read = mv88e6xxx_g2_smi_phy_read, 3261 3449 .phy_write = mv88e6xxx_g2_smi_phy_write, 3450 + .port_set_link = mv88e6xxx_port_set_link, 3451 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3452 + .port_set_speed = mv88e6185_port_set_speed, 3262 3453 }; 3263 3454 3264 3455 static const struct mv88e6xxx_ops mv88e6321_ops = { ··· 3270 3455 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3271 3456 .phy_read = mv88e6xxx_g2_smi_phy_read, 3272 3457 .phy_write = mv88e6xxx_g2_smi_phy_write, 3458 + .port_set_link = mv88e6xxx_port_set_link, 3459 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3460 + .port_set_speed = mv88e6185_port_set_speed, 3273 3461 }; 3274 3462 3275 3463 static const struct mv88e6xxx_ops mv88e6350_ops = { 3276 3464 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3277 3465 .phy_read = mv88e6xxx_g2_smi_phy_read, 3278 3466 .phy_write = mv88e6xxx_g2_smi_phy_write, 3467 + .port_set_link = mv88e6xxx_port_set_link, 3468 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3469 + .port_set_speed = mv88e6185_port_set_speed, 3279 3470 }; 3280 3471 3281 3472 static const struct mv88e6xxx_ops mv88e6351_ops = { 3282 3473 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3283 3474 .phy_read = mv88e6xxx_g2_smi_phy_read, 3284 3475 .phy_write = mv88e6xxx_g2_smi_phy_write, 3476 + .port_set_link = mv88e6xxx_port_set_link, 3477 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3478 + .port_set_speed = mv88e6185_port_set_speed, 3285 3479 }; 3286 3480 3287 3481 static const struct mv88e6xxx_ops mv88e6352_ops = { ··· 3299 3475 .set_switch_mac = mv88e6xxx_g2_set_switch_mac, 3300 3476 .phy_read = mv88e6xxx_g2_smi_phy_read, 3301 3477 .phy_write = mv88e6xxx_g2_smi_phy_write, 3478 + .port_set_link = mv88e6xxx_port_set_link, 3479 + .port_set_duplex = mv88e6xxx_port_set_duplex, 3480 + .port_set_rgmii_delay = mv88e6352_port_set_rgmii_delay, 3481 + .port_set_speed = mv88e6352_port_set_speed, 3302 3482 }; 3303 3483 3304 3484 static const struct mv88e6xxx_info mv88e6xxx_table[] = {
+45 -4
drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
··· 61 61 #define PORT_PCS_CTRL 0x01 62 62 #define PORT_PCS_CTRL_RGMII_DELAY_RXCLK BIT(15) 63 63 #define PORT_PCS_CTRL_RGMII_DELAY_TXCLK BIT(14) 64 + #define PORT_PCS_CTRL_FORCE_SPEED BIT(13) /* 6390 */ 65 + #define PORT_PCS_CTRL_ALTSPEED BIT(12) /* 6390 */ 66 + #define PORT_PCS_CTRL_200BASE BIT(12) /* 6352 */ 64 67 #define PORT_PCS_CTRL_FC BIT(7) 65 68 #define PORT_PCS_CTRL_FORCE_FC BIT(6) 66 69 #define PORT_PCS_CTRL_LINK_UP BIT(5) 67 70 #define PORT_PCS_CTRL_FORCE_LINK BIT(4) 68 71 #define PORT_PCS_CTRL_DUPLEX_FULL BIT(3) 69 72 #define PORT_PCS_CTRL_FORCE_DUPLEX BIT(2) 70 - #define PORT_PCS_CTRL_10 0x00 71 - #define PORT_PCS_CTRL_100 0x01 72 - #define PORT_PCS_CTRL_1000 0x02 73 - #define PORT_PCS_CTRL_UNFORCED 0x03 73 + #define PORT_PCS_CTRL_SPEED_MASK (0x03) 74 + #define PORT_PCS_CTRL_SPEED_10 (0x00) 75 + #define PORT_PCS_CTRL_SPEED_100 (0x01) 76 + #define PORT_PCS_CTRL_SPEED_200 (0x02) /* 6065 and non Gb chips */ 77 + #define PORT_PCS_CTRL_SPEED_1000 (0x02) 78 + #define PORT_PCS_CTRL_SPEED_10000 (0x03) /* 6390X */ 79 + #define PORT_PCS_CTRL_SPEED_UNFORCED (0x03) 74 80 #define PORT_PAUSE_CTRL 0x02 75 81 #define PORT_SWITCH_ID 0x03 76 82 #define PORT_SWITCH_ID_PROD_NUM_6085 0x04a ··· 733 727 u16 *val); 734 728 int (*phy_write)(struct mv88e6xxx_chip *chip, int addr, int reg, 735 729 u16 val); 730 + 731 + /* RGMII Receive/Transmit Timing Control 732 + * Add delay on PHY_INTERFACE_MODE_RGMII_*ID, no delay otherwise. 733 + */ 734 + int (*port_set_rgmii_delay)(struct mv88e6xxx_chip *chip, int port, 735 + phy_interface_t mode); 736 + 737 + #define LINK_FORCED_DOWN 0 738 + #define LINK_FORCED_UP 1 739 + #define LINK_UNFORCED -2 740 + 741 + /* Port's MAC link state 742 + * Use LINK_FORCED_UP or LINK_FORCED_DOWN to force link up or down, 743 + * or LINK_UNFORCED for normal link detection. 744 + */ 745 + int (*port_set_link)(struct mv88e6xxx_chip *chip, int port, int link); 746 + 747 + #define DUPLEX_UNFORCED -2 748 + 749 + /* Port's MAC duplex mode 750 + * 751 + * Use DUPLEX_HALF or DUPLEX_FULL to force half or full duplex, 752 + * or DUPLEX_UNFORCED for normal duplex detection. 753 + */ 754 + int (*port_set_duplex)(struct mv88e6xxx_chip *chip, int port, int dup); 755 + 756 + #define SPEED_MAX INT_MAX 757 + #define SPEED_UNFORCED -2 758 + 759 + /* Port's MAC speed (in Mbps) 760 + * 761 + * Depending on the chip, 10, 100, 200, 1000, 2500, 10000 are valid. 762 + * Use SPEED_UNFORCED for normal detection, SPEED_MAX for max value. 763 + */ 764 + int (*port_set_speed)(struct mv88e6xxx_chip *chip, int port, int speed); 736 765 }; 737 766 738 767 enum stat_type {
+497
drivers/net/dsa/mv88e6xxx/port.c
··· 1 + /* 2 + * Marvell 88E6xxx Switch Port Registers support 3 + * 4 + * Copyright (c) 2008 Marvell Semiconductor 5 + * 6 + * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + */ 13 + 14 + #include "mv88e6xxx.h" 15 + #include "port.h" 16 + 17 + int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 18 + u16 *val) 19 + { 20 + int addr = chip->info->port_base_addr + port; 21 + 22 + return mv88e6xxx_read(chip, addr, reg, val); 23 + } 24 + 25 + int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 26 + u16 val) 27 + { 28 + int addr = chip->info->port_base_addr + port; 29 + 30 + return mv88e6xxx_write(chip, addr, reg, val); 31 + } 32 + 33 + /* Offset 0x01: MAC (or PCS or Physical) Control Register 34 + * 35 + * Link, Duplex and Flow Control have one force bit, one value bit. 36 + * 37 + * For port's MAC speed, ForceSpd (or SpdValue) bits 1:0 program the value. 38 + * Alternative values require the 200BASE (or AltSpeed) bit 12 set. 39 + * Newer chips need a ForcedSpd bit 13 set to consider the value. 40 + */ 41 + 42 + static int mv88e6xxx_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 43 + phy_interface_t mode) 44 + { 45 + u16 reg; 46 + int err; 47 + 48 + err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 49 + if (err) 50 + return err; 51 + 52 + reg &= ~(PORT_PCS_CTRL_RGMII_DELAY_RXCLK | 53 + PORT_PCS_CTRL_RGMII_DELAY_TXCLK); 54 + 55 + switch (mode) { 56 + case PHY_INTERFACE_MODE_RGMII_RXID: 57 + reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK; 58 + break; 59 + case PHY_INTERFACE_MODE_RGMII_TXID: 60 + reg |= PORT_PCS_CTRL_RGMII_DELAY_TXCLK; 61 + break; 62 + case PHY_INTERFACE_MODE_RGMII_ID: 63 + reg |= PORT_PCS_CTRL_RGMII_DELAY_RXCLK | 64 + PORT_PCS_CTRL_RGMII_DELAY_TXCLK; 65 + break; 66 + default: 67 + /* no delay */ 68 + break; 69 + } 70 + 71 + err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 72 + if (err) 73 + return err; 74 + 75 + netdev_dbg(chip->ds->ports[port].netdev, "delay RXCLK %s, TXCLK %s\n", 76 + reg & PORT_PCS_CTRL_RGMII_DELAY_RXCLK ? "yes" : "no", 77 + reg & PORT_PCS_CTRL_RGMII_DELAY_TXCLK ? "yes" : "no"); 78 + 79 + return 0; 80 + } 81 + 82 + int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 83 + phy_interface_t mode) 84 + { 85 + if (port < 5) 86 + return -EOPNOTSUPP; 87 + 88 + return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 89 + } 90 + 91 + int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 92 + phy_interface_t mode) 93 + { 94 + if (port != 0) 95 + return -EOPNOTSUPP; 96 + 97 + return mv88e6xxx_port_set_rgmii_delay(chip, port, mode); 98 + } 99 + 100 + int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link) 101 + { 102 + u16 reg; 103 + int err; 104 + 105 + err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 106 + if (err) 107 + return err; 108 + 109 + reg &= ~(PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP); 110 + 111 + switch (link) { 112 + case LINK_FORCED_DOWN: 113 + reg |= PORT_PCS_CTRL_FORCE_LINK; 114 + break; 115 + case LINK_FORCED_UP: 116 + reg |= PORT_PCS_CTRL_FORCE_LINK | PORT_PCS_CTRL_LINK_UP; 117 + break; 118 + case LINK_UNFORCED: 119 + /* normal link detection */ 120 + break; 121 + default: 122 + return -EINVAL; 123 + } 124 + 125 + err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 126 + if (err) 127 + return err; 128 + 129 + netdev_dbg(chip->ds->ports[port].netdev, "%s link %s\n", 130 + reg & PORT_PCS_CTRL_FORCE_LINK ? "Force" : "Unforce", 131 + reg & PORT_PCS_CTRL_LINK_UP ? "up" : "down"); 132 + 133 + return 0; 134 + } 135 + 136 + int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup) 137 + { 138 + u16 reg; 139 + int err; 140 + 141 + err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 142 + if (err) 143 + return err; 144 + 145 + reg &= ~(PORT_PCS_CTRL_FORCE_DUPLEX | PORT_PCS_CTRL_DUPLEX_FULL); 146 + 147 + switch (dup) { 148 + case DUPLEX_HALF: 149 + reg |= PORT_PCS_CTRL_FORCE_DUPLEX; 150 + break; 151 + case DUPLEX_FULL: 152 + reg |= PORT_PCS_CTRL_FORCE_DUPLEX | PORT_PCS_CTRL_DUPLEX_FULL; 153 + break; 154 + case DUPLEX_UNFORCED: 155 + /* normal duplex detection */ 156 + break; 157 + default: 158 + return -EINVAL; 159 + } 160 + 161 + err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 162 + if (err) 163 + return err; 164 + 165 + netdev_dbg(chip->ds->ports[port].netdev, "%s %s duplex\n", 166 + reg & PORT_PCS_CTRL_FORCE_DUPLEX ? "Force" : "Unforce", 167 + reg & PORT_PCS_CTRL_DUPLEX_FULL ? "full" : "half"); 168 + 169 + return 0; 170 + } 171 + 172 + static int mv88e6xxx_port_set_speed(struct mv88e6xxx_chip *chip, int port, 173 + int speed, bool alt_bit, bool force_bit) 174 + { 175 + u16 reg, ctrl; 176 + int err; 177 + 178 + switch (speed) { 179 + case 10: 180 + ctrl = PORT_PCS_CTRL_SPEED_10; 181 + break; 182 + case 100: 183 + ctrl = PORT_PCS_CTRL_SPEED_100; 184 + break; 185 + case 200: 186 + if (alt_bit) 187 + ctrl = PORT_PCS_CTRL_SPEED_100 | PORT_PCS_CTRL_ALTSPEED; 188 + else 189 + ctrl = PORT_PCS_CTRL_SPEED_200; 190 + break; 191 + case 1000: 192 + ctrl = PORT_PCS_CTRL_SPEED_1000; 193 + break; 194 + case 2500: 195 + ctrl = PORT_PCS_CTRL_SPEED_1000 | PORT_PCS_CTRL_ALTSPEED; 196 + break; 197 + case 10000: 198 + /* all bits set, fall through... */ 199 + case SPEED_UNFORCED: 200 + ctrl = PORT_PCS_CTRL_SPEED_UNFORCED; 201 + break; 202 + default: 203 + return -EOPNOTSUPP; 204 + } 205 + 206 + err = mv88e6xxx_port_read(chip, port, PORT_PCS_CTRL, &reg); 207 + if (err) 208 + return err; 209 + 210 + reg &= ~PORT_PCS_CTRL_SPEED_MASK; 211 + if (alt_bit) 212 + reg &= ~PORT_PCS_CTRL_ALTSPEED; 213 + if (force_bit) { 214 + reg &= ~PORT_PCS_CTRL_FORCE_SPEED; 215 + if (speed) 216 + ctrl |= PORT_PCS_CTRL_FORCE_SPEED; 217 + } 218 + reg |= ctrl; 219 + 220 + err = mv88e6xxx_port_write(chip, port, PORT_PCS_CTRL, reg); 221 + if (err) 222 + return err; 223 + 224 + if (speed) 225 + netdev_dbg(chip->ds->ports[port].netdev, 226 + "Speed set to %d Mbps\n", speed); 227 + else 228 + netdev_dbg(chip->ds->ports[port].netdev, "Speed unforced\n"); 229 + 230 + return 0; 231 + } 232 + 233 + /* Support 10, 100, 200 Mbps (e.g. 88E6065 family) */ 234 + int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 235 + { 236 + if (speed == SPEED_MAX) 237 + speed = 200; 238 + 239 + if (speed > 200) 240 + return -EOPNOTSUPP; 241 + 242 + /* Setting 200 Mbps on port 0 to 3 selects 100 Mbps */ 243 + return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 244 + } 245 + 246 + /* Support 10, 100, 1000 Mbps (e.g. 88E6185 family) */ 247 + int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 248 + { 249 + if (speed == SPEED_MAX) 250 + speed = 1000; 251 + 252 + if (speed == 200 || speed > 1000) 253 + return -EOPNOTSUPP; 254 + 255 + return mv88e6xxx_port_set_speed(chip, port, speed, false, false); 256 + } 257 + 258 + /* Support 10, 100, 200, 1000 Mbps (e.g. 88E6352 family) */ 259 + int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 260 + { 261 + if (speed == SPEED_MAX) 262 + speed = 1000; 263 + 264 + if (speed > 1000) 265 + return -EOPNOTSUPP; 266 + 267 + if (speed == 200 && port < 5) 268 + return -EOPNOTSUPP; 269 + 270 + return mv88e6xxx_port_set_speed(chip, port, speed, true, false); 271 + } 272 + 273 + /* Support 10, 100, 200, 1000, 2500 Mbps (e.g. 88E6390) */ 274 + int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 275 + { 276 + if (speed == SPEED_MAX) 277 + speed = port < 9 ? 1000 : 2500; 278 + 279 + if (speed > 2500) 280 + return -EOPNOTSUPP; 281 + 282 + if (speed == 200 && port != 0) 283 + return -EOPNOTSUPP; 284 + 285 + if (speed == 2500 && port < 9) 286 + return -EOPNOTSUPP; 287 + 288 + return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 289 + } 290 + 291 + /* Support 10, 100, 200, 1000, 2500, 10000 Mbps (e.g. 88E6190X) */ 292 + int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed) 293 + { 294 + if (speed == SPEED_MAX) 295 + speed = port < 9 ? 1000 : 10000; 296 + 297 + if (speed == 200 && port != 0) 298 + return -EOPNOTSUPP; 299 + 300 + if (speed >= 2500 && port < 9) 301 + return -EOPNOTSUPP; 302 + 303 + return mv88e6xxx_port_set_speed(chip, port, speed, true, true); 304 + } 305 + 306 + /* Offset 0x04: Port Control Register */ 307 + 308 + static const char * const mv88e6xxx_port_state_names[] = { 309 + [PORT_CONTROL_STATE_DISABLED] = "Disabled", 310 + [PORT_CONTROL_STATE_BLOCKING] = "Blocking/Listening", 311 + [PORT_CONTROL_STATE_LEARNING] = "Learning", 312 + [PORT_CONTROL_STATE_FORWARDING] = "Forwarding", 313 + }; 314 + 315 + int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state) 316 + { 317 + u16 reg; 318 + int err; 319 + 320 + err = mv88e6xxx_port_read(chip, port, PORT_CONTROL, &reg); 321 + if (err) 322 + return err; 323 + 324 + reg &= ~PORT_CONTROL_STATE_MASK; 325 + reg |= state; 326 + 327 + err = mv88e6xxx_port_write(chip, port, PORT_CONTROL, reg); 328 + if (err) 329 + return err; 330 + 331 + netdev_dbg(chip->ds->ports[port].netdev, "PortState set to %s\n", 332 + mv88e6xxx_port_state_names[state]); 333 + 334 + return 0; 335 + } 336 + 337 + /* Offset 0x05: Port Control 1 */ 338 + 339 + /* Offset 0x06: Port Based VLAN Map */ 340 + 341 + int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map) 342 + { 343 + const u16 mask = GENMASK(mv88e6xxx_num_ports(chip) - 1, 0); 344 + u16 reg; 345 + int err; 346 + 347 + err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); 348 + if (err) 349 + return err; 350 + 351 + reg &= ~mask; 352 + reg |= map & mask; 353 + 354 + err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg); 355 + if (err) 356 + return err; 357 + 358 + netdev_dbg(chip->ds->ports[port].netdev, "VLANTable set to %.3x\n", 359 + map); 360 + 361 + return 0; 362 + } 363 + 364 + int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid) 365 + { 366 + const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 367 + u16 reg; 368 + int err; 369 + 370 + /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 371 + err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); 372 + if (err) 373 + return err; 374 + 375 + *fid = (reg & 0xf000) >> 12; 376 + 377 + /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 378 + if (upper_mask) { 379 + err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg); 380 + if (err) 381 + return err; 382 + 383 + *fid |= (reg & upper_mask) << 4; 384 + } 385 + 386 + return 0; 387 + } 388 + 389 + int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid) 390 + { 391 + const u16 upper_mask = (mv88e6xxx_num_databases(chip) - 1) >> 4; 392 + u16 reg; 393 + int err; 394 + 395 + if (fid >= mv88e6xxx_num_databases(chip)) 396 + return -EINVAL; 397 + 398 + /* Port's default FID lower 4 bits are located in reg 0x06, offset 12 */ 399 + err = mv88e6xxx_port_read(chip, port, PORT_BASE_VLAN, &reg); 400 + if (err) 401 + return err; 402 + 403 + reg &= 0x0fff; 404 + reg |= (fid & 0x000f) << 12; 405 + 406 + err = mv88e6xxx_port_write(chip, port, PORT_BASE_VLAN, reg); 407 + if (err) 408 + return err; 409 + 410 + /* Port's default FID upper bits are located in reg 0x05, offset 0 */ 411 + if (upper_mask) { 412 + err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_1, &reg); 413 + if (err) 414 + return err; 415 + 416 + reg &= ~upper_mask; 417 + reg |= (fid >> 4) & upper_mask; 418 + 419 + err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_1, reg); 420 + if (err) 421 + return err; 422 + } 423 + 424 + netdev_dbg(chip->ds->ports[port].netdev, "FID set to %u\n", fid); 425 + 426 + return 0; 427 + } 428 + 429 + /* Offset 0x07: Default Port VLAN ID & Priority */ 430 + 431 + int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid) 432 + { 433 + u16 reg; 434 + int err; 435 + 436 + err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg); 437 + if (err) 438 + return err; 439 + 440 + *pvid = reg & PORT_DEFAULT_VLAN_MASK; 441 + 442 + return 0; 443 + } 444 + 445 + int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid) 446 + { 447 + u16 reg; 448 + int err; 449 + 450 + err = mv88e6xxx_port_read(chip, port, PORT_DEFAULT_VLAN, &reg); 451 + if (err) 452 + return err; 453 + 454 + reg &= ~PORT_DEFAULT_VLAN_MASK; 455 + reg |= pvid & PORT_DEFAULT_VLAN_MASK; 456 + 457 + err = mv88e6xxx_port_write(chip, port, PORT_DEFAULT_VLAN, reg); 458 + if (err) 459 + return err; 460 + 461 + netdev_dbg(chip->ds->ports[port].netdev, "DefaultVID set to %u\n", 462 + pvid); 463 + 464 + return 0; 465 + } 466 + 467 + /* Offset 0x08: Port Control 2 Register */ 468 + 469 + static const char * const mv88e6xxx_port_8021q_mode_names[] = { 470 + [PORT_CONTROL_2_8021Q_DISABLED] = "Disabled", 471 + [PORT_CONTROL_2_8021Q_FALLBACK] = "Fallback", 472 + [PORT_CONTROL_2_8021Q_CHECK] = "Check", 473 + [PORT_CONTROL_2_8021Q_SECURE] = "Secure", 474 + }; 475 + 476 + int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 477 + u16 mode) 478 + { 479 + u16 reg; 480 + int err; 481 + 482 + err = mv88e6xxx_port_read(chip, port, PORT_CONTROL_2, &reg); 483 + if (err) 484 + return err; 485 + 486 + reg &= ~PORT_CONTROL_2_8021Q_MASK; 487 + reg |= mode & PORT_CONTROL_2_8021Q_MASK; 488 + 489 + err = mv88e6xxx_port_write(chip, port, PORT_CONTROL_2, reg); 490 + if (err) 491 + return err; 492 + 493 + netdev_dbg(chip->ds->ports[port].netdev, "802.1QMode set to %s\n", 494 + mv88e6xxx_port_8021q_mode_names[mode]); 495 + 496 + return 0; 497 + }
+52
drivers/net/dsa/mv88e6xxx/port.h
··· 1 + /* 2 + * Marvell 88E6xxx Switch Port Registers support 3 + * 4 + * Copyright (c) 2008 Marvell Semiconductor 5 + * 6 + * Copyright (c) 2016 Vivien Didelot <vivien.didelot@savoirfairelinux.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License as published by 10 + * the Free Software Foundation; either version 2 of the License, or 11 + * (at your option) any later version. 12 + */ 13 + 14 + #ifndef _MV88E6XXX_PORT_H 15 + #define _MV88E6XXX_PORT_H 16 + 17 + #include "mv88e6xxx.h" 18 + 19 + int mv88e6xxx_port_read(struct mv88e6xxx_chip *chip, int port, int reg, 20 + u16 *val); 21 + int mv88e6xxx_port_write(struct mv88e6xxx_chip *chip, int port, int reg, 22 + u16 val); 23 + 24 + int mv88e6352_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 25 + phy_interface_t mode); 26 + int mv88e6390_port_set_rgmii_delay(struct mv88e6xxx_chip *chip, int port, 27 + phy_interface_t mode); 28 + 29 + int mv88e6xxx_port_set_link(struct mv88e6xxx_chip *chip, int port, int link); 30 + 31 + int mv88e6xxx_port_set_duplex(struct mv88e6xxx_chip *chip, int port, int dup); 32 + 33 + int mv88e6065_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); 34 + int mv88e6185_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); 35 + int mv88e6352_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); 36 + int mv88e6390_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); 37 + int mv88e6390x_port_set_speed(struct mv88e6xxx_chip *chip, int port, int speed); 38 + 39 + int mv88e6xxx_port_set_state(struct mv88e6xxx_chip *chip, int port, u8 state); 40 + 41 + int mv88e6xxx_port_set_vlan_map(struct mv88e6xxx_chip *chip, int port, u16 map); 42 + 43 + int mv88e6xxx_port_get_fid(struct mv88e6xxx_chip *chip, int port, u16 *fid); 44 + int mv88e6xxx_port_set_fid(struct mv88e6xxx_chip *chip, int port, u16 fid); 45 + 46 + int mv88e6xxx_port_get_pvid(struct mv88e6xxx_chip *chip, int port, u16 *pvid); 47 + int mv88e6xxx_port_set_pvid(struct mv88e6xxx_chip *chip, int port, u16 pvid); 48 + 49 + int mv88e6xxx_port_set_8021q_mode(struct mv88e6xxx_chip *chip, int port, 50 + u16 mode); 51 + 52 + #endif /* _MV88E6XXX_PORT_H */