Mistake on this page?
Report an issue in GitHub or email us
sl_emac.h
1 /***************************************************************************//**
2  * @file sl_eth_phy.h
3  *******************************************************************************
4  * @section License
5  * <b>modifications (C) Copyright 2018 Silicon Labs, http://www.silabs.com</b>
6  * <b>original Copyright (c) 2015 ARM Limited</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Apache-2.0
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License"); you may
12  * not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
19  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  *
23  ******************************************************************************/
24 #ifndef SL_EMAC_H_
25 #define SL_EMAC_H_
26 
27 #include "EMAC.h"
28 #include "rtos/Semaphore.h"
29 #include "rtos/Mutex.h"
30 
31 class SL_EMAC : public EMAC {
32 public:
33  SL_EMAC();
34 
35  static SL_EMAC &get_instance();
36 
37  /**
38  * Return maximum transmission unit
39  *
40  * @return MTU in bytes
41  */
42  virtual uint32_t get_mtu_size() const;
43 
44  /**
45  * Gets memory buffer alignment preference
46  *
47  * Gets preferred memory buffer alignment of the Emac device.
48  * IP stack may or may not align link out memory buffer chains
49  * using the alignment.
50  *
51  * @return Memory alignment requirement in bytes
52  */
53  virtual uint32_t get_align_preference() const;
54 
55  /**
56  * Return interface name
57  *
58  * @param name Pointer to where the name should be written
59  * @param size Maximum number of character to copy
60  */
61  virtual void get_ifname(char *name, uint8_t size) const;
62 
63  /**
64  * Returns size of the underlying interface HW address size.
65  *
66  * @return HW address size in bytes
67  */
68  virtual uint8_t get_hwaddr_size() const;
69 
70  /**
71  * Return interface-supplied HW address
72  *
73  * Copies HW address to provided memory, @param addr has to be of correct
74  * size see @a get_hwaddr_size
75  *
76  * HW address need not be provided if this interface does not have its own
77  * HW address configuration; stack will choose address from central system
78  * configuration if the function returns false and does not write to addr.
79  *
80  * @param addr HW address for underlying interface
81  * @return true if HW address is available
82  */
83  virtual bool get_hwaddr(uint8_t *addr) const;
84 
85  /**
86  * Set HW address for interface
87  *
88  * Provided address has to be of correct size, see @a get_hwaddr_size
89  *
90  * Called to set the MAC address to actually use - if @a get_hwaddr is
91  * provided the stack would normally use that, but it could be overridden,
92  * eg for test purposes.
93  *
94  * @param addr Address to be set
95  */
96  virtual void set_hwaddr(const uint8_t *addr);
97 
98  /**
99  * Sends the packet over the link
100  *
101  * That can not be called from an interrupt context.
102  *
103  * @param buf Packet to be send
104  * @return True if the packet was send successfully, False otherwise
105  */
106  virtual bool link_out(emac_mem_buf_t *buf);
107 
108  /**
109  * Initializes the HW
110  *
111  * @return True on success, False in case of an error.
112  */
113  virtual bool power_up();
114 
115  /**
116  * Deinitializes the HW
117  *
118  */
119  virtual void power_down();
120 
121  /**
122  * Sets a callback that needs to be called for packets received for that
123  * interface
124  *
125  * @param input_cb Function to be register as a callback
126  */
127  virtual void set_link_input_cb(emac_link_input_cb_t input_cb);
128 
129  /**
130  * Sets a callback that needs to be called on link status changes for given
131  * interface
132  *
133  * @param state_cb Function to be register as a callback
134  */
135  virtual void set_link_state_cb(emac_link_state_change_cb_t state_cb);
136 
137  /** Add device to a multicast group
138  *
139  * @param address A multicast group hardware address
140  */
141  virtual void add_multicast_group(const uint8_t *address);
142 
143  /** Remove device from a multicast group
144  *
145  * @param address A multicast group hardware address
146  */
147  virtual void remove_multicast_group(const uint8_t *address);
148 
149  /** Request reception of all multicast packets
150  *
151  * @param all True to receive all multicasts
152  * False to receive only multicasts addressed to specified groups
153  */
154  virtual void set_all_multicast(bool all);
155 
156  /** Sets memory manager that is used to handle memory buffers
157  *
158  * @param mem_mngr Pointer to memory manager
159  */
160  virtual void set_memory_manager(EMACMemoryManager &mem_mngr);
161 
162  osThreadId_t thread; /** Ethernet driver thread */
163 
164 private:
165 
166  /* Instance variables */
167 
168  /** Semaphore protecting the TX state.
169  * Not a mutex since we're posting from IRQ
170  */
171  rtos::Semaphore tx_sem;
172  /** (R)MII address where the detected PHY is residing */
173  uint8_t phy_addr;
174  /** Index in RX queue for next packet to read */
175  uint8_t rx_idx;
176 
177  /** Multicast mask reference count. Multicast filtering is done using a hash
178  * bit, so multiple multicast addresses might map to the same bit. That's
179  * why there needs to be a reference count for every bit in the 64-bit mask
180  */
181  uint8_t mcast_hash_refcnt[64];
182 
183  /** Local reference to the buffer that's in the process of being sent */
184  emac_mem_buf_t *tx_buf;
185  /** List of current RX buffers, which autonomously get filled by the
186  * Ethernet peripheral.
187  */
188  emac_mem_buf_t *rx_bufs[SL_ETH_NUM_RX_BD];
189 
190  typedef struct {
191  uint32_t addr;
192  uint32_t status;
193  } sl_eth_bd_t;
194 
195  /** Internal list of DMA descriptors for the RX buffer pool */
196  sl_eth_bd_t rx_bds[SL_ETH_NUM_RX_BD];
197  /** Internal list of DMA descriptors to point to the current buffer being
198  * sent */
199  sl_eth_bd_t tx_bds[SL_ETH_NUM_TX_BD];
200 
201  /**< Processing thread */
202  mbed_rtos_storage_thread_t thread_cb;
203 
204  /**< Callback for incoming data */
205  emac_link_input_cb_t emac_link_input_cb;
206  /**< Callback for link state change */
207  emac_link_state_change_cb_t emac_link_state_cb;
208 
209  /**< Memory manager instance */
210  EMACMemoryManager *memory_manager;
211 
212  bool connected;
213  bool up;
214 
215  /* private functions */
216  /**
217  * Thread to de-escalate Ethernet peripheral IRQ's
218  */
219  static void eth_thread(void* instance);
220 
221  /**
222  * This function polls the (R)MII bus for the first
223  * available attached PHY chip, resets and enables the PHY
224  * in auto-negotiation mode.
225  */
226  void phy_init(void);
227 
228  /**
229  * Write to detected PHY register. Nop if no PHY initialized.
230  */
231  void write_phy(uint8_t reg_addr, uint16_t data);
232 
233  /**
234  * Read from detected PHY register. Nop if no PHY initialized.
235  */
236  void read_phy(uint8_t reg_addr, uint16_t *data);
237 
238  /**
239  * This function checks the detected PHY for its
240  * current link status. Nop if no PHY was previously detected.
241  * Fires callback set by set_link_state_cb on change in link state.
242  */
243  void link_state_poll(void);
244 
245  /**
246  * Initializes buffer structures
247  */
248  void data_init(void);
249 
250  /**
251  * De-initializes buffer structures
252  */
253  void data_deinit(void);
254 };
255 
256 #endif /* SL_EMAC_H_ */
virtual void set_all_multicast(bool all)
Request reception of all multicast packets.
virtual void set_hwaddr(const uint8_t *addr)
Set HW address for interface.
The Semaphore class is used to manage and protect access to a set of shared resources.
Definition: Semaphore.h:50
#define SL_ETH_NUM_RX_BD
Number of descriptors in receive list.
#define SL_ETH_NUM_TX_BD
Number of descriptors in transmit list.
virtual uint32_t get_mtu_size() const
Return maximum transmission unit.
virtual void add_multicast_group(const uint8_t *address)
Add device to a multicast group.
virtual bool power_up()
Initializes the HW.
virtual bool link_out(emac_mem_buf_t *buf)
Sends the packet over the link.
mbed::Callback< void(emac_mem_buf_t *buf)> emac_link_input_cb_t
Callback to be register with EMAC interface and to be called for received packets.
Definition: EMAC.h:48
virtual void get_ifname(char *name, uint8_t size) const
Return interface name.
virtual void set_memory_manager(EMACMemoryManager &mem_mngr)
Sets memory manager that is used to handle memory buffers.
virtual uint32_t get_align_preference() const
Gets memory buffer alignment preference.
This interface should be used to abstract low level access to networking hardware All operations rece...
Definition: EMAC.h:32
virtual bool get_hwaddr(uint8_t *addr) const
Return interface-supplied HW address.
virtual void remove_multicast_group(const uint8_t *address)
Remove device from a multicast group.
virtual uint8_t get_hwaddr_size() const
Returns size of the underlying interface HW address size.
virtual void power_down()
Deinitializes the HW.
virtual void set_link_input_cb(emac_link_input_cb_t input_cb)
Sets a callback that needs to be called for packets received for that interface.
virtual void set_link_state_cb(emac_link_state_change_cb_t state_cb)
Sets a callback that needs to be called on link status changes for given interface.
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.