2 * This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 * DWC Ether MAC version 4.00 has been used for developing this code.
5 * This only implements the mac core functions for this chip.
7 * Copyright (C) 2015 STMicroelectronics Ltd
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
13 * Author: Alexandre Torgue <alexandre.torgue@st.com>
16 #include <linux/crc32.h>
17 #include <linux/slab.h>
18 #include <linux/ethtool.h>
22 static void dwmac4_core_init(struct mac_device_info
*hw
, int mtu
)
24 void __iomem
*ioaddr
= hw
->pcsr
;
25 u32 value
= readl(ioaddr
+ GMAC_CONFIG
);
27 value
|= GMAC_CORE_INIT
;
30 value
|= GMAC_CONFIG_2K
;
32 value
|= GMAC_CONFIG_JE
;
34 writel(value
, ioaddr
+ GMAC_CONFIG
);
36 /* Mask GMAC interrupts */
37 writel(GMAC_INT_PMT_EN
, ioaddr
+ GMAC_INT_EN
);
40 static void dwmac4_dump_regs(struct mac_device_info
*hw
)
42 void __iomem
*ioaddr
= hw
->pcsr
;
45 pr_debug("\tDWMAC4 regs (base addr = 0x%p)\n", ioaddr
);
47 for (i
= 0; i
< GMAC_REG_NUM
; i
++) {
50 pr_debug("\tReg No. %d (offset 0x%x): 0x%08x\n", i
,
51 offset
, readl(ioaddr
+ offset
));
55 static int dwmac4_rx_ipc_enable(struct mac_device_info
*hw
)
57 void __iomem
*ioaddr
= hw
->pcsr
;
58 u32 value
= readl(ioaddr
+ GMAC_CONFIG
);
61 value
|= GMAC_CONFIG_IPC
;
63 value
&= ~GMAC_CONFIG_IPC
;
65 writel(value
, ioaddr
+ GMAC_CONFIG
);
67 value
= readl(ioaddr
+ GMAC_CONFIG
);
69 return !!(value
& GMAC_CONFIG_IPC
);
72 static void dwmac4_pmt(struct mac_device_info
*hw
, unsigned long mode
)
74 void __iomem
*ioaddr
= hw
->pcsr
;
77 if (mode
& WAKE_MAGIC
) {
78 pr_debug("GMAC: WOL Magic frame\n");
79 pmt
|= power_down
| magic_pkt_en
;
81 if (mode
& WAKE_UCAST
) {
82 pr_debug("GMAC: WOL on global unicast\n");
83 pmt
|= global_unicast
;
86 writel(pmt
, ioaddr
+ GMAC_PMT
);
89 static void dwmac4_set_umac_addr(struct mac_device_info
*hw
,
90 unsigned char *addr
, unsigned int reg_n
)
92 void __iomem
*ioaddr
= hw
->pcsr
;
94 stmmac_dwmac4_set_mac_addr(ioaddr
, addr
, GMAC_ADDR_HIGH(reg_n
),
95 GMAC_ADDR_LOW(reg_n
));
98 static void dwmac4_get_umac_addr(struct mac_device_info
*hw
,
99 unsigned char *addr
, unsigned int reg_n
)
101 void __iomem
*ioaddr
= hw
->pcsr
;
103 stmmac_dwmac4_get_mac_addr(ioaddr
, addr
, GMAC_ADDR_HIGH(reg_n
),
104 GMAC_ADDR_LOW(reg_n
));
107 static void dwmac4_set_filter(struct mac_device_info
*hw
,
108 struct net_device
*dev
)
110 void __iomem
*ioaddr
= (void __iomem
*)dev
->base_addr
;
111 unsigned int value
= 0;
113 if (dev
->flags
& IFF_PROMISC
) {
114 value
= GMAC_PACKET_FILTER_PR
;
115 } else if ((dev
->flags
& IFF_ALLMULTI
) ||
116 (netdev_mc_count(dev
) > HASH_TABLE_SIZE
)) {
118 value
= GMAC_PACKET_FILTER_PM
;
119 /* Set the 64 bits of the HASH tab. To be updated if taller
122 writel(0xffffffff, ioaddr
+ GMAC_HASH_TAB_0_31
);
123 writel(0xffffffff, ioaddr
+ GMAC_HASH_TAB_32_63
);
124 } else if (!netdev_mc_empty(dev
)) {
126 struct netdev_hw_addr
*ha
;
128 /* Hash filter for multicast */
129 value
= GMAC_PACKET_FILTER_HMC
;
131 memset(mc_filter
, 0, sizeof(mc_filter
));
132 netdev_for_each_mc_addr(ha
, dev
) {
133 /* The upper 6 bits of the calculated CRC are used to
134 * index the content of the Hash Table Reg 0 and 1.
137 (bitrev32(~crc32_le(~0, ha
->addr
, 6)) >> 26);
138 /* The most significant bit determines the register
139 * to use while the other 5 bits determines the bit
140 * within the selected register
142 mc_filter
[bit_nr
>> 5] |= (1 << (bit_nr
& 0x1F));
144 writel(mc_filter
[0], ioaddr
+ GMAC_HASH_TAB_0_31
);
145 writel(mc_filter
[1], ioaddr
+ GMAC_HASH_TAB_32_63
);
148 /* Handle multiple unicast addresses */
149 if (netdev_uc_count(dev
) > GMAC_MAX_PERFECT_ADDRESSES
) {
150 /* Switch to promiscuous mode if more than 128 addrs
153 value
|= GMAC_PACKET_FILTER_PR
;
154 } else if (!netdev_uc_empty(dev
)) {
156 struct netdev_hw_addr
*ha
;
158 netdev_for_each_uc_addr(ha
, dev
) {
159 dwmac4_set_umac_addr(ioaddr
, ha
->addr
, reg
);
164 writel(value
, ioaddr
+ GMAC_PACKET_FILTER
);
167 static void dwmac4_flow_ctrl(struct mac_device_info
*hw
, unsigned int duplex
,
168 unsigned int fc
, unsigned int pause_time
)
170 void __iomem
*ioaddr
= hw
->pcsr
;
171 u32 channel
= STMMAC_CHAN0
; /* FIXME */
172 unsigned int flow
= 0;
174 pr_debug("GMAC Flow-Control:\n");
176 pr_debug("\tReceive Flow-Control ON\n");
177 flow
|= GMAC_RX_FLOW_CTRL_RFE
;
178 writel(flow
, ioaddr
+ GMAC_RX_FLOW_CTRL
);
181 pr_debug("\tTransmit Flow-Control ON\n");
182 flow
|= GMAC_TX_FLOW_CTRL_TFE
;
183 writel(flow
, ioaddr
+ GMAC_QX_TX_FLOW_CTRL(channel
));
186 pr_debug("\tduplex mode: PAUSE %d\n", pause_time
);
187 flow
|= (pause_time
<< GMAC_TX_FLOW_CTRL_PT_SHIFT
);
188 writel(flow
, ioaddr
+ GMAC_QX_TX_FLOW_CTRL(channel
));
193 static void dwmac4_ctrl_ane(struct mac_device_info
*hw
, bool restart
)
195 void __iomem
*ioaddr
= hw
->pcsr
;
197 /* auto negotiation enable and External Loopback enable */
198 u32 value
= GMAC_AN_CTRL_ANE
| GMAC_AN_CTRL_ELE
;
201 value
|= GMAC_AN_CTRL_RAN
;
203 writel(value
, ioaddr
+ GMAC_AN_CTRL
);
206 static void dwmac4_get_adv(struct mac_device_info
*hw
, struct rgmii_adv
*adv
)
208 void __iomem
*ioaddr
= hw
->pcsr
;
209 u32 value
= readl(ioaddr
+ GMAC_AN_ADV
);
211 if (value
& GMAC_AN_FD
)
212 adv
->duplex
= DUPLEX_FULL
;
213 if (value
& GMAC_AN_HD
)
214 adv
->duplex
|= DUPLEX_HALF
;
216 adv
->pause
= (value
& GMAC_AN_PSE_MASK
) >> GMAC_AN_PSE_SHIFT
;
218 value
= readl(ioaddr
+ GMAC_AN_LPA
);
220 if (value
& GMAC_AN_FD
)
221 adv
->lp_duplex
= DUPLEX_FULL
;
222 if (value
& GMAC_AN_HD
)
223 adv
->lp_duplex
= DUPLEX_HALF
;
225 adv
->lp_pause
= (value
& GMAC_AN_PSE_MASK
) >> GMAC_AN_PSE_SHIFT
;
228 static int dwmac4_irq_status(struct mac_device_info
*hw
,
229 struct stmmac_extra_stats
*x
)
231 void __iomem
*ioaddr
= hw
->pcsr
;
232 u32 mtl_int_qx_status
;
236 intr_status
= readl(ioaddr
+ GMAC_INT_STATUS
);
238 /* Not used events (e.g. MMC interrupts) are not handled. */
239 if ((intr_status
& mmc_tx_irq
))
241 if (unlikely(intr_status
& mmc_rx_irq
))
243 if (unlikely(intr_status
& mmc_rx_csum_offload_irq
))
244 x
->mmc_rx_csum_offload_irq_n
++;
245 /* Clear the PMT bits 5 and 6 by reading the PMT status reg */
246 if (unlikely(intr_status
& pmt_irq
)) {
247 readl(ioaddr
+ GMAC_PMT
);
248 x
->irq_receive_pmt_irq_n
++;
251 if ((intr_status
& pcs_ane_irq
) || (intr_status
& pcs_link_irq
)) {
252 readl(ioaddr
+ GMAC_AN_STATUS
);
256 mtl_int_qx_status
= readl(ioaddr
+ MTL_INT_STATUS
);
257 /* Check MTL Interrupt: Currently only one queue is used: Q0. */
258 if (mtl_int_qx_status
& MTL_INT_Q0
) {
259 /* read Queue 0 Interrupt status */
260 u32 status
= readl(ioaddr
+ MTL_CHAN_INT_CTRL(STMMAC_CHAN0
));
262 if (status
& MTL_RX_OVERFLOW_INT
) {
263 /* clear Interrupt */
264 writel(status
| MTL_RX_OVERFLOW_INT
,
265 ioaddr
+ MTL_CHAN_INT_CTRL(STMMAC_CHAN0
));
266 ret
= CORE_IRQ_MTL_RX_OVERFLOW
;
273 static void dwmac4_debug(void __iomem
*ioaddr
, struct stmmac_extra_stats
*x
)
277 /* Currently only channel 0 is supported */
278 value
= readl(ioaddr
+ MTL_CHAN_TX_DEBUG(STMMAC_CHAN0
));
280 if (value
& MTL_DEBUG_TXSTSFSTS
)
281 x
->mtl_tx_status_fifo_full
++;
282 if (value
& MTL_DEBUG_TXFSTS
)
283 x
->mtl_tx_fifo_not_empty
++;
284 if (value
& MTL_DEBUG_TWCSTS
)
286 if (value
& MTL_DEBUG_TRCSTS_MASK
) {
287 u32 trcsts
= (value
& MTL_DEBUG_TRCSTS_MASK
)
288 >> MTL_DEBUG_TRCSTS_SHIFT
;
289 if (trcsts
== MTL_DEBUG_TRCSTS_WRITE
)
290 x
->mtl_tx_fifo_read_ctrl_write
++;
291 else if (trcsts
== MTL_DEBUG_TRCSTS_TXW
)
292 x
->mtl_tx_fifo_read_ctrl_wait
++;
293 else if (trcsts
== MTL_DEBUG_TRCSTS_READ
)
294 x
->mtl_tx_fifo_read_ctrl_read
++;
296 x
->mtl_tx_fifo_read_ctrl_idle
++;
298 if (value
& MTL_DEBUG_TXPAUSED
)
299 x
->mac_tx_in_pause
++;
301 value
= readl(ioaddr
+ MTL_CHAN_RX_DEBUG(STMMAC_CHAN0
));
303 if (value
& MTL_DEBUG_RXFSTS_MASK
) {
304 u32 rxfsts
= (value
& MTL_DEBUG_RXFSTS_MASK
)
305 >> MTL_DEBUG_RRCSTS_SHIFT
;
307 if (rxfsts
== MTL_DEBUG_RXFSTS_FULL
)
308 x
->mtl_rx_fifo_fill_level_full
++;
309 else if (rxfsts
== MTL_DEBUG_RXFSTS_AT
)
310 x
->mtl_rx_fifo_fill_above_thresh
++;
311 else if (rxfsts
== MTL_DEBUG_RXFSTS_BT
)
312 x
->mtl_rx_fifo_fill_below_thresh
++;
314 x
->mtl_rx_fifo_fill_level_empty
++;
316 if (value
& MTL_DEBUG_RRCSTS_MASK
) {
317 u32 rrcsts
= (value
& MTL_DEBUG_RRCSTS_MASK
) >>
318 MTL_DEBUG_RRCSTS_SHIFT
;
320 if (rrcsts
== MTL_DEBUG_RRCSTS_FLUSH
)
321 x
->mtl_rx_fifo_read_ctrl_flush
++;
322 else if (rrcsts
== MTL_DEBUG_RRCSTS_RSTAT
)
323 x
->mtl_rx_fifo_read_ctrl_read_data
++;
324 else if (rrcsts
== MTL_DEBUG_RRCSTS_RDATA
)
325 x
->mtl_rx_fifo_read_ctrl_status
++;
327 x
->mtl_rx_fifo_read_ctrl_idle
++;
329 if (value
& MTL_DEBUG_RWCSTS
)
330 x
->mtl_rx_fifo_ctrl_active
++;
333 value
= readl(ioaddr
+ GMAC_DEBUG
);
335 if (value
& GMAC_DEBUG_TFCSTS_MASK
) {
336 u32 tfcsts
= (value
& GMAC_DEBUG_TFCSTS_MASK
)
337 >> GMAC_DEBUG_TFCSTS_SHIFT
;
339 if (tfcsts
== GMAC_DEBUG_TFCSTS_XFER
)
340 x
->mac_tx_frame_ctrl_xfer
++;
341 else if (tfcsts
== GMAC_DEBUG_TFCSTS_GEN_PAUSE
)
342 x
->mac_tx_frame_ctrl_pause
++;
343 else if (tfcsts
== GMAC_DEBUG_TFCSTS_WAIT
)
344 x
->mac_tx_frame_ctrl_wait
++;
346 x
->mac_tx_frame_ctrl_idle
++;
348 if (value
& GMAC_DEBUG_TPESTS
)
349 x
->mac_gmii_tx_proto_engine
++;
350 if (value
& GMAC_DEBUG_RFCFCSTS_MASK
)
351 x
->mac_rx_frame_ctrl_fifo
= (value
& GMAC_DEBUG_RFCFCSTS_MASK
)
352 >> GMAC_DEBUG_RFCFCSTS_SHIFT
;
353 if (value
& GMAC_DEBUG_RPESTS
)
354 x
->mac_gmii_rx_proto_engine
++;
357 static const struct stmmac_ops dwmac4_ops
= {
358 .core_init
= dwmac4_core_init
,
359 .rx_ipc
= dwmac4_rx_ipc_enable
,
360 .dump_regs
= dwmac4_dump_regs
,
361 .host_irq_status
= dwmac4_irq_status
,
362 .flow_ctrl
= dwmac4_flow_ctrl
,
364 .set_umac_addr
= dwmac4_set_umac_addr
,
365 .get_umac_addr
= dwmac4_get_umac_addr
,
366 .ctrl_ane
= dwmac4_ctrl_ane
,
367 .get_adv
= dwmac4_get_adv
,
368 .debug
= dwmac4_debug
,
369 .set_filter
= dwmac4_set_filter
,
372 struct mac_device_info
*dwmac4_setup(void __iomem
*ioaddr
, int mcbins
,
373 int perfect_uc_entries
, int *synopsys_id
)
375 struct mac_device_info
*mac
;
376 u32 hwid
= readl(ioaddr
+ GMAC_VERSION
);
378 mac
= kzalloc(sizeof(const struct mac_device_info
), GFP_KERNEL
);
383 mac
->multicast_filter_bins
= mcbins
;
384 mac
->unicast_filter_entries
= perfect_uc_entries
;
385 mac
->mcast_bits_log2
= 0;
387 if (mac
->multicast_filter_bins
)
388 mac
->mcast_bits_log2
= ilog2(mac
->multicast_filter_bins
);
390 mac
->mac
= &dwmac4_ops
;
392 mac
->link
.port
= GMAC_CONFIG_PS
;
393 mac
->link
.duplex
= GMAC_CONFIG_DM
;
394 mac
->link
.speed
= GMAC_CONFIG_FES
;
395 mac
->mii
.addr
= GMAC_MDIO_ADDR
;
396 mac
->mii
.data
= GMAC_MDIO_DATA
;
398 /* Get and dump the chip ID */
399 *synopsys_id
= stmmac_get_synopsys_id(hwid
);
401 if (*synopsys_id
> DWMAC_CORE_4_00
)
402 mac
->dma
= &dwmac410_dma_ops
;
404 mac
->dma
= &dwmac4_dma_ops
;