diff options
author | Vivien Didelot <vivien.didelot@savoirfairelinux.com> | 2016-07-18 20:45:37 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-07-19 22:42:01 -0400 |
commit | 8ec61c7f7c6c75943e8c785729bd8de3440d158c (patch) | |
tree | 66cdf10f435673f02ecaa5b6f8a2938851733a64 /drivers/net/dsa | |
parent | 9bda889faed61c2b2f7c2356b6a9e577c9812cf0 (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.c | 50 | ||||
-rw-r--r-- | drivers/net/dsa/mv88e6xxx/mv88e6xxx.h | 23 |
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 | ||
3153 | static 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 */ |
3154 | static int mv88e6xxx_g2_switch_mac_write(struct mv88e6xxx_chip *chip, | 3177 | static 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 | ||
545 | struct mv88e6xxx_info { | 564 | struct mv88e6xxx_info { |