summaryrefslogtreecommitdiff
path: root/bsp/bouffalo_lab/libraries/bl_mcu_sdk/drivers/lhal/include/bflb_emac.h
blob: 7e28fd6abea856b4a76b1c357f60d753f029c656 (plain)
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
#ifndef _BFLB_EMAC_H
#define _BFLB_EMAC_H

#include "bflb_core.h"

/** @addtogroup LHAL
  * @{
  */

/** @addtogroup EMAC
  * @{
  */

#define EMAC_DO_FLUSH_DATA (1)

/* EMAC clock use external or use internal; 0: used external 1: used internal */
#define EMAC_CLK_USE_EXTERNAL (0)
#define EMAC_CLK_USE_INTERNAL (1)

/** @defgroup EMAC_CMD emac feature control cmd definition
  * @{
  */
#define EMAC_CMD_NO_PREAMBLE_MODE (0x01)
#define EMAC_CMD_EN_PROMISCUOUS   (0x02)
#define EMAC_CMD_FRAME_GAP_CHECK  (0x03)
#define EMAC_CMD_FULL_DUPLEX      (0x04)
#define EMAC_CMD_EN_TX_CRC_FIELD  (0x05)
#define EMAC_CMD_RECV_HUGE_FRAMES (0x06)
#define EMAC_CMD_EN_AUTO_PADDING  (0x07)
#define EMAC_CMD_RECV_SMALL_FRAME (0x08)
#define EMAC_CMD_SET_PHY_ADDRESS  (0x09)
#define EMAC_CMD_SET_MAC_ADDRESS  (0x0A)
#define EMAC_CMD_SET_PACKET_GAP   (0x0B)
#define EMAC_CMD_SET_MIN_FRAME    (0x0C)
#define EMAC_CMD_SET_MAX_FRAME    (0x0D)
#define EMAC_CMD_SET_MAXRET       (0x0E)
#define EMAC_CMD_SET_COLLVALID    (0x0F)
/**
  * @}
  */

/** @defgroup PHY_STATE phy state definition
  * @{
  */
#define PHY_STATE_DOWN    (0) /* PHY is not usable */
#define PHY_STATE_READY   (1) /* PHY is OK, wait for controller */
#define PHY_STATE_UP      (2) /* Network is ready for TX/RX */
#define PHY_STATE_RUNNING (3) /* working */
#define PHY_STATE_NOLINK  (4) /* no cable connected */
#define PHY_STATE_STOPPED (5) /* PHY has been stopped */
#define PHY_STATE_TESTING (6) /* in test mode */
/**
  * @}
  */

/* EMAC PACKET */
#define EMAC_NORMAL_PACKET   (uint32_t)(0)
#define EMAC_FRAGMENT_PACKET (uint32_t)(0x01)
#define EMAC_NOCOPY_PACKET   (uint32_t)(0x02)

/* ETH packet size */
/* ETH     | Header | Extra | VLAN tag | Payload   | CRC | */
/* Size    | 14     | 2     | 4        | 46 ~ 1500 | 4   | */
#define ETH_MAX_PACKET_SIZE          ((uint32_t)1524U) /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */
#define ETH_HEADER_SZIE              ((uint32_t)14U)   /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
#define ETH_CRC_SIZE                 ((uint32_t)4U)    /*!< Ethernet CRC */
#define ETH_EXTRA_SIZE               ((uint32_t)2U)    /*!< Extra bytes in some cases */
#define ETH_VLAN_TAG_SIZE            ((uint32_t)4U)    /*!< optional 802.1q VLAN Tag */
#define ETH_MIN_ETH_PAYLOAD_SIZE     ((uint32_t)46U)   /*!< Minimum Ethernet payload size */
#define ETH_MAX_ETH_PAYLOAD_SIZE     ((uint32_t)1500U) /*!< Maximum Ethernet payload size */
#define ETH_JUMBO_FRAME_PAYLOAD_SIZE ((uint32_t)9000U) /*!< Jumbo frame payload size */

/* ETH tx & rx buffer size */
#ifndef ETH_TX_BUFFER_SIZE
#define ETH_TX_BUFFER_SIZE (ETH_MAX_PACKET_SIZE)
#endif
#ifndef ETH_RX_BUFFER_SIZE
#define ETH_RX_BUFFER_SIZE (ETH_MAX_PACKET_SIZE)
#endif

/* emac interrupt UNMASK/MASK define */
#define EMAC_INT_EN_TX_DONE  (1 << 0)
#define EMAC_INT_EN_TX_ERROR (1 << 1)
#define EMAC_INT_EN_RX_DONE  (1 << 2)
#define EMAC_INT_EN_RX_ERROR (1 << 3)
#define EMAC_INT_EN_RX_BUSY  (1 << 4)
#define EMAC_INT_EN_TX_CTRL  (1 << 5)
#define EMAC_INT_EN_RX_CTRL  (1 << 6)
#define EMAC_INT_EN_ALL      (0x7f << 0)

