1/*
2 *	ASIX AX88172/AX88772/AX88178 USB 2.0 Ethernet Driver.
3 *	Copyright (c) 2008, 2011 S.Zharski <imker@gmx.li>
4 *	Distributed under the terms of the MIT license.
5 *
6 *	Heavily based on code of the
7 *	Driver for USB Ethernet Control Model devices
8 *	Copyright (C) 2008 Michael Lotz <mmlr@mlotz.ch>
9 *	Distributed under the terms of the MIT license.
10 *
11 */
12#ifndef _USB_MII_BUS_H_
13#define _USB_MII_BUS_H_
14
15
16#include "Driver.h"
17
18
19enum MII_Register {
20	MII_BMCR	= 0x00,
21	MII_BMSR	= 0x01,
22	MII_PHYID0	= 0x02,
23	MII_PHYID1	= 0x03,
24	MII_ANAR	= 0x04,
25	MII_ANLPAR	= 0x05,
26	MII_ANER	= 0x06
27};
28
29
30enum MII_BMCR {
31	BMCR_Reset			= 0x8000,
32	BMCR_Loopback		= 0x4000,
33	BMCR_SpeedSelection	= 0x2000,
34	BMCR_ANegEnabled	= 0x1000,
35	BMCR_PowerDown		= 0x0800,
36	BMCR_Isolate		= 0x0400,
37	BMCR_ANegRestart	= 0x0200,
38	BMCR_FullDuplex		= 0x0100,
39	BMCR_CollTest		= 0x0080
40};
41
42
43enum MII_BMSR {
44	BMSR_CAP_100BASE_T4		= 0x8000,	// PHY is able to perform 100base-T4
45	BMSR_CAP_100BASE_TXFD	= 0x4000,	// PHY is able to perform 100base-TX FD
46	BMSR_CAP_100BASE_TXHD	= 0x2000,	// PHY is able to perform 100base-TX HD
47	BMSR_CAP_10BASE_TXFD	= 0x1000,	// PHY is able to perform 10base-TX FD
48	BMSR_CAP_10BASE_TXHD	= 0x0800,	// PHY is able to perform 10base-TX HD
49	BMSR_MFPS				= 0x0040,	// Management frame preamble supression
50	BMSR_ANC				= 0x0020,	// Auto-negotiation complete
51	BMSR_RF					= 0x0010,	// Remote fault
52	BMSR_CAP_AN				= 0x0008,	// PHY is able to perform a-negotiation
53	BMSR_Link				= 0x0004,	// link state
54	BMSR_Jabber				= 0x0002,	// Jabber condition detected
55	BMSR_CAP_Ext			= 0x0001	// Extended register capable
56};
57
58
59enum MII_ANAR {
60	ANAR_NP			= 0x8000,	// Next page available
61	ANAR_ACK		= 0x4000,	// Link partner data reception ability ack-ed
62	ANAR_RF			= 0x2000,	// Fault condition detected and advertised
63	ANAR_PAUSE		= 0x0400,	// Pause operation enabled for full-duplex links
64	ANAR_T4			= 0x0200,	// 100BASE-T4 supported
65	ANAR_TX_FD		= 0x0100,	// 100BASE-TX full duplex supported
66	ANAR_TX_HD		= 0x0080,	// 100BASE-TX half duplex supported
67	ANAR_10_FD		= 0x0040,	// 10BASE-TX full duplex supported
68	ANAR_10_HD		= 0x0020,	// 10BASE-TX half duplex supported
69	ANAR_SELECTOR	= 0x0001	// Protocol sel. bits (hardcoded to ethernet)
70};
71
72
73enum MII_ANLPAR {
74	ANLPAR_NP		= 0x8000,	// Link partner next page enabled
75	ANLPAR_ACK		= 0x4000,	// Link partner data reception ability ack-ed
76	ANLPAR_RF		= 0x2000,	// Remote fault indicated by link partner
77	ANLPAR_PAUSE	= 0x0400,	// Pause operation supported by link partner
78	ANLPAR_T4		= 0x0200,	// 100BASE-T4 supported by link partner
79	ANLPAR_TX_FD	= 0x0100,	// 100BASE-TX FD supported by link partner
80	ANLPAR_TX_HD	= 0x0080,	// 100BASE-TX HD supported by link partner
81	ANLPAR_10_FD	= 0x0040,	// 10BASE-TX FD supported by link partner
82	ANLPAR_10_HD	= 0x0020,	// 10BASE-TX HD supported by link partner
83	ANLPAR_SELECTOR	= 0x0001	// Link partner's bin. encoded protocol selector
84};
85
86
87// index used to different PHY on MII bus
88enum PHYIndex {
89	CurrentPHY	 = -1,	// currently selected PHY.
90						// Internally used as def. index in case no PHYs found.
91	SecondaryPHY =  0,	// secondary PHY
92	PrimaryPHY	 =  1,	// primary PHY
93	PHYsCount	 =  2	// maximal count of PHYs on bus
94};
95
96
97// PHY type and id constants and masks.
98enum PHYType {
99	PHYTypeMask		= 0xe0,	// mask for PHY type bits
100	PHYNormal		= 0x00,	// 10/100 Ethernet PHY (Link reports as normal case)
101	PHYLinkAState	= 0x80,	// Special case 1 (Link reports is always active)
102	PHYGigabit		= 0x20,	// Gigabit Ethernet PHY on AX88178
103	PHYNotInstalled	= 0xe0,	// non-supported PHY
104
105	PHYIDMask		= 0x1f,	// mask for PHY ID bits
106	PHYIDEmbedded	= 0x10	// id for embedded PHY on AX88772
107};
108
109
110class MIIBus {
111public:
112							MIIBus();
113
114		status_t			Init(usb_device device);
115		status_t			InitCheck();
116
117		status_t			SetupPHY();
118
119		uint8				PHYID(PHYIndex phyIndex = CurrentPHY);
120		uint8				PHYType(PHYIndex phyIndex = CurrentPHY);
121		PHYIndex			ActivePHY() { return fSelectedPHY; }
122
123		status_t			Read(uint16 miiRegister, uint16 *value,
124								PHYIndex phyIndex = CurrentPHY);
125		status_t			Write(uint16 miiRegister, uint16 value,
126								PHYIndex phyIndex = CurrentPHY);
127
128		status_t			Status(uint16 *status,
129								PHYIndex phyIndex = CurrentPHY);
130		status_t			Dump();
131
132private:
133		status_t			fStatus;
134		usb_device			fDevice;
135		uint8				fPHYs[PHYsCount];
136		PHYIndex			fSelectedPHY;
137};
138
139#endif // _USB_MII_BUS_H_
140
141