1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
|
/*
* Copyright (C) Cvitek Co., Ltd. 2019-2020. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/******************************************************************************
* @file phy.h
* @brief header file for generic PHY Driver
* @version V1.0
* @date 21 March 2019
******************************************************************************/
#ifndef _ETH_PHY_H_
#define _ETH_PHY_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include "mmio.h"
#include "drv_ioremap.h"
/**
\brief Ethernet link speed
*/
#define CSI_ETH_SPEED_10M (0) ///< 10 Mbps link speed
#define CSI_ETH_SPEED_100M (1) ///< 100 Mbps link speed
#define CSI_ETH_SPEED_1G (2) ///< 1 Gpbs link speed
/**
\brief Ethernet duplex mode
*/
#define CSI_ETH_DUPLEX_HALF (0) ///< Half duplex link
#define CSI_ETH_DUPLEX_FULL (1) ///< Full duplex link
typedef void *eth_phy_handle_t;
typedef enum eth_power_state
{
CSI_ETH_POWER_OFF, ///< Power off: no operation possible
CSI_ETH_POWER_LOW, ///< Low Power mode: retain state, detect and signal wake-up events
CSI_ETH_POWER_FULL ///< Power on: full operation at maximum performance
} eth_power_state_t;
typedef int32_t (*csi_eth_phy_read_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data); ///< Read Ethernet PHY Register.
typedef int32_t (*csi_eth_phy_write_t)(uint8_t phy_addr, uint8_t reg_addr, uint16_t data); ///< Write Ethernet PHY Register.
typedef volatile struct eth_link_info
{
uint32_t speed : 2; ///< Link speed: 0= 10 MBit, 1= 100 MBit, 2= 1 GBit
uint32_t duplex : 1; ///< Duplex mode: 0= Half, 1= Full
uint32_t autoneg : 1; ///< Set the interface to Auto Negotiation mode of transmission parameters
uint32_t loopback : 1; ///< Set the interface into a Loop-back test mode
uint32_t isolation : 1; ///< Set to indicate electrical isolation of PHY interface from MII/RMII interface
uint32_t reserved : 26;
} eth_link_info_t;
typedef struct
{
csi_eth_phy_read_t phy_read;
csi_eth_phy_write_t phy_write;
eth_link_info_t link_info;
} eth_phy_priv_t;
typedef enum eth_link_state
{
ETH_LINK_DOWN, ///< Link is down
ETH_LINK_UP ///< Link is up
} eth_link_state_t;
/* Basic mode control register */
#define CVI_BMCR_RESV (0x003f)
#define CVI_BMCR_SPEED1000 (0x0040)
#define CVI_BMCR_CTST (0x0080)
#define CVI_BMCR_FULLDPLX (0x0100)
#define CVI_BMCR_ANRESTART (0x0200)
#define CVI_BMCR_ISOLATE (0x0400)
#define CVI_BMCR_PDOWN (0x0800)
#define CVI_BMCR_ANENABLE (0x1000)
#define CVI_BMCR_SPEED100 (0x2000)
#define CVI_BMCR_LOOPBACK (0x4000)
#define CVI_BMCR_RESET (0x8000)
#define BMCR_SPEED10 (0x0000)
/* Generic MII registers */
#define CVI_MII_BMCR (0x00)
#define CVI_MII_BMSR (0x01)
#define CVI_MII_PHYSID1 (0x02)
#define CVI_MII_PHYSID2 (0x03)
#define CVI_MII_ADVERTISE (0x04)
#define CVI_MII_LPA (0x05)
#define CVI_MII_EXPANSION (0x06)
#define CVI_MII_CTRL1000 (0x09)
#define CVI_MII_STAT1000 (0x0a)
#define MII_MMD_CTRL (0x0d)
#define MII_MMD_DATA (0x0e)
#define CVI_MII_ESTATUS (0x0f)
#define CVI_MII_DCOUNTER (0x12)
#define CVI_MII_FCSCOUNTER (0x13)
#define CVI_MII_NWAYTEST (0x14)
#define CVI_MII_RERRCOUNTER (0x15)
#define CVI_MII_SREVISION (0x16)
#define CVI_MII_RESV1 (0x17)
#define CVI_MII_LBRERROR (0x18)
#define CVI_MII_PHYADDR (0x19)
#define CVI_MII_RESV2 (0x1a)
#define CVI_MII_TPISTATUS (0x1b)
#define CVI_MII_NCONFIG (0x1c)
/* Advertisement control register. */
#define CVI_ADVERTISE_CSMA (0x0001)
#define CVI_ADVERTISE_SLCT (0x001f)
#define CVI_ADVERTISE_10HALF (0x0020)
#define CVI_ADVERTISE_1000XFULL (0x0020)
#define CVI_ADVERTISE_10FULL (0x0040)
#define CVI_ADVERTISE_1000XHALF (0x0040)
#define CVI_ADVERTISE_100HALF (0x0080)
#define CVI_ADVERTISE_1000XPAUSE (0x0080)
#define CVI_ADVERTISE_100FULL (0x0100)
#define CVI_ADVERTISE_1000XPSE_ASYM (0x0100)
#define CVI_ADVERTISE_100BASE4 (0x0200)
#define CVI_ADVERTISE_PAUSE_CAP (0x0400)
#define CVI_ADVERTISE_PAUSE_ASYM (0x0800)
#define CVI_ADVERTISE_RESV (0x1000)
#define CVI_ADVERTISE_RFAULT (0x2000)
#define CVI_ADVERTISE_LPACK (0x4000)
#define CVI_ADVERTISE_NPAGE (0x8000)
/* Basic mode status register. */
#define CVI_BMSR_ERCAP (0x0001)
#define CVI_BMSR_JCD (0x0002)
#define CVI_BMSR_LSTATUS (0x0004)
#define CVI_BMSR_ANEGCAPABLE (0x0008)
#define CVI_BMSR_RFAULT (0x0010)
#define CVI_BMSR_ANEGCOMPLETE (0x0020)
#define CVI_BMSR_RESV (0x00c0)
#define CVI_BMSR_ESTATEN (0x0100)
#define CVI_BMSR_100HALF2 (0x0200)
#define CVI_BMSR_100FULL2 (0x0400)
#define CVI_BMSR_10HALF (0x0800)
#define CVI_BMSR_10FULL (0x1000)
#define CVI_BMSR_100HALF (0x2000)
#define CVI_BMSR_100FULL (0x4000)
#define CVI_BMSR_100BASE4 (0x8000)
#define CVI_ADVERTISE_FULL (CVI_ADVERTISE_100FULL | CVI_ADVERTISE_10FULL | \
CVI_ADVERTISE_CSMA)
#define CVI_ADVERTISE_ALL (CVI_ADVERTISE_10HALF | CVI_ADVERTISE_10FULL | \
CVI_ADVERTISE_100HALF | CVI_ADVERTISE_100FULL)
/* Link partner ability register. */
#define CVI_LPA_SLCT (0x001f) /* Same as advertise selector */
#define CVI_LPA_10HALF (0x0020) /* Can do 10mbps half-duplex */
#define CVI_LPA_1000XFULL (0x0020) /* Can do 1000BASE-X full-duplex */
#define CVI_LPA_10FULL (0x0040) /* Can do 10mbps full-duplex */
#define CVI_LPA_1000XHALF (0x0040) /* Can do 1000BASE-X half-duplex */
#define CVI_LPA_100HALF (0x0080) /* Can do 100mbps half-duplex */
#define CVI_LPA_1000XPAUSE (0x0080) /* Can do 1000BASE-X pause */
#define CVI_LPA_100FULL (0x0100) /* Can do 100mbps full-duplex */
#define CVI_LPA_1000XPAUSE_ASYM (0x0100) /* Can do 1000BASE-X pause asym */
#define CVI_LPA_100BASE4 (0x0200) /* Can do 100mbps 4k packets */
#define CVI_LPA_PAUSE_CAP (0x0400) /* Can pause */
#define CVI_LPA_PAUSE_ASYM (0x0800) /* Can pause asymetrically */
#define CVI_LPA_RESV (0x1000) /* Unused */
#define CVI_LPA_RFAULT (0x2000) /* Link partner faulted */
#define CVI_LPA_LPACK (0x4000) /* Link partner acked us */
#define CVI_LPA_NPAGE (0x8000) /* Next page bit */
#define CVI_LPA_DUPLEX (CVI_LPA_10FULL | CVI_LPA_100FULL)
#define CVI_LPA_100 (CVI_LPA_100FULL | CVI_LPA_100HALF | CVI_LPA_100BASE4)
/* Expansion register for auto-negotiation. */
#define CVI_EXPANSION_NWAY (0x0001) /* Can do N-way auto-nego */
#define CVI_EXPANSION_LCWP (0x0002) /* Got new RX page code word */
#define CVI_EXPANSION_ENABLENPAGE (0x0004) /* This enables npage words */
#define CVI_EXPANSION_NPCAPABLE (0x0008) /* Link partner supports npage */
#define CVI_EXPANSION_MFAULTS (0x0010) /* Multiple faults detected */
#define CVI_EXPANSION_RESV (0xffe0) /* Unused */
#define CVI_ESTATUS_1000_XFULL (0x8000) /* Can do 1000BX Full */
#define CVI_ESTATUS_1000_XHALF (0x4000) /* Can do 1000BX Half */
#define CVI_ESTATUS_1000_TFULL (0x2000) /* Can do 1000BT Full */
#define CVI_ESTATUS_1000_THALF (0x1000) /* Can do 1000BT Half */
/* N-way test register. */
#define CVI_NWAYTEST_RESV1 (0x00ff) /* Unused */
#define CVI_NWAYTEST_LOOPBACK (0x0100) /* Enable loopback for N-way */
#define CVI_NWAYTEST_RESV2 (0xfe00) /* Unused */
/* 1000BASE-T Control register */
#define CVI_ADVERTISE_1000FULL 0x0200 /* Advertise 1000BASE-T full duplex */
#define CVI_ADVERTISE_1000HALF 0x0100 /* Advertise 1000BASE-T half duplex */
#define CTL1000_AS_MASTER 0x0800
#define CTL1000_ENABLE_MASTER 0x1000
/* 1000BASE-T Status register */
#define CVI_LPA_1000LOCALRXOK 0x2000 /* Link partner local receiver status */
#define CVI_LPA_1000REMRXOK 0x1000 /* Link partner remote receiver status */
#define CVI_LPA_1000FULL 0x0800 /* Link partner 1000BASE-T full duplex */
#define CVI_LPA_1000HALF 0x0400 /* Link partner 1000BASE-T half duplex */
/* Flow control flags */
#define CVI_FLOW_CTRL_TX 0x01
#define CVI_FLOW_CTRL_RX 0x02
/* MMD Access Control register fields */
#define CVI_MII_MMD_CTRL_DEVAD_MASK 0x1f /* Mask MMD DEVAD*/
#define CVI_MII_MMD_CTRL_ADDR 0x0000 /* Address */
#define CVI_MII_MMD_CTRL_NOINCR 0x4000 /* no post increment */
#define CVI_MII_MMD_CTRL_INCR_RDWT 0x8000 /* post increment on reads & writes */
#define CVI_MII_MMD_CTRL_INCR_ON_WT 0xC000 /* post increment on writes only */
/* Indicates what features are advertised by the interface. */
#define CVI_ADVERTISED_10baseT_Half (1 << 0)
#define CVI_ADVERTISED_10baseT_Full (1 << 1)
#define CVI_ADVERTISED_100baseT_Half (1 << 2)
#define CVI_ADVERTISED_100baseT_Full (1 << 3)
#define CVI_ADVERTISED_1000baseT_Half (1 << 4)
#define CVI_ADVERTISED_1000baseT_Full (1 << 5)
#define CVI_ADVERTISED_Autoneg (1 << 6)
#define CVI_ADVERTISED_TP (1 << 7)
#define CVI_ADVERTISED_AUI (1 << 8)
#define CVI_ADVERTISED_MII (1 << 9)
#define CVI_ADVERTISED_FIBRE (1 << 10)
#define CVI_ADVERTISED_BNC (1 << 11)
#define CVI_ADVERTISED_10000baseT_Full (1 << 12)
#define CVI_ADVERTISED_Pause (1 << 13)
#define CVI_ADVERTISED_Asym_Pause (1 << 14)
#define CVI_ADVERTISED_2500baseX_Full (1 << 15)
#define CVI_ADVERTISED_Backplane (1 << 16)
#define CVI_ADVERTISED_1000baseKX_Full (1 << 17)
#define CVI_ADVERTISED_10000baseKX4_Full (1 << 18)
#define CVI_ADVERTISED_10000baseKR_Full (1 << 19)
#define CVI_ADVERTISED_10000baseR_FEC (1 << 20)
#define CVI_ADVERTISED_1000baseX_Half (1 << 21)
#define CVI_ADVERTISED_1000baseX_Full (1 << 22)
/* Indicates what features are supported by the interface. */
#define CVI_SUPPORTED_10baseT_Half (1 << 0)
#define CVI_SUPPORTED_10baseT_Full (1 << 1)
#define CVI_SUPPORTED_100baseT_Half (1 << 2)
#define CVI_SUPPORTED_100baseT_Full (1 << 3)
#define CVI_SUPPORTED_1000baseT_Half (1 << 4)
#define CVI_SUPPORTED_1000baseT_Full (1 << 5)
#define CVI_SUPPORTED_Autoneg (1 << 6)
#define CVI_SUPPORTED_TP (1 << 7)
#define CVI_SUPPORTED_AUI (1 << 8)
#define CVI_SUPPORTED_MII (1 << 9)
#define CVI_SUPPORTED_FIBRE (1 << 10)
#define CVI_SUPPORTED_BNC (1 << 11)
#define CVI_SUPPORTED_10000baseT_Full (1 << 12)
#define CVI_SUPPORTED_Pause (1 << 13)
#define CVI_SUPPORTED_Asym_Pause (1 << 14)
#define CVI_SUPPORTED_2500baseX_Full (1 << 15)
#define CVI_SUPPORTED_Backplane (1 << 16)
#define CVI_SUPPORTED_1000baseKX_Full (1 << 17)
#define CVI_SUPPORTED_10000baseKX4_Full (1 << 18)
#define CVI_SUPPORTED_10000baseKR_Full (1 << 19)
#define CVI_SUPPORTED_10000baseR_FEC (1 << 20)
#define CVI_SUPPORTED_1000baseX_Half (1 << 21)
#define CVI_SUPPORTED_1000baseX_Full (1 << 22)
/* PHY features */
#define CVI_PHY_DEFAULT_FEATURES (CVI_SUPPORTED_Autoneg | \
CVI_SUPPORTED_TP | \
CVI_SUPPORTED_MII)
#define CVI_PHY_10BT_FEATURES (CVI_SUPPORTED_10baseT_Half | \
CVI_SUPPORTED_10baseT_Full)
#define CVI_PHY_100BT_FEATURES (CVI_SUPPORTED_100baseT_Half | \
CVI_SUPPORTED_100baseT_Full)
#define CVI_PHY_1000BT_FEATURES (CVI_SUPPORTED_1000baseT_Half | \
CVI_SUPPORTED_1000baseT_Full)
#define CVI_PHY_BASIC_FEATURES (CVI_PHY_10BT_FEATURES | \
CVI_PHY_100BT_FEATURES | \
CVI_PHY_DEFAULT_FEATURES)
#define CVI_PHY_GBIT_FEATURES (CVI_PHY_BASIC_FEATURES | \
CVI_PHY_1000BT_FEATURES)
#define CVI_PHY_ANEG_TIMEOUT 5000 /* in ms */
typedef enum {
LOOPBACK_XMII2MAC,
LOOPBACK_PCS2MAC,
LOOPBACK_PMA2MAC,
LOOPBACK_RMII2PHY,
} phy_loopback_mode_t;
/* phy interface mode */
typedef enum {
PHY_IF_MODE_MII,
PHY_IF_MODE_GMII,
PHY_IF_MODE_SGMII,
PHY_IF_MODE_TBI,
PHY_IF_MODE_RMII,
PHY_IF_MODE_RGMII,
PHY_IF_MODE_RGMII_ID,
PHY_IF_MODE_RGMII_RXID,
PHY_IF_MODE_RGMII_TXID,
PHY_IF_MODE_RTBI,
PHY_IF_MODE_NONE, /* Last One */
PHY_IF_MODE_COUNT,
} phy_if_mode_t;
typedef struct {
eth_phy_priv_t *priv;
eth_link_state_t link_state;
uint32_t supported;
uint32_t advertising;
/*
* platform specific
*/
uint32_t phy_addr;
phy_if_mode_t interface;
/*
* driver specific
*/
uint32_t phy_id;
uint32_t mask;
uint32_t features;
int8_t name[20];
/* config() should be called before calling start() */
int32_t (*config)(eth_phy_handle_t phy_dev);
int32_t (*start)(eth_phy_handle_t phy_dev);
int32_t (*stop)(eth_phy_handle_t phy_dev);
int32_t (*loopback)(eth_phy_handle_t phy_dev);
int32_t (*update_link)(eth_phy_handle_t phy_dev);
} eth_phy_dev_t;
/* ethernet phy config */
#define ETH_PHY_BASE (uintptr_t)DRV_IOREMAP((void *)0x03009000, 0x1000)
#define ETH_PHY_INIT_MASK 0xFFFFFFF9
#define ETH_PHY_SHUTDOWN (1 << 1)
#define ETH_PHY_POWERUP 0xFFFFFFFD
#define ETH_PHY_RESET 0xFFFFFFFB
#define ETH_PHY_RESET_N (1 << 2)
#define ETH_PHY_LED_LOW_ACTIVE (1 << 3)
int generic_phy_config_aneg(eth_phy_dev_t *dev);
int generic_phy_restart_aneg(eth_phy_dev_t *dev);
int generic_phy_update_link(eth_phy_dev_t *dev);
int32_t eth_phy_read(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
int32_t eth_phy_write(eth_phy_priv_t *priv, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
int32_t eth_phy_reset(eth_phy_handle_t handle);
int32_t eth_phy_config(eth_phy_handle_t handle);
int32_t eth_phy_start(eth_phy_handle_t handle);
int32_t eth_phy_update_link(eth_phy_handle_t handle);
int32_t genphy_config(eth_phy_dev_t *phy_dev);
int32_t genphy_update_link(eth_phy_dev_t *phy_dev);
int32_t cvi_eth_phy_power_control(eth_phy_handle_t handle, eth_power_state_t state);
eth_phy_handle_t cvi_eth_phy_init(csi_eth_phy_read_t fn_read, csi_eth_phy_write_t fn_write);
#ifdef __cplusplus
}
#endif
#endif /* _ETH_PHY_H_ */
|