1 /**
2  * Copyright (C) 2016 CSI Project. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _CSI_ETH_H_
18 #define _CSI_ETH_H_
19 
20 #include <stdbool.h>
21 #include "drv/eth.h"
22 #include "drv/eth_phy.h"
23 
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27 
28 typedef void *eth_mac_handle_t;
29 
30 #define MAX_FRAMELEN   1518        /*  (note: maximum ethernet frame length would be 1518) */
31 
32 #define CSI_ETH_MAC_API_VERSION CSI_DRIVER_VERSION_MAJOR_MINOR(2,1)  /* API version */
33 
34 #define _CSI_Driver_ETH_MAC_(n)      Driver_ETH_MAC##n
35 #define  CSI_Driver_ETH_MAC_(n) _CSI_Driver_ETH_MAC_(n)
36 
37 /****** Ethernet MAC Control Codes *****/
38 
39 #define CSI_ETH_MAC_CONFIGURE           (0x01)      ///< Configure MAC; arg = configuration
40 #define CSI_ETH_MAC_CONTROL_TX          (0x02)      ///< Transmitter; arg: 0=disabled (default), 1=enabled
41 #define CSI_ETH_MAC_CONTROL_RX          (0x03)      ///< Receiver; arg: 0=disabled (default), 1=enabled
42 #define CSI_ETH_MAC_FLUSH               (0x04)      ///< Flush buffer; arg = CSI_ETH_MAC_FLUSH_...
43 #define CSI_ETH_MAC_SLEEP               (0x05)      ///< Sleep mode; arg: 1=enter and wait for Magic packet, 0=exit
44 #define CSI_ETH_MAC_VLAN_FILTER         (0x06)      ///< VLAN Filter for received frames; arg15..0: VLAN Tag; arg16: optional CSI_ETH_MAC_VLAN_FILTER_ID_ONLY; 0=disabled (default)
45 #define DRV_ETH_MAC_ADJUST_LINK         (0x07)      ///< Adjust MAC link state according to phy state; arg: phy handle
46 #define DRV_ETH_MAC_CONTROL_IRQ         (0x08)      ///< Interrupt request; arg: 0=disable, 1=enable
47 
48 /*----- Ethernet MAC Configuration -----*/
49 #define CSI_ETH_MAC_SPEED_Pos            0
50 #define CSI_ETH_MAC_SPEED_Msk           (3UL                 << CSI_ETH_MAC_SPEED_Pos)
51 #define CSI_ETH_MAC_SPEED_10M           (CSI_ETH_SPEED_10M   << CSI_ETH_MAC_SPEED_Pos)  ///< 10 Mbps link speed
52 #define CSI_ETH_MAC_SPEED_100M          (CSI_ETH_SPEED_100M  << CSI_ETH_MAC_SPEED_Pos)  ///< 100 Mbps link speed
53 #define CSI_ETH_MAC_SPEED_1G            (CSI_ETH_SPEED_1G    << CSI_ETH_MAC_SPEED_Pos)  ///< 1 Gpbs link speed
54 #define CSI_ETH_MAC_DUPLEX_Pos           2
55 #define CSI_ETH_MAC_DUPLEX_Msk          (1UL                 << CSI_ETH_MAC_DUPLEX_Pos)
56 #define CSI_ETH_MAC_DUPLEX_HALF         (CSI_ETH_DUPLEX_HALF << CSI_ETH_MAC_DUPLEX_Pos) ///< Half duplex link
57 #define CSI_ETH_MAC_DUPLEX_FULL         (CSI_ETH_DUPLEX_FULL << CSI_ETH_MAC_DUPLEX_Pos) ///< Full duplex link
58 #define CSI_ETH_MAC_LOOPBACK            (1UL << 4)  ///< Loop-back test mode
59 #define CSI_ETH_MAC_CHECKSUM_OFFLOAD_RX (1UL << 5)  ///< Receiver Checksum offload
60 #define CSI_ETH_MAC_CHECKSUM_OFFLOAD_TX (1UL << 6)  ///< Transmitter Checksum offload
61 #define CSI_ETH_MAC_ADDRESS_BROADCAST   (1UL << 7)  ///< Accept frames with Broadcast address
62 #define CSI_ETH_MAC_ADDRESS_MULTICAST   (1UL << 8)  ///< Accept frames with any Multicast address
63 #define CSI_ETH_MAC_ADDRESS_ALL         (1UL << 9)  ///< Accept frames with any address (Promiscuous Mode)
64 
65 /*----- Ethernet MAC Flush Flags -----*/
66 #define CSI_ETH_MAC_FLUSH_RX            (1UL << 0)  ///< Flush Receive buffer
67 #define CSI_ETH_MAC_FLUSH_TX            (1UL << 1)  ///< Flush Transmit buffer
68 
69 /*----- Ethernet MAC VLAN Filter Flag -----*/
70 #define CSI_ETH_MAC_VLAN_FILTER_ID_ONLY (1UL << 16) ///< Compare only the VLAN Identifier (12-bit)
71 
72 
73 /****** Ethernet MAC Frame Transmit Flags *****/
74 #define CSI_ETH_MAC_TX_FRAME_FRAGMENT   (1UL << 0)  ///< Indicate frame fragment
75 #define CSI_ETH_MAC_TX_FRAME_EVENT      (1UL << 1)  ///< Generate event when frame is transmitted
76 #define CSI_ETH_MAC_TX_FRAME_TIMESTAMP  (1UL << 2)  ///< Capture frame time stamp
77 
78 
79 /****** Ethernet MAC Timer Control Codes *****/
80 #define CSI_ETH_MAC_TIMER_GET_TIME      (0x01)      ///< Get current time
81 #define CSI_ETH_MAC_TIMER_SET_TIME      (0x02)      ///< Set new time
82 #define CSI_ETH_MAC_TIMER_INC_TIME      (0x03)      ///< Increment current time
83 #define CSI_ETH_MAC_TIMER_DEC_TIME      (0x04)      ///< Decrement current time
84 #define CSI_ETH_MAC_TIMER_SET_ALCSI     (0x05)      ///< Set alarm time
85 #define CSI_ETH_MAC_TIMER_ADJUST_CLOCK  (0x06)      ///< Adjust clock frequency; time->ns: correction factor * 2^31
86 
87 
88 /**
89 \brief Ethernet MAC Time
90 */
91 typedef struct eth_mac_time {
92     uint32_t ns;                          ///< Nano seconds
93     uint32_t sec;                         ///< Seconds
94 } eth_mac_time_t;
95 
96 
97 /****** Ethernet MAC Event *****/
98 #define CSI_ETH_MAC_EVENT_RX_FRAME      (1UL << 0)  ///< Frame Received
99 #define CSI_ETH_MAC_EVENT_TX_FRAME      (1UL << 1)  ///< Frame Transmitted
100 #define CSI_ETH_MAC_EVENT_WAKEUP        (1UL << 2)  ///< Wake-up (on Magic Packet)
101 #define CSI_ETH_MAC_EVENT_TIMER_ALCSI   (1UL << 3)  ///< Timer Alarm
102 #define CSI_ETH_MAC_EVENT_LINK_CHANGE   (1UL << 4)  ///< Link state
103 
104 typedef void (*eth_event_cb_t)(int32_t idx, uint32_t event);  ///< Pointer to \ref eth_event_cb_t : Signal Ethernet Event.
105 
106 typedef enum {
107     FRAME_FILTER_RULE_POSITIVE_MATCHING  = 0,       /*!< Specifies that a filter should match a given pattern     */
108     FRAME_FILTER_RULE_NEGATIVE_MATCHING  = 1,       /*!< Specifies that a filter should NOT match a given pattern */
109 } frame_filter_rule_t;
110 
111 /**
112 \brief Ethernet MAC Capabilities
113 */
114 typedef struct eth_capabilities {
115     uint32_t checksum_offload_rx_ip4  : 1;        ///< 1 = IPv4 header checksum verified on receive
116     uint32_t checksum_offload_rx_ip6  : 1;        ///< 1 = IPv6 checksum verification supported on receive
117     uint32_t checksum_offload_rx_udp  : 1;        ///< 1 = UDP payload checksum verified on receive
118     uint32_t checksum_offload_rx_tcp  : 1;        ///< 1 = TCP payload checksum verified on receive
119     uint32_t checksum_offload_rx_icmp : 1;        ///< 1 = ICMP payload checksum verified on receive
120     uint32_t checksum_offload_tx_ip4  : 1;        ///< 1 = IPv4 header checksum generated on transmit
121     uint32_t checksum_offload_tx_ip6  : 1;        ///< 1 = IPv6 checksum generation supported on transmit
122     uint32_t checksum_offload_tx_udp  : 1;        ///< 1 = UDP payload checksum generated on transmit
123     uint32_t checksum_offload_tx_tcp  : 1;        ///< 1 = TCP payload checksum generated on transmit
124     uint32_t checksum_offload_tx_icmp : 1;        ///< 1 = ICMP payload checksum generated on transmit
125     uint32_t media_interface          : 2;        ///< Ethernet Media Interface type
126     uint32_t mac_address              : 1;        ///< 1 = driver provides initial valid MAC address
127     uint32_t event_rx_frame           : 1;        ///< 1 = callback event generated
128     uint32_t event_tx_frame           : 1;        ///< 1 = callback event generated
129     uint32_t event_wakeup             : 1;        ///< 1 = wakeup event generated
130     uint32_t precision_timer          : 1;        ///< 1 = Precision Timer supported
131     uint32_t reserved                 : 15;       ///< Reserved (must be zero)
132 } eth_capabilities_t;
133 
134 /**
135  * Structure describing a frame filter list item
136  */
137 typedef struct {
138     uint32_t                       id;             /*!< Unique identifier for a packet filter item */
139     frame_filter_rule_t            rule;           /*!< Filter matches are either POSITIVE or NEGATIVE matching */
140     uint16_t                       offset;         /*!< Offset in bytes to start filtering (referenced to the start of the ethernet packet) */
141     uint16_t                       mask_size;      /*!< Size of the mask in bytes */
142     uint8_t                       *mask;           /*!< Pattern mask bytes to be ANDed with the pattern eg. "\xff00" (must be in network byte order) */
143     uint8_t                       *pattern;        /*!< Pattern bytes used to filter eg. "\x0800"  (must be in network byte order) */
144     bool                           enabled_status; /*!< When returned from mhd_get_packet_filters, indicates if the filter is enabled */
145 } eth_frame_filter_t;
146 
147 struct eth_frame_filter_list {
148     struct eth_frame_filter_list  *next;
149 };
150 
151 typedef struct eth_frame_filter_list eth_frame_filter_list_t;
152 
153 typedef struct {
154     eth_event_cb_t      cb_event;
155     eth_capabilities_t  capabilities;
156 } eth_mac_priv_t;
157 
158 /**
159   \brief       Get driver version.
160   \param[in]   handle  ethernet handle
161   \return      ethernet version including chip version and driver version
162 */
163 csi_drv_version_t csi_eth_mac_get_version(eth_mac_handle_t handle);
164 
165 /**
166   \brief       Get driver capabilities.
167   \param[in]   idx device id
168   \return      ethernet capabilities
169 */
170 eth_capabilities_t csi_eth_mac_get_capabilities(int32_t idx);
171 
172 /**
173   \brief       This function is used to initialize Ethernet device and related resource, an event callback is registered. It is called when the middleware component like TCPIP starts operation.
174   \param[in]   idx device id
175   \param[in]   cb  callback to handle ethernet event
176   \return      return ethernet handle if success
177  */
178 eth_mac_handle_t csi_eth_mac_initialize(int32_t idx, eth_event_cb_t cb_event);
179 
180 /**
181   \brief       This function is used to de-initialize Ethernet device. It is called when the middleware component stops operation and releases the software resources used by the interface.
182   \param[in]   handle  ethernet handle
183   \return      error code
184  */
185 int32_t csi_eth_mac_uninitialize(eth_mac_handle_t handle);
186 
187 /**
188   \brief       Connect phy device to mac device.
189   \param[in]   handle_mac  mac handle
190   \param[in]   handle_phy  phy handle
191 */
192 void csi_eth_mac_connect_phy(eth_mac_handle_t handle_mac, eth_phy_handle_t handle_phy);
193 
194 /**
195   \brief       Control Ethernet MAC Device Power.
196   \param[in]   handle  ethernet handle
197   \param[in]   state  Power state
198   \return      error code
199 */
200 int32_t csi_eth_mac_power_control(eth_mac_handle_t handle, eth_power_state_t state);
201 
202 /**
203   \brief       Get Ethernet MAC Address.
204   \param[in]   handle  ethernet handle
205   \param[in]   mac  Pointer to address
206   \return      error code
207 */
208 int32_t csi_eth_mac_get_macaddr(eth_mac_handle_t handle, eth_mac_addr_t *mac);
209 
210 /**
211   \brief       Set Ethernet MAC Address.
212   \param[in]   handle  ethernet handle
213   \param[in]   mac  Pointer to address
214   \return      error code
215 */
216 int32_t csi_eth_mac_set_macaddr(eth_mac_handle_t handle, const eth_mac_addr_t *mac);
217 
218 /**
219   \brief       Configure Address Filter.
220   \param[in]   handle  ethernet handle
221   \param[in]   addr  Pointer to addresses
222   \param[in]   num_addr  Number of addresses to configure
223   \return      error code
224 */
225 int32_t csi_eth_mac_set_addrfilter(eth_mac_handle_t handle, const eth_mac_addr_t *addr, uint32_t num_addr);
226 
227 /**
228   \brief       Send Ethernet frame.
229   \param[in]   handle  ethernet handle
230   \param[in]   frame  Pointer to frame buffer with data to send
231   \param[in]   len    Frame buffer length in bytes
232   \param[in]   flags  Frame transmit flags (see CSI_ETH_MAC_TX_FRAME_...)
233   \return      error code
234 */
235 int32_t csi_eth_mac_send_frame(eth_mac_handle_t handle, const uint8_t *frame, uint32_t len, uint32_t flags);
236 
237 /**
238   \brief       Read data of received Ethernet frame.
239   \param[in]   handle  ethernet handle
240   \param[in]   frame  Pointer to frame buffer for data to read into
241   \param[in]   len    Frame buffer length in bytes
242   \return      number of data bytes read or execution status
243                  - value >= 0: number of data bytes read
244                  - value < 0: error occurred, value is execution status as defined with execution_status
245 */
246 int32_t csi_eth_mac_read_frame(eth_mac_handle_t handle, uint8_t *frame, uint32_t len);
247 
248 /**
249   \brief       Request data of received Ethernet frame.
250                csi_eth_mac_request_frame() and csi_eth_mac_release_frame()
251                must be called in pairs.
252   \param[in]   handle  ethernet handle
253   \param[in]   frame  Pointer to frame buffer pointer
254   \return      number of data bytes read or execution status
255                  - value >= 0: number of data bytes read
256                  - value < 0: error occurred
257 */
258 int32_t csi_eth_mac_request_frame(eth_mac_handle_t handle, uint8_t **frame);
259 
260 /**
261   \brief       Release current Ethernet frame.
262                csi_eth_mac_request_frame() and csi_eth_mac_release_frame()
263                must be called in pairs.
264   \param[in]   handle  ethernet handle
265   \return      error code
266 */
267 int32_t csi_eth_mac_release_frame(eth_mac_handle_t handle);
268 
269 /**
270   \brief       Get size of received Ethernet frame.
271   \param[in]   handle  ethernet handle
272   \return      number of bytes in received frame
273 */
274 int32_t csi_eth_mac_get_rx_framesize(eth_mac_handle_t handle);
275 
276 /**
277   \brief       Get time of received Ethernet frame.
278   \param[in]   handle  ethernet handle
279   \param[in]   time  Pointer to time structure for data to read into
280   \return      error code
281 */
282 int32_t csi_eth_mac_get_rx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
283 
284 /**
285   \brief       Get time of transmitted Ethernet frame.
286   \param[in]   handle  ethernet handle
287   \param[in]   time  Pointer to time structure for data to read into
288   \return      error code
289 */
290 int32_t csi_eth_mac_get_tx_frametime(eth_mac_handle_t handle, eth_mac_time_t *time);
291 
292 /**
293   \brief       Control Ethernet Interface.
294   \param[in]   handle  ethernet handle
295   \param[in]   control  Operation
296   \param[in]   arg      Argument of operation (optional)
297   \return      error code
298 */
299 int32_t csi_eth_mac_control(eth_mac_handle_t handle, uint32_t control, uint32_t arg);
300 
301 /**
302   \brief       Control Precision Timer.
303   \param[in]   handle  ethernet handle
304   \param[in]   control  Operation
305   \param[in]   time     Pointer to time structure
306   \return      error code
307 */
308 int32_t csi_eth_mac_control_time(eth_mac_handle_t handle, uint32_t control, eth_mac_time_t *time);
309 
310 /**
311   \brief       Read Ethernet PHY Register through Management Interface.
312   \param[in]   handle  ethernet handle
313   \param[in]   phy_addr  5-bit device address
314   \param[in]   reg_addr  5-bit register address
315   \param[out]  data      Pointer where the result is written to
316   \return      error code
317 */
318 int32_t csi_eth_mac_phy_read(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
319 
320 /**
321   \brief       Write Ethernet PHY Register through Management Interface.
322   \param[in]   handle  ethernet handle
323   \param[in]   phy_addr  5-bit device address
324   \param[in]   reg_addr  5-bit register address
325   \param[in]   data      16-bit data to write
326   \return      error code
327 */
328 int32_t csi_eth_mac_phy_write(eth_mac_handle_t handle, uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
329 
330 /**
331   \brief       Callback function that signals a Ethernet Event.
332   \param[in]   handle  ethernet handle
333   \param[in]   event  event notification mask
334   \return      none
335 */
336 void csi_eth_mac_signal_event(eth_mac_handle_t handle, uint32_t event);
337 
338 /**
339   \brief       Add Frame Filter Setting with Filter ID.
340   \param[in]   handle  ethernet handle
341   \param[in]   filter  Pointer to filter setting
342   \return      error code
343 */
344 int32_t csi_eth_mac_add_framefilter(eth_mac_handle_t handle, const eth_frame_filter_t *filter);
345 
346 /**
347   \brief       Remove Frame Filter Setting.
348   \param[in]   handle  ethernet handle
349   \param[in]   filter_id  Frame Filter ID
350   \return      error code
351 */
352 int32_t csi_eth_mac_remove_framefilter(eth_mac_handle_t handle, uint32_t filter_id);
353 
354 /**
355   \brief       Enable/Disable Specified Frame Filter ID.
356   \param[in]   handle  ethernet handle
357   \param[in]   filter_id  Frame Filter ID
358   \param[in]   en  Enable or disable
359   \return      error code
360 */
361 int32_t csi_eth_mac_en_framefilter(eth_mac_handle_t handle, uint32_t filter_id, bool en);
362 
363 /**
364   \brief       Get frame filter table list.
365   \param[in]   handle  ethernet handle
366   \param[in]   list  frame filter table list
367   \param[in]   count_out  the count of filter setting added
368   \param[in]   max_count  max filter setting can be supported
369   \return      error code
370 */
371 int32_t csi_eth_mac_get_framefilter(eth_mac_handle_t handle, eth_frame_filter_list_t *list, uint32_t *count_out, uint32_t max_count);
372 
373 #ifdef __cplusplus
374 }
375 #endif
376 
377 #endif
378