1 /*
2 * Copyright 2022, Cypress Semiconductor Corporation (an Infineon company)
3 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 /** @file
19 *
20 * Implements functions called by WHD user APIs, but not directly exposed to user
21 *
22 * This file provides functions which are not directly exposed to user but, called by end-user functions which allow actions such as
23 * seting the MAC address, getting channel info, etc
24 */
25
26 #include "whd_ap.h"
27 #include "whd_chip_constants.h"
28 #include "whd_debug.h"
29 #include "whd_events_int.h"
30 #include "whd_cdc_bdc.h"
31 #include "whd_thread_internal.h"
32 #include "whd_utils.h"
33 #include "whd_wifi_api.h"
34 #include "whd_wlioctl.h"
35
36 /******************************************************
37 * @cond Constants
38 ******************************************************/
39 #define MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT 0x02
40
41 /******************************************************
42 * Local Structures
43 ******************************************************/
44
45
46
47 /******************************************************
48 * Variables
49 ******************************************************/
50 void (*whd_wifi_link_update_callback)(void) = NULL;
51
52 /******************************************************
53 * Function definitions
54 ******************************************************/
55
whd_wifi_set_mac_address(whd_interface_t ifp,whd_mac_t mac)56 uint32_t whd_wifi_set_mac_address(whd_interface_t ifp, whd_mac_t mac)
57 {
58 whd_buffer_t buffer;
59 uint32_t *data;
60 whd_driver_t whd_driver = ifp->whd_driver;
61
62 /* AP interface needs to come up with MAC different from STA */
63 #ifdef APOLLO_AUDIO
64
65 /* Work around the issue of asking API to set one address and it sets a different address.
66 * This will cause any comparison of set and get mac address to fail. TODO: move twiddling this
67 * bit to a higher level.
68 */
69 if (0)
70 #else
71 if (ifp->role == WHD_AP_ROLE)
72 #endif
73 {
74 whd_mac_t ap_mac_address;
75
76 memcpy(&ap_mac_address, &mac, sizeof(whd_mac_t) );
77 if (ap_mac_address.octet[0] & MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT)
78 {
79 ap_mac_address.octet[0] &= (uint8_t) ~(MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT);
80 }
81 else
82 {
83 ap_mac_address.octet[0] |= MAC_ADDRESS_LOCALLY_ADMINISTERED_BIT;
84 }
85
86 data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR);
87 CHECK_IOCTL_BUFFER(data);
88 memcpy(data, &ap_mac_address, sizeof(whd_mac_t) );
89 CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL) );
90
91 if (memcmp(&mac, &ap_mac_address, sizeof(whd_mac_t) ) != 0)
92 {
93 WPRINT_WHD_INFO( (" STA MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n"
94 " AP MAC address : %02x:%02x:%02x:%02x:%02x:%02x \n",
95 mac.octet[0], mac.octet[1], mac.octet[2],
96 mac.octet[3], mac.octet[4], mac.octet[3],
97 ap_mac_address.octet[0], ap_mac_address.octet[1], ap_mac_address.octet[2],
98 ap_mac_address.octet[3], ap_mac_address.octet[4], ap_mac_address.octet[3]) );
99 }
100 }
101 else
102 {
103 data = (uint32_t *)whd_cdc_get_iovar_buffer(whd_driver, &buffer, sizeof(whd_mac_t), IOVAR_STR_CUR_ETHERADDR);
104 CHECK_IOCTL_BUFFER(data);
105 memcpy(data, &mac, sizeof(whd_mac_t) );
106 CHECK_RETURN(whd_cdc_send_iovar(ifp, CDC_SET, buffer, NULL) );
107 }
108
109 return WHD_SUCCESS;
110 }
111