#ifndef _DEV_MII_MIIVAR_H_
#define _DEV_MII_MIIVAR_H_
#include <sys/queue.h>
#include <net/if_var.h>
#include "opt_platform.h"
#ifdef FDT
#include <dev/ofw/openfirm.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
#endif
struct mii_softc;
struct mii_data {
struct ifmedia mii_media;
if_t mii_ifp;
LIST_HEAD(mii_listhead, mii_softc) mii_phys;
u_int mii_instance;
u_int mii_media_status;
u_int mii_media_active;
};
typedef struct mii_data mii_data_t;
struct mii_phy_funcs {
int (*pf_service)(struct mii_softc *, struct mii_data *, int);
void (*pf_status)(struct mii_softc *);
void (*pf_reset)(struct mii_softc *);
};
#define MII_TICK 1
#define MII_MEDIACHG 2
#define MII_POLLSTAT 3
struct mii_softc {
device_t mii_dev;
LIST_ENTRY(mii_softc) mii_list;
uint32_t mii_mpd_oui;
uint32_t mii_mpd_model;
uint32_t mii_mpd_rev;
u_int mii_capmask;
u_int mii_phy;
u_int mii_offset;
u_int mii_inst;
const struct mii_phy_funcs *mii_funcs;
struct mii_data *mii_pdata;
u_int mii_flags;
u_int mii_capabilities;
u_int mii_extcapabilities;
u_int mii_ticks;
u_int mii_anegticks;
u_int mii_media_active;
u_int mii_media_status;
u_int mii_maxspeed;
};
typedef struct mii_softc mii_softc_t;
#define MIIF_INITDONE 0x00000001
#define MIIF_NOISOLATE 0x00000002
#if 0
#define MIIF_NOLOOP 0x00000004
#endif
#define MIIF_DOINGAUTO 0x00000008
#define MIIF_AUTOTSLEEP 0x00000010
#define MIIF_HAVEFIBER 0x00000020
#define MIIF_HAVE_GTCR 0x00000040
#define MIIF_IS_1000X 0x00000080
#define MIIF_DOPAUSE 0x00000100
#define MIIF_IS_HPNA 0x00000200
#define MIIF_FORCEANEG 0x00000400
#define MIIF_RX_DELAY 0x00000800
#define MIIF_TX_DELAY 0x00001000
#define MIIF_NOMANPAUSE 0x00100000
#define MIIF_FORCEPAUSE 0x00200000
#define MIIF_MACPRIV0 0x01000000
#define MIIF_MACPRIV1 0x02000000
#define MIIF_MACPRIV2 0x04000000
#define MIIF_PHYPRIV0 0x10000000
#define MIIF_PHYPRIV1 0x20000000
#define MIIF_PHYPRIV2 0x40000000
#define MII_ANEGTICKS 5
#define MII_ANEGTICKS_GIGE 17
#define MIIF_INHERIT_MASK (MIIF_NOISOLATE|MIIF_NOLOOP|MIIF_AUTOTSLEEP)
#define MII_OFFSET_ANY -1
#define MII_PHY_ANY -1
enum mii_contype {
MII_CONTYPE_UNKNOWN,
MII_CONTYPE_MII,
MII_CONTYPE_GMII,
MII_CONTYPE_SGMII,
MII_CONTYPE_QSGMII,
MII_CONTYPE_TBI,
MII_CONTYPE_REVMII,
MII_CONTYPE_RMII,
MII_CONTYPE_RGMII,
MII_CONTYPE_RGMII_ID,
MII_CONTYPE_RGMII_RXID,
MII_CONTYPE_RGMII_TXID,
MII_CONTYPE_RTBI,
MII_CONTYPE_SMII,
MII_CONTYPE_XGMII,
MII_CONTYPE_TRGMII,
MII_CONTYPE_2000BX,
MII_CONTYPE_2500BX,
MII_CONTYPE_RXAUI,
MII_CONTYPE_COUNT
};
typedef enum mii_contype mii_contype_t;
static inline bool
mii_contype_is_rgmii(mii_contype_t con)
{
return (con >= MII_CONTYPE_RGMII && con <= MII_CONTYPE_RGMII_TXID);
}
struct mii_attach_args {
struct mii_data *mii_data;
u_int mii_phyno;
u_int mii_offset;
uint32_t mii_id1;
uint32_t mii_id2;
u_int mii_capmask;
#ifdef FDT
struct ofw_bus_devinfo obd;
struct resource_list rl;
#endif
};
typedef struct mii_attach_args mii_attach_args_t;
struct mii_phydesc {
uint32_t mpd_oui;
uint32_t mpd_model;
const char *mpd_name;
};
#define MII_PHY_DESC(a, b) { MII_OUI_ ## a, MII_MODEL_ ## a ## _ ## b, \
MII_STR_ ## a ## _ ## b }
#define MII_PHY_END { 0, 0, NULL }
#ifdef _KERNEL
#define PHY_READ(p, r) \
MIIBUS_READREG((p)->mii_dev, (p)->mii_phy, (r))
#define PHY_WRITE(p, r, v) \
MIIBUS_WRITEREG((p)->mii_dev, (p)->mii_phy, (r), (v))
#define PHY_SERVICE(p, d, o) \
(*(p)->mii_funcs->pf_service)((p), (d), (o))
#define PHY_STATUS(p) \
(*(p)->mii_funcs->pf_status)(p)
#define PHY_RESET(p) \
(*(p)->mii_funcs->pf_reset)(p)
enum miibus_device_ivars {
MIIBUS_IVAR_FLAGS = BUS_IVARS_PRIVATE
};
#define MIIBUS_ACCESSOR(var, ivar, type) \
__BUS_ACCESSOR(miibus, var, MIIBUS, ivar, type)
MIIBUS_ACCESSOR(flags, FLAGS, u_int)
DECLARE_CLASS(miibus_driver);
#ifdef FDT
DECLARE_CLASS(miibus_fdt_driver);
#endif
int mii_attach(device_t, device_t *, if_t, ifm_change_cb_t,
ifm_stat_cb_t, int, int, int, int);
int mii_mediachg(struct mii_data *);
void mii_tick(struct mii_data *);
void mii_pollstat(struct mii_data *);
void mii_phy_add_media(struct mii_softc *);
int mii_phy_auto(struct mii_softc *);
int mii_phy_detach(device_t dev);
u_int mii_phy_flowstatus(struct mii_softc *);
void mii_phy_reset(struct mii_softc *);
void mii_phy_setmedia(struct mii_softc *sc);
void mii_phy_update(struct mii_softc *, int);
int mii_phy_tick(struct mii_softc *);
int mii_phy_mac_match(struct mii_softc *, const char *);
int mii_dev_mac_match(device_t, const char *);
void *mii_phy_mac_softc(struct mii_softc *);
void *mii_dev_mac_softc(device_t);
const struct mii_phydesc * mii_phy_match(const struct mii_attach_args *ma,
const struct mii_phydesc *mpd);
const struct mii_phydesc * mii_phy_match_gen(const struct mii_attach_args *ma,
const struct mii_phydesc *mpd, size_t endlen);
int mii_phy_dev_probe(device_t dev, const struct mii_phydesc *mpd, int mrv);
void mii_phy_dev_attach(device_t dev, u_int flags,
const struct mii_phy_funcs *mpf, int add_media);
device_attach_t miibus_attach;
void ukphy_status(struct mii_softc *);
u_int mii_oui(u_int, u_int);
#define MII_OUI(id1, id2) mii_oui(id1, id2)
#define MII_MODEL(id2) (((id2) & IDR2_MODEL) >> 4)
#define MII_REV(id2) ((id2) & IDR2_REV)
#endif
#endif