Skip to content

Commit 70523e6

Browse files
cavagiudavem330
authored andcommitted
drivers: net: stmmac: reworking the PCS code.
The 3.xx and 4.xx synopsys gmacs have a very similar PCS embedded module and they share almost the same registers: for example: AN_Control, AN_Status, AN_Advertisement, AN_Link_Partner_Ability, AN_Expansion, TBI_Extended_Status. Just the RGMII/SMII Control/Status register differs. So This patch aims to reorganize and enhance the PCS support. It removes the existent support from the dwmac1000/dwmac4_core.c moving basic PCS functions inside a new file called: stmmac_pcs.h. The patch also reviews the available APIs to be better shared among different hardware and easily enhanced to support new features. Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a5e4bd9 commit 70523e6

File tree

9 files changed

+350
-165
lines changed

9 files changed

+350
-165
lines changed

Documentation/networking/stmmac.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ Please see the following document:
285285
o mmc_core.c/mmc.h: Management MAC Counters;
286286
o stmmac_hwtstamp.c: HW timestamp support for PTP;
287287
o stmmac_ptp.c: PTP 1588 clock;
288+
o stmmac_pcs.h: Physical Coding Sublayer common implementation;
288289
o dwmac-<XXX>.c: these are for the platform glue-logic file; e.g. dwmac-sti.c
289290
for STMicroelectronics SoCs.
290291

