1/* 2 * net/dsa/mv88e6xxx.c - Marvell 88e6xxx switch chip support 3 * Copyright (c) 2008 Marvell Semiconductor 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 */ 10 11#include <linux/delay.h> 12#include <linux/jiffies.h> 13#include <linux/list.h> 14#include <linux/module.h> 15#include <linux/netdevice.h> 16#include <linux/phy.h> 17#include <net/dsa.h> 18#include "mv88e6xxx.h" 19 20/* If the switch's ADDR[4:0] strap pins are strapped to zero, it will 21 * use all 32 SMI bus addresses on its SMI bus, and all switch registers 22 * will be directly accessible on some {device address,register address} 23 * pair. If the ADDR[4:0] pins are not strapped to zero, the switch 24 * will only respond to SMI transactions to that specific address, and 25 * an indirect addressing mechanism needs to be used to access its 26 * registers. 27 */ 28static int mv88e6xxx_reg_wait_ready(struct mii_bus *bus, int sw_addr) 29{ 30 int ret; 31 int i; 32 33 for (i = 0; i < 16; i++) { 34 ret = mdiobus_read(bus, sw_addr, 0); 35 if (ret < 0) 36 return ret; 37 38 if ((ret & 0x8000) == 0) 39 return 0; 40 } 41 42 return -ETIMEDOUT; 43} 44 45int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg) 46{ 47 int ret; 48 49 if (sw_addr == 0) 50 return mdiobus_read(bus, addr, reg); 51 52 /* Wait for the bus to become free. */ 53 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 54 if (ret < 0) 55 return ret; 56 57 /* Transmit the read command. */ 58 ret = mdiobus_write(bus, sw_addr, 0, 0x9800 | (addr << 5) | reg); 59 if (ret < 0) 60 return ret; 61 62 /* Wait for the read command to complete. */ 63 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 64 if (ret < 0) 65 return ret; 66 67 /* Read the data. */ 68 ret = mdiobus_read(bus, sw_addr, 1); 69 if (ret < 0) 70 return ret; 71 72 return ret & 0xffff; 73} 74 75int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg) 76{ 77 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 78 struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 79 int ret; 80 81 if (bus == NULL) 82 return -EINVAL; 83 84 mutex_lock(&ps->smi_mutex); 85 ret = __mv88e6xxx_reg_read(bus, ds->pd->sw_addr, addr, reg); 86 mutex_unlock(&ps->smi_mutex); 87 88 return ret; 89} 90 91int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr, 92 int reg, u16 val) 93{ 94 int ret; 95 96 if (sw_addr == 0) 97 return mdiobus_write(bus, addr, reg, val); 98 99 /* Wait for the bus to become free. */ 100 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 101 if (ret < 0) 102 return ret; 103 104 /* Transmit the data to write. */ 105 ret = mdiobus_write(bus, sw_addr, 1, val); 106 if (ret < 0) 107 return ret; 108 109 /* Transmit the write command. */ 110 ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg); 111 if (ret < 0) 112 return ret; 113 114 /* Wait for the write command to complete. */ 115 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 116 if (ret < 0) 117 return ret; 118 119 return 0; 120} 121 122int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) 123{ 124 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 125 struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 126 int ret; 127 128 if (bus == NULL) 129 return -EINVAL; 130 131 mutex_lock(&ps->smi_mutex); 132 ret = __mv88e6xxx_reg_write(bus, ds->pd->sw_addr, addr, reg, val); 133 mutex_unlock(&ps->smi_mutex); 134 135 return ret; 136} 137 138int mv88e6xxx_config_prio(struct dsa_switch *ds) 139{ 140 /* Configure the IP ToS mapping registers. */ 141 REG_WRITE(REG_GLOBAL, 0x10, 0x0000); 142 REG_WRITE(REG_GLOBAL, 0x11, 0x0000); 143 REG_WRITE(REG_GLOBAL, 0x12, 0x5555); 144 REG_WRITE(REG_GLOBAL, 0x13, 0x5555); 145 REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa); 146 REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa); 147 REG_WRITE(REG_GLOBAL, 0x16, 0xffff); 148 REG_WRITE(REG_GLOBAL, 0x17, 0xffff); 149 150 /* Configure the IEEE 802.1p priority mapping register. */ 151 REG_WRITE(REG_GLOBAL, 0x18, 0xfa41); 152 153 return 0; 154} 155 156int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) 157{ 158 REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]); 159 REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]); 160 REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]); 161 162 return 0; 163} 164 165int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) 166{ 167 int i; 168 int ret; 169 170 for (i = 0; i < 6; i++) { 171 int j; 172 173 /* Write the MAC address byte. */ 174 REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]); 175 176 /* Wait for the write to complete. */ 177 for (j = 0; j < 16; j++) { 178 ret = REG_READ(REG_GLOBAL2, 0x0d); 179 if ((ret & 0x8000) == 0) 180 break; 181 } 182 if (j == 16) 183 return -ETIMEDOUT; 184 } 185 186 return 0; 187} 188 189int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum) 190{ 191 if (addr >= 0) 192 return mv88e6xxx_reg_read(ds, addr, regnum); 193 return 0xffff; 194} 195 196int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val) 197{ 198 if (addr >= 0) 199 return mv88e6xxx_reg_write(ds, addr, regnum, val); 200 return 0; 201} 202 203#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU 204static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) 205{ 206 int ret; 207 unsigned long timeout; 208 209 ret = REG_READ(REG_GLOBAL, 0x04); 210 REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000); 211 212 timeout = jiffies + 1 * HZ; 213 while (time_before(jiffies, timeout)) { 214 ret = REG_READ(REG_GLOBAL, 0x00); 215 usleep_range(1000, 2000); 216 if ((ret & 0xc000) != 0xc000) 217 return 0; 218 } 219 220 return -ETIMEDOUT; 221} 222 223static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) 224{ 225 int ret; 226 unsigned long timeout; 227 228 ret = REG_READ(REG_GLOBAL, 0x04); 229 REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000); 230 231 timeout = jiffies + 1 * HZ; 232 while (time_before(jiffies, timeout)) { 233 ret = REG_READ(REG_GLOBAL, 0x00); 234 usleep_range(1000, 2000); 235 if ((ret & 0xc000) == 0xc000) 236 return 0; 237 } 238 239 return -ETIMEDOUT; 240} 241 242static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly) 243{ 244 struct mv88e6xxx_priv_state *ps; 245 246 ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work); 247 if (mutex_trylock(&ps->ppu_mutex)) { 248 struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1; 249 250 if (mv88e6xxx_ppu_enable(ds) == 0) 251 ps->ppu_disabled = 0; 252 mutex_unlock(&ps->ppu_mutex); 253 } 254} 255 256static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps) 257{ 258 struct mv88e6xxx_priv_state *ps = (void *)_ps; 259 260 schedule_work(&ps->ppu_work); 261} 262 263static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds) 264{ 265 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 266 int ret; 267 268 mutex_lock(&ps->ppu_mutex); 269 270 /* If the PHY polling unit is enabled, disable it so that 271 * we can access the PHY registers. If it was already 272 * disabled, cancel the timer that is going to re-enable 273 * it. 274 */ 275 if (!ps->ppu_disabled) { 276 ret = mv88e6xxx_ppu_disable(ds); 277 if (ret < 0) { 278 mutex_unlock(&ps->ppu_mutex); 279 return ret; 280 } 281 ps->ppu_disabled = 1; 282 } else { 283 del_timer(&ps->ppu_timer); 284 ret = 0; 285 } 286 287 return ret; 288} 289 290static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds) 291{ 292 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 293 294 /* Schedule a timer to re-enable the PHY polling unit. */ 295 mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10)); 296 mutex_unlock(&ps->ppu_mutex); 297} 298 299void mv88e6xxx_ppu_state_init(struct dsa_switch *ds) 300{ 301 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 302 303 mutex_init(&ps->ppu_mutex); 304 INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work); 305 init_timer(&ps->ppu_timer); 306 ps->ppu_timer.data = (unsigned long)ps; 307 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer; 308} 309 310int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) 311{ 312 int ret; 313 314 ret = mv88e6xxx_ppu_access_get(ds); 315 if (ret >= 0) { 316 ret = mv88e6xxx_reg_read(ds, addr, regnum); 317 mv88e6xxx_ppu_access_put(ds); 318 } 319 320 return ret; 321} 322 323int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, 324 int regnum, u16 val) 325{ 326 int ret; 327 328 ret = mv88e6xxx_ppu_access_get(ds); 329 if (ret >= 0) { 330 ret = mv88e6xxx_reg_write(ds, addr, regnum, val); 331 mv88e6xxx_ppu_access_put(ds); 332 } 333 334 return ret; 335} 336#endif 337 338void mv88e6xxx_poll_link(struct dsa_switch *ds) 339{ 340 int i; 341 342 for (i = 0; i < DSA_MAX_PORTS; i++) { 343 struct net_device *dev; 344 int uninitialized_var(port_status); 345 int link; 346 int speed; 347 int duplex; 348 int fc; 349 350 dev = ds->ports[i]; 351 if (dev == NULL) 352 continue; 353 354 link = 0; 355 if (dev->flags & IFF_UP) { 356 port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00); 357 if (port_status < 0) 358 continue; 359 360 link = !!(port_status & 0x0800); 361 } 362 363 if (!link) { 364 if (netif_carrier_ok(dev)) { 365 netdev_info(dev, "link down\n"); 366 netif_carrier_off(dev); 367 } 368 continue; 369 } 370 371 switch (port_status & 0x0300) { 372 case 0x0000: 373 speed = 10; 374 break; 375 case 0x0100: 376 speed = 100; 377 break; 378 case 0x0200: 379 speed = 1000; 380 break; 381 default: 382 speed = -1; 383 break; 384 } 385 duplex = (port_status & 0x0400) ? 1 : 0; 386 fc = (port_status & 0x8000) ? 1 : 0; 387 388 if (!netif_carrier_ok(dev)) { 389 netdev_info(dev, 390 "link up, %d Mb/s, %s duplex, flow control %sabled\n", 391 speed, 392 duplex ? "full" : "half", 393 fc ? "en" : "dis"); 394 netif_carrier_on(dev); 395 } 396 } 397} 398 399static int mv88e6xxx_stats_wait(struct dsa_switch *ds) 400{ 401 int ret; 402 int i; 403 404 for (i = 0; i < 10; i++) { 405 ret = REG_READ(REG_GLOBAL, 0x1d); 406 if ((ret & 0x8000) == 0) 407 return 0; 408 } 409 410 return -ETIMEDOUT; 411} 412 413static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port) 414{ 415 int ret; 416 417 /* Snapshot the hardware statistics counters for this port. */ 418 REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port); 419 420 /* Wait for the snapshotting to complete. */ 421 ret = mv88e6xxx_stats_wait(ds); 422 if (ret < 0) 423 return ret; 424 425 return 0; 426} 427 428static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val) 429{ 430 u32 _val; 431 int ret; 432 433 *val = 0; 434 435 ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat); 436 if (ret < 0) 437 return; 438 439 ret = mv88e6xxx_stats_wait(ds); 440 if (ret < 0) 441 return; 442 443 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e); 444 if (ret < 0) 445 return; 446 447 _val = ret << 16; 448 449 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f); 450 if (ret < 0) 451 return; 452 453 *val = _val | ret; 454} 455 456void mv88e6xxx_get_strings(struct dsa_switch *ds, 457 int nr_stats, struct mv88e6xxx_hw_stat *stats, 458 int port, uint8_t *data) 459{ 460 int i; 461 462 for (i = 0; i < nr_stats; i++) { 463 memcpy(data + i * ETH_GSTRING_LEN, 464 stats[i].string, ETH_GSTRING_LEN); 465 } 466} 467 468void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, 469 int nr_stats, struct mv88e6xxx_hw_stat *stats, 470 int port, uint64_t *data) 471{ 472 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 473 int ret; 474 int i; 475 476 mutex_lock(&ps->stats_mutex); 477 478 ret = mv88e6xxx_stats_snapshot(ds, port); 479 if (ret < 0) { 480 mutex_unlock(&ps->stats_mutex); 481 return; 482 } 483 484 /* Read each of the counters. */ 485 for (i = 0; i < nr_stats; i++) { 486 struct mv88e6xxx_hw_stat *s = stats + i; 487 u32 low; 488 u32 high; 489 490 mv88e6xxx_stats_read(ds, s->reg, &low); 491 if (s->sizeof_stat == 8) 492 mv88e6xxx_stats_read(ds, s->reg + 1, &high); 493 else 494 high = 0; 495 496 data[i] = (((u64)high) << 32) | low; 497 } 498 499 mutex_unlock(&ps->stats_mutex); 500} 501 502static int __init mv88e6xxx_init(void) 503{ 504#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 505 register_switch_driver(&mv88e6131_switch_driver); 506#endif 507#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) 508 register_switch_driver(&mv88e6123_61_65_switch_driver); 509#endif 510#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 511 register_switch_driver(&mv88e6171_switch_driver); 512#endif 513 return 0; 514} 515module_init(mv88e6xxx_init); 516 517static void __exit mv88e6xxx_cleanup(void) 518{ 519#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 520 unregister_switch_driver(&mv88e6171_switch_driver); 521#endif 522#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) 523 unregister_switch_driver(&mv88e6123_61_65_switch_driver); 524#endif 525#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 526 unregister_switch_driver(&mv88e6131_switch_driver); 527#endif 528} 529module_exit(mv88e6xxx_cleanup); 530 531MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 532MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); 533MODULE_LICENSE("GPL"); 534