141 lines · c
1/* SPDX-License-Identifier: GPL-2.0-or-later */2/*3 * stmmac_pcs.h: Physical Coding Sublayer Header File4 *5 * Copyright (C) 2016 STMicroelectronics (R&D) Limited6 * 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 743#define GMAC_ANE_RFE GENMASK(13, 12)44#define GMAC_ANE_RFE_SHIFT 1245#define GMAC_ANE_ACK BIT(14)46 47/**48 * dwmac_pcs_isr - TBI, RTBI, or SGMII PHY ISR49 * @ioaddr: IO registers pointer50 * @reg: Base address of the AN Control Register.51 * @intr_status: GMAC core interrupt status52 * @x: pointer to log these events as stats53 * Description: it is the ISR for PCS events: Auto-Negotiation Completed and54 * Link status.55 */56static 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 else73 pr_info("stmmac_pcs: Link Down\n");74 }75}76 77/**78 * dwmac_ctrl_ane - To program the AN Control Register.79 * @ioaddr: IO registers pointer80 * @reg: Base address of the AN Control Register.81 * @ane: to enable the auto-negotiation82 * @srgmi_ral: to manage MAC-2-MAC SGMII connections.83 * @loopback: to cause the PHY to loopback tx data into rx path.84 * Description: this is the main function to configure the AN control register85 * and init the ANE, select loopback (usually for debugging purpose) and86 * configure SGMII RAL.87 */88static inline void dwmac_ctrl_ane(void __iomem *ioaddr, u32 reg, bool ane,89 bool srgmi_ral, bool loopback)90{91 u32 value = readl(ioaddr + GMAC_AN_CTRL(reg));92 93 /* Enable and restart the Auto-Negotiation */94 if (ane)95 value |= GMAC_AN_CTRL_ANE | GMAC_AN_CTRL_RAN;96 else97 value &= ~GMAC_AN_CTRL_ANE;98 99 /* In case of MAC-2-MAC connection, block is configured to operate100 * according to MAC conf register.101 */102 if (srgmi_ral)103 value |= GMAC_AN_CTRL_SGMRAL;104 105 if (loopback)106 value |= GMAC_AN_CTRL_ELE;107 108 writel(value, ioaddr + GMAC_AN_CTRL(reg));109}110 111/**112 * dwmac_get_adv_lp - Get ADV and LP cap113 * @ioaddr: IO registers pointer114 * @reg: Base address of the AN Control Register.115 * @adv_lp: structure to store the adv,lp status116 * Description: this is to expose the ANE advertisement and Link partner ability117 * status to ethtool support.118 */119static inline void dwmac_get_adv_lp(void __iomem *ioaddr, u32 reg,120 struct rgmii_adv *adv_lp)121{122 u32 value = readl(ioaddr + GMAC_ANE_ADV(reg));123 124 if (value & GMAC_ANE_FD)125 adv_lp->duplex = DUPLEX_FULL;126 if (value & GMAC_ANE_HD)127 adv_lp->duplex |= DUPLEX_HALF;128 129 adv_lp->pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;130 131 value = readl(ioaddr + GMAC_ANE_LPA(reg));132 133 if (value & GMAC_ANE_FD)134 adv_lp->lp_duplex = DUPLEX_FULL;135 if (value & GMAC_ANE_HD)136 adv_lp->lp_duplex = DUPLEX_HALF;137 138 adv_lp->lp_pause = (value & GMAC_ANE_PSE) >> GMAC_ANE_PSE_SHIFT;139}140#endif /* __STMMAC_PCS_H__ */141