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