1 // SPDX-License-Identifier: GPL-2.0 2 #include "cmd.h" 3 4 #include <linux/module.h> 5 #include <linux/slab.h> 6 #include <linux/etherdevice.h> 7 8 #include "wl1251.h" 9 #include "reg.h" 10 #include "io.h" 11 #include "ps.h" 12 #include "acx.h" 13 14 /** 15 * wl1251_cmd_send - Send command to firmware 16 * 17 * @wl: wl struct 18 * @id: command id 19 * @buf: buffer containing the command, must work with dma 20 * @len: length of the buffer 21 */ 22 int wl1251_cmd_send(struct wl1251 *wl, u16 id, void *buf, size_t len) 23 { 24 struct wl1251_cmd_header *cmd; 25 unsigned long timeout; 26 u32 intr; 27 int ret = 0; 28 29 cmd = buf; 30 cmd->id = id; 31 cmd->status = 0; 32 33 WARN_ON(len % 4 != 0); 34 35 wl1251_mem_write(wl, wl->cmd_box_addr, buf, len); 36 37 wl1251_reg_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_CMD); 38 39 timeout = jiffies + msecs_to_jiffies(WL1251_COMMAND_TIMEOUT); 40 41 intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 42 while (!(intr & WL1251_ACX_INTR_CMD_COMPLETE)) { 43 if (time_after(jiffies, timeout)) { 44 wl1251_error("command complete timeout"); 45 ret = -ETIMEDOUT; 46 goto out; 47 } 48 49 msleep(1); 50 51 intr = wl1251_reg_read32(wl, ACX_REG_INTERRUPT_NO_CLEAR); 52 } 53 54 wl1251_reg_write32(wl, ACX_REG_INTERRUPT_ACK, 55 WL1251_ACX_INTR_CMD_COMPLETE); 56 57 out: 58 return ret; 59 } 60 61 /** 62 * wl1251_cmd_interrogate - Read acx from firmware 63 * 64 * @wl: wl struct 65 * @id: acx id 66 * @buf: buffer for the response, including all headers, must work with dma 67 * @len: length of buf 68 */ 69 int wl1251_cmd_interrogate(struct wl1251 *wl, u16 id, void *buf, size_t len) 70 { 71 struct acx_header *acx = buf; 72 int ret; 73 74 wl1251_debug(DEBUG_CMD, "cmd interrogate"); 75 76 acx->id = id; 77 78 /* payload length, does not include any headers */ 79 acx->len = len - sizeof(*acx); 80 81 ret = wl1251_cmd_send(wl, CMD_INTERROGATE, acx, sizeof(*acx)); 82 if (ret < 0) { 83 wl1251_error("INTERROGATE command failed"); 84 goto out; 85 } 86 87 /* the interrogate command got in, we can read the answer */ 88 wl1251_mem_read(wl, wl->cmd_box_addr, buf, len); 89 90 acx = buf; 91 if (acx->cmd.status != CMD_STATUS_SUCCESS) 92 wl1251_error("INTERROGATE command error: %d", 93 acx->cmd.status); 94 95 out: 96 return ret; 97 } 98 99 /** 100 * wl1251_cmd_configure - Write acx value to firmware 101 * 102 * @wl: wl struct 103 * @id: acx id 104 * @buf: buffer containing acx, including all headers, must work with dma 105 * @len: length of buf 106 */ 107 int wl1251_cmd_configure(struct wl1251 *wl, u16 id, void *buf, size_t len) 108 { 109 struct acx_header *acx = buf; 110 int ret; 111 112 wl1251_debug(DEBUG_CMD, "cmd configure"); 113 114 acx->id = id; 115 116 /* payload length, does not include any headers */ 117 acx->len = len - sizeof(*acx); 118 119 ret = wl1251_cmd_send(wl, CMD_CONFIGURE, acx, len); 120 if (ret < 0) { 121 wl1251_warning("CONFIGURE command NOK"); 122 return ret; 123 } 124 125 return 0; 126 } 127 128 int wl1251_cmd_vbm(struct wl1251 *wl, u8 identity, 129 void *bitmap, u16 bitmap_len, u8 bitmap_control) 130 { 131 struct wl1251_cmd_vbm_update *vbm; 132 int ret; 133 134 wl1251_debug(DEBUG_CMD, "cmd vbm"); 135 136 vbm = kzalloc(sizeof(*vbm), GFP_KERNEL); 137 if (!vbm) 138 return -ENOMEM; 139 140 /* Count and period will be filled by the target */ 141 vbm->tim.bitmap_ctrl = bitmap_control; 142 if (bitmap_len > PARTIAL_VBM_MAX) { 143 wl1251_warning("cmd vbm len is %d B, truncating to %d", 144 bitmap_len, PARTIAL_VBM_MAX); 145 bitmap_len = PARTIAL_VBM_MAX; 146 } 147 memcpy(vbm->tim.pvb_field, bitmap, bitmap_len); 148 vbm->tim.identity = identity; 149 vbm->tim.length = bitmap_len + 3; 150 151 vbm->len = cpu_to_le16(bitmap_len + 5); 152 153 ret = wl1251_cmd_send(wl, CMD_VBM, vbm, sizeof(*vbm)); 154 if (ret < 0) { 155 wl1251_error("VBM command failed"); 156 goto out; 157 } 158 159 out: 160 kfree(vbm); 161 return ret; 162 } 163 164 int wl1251_cmd_data_path_rx(struct wl1251 *wl, u8 channel, bool enable) 165 { 166 struct cmd_enabledisable_path *cmd; 167 int ret; 168 u16 cmd_rx; 169 170 wl1251_debug(DEBUG_CMD, "cmd data path"); 171 172 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 173 if (!cmd) 174 return -ENOMEM; 175 176 cmd->channel = channel; 177 178 if (enable) 179 cmd_rx = CMD_ENABLE_RX; 180 else 181 cmd_rx = CMD_DISABLE_RX; 182 183 ret = wl1251_cmd_send(wl, cmd_rx, cmd, sizeof(*cmd)); 184 if (ret < 0) { 185 wl1251_error("rx %s cmd for channel %d failed", 186 enable ? "start" : "stop", channel); 187 goto out; 188 } 189 190 wl1251_debug(DEBUG_BOOT, "rx %s cmd channel %d", 191 enable ? "start" : "stop", channel); 192 193 out: 194 kfree(cmd); 195 return ret; 196 } 197 198 int wl1251_cmd_data_path_tx(struct wl1251 *wl, u8 channel, bool enable) 199 { 200 struct cmd_enabledisable_path *cmd; 201 int ret; 202 u16 cmd_tx; 203 204 wl1251_debug(DEBUG_CMD, "cmd data path"); 205 206 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 207 if (!cmd) 208 return -ENOMEM; 209 210 cmd->channel = channel; 211 212 if (enable) 213 cmd_tx = CMD_ENABLE_TX; 214 else 215 cmd_tx = CMD_DISABLE_TX; 216 217 ret = wl1251_cmd_send(wl, cmd_tx, cmd, sizeof(*cmd)); 218 if (ret < 0) 219 wl1251_error("tx %s cmd for channel %d failed", 220 enable ? "start" : "stop", channel); 221 else 222 wl1251_debug(DEBUG_BOOT, "tx %s cmd channel %d", 223 enable ? "start" : "stop", channel); 224 225 kfree(cmd); 226 return ret; 227 } 228 229 int wl1251_cmd_join(struct wl1251 *wl, u8 bss_type, u8 channel, 230 u16 beacon_interval, u8 dtim_interval) 231 { 232 struct cmd_join *join; 233 int ret, i; 234 u8 *bssid; 235 236 join = kzalloc(sizeof(*join), GFP_KERNEL); 237 if (!join) 238 return -ENOMEM; 239 240 wl1251_debug(DEBUG_CMD, "cmd join%s ch %d %d/%d", 241 bss_type == BSS_TYPE_IBSS ? " ibss" : "", 242 channel, beacon_interval, dtim_interval); 243 244 /* Reverse order BSSID */ 245 bssid = (u8 *) &join->bssid_lsb; 246 for (i = 0; i < ETH_ALEN; i++) 247 bssid[i] = wl->bssid[ETH_ALEN - i - 1]; 248 249 join->rx_config_options = wl->rx_config; 250 join->rx_filter_options = wl->rx_filter; 251 252 join->basic_rate_set = RATE_MASK_1MBPS | RATE_MASK_2MBPS | 253 RATE_MASK_5_5MBPS | RATE_MASK_11MBPS; 254 255 join->beacon_interval = beacon_interval; 256 join->dtim_interval = dtim_interval; 257 join->bss_type = bss_type; 258 join->channel = channel; 259 join->ctrl = JOIN_CMD_CTRL_TX_FLUSH; 260 261 ret = wl1251_cmd_send(wl, CMD_START_JOIN, join, sizeof(*join)); 262 if (ret < 0) { 263 wl1251_error("failed to initiate cmd join"); 264 goto out; 265 } 266 267 out: 268 kfree(join); 269 return ret; 270 } 271 272 int wl1251_cmd_ps_mode(struct wl1251 *wl, u8 ps_mode) 273 { 274 struct wl1251_cmd_ps_params *ps_params = NULL; 275 int ret = 0; 276 277 wl1251_debug(DEBUG_CMD, "cmd set ps mode"); 278 279 ps_params = kzalloc(sizeof(*ps_params), GFP_KERNEL); 280 if (!ps_params) 281 return -ENOMEM; 282 283 ps_params->ps_mode = ps_mode; 284 ps_params->send_null_data = 1; 285 ps_params->retries = 5; 286 ps_params->hang_over_period = 128; 287 ps_params->null_data_rate = 1; /* 1 Mbps */ 288 289 ret = wl1251_cmd_send(wl, CMD_SET_PS_MODE, ps_params, 290 sizeof(*ps_params)); 291 if (ret < 0) { 292 wl1251_error("cmd set_ps_mode failed"); 293 goto out; 294 } 295 296 out: 297 kfree(ps_params); 298 return ret; 299 } 300 301 int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, 302 void *buf, size_t buf_len) 303 { 304 struct wl1251_cmd_packet_template *cmd; 305 size_t cmd_len; 306 int ret = 0; 307 308 wl1251_debug(DEBUG_CMD, "cmd template %d", cmd_id); 309 310 WARN_ON(buf_len > WL1251_MAX_TEMPLATE_SIZE); 311 buf_len = min_t(size_t, buf_len, WL1251_MAX_TEMPLATE_SIZE); 312 cmd_len = ALIGN(sizeof(*cmd) + buf_len, 4); 313 314 cmd = kzalloc(cmd_len, GFP_KERNEL); 315 if (!cmd) 316 return -ENOMEM; 317 318 cmd->size = cpu_to_le16(buf_len); 319 320 if (buf) 321 memcpy(cmd->data, buf, buf_len); 322 323 ret = wl1251_cmd_send(wl, cmd_id, cmd, cmd_len); 324 if (ret < 0) { 325 wl1251_warning("cmd set_template failed: %d", ret); 326 goto out; 327 } 328 329 out: 330 kfree(cmd); 331 return ret; 332 } 333 334 int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len, 335 struct ieee80211_channel *channels[], 336 unsigned int n_channels, unsigned int n_probes) 337 { 338 struct wl1251_cmd_scan *cmd; 339 int i, ret = 0; 340 341 wl1251_debug(DEBUG_CMD, "cmd scan channels %d", n_channels); 342 343 WARN_ON(n_channels > SCAN_MAX_NUM_OF_CHANNELS); 344 345 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 346 if (!cmd) 347 return -ENOMEM; 348 349 cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD); 350 cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN | 351 CFG_RX_MGMT_EN | 352 CFG_RX_BCN_EN); 353 cmd->params.scan_options = 0; 354 /* 355 * Use high priority scan when not associated to prevent fw issue 356 * causing never-ending scans (sometimes 20+ minutes). 357 * Note: This bug may be caused by the fw's DTIM handling. 358 */ 359 if (is_zero_ether_addr(wl->bssid)) 360 cmd->params.scan_options |= cpu_to_le16(WL1251_SCAN_OPT_PRIORITY_HIGH); 361 cmd->params.num_channels = n_channels; 362 cmd->params.num_probe_requests = n_probes; 363 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */ 364 cmd->params.tid_trigger = 0; 365 366 for (i = 0; i < n_channels; i++) { 367 cmd->channels[i].min_duration = 368 cpu_to_le32(WL1251_SCAN_MIN_DURATION); 369 cmd->channels[i].max_duration = 370 cpu_to_le32(WL1251_SCAN_MAX_DURATION); 371 memset(&cmd->channels[i].bssid_lsb, 0xff, 4); 372 memset(&cmd->channels[i].bssid_msb, 0xff, 2); 373 cmd->channels[i].early_termination = 0; 374 cmd->channels[i].tx_power_att = 0; 375 cmd->channels[i].channel = channels[i]->hw_value; 376 } 377 378 if (ssid) { 379 int len = clamp_val(ssid_len, 0, IEEE80211_MAX_SSID_LEN); 380 381 cmd->params.ssid_len = len; 382 memcpy(cmd->params.ssid, ssid, len); 383 } 384 385 ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd)); 386 if (ret < 0) { 387 wl1251_error("cmd scan failed: %d", ret); 388 goto out; 389 } 390 391 wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd)); 392 393 if (cmd->header.status != CMD_STATUS_SUCCESS) { 394 wl1251_error("cmd scan status wasn't success: %d", 395 cmd->header.status); 396 ret = -EIO; 397 goto out; 398 } 399 400 out: 401 kfree(cmd); 402 return ret; 403 } 404 405 int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout) 406 { 407 struct wl1251_cmd_trigger_scan_to *cmd; 408 int ret; 409 410 wl1251_debug(DEBUG_CMD, "cmd trigger scan to"); 411 412 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 413 if (!cmd) 414 return -ENOMEM; 415 416 cmd->timeout = timeout; 417 418 ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, cmd, sizeof(*cmd)); 419 if (ret < 0) { 420 wl1251_error("cmd trigger scan to failed: %d", ret); 421 goto out; 422 } 423 424 out: 425 kfree(cmd); 426 return ret; 427 } 428