/* emac interrupt status define */
#define EMAC_INT_STS_TX_DONE  (1 << 0)
#define EMAC_INT_STS_TX_ERROR (1 << 1)
#define EMAC_INT_STS_RX_DONE  (1 << 2)
#define EMAC_INT_STS_RX_ERROR (1 << 3)
#define EMAC_INT_STS_RX_BUSY  (1 << 4)
#define EMAC_INT_STS_TX_CTRL  (1 << 5)
#define EMAC_INT_STS_RX_CTRL  (1 << 6)
#define EMAC_INT_STS_ALL      (0x7f << 0)

/* emac buffer descriptors type define */
#define EMAC_BD_TYPE_INVLAID (0)
#define EMAC_BD_TYPE_TX      (1)
#define EMAC_BD_TYPE_RX      (2)
#define EMAC_BD_TYPE_NONE    (3)
#define EMAC_BD_TYPE_MAX     (0x7FFFFFFF)

/**
 * @brief EMAC configuration structure
 *
 * @param mac_addr  EMAC mac addr
 * @param inside_clk EMAC select inside or external @ref EMAC_CLK_USE_EXTERNAL or EMAC_CLK_USE_INTERNAL
 * @param mii_clk_div mii clock div
 * @param min_frame_len min frame len
 * @param max_frame_len max frame len
 *
 */
struct bflb_emac_config_s {
    uint8_t mac_addr[6];
    uint8_t inside_clk;
    uint8_t mii_clk_div;
    uint16_t min_frame_len;
    uint16_t max_frame_len;
};

/**
 * @brief EMAC phy configuration structure
 *
 * @param auto_negotiation EMAC phy speed and mode auto negotiation
 * @param full_duplex      EMAC phy duplex mode
 * @param phy_state        EMAC phy down,ready,up,running,nolink,halted, @ref PHY_STATE
 * @param use_irq          EMAC phy interrupt enable 0: no IRQ used
 * @param speed            EMAC phy speed mode
 * @param phy_address      EMAC phy address
 * @param phy_id           EMAC phy read phy id
 */
struct bflb_emac_phy_cfg_s {
    uint8_t auto_negotiation;
    uint8_t full_duplex;
    uint8_t phy_state;
    uint8_t use_irq;
    uint16_t speed;
    uint16_t phy_address;
    uint32_t phy_id;
};

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] config
 */
void bflb_emac_init(struct bflb_device_s *dev, const struct bflb_emac_config_s *config);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_stop(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_start(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_start_tx(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_stop_tx(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_start_rx(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 */
void bflb_emac_stop_rx(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] eth_tx_buff
 * @param [in] tx_buf_count
 * @param [in] eth_rx_buff
 * @param [in] rx_buf_count
 */
void bflb_emac_bd_init(struct bflb_device_s *dev, uint8_t *eth_tx_buff, uint8_t tx_buf_count, uint8_t *eth_rx_buff, uint8_t rx_buf_count);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] bdt
 * @return uint32_t
 */
uint32_t bflb_emac_bd_get_cur_active(struct bflb_device_s *dev, uint8_t bdt);

/**
 * @brief
 *
 * @param [in] index
 */
void bflb_emac_bd_rx_enqueue(uint32_t index);

/**
 * @brief
 *
 * @param [in] index
 */
void bflb_emac_bd_rx_on_err(uint32_t index);

/**
 * @brief
 *
 * @param [in] index
 */
void bflb_emac_bd_tx_dequeue(uint32_t index);

/**
 * @brief
 *
 * @param [in] index
 */
void bflb_emac_bd_tx_on_err(uint32_t index);

/**
 * @brief
 *
 * @param [in] flags
 * @param [in] len
 * @param [in] data_in
 * @return int
 */
int bflb_emac_bd_tx_enqueue(uint32_t flags, uint32_t len, const uint8_t *data_in);

/**
 * @brief
 *
 * @param [in] flags
 * @param [in] len
 * @param [in] data_out
 * @return int
 */
int bflb_emac_bd_rx_dequeue(uint32_t flags, uint32_t *len, uint8_t *data_out);

/**
 * @brief
 *
 * @return int
 */
int emac_bd_fragment_support(void);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] flag
 * @param [in] enable
 */
void bflb_emac_int_enable(struct bflb_device_s *dev, uint32_t flag, bool enable);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] flag
 */
void bflb_emac_int_clear(struct bflb_device_s *dev, uint32_t flag);

/**
 * @brief
 *
 * @param [in] dev
 * @return uint32_t
 */
uint32_t bflb_emac_get_int_status(struct bflb_device_s *dev);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] cmd
 * @param [in] arg
 * @return int
 */
int bflb_emac_feature_control(struct bflb_device_s *dev, int cmd, size_t arg);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] phy_reg
 * @param [in] phy_reg_val
 * @return int
 */
int bflb_emac_phy_reg_read(struct bflb_device_s *dev, uint16_t phy_reg, uint16_t *phy_reg_val);

/**
 * @brief
 *
 * @param [in] dev
 * @param [in] phy_reg
 * @param [in] phy_reg_val
 * @return int
 */
int bflb_emac_phy_reg_write(struct bflb_device_s *dev, uint16_t phy_reg, uint16_t phy_reg_val);

#ifdef __cplusplus
}
#endif

/**
  * @}
  */

/**
  * @}
  */

#endif