0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <linux/netdevice.h>
0010 #include <net/dsa.h>
0011 #include <linux/if_bridge.h>
0012
0013 #include "qca8k.h"
0014
0015 #define MIB_DESC(_s, _o, _n) \
0016 { \
0017 .size = (_s), \
0018 .offset = (_o), \
0019 .name = (_n), \
0020 }
0021
0022 const struct qca8k_mib_desc ar8327_mib[] = {
0023 MIB_DESC(1, 0x00, "RxBroad"),
0024 MIB_DESC(1, 0x04, "RxPause"),
0025 MIB_DESC(1, 0x08, "RxMulti"),
0026 MIB_DESC(1, 0x0c, "RxFcsErr"),
0027 MIB_DESC(1, 0x10, "RxAlignErr"),
0028 MIB_DESC(1, 0x14, "RxRunt"),
0029 MIB_DESC(1, 0x18, "RxFragment"),
0030 MIB_DESC(1, 0x1c, "Rx64Byte"),
0031 MIB_DESC(1, 0x20, "Rx128Byte"),
0032 MIB_DESC(1, 0x24, "Rx256Byte"),
0033 MIB_DESC(1, 0x28, "Rx512Byte"),
0034 MIB_DESC(1, 0x2c, "Rx1024Byte"),
0035 MIB_DESC(1, 0x30, "Rx1518Byte"),
0036 MIB_DESC(1, 0x34, "RxMaxByte"),
0037 MIB_DESC(1, 0x38, "RxTooLong"),
0038 MIB_DESC(2, 0x3c, "RxGoodByte"),
0039 MIB_DESC(2, 0x44, "RxBadByte"),
0040 MIB_DESC(1, 0x4c, "RxOverFlow"),
0041 MIB_DESC(1, 0x50, "Filtered"),
0042 MIB_DESC(1, 0x54, "TxBroad"),
0043 MIB_DESC(1, 0x58, "TxPause"),
0044 MIB_DESC(1, 0x5c, "TxMulti"),
0045 MIB_DESC(1, 0x60, "TxUnderRun"),
0046 MIB_DESC(1, 0x64, "Tx64Byte"),
0047 MIB_DESC(1, 0x68, "Tx128Byte"),
0048 MIB_DESC(1, 0x6c, "Tx256Byte"),
0049 MIB_DESC(1, 0x70, "Tx512Byte"),
0050 MIB_DESC(1, 0x74, "Tx1024Byte"),
0051 MIB_DESC(1, 0x78, "Tx1518Byte"),
0052 MIB_DESC(1, 0x7c, "TxMaxByte"),
0053 MIB_DESC(1, 0x80, "TxOverSize"),
0054 MIB_DESC(2, 0x84, "TxByte"),
0055 MIB_DESC(1, 0x8c, "TxCollision"),
0056 MIB_DESC(1, 0x90, "TxAbortCol"),
0057 MIB_DESC(1, 0x94, "TxMultiCol"),
0058 MIB_DESC(1, 0x98, "TxSingleCol"),
0059 MIB_DESC(1, 0x9c, "TxExcDefer"),
0060 MIB_DESC(1, 0xa0, "TxDefer"),
0061 MIB_DESC(1, 0xa4, "TxLateCol"),
0062 MIB_DESC(1, 0xa8, "RXUnicast"),
0063 MIB_DESC(1, 0xac, "TXUnicast"),
0064 };
0065
0066 int qca8k_read(struct qca8k_priv *priv, u32 reg, u32 *val)
0067 {
0068 return regmap_read(priv->regmap, reg, val);
0069 }
0070
0071 int qca8k_write(struct qca8k_priv *priv, u32 reg, u32 val)
0072 {
0073 return regmap_write(priv->regmap, reg, val);
0074 }
0075
0076 int qca8k_rmw(struct qca8k_priv *priv, u32 reg, u32 mask, u32 write_val)
0077 {
0078 return regmap_update_bits(priv->regmap, reg, mask, write_val);
0079 }
0080
0081 static const struct regmap_range qca8k_readable_ranges[] = {
0082 regmap_reg_range(0x0000, 0x00e4),
0083 regmap_reg_range(0x0100, 0x0168),
0084 regmap_reg_range(0x0200, 0x0270),
0085 regmap_reg_range(0x0400, 0x0454),
0086 regmap_reg_range(0x0600, 0x0718),
0087 regmap_reg_range(0x0800, 0x0b70),
0088 regmap_reg_range(0x0c00, 0x0c80),
0089 regmap_reg_range(0x0e00, 0x0e98),
0090 regmap_reg_range(0x1000, 0x10ac),
0091 regmap_reg_range(0x1100, 0x11ac),
0092 regmap_reg_range(0x1200, 0x12ac),
0093 regmap_reg_range(0x1300, 0x13ac),
0094 regmap_reg_range(0x1400, 0x14ac),
0095 regmap_reg_range(0x1500, 0x15ac),
0096 regmap_reg_range(0x1600, 0x16ac),
0097 };
0098
0099 const struct regmap_access_table qca8k_readable_table = {
0100 .yes_ranges = qca8k_readable_ranges,
0101 .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges),
0102 };
0103
0104
0105 static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
0106 {
0107 int i, count = len / sizeof(u32), ret;
0108
0109 if (priv->mgmt_master && priv->info->ops->read_eth &&
0110 !priv->info->ops->read_eth(priv, reg, val, len))
0111 return 0;
0112
0113 for (i = 0; i < count; i++) {
0114 ret = regmap_read(priv->regmap, reg + (i * 4), val + i);
0115 if (ret < 0)
0116 return ret;
0117 }
0118
0119 return 0;
0120 }
0121
0122
0123 static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len)
0124 {
0125 int i, count = len / sizeof(u32), ret;
0126 u32 tmp;
0127
0128 if (priv->mgmt_master && priv->info->ops->write_eth &&
0129 !priv->info->ops->write_eth(priv, reg, val, len))
0130 return 0;
0131
0132 for (i = 0; i < count; i++) {
0133 tmp = val[i];
0134
0135 ret = regmap_write(priv->regmap, reg + (i * 4), tmp);
0136 if (ret < 0)
0137 return ret;
0138 }
0139
0140 return 0;
0141 }
0142
0143 static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask)
0144 {
0145 u32 val;
0146
0147 return regmap_read_poll_timeout(priv->regmap, reg, val, !(val & mask), 0,
0148 QCA8K_BUSY_WAIT_TIMEOUT * USEC_PER_MSEC);
0149 }
0150
0151 static int qca8k_fdb_read(struct qca8k_priv *priv, struct qca8k_fdb *fdb)
0152 {
0153 u32 reg[3];
0154 int ret;
0155
0156
0157 ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
0158 if (ret)
0159 return ret;
0160
0161
0162 fdb->vid = FIELD_GET(QCA8K_ATU_VID_MASK, reg[2]);
0163
0164 fdb->aging = FIELD_GET(QCA8K_ATU_STATUS_MASK, reg[2]);
0165
0166 fdb->port_mask = FIELD_GET(QCA8K_ATU_PORT_MASK, reg[1]);
0167
0168 fdb->mac[0] = FIELD_GET(QCA8K_ATU_ADDR0_MASK, reg[1]);
0169 fdb->mac[1] = FIELD_GET(QCA8K_ATU_ADDR1_MASK, reg[1]);
0170 fdb->mac[2] = FIELD_GET(QCA8K_ATU_ADDR2_MASK, reg[0]);
0171 fdb->mac[3] = FIELD_GET(QCA8K_ATU_ADDR3_MASK, reg[0]);
0172 fdb->mac[4] = FIELD_GET(QCA8K_ATU_ADDR4_MASK, reg[0]);
0173 fdb->mac[5] = FIELD_GET(QCA8K_ATU_ADDR5_MASK, reg[0]);
0174
0175 return 0;
0176 }
0177
0178 static void qca8k_fdb_write(struct qca8k_priv *priv, u16 vid, u8 port_mask,
0179 const u8 *mac, u8 aging)
0180 {
0181 u32 reg[3] = { 0 };
0182
0183
0184 reg[2] = FIELD_PREP(QCA8K_ATU_VID_MASK, vid);
0185
0186 reg[2] |= FIELD_PREP(QCA8K_ATU_STATUS_MASK, aging);
0187
0188 reg[1] = FIELD_PREP(QCA8K_ATU_PORT_MASK, port_mask);
0189
0190 reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR0_MASK, mac[0]);
0191 reg[1] |= FIELD_PREP(QCA8K_ATU_ADDR1_MASK, mac[1]);
0192 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR2_MASK, mac[2]);
0193 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR3_MASK, mac[3]);
0194 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR4_MASK, mac[4]);
0195 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]);
0196
0197
0198 qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, sizeof(reg));
0199 }
0200
0201 static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
0202 int port)
0203 {
0204 u32 reg;
0205 int ret;
0206
0207
0208 reg = QCA8K_ATU_FUNC_BUSY;
0209 reg |= cmd;
0210 if (port >= 0) {
0211 reg |= QCA8K_ATU_FUNC_PORT_EN;
0212 reg |= FIELD_PREP(QCA8K_ATU_FUNC_PORT_MASK, port);
0213 }
0214
0215
0216 ret = qca8k_write(priv, QCA8K_REG_ATU_FUNC, reg);
0217 if (ret)
0218 return ret;
0219
0220
0221 ret = qca8k_busy_wait(priv, QCA8K_REG_ATU_FUNC, QCA8K_ATU_FUNC_BUSY);
0222 if (ret)
0223 return ret;
0224
0225
0226 if (cmd == QCA8K_FDB_LOAD) {
0227 ret = qca8k_read(priv, QCA8K_REG_ATU_FUNC, ®);
0228 if (ret < 0)
0229 return ret;
0230 if (reg & QCA8K_ATU_FUNC_FULL)
0231 return -1;
0232 }
0233
0234 return 0;
0235 }
0236
0237 static int qca8k_fdb_next(struct qca8k_priv *priv, struct qca8k_fdb *fdb,
0238 int port)
0239 {
0240 int ret;
0241
0242 qca8k_fdb_write(priv, fdb->vid, fdb->port_mask, fdb->mac, fdb->aging);
0243 ret = qca8k_fdb_access(priv, QCA8K_FDB_NEXT, port);
0244 if (ret < 0)
0245 return ret;
0246
0247 return qca8k_fdb_read(priv, fdb);
0248 }
0249
0250 static int qca8k_fdb_add(struct qca8k_priv *priv, const u8 *mac,
0251 u16 port_mask, u16 vid, u8 aging)
0252 {
0253 int ret;
0254
0255 mutex_lock(&priv->reg_mutex);
0256 qca8k_fdb_write(priv, vid, port_mask, mac, aging);
0257 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
0258 mutex_unlock(&priv->reg_mutex);
0259
0260 return ret;
0261 }
0262
0263 static int qca8k_fdb_del(struct qca8k_priv *priv, const u8 *mac,
0264 u16 port_mask, u16 vid)
0265 {
0266 int ret;
0267
0268 mutex_lock(&priv->reg_mutex);
0269 qca8k_fdb_write(priv, vid, port_mask, mac, 0);
0270 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
0271 mutex_unlock(&priv->reg_mutex);
0272
0273 return ret;
0274 }
0275
0276 void qca8k_fdb_flush(struct qca8k_priv *priv)
0277 {
0278 mutex_lock(&priv->reg_mutex);
0279 qca8k_fdb_access(priv, QCA8K_FDB_FLUSH, -1);
0280 mutex_unlock(&priv->reg_mutex);
0281 }
0282
0283 static int qca8k_fdb_search_and_insert(struct qca8k_priv *priv, u8 port_mask,
0284 const u8 *mac, u16 vid)
0285 {
0286 struct qca8k_fdb fdb = { 0 };
0287 int ret;
0288
0289 mutex_lock(&priv->reg_mutex);
0290
0291 qca8k_fdb_write(priv, vid, 0, mac, 0);
0292 ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
0293 if (ret < 0)
0294 goto exit;
0295
0296 ret = qca8k_fdb_read(priv, &fdb);
0297 if (ret < 0)
0298 goto exit;
0299
0300
0301 if (!fdb.aging) {
0302 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
0303 if (ret)
0304 goto exit;
0305 }
0306
0307
0308 fdb.port_mask |= port_mask;
0309
0310 qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
0311 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
0312
0313 exit:
0314 mutex_unlock(&priv->reg_mutex);
0315 return ret;
0316 }
0317
0318 static int qca8k_fdb_search_and_del(struct qca8k_priv *priv, u8 port_mask,
0319 const u8 *mac, u16 vid)
0320 {
0321 struct qca8k_fdb fdb = { 0 };
0322 int ret;
0323
0324 mutex_lock(&priv->reg_mutex);
0325
0326 qca8k_fdb_write(priv, vid, 0, mac, 0);
0327 ret = qca8k_fdb_access(priv, QCA8K_FDB_SEARCH, -1);
0328 if (ret < 0)
0329 goto exit;
0330
0331
0332 if (!fdb.aging) {
0333 ret = -EINVAL;
0334 goto exit;
0335 }
0336
0337 ret = qca8k_fdb_access(priv, QCA8K_FDB_PURGE, -1);
0338 if (ret)
0339 goto exit;
0340
0341
0342 if (fdb.port_mask == port_mask)
0343 goto exit;
0344
0345
0346 fdb.port_mask &= ~port_mask;
0347
0348 qca8k_fdb_write(priv, vid, fdb.port_mask, mac, fdb.aging);
0349 ret = qca8k_fdb_access(priv, QCA8K_FDB_LOAD, -1);
0350
0351 exit:
0352 mutex_unlock(&priv->reg_mutex);
0353 return ret;
0354 }
0355
0356 static int qca8k_vlan_access(struct qca8k_priv *priv,
0357 enum qca8k_vlan_cmd cmd, u16 vid)
0358 {
0359 u32 reg;
0360 int ret;
0361
0362
0363 reg = QCA8K_VTU_FUNC1_BUSY;
0364 reg |= cmd;
0365 reg |= FIELD_PREP(QCA8K_VTU_FUNC1_VID_MASK, vid);
0366
0367
0368 ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC1, reg);
0369 if (ret)
0370 return ret;
0371
0372
0373 ret = qca8k_busy_wait(priv, QCA8K_REG_VTU_FUNC1, QCA8K_VTU_FUNC1_BUSY);
0374 if (ret)
0375 return ret;
0376
0377
0378 if (cmd == QCA8K_VLAN_LOAD) {
0379 ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC1, ®);
0380 if (ret < 0)
0381 return ret;
0382 if (reg & QCA8K_VTU_FUNC1_FULL)
0383 return -ENOMEM;
0384 }
0385
0386 return 0;
0387 }
0388
0389 static int qca8k_vlan_add(struct qca8k_priv *priv, u8 port, u16 vid,
0390 bool untagged)
0391 {
0392 u32 reg;
0393 int ret;
0394
0395
0396
0397
0398 if (vid == 0)
0399 return 0;
0400
0401 mutex_lock(&priv->reg_mutex);
0402 ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
0403 if (ret < 0)
0404 goto out;
0405
0406 ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
0407 if (ret < 0)
0408 goto out;
0409 reg |= QCA8K_VTU_FUNC0_VALID | QCA8K_VTU_FUNC0_IVL_EN;
0410 reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
0411 if (untagged)
0412 reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_UNTAG(port);
0413 else
0414 reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_TAG(port);
0415
0416 ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
0417 if (ret)
0418 goto out;
0419 ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
0420
0421 out:
0422 mutex_unlock(&priv->reg_mutex);
0423
0424 return ret;
0425 }
0426
0427 static int qca8k_vlan_del(struct qca8k_priv *priv, u8 port, u16 vid)
0428 {
0429 u32 reg, mask;
0430 int ret, i;
0431 bool del;
0432
0433 mutex_lock(&priv->reg_mutex);
0434 ret = qca8k_vlan_access(priv, QCA8K_VLAN_READ, vid);
0435 if (ret < 0)
0436 goto out;
0437
0438 ret = qca8k_read(priv, QCA8K_REG_VTU_FUNC0, ®);
0439 if (ret < 0)
0440 goto out;
0441 reg &= ~QCA8K_VTU_FUNC0_EG_MODE_PORT_MASK(port);
0442 reg |= QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(port);
0443
0444
0445 del = true;
0446 for (i = 0; i < QCA8K_NUM_PORTS; i++) {
0447 mask = QCA8K_VTU_FUNC0_EG_MODE_PORT_NOT(i);
0448
0449 if ((reg & mask) != mask) {
0450 del = false;
0451 break;
0452 }
0453 }
0454
0455 if (del) {
0456 ret = qca8k_vlan_access(priv, QCA8K_VLAN_PURGE, vid);
0457 } else {
0458 ret = qca8k_write(priv, QCA8K_REG_VTU_FUNC0, reg);
0459 if (ret)
0460 goto out;
0461 ret = qca8k_vlan_access(priv, QCA8K_VLAN_LOAD, vid);
0462 }
0463
0464 out:
0465 mutex_unlock(&priv->reg_mutex);
0466
0467 return ret;
0468 }
0469
0470 int qca8k_mib_init(struct qca8k_priv *priv)
0471 {
0472 int ret;
0473
0474 mutex_lock(&priv->reg_mutex);
0475 ret = regmap_update_bits(priv->regmap, QCA8K_REG_MIB,
0476 QCA8K_MIB_FUNC | QCA8K_MIB_BUSY,
0477 FIELD_PREP(QCA8K_MIB_FUNC, QCA8K_MIB_FLUSH) |
0478 QCA8K_MIB_BUSY);
0479 if (ret)
0480 goto exit;
0481
0482 ret = qca8k_busy_wait(priv, QCA8K_REG_MIB, QCA8K_MIB_BUSY);
0483 if (ret)
0484 goto exit;
0485
0486 ret = regmap_set_bits(priv->regmap, QCA8K_REG_MIB, QCA8K_MIB_CPU_KEEP);
0487 if (ret)
0488 goto exit;
0489
0490 ret = qca8k_write(priv, QCA8K_REG_MODULE_EN, QCA8K_MODULE_EN_MIB);
0491
0492 exit:
0493 mutex_unlock(&priv->reg_mutex);
0494 return ret;
0495 }
0496
0497 void qca8k_port_set_status(struct qca8k_priv *priv, int port, int enable)
0498 {
0499 u32 mask = QCA8K_PORT_STATUS_TXMAC | QCA8K_PORT_STATUS_RXMAC;
0500
0501
0502 if (port > 0 && port < 6)
0503 mask |= QCA8K_PORT_STATUS_LINK_AUTO;
0504
0505 if (enable)
0506 regmap_set_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
0507 else
0508 regmap_clear_bits(priv->regmap, QCA8K_REG_PORT_STATUS(port), mask);
0509 }
0510
0511 void qca8k_get_strings(struct dsa_switch *ds, int port, u32 stringset,
0512 uint8_t *data)
0513 {
0514 struct qca8k_priv *priv = ds->priv;
0515 int i;
0516
0517 if (stringset != ETH_SS_STATS)
0518 return;
0519
0520 for (i = 0; i < priv->info->mib_count; i++)
0521 strncpy(data + i * ETH_GSTRING_LEN, ar8327_mib[i].name,
0522 ETH_GSTRING_LEN);
0523 }
0524
0525 void qca8k_get_ethtool_stats(struct dsa_switch *ds, int port,
0526 uint64_t *data)
0527 {
0528 struct qca8k_priv *priv = ds->priv;
0529 const struct qca8k_mib_desc *mib;
0530 u32 reg, i, val;
0531 u32 hi = 0;
0532 int ret;
0533
0534 if (priv->mgmt_master && priv->info->ops->autocast_mib &&
0535 priv->info->ops->autocast_mib(ds, port, data) > 0)
0536 return;
0537
0538 for (i = 0; i < priv->info->mib_count; i++) {
0539 mib = &ar8327_mib[i];
0540 reg = QCA8K_PORT_MIB_COUNTER(port) + mib->offset;
0541
0542 ret = qca8k_read(priv, reg, &val);
0543 if (ret < 0)
0544 continue;
0545
0546 if (mib->size == 2) {
0547 ret = qca8k_read(priv, reg + 4, &hi);
0548 if (ret < 0)
0549 continue;
0550 }
0551
0552 data[i] = val;
0553 if (mib->size == 2)
0554 data[i] |= (u64)hi << 32;
0555 }
0556 }
0557
0558 int qca8k_get_sset_count(struct dsa_switch *ds, int port, int sset)
0559 {
0560 struct qca8k_priv *priv = ds->priv;
0561
0562 if (sset != ETH_SS_STATS)
0563 return 0;
0564
0565 return priv->info->mib_count;
0566 }
0567
0568 int qca8k_set_mac_eee(struct dsa_switch *ds, int port,
0569 struct ethtool_eee *eee)
0570 {
0571 u32 lpi_en = QCA8K_REG_EEE_CTRL_LPI_EN(port);
0572 struct qca8k_priv *priv = ds->priv;
0573 u32 reg;
0574 int ret;
0575
0576 mutex_lock(&priv->reg_mutex);
0577 ret = qca8k_read(priv, QCA8K_REG_EEE_CTRL, ®);
0578 if (ret < 0)
0579 goto exit;
0580
0581 if (eee->eee_enabled)
0582 reg |= lpi_en;
0583 else
0584 reg &= ~lpi_en;
0585 ret = qca8k_write(priv, QCA8K_REG_EEE_CTRL, reg);
0586
0587 exit:
0588 mutex_unlock(&priv->reg_mutex);
0589 return ret;
0590 }
0591
0592 int qca8k_get_mac_eee(struct dsa_switch *ds, int port,
0593 struct ethtool_eee *e)
0594 {
0595
0596 return 0;
0597 }
0598
0599 void qca8k_port_stp_state_set(struct dsa_switch *ds, int port, u8 state)
0600 {
0601 struct qca8k_priv *priv = ds->priv;
0602 u32 stp_state;
0603
0604 switch (state) {
0605 case BR_STATE_DISABLED:
0606 stp_state = QCA8K_PORT_LOOKUP_STATE_DISABLED;
0607 break;
0608 case BR_STATE_BLOCKING:
0609 stp_state = QCA8K_PORT_LOOKUP_STATE_BLOCKING;
0610 break;
0611 case BR_STATE_LISTENING:
0612 stp_state = QCA8K_PORT_LOOKUP_STATE_LISTENING;
0613 break;
0614 case BR_STATE_LEARNING:
0615 stp_state = QCA8K_PORT_LOOKUP_STATE_LEARNING;
0616 break;
0617 case BR_STATE_FORWARDING:
0618 default:
0619 stp_state = QCA8K_PORT_LOOKUP_STATE_FORWARD;
0620 break;
0621 }
0622
0623 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
0624 QCA8K_PORT_LOOKUP_STATE_MASK, stp_state);
0625 }
0626
0627 int qca8k_port_bridge_join(struct dsa_switch *ds, int port,
0628 struct dsa_bridge bridge,
0629 bool *tx_fwd_offload,
0630 struct netlink_ext_ack *extack)
0631 {
0632 struct qca8k_priv *priv = ds->priv;
0633 int port_mask, cpu_port;
0634 int i, ret;
0635
0636 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
0637 port_mask = BIT(cpu_port);
0638
0639 for (i = 0; i < QCA8K_NUM_PORTS; i++) {
0640 if (dsa_is_cpu_port(ds, i))
0641 continue;
0642 if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
0643 continue;
0644
0645
0646
0647 ret = regmap_set_bits(priv->regmap,
0648 QCA8K_PORT_LOOKUP_CTRL(i),
0649 BIT(port));
0650 if (ret)
0651 return ret;
0652 if (i != port)
0653 port_mask |= BIT(i);
0654 }
0655
0656
0657 ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
0658 QCA8K_PORT_LOOKUP_MEMBER, port_mask);
0659
0660 return ret;
0661 }
0662
0663 void qca8k_port_bridge_leave(struct dsa_switch *ds, int port,
0664 struct dsa_bridge bridge)
0665 {
0666 struct qca8k_priv *priv = ds->priv;
0667 int cpu_port, i;
0668
0669 cpu_port = dsa_to_port(ds, port)->cpu_dp->index;
0670
0671 for (i = 0; i < QCA8K_NUM_PORTS; i++) {
0672 if (dsa_is_cpu_port(ds, i))
0673 continue;
0674 if (!dsa_port_offloads_bridge(dsa_to_port(ds, i), &bridge))
0675 continue;
0676
0677
0678
0679 regmap_clear_bits(priv->regmap,
0680 QCA8K_PORT_LOOKUP_CTRL(i),
0681 BIT(port));
0682 }
0683
0684
0685
0686
0687 qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
0688 QCA8K_PORT_LOOKUP_MEMBER, BIT(cpu_port));
0689 }
0690
0691 void qca8k_port_fast_age(struct dsa_switch *ds, int port)
0692 {
0693 struct qca8k_priv *priv = ds->priv;
0694
0695 mutex_lock(&priv->reg_mutex);
0696 qca8k_fdb_access(priv, QCA8K_FDB_FLUSH_PORT, port);
0697 mutex_unlock(&priv->reg_mutex);
0698 }
0699
0700 int qca8k_set_ageing_time(struct dsa_switch *ds, unsigned int msecs)
0701 {
0702 struct qca8k_priv *priv = ds->priv;
0703 unsigned int secs = msecs / 1000;
0704 u32 val;
0705
0706
0707 val = secs / 7;
0708
0709
0710
0711
0712 if (!val)
0713 val = 1;
0714
0715 return regmap_update_bits(priv->regmap, QCA8K_REG_ATU_CTRL,
0716 QCA8K_ATU_AGE_TIME_MASK,
0717 QCA8K_ATU_AGE_TIME(val));
0718 }
0719
0720 int qca8k_port_enable(struct dsa_switch *ds, int port,
0721 struct phy_device *phy)
0722 {
0723 struct qca8k_priv *priv = ds->priv;
0724
0725 qca8k_port_set_status(priv, port, 1);
0726 priv->port_enabled_map |= BIT(port);
0727
0728 if (dsa_is_user_port(ds, port))
0729 phy_support_asym_pause(phy);
0730
0731 return 0;
0732 }
0733
0734 void qca8k_port_disable(struct dsa_switch *ds, int port)
0735 {
0736 struct qca8k_priv *priv = ds->priv;
0737
0738 qca8k_port_set_status(priv, port, 0);
0739 priv->port_enabled_map &= ~BIT(port);
0740 }
0741
0742 int qca8k_port_change_mtu(struct dsa_switch *ds, int port, int new_mtu)
0743 {
0744 struct qca8k_priv *priv = ds->priv;
0745 int ret;
0746
0747
0748
0749
0750
0751
0752
0753 if (!dsa_is_cpu_port(ds, port))
0754 return 0;
0755
0756
0757
0758
0759
0760
0761 if (priv->port_enabled_map & BIT(0))
0762 qca8k_port_set_status(priv, 0, 0);
0763
0764 if (priv->port_enabled_map & BIT(6))
0765 qca8k_port_set_status(priv, 6, 0);
0766
0767
0768 ret = qca8k_write(priv, QCA8K_MAX_FRAME_SIZE, new_mtu +
0769 ETH_HLEN + ETH_FCS_LEN);
0770
0771 if (priv->port_enabled_map & BIT(0))
0772 qca8k_port_set_status(priv, 0, 1);
0773
0774 if (priv->port_enabled_map & BIT(6))
0775 qca8k_port_set_status(priv, 6, 1);
0776
0777 return ret;
0778 }
0779
0780 int qca8k_port_max_mtu(struct dsa_switch *ds, int port)
0781 {
0782 return QCA8K_MAX_MTU;
0783 }
0784
0785 int qca8k_port_fdb_insert(struct qca8k_priv *priv, const u8 *addr,
0786 u16 port_mask, u16 vid)
0787 {
0788
0789 if (!vid)
0790 vid = QCA8K_PORT_VID_DEF;
0791
0792 return qca8k_fdb_add(priv, addr, port_mask, vid,
0793 QCA8K_ATU_STATUS_STATIC);
0794 }
0795
0796 int qca8k_port_fdb_add(struct dsa_switch *ds, int port,
0797 const unsigned char *addr, u16 vid,
0798 struct dsa_db db)
0799 {
0800 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
0801 u16 port_mask = BIT(port);
0802
0803 return qca8k_port_fdb_insert(priv, addr, port_mask, vid);
0804 }
0805
0806 int qca8k_port_fdb_del(struct dsa_switch *ds, int port,
0807 const unsigned char *addr, u16 vid,
0808 struct dsa_db db)
0809 {
0810 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
0811 u16 port_mask = BIT(port);
0812
0813 if (!vid)
0814 vid = QCA8K_PORT_VID_DEF;
0815
0816 return qca8k_fdb_del(priv, addr, port_mask, vid);
0817 }
0818
0819 int qca8k_port_fdb_dump(struct dsa_switch *ds, int port,
0820 dsa_fdb_dump_cb_t *cb, void *data)
0821 {
0822 struct qca8k_priv *priv = (struct qca8k_priv *)ds->priv;
0823 struct qca8k_fdb _fdb = { 0 };
0824 int cnt = QCA8K_NUM_FDB_RECORDS;
0825 bool is_static;
0826 int ret = 0;
0827
0828 mutex_lock(&priv->reg_mutex);
0829 while (cnt-- && !qca8k_fdb_next(priv, &_fdb, port)) {
0830 if (!_fdb.aging)
0831 break;
0832 is_static = (_fdb.aging == QCA8K_ATU_STATUS_STATIC);
0833 ret = cb(_fdb.mac, _fdb.vid, is_static, data);
0834 if (ret)
0835 break;
0836 }
0837 mutex_unlock(&priv->reg_mutex);
0838
0839 return 0;
0840 }
0841
0842 int qca8k_port_mdb_add(struct dsa_switch *ds, int port,
0843 const struct switchdev_obj_port_mdb *mdb,
0844 struct dsa_db db)
0845 {
0846 struct qca8k_priv *priv = ds->priv;
0847 const u8 *addr = mdb->addr;
0848 u16 vid = mdb->vid;
0849
0850 return qca8k_fdb_search_and_insert(priv, BIT(port), addr, vid);
0851 }
0852
0853 int qca8k_port_mdb_del(struct dsa_switch *ds, int port,
0854 const struct switchdev_obj_port_mdb *mdb,
0855 struct dsa_db db)
0856 {
0857 struct qca8k_priv *priv = ds->priv;
0858 const u8 *addr = mdb->addr;
0859 u16 vid = mdb->vid;
0860
0861 return qca8k_fdb_search_and_del(priv, BIT(port), addr, vid);
0862 }
0863
0864 int qca8k_port_mirror_add(struct dsa_switch *ds, int port,
0865 struct dsa_mall_mirror_tc_entry *mirror,
0866 bool ingress, struct netlink_ext_ack *extack)
0867 {
0868 struct qca8k_priv *priv = ds->priv;
0869 int monitor_port, ret;
0870 u32 reg, val;
0871
0872
0873 if ((ingress ? priv->mirror_rx : priv->mirror_tx) & BIT(port))
0874 return -EEXIST;
0875
0876 ret = regmap_read(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0, &val);
0877 if (ret)
0878 return ret;
0879
0880
0881
0882
0883
0884 monitor_port = FIELD_GET(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
0885 if (monitor_port != 0xF && monitor_port != mirror->to_local_port)
0886 return -EEXIST;
0887
0888
0889 val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM,
0890 mirror->to_local_port);
0891 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
0892 QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
0893 if (ret)
0894 return ret;
0895
0896 if (ingress) {
0897 reg = QCA8K_PORT_LOOKUP_CTRL(port);
0898 val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
0899 } else {
0900 reg = QCA8K_REG_PORT_HOL_CTRL1(port);
0901 val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
0902 }
0903
0904 ret = regmap_update_bits(priv->regmap, reg, val, val);
0905 if (ret)
0906 return ret;
0907
0908
0909
0910
0911 if (ingress)
0912 priv->mirror_rx |= BIT(port);
0913 else
0914 priv->mirror_tx |= BIT(port);
0915
0916 return 0;
0917 }
0918
0919 void qca8k_port_mirror_del(struct dsa_switch *ds, int port,
0920 struct dsa_mall_mirror_tc_entry *mirror)
0921 {
0922 struct qca8k_priv *priv = ds->priv;
0923 u32 reg, val;
0924 int ret;
0925
0926 if (mirror->ingress) {
0927 reg = QCA8K_PORT_LOOKUP_CTRL(port);
0928 val = QCA8K_PORT_LOOKUP_ING_MIRROR_EN;
0929 } else {
0930 reg = QCA8K_REG_PORT_HOL_CTRL1(port);
0931 val = QCA8K_PORT_HOL_CTRL1_EG_MIRROR_EN;
0932 }
0933
0934 ret = regmap_clear_bits(priv->regmap, reg, val);
0935 if (ret)
0936 goto err;
0937
0938 if (mirror->ingress)
0939 priv->mirror_rx &= ~BIT(port);
0940 else
0941 priv->mirror_tx &= ~BIT(port);
0942
0943
0944 if (!priv->mirror_rx && !priv->mirror_tx) {
0945 val = FIELD_PREP(QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, 0xF);
0946 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GLOBAL_FW_CTRL0,
0947 QCA8K_GLOBAL_FW_CTRL0_MIRROR_PORT_NUM, val);
0948 if (ret)
0949 goto err;
0950 }
0951 err:
0952 dev_err(priv->dev, "Failed to del mirror port from %d", port);
0953 }
0954
0955 int qca8k_port_vlan_filtering(struct dsa_switch *ds, int port,
0956 bool vlan_filtering,
0957 struct netlink_ext_ack *extack)
0958 {
0959 struct qca8k_priv *priv = ds->priv;
0960 int ret;
0961
0962 if (vlan_filtering) {
0963 ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
0964 QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
0965 QCA8K_PORT_LOOKUP_VLAN_MODE_SECURE);
0966 } else {
0967 ret = qca8k_rmw(priv, QCA8K_PORT_LOOKUP_CTRL(port),
0968 QCA8K_PORT_LOOKUP_VLAN_MODE_MASK,
0969 QCA8K_PORT_LOOKUP_VLAN_MODE_NONE);
0970 }
0971
0972 return ret;
0973 }
0974
0975 int qca8k_port_vlan_add(struct dsa_switch *ds, int port,
0976 const struct switchdev_obj_port_vlan *vlan,
0977 struct netlink_ext_ack *extack)
0978 {
0979 bool untagged = vlan->flags & BRIDGE_VLAN_INFO_UNTAGGED;
0980 bool pvid = vlan->flags & BRIDGE_VLAN_INFO_PVID;
0981 struct qca8k_priv *priv = ds->priv;
0982 int ret;
0983
0984 ret = qca8k_vlan_add(priv, port, vlan->vid, untagged);
0985 if (ret) {
0986 dev_err(priv->dev, "Failed to add VLAN to port %d (%d)", port, ret);
0987 return ret;
0988 }
0989
0990 if (pvid) {
0991 ret = qca8k_rmw(priv, QCA8K_EGRESS_VLAN(port),
0992 QCA8K_EGREES_VLAN_PORT_MASK(port),
0993 QCA8K_EGREES_VLAN_PORT(port, vlan->vid));
0994 if (ret)
0995 return ret;
0996
0997 ret = qca8k_write(priv, QCA8K_REG_PORT_VLAN_CTRL0(port),
0998 QCA8K_PORT_VLAN_CVID(vlan->vid) |
0999 QCA8K_PORT_VLAN_SVID(vlan->vid));
1000 }
1001
1002 return ret;
1003 }
1004
1005 int qca8k_port_vlan_del(struct dsa_switch *ds, int port,
1006 const struct switchdev_obj_port_vlan *vlan)
1007 {
1008 struct qca8k_priv *priv = ds->priv;
1009 int ret;
1010
1011 ret = qca8k_vlan_del(priv, port, vlan->vid);
1012 if (ret)
1013 dev_err(priv->dev, "Failed to delete VLAN from port %d (%d)", port, ret);
1014
1015 return ret;
1016 }
1017
1018 static bool qca8k_lag_can_offload(struct dsa_switch *ds,
1019 struct dsa_lag lag,
1020 struct netdev_lag_upper_info *info)
1021 {
1022 struct dsa_port *dp;
1023 int members = 0;
1024
1025 if (!lag.id)
1026 return false;
1027
1028 dsa_lag_foreach_port(dp, ds->dst, &lag)
1029
1030 members++;
1031
1032 if (members > QCA8K_NUM_PORTS_FOR_LAG)
1033 return false;
1034
1035 if (info->tx_type != NETDEV_LAG_TX_TYPE_HASH)
1036 return false;
1037
1038 if (info->hash_type != NETDEV_LAG_HASH_L2 &&
1039 info->hash_type != NETDEV_LAG_HASH_L23)
1040 return false;
1041
1042 return true;
1043 }
1044
1045 static int qca8k_lag_setup_hash(struct dsa_switch *ds,
1046 struct dsa_lag lag,
1047 struct netdev_lag_upper_info *info)
1048 {
1049 struct net_device *lag_dev = lag.dev;
1050 struct qca8k_priv *priv = ds->priv;
1051 bool unique_lag = true;
1052 unsigned int i;
1053 u32 hash = 0;
1054
1055 switch (info->hash_type) {
1056 case NETDEV_LAG_HASH_L23:
1057 hash |= QCA8K_TRUNK_HASH_SIP_EN;
1058 hash |= QCA8K_TRUNK_HASH_DIP_EN;
1059 fallthrough;
1060 case NETDEV_LAG_HASH_L2:
1061 hash |= QCA8K_TRUNK_HASH_SA_EN;
1062 hash |= QCA8K_TRUNK_HASH_DA_EN;
1063 break;
1064 default:
1065 return -EOPNOTSUPP;
1066 }
1067
1068
1069 dsa_lags_foreach_id(i, ds->dst)
1070 if (i != lag.id && dsa_lag_by_id(ds->dst, i)) {
1071 unique_lag = false;
1072 break;
1073 }
1074
1075
1076
1077
1078
1079
1080
1081
1082 if (unique_lag) {
1083 priv->lag_hash_mode = hash;
1084 } else if (priv->lag_hash_mode != hash) {
1085 netdev_err(lag_dev, "Error: Mismatched Hash Mode across different lag is not supported\n");
1086 return -EOPNOTSUPP;
1087 }
1088
1089 return regmap_update_bits(priv->regmap, QCA8K_TRUNK_HASH_EN_CTRL,
1090 QCA8K_TRUNK_HASH_MASK, hash);
1091 }
1092
1093 static int qca8k_lag_refresh_portmap(struct dsa_switch *ds, int port,
1094 struct dsa_lag lag, bool delete)
1095 {
1096 struct qca8k_priv *priv = ds->priv;
1097 int ret, id, i;
1098 u32 val;
1099
1100
1101 id = lag.id - 1;
1102
1103
1104 ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0, &val);
1105 if (ret)
1106 return ret;
1107
1108
1109 val >>= QCA8K_REG_GOL_TRUNK_SHIFT(id);
1110 val &= QCA8K_REG_GOL_TRUNK_MEMBER_MASK;
1111 if (delete)
1112 val &= ~BIT(port);
1113 else
1114 val |= BIT(port);
1115
1116
1117 ret = regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL0,
1118 QCA8K_REG_GOL_TRUNK_MEMBER(id) |
1119 QCA8K_REG_GOL_TRUNK_EN(id),
1120 !val << QCA8K_REG_GOL_TRUNK_SHIFT(id) |
1121 val << QCA8K_REG_GOL_TRUNK_SHIFT(id));
1122
1123
1124 for (i = 0; i < QCA8K_NUM_PORTS_FOR_LAG; i++) {
1125 ret = regmap_read(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id), &val);
1126 if (ret)
1127 return ret;
1128
1129 val >>= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i);
1130 val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_MASK;
1131
1132 if (delete) {
1133
1134
1135
1136 if (val != QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
1137 continue;
1138
1139 val &= QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT_MASK;
1140 if (val != port)
1141 continue;
1142 } else {
1143
1144
1145
1146 if (val == QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN_MASK)
1147 continue;
1148 }
1149
1150
1151 break;
1152 }
1153
1154
1155 return regmap_update_bits(priv->regmap, QCA8K_REG_GOL_TRUNK_CTRL(id),
1156 QCA8K_REG_GOL_TRUNK_ID_MEM_ID_EN(id, i) |
1157 QCA8K_REG_GOL_TRUNK_ID_MEM_ID_PORT(id, i),
1158 !delete << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i) |
1159 port << QCA8K_REG_GOL_TRUNK_ID_MEM_ID_SHIFT(id, i));
1160 }
1161
1162 int qca8k_port_lag_join(struct dsa_switch *ds, int port, struct dsa_lag lag,
1163 struct netdev_lag_upper_info *info)
1164 {
1165 int ret;
1166
1167 if (!qca8k_lag_can_offload(ds, lag, info))
1168 return -EOPNOTSUPP;
1169
1170 ret = qca8k_lag_setup_hash(ds, lag, info);
1171 if (ret)
1172 return ret;
1173
1174 return qca8k_lag_refresh_portmap(ds, port, lag, false);
1175 }
1176
1177 int qca8k_port_lag_leave(struct dsa_switch *ds, int port,
1178 struct dsa_lag lag)
1179 {
1180 return qca8k_lag_refresh_portmap(ds, port, lag, true);
1181 }
1182
1183 int qca8k_read_switch_id(struct qca8k_priv *priv)
1184 {
1185 u32 val;
1186 u8 id;
1187 int ret;
1188
1189 if (!priv->info)
1190 return -ENODEV;
1191
1192 ret = qca8k_read(priv, QCA8K_REG_MASK_CTRL, &val);
1193 if (ret < 0)
1194 return -ENODEV;
1195
1196 id = QCA8K_MASK_CTRL_DEVICE_ID(val);
1197 if (id != priv->info->id) {
1198 dev_err(priv->dev,
1199 "Switch id detected %x but expected %x",
1200 id, priv->info->id);
1201 return -ENODEV;
1202 }
1203
1204 priv->switch_id = id;
1205
1206
1207 priv->switch_revision = QCA8K_MASK_CTRL_REV_ID(val);
1208
1209 return 0;
1210 }