| /* SPDX-License-Identifier: GPL-2.0-or-later */ |
| /* |
| * stmmac_pcs.h: Physical Coding Sublayer Header File |
| * |
| * Copyright (C) 2016 STMicroelectronics (R&D) Limited |
| * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> |
| */ |
| |
| #ifndef __STMMAC_PCS_H__ |
| #define __STMMAC_PCS_H__ |
| |
| #include <linux/slab.h> |
| #include <linux/io.h> |
| #include "common.h" |
| |
| /* PCS registers (AN/TBI/SGMII/RGMII) offsets */ |
| #define GMAC_AN_CTRL(x) (x) /* AN control */ |
| #define GMAC_AN_STATUS(x) (x + 0x4) /* AN status */ |
| #define GMAC_ANE_ADV(x) (x + 0x8) /* ANE Advertisement */ |
| #define GMAC_ANE_LPA(x) (x + 0xc) /* ANE link partener ability */ |
| #define GMAC_ANE_EXP(x) (x + 0x10) /* ANE expansion */ |
| #define GMAC_TBI(x) (x + 0x14) /* TBI extend status */ |
| |
| /* AN Configuration defines */ |
| #define GMAC_AN_CTRL_RAN BIT(9) /* Restart Auto-Negotiation */ |
| #define GMAC_AN_CTRL_ANE BIT(12) /* Auto-Negotiation Enable */ |
| #define GMAC_AN_CTRL_ELE BIT(14) /* External Loopback Enable */ |
| #define GMAC_AN_CTRL_ECD BIT(16) /* Enable Comma Detect */ |
| #define GMAC_AN_CTRL_LR BIT(17) /* Lock to Reference */ |
| #define GMAC_AN_CTRL_SGMRAL BIT(18) /* SGMII RAL Control */ |
| |
| /* AN Status defines */ |
| #define GMAC_AN_STATUS_LS BIT(2) /* Link Status 0:down 1:up */ |
| #define GMAC_AN_STATUS_ANA BIT(3) /* Auto-Negotiation Ability */ |
| #define GMAC_AN_STATUS_ANC BIT(5) /* Auto-Negotiation Complete */ |
| #define GMAC_AN_STATUS_ES BIT(8) /* Extended Status */ |
| |
| /* ADV and LPA defines */ |
| #define GMAC_ANE_FD BIT(5) |
| #define GMAC_ANE_HD BIT(6) |
| #define GMAC_ANE_PSE GENMASK(8, 7) |
| #define GMAC_ANE_PSE_SHIFT 7 |
| #define GMAC_ANE_RFE GENMASK(13, 12) |
| #define GMAC_ANE_RFE_SHIFT 12 |
| #define GMAC_ANE_ACK BIT(14) |
| |
| /** |
| * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR |
| * @ioaddr: IO registers pointer |
| * @reg: Base address of the AN Control Register. |
| * @intr_status: GMAC core interrupt status |
| * @x: pointer to log these events as stats |
| * Description: it is the ISR for PCS events: Auto-Negotiation Completed and |
| * Link status. |
| */ |
| static inline void dwmac_pcs_isr(void __iomem *ioaddr, u32 reg, |
| unsigned int intr_status, |
| struct stmmac_extra_stats *x) |
| { |
| u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); |
| |
| if (intr_status & PCS_ANE_IRQ) { |
| x->irq_pcs_ane_n++; |
| if (val & GMAC_AN_STATUS_ANC) |
| pr_info("stmmac_pcs: ANE process completed\n"); |
| } |
| |
| if (intr_status & PCS_LINK_IRQ) { |
| x->irq_pcs_link_n++; |
| if (val & GMAC_AN_STATUS_LS) |
| pr_info("stmmac_pcs: Link Up\n"); |
| else |
| pr_info("stmmac_pcs: Link Down\n"); |
| } |
| } |
| |
| /** |
| * dwmac_ctrl_ane - To program the AN Control Register. |
| * @ioaddr: IO registers pointer |
| * @reg: Base address of the AN Control Register. |
| * @ane: to enable the auto-negotiation |
| * @srgmi_ral: to manage MAC-2-MAC SGMII connections. |
| * @loopback: to cause the PHY to loopback tx data into rx path. |
| * Description: this is the main function to configure the AN control register |
| * and init the ANE, select loopback (usually for debugging purpose) and |
| * configure SGMII RAL. |
| */ |
| static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane, |
| bool srgmi_ral, bool loopback) |
| { |
| u32 value = readl(ioaddr + GMAC_AN_CTRL(reg)); |
| |
| /* Enable and restart the Auto-Negotiation */ |
| if (ane) |
| value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN; |
| else |
| value &= ~GMAC_AN_CTRL_ANE; |
| |
| /* In case of MAC-2-MAC connection, block is configured to operate |
| * according to MAC conf register. |
| */ |
| if (srgmi_ral) |
| value |= GMAC_AN_CTRL_SGMRAL; |
| |
| if (loopback) |
| value |= GMAC_AN_CTRL_ELE; |
| |
| writel(value, ioaddr + GMAC_AN_CTRL(reg)); |
| } |
| |
| /** |
| * dwmac_get_adv_lp - Get ADV and LP cap |
| * @ioaddr: IO registers pointer |
| * @reg: Base address of the AN Control Register. |
| * @adv_lp: structure to store the adv,lp status |
| * Description: this is to expose the ANE advertisement and Link partner ability |
| * status to ethtool support. |
| */ |
| static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg, |
| struct rgmii_adv *adv_lp) |
| { |
| u32 value = readl(ioaddr + GMAC_ANE_ADV(reg)); |
| |
| if (value & GMAC_ANE_FD) |
| adv_lp->duplex = DUPLEX_FULL; |
| if (value & GMAC_ANE_HD) |
| adv_lp->duplex |= DUPLEX_HALF; |
| |
| adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; |
| |
| value = readl(ioaddr + GMAC_ANE_LPA(reg)); |
| |
| if (value & GMAC_ANE_FD) |
| adv_lp->lp_duplex = DUPLEX_FULL; |
| if (value & GMAC_ANE_HD) |
| adv_lp->lp_duplex = DUPLEX_HALF; |
| |
| adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; |
| } |
| #endif /* __STMMAC_PCS_H__ */ |