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

Configure Feed

Select the types of activity you want to include in your feed.

at v4.0 633 lines 14 kB view raw
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 if (ret < 0) 89 return ret; 90 91 dev_dbg(ds->master_dev, "<- addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", 92 addr, reg, ret); 93 94 return ret; 95} 96 97int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr, 98 int reg, u16 val) 99{ 100 int ret; 101 102 if (sw_addr == 0) 103 return mdiobus_write(bus, addr, reg, val); 104 105 /* Wait for the bus to become free. */ 106 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 107 if (ret < 0) 108 return ret; 109 110 /* Transmit the data to write. */ 111 ret = mdiobus_write(bus, sw_addr, 1, val); 112 if (ret < 0) 113 return ret; 114 115 /* Transmit the write command. */ 116 ret = mdiobus_write(bus, sw_addr, 0, 0x9400 | (addr << 5) | reg); 117 if (ret < 0) 118 return ret; 119 120 /* Wait for the write command to complete. */ 121 ret = mv88e6xxx_reg_wait_ready(bus, sw_addr); 122 if (ret < 0) 123 return ret; 124 125 return 0; 126} 127 128int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val) 129{ 130 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 131 struct mii_bus *bus = dsa_host_dev_to_mii_bus(ds->master_dev); 132 int ret; 133 134 if (bus == NULL) 135 return -EINVAL; 136 137 dev_dbg(ds->master_dev, "-> addr: 0x%.2x reg: 0x%.2x val: 0x%.4x\n", 138 addr, reg, val); 139 140 mutex_lock(&ps->smi_mutex); 141 ret = __mv88e6xxx_reg_write(bus, 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 /* Configure the IP ToS mapping registers. */ 150 REG_WRITE(REG_GLOBAL, 0x10, 0x0000); 151 REG_WRITE(REG_GLOBAL, 0x11, 0x0000); 152 REG_WRITE(REG_GLOBAL, 0x12, 0x5555); 153 REG_WRITE(REG_GLOBAL, 0x13, 0x5555); 154 REG_WRITE(REG_GLOBAL, 0x14, 0xaaaa); 155 REG_WRITE(REG_GLOBAL, 0x15, 0xaaaa); 156 REG_WRITE(REG_GLOBAL, 0x16, 0xffff); 157 REG_WRITE(REG_GLOBAL, 0x17, 0xffff); 158 159 /* Configure the IEEE 802.1p priority mapping register. */ 160 REG_WRITE(REG_GLOBAL, 0x18, 0xfa41); 161 162 return 0; 163} 164 165int mv88e6xxx_set_addr_direct(struct dsa_switch *ds, u8 *addr) 166{ 167 REG_WRITE(REG_GLOBAL, 0x01, (addr[0] << 8) | addr[1]); 168 REG_WRITE(REG_GLOBAL, 0x02, (addr[2] << 8) | addr[3]); 169 REG_WRITE(REG_GLOBAL, 0x03, (addr[4] << 8) | addr[5]); 170 171 return 0; 172} 173 174int mv88e6xxx_set_addr_indirect(struct dsa_switch *ds, u8 *addr) 175{ 176 int i; 177 int ret; 178 179 for (i = 0; i < 6; i++) { 180 int j; 181 182 /* Write the MAC address byte. */ 183 REG_WRITE(REG_GLOBAL2, 0x0d, 0x8000 | (i << 8) | addr[i]); 184 185 /* Wait for the write to complete. */ 186 for (j = 0; j < 16; j++) { 187 ret = REG_READ(REG_GLOBAL2, 0x0d); 188 if ((ret & 0x8000) == 0) 189 break; 190 } 191 if (j == 16) 192 return -ETIMEDOUT; 193 } 194 195 return 0; 196} 197 198int mv88e6xxx_phy_read(struct dsa_switch *ds, int addr, int regnum) 199{ 200 if (addr >= 0) 201 return mv88e6xxx_reg_read(ds, addr, regnum); 202 return 0xffff; 203} 204 205int mv88e6xxx_phy_write(struct dsa_switch *ds, int addr, int regnum, u16 val) 206{ 207 if (addr >= 0) 208 return mv88e6xxx_reg_write(ds, addr, regnum, val); 209 return 0; 210} 211 212#ifdef CONFIG_NET_DSA_MV88E6XXX_NEED_PPU 213static int mv88e6xxx_ppu_disable(struct dsa_switch *ds) 214{ 215 int ret; 216 unsigned long timeout; 217 218 ret = REG_READ(REG_GLOBAL, 0x04); 219 REG_WRITE(REG_GLOBAL, 0x04, ret & ~0x4000); 220 221 timeout = jiffies + 1 * HZ; 222 while (time_before(jiffies, timeout)) { 223 ret = REG_READ(REG_GLOBAL, 0x00); 224 usleep_range(1000, 2000); 225 if ((ret & 0xc000) != 0xc000) 226 return 0; 227 } 228 229 return -ETIMEDOUT; 230} 231 232static int mv88e6xxx_ppu_enable(struct dsa_switch *ds) 233{ 234 int ret; 235 unsigned long timeout; 236 237 ret = REG_READ(REG_GLOBAL, 0x04); 238 REG_WRITE(REG_GLOBAL, 0x04, ret | 0x4000); 239 240 timeout = jiffies + 1 * HZ; 241 while (time_before(jiffies, timeout)) { 242 ret = REG_READ(REG_GLOBAL, 0x00); 243 usleep_range(1000, 2000); 244 if ((ret & 0xc000) == 0xc000) 245 return 0; 246 } 247 248 return -ETIMEDOUT; 249} 250 251static void mv88e6xxx_ppu_reenable_work(struct work_struct *ugly) 252{ 253 struct mv88e6xxx_priv_state *ps; 254 255 ps = container_of(ugly, struct mv88e6xxx_priv_state, ppu_work); 256 if (mutex_trylock(&ps->ppu_mutex)) { 257 struct dsa_switch *ds = ((struct dsa_switch *)ps) - 1; 258 259 if (mv88e6xxx_ppu_enable(ds) == 0) 260 ps->ppu_disabled = 0; 261 mutex_unlock(&ps->ppu_mutex); 262 } 263} 264 265static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps) 266{ 267 struct mv88e6xxx_priv_state *ps = (void *)_ps; 268 269 schedule_work(&ps->ppu_work); 270} 271 272static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds) 273{ 274 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 275 int ret; 276 277 mutex_lock(&ps->ppu_mutex); 278 279 /* If the PHY polling unit is enabled, disable it so that 280 * we can access the PHY registers. If it was already 281 * disabled, cancel the timer that is going to re-enable 282 * it. 283 */ 284 if (!ps->ppu_disabled) { 285 ret = mv88e6xxx_ppu_disable(ds); 286 if (ret < 0) { 287 mutex_unlock(&ps->ppu_mutex); 288 return ret; 289 } 290 ps->ppu_disabled = 1; 291 } else { 292 del_timer(&ps->ppu_timer); 293 ret = 0; 294 } 295 296 return ret; 297} 298 299static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds) 300{ 301 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 302 303 /* Schedule a timer to re-enable the PHY polling unit. */ 304 mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10)); 305 mutex_unlock(&ps->ppu_mutex); 306} 307 308void mv88e6xxx_ppu_state_init(struct dsa_switch *ds) 309{ 310 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 311 312 mutex_init(&ps->ppu_mutex); 313 INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work); 314 init_timer(&ps->ppu_timer); 315 ps->ppu_timer.data = (unsigned long)ps; 316 ps->ppu_timer.function = mv88e6xxx_ppu_reenable_timer; 317} 318 319int mv88e6xxx_phy_read_ppu(struct dsa_switch *ds, int addr, int regnum) 320{ 321 int ret; 322 323 ret = mv88e6xxx_ppu_access_get(ds); 324 if (ret >= 0) { 325 ret = mv88e6xxx_reg_read(ds, addr, regnum); 326 mv88e6xxx_ppu_access_put(ds); 327 } 328 329 return ret; 330} 331 332int mv88e6xxx_phy_write_ppu(struct dsa_switch *ds, int addr, 333 int regnum, u16 val) 334{ 335 int ret; 336 337 ret = mv88e6xxx_ppu_access_get(ds); 338 if (ret >= 0) { 339 ret = mv88e6xxx_reg_write(ds, addr, regnum, val); 340 mv88e6xxx_ppu_access_put(ds); 341 } 342 343 return ret; 344} 345#endif 346 347void mv88e6xxx_poll_link(struct dsa_switch *ds) 348{ 349 int i; 350 351 for (i = 0; i < DSA_MAX_PORTS; i++) { 352 struct net_device *dev; 353 int uninitialized_var(port_status); 354 int link; 355 int speed; 356 int duplex; 357 int fc; 358 359 dev = ds->ports[i]; 360 if (dev == NULL) 361 continue; 362 363 link = 0; 364 if (dev->flags & IFF_UP) { 365 port_status = mv88e6xxx_reg_read(ds, REG_PORT(i), 0x00); 366 if (port_status < 0) 367 continue; 368 369 link = !!(port_status & 0x0800); 370 } 371 372 if (!link) { 373 if (netif_carrier_ok(dev)) { 374 netdev_info(dev, "link down\n"); 375 netif_carrier_off(dev); 376 } 377 continue; 378 } 379 380 switch (port_status & 0x0300) { 381 case 0x0000: 382 speed = 10; 383 break; 384 case 0x0100: 385 speed = 100; 386 break; 387 case 0x0200: 388 speed = 1000; 389 break; 390 default: 391 speed = -1; 392 break; 393 } 394 duplex = (port_status & 0x0400) ? 1 : 0; 395 fc = (port_status & 0x8000) ? 1 : 0; 396 397 if (!netif_carrier_ok(dev)) { 398 netdev_info(dev, 399 "link up, %d Mb/s, %s duplex, flow control %sabled\n", 400 speed, 401 duplex ? "full" : "half", 402 fc ? "en" : "dis"); 403 netif_carrier_on(dev); 404 } 405 } 406} 407 408static int mv88e6xxx_stats_wait(struct dsa_switch *ds) 409{ 410 int ret; 411 int i; 412 413 for (i = 0; i < 10; i++) { 414 ret = REG_READ(REG_GLOBAL, 0x1d); 415 if ((ret & 0x8000) == 0) 416 return 0; 417 } 418 419 return -ETIMEDOUT; 420} 421 422static int mv88e6xxx_stats_snapshot(struct dsa_switch *ds, int port) 423{ 424 int ret; 425 426 /* Snapshot the hardware statistics counters for this port. */ 427 REG_WRITE(REG_GLOBAL, 0x1d, 0xdc00 | port); 428 429 /* Wait for the snapshotting to complete. */ 430 ret = mv88e6xxx_stats_wait(ds); 431 if (ret < 0) 432 return ret; 433 434 return 0; 435} 436 437static void mv88e6xxx_stats_read(struct dsa_switch *ds, int stat, u32 *val) 438{ 439 u32 _val; 440 int ret; 441 442 *val = 0; 443 444 ret = mv88e6xxx_reg_write(ds, REG_GLOBAL, 0x1d, 0xcc00 | stat); 445 if (ret < 0) 446 return; 447 448 ret = mv88e6xxx_stats_wait(ds); 449 if (ret < 0) 450 return; 451 452 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1e); 453 if (ret < 0) 454 return; 455 456 _val = ret << 16; 457 458 ret = mv88e6xxx_reg_read(ds, REG_GLOBAL, 0x1f); 459 if (ret < 0) 460 return; 461 462 *val = _val | ret; 463} 464 465void mv88e6xxx_get_strings(struct dsa_switch *ds, 466 int nr_stats, struct mv88e6xxx_hw_stat *stats, 467 int port, uint8_t *data) 468{ 469 int i; 470 471 for (i = 0; i < nr_stats; i++) { 472 memcpy(data + i * ETH_GSTRING_LEN, 473 stats[i].string, ETH_GSTRING_LEN); 474 } 475} 476 477void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds, 478 int nr_stats, struct mv88e6xxx_hw_stat *stats, 479 int port, uint64_t *data) 480{ 481 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 482 int ret; 483 int i; 484 485 mutex_lock(&ps->stats_mutex); 486 487 ret = mv88e6xxx_stats_snapshot(ds, port); 488 if (ret < 0) { 489 mutex_unlock(&ps->stats_mutex); 490 return; 491 } 492 493 /* Read each of the counters. */ 494 for (i = 0; i < nr_stats; i++) { 495 struct mv88e6xxx_hw_stat *s = stats + i; 496 u32 low; 497 u32 high = 0; 498 499 if (s->reg >= 0x100) { 500 int ret; 501 502 ret = mv88e6xxx_reg_read(ds, REG_PORT(port), 503 s->reg - 0x100); 504 if (ret < 0) 505 goto error; 506 low = ret; 507 if (s->sizeof_stat == 4) { 508 ret = mv88e6xxx_reg_read(ds, REG_PORT(port), 509 s->reg - 0x100 + 1); 510 if (ret < 0) 511 goto error; 512 high = ret; 513 } 514 data[i] = (((u64)high) << 16) | low; 515 continue; 516 } 517 mv88e6xxx_stats_read(ds, s->reg, &low); 518 if (s->sizeof_stat == 8) 519 mv88e6xxx_stats_read(ds, s->reg + 1, &high); 520 521 data[i] = (((u64)high) << 32) | low; 522 } 523error: 524 mutex_unlock(&ps->stats_mutex); 525} 526 527int mv88e6xxx_get_regs_len(struct dsa_switch *ds, int port) 528{ 529 return 32 * sizeof(u16); 530} 531 532void mv88e6xxx_get_regs(struct dsa_switch *ds, int port, 533 struct ethtool_regs *regs, void *_p) 534{ 535 u16 *p = _p; 536 int i; 537 538 regs->version = 0; 539 540 memset(p, 0xff, 32 * sizeof(u16)); 541 542 for (i = 0; i < 32; i++) { 543 int ret; 544 545 ret = mv88e6xxx_reg_read(ds, REG_PORT(port), i); 546 if (ret >= 0) 547 p[i] = ret; 548 } 549} 550 551#ifdef CONFIG_NET_DSA_HWMON 552 553int mv88e6xxx_get_temp(struct dsa_switch *ds, int *temp) 554{ 555 struct mv88e6xxx_priv_state *ps = ds_to_priv(ds); 556 int ret; 557 int val; 558 559 *temp = 0; 560 561 mutex_lock(&ps->phy_mutex); 562 563 ret = mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x6); 564 if (ret < 0) 565 goto error; 566 567 /* Enable temperature sensor */ 568 ret = mv88e6xxx_phy_read(ds, 0x0, 0x1a); 569 if (ret < 0) 570 goto error; 571 572 ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret | (1 << 5)); 573 if (ret < 0) 574 goto error; 575 576 /* Wait for temperature to stabilize */ 577 usleep_range(10000, 12000); 578 579 val = mv88e6xxx_phy_read(ds, 0x0, 0x1a); 580 if (val < 0) { 581 ret = val; 582 goto error; 583 } 584 585 /* Disable temperature sensor */ 586 ret = mv88e6xxx_phy_write(ds, 0x0, 0x1a, ret & ~(1 << 5)); 587 if (ret < 0) 588 goto error; 589 590 *temp = ((val & 0x1f) - 5) * 5; 591 592error: 593 mv88e6xxx_phy_write(ds, 0x0, 0x16, 0x0); 594 mutex_unlock(&ps->phy_mutex); 595 return ret; 596} 597#endif /* CONFIG_NET_DSA_HWMON */ 598 599static int __init mv88e6xxx_init(void) 600{ 601#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 602 register_switch_driver(&mv88e6131_switch_driver); 603#endif 604#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) 605 register_switch_driver(&mv88e6123_61_65_switch_driver); 606#endif 607#if IS_ENABLED(CONFIG_NET_DSA_MV88E6352) 608 register_switch_driver(&mv88e6352_switch_driver); 609#endif 610#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 611 register_switch_driver(&mv88e6171_switch_driver); 612#endif 613 return 0; 614} 615module_init(mv88e6xxx_init); 616 617static void __exit mv88e6xxx_cleanup(void) 618{ 619#if IS_ENABLED(CONFIG_NET_DSA_MV88E6171) 620 unregister_switch_driver(&mv88e6171_switch_driver); 621#endif 622#if IS_ENABLED(CONFIG_NET_DSA_MV88E6123_61_65) 623 unregister_switch_driver(&mv88e6123_61_65_switch_driver); 624#endif 625#if IS_ENABLED(CONFIG_NET_DSA_MV88E6131) 626 unregister_switch_driver(&mv88e6131_switch_driver); 627#endif 628} 629module_exit(mv88e6xxx_cleanup); 630 631MODULE_AUTHOR("Lennert Buytenhek <buytenh@wantstofly.org>"); 632MODULE_DESCRIPTION("Driver for Marvell 88E6XXX ethernet switch chips"); 633MODULE_LICENSE("GPL");