1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * stmmac_pcs.h: Physical Coding Sublayer Header File 4 * 5 * Copyright (C) 2016 STMicroelectronics (R&D) Limited 6 * Author: Giuseppe Cavallaro <peppe.cavallaro@st.com> 7 */ 8 9 #ifndef __STMMAC_PCS_H__ 10 #define __STMMAC_PCS_H__ 11 12 #include <linux/slab.h> 13 #include <linux/io.h> 14 #include "common.h" 15 16 /* PCS registers (AN/TBI/SGMII/RGMII) offsets */ 17 #define GMAC_AN_CTRL(x) (x) /* AN control */ 18 #define GMAC_AN_STATUS(x) (x + 0x4) /* AN status */ 19 #define GMAC_ANE_ADV(x) (x + 0x8) /* ANE Advertisement */ 20 #define GMAC_ANE_LPA(x) (x + 0xc) /* ANE link partener ability */ 21 #define GMAC_ANE_EXP(x) (x + 0x10) /* ANE expansion */ 22 #define GMAC_TBI(x) (x + 0x14) /* TBI extend status */ 23 24 /* AN Configuration defines */ 25 #define GMAC_AN_CTRL_RAN BIT(9) /* Restart Auto-Negotiation */ 26 #define GMAC_AN_CTRL_ANE BIT(12) /* Auto-Negotiation Enable */ 27 #define GMAC_AN_CTRL_ELE BIT(14) /* External Loopback Enable */ 28 #define GMAC_AN_CTRL_ECD BIT(16) /* Enable Comma Detect */ 29 #define GMAC_AN_CTRL_LR BIT(17) /* Lock to Reference */ 30 #define GMAC_AN_CTRL_SGMRAL BIT(18) /* SGMII RAL Control */ 31 32 /* AN Status defines */ 33 #define GMAC_AN_STATUS_LS BIT(2) /* Link Status 0:down 1:up */ 34 #define GMAC_AN_STATUS_ANA BIT(3) /* Auto-Negotiation Ability */ 35 #define GMAC_AN_STATUS_ANC BIT(5) /* Auto-Negotiation Complete */ 36 #define GMAC_AN_STATUS_ES BIT(8) /* Extended Status */ 37 38 /* ADV and LPA defines */ 39 #define GMAC_ANE_FD BIT(5) 40 #define GMAC_ANE_HD BIT(6) 41 #define GMAC_ANE_PSE GENMASK(8, 7) 42 #define GMAC_ANE_PSE_SHIFT 7 43 #define GMAC_ANE_RFE GENMASK(13, 12) 44 #define GMAC_ANE_RFE_SHIFT 12 45 #define GMAC_ANE_ACK BIT(14) 46 47 /** 48 * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR 49 * @ioaddr: IO registers pointer 50 * @reg: Base address of the AN Control Register. 51 * @intr_status: GMAC core interrupt status 52 * @x: pointer to log these events as stats 53 * Description: it is the ISR for PCS events: Auto-Negotiation Completed and 54 * Link status. 55 */ 56 static inline void dwmac_pcs_isr(void __iomem *ioaddr, u32 reg, 57 unsigned int intr_status, 58 struct stmmac_extra_stats *x) 59 { 60 u32 val = readl(ioaddr + GMAC_AN_STATUS(reg)); 61 62 if (intr_status & PCS_ANE_IRQ) { 63 x->irq_pcs_ane_n++; 64 if (val & GMAC_AN_STATUS_ANC) 65 pr_info("stmmac_pcs: ANE process completed\n"); 66 } 67 68 if (intr_status & PCS_LINK_IRQ) { 69 x->irq_pcs_link_n++; 70 if (val & GMAC_AN_STATUS_LS) 71 pr_info("stmmac_pcs: Link Up\n"); 72 else 73 pr_info("stmmac_pcs: Link Down\n"); 74 } 75 } 76 77 /** 78 * dwmac_rane - To restart ANE 79 * @ioaddr: IO registers pointer 80 * @reg: Base address of the AN Control Register. 81 * @restart: to restart ANE 82 * Description: this is to just restart the Auto-Negotiation. 83 */ 84 static inline void dwmac_rane(void __iomem *ioaddr, u32 reg, bool restart) 85 { 86 u32 value = readl(ioaddr + GMAC_AN_CTRL(reg)); 87 88 if (restart) 89 value |= GMAC_AN_CTRL_RAN; 90 91 writel(value, ioaddr + GMAC_AN_CTRL(reg)); 92 } 93 94 /** 95 * dwmac_ctrl_ane - To program the AN Control Register. 96 * @ioaddr: IO registers pointer 97 * @reg: Base address of the AN Control Register. 98 * @ane: to enable the auto-negotiation 99 * @srgmi_ral: to manage MAC-2-MAC SGMII connections. 100 * @loopback: to cause the PHY to loopback tx data into rx path. 101 * Description: this is the main function to configure the AN control register 102 * and init the ANE, select loopback (usually for debugging purpose) and 103 * configure SGMII RAL. 104 */ 105 static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane, 106 bool srgmi_ral, bool loopback) 107 { 108 u32 value = readl(ioaddr + GMAC_AN_CTRL(reg)); 109 110 /* Enable and restart the Auto-Negotiation */ 111 if (ane) 112 value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN; 113 114 /* In case of MAC-2-MAC connection, block is configured to operate 115 * according to MAC conf register. 116 */ 117 if (srgmi_ral) 118 value |= GMAC_AN_CTRL_SGMRAL; 119 120 if (loopback) 121 value |= GMAC_AN_CTRL_ELE; 122 123 writel(value, ioaddr + GMAC_AN_CTRL(reg)); 124 } 125 126 /** 127 * dwmac_get_adv_lp - Get ADV and LP cap 128 * @ioaddr: IO registers pointer 129 * @reg: Base address of the AN Control Register. 130 * @adv_lp: structure to store the adv,lp status 131 * Description: this is to expose the ANE advertisement and Link partner ability 132 * status to ethtool support. 133 */ 134 static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg, 135 struct rgmii_adv *adv_lp) 136 { 137 u32 value = readl(ioaddr + GMAC_ANE_ADV(reg)); 138 139 if (value & GMAC_ANE_FD) 140 adv_lp->duplex = DUPLEX_FULL; 141 if (value & GMAC_ANE_HD) 142 adv_lp->duplex |= DUPLEX_HALF; 143 144 adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; 145 146 value = readl(ioaddr + GMAC_ANE_LPA(reg)); 147 148 if (value & GMAC_ANE_FD) 149 adv_lp->lp_duplex = DUPLEX_FULL; 150 if (value & GMAC_ANE_HD) 151 adv_lp->lp_duplex = DUPLEX_HALF; 152 153 adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT; 154 } 155 #endif /* __STMMAC_PCS_H__ */ 156