1 /*
2 * Copyright (c) 2024 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @brief File containing SoftAP specific definitions for the
9 * FMAC IF Layer of the Wi-Fi driver.
10 */
11
12 #include "system/fmac_ap.h"
13 #include "system/fmac_peer.h"
14 #include "queue.h"
15 #include "system/fmac_tx.h"
16 #include "common/fmac_util.h"
17
sap_client_ps_get_frames(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_sap_ps_get_frames * config)18 enum nrf_wifi_status sap_client_ps_get_frames(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
19 struct nrf_wifi_sap_ps_get_frames *config)
20 {
21 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
22 struct peers_info *peer = NULL;
23 void *wakeup_client_q = NULL;
24 int id = -1;
25 int ac = 0;
26 int desc = 0;
27 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
28 struct nrf_wifi_sys_fmac_priv *sys_priv = NULL;
29
30 if (!fmac_dev_ctx || !config) {
31 nrf_wifi_osal_log_err("%s: Invalid params",
32 __func__);
33 goto out;
34 }
35
36 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
37 sys_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
38
39 nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock);
40
41 id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, config->mac_addr);
42
43 if (id == -1) {
44 nrf_wifi_osal_log_err("%s: Invalid Peer_ID, Mac Addr =%pM",
45 __func__,
46 config->mac_addr);
47
48 nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
49 goto out;
50 }
51
52
53 peer = &sys_dev_ctx->tx_config.peers[id];
54 peer->ps_token_count = config->num_frames;
55
56 wakeup_client_q = sys_dev_ctx->tx_config.wakeup_client_q;
57
58 if (wakeup_client_q) {
59 nrf_wifi_utils_q_enqueue(wakeup_client_q,
60 peer);
61 }
62
63 for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) {
64 desc = tx_desc_get(fmac_dev_ctx, ac);
65
66 if (desc < sys_priv->num_tx_tokens) {
67 tx_pending_process(fmac_dev_ctx, desc, ac);
68 }
69 }
70
71 nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
72
73 status = NRF_WIFI_STATUS_SUCCESS;
74 out:
75 return status;
76 }
77
78
sap_client_update_pmmode(struct nrf_wifi_fmac_dev_ctx * fmac_dev_ctx,struct nrf_wifi_sap_client_pwrsave * config)79 enum nrf_wifi_status sap_client_update_pmmode(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx,
80 struct nrf_wifi_sap_client_pwrsave *config)
81 {
82 enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL;
83 struct peers_info *peer = NULL;
84 void *wakeup_client_q = NULL;
85 int id = -1;
86 int ac = 0;
87 int desc = 0;
88 struct nrf_wifi_sys_fmac_dev_ctx *sys_dev_ctx = NULL;
89 struct nrf_wifi_sys_fmac_priv *sys_priv = NULL;
90
91 if (!fmac_dev_ctx || !config) {
92 nrf_wifi_osal_log_err("%s: Invalid params",
93 __func__);
94 goto out;
95 }
96
97 sys_dev_ctx = wifi_dev_priv(fmac_dev_ctx);
98 sys_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv);
99
100 nrf_wifi_osal_spinlock_take(sys_dev_ctx->tx_config.tx_lock);
101
102 id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx,
103 config->mac_addr);
104
105 if (id == -1) {
106 nrf_wifi_osal_log_err("%s: Invalid Peer_ID, Mac address = %pM",
107 __func__,
108 config->mac_addr);
109
110 nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
111
112 goto out;
113 }
114
115
116 peer = &sys_dev_ctx->tx_config.peers[id];
117 peer->ps_state = config->sta_ps_state;
118
119 if (peer->ps_state == NRF_WIFI_CLIENT_ACTIVE) {
120 wakeup_client_q = sys_dev_ctx->tx_config.wakeup_client_q;
121
122 if (wakeup_client_q) {
123 nrf_wifi_utils_q_enqueue(wakeup_client_q,
124 peer);
125 }
126
127 for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) {
128 desc = tx_desc_get(fmac_dev_ctx, ac);
129
130 if (desc < sys_priv->num_tx_tokens) {
131 tx_pending_process(fmac_dev_ctx, desc, ac);
132 }
133 }
134 }
135
136 nrf_wifi_osal_spinlock_rel(sys_dev_ctx->tx_config.tx_lock);
137
138 status = NRF_WIFI_STATUS_SUCCESS;
139
140 out:
141 return status;
142 }
143