linux/drivers/net/sfc/mdio_10g.h
<<
>>
Prefs
   1/****************************************************************************
   2 * Driver for Solarflare Solarstorm network controllers and boards
   3 * Copyright 2006-2008 Solarflare Communications Inc.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of the GNU General Public License version 2 as published
   7 * by the Free Software Foundation, incorporated herein by reference.
   8 */
   9
  10#ifndef EFX_MDIO_10G_H
  11#define EFX_MDIO_10G_H
  12
  13/*
  14 * Definitions needed for doing 10G MDIO as specified in clause 45
  15 * MDIO, which do not appear in Linux yet. Also some helper functions.
  16 */
  17
  18#include "efx.h"
  19#include "boards.h"
  20
  21/* Numbering of the MDIO Manageable Devices (MMDs) */
  22/* Physical Medium Attachment/ Physical Medium Dependent sublayer */
  23#define MDIO_MMD_PMAPMD (1)
  24/* WAN Interface Sublayer */
  25#define MDIO_MMD_WIS    (2)
  26/* Physical Coding Sublayer */
  27#define MDIO_MMD_PCS    (3)
  28/* PHY Extender Sublayer */
  29#define MDIO_MMD_PHYXS  (4)
  30/* Extender Sublayer */
  31#define MDIO_MMD_DTEXS  (5)
  32/* Transmission convergence */
  33#define MDIO_MMD_TC     (6)
  34/* Auto negotiation */
  35#define MDIO_MMD_AN     (7)
  36
  37/* Generic register locations */
  38#define MDIO_MMDREG_CTRL1       (0)
  39#define MDIO_MMDREG_STAT1       (1)
  40#define MDIO_MMDREG_IDHI        (2)
  41#define MDIO_MMDREG_IDLOW       (3)
  42#define MDIO_MMDREG_SPEED       (4)
  43#define MDIO_MMDREG_DEVS0       (5)
  44#define MDIO_MMDREG_DEVS1       (6)
  45#define MDIO_MMDREG_CTRL2       (7)
  46#define MDIO_MMDREG_STAT2       (8)
  47#define MDIO_MMDREG_TXDIS       (9)
  48
  49/* Bits in MMDREG_CTRL1 */
  50/* Reset */
  51#define MDIO_MMDREG_CTRL1_RESET_LBN     (15)
  52#define MDIO_MMDREG_CTRL1_RESET_WIDTH   (1)
  53/* Loopback */
  54/* Loopback bit for WIS, PCS, PHYSX and DTEXS */
  55#define MDIO_MMDREG_CTRL1_LBACK_LBN     (14)
  56#define MDIO_MMDREG_CTRL1_LBACK_WIDTH   (1)
  57
  58/* Bits in MMDREG_STAT1 */
  59#define MDIO_MMDREG_STAT1_FAULT_LBN     (7)
  60#define MDIO_MMDREG_STAT1_FAULT_WIDTH   (1)
  61/* Link state */
  62#define MDIO_MMDREG_STAT1_LINK_LBN      (2)
  63#define MDIO_MMDREG_STAT1_LINK_WIDTH    (1)
  64/* Low power ability */
  65#define MDIO_MMDREG_STAT1_LPABLE_LBN    (1)
  66#define MDIO_MMDREG_STAT1_LPABLE_WIDTH  (1)
  67
  68/* Bits in ID reg */
  69#define MDIO_ID_REV(_id32)      (_id32 & 0xf)
  70#define MDIO_ID_MODEL(_id32)    ((_id32 >> 4) & 0x3f)
  71#define MDIO_ID_OUI(_id32)      (_id32 >> 10)
  72
  73/* Bits in MMDREG_DEVS0. Someone thoughtfully layed things out
  74 * so the 'bit present' bit number of an MMD is the number of
  75 * that MMD */
  76#define DEV_PRESENT_BIT(_b) (1 << _b)
  77
  78#define MDIO_MMDREG_DEVS0_PHYXS  DEV_PRESENT_BIT(MDIO_MMD_PHYXS)
  79#define MDIO_MMDREG_DEVS0_PCS    DEV_PRESENT_BIT(MDIO_MMD_PCS)
  80#define MDIO_MMDREG_DEVS0_PMAPMD DEV_PRESENT_BIT(MDIO_MMD_PMAPMD)
  81
  82/* Bits in MMDREG_STAT2 */
  83#define MDIO_MMDREG_STAT2_PRESENT_VAL   (2)
  84#define MDIO_MMDREG_STAT2_PRESENT_LBN   (14)
  85#define MDIO_MMDREG_STAT2_PRESENT_WIDTH (2)
  86
  87/* Bits in MMDREG_TXDIS */
  88#define MDIO_MMDREG_TXDIS_GLOBAL_LBN    (0)
  89#define MDIO_MMDREG_TXDIS_GLOBAL_WIDTH  (1)
  90
  91/* MMD-specific bits, ordered by MMD, then register */
  92#define MDIO_PMAPMD_CTRL1_LBACK_LBN     (0)
  93#define MDIO_PMAPMD_CTRL1_LBACK_WIDTH   (1)
  94
  95/* PMA type (4 bits) */
  96#define MDIO_PMAPMD_CTRL2_10G_CX4       (0x0)
  97#define MDIO_PMAPMD_CTRL2_10G_EW        (0x1)
  98#define MDIO_PMAPMD_CTRL2_10G_LW        (0x2)
  99#define MDIO_PMAPMD_CTRL2_10G_SW        (0x3)
 100#define MDIO_PMAPMD_CTRL2_10G_LX4       (0x4)
 101#define MDIO_PMAPMD_CTRL2_10G_ER        (0x5)
 102#define MDIO_PMAPMD_CTRL2_10G_LR        (0x6)
 103#define MDIO_PMAPMD_CTRL2_10G_SR        (0x7)
 104/* Reserved */
 105#define MDIO_PMAPMD_CTRL2_10G_BT        (0x9)
 106/* Reserved */
 107/* Reserved */
 108#define MDIO_PMAPMD_CTRL2_1G_BT         (0xc)
 109/* Reserved */
 110#define MDIO_PMAPMD_CTRL2_100_BT        (0xe)
 111#define MDIO_PMAPMD_CTRL2_10_BT         (0xf)
 112#define MDIO_PMAPMD_CTRL2_TYPE_MASK     (0xf)
 113
 114/* PHY XGXS lane state */
 115#define MDIO_PHYXS_LANE_STATE           (0x18)
 116#define MDIO_PHYXS_LANE_ALIGNED_LBN     (12)
 117
 118/* AN registers */
 119#define MDIO_AN_STATUS                  (1)
 120#define MDIO_AN_STATUS_XNP_LBN          (7)
 121#define MDIO_AN_STATUS_PAGE_LBN         (6)
 122#define MDIO_AN_STATUS_AN_DONE_LBN      (5)
 123#define MDIO_AN_STATUS_LP_AN_CAP_LBN    (0)
 124
 125#define MDIO_AN_10GBT_STATUS            (33)
 126#define MDIO_AN_10GBT_STATUS_MS_FLT_LBN (15) /* MASTER/SLAVE config fault */
 127#define MDIO_AN_10GBT_STATUS_MS_LBN     (14) /* MASTER/SLAVE config */
 128#define MDIO_AN_10GBT_STATUS_LOC_OK_LBN (13) /* Local OK */
 129#define MDIO_AN_10GBT_STATUS_REM_OK_LBN (12) /* Remote OK */
 130#define MDIO_AN_10GBT_STATUS_LP_10G_LBN (11) /* Link partner is 10GBT capable */
 131#define MDIO_AN_10GBT_STATUS_LP_LTA_LBN (10) /* LP loop timing ability */
 132#define MDIO_AN_10GBT_STATUS_LP_TRR_LBN (9)  /* LP Training Reset Request */
 133
 134
 135/* Packing of the prt and dev arguments of clause 45 style MDIO into a
 136 * single int so they can be passed into the mdio_read/write functions
 137 * that currently exist. Note that as Falcon is the only current user,
 138 * the packed form is chosen to match what Falcon needs to write into
 139 * a register. This is checked at compile-time so do not change it. If
 140 * your target chip needs things layed out differently you will need
 141 * to unpack the arguments in your chip-specific mdio functions.
 142 */
 143 /* These are defined by the standard. */
 144#define MDIO45_PRT_ID_WIDTH  (5)
 145#define MDIO45_DEV_ID_WIDTH  (5)
 146
 147/* The prt ID is just packed in immediately to the left of the dev ID */
 148#define MDIO45_PRT_DEV_WIDTH (MDIO45_PRT_ID_WIDTH + MDIO45_DEV_ID_WIDTH)
 149
 150#define MDIO45_PRT_ID_MASK   ((1 << MDIO45_PRT_DEV_WIDTH) - 1)
 151/* This is the prt + dev extended by 1 bit to hold the 'is clause 45' flag. */
 152#define MDIO45_XPRT_ID_WIDTH   (MDIO45_PRT_DEV_WIDTH + 1)
 153#define MDIO45_XPRT_ID_MASK   ((1 << MDIO45_XPRT_ID_WIDTH) - 1)
 154#define MDIO45_XPRT_ID_IS10G   (1 << (MDIO45_XPRT_ID_WIDTH - 1))
 155
 156
 157#define MDIO45_PRT_ID_COMP_LBN   MDIO45_DEV_ID_WIDTH
 158#define MDIO45_PRT_ID_COMP_WIDTH  MDIO45_PRT_ID_WIDTH
 159#define MDIO45_DEV_ID_COMP_LBN    0
 160#define MDIO45_DEV_ID_COMP_WIDTH  MDIO45_DEV_ID_WIDTH
 161
 162/* Compose port and device into a phy_id */
 163static inline int mdio_clause45_pack(u8 prt, u8 dev)
 164{
 165        efx_dword_t phy_id;
 166        EFX_POPULATE_DWORD_2(phy_id, MDIO45_PRT_ID_COMP, prt,
 167                             MDIO45_DEV_ID_COMP, dev);
 168        return MDIO45_XPRT_ID_IS10G | EFX_DWORD_VAL(phy_id);
 169}
 170
 171static inline void mdio_clause45_unpack(u32 val, u8 *prt, u8 *dev)
 172{
 173        efx_dword_t phy_id;
 174        EFX_POPULATE_DWORD_1(phy_id, EFX_DWORD_0, val);
 175        *prt = EFX_DWORD_FIELD(phy_id, MDIO45_PRT_ID_COMP);
 176        *dev = EFX_DWORD_FIELD(phy_id, MDIO45_DEV_ID_COMP);
 177}
 178
 179static inline int mdio_clause45_read(struct efx_nic *efx,
 180                                     u8 prt, u8 dev, u16 addr)
 181{
 182        return efx->mii.mdio_read(efx->net_dev,
 183                                  mdio_clause45_pack(prt, dev), addr);
 184}
 185
 186static inline void mdio_clause45_write(struct efx_nic *efx,
 187                                       u8 prt, u8 dev, u16 addr, int value)
 188{
 189        efx->mii.mdio_write(efx->net_dev,
 190                            mdio_clause45_pack(prt, dev), addr, value);
 191}
 192
 193
 194static inline u32 mdio_clause45_read_id(struct efx_nic *efx, int mmd)
 195{
 196        int phy_id = efx->mii.phy_id;
 197        u16 id_low = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDLOW);
 198        u16 id_hi = mdio_clause45_read(efx, phy_id, mmd, MDIO_MMDREG_IDHI);
 199        return (id_hi << 16) | (id_low);
 200}
 201
 202static inline bool mdio_clause45_phyxgxs_lane_sync(struct efx_nic *efx)
 203{
 204        int i, lane_status;
 205        bool sync;
 206
 207        for (i = 0; i < 2; ++i)
 208                lane_status = mdio_clause45_read(efx, efx->mii.phy_id,
 209                                                 MDIO_MMD_PHYXS,
 210                                                 MDIO_PHYXS_LANE_STATE);
 211
 212        sync = !!(lane_status & (1 << MDIO_PHYXS_LANE_ALIGNED_LBN));
 213        if (!sync)
 214                EFX_LOG(efx, "XGXS lane status: %x\n", lane_status);
 215        return sync;
 216}
 217
 218extern const char *mdio_clause45_mmd_name(int mmd);
 219
 220/*
 221 * Reset a specific MMD and wait for reset to clear.
 222 * Return number of spins left (>0) on success, -%ETIMEDOUT on failure.
 223 *
 224 * This function will sleep
 225 */
 226extern int mdio_clause45_reset_mmd(struct efx_nic *efx, int mmd,
 227                                   int spins, int spintime);
 228
 229/* As mdio_clause45_check_mmd but for multiple MMDs */
 230int mdio_clause45_check_mmds(struct efx_nic *efx,
 231                             unsigned int mmd_mask, unsigned int fatal_mask);
 232
 233/* Check the link status of specified mmds in bit mask */
 234extern bool mdio_clause45_links_ok(struct efx_nic *efx,
 235                                   unsigned int mmd_mask);
 236
 237/* Generic transmit disable support though PMAPMD */
 238extern void mdio_clause45_transmit_disable(struct efx_nic *efx);
 239
 240/* Generic part of reconfigure: set/clear loopback bits */
 241extern void mdio_clause45_phy_reconfigure(struct efx_nic *efx);
 242
 243/* Read (some of) the PHY settings over MDIO */
 244extern void mdio_clause45_get_settings(struct efx_nic *efx,
 245                                       struct ethtool_cmd *ecmd);
 246
 247/* Set (some of) the PHY settings over MDIO */
 248extern int mdio_clause45_set_settings(struct efx_nic *efx,
 249                                      struct ethtool_cmd *ecmd);
 250
 251/* Wait for specified MMDs to exit reset within a timeout */
 252extern int mdio_clause45_wait_reset_mmds(struct efx_nic *efx,
 253                                         unsigned int mmd_mask);
 254
 255#endif /* EFX_MDIO_10G_H */
 256
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.