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

Merge branch 'stmmac-flow-control'

Vince Bridgers says:

====================
stmmac: Correct flow control configuration

This series of patches corrects flow control configuration for the Synopsys
GMAC driver.

Flow control is configured based on a configurable receive fifo size. If
less than 4Kbytes flow control is left disabled and a warning is presented. If
a receive fifo size is not specified, flow control is left disabled to
maintain current behavior. Unicast pause detection was disabled, but is now
enabled. The pause time was modified to be maximum time per a XON/XOFF
flow control mode of operation.

This patch was tested on an Altera Cyclone 5 and an Altera Arria 10 devkit,
and verified that flow control operates as expected when enabled.

Please consider this series for inclusion so that flow control will
function as expected for the Synopsys GMAC controller.
====================

Acked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

+111 -10
+6
Documentation/devicetree/bindings/net/ethernet.txt
··· 19 19 - phy: the same as "phy-handle" property, not recommended for new bindings. 20 20 - phy-device: the same as "phy-handle" property, not recommended for new 21 21 bindings. 22 + - rx-fifo-depth: the size of the controller's receive fifo in bytes. This 23 + is used for components that can have configurable receive fifo sizes, 24 + and is useful for determining certain configuration settings such as 25 + flow control thresholds. 26 + - tx-fifo-depth: the size of the controller's transmit fifo in bytes. This 27 + is used for components that can have configurable fifo sizes. 22 28 23 29 Child nodes of the Ethernet controller are typically the individual PHY devices 24 30 connected via the MDIO bus (sometimes the MDIO bus controller is separate).
+4
Documentation/devicetree/bindings/net/stmmac.txt
··· 45 45 If not passed then the system clock will be used and this is fine on some 46 46 platforms. 47 47 - snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register. 48 + - tx-fifo-depth: See ethernet.txt file in the same directory 49 + - rx-fifo-depth: See ethernet.txt file in the same directory 48 50 49 51 Examples: 50 52 ··· 61 59 phy-mode = "gmii"; 62 60 snps,multicast-filter-bins = <256>; 63 61 snps,perfect-filter-entries = <128>; 62 + rx-fifo-depth = <16384>; 63 + tx-fifo-depth = <16384>; 64 64 clocks = <&clock>; 65 65 clock-names = "stmmaceth"; 66 66 };
+3 -2
drivers/net/ethernet/stmicro/stmmac/common.h
··· 150 150 #define MAC_CSR_H_FRQ_MASK 0x20 151 151 152 152 #define HASH_TABLE_SIZE 64 153 - #define PAUSE_TIME 0x200 153 + #define PAUSE_TIME 0xffff 154 154 155 155 /* Flow Control defines */ 156 156 #define FLOW_OFF 0 ··· 357 357 void (*dump_regs) (void __iomem *ioaddr); 358 358 /* Set tx/rx threshold in the csr6 register 359 359 * An invalid value enables the store-and-forward mode */ 360 - void (*dma_mode) (void __iomem *ioaddr, int txmode, int rxmode); 360 + void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode, 361 + int rxfifosz); 361 362 /* To track extra statistic (if supported) */ 362 363 void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, 363 364 void __iomem *ioaddr);
+51
drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
··· 172 172 /* GMAC FLOW CTRL defines */ 173 173 #define GMAC_FLOW_CTRL_PT_MASK 0xffff0000 /* Pause Time Mask */ 174 174 #define GMAC_FLOW_CTRL_PT_SHIFT 16 175 + #define GMAC_FLOW_CTRL_UP 0x00000008 /* Unicast pause frame enable */ 175 176 #define GMAC_FLOW_CTRL_RFE 0x00000004 /* Rx Flow Control Enable */ 176 177 #define GMAC_FLOW_CTRL_TFE 0x00000002 /* Tx Flow Control Enable */ 177 178 #define GMAC_FLOW_CTRL_FCB_BPA 0x00000001 /* Flow Control Busy ... */ ··· 246 245 #define DMA_CONTROL_EFC 0x00000100 247 246 #define DMA_CONTROL_FEF 0x00000080 248 247 #define DMA_CONTROL_FUF 0x00000040 248 + 249 + /* Receive flow control activation field 250 + * RFA field in DMA control register, bits 23,10:9 251 + */ 252 + #define DMA_CONTROL_RFA_MASK 0x00800600 253 + 254 + /* Receive flow control deactivation field 255 + * RFD field in DMA control register, bits 22,12:11 256 + */ 257 + #define DMA_CONTROL_RFD_MASK 0x00401800 258 + 259 + /* RFD and RFA fields are encoded as follows 260 + * 261 + * Bit Field 262 + * 0,00 - Full minus 1KB (only valid when rxfifo >= 4KB and EFC enabled) 263 + * 0,01 - Full minus 2KB (only valid when rxfifo >= 4KB and EFC enabled) 264 + * 0,10 - Full minus 3KB (only valid when rxfifo >= 4KB and EFC enabled) 265 + * 0,11 - Full minus 4KB (only valid when rxfifo > 4KB and EFC enabled) 266 + * 1,00 - Full minus 5KB (only valid when rxfifo > 8KB and EFC enabled) 267 + * 1,01 - Full minus 6KB (only valid when rxfifo > 8KB and EFC enabled) 268 + * 1,10 - Full minus 7KB (only valid when rxfifo > 8KB and EFC enabled) 269 + * 1,11 - Reserved 270 + * 271 + * RFD should always be > RFA for a given FIFO size. RFD == RFA may work, 272 + * but packet throughput performance may not be as expected. 273 + * 274 + * Be sure that bit 3 in GMAC Register 6 is set for Unicast Pause frame 275 + * detection (IEEE Specification Requirement, Annex 31B, 31B.1, Pause 276 + * Description). 277 + * 278 + * Be sure that DZPA (bit 7 in Flow Control Register, GMAC Register 6), 279 + * is set to 0. This allows pause frames with a quanta of 0 to be sent 280 + * as an XOFF message to the link peer. 281 + */ 282 + 283 + #define RFA_FULL_MINUS_1K 0x00000000 284 + #define RFA_FULL_MINUS_2K 0x00000200 285 + #define RFA_FULL_MINUS_3K 0x00000400 286 + #define RFA_FULL_MINUS_4K 0x00000600 287 + #define RFA_FULL_MINUS_5K 0x00800000 288 + #define RFA_FULL_MINUS_6K 0x00800200 289 + #define RFA_FULL_MINUS_7K 0x00800400 290 + 291 + #define RFD_FULL_MINUS_1K 0x00000000 292 + #define RFD_FULL_MINUS_2K 0x00000800 293 + #define RFD_FULL_MINUS_3K 0x00001000 294 + #define RFD_FULL_MINUS_4K 0x00001800 295 + #define RFD_FULL_MINUS_5K 0x00400000 296 + #define RFD_FULL_MINUS_6K 0x00400800 297 + #define RFD_FULL_MINUS_7K 0x00401000 249 298 250 299 enum rtc_control { 251 300 DMA_CONTROL_RTC_64 = 0x00000000,
+4 -1
drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
··· 201 201 unsigned int fc, unsigned int pause_time) 202 202 { 203 203 void __iomem *ioaddr = hw->pcsr; 204 - unsigned int flow = 0; 204 + /* Set flow such that DZPQ in Mac Register 6 is 0, 205 + * and unicast pause detect is enabled. 206 + */ 207 + unsigned int flow = GMAC_FLOW_CTRL_UP; 205 208 206 209 pr_debug("GMAC Flow-Control:\n"); 207 210 if (fc & FLOW_RX) {
+25 -1
drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c
··· 106 106 return 0; 107 107 } 108 108 109 + static u32 dwmac1000_configure_fc(u32 csr6, int rxfifosz) 110 + { 111 + csr6 &= ~DMA_CONTROL_RFA_MASK; 112 + csr6 &= ~DMA_CONTROL_RFD_MASK; 113 + 114 + /* Leave flow control disabled if receive fifo size is less than 115 + * 4K or 0. Otherwise, send XOFF when fifo is 1K less than full, 116 + * and send XON when 2K less than full. 117 + */ 118 + if (rxfifosz < 4096) { 119 + csr6 &= ~DMA_CONTROL_EFC; 120 + pr_debug("GMAC: disabling flow control, rxfifo too small(%d)\n", 121 + rxfifosz); 122 + } else { 123 + csr6 |= DMA_CONTROL_EFC; 124 + csr6 |= RFA_FULL_MINUS_1K; 125 + csr6 |= RFD_FULL_MINUS_2K; 126 + } 127 + return csr6; 128 + } 129 + 109 130 static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode, 110 - int rxmode) 131 + int rxmode, int rxfifosz) 111 132 { 112 133 u32 csr6 = readl(ioaddr + DMA_CONTROL); 113 134 ··· 173 152 else 174 153 csr6 |= DMA_CONTROL_RTC_128; 175 154 } 155 + 156 + /* Configure flow control based on rx fifo size */ 157 + csr6 = dwmac1000_configure_fc(csr6, rxfifosz); 176 158 177 159 writel(csr6, ioaddr + DMA_CONTROL); 178 160 }
+1 -1
drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c
··· 72 72 * control register. 73 73 */ 74 74 static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode, 75 - int rxmode) 75 + int rxmode, int rxfifosz) 76 76 { 77 77 u32 csr6 = readl(ioaddr + DMA_CONTROL); 78 78
+11 -5
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
··· 1277 1277 */ 1278 1278 static void stmmac_dma_operation_mode(struct stmmac_priv *priv) 1279 1279 { 1280 + int rxfifosz = priv->plat->rx_fifo_size; 1281 + 1280 1282 if (priv->plat->force_thresh_dma_mode) 1281 - priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1283 + priv->hw->dma->dma_mode(priv->ioaddr, tc, tc, rxfifosz); 1282 1284 else if (priv->plat->force_sf_dma_mode || priv->plat->tx_coe) { 1283 1285 /* 1284 1286 * In case of GMAC, SF mode can be enabled ··· 1289 1287 * 2) There is no bugged Jumbo frame support 1290 1288 * that needs to not insert csum in the TDES. 1291 1289 */ 1292 - priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE); 1290 + priv->hw->dma->dma_mode(priv->ioaddr, SF_DMA_MODE, SF_DMA_MODE, 1291 + rxfifosz); 1293 1292 priv->xstats.threshold = SF_DMA_MODE; 1294 1293 } else 1295 - priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE); 1294 + priv->hw->dma->dma_mode(priv->ioaddr, tc, SF_DMA_MODE, 1295 + rxfifosz); 1296 1296 } 1297 1297 1298 1298 /** ··· 1446 1442 static void stmmac_dma_interrupt(struct stmmac_priv *priv) 1447 1443 { 1448 1444 int status; 1445 + int rxfifosz = priv->plat->rx_fifo_size; 1449 1446 1450 1447 status = priv->hw->dma->dma_interrupt(priv->ioaddr, &priv->xstats); 1451 1448 if (likely((status & handle_rx)) || (status & handle_tx)) { ··· 1461 1456 (tc <= 256)) { 1462 1457 tc += 64; 1463 1458 if (priv->plat->force_thresh_dma_mode) 1464 - priv->hw->dma->dma_mode(priv->ioaddr, tc, tc); 1459 + priv->hw->dma->dma_mode(priv->ioaddr, tc, tc, 1460 + rxfifosz); 1465 1461 else 1466 1462 priv->hw->dma->dma_mode(priv->ioaddr, tc, 1467 - SF_DMA_MODE); 1463 + SF_DMA_MODE, rxfifosz); 1468 1464 priv->xstats.threshold = tc; 1469 1465 } 1470 1466 } else if (unlikely(status == tx_hard_error))
+4
drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
··· 181 181 sizeof(struct stmmac_mdio_bus_data), 182 182 GFP_KERNEL); 183 183 184 + of_property_read_u32(np, "tx-fifo-depth", &plat->tx_fifo_size); 185 + 186 + of_property_read_u32(np, "rx-fifo-depth", &plat->rx_fifo_size); 187 + 184 188 plat->force_sf_dma_mode = 185 189 of_property_read_bool(np, "snps,force_sf_dma_mode"); 186 190
+2
include/linux/stmmac.h
··· 114 114 int maxmtu; 115 115 int multicast_filter_bins; 116 116 int unicast_filter_entries; 117 + int tx_fifo_size; 118 + int rx_fifo_size; 117 119 void (*fix_mac_speed)(void *priv, unsigned int speed); 118 120 void (*bus_setup)(void __iomem *ioaddr); 119 121 void *(*setup)(struct platform_device *pdev);