linux/drivers/net/ethernet/stmicro/stmmac/stmmac_pcs.h
<<
>>
Prefs
   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 */
  60static 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 */
  88static 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 */
 109static 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 */
 138static 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