drivers/net/ethernet/stmicro/stmmac/common.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,11 @@ struct stmmac_extra_stats {
232232
#define DMA_HW_FEAT_ACTPHYIF 0x70000000 /* Active/selected PHY iface */
233233
#define DEFAULT_DMA_PBL 8
234234

235+
/* PCS status and mask defines */
236+
#define PCS_ANE_IRQ BIT(2) /* PCS Auto-Negotiation */
237+
#define PCS_LINK_IRQ BIT(1) /* PCS Link */
238+
#define PCS_RGSMIIIS_IRQ BIT(0) /* RGMII or SMII Interrupt */
239+
235240
/* Max/Min RI Watchdog Timer count value */
236241
#define MAX_DMA_RIWT 0xff
237242
#define MIN_DMA_RIWT 0x20
@@ -272,9 +277,6 @@ enum dma_irq_status {
272277
#define CORE_IRQ_RX_PATH_IN_LPI_MODE (1 << 2)
273278
#define CORE_IRQ_RX_PATH_EXIT_LPI_MODE (1 << 3)
274279

275-
#define CORE_PCS_ANE_COMPLETE (1 << 5)
276-
#define CORE_PCS_LINK_STATUS (1 << 6)
277-
#define CORE_RGMII_IRQ (1 << 7)
278280
#define CORE_IRQ_MTL_RX_OVERFLOW BIT(8)
279281

280282
/* Physical Coding Sublayer */
@@ -469,9 +471,12 @@ struct stmmac_ops {
469471
void (*reset_eee_mode)(struct mac_device_info *hw);
470472
void (*set_eee_timer)(struct mac_device_info *hw, int ls, int tw);
471473
void (*set_eee_pls)(struct mac_device_info *hw, int link);
472-
void (*ctrl_ane)(struct mac_device_info *hw, bool restart);
473-
void (*get_adv)(struct mac_device_info *hw, struct rgmii_adv *adv);
474474
void (*debug)(void __iomem *ioaddr, struct stmmac_extra_stats *x);
475+
/* PCS calls */
476+
void (*pcs_ctrl_ane)(void __iomem *ioaddr, bool ane, bool srgmi_ral,
477+
bool loopback);
478+
void (*pcs_rane)(void __iomem *ioaddr, bool restart);
479+
void (*pcs_get_adv_lp)(void __iomem *ioaddr, struct rgmii_adv *adv);
475480
};
476481

477482
/* PTP and HW Timer helpers */
@@ -546,6 +551,7 @@ void stmmac_dwmac4_get_mac_addr(void __iomem *ioaddr, unsigned char *addr,
546551
void stmmac_dwmac4_set_mac(void __iomem *ioaddr, bool enable);
547552

548553
void dwmac_dma_flush_tx_fifo(void __iomem *ioaddr);
554+
549555
extern const struct stmmac_mode_ops ring_mode_ops;
550556
extern const struct stmmac_mode_ops chain_mode_ops;
551557
extern const struct stmmac_desc_ops dwmac4_desc_ops;

drivers/net/ethernet/stmicro/stmmac/dwmac1000.h

Lines changed: 17 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,6 @@ enum dwmac1000_irq_status {
4646
mmc_rx_irq = 0x0020,
4747
mmc_irq = 0x0010,
4848
pmt_irq = 0x0008,
49-
pcs_ane_irq = 0x0004,
50-
pcs_link_irq = 0x0002,
51-
rgmii_irq = 0x0001,
5249
};
5350
#define GMAC_INT_MASK 0x0000003c /* interrupt mask register */
5451

@@ -90,42 +87,23 @@ enum power_event {
9087
(reg * 8))
9188
#define GMAC_MAX_PERFECT_ADDRESSES 1
9289

93-
/* PCS registers (AN/TBI/SGMII/RGMII) offset */
94-
#define GMAC_AN_CTRL 0x000000c0 /* AN control */
95-
#define GMAC_AN_STATUS 0x000000c4 /* AN status */
96-
#define GMAC_ANE_ADV 0x000000c8 /* Auto-Neg. Advertisement */
97-
#define GMAC_ANE_LPA 0x000000cc /* Auto-Neg. link partener ability */
98-
#define GMAC_ANE_EXP 0x000000d0 /* ANE expansion */
99-
#define GMAC_TBI 0x000000d4 /* TBI extend status */
100-
#define GMAC_S_R_GMII 0x000000d8 /* SGMII RGMII status */
101-
102-
/* AN Configuration defines */
103-
#define GMAC_AN_CTRL_RAN 0x00000200 /* Restart Auto-Negotiation */
104-
#define GMAC_AN_CTRL_ANE 0x00001000 /* Auto-Negotiation Enable */
105-
#define GMAC_AN_CTRL_ELE 0x00004000 /* External Loopback Enable */
106-
#define GMAC_AN_CTRL_ECD 0x00010000 /* Enable Comma Detect */
107-
#define GMAC_AN_CTRL_LR 0x00020000 /* Lock to Reference */
108-
#define GMAC_AN_CTRL_SGMRAL 0x00040000 /* SGMII RAL Control */
109-
110-
/* AN Status defines */
111-
#define GMAC_AN_STATUS_LS 0x00000004 /* Link Status 0:down 1:up */
112-
#define GMAC_AN_STATUS_ANA 0x00000008 /* Auto-Negotiation Ability */
113-
#define GMAC_AN_STATUS_ANC 0x00000020 /* Auto-Negotiation Complete */
114-
#define GMAC_AN_STATUS_ES 0x00000100 /* Extended Status */
115-
116-
/* Register 54 (SGMII/RGMII status register) */
117-
#define GMAC_S_R_GMII_LINK 0x8
118-
#define GMAC_S_R_GMII_SPEED 0x5
119-
#define GMAC_S_R_GMII_SPEED_SHIFT 0x1
120-
#define GMAC_S_R_GMII_MODE 0x1
121-
#define GMAC_S_R_GMII_SPEED_125 2
122-
#define GMAC_S_R_GMII_SPEED_25 1
123-
124-
/* Common ADV and LPA defines */
125-
#define GMAC_ANE_FD (1 << 5)
126-
#define GMAC_ANE_HD (1 << 6)
127-
#define GMAC_ANE_PSE (3 << 7)
128-
#define GMAC_ANE_PSE_SHIFT 7
90+
#define GMAC_PCS_BASE 0x000000c0 /* PCS register base */
91+
#define GMAC_RGSMIIIS 0x000000d8 /* RGMII/SMII status */
92+
93+
/* SGMII/RGMII status register */
94+
#define GMAC_RGSMIIIS_LNKMODE BIT(0)
95+
#define GMAC_RGSMIIIS_SPEED GENMASK(2, 1)
96+
#define GMAC_RGSMIIIS_SPEED_SHIFT 1
97+
#define GMAC_RGSMIIIS_LNKSTS BIT(3)
98+
#define GMAC_RGSMIIIS_JABTO BIT(4)
99+
#define GMAC_RGSMIIIS_FALSECARDET BIT(5)
100+
#define GMAC_RGSMIIIS_SMIDRXS BIT(16)
101+
/* LNKMOD */
102+
#define GMAC_RGSMIIIS_LNKMOD_MASK 0x1
103+
/* LNKSPEED */
104+
#define GMAC_RGSMIIIS_SPEED_125 0x2
105+
#define GMAC_RGSMIIIS_SPEED_25 0x1
106+
#define GMAC_RGSMIIIS_SPEED_2_5 0x0
129107

130108
/* GMAC Configuration defines */
131109
#define GMAC_CONTROL_2K 0x08000000 /* IEEE 802.3as 2K packets */

drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c

Lines changed: 51 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <linux/slab.h>
3131
#include <linux/ethtool.h>
3232
#include <asm/io.h>
33+
#include "stmmac_pcs.h"
3334
#include "dwmac1000.h"
3435

3536
static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
@@ -241,6 +242,39 @@ static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
241242
writel(pmt, ioaddr + GMAC_PMT);
242243
}
243244

245+
/* RGMII or SMII interface */
246+
static void dwmac1000_rgsmii(void __iomem *ioaddr, struct stmmac_extra_stats *x)
247+
{
248+
u32 status;
249+
250+
status = readl(ioaddr + GMAC_RGSMIIIS);
251+
x->irq_rgmii_n++;
252+
253+
/* Check the link status */
254+
if (status & GMAC_RGSMIIIS_LNKSTS) {
255+
int speed_value;
256+
257+
x->pcs_link = 1;
258+
259+
speed_value = ((status & GMAC_RGSMIIIS_SPEED) >>
260+
GMAC_RGSMIIIS_SPEED_SHIFT);
261+
if (speed_value == GMAC_RGSMIIIS_SPEED_125)
262+
x->pcs_speed = SPEED_1000;
263+
else if (speed_value == GMAC_RGSMIIIS_SPEED_25)
264+
x->pcs_speed = SPEED_100;
265+
else
266+
x->pcs_speed = SPEED_10;
267+
268+
x->pcs_duplex = (status & GMAC_RGSMIIIS_LNKMOD_MASK);
269+
270+
pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed,
271+
x->pcs_duplex ? "Full" : "Half");
272+
} else {
273+
x->pcs_link = 0;
274+
pr_info("Link is Down\n");
275+
}
276+
}
277+
244278
static int dwmac1000_irq_status(struct mac_device_info *hw,
245279
struct stmmac_extra_stats *x)
246280
{
@@ -260,6 +294,7 @@ static int dwmac1000_irq_status(struct mac_device_info *hw,
260294
readl(ioaddr + GMAC_PMT);
261295
x->irq_receive_pmt_irq_n++;
262296
}
297+
263298
/* MAC trx/rx EEE LPI entry/exit interrupts */
264299
if (intr_status & lpiis_irq) {
265300
/* Clean LPI interrupt by reading the Reg 12 */
@@ -275,36 +310,10 @@ static int dwmac1000_irq_status(struct mac_device_info *hw,
275310
x->irq_rx_path_exit_lpi_mode_n++;
276311
}
277312

278-
if ((intr_status & pcs_ane_irq) || (intr_status & pcs_link_irq)) {
279-
readl(ioaddr + GMAC_AN_STATUS);
280-
x->irq_pcs_ane_n++;
281-
}
282-
if (intr_status & rgmii_irq) {
283-
u32 status = readl(ioaddr + GMAC_S_R_GMII);
284-
x->irq_rgmii_n++;
285-
286-
/* Save and dump the link status. */
287-
if (status & GMAC_S_R_GMII_LINK) {
288-
int speed_value = (status & GMAC_S_R_GMII_SPEED) >>
289-
GMAC_S_R_GMII_SPEED_SHIFT;
290-
x->pcs_duplex = (status & GMAC_S_R_GMII_MODE);
291-
292-
if (speed_value == GMAC_S_R_GMII_SPEED_125)
293-
x->pcs_speed = SPEED_1000;
294-
else if (speed_value == GMAC_S_R_GMII_SPEED_25)
295-
x->pcs_speed = SPEED_100;
296-
else
297-
x->pcs_speed = SPEED_10;
298-
299-
x->pcs_link = 1;
300-
pr_debug("%s: Link is Up - %d/%s\n", __func__,
301-
(int)x->pcs_speed,
302-
x->pcs_duplex ? "Full" : "Half");
303-
} else {
304-
x->pcs_link = 0;
305-
pr_debug("%s: Link is Down\n", __func__);
306-
}
307-
}
313+
dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x);
314+
315+
if (intr_status & PCS_RGSMIIIS_IRQ)
316+
dwmac1000_rgsmii(ioaddr, x);
308317

309318
return ret;
310319
}
@@ -363,38 +372,20 @@ static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
363372
writel(value, ioaddr + LPI_TIMER_CTRL);
364373
}
365374

