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

net: dsa: qca8k: convert to regmap read/write API

Convert qca8k to regmap read/write bulk API. The mgmt eth can write up
to 32 bytes of data at times. Currently we use a custom function to do
it but regmap now supports declaration of read/write bulk even without a
bus.

Drop the custom function and rework the regmap function to this new
implementation.

Rework the qca8k_fdb_read/write function to use the new
regmap_bulk_read/write as the old qca8k_bulk_read/write are now dropped.

Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Christian Marangi and committed by
David S. Miller
c766e077 e03cea60

+77 -65
+73 -19
drivers/net/dsa/qca/qca8k-8xxx.c
··· 425 425 } 426 426 427 427 static int 428 - qca8k_regmap_read(void *ctx, uint32_t reg, uint32_t *val) 428 + qca8k_read_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t *val) 429 429 { 430 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; 431 430 struct mii_bus *bus = priv->bus; 432 431 u16 r1, r2, page; 433 432 int ret; 434 - 435 - if (!qca8k_read_eth(priv, reg, val, sizeof(*val))) 436 - return 0; 437 433 438 434 qca8k_split_addr(reg, &r1, &r2, &page); 439 435 ··· 447 451 } 448 452 449 453 static int 450 - qca8k_regmap_write(void *ctx, uint32_t reg, uint32_t val) 454 + qca8k_write_mii(struct qca8k_priv *priv, uint32_t reg, uint32_t val) 451 455 { 452 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; 453 456 struct mii_bus *bus = priv->bus; 454 457 u16 r1, r2, page; 455 458 int ret; 456 - 457 - if (!qca8k_write_eth(priv, reg, &val, sizeof(val))) 458 - return 0; 459 459 460 460 qca8k_split_addr(reg, &r1, &r2, &page); 461 461 ··· 469 477 } 470 478 471 479 static int 472 - qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) 480 + qca8k_regmap_update_bits_mii(struct qca8k_priv *priv, uint32_t reg, 481 + uint32_t mask, uint32_t write_val) 473 482 { 474 - struct qca8k_priv *priv = (struct qca8k_priv *)ctx; 475 483 struct mii_bus *bus = priv->bus; 476 484 u16 r1, r2, page; 477 485 u32 val; 478 486 int ret; 479 - 480 - if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) 481 - return 0; 482 487 483 488 qca8k_split_addr(reg, &r1, &r2, &page); 484 489 ··· 499 510 return ret; 500 511 } 501 512 513 + static int 514 + qca8k_bulk_read(void *ctx, const void *reg_buf, size_t reg_len, 515 + void *val_buf, size_t val_len) 516 + { 517 + int i, count = val_len / sizeof(u32), ret; 518 + u32 reg = *(u32 *)reg_buf & U16_MAX; 519 + struct qca8k_priv *priv = ctx; 520 + 521 + if (priv->mgmt_master && 522 + !qca8k_read_eth(priv, reg, val_buf, val_len)) 523 + return 0; 524 + 525 + /* loop count times and increment reg of 4 */ 526 + for (i = 0; i < count; i++, reg += sizeof(u32)) { 527 + ret = qca8k_read_mii(priv, reg, val_buf + i); 528 + if (ret < 0) 529 + return ret; 530 + } 531 + 532 + return 0; 533 + } 534 + 535 + static int 536 + qca8k_bulk_gather_write(void *ctx, const void *reg_buf, size_t reg_len, 537 + const void *val_buf, size_t val_len) 538 + { 539 + int i, count = val_len / sizeof(u32), ret; 540 + u32 reg = *(u32 *)reg_buf & U16_MAX; 541 + struct qca8k_priv *priv = ctx; 542 + u32 *val = (u32 *)val_buf; 543 + 544 + if (priv->mgmt_master && 545 + !qca8k_write_eth(priv, reg, val, val_len)) 546 + return 0; 547 + 548 + /* loop count times, increment reg of 4 and increment val ptr to 549 + * the next value 550 + */ 551 + for (i = 0; i < count; i++, reg += sizeof(u32), val++) { 552 + ret = qca8k_write_mii(priv, reg, *val); 553 + if (ret < 0) 554 + return ret; 555 + } 556 + 557 + return 0; 558 + } 559 + 560 + static int 561 + qca8k_bulk_write(void *ctx, const void *data, size_t bytes) 562 + { 563 + return qca8k_bulk_gather_write(ctx, data, sizeof(u16), data + sizeof(u16), 564 + bytes - sizeof(u16)); 565 + } 566 + 567 + static int 568 + qca8k_regmap_update_bits(void *ctx, uint32_t reg, uint32_t mask, uint32_t write_val) 569 + { 570 + struct qca8k_priv *priv = ctx; 571 + 572 + if (!qca8k_regmap_update_bits_eth(priv, reg, mask, write_val)) 573 + return 0; 574 + 575 + return qca8k_regmap_update_bits_mii(priv, reg, mask, write_val); 576 + } 577 + 502 578 static struct regmap_config qca8k_regmap_config = { 503 579 .reg_bits = 16, 504 580 .val_bits = 32, 505 581 .reg_stride = 4, 506 582 .max_register = 0x16ac, /* end MIB - Port6 range */ 507 - .reg_read = qca8k_regmap_read, 508 - .reg_write = qca8k_regmap_write, 583 + .read = qca8k_bulk_read, 584 + .write = qca8k_bulk_write, 509 585 .reg_update_bits = qca8k_regmap_update_bits, 510 586 .rd_table = &qca8k_readable_table, 511 587 .disable_locking = true, /* Locking is handled by qca8k read/write */ 512 588 .cache_type = REGCACHE_NONE, /* Explicitly disable CACHE */ 589 + .max_raw_read = 32, /* mgmt eth can read/write up to 8 registers at time */ 590 + .max_raw_write = 32, 513 591 }; 514 592 515 593 static int ··· 2145 2089 2146 2090 static const struct qca8k_info_ops qca8xxx_ops = { 2147 2091 .autocast_mib = qca8k_get_ethtool_stats_eth, 2148 - .read_eth = qca8k_read_eth, 2149 - .write_eth = qca8k_write_eth, 2150 2092 }; 2151 2093 2152 2094 static const struct qca8k_match_data qca8327 = {
+4 -43
drivers/net/dsa/qca/qca8k-common.c
··· 101 101 .n_yes_ranges = ARRAY_SIZE(qca8k_readable_ranges), 102 102 }; 103 103 104 - /* TODO: remove these extra ops when we can support regmap bulk read/write */ 105 - static int qca8k_bulk_read(struct qca8k_priv *priv, u32 reg, u32 *val, int len) 106 - { 107 - int i, count = len / sizeof(u32), ret; 108 - 109 - if (priv->mgmt_master && priv->info->ops->read_eth && 110 - !priv->info->ops->read_eth(priv, reg, val, len)) 111 - return 0; 112 - 113 - for (i = 0; i < count; i++) { 114 - ret = regmap_read(priv->regmap, reg + (i * 4), val + i); 115 - if (ret < 0) 116 - return ret; 117 - } 118 - 119 - return 0; 120 - } 121 - 122 - /* TODO: remove these extra ops when we can support regmap bulk read/write */ 123 - static int qca8k_bulk_write(struct qca8k_priv *priv, u32 reg, u32 *val, int len) 124 - { 125 - int i, count = len / sizeof(u32), ret; 126 - u32 tmp; 127 - 128 - if (priv->mgmt_master && priv->info->ops->write_eth && 129 - !priv->info->ops->write_eth(priv, reg, val, len)) 130 - return 0; 131 - 132 - for (i = 0; i < count; i++) { 133 - tmp = val[i]; 134 - 135 - ret = regmap_write(priv->regmap, reg + (i * 4), tmp); 136 - if (ret < 0) 137 - return ret; 138 - } 139 - 140 - return 0; 141 - } 142 - 143 104 static int qca8k_busy_wait(struct qca8k_priv *priv, u32 reg, u32 mask) 144 105 { 145 106 u32 val; ··· 115 154 int ret; 116 155 117 156 /* load the ARL table into an array */ 118 - ret = qca8k_bulk_read(priv, QCA8K_REG_ATU_DATA0, reg, 119 - QCA8K_ATU_TABLE_SIZE * sizeof(u32)); 157 + ret = regmap_bulk_read(priv->regmap, QCA8K_REG_ATU_DATA0, reg, 158 + QCA8K_ATU_TABLE_SIZE); 120 159 if (ret) 121 160 return ret; 122 161 ··· 157 196 reg[0] |= FIELD_PREP(QCA8K_ATU_ADDR5_MASK, mac[5]); 158 197 159 198 /* load the array into the ARL table */ 160 - qca8k_bulk_write(priv, QCA8K_REG_ATU_DATA0, reg, 161 - QCA8K_ATU_TABLE_SIZE * sizeof(u32)); 199 + regmap_bulk_write(priv->regmap, QCA8K_REG_ATU_DATA0, reg, 200 + QCA8K_ATU_TABLE_SIZE); 162 201 } 163 202 164 203 static int qca8k_fdb_access(struct qca8k_priv *priv, enum qca8k_fdb_cmd cmd,
-3
drivers/net/dsa/qca/qca8k.h
··· 330 330 331 331 struct qca8k_info_ops { 332 332 int (*autocast_mib)(struct dsa_switch *ds, int port, u64 *data); 333 - /* TODO: remove these extra ops when we can support regmap bulk read/write */ 334 - int (*read_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); 335 - int (*write_eth)(struct qca8k_priv *priv, u32 reg, u32 *val, int len); 336 333 }; 337 334 338 335 struct qca8k_match_data {