aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/dsa
diff options
context:
space:
mode:
authorVivien Didelot <vivien.didelot@savoirfairelinux.com>2016-07-18 20:45:37 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-19 22:42:01 -0400
commit8ec61c7f7c6c75943e8c785729bd8de3440d158c (patch)
tree66cdf10f435673f02ecaa5b6f8a2938851733a64 /drivers/net/dsa
parent9bda889faed61c2b2f7c2356b6a9e577c9812cf0 (diff)
net: dsa: mv88e6xxx: add cap for IRL
Add capability flags to describe the presence of Ingress Rate Limit unit registers and an helper function to clear it. In the meantime, fix a few harmless issues: - 6185 and 6095 don't have such registers (reserved) - the previous code didn't wait for the IRL operation to complete Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com> Reviewed-by: Andrew Lunn <andrew@lunn.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/dsa')
-rw-r--r--drivers/net/dsa/mv88e6xxx/chip.c50
-rw-r--r--drivers/net/dsa/mv88e6xxx/mv88e6xxx.h23
2 files changed, 53 insertions, 20 deletions
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 34227929e388..bc26b4f3547c 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -3150,6 +3150,29 @@ static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
3150 return 0; 3150 return 0;
3151} 3151}
3152 3152
3153static int mv88e6xxx_g2_clear_irl(struct mv88e6xxx_chip *chip)
3154{
3155 int port, err;
3156
3157 /* Init all Ingress Rate Limit resources of all ports */
3158 for (port = 0; port < chip->info->num_ports; ++port) {
3159 /* XXX newer chips (like 88E6390) have different 2-bit ops */
3160 err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD,
3161 GLOBAL2_IRL_CMD_OP_INIT_ALL |
3162 (port << 8));
3163 if (err)
3164 break;
3165
3166 /* Wait for the operation to complete */
3167 err = _mv88e6xxx_wait(chip, REG_GLOBAL2, GLOBAL2_IRL_CMD,
3168 GLOBAL2_IRL_CMD_BUSY);
3169 if (err)
3170 break;
3171 }
3172
3173 return err;
3174}
3175
3153/* Indirect write to the Switch MAC/WoL/WoF register */ 3176/* Indirect write to the Switch MAC/WoL/WoF register */
3154static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip, 3177static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip,
3155 unsigned int pointer, u8 data) 3178 unsigned int pointer, u8 data)
@@ -3198,7 +3221,6 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
3198{ 3221{
3199 u16 reg; 3222 u16 reg;
3200 int err; 3223 int err;
3201 int i;
3202 3224
3203 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) { 3225 if (mv88e6xxx_has(chip, MV88E6XXX_FLAG_G2_MGMT_EN_2X)) {
3204 /* Consider the frames with reserved multicast destination 3226 /* Consider the frames with reserved multicast destination
@@ -3243,6 +3265,15 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
3243 if (err) 3265 if (err)
3244 return err; 3266 return err;
3245 3267
3268 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_IRL)) {
3269 /* Disable ingress rate limiting by resetting all per port
3270 * ingress rate limit resources to their initial state.
3271 */
3272 err = mv88e6xxx_g2_clear_irl(chip);
3273 if (err)
3274 return err;
3275 }
3276
3246 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) { 3277 if (mv88e6xxx_has(chip, MV88E6XXX_FLAGS_PVT)) {
3247 /* Initialize Cross-chip Port VLAN Table to reset defaults */ 3278 /* Initialize Cross-chip Port VLAN Table to reset defaults */
3248 err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_PVT_ADDR, 3279 err = mv88e6xxx_write(chip, REG_GLOBAL2, GLOBAL2_PVT_ADDR,
@@ -3258,23 +3289,6 @@ static int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
3258 return err; 3289 return err;
3259 } 3290 }
3260 3291
3261 if (mv88e6xxx_6352_family(chip) || mv88e6xxx_6351_family(chip) ||
3262 mv88e6xxx_6165_family(chip) || mv88e6xxx_6097_family(chip) ||
3263 mv88e6xxx_6185_family(chip) || mv88e6xxx_6095_family(chip) ||
3264 mv88e6xxx_6320_family(chip)) {
3265 /* Disable ingress rate limiting by resetting all
3266 * ingress rate limit registers to their initial
3267 * state.
3268 */
3269 for (i = 0; i < chip->info->num_ports; i++) {
3270 err = _mv88e6xxx_reg_write(chip, REG_GLOBAL2,
3271 GLOBAL2_INGRESS_OP,
3272 0x9000 | (i << 8));
3273 if (err)
3274 return err;
3275 }
3276 }
3277
3278 return 0; 3292 return 0;
3279} 3293}
3280 3294
diff --git a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
index 06b11fbf35a5..9ea5363b09b1 100644
--- a/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
+++ b/drivers/net/dsa/mv88e6xxx/mv88e6xxx.h
@@ -298,8 +298,13 @@
298#define GLOBAL2_TRUNK_MAPPING 0x08 298#define GLOBAL2_TRUNK_MAPPING 0x08
299#define GLOBAL2_TRUNK_MAPPING_UPDATE BIT(15) 299#define GLOBAL2_TRUNK_MAPPING_UPDATE BIT(15)
300#define GLOBAL2_TRUNK_MAPPING_ID_SHIFT 11 300#define GLOBAL2_TRUNK_MAPPING_ID_SHIFT 11
301#define GLOBAL2_INGRESS_OP 0x09 301#define GLOBAL2_IRL_CMD 0x09
302#define GLOBAL2_INGRESS_DATA 0x0a 302#define GLOBAL2_IRL_CMD_BUSY BIT(15)
303#define GLOBAL2_IRL_CMD_OP_INIT_ALL ((0x001 << 12) | GLOBAL2_IRL_CMD_BUSY)
304#define GLOBAL2_IRL_CMD_OP_INIT_SEL ((0x010 << 12) | GLOBAL2_IRL_CMD_BUSY)
305#define GLOBAL2_IRL_CMD_OP_WRITE_SEL ((0x011 << 12) | GLOBAL2_IRL_CMD_BUSY)
306#define GLOBAL2_IRL_CMD_OP_READ_SEL ((0x100 << 12) | GLOBAL2_IRL_CMD_BUSY)
307#define GLOBAL2_IRL_DATA 0x0a
303#define GLOBAL2_PVT_ADDR 0x0b 308#define GLOBAL2_PVT_ADDR 0x0b
304#define GLOBAL2_PVT_ADDR_BUSY BIT(15) 309#define GLOBAL2_PVT_ADDR_BUSY BIT(15)
305#define GLOBAL2_PVT_ADDR_OP_INIT_ONES ((0x01 << 12) | GLOBAL2_PVT_ADDR_BUSY) 310#define GLOBAL2_PVT_ADDR_OP_INIT_ONES ((0x01 << 12) | GLOBAL2_PVT_ADDR_BUSY)
@@ -393,6 +398,8 @@ enum mv88e6xxx_cap {
393 MV88E6XXX_CAP_GLOBAL2, 398 MV88E6XXX_CAP_GLOBAL2,
394 MV88E6XXX_CAP_G2_MGMT_EN_2X, /* (0x02) MGMT Enable Register 2x */ 399 MV88E6XXX_CAP_G2_MGMT_EN_2X, /* (0x02) MGMT Enable Register 2x */
395 MV88E6XXX_CAP_G2_MGMT_EN_0X, /* (0x03) MGMT Enable Register 0x */ 400 MV88E6XXX_CAP_G2_MGMT_EN_0X, /* (0x03) MGMT Enable Register 0x */
401 MV88E6XXX_CAP_G2_IRL_CMD, /* (0x09) Ingress Rate Command */
402 MV88E6XXX_CAP_G2_IRL_DATA, /* (0x0a) Ingress Rate Data */
396 MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */ 403 MV88E6XXX_CAP_G2_PVT_ADDR, /* (0x0b) Cross Chip Port VLAN Addr */
397 MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */ 404 MV88E6XXX_CAP_G2_PVT_DATA, /* (0x0c) Cross Chip Port VLAN Data */
398 MV88E6XXX_CAP_G2_SWITCH_MAC, /* (0x0d) Switch MAC/WoL/WoF */ 405 MV88E6XXX_CAP_G2_SWITCH_MAC, /* (0x0d) Switch MAC/WoL/WoF */
@@ -440,6 +447,8 @@ enum mv88e6xxx_cap {
440#define MV88E6XXX_FLAG_GLOBAL2 BIT(MV88E6XXX_CAP_GLOBAL2) 447#define MV88E6XXX_FLAG_GLOBAL2 BIT(MV88E6XXX_CAP_GLOBAL2)
441#define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT(MV88E6XXX_CAP_G2_MGMT_EN_2X) 448#define MV88E6XXX_FLAG_G2_MGMT_EN_2X BIT(MV88E6XXX_CAP_G2_MGMT_EN_2X)
442#define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT(MV88E6XXX_CAP_G2_MGMT_EN_0X) 449#define MV88E6XXX_FLAG_G2_MGMT_EN_0X BIT(MV88E6XXX_CAP_G2_MGMT_EN_0X)
450#define MV88E6XXX_FLAG_G2_IRL_CMD BIT(MV88E6XXX_CAP_G2_IRL_CMD)
451#define MV88E6XXX_FLAG_G2_IRL_DATA BIT(MV88E6XXX_CAP_G2_IRL_DATA)
443#define MV88E6XXX_FLAG_G2_PVT_ADDR BIT(MV88E6XXX_CAP_G2_PVT_ADDR) 452#define MV88E6XXX_FLAG_G2_PVT_ADDR BIT(MV88E6XXX_CAP_G2_PVT_ADDR)
444#define MV88E6XXX_FLAG_G2_PVT_DATA BIT(MV88E6XXX_CAP_G2_PVT_DATA) 453#define MV88E6XXX_FLAG_G2_PVT_DATA BIT(MV88E6XXX_CAP_G2_PVT_DATA)
445#define MV88E6XXX_FLAG_G2_SWITCH_MAC BIT(MV88E6XXX_CAP_G2_SWITCH_MAC) 454#define MV88E6XXX_FLAG_G2_SWITCH_MAC BIT(MV88E6XXX_CAP_G2_SWITCH_MAC)
@@ -453,6 +462,11 @@ enum mv88e6xxx_cap {
453#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT) 462#define MV88E6XXX_FLAG_TEMP_LIMIT BIT(MV88E6XXX_CAP_TEMP_LIMIT)
454#define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU) 463#define MV88E6XXX_FLAG_VTU BIT(MV88E6XXX_CAP_VTU)
455 464
465/* Ingress Rate Limit unit */
466#define MV88E6XXX_FLAGS_IRL \
467 (MV88E6XXX_FLAG_G2_IRL_CMD | \
468 MV88E6XXX_FLAG_G2_IRL_DATA)
469
456/* Cross-chip Port VLAN Table */ 470/* Cross-chip Port VLAN Table */
457#define MV88E6XXX_FLAGS_PVT \ 471#define MV88E6XXX_FLAGS_PVT \
458 (MV88E6XXX_FLAG_G2_PVT_ADDR | \ 472 (MV88E6XXX_FLAG_G2_PVT_ADDR | \
@@ -474,6 +488,7 @@ enum mv88e6xxx_cap {
474 MV88E6XXX_FLAG_PPU | \ 488 MV88E6XXX_FLAG_PPU | \
475 MV88E6XXX_FLAG_STU | \ 489 MV88E6XXX_FLAG_STU | \
476 MV88E6XXX_FLAG_VTU | \ 490 MV88E6XXX_FLAG_VTU | \
491 MV88E6XXX_FLAGS_IRL | \
477 MV88E6XXX_FLAGS_PVT) 492 MV88E6XXX_FLAGS_PVT)
478 493
479#define MV88E6XXX_FLAGS_FAMILY_6165 \ 494#define MV88E6XXX_FLAGS_FAMILY_6165 \
@@ -486,6 +501,7 @@ enum mv88e6xxx_cap {
486 MV88E6XXX_FLAG_STU | \ 501 MV88E6XXX_FLAG_STU | \
487 MV88E6XXX_FLAG_TEMP | \ 502 MV88E6XXX_FLAG_TEMP | \
488 MV88E6XXX_FLAG_VTU | \ 503 MV88E6XXX_FLAG_VTU | \
504 MV88E6XXX_FLAGS_IRL | \
489 MV88E6XXX_FLAGS_PVT) 505 MV88E6XXX_FLAGS_PVT)
490 506
491#define MV88E6XXX_FLAGS_FAMILY_6185 \ 507#define MV88E6XXX_FLAGS_FAMILY_6185 \
@@ -509,6 +525,7 @@ enum mv88e6xxx_cap {
509 MV88E6XXX_FLAG_TEMP | \ 525 MV88E6XXX_FLAG_TEMP | \
510 MV88E6XXX_FLAG_TEMP_LIMIT | \ 526 MV88E6XXX_FLAG_TEMP_LIMIT | \
511 MV88E6XXX_FLAG_VTU | \ 527 MV88E6XXX_FLAG_VTU | \
528 MV88E6XXX_FLAGS_IRL | \
512 MV88E6XXX_FLAGS_PVT) 529 MV88E6XXX_FLAGS_PVT)
513 530
514#define MV88E6XXX_FLAGS_FAMILY_6351 \ 531#define MV88E6XXX_FLAGS_FAMILY_6351 \
@@ -523,6 +540,7 @@ enum mv88e6xxx_cap {
523 MV88E6XXX_FLAG_STU | \ 540 MV88E6XXX_FLAG_STU | \
524 MV88E6XXX_FLAG_TEMP | \ 541 MV88E6XXX_FLAG_TEMP | \
525 MV88E6XXX_FLAG_VTU | \ 542 MV88E6XXX_FLAG_VTU | \
543 MV88E6XXX_FLAGS_IRL | \
526 MV88E6XXX_FLAGS_PVT) 544 MV88E6XXX_FLAGS_PVT)
527 545
528#define MV88E6XXX_FLAGS_FAMILY_6352 \ 546#define MV88E6XXX_FLAGS_FAMILY_6352 \
@@ -540,6 +558,7 @@ enum mv88e6xxx_cap {
540 MV88E6XXX_FLAG_TEMP | \ 558 MV88E6XXX_FLAG_TEMP | \
541 MV88E6XXX_FLAG_TEMP_LIMIT | \ 559 MV88E6XXX_FLAG_TEMP_LIMIT | \
542 MV88E6XXX_FLAG_VTU | \ 560 MV88E6XXX_FLAG_VTU | \
561 MV88E6XXX_FLAGS_IRL | \
543 MV88E6XXX_FLAGS_PVT) 562 MV88E6XXX_FLAGS_PVT)
544 563
545struct mv88e6xxx_info { 564struct mv88e6xxx_info {