cc33xx_driver.c
Go to the documentation of this file.
1 /**
2  * @file cc33xx_driver.c
3  * @brief CC3300/CC3301 Wi-Fi controller
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2024 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneTCP Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.4.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL NIC_TRACE_LEVEL
33 
34 //Dependencies
35 #include <stdint.h>
36 #include "wlan_if.h"
37 #include "errors.h"
38 #include "core/net.h"
40 #include "debug.h"
41 
42 //Underlying network interface
45 
46 //Forward declaration of functions
47 void cc33xxEventCallback(WlanEvent_t *wlanEvent);
48 void cc33xxStaRxCallback(WlanRole_e role, uint8_t *data, uint32_t length);
49 void cc33xxApRxCallback(WlanRole_e role, uint8_t *data, uint32_t length);
50 
51 
52 /**
53  * @brief CC33xx driver (STA mode)
54  **/
55 
57 {
59  ETH_MTU,
60  cc33xxInit,
61  cc33xxTick,
67  NULL,
68  NULL,
69  NULL,
70  TRUE,
71  TRUE,
72  TRUE,
73  TRUE
74 };
75 
76 
77 /**
78  * @brief CC33xx driver (AP mode)
79  **/
80 
82 {
84  ETH_MTU,
85  cc33xxInit,
86  cc33xxTick,
92  NULL,
93  NULL,
94  NULL,
95  TRUE,
96  TRUE,
97  TRUE,
98  TRUE
99 };
100 
101 
102 /**
103  * @brief CC33xx initialization
104  * @param[in] interface Underlying network interface
105  * @return Error code
106  **/
107 
109 {
110  int_t ret;
111  WlanMacAddress_t macAddrParams;
112 
113  //Initialize status code
114  ret = WLAN_RET_CODE_OK;
115 
116  //STA or AP mode?
117  if(interface->nicDriver == &cc33xxStaDriver)
118  {
119  //Debug message
120  TRACE_INFO("Initializing CC33xx (STA mode)...\r\n");
121  }
122  else
123  {
124  //Debug message
125  TRACE_INFO("Initializing CC33xx (AP mode)...\r\n");
126  }
127 
128  //Initialization sequence is performed once
129  if(cc33xxStaInterface == NULL && cc33xxApInterface == NULL)
130  {
131  //Wi-Fi host driver initialization
132  ret = Wlan_Start(cc33xxEventCallback);
133  }
134 
135  //Check status code
136  if(ret == WLAN_RET_CODE_OK)
137  {
138  //STA or AP mode?
139  if(interface->nicDriver == &cc33xxStaDriver)
140  {
141  //Save underlying network interface (STA mode)
142  cc33xxStaInterface = interface;
143 
144  //Optionally set the MAC address
145  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
146  {
147  //Use the factory preprogrammed station address
148  macAddrParams.roleType = WLAN_ROLE_STA;
149  osMemset(macAddrParams.pMacAddress, 0, 6);
150  ret = Wlan_Get(WLAN_GET_MACADDRESS, &macAddrParams);
151 
152  //Check status code
153  if(ret == WLAN_RET_CODE_OK)
154  {
155  //Generate the 64-bit interface identifier
156  macAddrToEui64(&interface->macAddr, &interface->eui64);
157  }
158  }
159  else
160  {
161  //Override the factory preprogrammed address
162  macAddrParams.roleType = WLAN_ROLE_STA;
163  osMemcpy(macAddrParams.pMacAddress, interface->macAddr.b, 6);
164  ret = Wlan_Set(WLAN_SET_MACADDRESS, &macAddrParams);
165  }
166 
167  //Check status code
168  if(ret == WLAN_RET_CODE_OK)
169  {
170  //Register RX callback
171  ret = Wlan_EtherPacketRecvRegisterCallback(WLAN_ROLE_STA,
173  }
174  }
175  else
176  {
177  //Save underlying network interface (AP mode)
178  cc33xxApInterface = interface;
179 
180  //Optionally set the MAC address
181  if(macCompAddr(&interface->macAddr, &MAC_UNSPECIFIED_ADDR))
182  {
183  //Use the factory preprogrammed station address
184  macAddrParams.roleType = WLAN_ROLE_AP;
185  osMemset(macAddrParams.pMacAddress, 0, 6);
186  ret = Wlan_Get(WLAN_GET_MACADDRESS, &macAddrParams);
187 
188  //Check status code
189  if(ret == WLAN_RET_CODE_OK)
190  {
191  //Generate the 64-bit interface identifier
192  macAddrToEui64(&interface->macAddr, &interface->eui64);
193  }
194  }
195  else
196  {
197  //Override the factory preprogrammed address
198  macAddrParams.roleType = WLAN_ROLE_AP;
199  osMemcpy(macAddrParams.pMacAddress, interface->macAddr.b, 6);
200  ret = Wlan_Set(WLAN_SET_MACADDRESS, &macAddrParams);
201  }
202 
203  //Check status code
204  if(ret == WLAN_RET_CODE_OK)
205  {
206  //Register RX callback
207  ret = Wlan_EtherPacketRecvRegisterCallback(WLAN_ROLE_AP,
209  }
210  }
211  }
212 
213  //CC33xx is now ready to send
214  osSetEvent(&interface->nicTxEvent);
215 
216  //Return status code
217  if(ret == WLAN_RET_CODE_OK)
218  {
219  return NO_ERROR;
220  }
221  else
222  {
223  return ERROR_FAILURE;
224  }
225 }
226 
227 
228 /**
229  * @brief CC33xx timer handler
230  *
231  * This routine is periodically called by the TCP/IP stack to handle periodic
232  * operations such as polling the link state
233  *
234  * @param[in] interface Underlying network interface
235  **/
236 
237 void cc33xxTick(NetInterface *interface)
238 {
239 }
240 
241 
242 /**
243  * @brief Enable interrupts
244  * @param[in] interface Underlying network interface
245  **/
246 
248 {
249 }
250 
251 
252 /**
253  * @brief Disable interrupts
254  * @param[in] interface Underlying network interface
255  **/
256 
258 {
259 }
260 
261 
262 /**
263  * @brief CC33xx event handler
264  * @param[in] interface Underlying network interface
265  **/
266 
268 {
269 }
270 
271 
272 /**
273  * @brief Send a packet
274  * @param[in] interface Underlying network interface
275  * @param[in] buffer Multi-part buffer containing the data to send
276  * @param[in] offset Offset to the first data byte
277  * @param[in] ancillary Additional options passed to the stack along with
278  * the packet
279  * @return Error code
280  **/
281 
283  const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
284 {
285  static uint8_t temp[2048];
286  int_t ret;
287  size_t length;
288 
289  //Retrieve the length of the packet
290  length = netBufferGetLength(buffer) - offset;
291 
292  //Debug message
293  //TRACE_INFO("CC33xx TX packet (%u bytes)\r\n", length);
294 
295  //Make sure the link is up before transmitting the frame
296  if(!interface->linkState)
297  {
298  //The transmitter can accept another packet
299  osSetEvent(&interface->nicTxEvent);
300  //Drop current packet
301  return NO_ERROR;
302  }
303 
304  //Copy user data to the transmit buffer
305  netBufferRead(temp, buffer, offset, length);
306 
307  //STA or AP mode?
308  if(interface == cc33xxStaInterface)
309  {
310  //Send packet
311  ret = Wlan_EtherPacketSend(WLAN_ROLE_STA, temp, length, 0);
312  }
313  else
314  {
315  //Send packet
316  ret = Wlan_EtherPacketSend(WLAN_ROLE_AP, temp, length, 0);
317  }
318 
319  //The transmitter can accept another packet
320  osSetEvent(&interface->nicTxEvent);
321 
322  //Return status code
323  if(ret >= 0)
324  {
325  return NO_ERROR;
326  }
327  else
328  {
329  return ERROR_FAILURE;
330  }
331 }
332 
333 
334 /**
335  * @brief Configure MAC address filtering
336  * @param[in] interface Underlying network interface
337  * @return Error code
338  **/
339 
341 {
342  //Debug message
343  TRACE_INFO("Updating CC33xx multicast filter...\r\n");
344 
345  //Successful processing
346  return NO_ERROR;
347 }
348 
349 
350 /**
351  * @brief WLAN event callback function
352  * @param[in] event Pointer to the event object
353  **/
354 
355 void __weak_func cc33xxEventCallback(WlanEvent_t *event)
356 {
357  //Debug message
358  TRACE_INFO("CC33xx WLAN event callback\r\n");
359 
360  if(event->Id == WLAN_EVENT_CONNECT)
361  {
362  //Debug message
363  TRACE_INFO(" WLAN_EVENT_CONNECT\r\n");
364  TRACE_INFO(" Channel = %u\r\n", event->Data.Connect.Channel);
365  }
366  else if(event->Id == WLAN_EVENT_DISCONNECT)
367  {
368  //Debug message
369  TRACE_INFO(" WLAN_EVENT_DISCONNECT\r\n");
370  TRACE_INFO(" Reason Code = %u\r\n", event->Data.Disconnect.ReasonCode);
371  }
372  else if(event->Id == WLAN_EVENT_SCAN_RESULT)
373  {
374  //Debug message
375  TRACE_INFO(" WLAN_EVENT_SCAN_RESULT\r\n");
376  }
377  else if(event->Id == WLAN_EVENT_ADD_PEER)
378  {
379  //Debug message
380  TRACE_INFO(" WLAN_EVENT_ADD_PEER\r\n");
381  TRACE_INFO_ARRAY(" MAC = ", event->Data.AddPeer.Mac, 6);
382  }
383  else if(event->Id == WLAN_EVENT_REMOVE_PEER)
384  {
385  //Debug message
386  TRACE_INFO(" WLAN_EVENT_REMOVE_PEER\r\n");
387  TRACE_INFO_ARRAY(" MAC = ", event->Data.RemovePeer.Mac, 6);
388  }
389  else
390  {
391  //Debug message
392  TRACE_INFO(" Unknown event ID (%u)\r\n", event->Id);
393  }
394 }
395 
396 
397 /**
398  * @brief Process incoming packets (STA interface)
399  * @param[in] role WLAN role
400  * @param[in] data Pointer to the received packet
401  * @param[in] length Length of the packet, in bytes
402  **/
403 
404 void cc33xxStaRxCallback(WlanRole_e role, uint8_t *data, uint32_t length)
405 {
406  NetRxAncillary ancillary;
407 
408  //Debug message
409  //TRACE_INFO("CC33xx STA RX received callback (%u bytes)\r\n", length);
410 
411  //Valid STA interface?
412  if(cc33xxStaInterface != NULL)
413  {
414  //Get exclusive access
416 
417  //Additional options can be passed to the stack along with the packet
418  ancillary = NET_DEFAULT_RX_ANCILLARY;
419 
420  //Pass the packet to the upper layer
422 
423  //Release exclusive access
425  }
426 }
427 
428 
429 /**
430  * @brief Process incoming packets (AP interface)
431  * @param[in] role WLAN role
432  * @param[in] data Pointer to the received packet
433  * @param[in] length Length of the packet, in bytes
434  **/
435 
436 void cc33xxApRxCallback(WlanRole_e role, uint8_t *data, uint32_t length)
437 {
438  NetRxAncillary ancillary;
439 
440  //Debug message
441  //TRACE_INFO("CC33xx AP RX received callback (%u bytes)\r\n", length);
442 
443  //Valid AP interface?
444  if(cc33xxApInterface != NULL)
445  {
446  //Get exclusive access
448 
449  //Additional options can be passed to the stack along with the packet
450  ancillary = NET_DEFAULT_RX_ANCILLARY;
451 
452  //Pass the packet to the upper layer
454 
455  //Release exclusive access
457  }
458 }
void cc33xxEnableIrq(NetInterface *interface)
Enable interrupts.
const NicDriver cc33xxStaDriver
CC33xx driver (STA mode)
Definition: cc33xx_driver.c:56
const NicDriver cc33xxApDriver
CC33xx driver (AP mode)
Definition: cc33xx_driver.c:81
void cc33xxTick(NetInterface *interface)
CC33xx timer handler.
error_t cc33xxUpdateMacAddrFilter(NetInterface *interface)
Configure MAC address filtering.
void cc33xxStaRxCallback(WlanRole_e role, uint8_t *data, uint32_t length)
Process incoming packets (STA interface)
void cc33xxEventHandler(NetInterface *interface)
CC33xx event handler.
NetInterface * cc33xxApInterface
Definition: cc33xx_driver.c:44
void cc33xxDisableIrq(NetInterface *interface)
Disable interrupts.
void cc33xxEventCallback(WlanEvent_t *wlanEvent)
WLAN event callback function.
NetInterface * cc33xxStaInterface
Definition: cc33xx_driver.c:43
void cc33xxApRxCallback(WlanRole_e role, uint8_t *data, uint32_t length)
Process incoming packets (AP interface)
error_t cc33xxInit(NetInterface *interface)
CC33xx initialization.
error_t cc33xxSendPacket(NetInterface *interface, const NetBuffer *buffer, size_t offset, NetTxAncillary *ancillary)
Send a packet.
CC3300/CC3301 Wi-Fi controller.
signed int int_t
Definition: compiler_port.h:49
Debugging facilities.
#define TRACE_INFO_ARRAY(p, a, n)
Definition: debug.h:96
#define TRACE_INFO(...)
Definition: debug.h:95
error_t
Error codes.
Definition: error.h:43
@ NO_ERROR
Success.
Definition: error.h:44
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
const MacAddr MAC_UNSPECIFIED_ADDR
Definition: ethernet.c:53
void macAddrToEui64(const MacAddr *macAddr, Eui64 *interfaceId)
Map a MAC address to the IPv6 modified EUI-64 identifier.
Definition: ethernet.c:944
#define ETH_MTU
Definition: ethernet.h:116
uint8_t data[]
Definition: ethernet.h:222
#define macCompAddr(macAddr1, macAddr2)
Definition: ethernet.h:130
TCP/IP stack core.
#define NetInterface
Definition: net.h:36
#define netMutex
Definition: net_legacy.h:195
size_t netBufferGetLength(const NetBuffer *buffer)
Get the actual length of a multi-part buffer.
Definition: net_mem.c:297
size_t netBufferRead(void *dest, const NetBuffer *src, size_t srcOffset, size_t length)
Read data from a multi-part buffer.
Definition: net_mem.c:674
const NetRxAncillary NET_DEFAULT_RX_ANCILLARY
Definition: net_misc.c:101
#define NetRxAncillary
Definition: net_misc.h:40
#define NetTxAncillary
Definition: net_misc.h:36
void nicProcessPacket(NetInterface *interface, uint8_t *packet, size_t length, NetRxAncillary *ancillary)
Handle a packet received by the network controller.
Definition: nic.c:391
@ NIC_TYPE_ETHERNET
Ethernet interface.
Definition: nic.h:83
#define osMemset(p, value, length)
Definition: os_port.h:135
#define osMemcpy(dest, src, length)
Definition: os_port.h:141
#define TRUE
Definition: os_port.h:50
void osAcquireMutex(OsMutex *mutex)
Acquire ownership of the specified mutex object.
void osReleaseMutex(OsMutex *mutex)
Release ownership of the specified mutex object.
void osSetEvent(OsEvent *event)
Set the specified event object to the signaled state.
Structure describing a buffer that spans multiple chunks.
Definition: net_mem.h:89
NIC driver.
Definition: nic.h:283
uint8_t length
Definition: tcp.h:368