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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'net-stmmac-yet-more-eee-updates'

Russell King says:

====================
net: stmmac: yet more EEE updates

Continuing on with the STMMAC EEE cleanups from last cycle, this series
further cleans up the EEE code, and fixes a problem with the existing
implementation - disabling EEE doesn't immediately disable LPI
signalling until the next packet is transmitted. It likely also fixes
a potential race condition when trying to disable LPI vs the software
timer.
====================

Link: https://patch.msgid.link/Z6NqGnM2yL7Ayo-T@shell.armlinux.org.uk
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+155 -226
+14
drivers/net/ethernet/stmicro/stmmac/common.h
··· 530 530 #define STMMAC_DEFAULT_TWT_LS 0x1E 531 531 #define STMMAC_ET_MAX 0xFFFFF 532 532 533 + /* Common LPI register bits */ 534 + #define LPI_CTRL_STATUS_LPITCSE BIT(21) /* LPI Tx Clock Stop Enable, gmac4, xgmac2 only */ 535 + #define LPI_CTRL_STATUS_LPIATE BIT(20) /* LPI Timer Enable, gmac4 only */ 536 + #define LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */ 537 + #define LPI_CTRL_STATUS_PLSEN BIT(18) /* Enable PHY Link Status */ 538 + #define LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */ 539 + #define LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */ 540 + #define LPI_CTRL_STATUS_RLPIST BIT(9) /* Receive LPI state, gmac1000 only? */ 541 + #define LPI_CTRL_STATUS_TLPIST BIT(8) /* Transmit LPI state, gmac1000 only? */ 542 + #define LPI_CTRL_STATUS_RLPIEX BIT(3) /* Receive LPI Exit */ 543 + #define LPI_CTRL_STATUS_RLPIEN BIT(2) /* Receive LPI Entry */ 544 + #define LPI_CTRL_STATUS_TLPIEX BIT(1) /* Transmit LPI Exit */ 545 + #define LPI_CTRL_STATUS_TLPIEN BIT(0) /* Transmit LPI Entry */ 546 + 533 547 #define STMMAC_CHAIN_MODE 0x1 534 548 #define STMMAC_RING_MODE 0x2 535 549
+1 -12
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
··· 59 59 /* Energy Efficient Ethernet (EEE) 60 60 * 61 61 * LPI status, timer and control register offset 62 + * For LPI control and status bit definitions, see common.h. 62 63 */ 63 64 #define LPI_CTRL_STATUS 0x0030 64 65 #define LPI_TIMER_CTRL 0x0034 65 - 66 - /* LPI control and status defines */ 67 - #define LPI_CTRL_STATUS_LPITXA 0x00080000 /* Enable LPI TX Automate */ 68 - #define LPI_CTRL_STATUS_PLSEN 0x00040000 /* Enable PHY Link Status */ 69 - #define LPI_CTRL_STATUS_PLS 0x00020000 /* PHY Link Status */ 70 - #define LPI_CTRL_STATUS_LPIEN 0x00010000 /* LPI Enable */ 71 - #define LPI_CTRL_STATUS_RLPIST 0x00000200 /* Receive LPI state */ 72 - #define LPI_CTRL_STATUS_TLPIST 0x00000100 /* Transmit LPI state */ 73 - #define LPI_CTRL_STATUS_RLPIEX 0x00000008 /* Receive LPI Exit */ 74 - #define LPI_CTRL_STATUS_RLPIEN 0x00000004 /* Receive LPI Entry */ 75 - #define LPI_CTRL_STATUS_TLPIEX 0x00000002 /* Transmit LPI Exit */ 76 - #define LPI_CTRL_STATUS_TLPIEN 0x00000001 /* Transmit LPI Entry */ 77 66 78 67 /* GMAC HW ADDR regs */ 79 68 #define GMAC_ADDR_HIGH(reg) ((reg > 15) ? 0x00000800 + (reg - 16) * 8 : \
+12 -20
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
··· 342 342 return ret; 343 343 } 344 344 345 - static void dwmac1000_set_eee_mode(struct mac_device_info *hw, 346 - bool en_tx_lpi_clockgating) 345 + static int dwmac1000_set_lpi_mode(struct mac_device_info *hw, 346 + enum stmmac_lpi_mode mode, 347 + bool en_tx_lpi_clockgating, u32 et) 347 348 { 348 349 void __iomem *ioaddr = hw->pcsr; 349 350 u32 value; 350 351 351 - /*TODO - en_tx_lpi_clockgating treatment */ 352 - 353 - /* Enable the link status receive on RGMII, SGMII ore SMII 354 - * receive path and instruct the transmit to enter in LPI 355 - * state. 356 - */ 357 - value = readl(ioaddr + LPI_CTRL_STATUS); 358 - value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 359 - writel(value, ioaddr + LPI_CTRL_STATUS); 360 - } 361 - 362 - static void dwmac1000_reset_eee_mode(struct mac_device_info *hw) 363 - { 364 - void __iomem *ioaddr = hw->pcsr; 365 - u32 value; 352 + if (mode == STMMAC_LPI_TIMER) 353 + return -EOPNOTSUPP; 366 354 367 355 value = readl(ioaddr + LPI_CTRL_STATUS); 368 - value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA); 356 + if (mode == STMMAC_LPI_FORCED) 357 + value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 358 + else 359 + value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA); 369 360 writel(value, ioaddr + LPI_CTRL_STATUS); 361 + 362 + return 0; 370 363 } 371 364 372 365 static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link) ··· 502 509 .pmt = dwmac1000_pmt, 503 510 .set_umac_addr = dwmac1000_set_umac_addr, 504 511 .get_umac_addr = dwmac1000_get_umac_addr, 505 - .set_eee_mode = dwmac1000_set_eee_mode, 506 - .reset_eee_mode = dwmac1000_reset_eee_mode, 512 + .set_lpi_mode = dwmac1000_set_lpi_mode, 507 513 .set_eee_timer = dwmac1000_set_eee_timer, 508 514 .set_eee_pls = dwmac1000_set_eee_pls, 509 515 .debug = dwmac1000_debug,
+1 -11
drivers/net/ethernet/stmicro/stmmac/dwmac4.h
··· 177 177 /* Energy Efficient Ethernet (EEE) for GMAC4 178 178 * 179 179 * LPI status, timer and control register offset 180 + * For LPI control and status bit definitions, see common.h. 180 181 */ 181 182 #define GMAC4_LPI_CTRL_STATUS 0xd0 182 183 #define GMAC4_LPI_TIMER_CTRL 0xd4 183 184 #define GMAC4_LPI_ENTRY_TIMER 0xd8 184 185 #define GMAC4_MAC_ONEUS_TIC_COUNTER 0xdc 185 - 186 - /* LPI control and status defines */ 187 - #define GMAC4_LPI_CTRL_STATUS_LPITCSE BIT(21) /* LPI Tx Clock Stop Enable */ 188 - #define GMAC4_LPI_CTRL_STATUS_LPIATE BIT(20) /* LPI Timer Enable */ 189 - #define GMAC4_LPI_CTRL_STATUS_LPITXA BIT(19) /* Enable LPI TX Automate */ 190 - #define GMAC4_LPI_CTRL_STATUS_PLS BIT(17) /* PHY Link Status */ 191 - #define GMAC4_LPI_CTRL_STATUS_LPIEN BIT(16) /* LPI Enable */ 192 - #define GMAC4_LPI_CTRL_STATUS_RLPIEX BIT(3) /* Receive LPI Exit */ 193 - #define GMAC4_LPI_CTRL_STATUS_RLPIEN BIT(2) /* Receive LPI Entry */ 194 - #define GMAC4_LPI_CTRL_STATUS_TLPIEX BIT(1) /* Transmit LPI Exit */ 195 - #define GMAC4_LPI_CTRL_STATUS_TLPIEN BIT(0) /* Transmit LPI Entry */ 196 186 197 187 /* MAC Debug bitmap */ 198 188 #define GMAC_DEBUG_TFCSTS_MASK GENMASK(18, 17)
+42 -56
drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
··· 376 376 GMAC_ADDR_LOW(reg_n)); 377 377 } 378 378 379 - static void dwmac4_set_eee_mode(struct mac_device_info *hw, 380 - bool en_tx_lpi_clockgating) 379 + static int dwmac4_set_lpi_mode(struct mac_device_info *hw, 380 + enum stmmac_lpi_mode mode, 381 + bool en_tx_lpi_clockgating, u32 et) 381 382 { 382 383 void __iomem *ioaddr = hw->pcsr; 383 - u32 value; 384 + u32 value, mask; 384 385 385 - /* Enable the link status receive on RGMII, SGMII ore SMII 386 - * receive path and instruct the transmit to enter in LPI 387 - * state. 388 - */ 389 - value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 390 - value |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA; 386 + if (mode == STMMAC_LPI_DISABLE) { 387 + value = 0; 388 + } else { 389 + value = LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 391 390 392 - if (en_tx_lpi_clockgating) 393 - value |= GMAC4_LPI_CTRL_STATUS_LPITCSE; 391 + if (mode == STMMAC_LPI_TIMER) { 392 + /* Return ERANGE if the timer is larger than the 393 + * register field. 394 + */ 395 + if (et > STMMAC_ET_MAX) 396 + return -ERANGE; 394 397 398 + /* Set the hardware LPI entry timer */ 399 + writel(et, ioaddr + GMAC4_LPI_ENTRY_TIMER); 400 + 401 + /* Interpret a zero LPI entry timer to mean 402 + * immediate entry into LPI mode. 403 + */ 404 + if (et) 405 + value |= LPI_CTRL_STATUS_LPIATE; 406 + } 407 + 408 + if (en_tx_lpi_clockgating) 409 + value |= LPI_CTRL_STATUS_LPITCSE; 410 + } 411 + 412 + mask = LPI_CTRL_STATUS_LPIATE | LPI_CTRL_STATUS_LPIEN | 413 + LPI_CTRL_STATUS_LPITXA | LPI_CTRL_STATUS_LPITCSE; 414 + 415 + value |= readl(ioaddr + GMAC4_LPI_CTRL_STATUS) & ~mask; 395 416 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); 396 - } 397 417 398 - static void dwmac4_reset_eee_mode(struct mac_device_info *hw) 399 - { 400 - void __iomem *ioaddr = hw->pcsr; 401 - u32 value; 402 - 403 - value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 404 - value &= ~(GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA); 405 - writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); 418 + return 0; 406 419 } 407 420 408 421 static void dwmac4_set_eee_pls(struct mac_device_info *hw, int link) ··· 426 413 value = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 427 414 428 415 if (link) 429 - value |= GMAC4_LPI_CTRL_STATUS_PLS; 416 + value |= LPI_CTRL_STATUS_PLS; 430 417 else 431 - value &= ~GMAC4_LPI_CTRL_STATUS_PLS; 418 + value &= ~LPI_CTRL_STATUS_PLS; 432 419 433 420 writel(value, ioaddr + GMAC4_LPI_CTRL_STATUS); 434 - } 435 - 436 - static void dwmac4_set_eee_lpi_entry_timer(struct mac_device_info *hw, u32 et) 437 - { 438 - void __iomem *ioaddr = hw->pcsr; 439 - u32 value = et & STMMAC_ET_MAX; 440 - int regval; 441 - 442 - /* Program LPI entry timer value into register */ 443 - writel(value, ioaddr + GMAC4_LPI_ENTRY_TIMER); 444 - 445 - /* Enable/disable LPI entry timer */ 446 - regval = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 447 - regval |= GMAC4_LPI_CTRL_STATUS_LPIEN | GMAC4_LPI_CTRL_STATUS_LPITXA; 448 - 449 - if (et) 450 - regval |= GMAC4_LPI_CTRL_STATUS_LPIATE; 451 - else 452 - regval &= ~GMAC4_LPI_CTRL_STATUS_LPIATE; 453 - 454 - writel(regval, ioaddr + GMAC4_LPI_CTRL_STATUS); 455 421 } 456 422 457 423 static void dwmac4_set_eee_timer(struct mac_device_info *hw, int ls, int tw) ··· 841 849 /* Clear LPI interrupt by reading MAC_LPI_Control_Status */ 842 850 u32 status = readl(ioaddr + GMAC4_LPI_CTRL_STATUS); 843 851 844 - if (status & GMAC4_LPI_CTRL_STATUS_TLPIEN) { 852 + if (status & LPI_CTRL_STATUS_TLPIEN) { 845 853 ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE; 846 854 x->irq_tx_path_in_lpi_mode_n++; 847 855 } 848 - if (status & GMAC4_LPI_CTRL_STATUS_TLPIEX) { 856 + if (status & LPI_CTRL_STATUS_TLPIEX) { 849 857 ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE; 850 858 x->irq_tx_path_exit_lpi_mode_n++; 851 859 } 852 - if (status & GMAC4_LPI_CTRL_STATUS_RLPIEN) 860 + if (status & LPI_CTRL_STATUS_RLPIEN) 853 861 x->irq_rx_path_in_lpi_mode_n++; 854 - if (status & GMAC4_LPI_CTRL_STATUS_RLPIEX) 862 + if (status & LPI_CTRL_STATUS_RLPIEX) 855 863 x->irq_rx_path_exit_lpi_mode_n++; 856 864 } 857 865 ··· 1193 1201 .pmt = dwmac4_pmt, 1194 1202 .set_umac_addr = dwmac4_set_umac_addr, 1195 1203 .get_umac_addr = dwmac4_get_umac_addr, 1196 - .set_eee_mode = dwmac4_set_eee_mode, 1197 - .reset_eee_mode = dwmac4_reset_eee_mode, 1198 - .set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer, 1204 + .set_lpi_mode = dwmac4_set_lpi_mode, 1199 1205 .set_eee_timer = dwmac4_set_eee_timer, 1200 1206 .set_eee_pls = dwmac4_set_eee_pls, 1201 1207 .pcs_ctrl_ane = dwmac4_ctrl_ane, ··· 1235 1245 .pmt = dwmac4_pmt, 1236 1246 .set_umac_addr = dwmac4_set_umac_addr, 1237 1247 .get_umac_addr = dwmac4_get_umac_addr, 1238 - .set_eee_mode = dwmac4_set_eee_mode, 1239 - .reset_eee_mode = dwmac4_reset_eee_mode, 1240 - .set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer, 1248 + .set_lpi_mode = dwmac4_set_lpi_mode, 1241 1249 .set_eee_timer = dwmac4_set_eee_timer, 1242 1250 .set_eee_pls = dwmac4_set_eee_pls, 1243 1251 .pcs_ctrl_ane = dwmac4_ctrl_ane, ··· 1279 1291 .pmt = dwmac4_pmt, 1280 1292 .set_umac_addr = dwmac4_set_umac_addr, 1281 1293 .get_umac_addr = dwmac4_get_umac_addr, 1282 - .set_eee_mode = dwmac4_set_eee_mode, 1283 - .reset_eee_mode = dwmac4_reset_eee_mode, 1284 - .set_eee_lpi_entry_timer = dwmac4_set_eee_lpi_entry_timer, 1294 + .set_lpi_mode = dwmac4_set_lpi_mode, 1285 1295 .set_eee_timer = dwmac4_set_eee_timer, 1286 1296 .set_eee_pls = dwmac4_set_eee_pls, 1287 1297 .pcs_ctrl_ane = dwmac4_ctrl_ane,
+1 -8
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
··· 112 112 #define XGMAC_MGKPKTEN BIT(1) 113 113 #define XGMAC_PWRDWN BIT(0) 114 114 #define XGMAC_LPI_CTRL 0x000000d0 115 - #define XGMAC_TXCGE BIT(21) 116 - #define XGMAC_LPITXA BIT(19) 117 - #define XGMAC_PLS BIT(17) 118 - #define XGMAC_LPITXEN BIT(16) 119 - #define XGMAC_RLPIEX BIT(3) 120 - #define XGMAC_RLPIEN BIT(2) 121 - #define XGMAC_TLPIEX BIT(1) 122 - #define XGMAC_TLPIEN BIT(0) 115 + /* For definitions, see LPI_CTRL_STATUS_xxx in common.h */ 123 116 #define XGMAC_LPI_TIMER_CTRL 0x000000d4 124 117 #define XGMAC_HW_FEATURE0 0x0000011c 125 118 #define XGMAC_HWFEAT_EDMA BIT(31)
+23 -26
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_core.c
··· 316 316 if (stat & XGMAC_LPIIS) { 317 317 u32 lpi = readl(ioaddr + XGMAC_LPI_CTRL); 318 318 319 - if (lpi & XGMAC_TLPIEN) { 319 + if (lpi & LPI_CTRL_STATUS_TLPIEN) { 320 320 ret |= CORE_IRQ_TX_PATH_IN_LPI_MODE; 321 321 x->irq_tx_path_in_lpi_mode_n++; 322 322 } 323 - if (lpi & XGMAC_TLPIEX) { 323 + if (lpi & LPI_CTRL_STATUS_TLPIEX) { 324 324 ret |= CORE_IRQ_TX_PATH_EXIT_LPI_MODE; 325 325 x->irq_tx_path_exit_lpi_mode_n++; 326 326 } 327 - if (lpi & XGMAC_RLPIEN) 327 + if (lpi & LPI_CTRL_STATUS_RLPIEN) 328 328 x->irq_rx_path_in_lpi_mode_n++; 329 - if (lpi & XGMAC_RLPIEX) 329 + if (lpi & LPI_CTRL_STATUS_RLPIEX) 330 330 x->irq_rx_path_exit_lpi_mode_n++; 331 331 } 332 332 ··· 425 425 addr[5] = (hi_addr >> 8) & 0xff; 426 426 } 427 427 428 - static void dwxgmac2_set_eee_mode(struct mac_device_info *hw, 429 - bool en_tx_lpi_clockgating) 428 + static int dwxgmac2_set_lpi_mode(struct mac_device_info *hw, 429 + enum stmmac_lpi_mode mode, 430 + bool en_tx_lpi_clockgating, u32 et) 430 431 { 431 432 void __iomem *ioaddr = hw->pcsr; 432 433 u32 value; 433 434 434 - value = readl(ioaddr + XGMAC_LPI_CTRL); 435 - 436 - value |= XGMAC_LPITXEN | XGMAC_LPITXA; 437 - if (en_tx_lpi_clockgating) 438 - value |= XGMAC_TXCGE; 439 - 440 - writel(value, ioaddr + XGMAC_LPI_CTRL); 441 - } 442 - 443 - static void dwxgmac2_reset_eee_mode(struct mac_device_info *hw) 444 - { 445 - void __iomem *ioaddr = hw->pcsr; 446 - u32 value; 435 + if (mode == STMMAC_LPI_TIMER) 436 + return -EOPNOTSUPP; 447 437 448 438 value = readl(ioaddr + XGMAC_LPI_CTRL); 449 - value &= ~(XGMAC_LPITXEN | XGMAC_LPITXA | XGMAC_TXCGE); 439 + if (mode == STMMAC_LPI_FORCED) { 440 + value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA; 441 + if (en_tx_lpi_clockgating) 442 + value |= LPI_CTRL_STATUS_LPITCSE; 443 + } else { 444 + value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA | 445 + LPI_CTRL_STATUS_LPITCSE); 446 + } 450 447 writel(value, ioaddr + XGMAC_LPI_CTRL); 448 + 449 + return 0; 451 450 } 452 451 453 452 static void dwxgmac2_set_eee_pls(struct mac_device_info *hw, int link) ··· 456 457 457 458 value = readl(ioaddr + XGMAC_LPI_CTRL); 458 459 if (link) 459 - value |= XGMAC_PLS; 460 + value |= LPI_CTRL_STATUS_PLS; 460 461 else 461 - value &= ~XGMAC_PLS; 462 + value &= ~LPI_CTRL_STATUS_PLS; 462 463 writel(value, ioaddr + XGMAC_LPI_CTRL); 463 464 } 464 465 ··· 1524 1525 .pmt = dwxgmac2_pmt, 1525 1526 .set_umac_addr = dwxgmac2_set_umac_addr, 1526 1527 .get_umac_addr = dwxgmac2_get_umac_addr, 1527 - .set_eee_mode = dwxgmac2_set_eee_mode, 1528 - .reset_eee_mode = dwxgmac2_reset_eee_mode, 1528 + .set_lpi_mode = dwxgmac2_set_lpi_mode, 1529 1529 .set_eee_timer = dwxgmac2_set_eee_timer, 1530 1530 .set_eee_pls = dwxgmac2_set_eee_pls, 1531 1531 .debug = NULL, ··· 1580 1582 .pmt = dwxgmac2_pmt, 1581 1583 .set_umac_addr = dwxgmac2_set_umac_addr, 1582 1584 .get_umac_addr = dwxgmac2_get_umac_addr, 1583 - .set_eee_mode = dwxgmac2_set_eee_mode, 1584 - .reset_eee_mode = dwxgmac2_reset_eee_mode, 1585 + .set_lpi_mode = dwxgmac2_set_lpi_mode, 1585 1586 .set_eee_timer = dwxgmac2_set_eee_timer, 1586 1587 .set_eee_pls = dwxgmac2_set_eee_pls, 1587 1588 .debug = NULL,
+11 -10
drivers/net/ethernet/stmicro/stmmac/hwif.h
··· 306 306 struct stmmac_rss; 307 307 struct stmmac_est; 308 308 309 + enum stmmac_lpi_mode { 310 + STMMAC_LPI_DISABLE, 311 + STMMAC_LPI_FORCED, 312 + STMMAC_LPI_TIMER, 313 + }; 314 + 309 315 /* Helpers to program the MAC core */ 310 316 struct stmmac_ops { 311 317 /* MAC core initialization */ ··· 366 360 unsigned int reg_n); 367 361 void (*get_umac_addr)(struct mac_device_info *hw, unsigned char *addr, 368 362 unsigned int reg_n); 369 - void (*set_eee_mode)(struct mac_device_info *hw, 370 - bool en_tx_lpi_clockgating); 371 - void (*reset_eee_mode)(struct mac_device_info *hw); 372 - void (*set_eee_lpi_entry_timer)(struct mac_device_info *hw, u32 et); 363 + int (*set_lpi_mode)(struct mac_device_info *hw, 364 + enum stmmac_lpi_mode mode, 365 + bool en_tx_lpi_clockgating, u32 et); 373 366 void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw); 374 367 void (*set_eee_pls)(struct mac_device_info *hw, int link); 375 368 void (*debug)(struct stmmac_priv *priv, void __iomem *ioaddr, ··· 472 467 stmmac_do_void_callback(__priv, mac, set_umac_addr, __args) 473 468 #define stmmac_get_umac_addr(__priv, __args...) \ 474 469 stmmac_do_void_callback(__priv, mac, get_umac_addr, __args) 475 - #define stmmac_set_eee_mode(__priv, __args...) \ 476 - stmmac_do_void_callback(__priv, mac, set_eee_mode, __args) 477 - #define stmmac_reset_eee_mode(__priv, __args...) \ 478 - stmmac_do_void_callback(__priv, mac, reset_eee_mode, __args) 479 - #define stmmac_set_eee_lpi_timer(__priv, __args...) \ 480 - stmmac_do_void_callback(__priv, mac, set_eee_lpi_entry_timer, __args) 470 + #define stmmac_set_lpi_mode(__priv, __args...) \ 471 + stmmac_do_callback(__priv, mac, set_lpi_mode, __args) 481 472 #define stmmac_set_eee_timer(__priv, __args...) \ 482 473 stmmac_do_void_callback(__priv, mac, set_eee_timer, __args) 483 474 #define stmmac_set_eee_pls(__priv, __args...) \
+50 -83
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 390 390 return dirty; 391 391 } 392 392 393 - static void stmmac_disable_hw_lpi_timer(struct stmmac_priv *priv) 394 - { 395 - stmmac_set_eee_lpi_timer(priv, priv->hw, 0); 396 - } 397 - 398 - static void stmmac_enable_hw_lpi_timer(struct stmmac_priv *priv) 399 - { 400 - stmmac_set_eee_lpi_timer(priv, priv->hw, priv->tx_lpi_timer); 401 - } 402 - 403 393 static bool stmmac_eee_tx_busy(struct stmmac_priv *priv) 404 394 { 405 395 u32 tx_cnt = priv->plat->tx_queues_to_use; ··· 426 436 427 437 /* Check and enter in LPI mode */ 428 438 if (!priv->tx_path_in_lpi_mode) 429 - stmmac_set_eee_mode(priv, priv->hw, 430 - priv->plat->flags & STMMAC_FLAG_EN_TX_LPI_CLOCKGATING); 439 + stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_FORCED, 440 + priv->plat->flags & STMMAC_FLAG_EN_TX_LPI_CLOCKGATING, 441 + 0); 431 442 } 432 443 433 444 /** ··· 438 447 */ 439 448 static void stmmac_stop_sw_lpi(struct stmmac_priv *priv) 440 449 { 441 - stmmac_reset_eee_mode(priv, priv->hw); 442 450 del_timer_sync(&priv->eee_ctrl_timer); 451 + stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_DISABLE, false, 0); 443 452 priv->tx_path_in_lpi_mode = false; 444 453 } 445 454 ··· 455 464 struct stmmac_priv *priv = from_timer(priv, t, eee_ctrl_timer); 456 465 457 466 stmmac_try_to_start_sw_lpi(priv); 458 - } 459 - 460 - /** 461 - * stmmac_eee_init - init EEE 462 - * @priv: driver private structure 463 - * @active: indicates whether EEE should be enabled. 464 - * Description: 465 - * if the GMAC supports the EEE (from the HW cap reg) and the phy device 466 - * can also manage EEE, this function enable the LPI state and start related 467 - * timer. 468 - */ 469 - static void stmmac_eee_init(struct stmmac_priv *priv, bool active) 470 - { 471 - priv->eee_active = active; 472 - 473 - /* Check if MAC core supports the EEE feature. */ 474 - if (!priv->dma_cap.eee) { 475 - priv->eee_enabled = false; 476 - return; 477 - } 478 - 479 - mutex_lock(&priv->lock); 480 - 481 - /* Check if it needs to be deactivated */ 482 - if (!priv->eee_active) { 483 - if (priv->eee_enabled) { 484 - netdev_dbg(priv->dev, "disable EEE\n"); 485 - priv->eee_sw_timer_en = false; 486 - stmmac_disable_hw_lpi_timer(priv); 487 - del_timer_sync(&priv->eee_ctrl_timer); 488 - stmmac_set_eee_timer(priv, priv->hw, 0, 489 - STMMAC_DEFAULT_TWT_LS); 490 - if (priv->hw->xpcs) 491 - xpcs_config_eee(priv->hw->xpcs, 492 - priv->plat->mult_fact_100ns, 493 - false); 494 - } 495 - priv->eee_enabled = false; 496 - mutex_unlock(&priv->lock); 497 - return; 498 - } 499 - 500 - if (priv->eee_active && !priv->eee_enabled) { 501 - stmmac_set_eee_timer(priv, priv->hw, STMMAC_DEFAULT_LIT_LS, 502 - STMMAC_DEFAULT_TWT_LS); 503 - if (priv->hw->xpcs) 504 - xpcs_config_eee(priv->hw->xpcs, 505 - priv->plat->mult_fact_100ns, 506 - true); 507 - } 508 - 509 - if (priv->plat->has_gmac4 && priv->tx_lpi_timer <= STMMAC_ET_MAX) { 510 - /* Use hardware LPI mode */ 511 - del_timer_sync(&priv->eee_ctrl_timer); 512 - priv->tx_path_in_lpi_mode = false; 513 - priv->eee_sw_timer_en = false; 514 - stmmac_enable_hw_lpi_timer(priv); 515 - } else { 516 - /* Use software LPI mode */ 517 - priv->eee_sw_timer_en = true; 518 - stmmac_disable_hw_lpi_timer(priv); 519 - stmmac_restart_sw_lpi_timer(priv); 520 - } 521 - 522 - priv->eee_enabled = true; 523 - 524 - mutex_unlock(&priv->lock); 525 - netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n"); 526 467 } 527 468 528 469 /* stmmac_get_tx_hwtstamp - get HW TX timestamps ··· 1033 1110 { 1034 1111 struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); 1035 1112 1036 - stmmac_eee_init(priv, false); 1113 + priv->eee_active = false; 1114 + 1115 + mutex_lock(&priv->lock); 1116 + 1117 + priv->eee_enabled = false; 1118 + 1119 + netdev_dbg(priv->dev, "disable EEE\n"); 1120 + priv->eee_sw_timer_en = false; 1121 + del_timer_sync(&priv->eee_ctrl_timer); 1122 + stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_DISABLE, false, 0); 1123 + priv->tx_path_in_lpi_mode = false; 1124 + 1125 + stmmac_set_eee_timer(priv, priv->hw, 0, STMMAC_DEFAULT_TWT_LS); 1126 + if (priv->hw->xpcs) 1127 + xpcs_config_eee(priv->hw->xpcs, priv->plat->mult_fact_100ns, 1128 + false); 1129 + 1130 + mutex_unlock(&priv->lock); 1037 1131 } 1038 1132 1039 1133 static int stmmac_mac_enable_tx_lpi(struct phylink_config *config, u32 timer, 1040 1134 bool tx_clk_stop) 1041 1135 { 1042 1136 struct stmmac_priv *priv = netdev_priv(to_net_dev(config->dev)); 1137 + int ret; 1043 1138 1044 1139 priv->tx_lpi_timer = timer; 1045 - stmmac_eee_init(priv, true); 1140 + priv->eee_active = true; 1141 + 1142 + mutex_lock(&priv->lock); 1143 + 1144 + priv->eee_enabled = true; 1145 + 1146 + stmmac_set_eee_timer(priv, priv->hw, STMMAC_DEFAULT_LIT_LS, 1147 + STMMAC_DEFAULT_TWT_LS); 1148 + if (priv->hw->xpcs) 1149 + xpcs_config_eee(priv->hw->xpcs, priv->plat->mult_fact_100ns, 1150 + true); 1151 + 1152 + /* Try to cnfigure the hardware timer. */ 1153 + ret = stmmac_set_lpi_mode(priv, priv->hw, STMMAC_LPI_TIMER, 1154 + priv->plat->flags & STMMAC_FLAG_EN_TX_LPI_CLOCKGATING, 1155 + priv->tx_lpi_timer); 1156 + 1157 + if (ret) { 1158 + /* Hardware timer mode not supported, or value out of range. 1159 + * Fall back to using software LPI mode 1160 + */ 1161 + priv->eee_sw_timer_en = true; 1162 + stmmac_restart_sw_lpi_timer(priv); 1163 + } 1164 + 1165 + mutex_unlock(&priv->lock); 1166 + netdev_dbg(priv->dev, "Energy-Efficient Ethernet initialized\n"); 1046 1167 1047 1168 return 0; 1048 1169 }