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.16-rc5 955 lines 24 kB view raw
1/* 2 * Copyright (C) 2009 Felix Fietkau <nbd@nbd.name> 3 * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org> 4 * Copyright (c) 2015, The Linux Foundation. All rights reserved. 5 * Copyright (c) 2016 John Crispin <john@phrozen.org> 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 and 9 * only version 2 as published by the Free Software Foundation. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 */ 16 17#include <linux/module.h> 18#include <linux/phy.h> 19#include <linux/netdevice.h> 20#include <net/dsa.h> 21#include <linux/of_net.h> 22#include <linux/of_platform.h> 23#include <linux/if_bridge.h> 24#include <linux/mdio.h> 25#include <linux/etherdevice.h> 26 27#include "qca8k.h" 28 29#define MIB_DESC(_s, _o, _n) \ 30 { \ 31 .size = (_s), \ 32 .offset = (_o), \ 33 .name = (_n), \ 34 } 35 36static const struct qca8k_mib_desc ar8327_mib[] = { 37 MIB_DESC(1, 0x00, "RxBroad"), 38 MIB_DESC(1, 0x04, "RxPause"), 39 MIB_DESC(1, 0x08, "RxMulti"), 40 MIB_DESC(1, 0x0c, "RxFcsErr"), 41 MIB_DESC(1, 0x10, "RxAlignErr"), 42 MIB_DESC(1, 0x14, "RxRunt"), 43 MIB_DESC(1, 0x18, "RxFragment"), 44 MIB_DESC(1, 0x1c, "Rx64Byte"), 45 MIB_DESC(1, 0x20, "Rx128Byte"), 46 MIB_DESC(1, 0x24, "Rx256Byte"), 47 MIB_DESC(1, 0x28, "Rx512Byte"), 48 MIB_DESC(1, 0x2c, "Rx1024Byte"), 49 MIB_DESC(1, 0x30, "Rx1518Byte"), 50 MIB_DESC(1, 0x34, "RxMaxByte"), 51 MIB_DESC(1, 0x38, "RxTooLong"), 52 MIB_DESC(2, 0x3c, "RxGoodByte"), 53 MIB_DESC(2, 0x44, "RxBadByte"), 54 MIB_DESC(1, 0x4c, "RxOverFlow"), 55 MIB_DESC(1, 0x50, "Filtered"), 56 MIB_DESC(1, 0x54, "TxBroad"), 57 MIB_DESC(1, 0x58, "TxPause"), 58 MIB_DESC(1, 0x5c, "TxMulti"), 59 MIB_DESC(1, 0x60, "TxUnderRun"), 60 MIB_DESC(1, 0x64, "Tx64Byte"), 61 MIB_DESC(1, 0x68, "Tx128Byte"), 62 MIB_DESC(1, 0x6c, "Tx256Byte"), 63 MIB_DESC(1, 0x70, "Tx512Byte"), 64 MIB_DESC(1, 0x74, "Tx1024Byte"), 65 MIB_DESC(1, 0x78, "Tx1518Byte"), 66 MIB_DESC(1, 0x7c, "TxMaxByte"), 67 MIB_DESC(1, 0x80, "TxOverSize"), 68 MIB_DESC(2, 0x84, "TxByte"), 69 MIB_DESC(1, 0x8c, "TxCollision"), 70 MIB_DESC(1, 0x90, "TxAbortCol"), 71 MIB_DESC(1, 0x94, "TxMultiCol"), 72 MIB_DESC(1, 0x98, "TxSingleCol"), 73 MIB_DESC(1, 0x9c, "TxExcDefer"), 74 MIB_DESC(1, 0xa0, "TxDefer"), 75 MIB_DESC(1, 0xa4, "TxLateCol"), 76}; 77 78/* The 32bit switch registers are accessed indirectly. To achieve this we need 79 * to set the page of the register. Track the last page that was set to reduce 80 * mdio writes 81 */ 82static u16 qca8k_current_page = 0xffff; 83 84static void 85qca8k_split_addr(u32 regaddr, u16 *r1, u16 *r2, u16 *page) 86{ 87 regaddr >>= 1; 88 *r1 = regaddr & 0x1e; 89 90 regaddr >>= 5; 91 *r2 = regaddr & 0x7; 92 93 regaddr >>= 3; 94 *page = regaddr & 0x3ff; 95} 96 97static u32 98qca8k_mii_read32(struct mii_bus *bus, int phy_id, u32 regnum) 99{ 100 u32 val; 101 int ret; 102 103 ret = bus->read(bus, phy_id, regnum); 104 if (ret >= 0) { 105 val = ret; 106 ret = bus->read(bus, phy_id, regnum + 1); 107 val |= ret << 16; 108 } 109 110 if (ret < 0) { 111 dev_err_ratelimited(&bus->dev, 112 "failed to read qca8k 32bit register\n"); 113 return ret; 114 } 115 116 return val; 117} 118 119static void 120qca8k_mii_write32(struct mii_bus *bus, int phy_id, u32 regnum, u32 val) 121{ 122 u16 lo, hi; 123 int ret; 124 125 lo = val & 0xffff; 126 hi = (u16)(val >> 16); 127 128 ret = bus->write(bus, phy_id, regnum, lo); 129 if (ret >= 0) 130 ret = bus->write(bus, phy_id, regnum + 1, hi); 131 if (ret < 0) 132 dev_err_ratelimited(&bus->dev, 133 "failed to write qca8k 32bit register\n"); 134} 135 136static void 137qca8k_set_page(struct mii_bus *bus, u16 page) 138{ 139 if (page == qca8k_current_page) 140 return; 141 142 if (bus->write(bus, 0x18, 0, page) < 0) 143 dev_err_ratelimited(&bus->dev, 144 "failed to set qca8k page\n"); 145 qca8k_current_page = page; 146} 147 148static u32 149qca8k_read(struct qca8k_priv *priv, u32 reg) 150{ 151 u16 r1, r2, page; 152 u32 val; 153 154 qca8k_split_addr(reg, &r1, &r2, &page); 155 156 mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); 157 158 qca8k_set_page(priv->bus, page); 159 val = qca8k_mii_read32(priv->bus, 0x10 | r2, r1); 160 161 mutex_unlock(&priv->bus->mdio_lock); 162 163 return val; 164} 165 166static void 167qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val) 168{ 169 u16 r1, r2, page; 170 171 qca8k_split_addr(reg, &r1, &r2, &page); 172 173 mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); 174 175 qca8k_set_page(priv->bus, page); 176 qca8k_mii_write32(priv->bus, 0x10 | r2, r1, val); 177 178 mutex_unlock(&priv->bus->mdio_lock); 179} 180 181static u32 182qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 val) 183{ 184 u16 r1, r2, page; 185 u32 ret; 186 187 qca8k_split_addr(reg, &r1, &r2, &page); 188 189 mutex_lock_nested(&priv->bus->mdio_lock, MDIO_MUTEX_NESTED); 190 191 qca8k_set_page(priv->bus, page); 192 ret = qca8k_mii_read32(priv->bus, 0x10 | r2, r1); 193 ret &= ~mask; 194 ret |= val; 195 qca8k_mii_write32(priv->bus, 0x10 | r2, r1, ret); 196 197 mutex_unlock(&priv->bus->mdio_lock); 198 199 return ret; 200} 201 202static void 203qca8k_reg_set(struct qca8k_priv *priv, u32 reg, u32 val) 204{ 205 qca8k_rmw(priv, reg, 0, val); 206} 207 208static void 209qca8k_reg_clear(struct qca8k_priv *priv, u32 reg, u32 val) 210{ 211 qca8k_rmw(priv, reg, val, 0); 212} 213 214static int 215qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) 216{ 217 struct qca8k_priv *priv = (struct qca8k_priv *)ctx; 218 219 *val = qca8k_read(priv, reg); 220 221 return 0; 222} 223 224static int 225qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) 226{ 227 struct qca8k_priv *priv = (struct qca8k_priv *)ctx; 228 229 qca8k_write(priv, reg, val); 230 231 return 0; 232} 233 234static const struct regmap_range qca8k_readable_ranges[] = { 235 regmap_reg_range(0x0000, 0x00e4), /* Global control */ 236 regmap_reg_range(0x0100, 0x0168), /* EEE control */ 237 regmap_reg_range(0x0200, 0x0270), /* Parser control */ 238 regmap_reg_range(0x0400, 0x0454), /* ACL */ 239 regmap_reg_range(0x0600, 0x0718), /* Lookup */ 240 regmap_reg_range(0x0800, 0x0b70), /* QM */ 241 regmap_reg_range(0x0c00, 0x0c80), /* PKT */ 242 regmap_reg_range(0x0e00, 0x0e98), /* L3 */ 243 regmap_reg_range(0x1000, 0x10ac), /* MIB - Port0 */ 244 regmap_reg_range(0x1100, 0x11ac), /* MIB - Port1 */ 245 regmap_reg_range(0x1200, 0x12ac), /* MIB - Port2 */ 246 regmap_reg_range(0x1300, 0x13ac), /* MIB - Port3 */ 247 regmap_reg_range(0x1400, 0x14ac), /* MIB - Port4 */ 248 regmap_reg_range(0x1500, 0x15ac), /* MIB - Port5 */ 249 regmap_reg_range(0x1600, 0x16ac), /* MIB - Port6 */ 250 251}; 252 253static const struct regmap_access_table qca8k_readable_table = { 254 .yes_ranges = qca8k_readable_ranges, 255 .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), 256}; 257 258static struct regmap_config qca8k_regmap_config = { 259 .reg_bits = 16, 260 .val_bits = 32, 261 .reg_stride = 4, 262 .max_register = 0x16ac, /* end MIB - Port6 range */ 263 .reg_read = qca8k_regmap_read, 264 .reg_write = qca8k_regmap_write, 265 .rd_table = &qca8k_readable_table, 266}; 267 268static int 269qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) 270{ 271 unsigned long timeout; 272 273 timeout = jiffies + msecs_to_jiffies(20); 274 275 /* loop until the busy flag has cleared */ 276 do { 277 u32 val = qca8k_read(priv, reg); 278 int busy = val & mask; 279 280 if (!busy) 281 break; 282 cond_resched(); 283 } while (!time_after_eq(jiffies, timeout)); 284 285 return time_after_eq(jiffies, timeout); 286} 287 288static void 289qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb) 290{ 291 u32 reg[4]; 292 int i; 293 294 /* load the ARL table into an array */ 295 for (i = 0; i < 4; i++) 296 reg[i] = qca8k_read(priv, QCA8K_REG_ATU_DATA0 + (i * 4)); 297 298 /* vid - 83:72 */ 299 fdb->vid = (reg[2] >> QCA8K_ATU_VID_S) & QCA8K_ATU_VID_M; 300 /* aging - 67:64 */ 301 fdb->aging = reg[2] & QCA8K_ATU_STATUS_M; 302 /* portmask - 54:48 */ 303 fdb->port_mask = (reg[1] >> QCA8K_ATU_PORT_S) & QCA8K_ATU_PORT_M; 304 /* mac - 47:0 */ 305 fdb->mac[0] = (reg[1] >> QCA8K_ATU_ADDR0_S) & 0xff; 306 fdb->mac[1] = reg[1] & 0xff; 307 fdb->mac[2] = (reg[0] >> QCA8K_ATU_ADDR2_S) & 0xff; 308 fdb->mac[3] = (reg[0] >> QCA8K_ATU_ADDR3_S) & 0xff; 309 fdb->mac[4] = (reg[0] >> QCA8K_ATU_ADDR4_S) & 0xff; 310 fdb->mac[5] = reg[0] & 0xff; 311} 312 313static void 314qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask, const u8 *mac, 315 u8 aging) 316{ 317 u32 reg[3] = { 0 }; 318 int i; 319 320 /* vid - 83:72 */ 321 reg[2] = (vid & QCA8K_ATU_VID_M) << QCA8K_ATU_VID_S; 322 /* aging - 67:64 */ 323 reg[2] |= aging & QCA8K_ATU_STATUS_M; 324 /* portmask - 54:48 */ 325 reg[1] = (port_mask & QCA8K_ATU_PORT_M) << QCA8K_ATU_PORT_S; 326 /* mac - 47:0 */ 327 reg[1] |= mac[0] << QCA8K_ATU_ADDR0_S; 328 reg[1] |= mac[1]; 329 reg[0] |= mac[2] << QCA8K_ATU_ADDR2_S; 330 reg[0] |= mac[3] << QCA8K_ATU_ADDR3_S; 331 reg[0] |= mac[4] << QCA8K_ATU_ADDR4_S; 332 reg[0] |= mac[5]; 333 334 /* load the array into the ARL table */ 335 for (i = 0; i < 3; i++) 336 qca8k_write(priv, QCA8K_REG_ATU_DATA0 + (i * 4), reg[i]); 337} 338 339static int 340qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd, int port) 341{ 342 u32 reg; 343 344 /* Set the command and FDB index */ 345 reg = QCA8K_ATU_FUNC_BUSY; 346 reg |= cmd; 347 if (port >= 0) { 348 reg |= QCA8K_ATU_FUNC_PORT_EN; 349 reg |= (port & QCA8K_ATU_FUNC_PORT_M) << QCA8K_ATU_FUNC_PORT_S; 350 } 351 352 /* Write the function register triggering the table access */ 353 qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg); 354 355 /* wait for completion */ 356 if (qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY)) 357 return -1; 358 359 /* Check for table full violation when adding an entry */ 360 if (cmd == QCA8K_FDB_LOAD) { 361 reg = qca8k_read(priv, QCA8K_REG_ATU_FUNC); 362 if (reg & QCA8K_ATU_FUNC_FULL) 363 return -1; 364 } 365 366 return 0; 367} 368 369static int 370qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb, int port) 371{ 372 int ret; 373 374 qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging); 375 ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port); 376 if (ret >= 0) 377 qca8k_fdb_read(priv, fdb); 378 379 return ret; 380} 381 382static int 383qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, 384 u16 vid, u8 aging) 385{ 386 int ret; 387 388 mutex_lock(&priv->reg_mutex); 389 qca8k_fdb_write(priv, vid, port_mask, mac, aging); 390 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1); 391 mutex_unlock(&priv->reg_mutex); 392 393 return ret; 394} 395 396static int 397qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac, u16 port_mask, u16 vid) 398{ 399 int ret; 400 401 mutex_lock(&priv->reg_mutex); 402 qca8k_fdb_write(priv, vid, port_mask, mac, 0); 403 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1); 404 mutex_unlock(&priv->reg_mutex); 405 406 return ret; 407} 408 409static void 410qca8k_fdb_flush(struct qca8k_priv *priv) 411{ 412 mutex_lock(&priv->reg_mutex); 413 qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1); 414 mutex_unlock(&priv->reg_mutex); 415} 416 417static void 418qca8k_mib_init(struct qca8k_priv *priv) 419{ 420 mutex_lock(&priv->reg_mutex); 421 qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_FLUSH | QCA8K_MIB_BUSY); 422 qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY); 423 qca8k_reg_set(priv, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP); 424 qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB); 425 mutex_unlock(&priv->reg_mutex); 426} 427 428static int 429qca8k_set_pad_ctrl(struct qca8k_priv *priv, int port, int mode) 430{ 431 u32 reg; 432 433 switch (port) { 434 case 0: 435 reg = QCA8K_REG_PORT0_PAD_CTRL; 436 break; 437 case 6: 438 reg = QCA8K_REG_PORT6_PAD_CTRL; 439 break; 440 default: 441 pr_err("Can't set PAD_CTRL on port %d\n", port); 442 return -EINVAL; 443 } 444 445 /* Configure a port to be directly connected to an external 446 * PHY or MAC. 447 */ 448 switch (mode) { 449 case PHY_INTERFACE_MODE_RGMII: 450 qca8k_write(priv, reg, 451 QCA8K_PORT_PAD_RGMII_EN | 452 QCA8K_PORT_PAD_RGMII_TX_DELAY(3) | 453 QCA8K_PORT_PAD_RGMII_RX_DELAY(3)); 454 455 /* According to the datasheet, RGMII delay is enabled through 456 * PORT5_PAD_CTRL for all ports, rather than individual port 457 * registers 458 */ 459 qca8k_write(priv, QCA8K_REG_PORT5_PAD_CTRL, 460 QCA8K_PORT_PAD_RGMII_RX_DELAY_EN); 461 break; 462 case PHY_INTERFACE_MODE_SGMII: 463 qca8k_write(priv, reg, QCA8K_PORT_PAD_SGMII_EN); 464 break; 465 default: 466 pr_err("xMII mode %d not supported\n", mode); 467 return -EINVAL; 468 } 469 470 return 0; 471} 472 473static void 474qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable) 475{ 476 u32 mask = QCA8K_PORT_STATUS_TXMAC; 477 478 /* Port 0 and 6 have no internal PHY */ 479 if ((port > 0) && (port < 6)) 480 mask |= QCA8K_PORT_STATUS_LINK_AUTO; 481 482 if (enable) 483 qca8k_reg_set(priv, QCA8K_REG_PORT_STATUS(port), mask); 484 else 485 qca8k_reg_clear(priv, QCA8K_REG_PORT_STATUS(port), mask); 486} 487 488static int 489qca8k_setup(struct dsa_switch *ds) 490{ 491 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 492 int ret, i, phy_mode = -1; 493 494 /* Make sure that port 0 is the cpu port */ 495 if (!dsa_is_cpu_port(ds, 0)) { 496 pr_err("port 0 is not the CPU port\n"); 497 return -EINVAL; 498 } 499 500 mutex_init(&priv->reg_mutex); 501 502 /* Start by setting up the register mapping */ 503 priv->regmap = devm_regmap_init(ds->dev, NULL, priv, 504 &qca8k_regmap_config); 505 if (IS_ERR(priv->regmap)) 506 pr_warn("regmap initialization failed"); 507 508 /* Initialize CPU port pad mode (xMII type, delays...) */ 509 phy_mode = of_get_phy_mode(ds->ports[QCA8K_CPU_PORT].dn); 510 if (phy_mode < 0) { 511 pr_err("Can't find phy-mode for master device\n"); 512 return phy_mode; 513 } 514 ret = qca8k_set_pad_ctrl(priv, QCA8K_CPU_PORT, phy_mode); 515 if (ret < 0) 516 return ret; 517 518 /* Enable CPU Port */ 519 qca8k_reg_set(priv, QCA8K_REG_GLOBAL_FW_CTRL0, 520 QCA8K_GLOBAL_FW_CTRL0_CPU_PORT_EN); 521 qca8k_port_set_status(priv, QCA8K_CPU_PORT, 1); 522 priv->port_sts[QCA8K_CPU_PORT].enabled = 1; 523 524 /* Enable MIB counters */ 525 qca8k_mib_init(priv); 526 527 /* Enable QCA header mode on the cpu port */ 528 qca8k_write(priv, QCA8K_REG_PORT_HDR_CTRL(QCA8K_CPU_PORT), 529 QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_TX_S | 530 QCA8K_PORT_HDR_CTRL_ALL << QCA8K_PORT_HDR_CTRL_RX_S); 531 532 /* Disable forwarding by default on all ports */ 533 for (i = 0; i < QCA8K_NUM_PORTS; i++) 534 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), 535 QCA8K_PORT_LOOKUP_MEMBER, 0); 536 537 /* Disable MAC by default on all user ports */ 538 for (i = 1; i < QCA8K_NUM_PORTS; i++) 539 if (dsa_is_user_port(ds, i)) 540 qca8k_port_set_status(priv, i, 0); 541 542 /* Forward all unknown frames to CPU port for Linux processing */ 543 qca8k_write(priv, QCA8K_REG_GLOBAL_FW_CTRL1, 544 BIT(0) << QCA8K_GLOBAL_FW_CTRL1_IGMP_DP_S | 545 BIT(0) << QCA8K_GLOBAL_FW_CTRL1_BC_DP_S | 546 BIT(0) << QCA8K_GLOBAL_FW_CTRL1_MC_DP_S | 547 BIT(0) << QCA8K_GLOBAL_FW_CTRL1_UC_DP_S); 548 549 /* Setup connection between CPU port & user ports */ 550 for (i = 0; i < DSA_MAX_PORTS; i++) { 551 /* CPU port gets connected to all user ports of the switch */ 552 if (dsa_is_cpu_port(ds, i)) { 553 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(QCA8K_CPU_PORT), 554 QCA8K_PORT_LOOKUP_MEMBER, dsa_user_ports(ds)); 555 } 556 557 /* Invividual user ports get connected to CPU port only */ 558 if (dsa_is_user_port(ds, i)) { 559 int shift = 16 * (i % 2); 560 561 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(i), 562 QCA8K_PORT_LOOKUP_MEMBER, 563 BIT(QCA8K_CPU_PORT)); 564 565 /* Enable ARP Auto-learning by default */ 566 qca8k_reg_set(priv, QCA8K_PORT_LOOKUP_CTRL(i), 567 QCA8K_PORT_LOOKUP_LEARN); 568 569 /* For port based vlans to work we need to set the 570 * default egress vid 571 */ 572 qca8k_rmw(priv, QCA8K_EGRESS_VLAN(i), 573 0xffff << shift, 1 << shift); 574 qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(i), 575 QCA8K_PORT_VLAN_CVID(1) | 576 QCA8K_PORT_VLAN_SVID(1)); 577 } 578 } 579 580 /* Flush the FDB table */ 581 qca8k_fdb_flush(priv); 582 583 return 0; 584} 585 586static int 587qca8k_phy_read(struct dsa_switch *ds, int phy, int regnum) 588{ 589 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 590 591 return mdiobus_read(priv->bus, phy, regnum); 592} 593 594static int 595qca8k_phy_write(struct dsa_switch *ds, int phy, int regnum, u16 val) 596{ 597 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 598 599 return mdiobus_write(priv->bus, phy, regnum, val); 600} 601 602static void 603qca8k_get_strings(struct dsa_switch *ds, int port, uint8_t *data) 604{ 605 int i; 606 607 for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) 608 strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name, 609 ETH_GSTRING_LEN); 610} 611 612static void 613qca8k_get_ethtool_stats(struct dsa_switch *ds, int port, 614 uint64_t *data) 615{ 616 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 617 const struct qca8k_mib_desc *mib; 618 u32 reg, i; 619 u64 hi; 620 621 for (i = 0; i < ARRAY_SIZE(ar8327_mib); i++) { 622 mib = &ar8327_mib[i]; 623 reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset; 624 625 data[i] = qca8k_read(priv, reg); 626 if (mib->size == 2) { 627 hi = qca8k_read(priv, reg + 4); 628 data[i] |= hi << 32; 629 } 630 } 631} 632 633static int 634qca8k_get_sset_count(struct dsa_switch *ds) 635{ 636 return ARRAY_SIZE(ar8327_mib); 637} 638 639static int 640qca8k_set_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *eee) 641{ 642 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 643 u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port); 644 u32 reg; 645 646 mutex_lock(&priv->reg_mutex); 647 reg = qca8k_read(priv, QCA8K_REG_EEE_CTRL); 648 if (eee->eee_enabled) 649 reg |= lpi_en; 650 else 651 reg &= ~lpi_en; 652 qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg); 653 mutex_unlock(&priv->reg_mutex); 654 655 return 0; 656} 657 658static int 659qca8k_get_mac_eee(struct dsa_switch *ds, int port, struct ethtool_eee *e) 660{ 661 /* Nothing to do on the port's MAC */ 662 return 0; 663} 664 665static void 666qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state) 667{ 668 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 669 u32 stp_state; 670 671 switch (state) { 672 case BR_STATE_DISABLED: 673 stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED; 674 break; 675 case BR_STATE_BLOCKING: 676 stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING; 677 break; 678 case BR_STATE_LISTENING: 679 stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING; 680 break; 681 case BR_STATE_LEARNING: 682 stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING; 683 break; 684 case BR_STATE_FORWARDING: 685 default: 686 stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD; 687 break; 688 } 689 690 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), 691 QCA8K_PORT_LOOKUP_STATE_MASK, stp_state); 692} 693 694static int 695qca8k_port_bridge_join(struct dsa_switch *ds, int port, struct net_device *br) 696{ 697 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 698 int port_mask = BIT(QCA8K_CPU_PORT); 699 int i; 700 701 for (i = 1; i < QCA8K_NUM_PORTS; i++) { 702 if (dsa_to_port(ds, i)->bridge_dev != br) 703 continue; 704 /* Add this port to the portvlan mask of the other ports 705 * in the bridge 706 */ 707 qca8k_reg_set(priv, 708 QCA8K_PORT_LOOKUP_CTRL(i), 709 BIT(port)); 710 if (i != port) 711 port_mask |= BIT(i); 712 } 713 /* Add all other ports to this ports portvlan mask */ 714 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), 715 QCA8K_PORT_LOOKUP_MEMBER, port_mask); 716 717 return 0; 718} 719 720static void 721qca8k_port_bridge_leave(struct dsa_switch *ds, int port, struct net_device *br) 722{ 723 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 724 int i; 725 726 for (i = 1; i < QCA8K_NUM_PORTS; i++) { 727 if (dsa_to_port(ds, i)->bridge_dev != br) 728 continue; 729 /* Remove this port to the portvlan mask of the other ports 730 * in the bridge 731 */ 732 qca8k_reg_clear(priv, 733 QCA8K_PORT_LOOKUP_CTRL(i), 734 BIT(port)); 735 } 736 737 /* Set the cpu port to be the only one in the portvlan mask of 738 * this port 739 */ 740 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port), 741 QCA8K_PORT_LOOKUP_MEMBER, BIT(QCA8K_CPU_PORT)); 742} 743 744static int 745qca8k_port_enable(struct dsa_switch *ds, int port, 746 struct phy_device *phy) 747{ 748 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 749 750 qca8k_port_set_status(priv, port, 1); 751 priv->port_sts[port].enabled = 1; 752 753 return 0; 754} 755 756static void 757qca8k_port_disable(struct dsa_switch *ds, int port, 758 struct phy_device *phy) 759{ 760 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 761 762 qca8k_port_set_status(priv, port, 0); 763 priv->port_sts[port].enabled = 0; 764} 765 766static int 767qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr, 768 u16 port_mask, u16 vid) 769{ 770 /* Set the vid to the port vlan id if no vid is set */ 771 if (!vid) 772 vid = 1; 773 774 return qca8k_fdb_add(priv, addr, port_mask, vid, 775 QCA8K_ATU_STATUS_STATIC); 776} 777 778static int 779qca8k_port_fdb_add(struct dsa_switch *ds, int port, 780 const unsigned char *addr, u16 vid) 781{ 782 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 783 u16 port_mask = BIT(port); 784 785 return qca8k_port_fdb_insert(priv, addr, port_mask, vid); 786} 787 788static int 789qca8k_port_fdb_del(struct dsa_switch *ds, int port, 790 const unsigned char *addr, u16 vid) 791{ 792 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 793 u16 port_mask = BIT(port); 794 795 if (!vid) 796 vid = 1; 797 798 return qca8k_fdb_del(priv, addr, port_mask, vid); 799} 800 801static int 802qca8k_port_fdb_dump(struct dsa_switch *ds, int port, 803 dsa_fdb_dump_cb_t *cb, void *data) 804{ 805 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv; 806 struct qca8k_fdb _fdb = { 0 }; 807 int cnt = QCA8K_NUM_FDB_RECORDS; 808 bool is_static; 809 int ret = 0; 810 811 mutex_lock(&priv->reg_mutex); 812 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) { 813 if (!_fdb.aging) 814 break; 815 is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC); 816 ret = cb(_fdb.mac, _fdb.vid, is_static, data); 817 if (ret) 818 break; 819 } 820 mutex_unlock(&priv->reg_mutex); 821 822 return 0; 823} 824 825static enum dsa_tag_protocol 826qca8k_get_tag_protocol(struct dsa_switch *ds, int port) 827{ 828 return DSA_TAG_PROTO_QCA; 829} 830 831static const struct dsa_switch_ops qca8k_switch_ops = { 832 .get_tag_protocol = qca8k_get_tag_protocol, 833 .setup = qca8k_setup, 834 .get_strings = qca8k_get_strings, 835 .phy_read = qca8k_phy_read, 836 .phy_write = qca8k_phy_write, 837 .get_ethtool_stats = qca8k_get_ethtool_stats, 838 .get_sset_count = qca8k_get_sset_count, 839 .get_mac_eee = qca8k_get_mac_eee, 840 .set_mac_eee = qca8k_set_mac_eee, 841 .port_enable = qca8k_port_enable, 842 .port_disable = qca8k_port_disable, 843 .port_stp_state_set = qca8k_port_stp_state_set, 844 .port_bridge_join = qca8k_port_bridge_join, 845 .port_bridge_leave = qca8k_port_bridge_leave, 846 .port_fdb_add = qca8k_port_fdb_add, 847 .port_fdb_del = qca8k_port_fdb_del, 848 .port_fdb_dump = qca8k_port_fdb_dump, 849}; 850 851static int 852qca8k_sw_probe(struct mdio_device *mdiodev) 853{ 854 struct qca8k_priv *priv; 855 u32 id; 856 857 /* allocate the private data struct so that we can probe the switches 858 * ID register 859 */ 860 priv = devm_kzalloc(&mdiodev->dev, sizeof(*priv), GFP_KERNEL); 861 if (!priv) 862 return -ENOMEM; 863 864 priv->bus = mdiodev->bus; 865 866 /* read the switches ID register */ 867 id = qca8k_read(priv, QCA8K_REG_MASK_CTRL); 868 id >>= QCA8K_MASK_CTRL_ID_S; 869 id &= QCA8K_MASK_CTRL_ID_M; 870 if (id != QCA8K_ID_QCA8337) 871 return -ENODEV; 872 873 priv->ds = dsa_switch_alloc(&mdiodev->dev, DSA_MAX_PORTS); 874 if (!priv->ds) 875 return -ENOMEM; 876 877 priv->ds->priv = priv; 878 priv->ds->ops = &qca8k_switch_ops; 879 mutex_init(&priv->reg_mutex); 880 dev_set_drvdata(&mdiodev->dev, priv); 881 882 return dsa_register_switch(priv->ds); 883} 884 885static void 886qca8k_sw_remove(struct mdio_device *mdiodev) 887{ 888 struct qca8k_priv *priv = dev_get_drvdata(&mdiodev->dev); 889 int i; 890 891 for (i = 0; i < QCA8K_NUM_PORTS; i++) 892 qca8k_port_set_status(priv, i, 0); 893 894 dsa_unregister_switch(priv->ds); 895} 896 897#ifdef CONFIG_PM_SLEEP 898static void 899qca8k_set_pm(struct qca8k_priv *priv, int enable) 900{ 901 int i; 902 903 for (i = 0; i < QCA8K_NUM_PORTS; i++) { 904 if (!priv->port_sts[i].enabled) 905 continue; 906 907 qca8k_port_set_status(priv, i, enable); 908 } 909} 910 911static int qca8k_suspend(struct device *dev) 912{ 913 struct platform_device *pdev = to_platform_device(dev); 914 struct qca8k_priv *priv = platform_get_drvdata(pdev); 915 916 qca8k_set_pm(priv, 0); 917 918 return dsa_switch_suspend(priv->ds); 919} 920 921static int qca8k_resume(struct device *dev) 922{ 923 struct platform_device *pdev = to_platform_device(dev); 924 struct qca8k_priv *priv = platform_get_drvdata(pdev); 925 926 qca8k_set_pm(priv, 1); 927 928 return dsa_switch_resume(priv->ds); 929} 930#endif /* CONFIG_PM_SLEEP */ 931 932static SIMPLE_DEV_PM_OPS(qca8k_pm_ops, 933 qca8k_suspend, qca8k_resume); 934 935static const struct of_device_id qca8k_of_match[] = { 936 { .compatible = "qca,qca8337" }, 937 { /* sentinel */ }, 938}; 939 940static struct mdio_driver qca8kmdio_driver = { 941 .probe = qca8k_sw_probe, 942 .remove = qca8k_sw_remove, 943 .mdiodrv.driver = { 944 .name = "qca8k", 945 .of_match_table = qca8k_of_match, 946 .pm = &qca8k_pm_ops, 947 }, 948}; 949 950mdio_module_driver(qca8kmdio_driver); 951 952MODULE_AUTHOR("Mathieu Olivari, John Crispin <john@phrozen.org>"); 953MODULE_DESCRIPTION("Driver for QCA8K ethernet switch family"); 954MODULE_LICENSE("GPL v2"); 955MODULE_ALIAS("platform:qca8k");