366-
static void dwmac1000_ctrl_ane(struct mac_device_info *hw, bool restart)
375+
static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
376+
bool loopback)
367377
{
368-
void __iomem *ioaddr = hw->pcsr;
369-
/* auto negotiation enable and External Loopback enable */
370-
u32 value = GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_ELE;
371-
372-
if (restart)
373-
value |= GMAC_AN_CTRL_RAN;
374-
375-
writel(value, ioaddr + GMAC_AN_CTRL);
378+
dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
376379
}
377380

378-
static void dwmac1000_get_adv(struct mac_device_info *hw, struct rgmii_adv *adv)
381+
static void dwmac1000_rane(void __iomem *ioaddr, bool restart)
379382
{
380-
void __iomem *ioaddr = hw->pcsr;
381-
u32 value = readl(ioaddr + GMAC_ANE_ADV);
382-
383-
if (value & GMAC_ANE_FD)
384-
adv->duplex = DUPLEX_FULL;
385-
if (value & GMAC_ANE_HD)
386-
adv->duplex |= DUPLEX_HALF;
387-
388-
adv->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
389-
390-
value = readl(ioaddr + GMAC_ANE_LPA);
391-
392-
if (value & GMAC_ANE_FD)
393-
adv->lp_duplex = DUPLEX_FULL;
394-
if (value & GMAC_ANE_HD)
395-
adv->lp_duplex = DUPLEX_HALF;
383+
dwmac_rane(ioaddr, GMAC_PCS_BASE, restart);
384+
}
396385

