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