1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing peer handling specific definitions for the
9 * FMAC IF Layer of the Wi-Fi driver.
10 */
11
12 #include "common/hal_mem.h"
13 #include "system/fmac_peer.h"
14 #include "host_rpu_umac_if.h"
15 #include "common/fmac_util.h"
16
nrf_wifi_fmac_peer_get_id(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,const unsigned char * mac_addr)17 int nrf_wifi_fmac_peer_get_id(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
18 const unsigned char *mac_addr)
19 {
20 int i;
21 struct peers_info *peer;
22 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
23
24 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
25
26 if (nrf_wifi_util_is_multicast_addr(mac_addr)) {
27 return MAX_PEERS;
28 }
29
30 for (i = 0; i < MAX_PEERS; i++) {
31 peer = &sys_dev_ctx->tx_config.peers[i];
32 if (peer->peer_id == -1) {
33 continue;
34 }
35
36 if ((nrf_wifi_util_ether_addr_equal(mac_addr,
37 (void *)peer->ra_addr))) {
38 return peer->peer_id;
39 }
40 }
41 return -1;
42 }
43
nrf_wifi_fmac_peer_add(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char if_idx,const unsigned char * mac_addr,unsigned char is_legacy,unsigned char qos_supported)44 int nrf_wifi_fmac_peer_add(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
45 unsigned char if_idx,
46 const unsigned char *mac_addr,
47 unsigned char is_legacy,
48 unsigned char qos_supported)
49 {
50 int i;
51 struct peers_info *peer;
52 struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
53 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
54
55 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
56
57 vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
58
59 if (nrf_wifi_util_is_multicast_addr(mac_addr)
60 && (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP)) {
61
62 sys_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx;
63 sys_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = MAX_PEERS;
64 sys_dev_ctx->tx_config.peers[MAX_PEERS].is_legacy = 1;
65
66
67 return MAX_PEERS;
68 }
69
70 for (i = 0; i < MAX_PEERS; i++) {
71 peer = &sys_dev_ctx->tx_config.peers[i];
72
73 if (peer->peer_id == -1) {
74 nrf_wifi_osal_mem_cpy(peer->ra_addr,
75 mac_addr,
76 NRF_WIFI_ETH_ADDR_LEN);
77 peer->if_idx = if_idx;
78 peer->peer_id = i;
79 peer->is_legacy = is_legacy;
80 peer->qos_supported = qos_supported;
81 if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) {
82 hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx,
83 (RPU_MEM_UMAC_PEND_Q_BMP +
84 sizeof(struct sap_client_pend_frames_bitmap) * i),
85 peer->ra_addr,
86 NRF_WIFI_FMAC_ETH_ADDR_LEN);
87 }
88 return i;
89 }
90 }
91
92 nrf_wifi_osal_log_err("%s: Failed !! No Space Available",
93 __func__);
94
95 return -1;
96 }
97
98
nrf_wifi_fmac_peer_remove(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char if_idx,int peer_id)99 void nrf_wifi_fmac_peer_remove(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
100 unsigned char if_idx,
101 int peer_id)
102 {
103 struct peers_info *peer;
104 struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
105 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
106
107 if (peer_id == -1 || peer_id >= MAX_PEERS) {
108 return;
109 }
110
111 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
112
113 vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
114 peer = &sys_dev_ctx->tx_config.peers[peer_id];
115
116 if (!peer || peer->peer_id == -1 || peer->peer_id >= MAX_PEERS ||
117 peer->if_idx != if_idx) {
118 return;
119 }
120
121 if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) {
122 hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx,
123 (RPU_MEM_UMAC_PEND_Q_BMP +
124 (sizeof(struct sap_client_pend_frames_bitmap) * peer_id)),
125 peer->ra_addr,
126 NRF_WIFI_FMAC_ETH_ADDR_LEN);
127 }
128
129 nrf_wifi_osal_mem_set(peer,
130 0x0,
131 sizeof(struct peers_info));
132 peer->peer_id = -1;
133 }
134
135
nrf_wifi_fmac_peers_flush(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,unsigned char if_idx)136 void nrf_wifi_fmac_peers_flush(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
137 unsigned char if_idx)
138 {
139 struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL;
140 unsigned int i = 0;
141 struct peers_info *peer = NULL;
142 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
143
144 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
145
146 vif_ctx = sys_dev_ctx->vif_ctx[if_idx];
147 sys_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = -1;
148
149 for (i = 0; i < MAX_PEERS; i++) {
150 peer = &sys_dev_ctx->tx_config.peers[i];
151
152 if (peer->peer_id == -1)
153 continue;
154
155 if (peer->if_idx == if_idx) {
156
157 nrf_wifi_osal_mem_set(peer,
158 0x0,
159 sizeof(struct peers_info));
160 peer->peer_id = -1;
161
162 if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) {
163 hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx,
164 (RPU_MEM_UMAC_PEND_Q_BMP +
165 sizeof(struct sap_client_pend_frames_bitmap) * i),
166 peer->ra_addr,
167 NRF_WIFI_FMAC_ETH_ADDR_LEN);
168 }
169 }
170 }
171 }
172