397-
adv->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;
386+
static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
387+
{
388+
dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
398389
}
399390

400391
static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
@@ -485,9 +476,10 @@ static const struct stmmac_ops dwmac1000_ops = {
485476
.reset_eee_mode = dwmac1000_reset_eee_mode,
486477
.set_eee_timer = dwmac1000_set_eee_timer,
487478
.set_eee_pls = dwmac1000_set_eee_pls,
488-
.ctrl_ane = dwmac1000_ctrl_ane,
489-
.get_adv = dwmac1000_get_adv,
490479
.debug = dwmac1000_debug,
480+
.pcs_ctrl_ane = dwmac1000_ctrl_ane,
481+
.pcs_rane = dwmac1000_rane,
482+
.pcs_get_adv_lp = dwmac1000_get_adv_lp,
491483
};
492484

493485
struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,

drivers/net/ethernet/stmicro/stmmac/dwmac4.h

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,8 @@
2424
#define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
2525
#define GMAC_INT_STATUS 0x000000b0
2626
#define GMAC_INT_EN 0x000000b4
27-
#define GMAC_AN_CTRL 0x000000e0
28-
#define GMAC_AN_STATUS 0x000000e4
29-
#define GMAC_AN_ADV 0x000000e8
30-
#define GMAC_AN_LPA 0x000000ec
27+
#define GMAC_PCS_BASE 0x000000e0
28+
#define GMAC_PHYIF_CONTROL_STATUS 0x000000f8
3129
#define GMAC_PMT 0x000000c0
3230
#define GMAC_VERSION 0x00000110
3331
#define GMAC_DEBUG 0x00000114
@@ -64,19 +62,8 @@ enum dwmac4_irq_status {
6462
mmc_rx_irq = 0x00000200,
6563
mmc_irq = 0x00000100,
6664
pmt_irq = 0x00000010,
67-
pcs_ane_irq = 0x00000004,
68-
pcs_link_irq = 0x00000002,
6965
};
7066

71-
/* MAC Auto-Neg bitmap*/
72-
#define GMAC_AN_CTRL_RAN BIT(9)
73-
#define GMAC_AN_CTRL_ANE BIT(12)
74-
#define GMAC_AN_CTRL_ELE BIT(14)
75-
#define GMAC_AN_FD BIT(5)
76-
#define GMAC_AN_HD BIT(6)
77-
#define GMAC_AN_PSE_MASK GENMASK(8, 7)
78-
#define GMAC_AN_PSE_SHIFT 7
79-
8067
/* MAC PMT bitmap */
8168
enum power_event {
8269
pointer_reset = 0x80000000,
@@ -250,6 +237,23 @@ enum power_event {
250237
#define MTL_DEBUG_RRCSTS_FLUSH 3
251238
#define MTL_DEBUG_RWCSTS BIT(0)
252239

240+
/* SGMII/RGMII status register */
241+
#define GMAC_PHYIF_CTRLSTATUS_TC BIT(0)
242+
#define GMAC_PHYIF_CTRLSTATUS_LUD BIT(1)
243+
#define GMAC_PHYIF_CTRLSTATUS_SMIDRXS BIT(4)
244+
#define GMAC_PHYIF_CTRLSTATUS_LNKMOD BIT(16)
245+
#define GMAC_PHYIF_CTRLSTATUS_SPEED GENMASK(18, 17)
246+
#define GMAC_PHYIF_CTRLSTATUS_SPEED_SHIFT 17
247+
#define GMAC_PHYIF_CTRLSTATUS_LNKSTS BIT(19)
248+
#define GMAC_PHYIF_CTRLSTATUS_JABTO BIT(20)
249+
#define GMAC_PHYIF_CTRLSTATUS_FALSECARDET BIT(21)
250+
/* LNKMOD */
251+
#define GMAC_PHYIF_CTRLSTATUS_LNKMOD_MASK 0x1
252+
/* LNKSPEED */
253+
#define GMAC_PHYIF_CTRLSTATUS_SPEED_125 0x2
254+
#define GMAC_PHYIF_CTRLSTATUS_SPEED_25 0x1
255+
#define GMAC_PHYIF_CTRLSTATUS_SPEED_2_5 0x0
256+
253257
extern const struct stmmac_dma_ops dwmac4_dma_ops;
254258
extern const struct stmmac_dma_ops dwmac410_dma_ops;
255259
#endif /* __DWMAC4_H__ */

0 commit comments

Comments
 (0)