1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright (c) 2024 Pengutronix, Oleksij Rempel <kernel@pengutronix.de> 3 4 #include <linux/dsa/ksz_common.h> 5 #include <net/dsa.h> 6 #include <net/dscp.h> 7 #include <net/ieee8021q.h> 8 9 #include "ksz_common.h" 10 #include "ksz_dcb.h" 11 #include "ksz8.h" 12 13 /* Port X Control 0 register. 14 * The datasheet specifies: Port 1 - 0x10, Port 2 - 0x20, Port 3 - 0x30. 15 * However, the driver uses get_port_addr(), which maps Port 1 to offset 0. 16 * Therefore, we define the base offset as 0x00 here to align with that logic. 17 */ 18 #define KSZ8_REG_PORT_1_CTRL_0 0x00 19 #define KSZ8_PORT_DIFFSERV_ENABLE BIT(6) 20 #define KSZ8_PORT_802_1P_ENABLE BIT(5) 21 #define KSZ8_PORT_BASED_PRIO_M GENMASK(4, 3) 22 23 #define KSZ88X3_REG_TOS_DSCP_CTRL 0x60 24 #define KSZ8765_REG_TOS_DSCP_CTRL 0x90 25 26 #define KSZ9477_REG_SW_MAC_TOS_CTRL 0x033e 27 #define KSZ9477_SW_TOS_DSCP_REMAP BIT(0) 28 #define KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M GENMASK(5, 3) 29 30 #define KSZ9477_REG_DIFFSERV_PRIO_MAP 0x0340 31 32 #define KSZ9477_REG_PORT_MRI_PRIO_CTRL 0x0801 33 #define KSZ9477_PORT_HIGHEST_PRIO BIT(7) 34 #define KSZ9477_PORT_OR_PRIO BIT(6) 35 #define KSZ9477_PORT_MAC_PRIO_ENABLE BIT(4) 36 #define KSZ9477_PORT_VLAN_PRIO_ENABLE BIT(3) 37 #define KSZ9477_PORT_802_1P_PRIO_ENABLE BIT(2) 38 #define KSZ9477_PORT_DIFFSERV_PRIO_ENABLE BIT(1) 39 #define KSZ9477_PORT_ACL_PRIO_ENABLE BIT(0) 40 41 #define KSZ9477_REG_PORT_MRI_MAC_CTRL 0x0802 42 #define KSZ9477_PORT_BASED_PRIO_M GENMASK(2, 0) 43 44 struct ksz_apptrust_map { 45 u8 apptrust; 46 u8 bit; 47 }; 48 49 static const struct ksz_apptrust_map ksz8_apptrust_map_to_bit[] = { 50 { DCB_APP_SEL_PCP, KSZ8_PORT_802_1P_ENABLE }, 51 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ8_PORT_DIFFSERV_ENABLE }, 52 }; 53 54 static const struct ksz_apptrust_map ksz9477_apptrust_map_to_bit[] = { 55 { DCB_APP_SEL_PCP, KSZ9477_PORT_802_1P_PRIO_ENABLE }, 56 { IEEE_8021QAZ_APP_SEL_DSCP, KSZ9477_PORT_DIFFSERV_PRIO_ENABLE }, 57 }; 58 59 /* ksz_supported_apptrust[] - Supported apptrust selectors and Priority Order 60 * of Internal Priority Map (IPM) sources. 61 * 62 * This array defines the apptrust selectors supported by the hardware, where 63 * the index within the array indicates the priority of the selector - lower 64 * indices correspond to higher priority. This fixed priority scheme is due to 65 * the hardware's design, which does not support configurable priority among 66 * different priority sources. 67 * 68 * The priority sources, including Tail Tag, ACL, VLAN PCP and DSCP are ordered 69 * by the hardware's fixed logic, as detailed below. The order reflects a 70 * non-configurable precedence where certain types of priority information 71 * override others: 72 * 73 * 1. Tail Tag - Highest priority, overrides ACL, VLAN PCP, and DSCP priorities. 74 * 2. ACL - Overrides VLAN PCP and DSCP priorities. 75 * 3. VLAN PCP - Overrides DSCP priority. 76 * 4. DSCP - Lowest priority, does not override any other priority source. 77 * 78 * In this context, the array's lower index (higher priority) for 79 * 'DCB_APP_SEL_PCP' suggests its relative priority over 80 * 'IEEE_8021QAZ_APP_SEL_DSCP' within the system's fixed priority scheme. 81 * 82 * DCB_APP_SEL_PCP - Priority Code Point selector 83 * IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector 84 */ 85 static const u8 ksz_supported_apptrust[] = { 86 DCB_APP_SEL_PCP, 87 IEEE_8021QAZ_APP_SEL_DSCP, 88 }; 89 90 static const char * const ksz_supported_apptrust_variants[] = { 91 "empty", "dscp", "pcp", "dscp pcp" 92 }; 93 94 static void ksz_get_default_port_prio_reg(struct ksz_device *dev, int *reg, 95 u8 *mask, int *shift) 96 { 97 if (is_ksz8(dev)) { 98 *reg = KSZ8_REG_PORT_1_CTRL_0; 99 *mask = KSZ8_PORT_BASED_PRIO_M; 100 *shift = __bf_shf(KSZ8_PORT_BASED_PRIO_M); 101 } else { 102 *reg = KSZ9477_REG_PORT_MRI_MAC_CTRL; 103 *mask = KSZ9477_PORT_BASED_PRIO_M; 104 *shift = __bf_shf(KSZ9477_PORT_BASED_PRIO_M); 105 } 106 } 107 108 /** 109 * ksz_get_dscp_prio_reg - Retrieves the DSCP-to-priority-mapping register 110 * @dev: Pointer to the KSZ switch device structure 111 * @reg: Pointer to the register address to be set 112 * @per_reg: Pointer to the number of DSCP values per register 113 * @mask: Pointer to the mask to be set 114 * 115 * This function retrieves the DSCP to priority mapping register, the number of 116 * DSCP values per register, and the mask to be set. 117 */ 118 static void ksz_get_dscp_prio_reg(struct ksz_device *dev, int *reg, 119 int *per_reg, u8 *mask) 120 { 121 if (ksz_is_ksz87xx(dev) || ksz_is_8895_family(dev)) { 122 *reg = KSZ8765_REG_TOS_DSCP_CTRL; 123 *per_reg = 4; 124 *mask = GENMASK(1, 0); 125 } else if (ksz_is_ksz88x3(dev)) { 126 *reg = KSZ88X3_REG_TOS_DSCP_CTRL; 127 *per_reg = 4; 128 *mask = GENMASK(1, 0); 129 } else { 130 *reg = KSZ9477_REG_DIFFSERV_PRIO_MAP; 131 *per_reg = 2; 132 *mask = GENMASK(2, 0); 133 } 134 } 135 136 /** 137 * ksz_get_apptrust_map_and_reg - Retrieves the apptrust map and register 138 * @dev: Pointer to the KSZ switch device structure 139 * @map: Pointer to the apptrust map to be set 140 * @reg: Pointer to the register address to be set 141 * @mask: Pointer to the mask to be set 142 * 143 * This function retrieves the apptrust map and register address for the 144 * apptrust configuration. 145 */ 146 static void ksz_get_apptrust_map_and_reg(struct ksz_device *dev, 147 const struct ksz_apptrust_map **map, 148 int *reg, u8 *mask) 149 { 150 if (is_ksz8(dev)) { 151 *map = ksz8_apptrust_map_to_bit; 152 *reg = KSZ8_REG_PORT_1_CTRL_0; 153 *mask = KSZ8_PORT_DIFFSERV_ENABLE | KSZ8_PORT_802_1P_ENABLE; 154 } else { 155 *map = ksz9477_apptrust_map_to_bit; 156 *reg = KSZ9477_REG_PORT_MRI_PRIO_CTRL; 157 *mask = KSZ9477_PORT_802_1P_PRIO_ENABLE | 158 KSZ9477_PORT_DIFFSERV_PRIO_ENABLE; 159 } 160 } 161 162 /** 163 * ksz_port_get_default_prio - Retrieves the default priority for a port on a 164 * KSZ switch 165 * @ds: Pointer to the DSA switch structure 166 * @port: Port number from which to get the default priority 167 * 168 * This function fetches the default priority for the specified port on a KSZ 169 * switch. 170 * 171 * Return: The default priority of the port on success, or a negative error 172 * code on failure. 173 */ 174 int ksz_port_get_default_prio(struct dsa_switch *ds, int port) 175 { 176 struct ksz_device *dev = ds->priv; 177 int ret, reg, shift; 178 u8 data, mask; 179 180 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift); 181 182 ret = ksz_pread8(dev, port, reg, &data); 183 if (ret) 184 return ret; 185 186 return (data & mask) >> shift; 187 } 188 189 /** 190 * ksz_port_set_default_prio - Sets the default priority for a port on a KSZ 191 * switch 192 * @ds: Pointer to the DSA switch structure 193 * @port: Port number for which to set the default priority 194 * @prio: Priority value to set 195 * 196 * This function sets the default priority for the specified port on a KSZ 197 * switch. 198 * 199 * Return: 0 on success, or a negative error code on failure. 200 */ 201 int ksz_port_set_default_prio(struct dsa_switch *ds, int port, u8 prio) 202 { 203 struct ksz_device *dev = ds->priv; 204 int reg, shift; 205 u8 mask; 206 207 if (prio >= dev->info->num_ipms) 208 return -EINVAL; 209 210 ksz_get_default_port_prio_reg(dev, ®, &mask, &shift); 211 212 return ksz_prmw8(dev, port, reg, mask, (prio << shift) & mask); 213 } 214 215 /** 216 * ksz_port_get_dscp_prio - Retrieves the priority for a DSCP value on a KSZ 217 * switch 218 * @ds: Pointer to the DSA switch structure 219 * @port: Port number for which to get the priority 220 * @dscp: DSCP value for which to get the priority 221 * 222 * This function fetches the priority value from switch global DSCP-to-priorty 223 * mapping table for the specified DSCP value. 224 * 225 * Return: The priority value for the DSCP on success, or a negative error 226 * code on failure. 227 */ 228 int ksz_port_get_dscp_prio(struct dsa_switch *ds, int port, u8 dscp) 229 { 230 struct ksz_device *dev = ds->priv; 231 int reg, per_reg, ret, shift; 232 u8 data, mask; 233 234 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask); 235 236 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as Internal 237 * Priority Map (IPM) 238 */ 239 if (!is_ksz8(dev)) { 240 ret = ksz_read8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, &data); 241 if (ret) 242 return ret; 243 244 /* If DSCP remapping is disabled, DSCP bits 3-5 are used as 245 * Internal Priority Map (IPM) 246 */ 247 if (!(data & KSZ9477_SW_TOS_DSCP_REMAP)) 248 return FIELD_GET(KSZ9477_SW_TOS_DSCP_DEFAULT_PRIO_M, 249 dscp); 250 } 251 252 /* In case DSCP remapping is enabled, we need to write the DSCP to 253 * priority mapping table. 254 */ 255 reg += dscp / per_reg; 256 ret = ksz_read8(dev, reg, &data); 257 if (ret) 258 return ret; 259 260 shift = (dscp % per_reg) * (8 / per_reg); 261 262 return (data >> shift) & mask; 263 } 264 265 /** 266 * ksz_set_global_dscp_entry - Sets the global DSCP-to-priority mapping entry 267 * @dev: Pointer to the KSZ switch device structure 268 * @dscp: DSCP value for which to set the priority 269 * @ipm: Priority value to set 270 * 271 * This function sets the global DSCP-to-priority mapping entry for the 272 * specified DSCP value. 273 * 274 * Return: 0 on success, or a negative error code on failure. 275 */ 276 static int ksz_set_global_dscp_entry(struct ksz_device *dev, u8 dscp, u8 ipm) 277 { 278 int reg, per_reg, shift; 279 u8 mask; 280 281 ksz_get_dscp_prio_reg(dev, ®, &per_reg, &mask); 282 283 shift = (dscp % per_reg) * (8 / per_reg); 284 285 return ksz_rmw8(dev, reg + (dscp / per_reg), mask << shift, 286 ipm << shift); 287 } 288 289 /** 290 * ksz_init_global_dscp_map - Initializes the global DSCP-to-priority mapping 291 * @dev: Pointer to the KSZ switch device structure 292 * 293 * This function initializes the global DSCP-to-priority mapping table for the 294 * switch. 295 * 296 * Return: 0 on success, or a negative error code on failure 297 */ 298 static int ksz_init_global_dscp_map(struct ksz_device *dev) 299 { 300 int ret, dscp; 301 302 /* On KSZ9xxx variants, DSCP remapping is disabled by default. 303 * Enable to have, predictable and reproducible behavior across 304 * different devices. 305 */ 306 if (!is_ksz8(dev)) { 307 ret = ksz_rmw8(dev, KSZ9477_REG_SW_MAC_TOS_CTRL, 308 KSZ9477_SW_TOS_DSCP_REMAP, 309 KSZ9477_SW_TOS_DSCP_REMAP); 310 if (ret) 311 return ret; 312 } 313 314 for (dscp = 0; dscp < DSCP_MAX; dscp++) { 315 int ipm, tt; 316 317 /* Map DSCP to Traffic Type, which is corresponding to the 318 * Internal Priority Map (IPM) in the switch. 319 */ 320 if (!is_ksz8(dev)) { 321 ipm = ietf_dscp_to_ieee8021q_tt(dscp); 322 } else { 323 /* On KSZ8xxx variants we do not have IPM to queue 324 * remapping table. We need to convert DSCP to Traffic 325 * Type and then to queue. 326 */ 327 tt = ietf_dscp_to_ieee8021q_tt(dscp); 328 if (tt < 0) 329 return tt; 330 331 ipm = ieee8021q_tt_to_tc(tt, dev->info->num_tx_queues); 332 } 333 334 if (ipm < 0) 335 return ipm; 336 337 ret = ksz_set_global_dscp_entry(dev, dscp, ipm); 338 } 339 340 return 0; 341 } 342 343 /** 344 * ksz_port_add_dscp_prio - Adds a DSCP-to-priority mapping entry for a port on 345 * a KSZ switch. 346 * @ds: Pointer to the DSA switch structure 347 * @port: Port number for which to add the DSCP-to-priority mapping entry 348 * @dscp: DSCP value for which to add the priority 349 * @prio: Priority value to set 350 * 351 * Return: 0 on success, or a negative error code on failure 352 */ 353 int ksz_port_add_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio) 354 { 355 struct ksz_device *dev = ds->priv; 356 357 if (prio >= dev->info->num_ipms) 358 return -ERANGE; 359 360 return ksz_set_global_dscp_entry(dev, dscp, prio); 361 } 362 363 /** 364 * ksz_port_del_dscp_prio - Deletes a DSCP-to-priority mapping entry for a port 365 * on a KSZ switch. 366 * @ds: Pointer to the DSA switch structure 367 * @port: Port number for which to delete the DSCP-to-priority mapping entry 368 * @dscp: DSCP value for which to delete the priority 369 * @prio: Priority value to delete 370 * 371 * Return: 0 on success, or a negative error code on failure 372 */ 373 int ksz_port_del_dscp_prio(struct dsa_switch *ds, int port, u8 dscp, u8 prio) 374 { 375 struct ksz_device *dev = ds->priv; 376 int ipm; 377 378 if (ksz_port_get_dscp_prio(ds, port, dscp) != prio) 379 return 0; 380 381 if (is_ksz8(dev)) { 382 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE, 383 dev->info->num_tx_queues); 384 if (ipm < 0) 385 return ipm; 386 } else { 387 ipm = IEEE8021Q_TT_BE; 388 } 389 390 return ksz_set_global_dscp_entry(dev, dscp, ipm); 391 } 392 393 /** 394 * ksz_apptrust_error - Prints an error message for an invalid apptrust selector 395 * @dev: Pointer to the KSZ switch device structure 396 * 397 * This function prints an error message when an invalid apptrust selector is 398 * provided. 399 */ 400 static void ksz_apptrust_error(struct ksz_device *dev) 401 { 402 char supported_apptrust_variants[64]; 403 int i; 404 405 supported_apptrust_variants[0] = '\0'; 406 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust_variants); i++) { 407 if (i > 0) 408 strlcat(supported_apptrust_variants, ", ", 409 sizeof(supported_apptrust_variants)); 410 strlcat(supported_apptrust_variants, 411 ksz_supported_apptrust_variants[i], 412 sizeof(supported_apptrust_variants)); 413 } 414 415 dev_err(dev->dev, "Invalid apptrust selector or priority order. Supported: %s\n", 416 supported_apptrust_variants); 417 } 418 419 /** 420 * ksz_port_set_apptrust_validate - Validates the apptrust selectors 421 * @dev: Pointer to the KSZ switch device structure 422 * @port: Port number for which to set the apptrust selectors 423 * @sel: Array of apptrust selectors to validate 424 * @nsel: Number of apptrust selectors in the array 425 * 426 * This function validates the apptrust selectors provided and ensures that 427 * they are in the correct order. 428 * 429 * This family of switches supports two apptrust selectors: DCB_APP_SEL_PCP and 430 * IEEE_8021QAZ_APP_SEL_DSCP. The priority order of the selectors is fixed and 431 * cannot be changed. The order is as follows: 432 * 1. DCB_APP_SEL_PCP - Priority Code Point selector (highest priority) 433 * 2. IEEE_8021QAZ_APP_SEL_DSCP - Differentiated Services Code Point selector 434 * (lowest priority) 435 * 436 * Return: 0 on success, or a negative error code on failure 437 */ 438 static int ksz_port_set_apptrust_validate(struct ksz_device *dev, int port, 439 const u8 *sel, int nsel) 440 { 441 int i, j, found; 442 int j_prev = 0; 443 444 /* Iterate through the requested selectors */ 445 for (i = 0; i < nsel; i++) { 446 found = 0; 447 448 /* Check if the current selector is supported by the hardware */ 449 for (j = 0; j < sizeof(ksz_supported_apptrust); j++) { 450 if (sel[i] != ksz_supported_apptrust[j]) 451 continue; 452 453 found = 1; 454 455 /* Ensure that no higher priority selector (lower index) 456 * precedes a lower priority one 457 */ 458 if (i > 0 && j <= j_prev) 459 goto err_sel_not_vaild; 460 461 j_prev = j; 462 break; 463 } 464 465 if (!found) 466 goto err_sel_not_vaild; 467 } 468 469 return 0; 470 471 err_sel_not_vaild: 472 ksz_apptrust_error(dev); 473 474 return -EINVAL; 475 } 476 477 /** 478 * ksz_port_set_apptrust - Sets the apptrust selectors for a port on a KSZ 479 * switch 480 * @ds: Pointer to the DSA switch structure 481 * @port: Port number for which to set the apptrust selectors 482 * @sel: Array of apptrust selectors to set 483 * @nsel: Number of apptrust selectors in the array 484 * 485 * This function sets the apptrust selectors for the specified port on a KSZ 486 * switch. 487 * 488 * Return: 0 on success, or a negative error code on failure 489 */ 490 int ksz_port_set_apptrust(struct dsa_switch *ds, int port, 491 const u8 *sel, int nsel) 492 { 493 const struct ksz_apptrust_map *map; 494 struct ksz_device *dev = ds->priv; 495 int reg, i, ret; 496 u8 data = 0; 497 u8 mask; 498 499 ret = ksz_port_set_apptrust_validate(dev, port, sel, nsel); 500 if (ret) 501 return ret; 502 503 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask); 504 505 for (i = 0; i < nsel; i++) { 506 int j; 507 508 for (j = 0; j < ARRAY_SIZE(ksz_supported_apptrust); j++) { 509 if (sel[i] != ksz_supported_apptrust[j]) 510 continue; 511 512 data |= map[j].bit; 513 break; 514 } 515 } 516 517 return ksz_prmw8(dev, port, reg, mask, data); 518 } 519 520 /** 521 * ksz_port_get_apptrust - Retrieves the apptrust selectors for a port on a KSZ 522 * switch 523 * @ds: Pointer to the DSA switch structure 524 * @port: Port number for which to get the apptrust selectors 525 * @sel: Array to store the apptrust selectors 526 * @nsel: Number of apptrust selectors in the array 527 * 528 * This function fetches the apptrust selectors for the specified port on a KSZ 529 * switch. 530 * 531 * Return: 0 on success, or a negative error code on failure 532 */ 533 int ksz_port_get_apptrust(struct dsa_switch *ds, int port, u8 *sel, int *nsel) 534 { 535 const struct ksz_apptrust_map *map; 536 struct ksz_device *dev = ds->priv; 537 int reg, i, ret; 538 u8 data; 539 u8 mask; 540 541 ksz_get_apptrust_map_and_reg(dev, &map, ®, &mask); 542 543 ret = ksz_pread8(dev, port, reg, &data); 544 if (ret) 545 return ret; 546 547 *nsel = 0; 548 for (i = 0; i < ARRAY_SIZE(ksz_supported_apptrust); i++) { 549 if (data & map[i].bit) 550 sel[(*nsel)++] = ksz_supported_apptrust[i]; 551 } 552 553 return 0; 554 } 555 556 /** 557 * ksz_dcb_init_port - Initializes the DCB configuration for a port on a KSZ 558 * @dev: Pointer to the KSZ switch device structure 559 * @port: Port number for which to initialize the DCB configuration 560 * 561 * This function initializes the DCB configuration for the specified port on a 562 * KSZ switch. Particular DCB configuration is set for the port, including the 563 * default priority and apptrust selectors. 564 * The default priority is set to Best Effort, and the apptrust selectors are 565 * set to all supported selectors. 566 * 567 * Return: 0 on success, or a negative error code on failure 568 */ 569 int ksz_dcb_init_port(struct ksz_device *dev, int port) 570 { 571 const u8 ksz_default_apptrust[] = { DCB_APP_SEL_PCP }; 572 int ret, ipm; 573 574 if (is_ksz8(dev)) { 575 ipm = ieee8021q_tt_to_tc(IEEE8021Q_TT_BE, 576 dev->info->num_tx_queues); 577 if (ipm < 0) 578 return ipm; 579 } else { 580 ipm = IEEE8021Q_TT_BE; 581 } 582 583 /* Set the default priority for the port to Best Effort */ 584 ret = ksz_port_set_default_prio(dev->ds, port, ipm); 585 if (ret) 586 return ret; 587 588 return ksz_port_set_apptrust(dev->ds, port, ksz_default_apptrust, 589 ARRAY_SIZE(ksz_default_apptrust)); 590 } 591 592 /** 593 * ksz_dcb_init - Initializes the DCB configuration for a KSZ switch 594 * @dev: Pointer to the KSZ switch device structure 595 * 596 * This function initializes the DCB configuration for a KSZ switch. The global 597 * DSCP-to-priority mapping table is initialized. 598 * 599 * Return: 0 on success, or a negative error code on failure 600 */ 601 int ksz_dcb_init(struct ksz_device *dev) 602 { 603 return ksz_init_global_dscp_map(dev); 604 } 605