Lines Matching +full:secure +full:- +full:firmware

1 // SPDX-License-Identifier: GPL-2.0-only
3 * Handling of the chip-to-host events (aka indications) of the hardware API.
5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
6 * Copyright (c) 2010, ST-Ericsson
24 int cmd = hif->id; in wfx_hif_generic_confirm()
25 int len = le16_to_cpu(hif->len) - 4; /* drop header */ in wfx_hif_generic_confirm()
27 WARN(!mutex_is_locked(&wdev->hif_cmd.lock), "data locking error"); in wfx_hif_generic_confirm()
29 if (!wdev->hif_cmd.buf_send) { in wfx_hif_generic_confirm()
30 dev_warn(wdev->dev, "unexpected confirmation: 0x%.2x\n", cmd); in wfx_hif_generic_confirm()
31 return -EINVAL; in wfx_hif_generic_confirm()
34 if (cmd != wdev->hif_cmd.buf_send->id) { in wfx_hif_generic_confirm()
35 dev_warn(wdev->dev, "chip response mismatch request: 0x%.2x vs 0x%.2x\n", in wfx_hif_generic_confirm()
36 cmd, wdev->hif_cmd.buf_send->id); in wfx_hif_generic_confirm()
37 return -EINVAL; in wfx_hif_generic_confirm()
40 if (wdev->hif_cmd.buf_recv) { in wfx_hif_generic_confirm()
41 if (wdev->hif_cmd.len_recv >= len && len > 0) in wfx_hif_generic_confirm()
42 memcpy(wdev->hif_cmd.buf_recv, buf, len); in wfx_hif_generic_confirm()
44 status = -EIO; in wfx_hif_generic_confirm()
46 wdev->hif_cmd.ret = status; in wfx_hif_generic_confirm()
48 complete(&wdev->hif_cmd.done); in wfx_hif_generic_confirm()
67 WARN(body->num_tx_confs <= 0, "corrupted message"); in wfx_hif_multi_tx_confirm()
68 for (i = 0; i < body->num_tx_confs; i++) in wfx_hif_multi_tx_confirm()
69 wfx_tx_confirm_cb(wdev, &body->tx_conf_payload[i]); in wfx_hif_multi_tx_confirm()
78 if (body->status || body->firmware_type > 4) { in wfx_hif_startup_indication()
79 dev_err(wdev->dev, "received invalid startup indication"); in wfx_hif_startup_indication()
80 return -EINVAL; in wfx_hif_startup_indication()
82 memcpy(&wdev->hw_caps, body, sizeof(struct wfx_hif_ind_startup)); in wfx_hif_startup_indication()
83 complete(&wdev->firmware_ready); in wfx_hif_startup_indication()
90 if (!wdev->pdata.gpio_wakeup || gpiod_get_value(wdev->pdata.gpio_wakeup) == 0) { in wfx_hif_wakeup_indication()
91 dev_warn(wdev->dev, "unexpected wake-up indication\n"); in wfx_hif_wakeup_indication()
92 return -EIO; in wfx_hif_wakeup_indication()
100 struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_receive_indication()
104 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_receive_indication()
105 return -EIO; in wfx_hif_receive_indication()
116 struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_event_indication()
118 int type = le32_to_cpu(body->event_id); in wfx_hif_event_indication()
121 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_event_indication()
122 return -EIO; in wfx_hif_event_indication()
127 wfx_event_report_rssi(wvif, body->event_data.rcpi_rssi); in wfx_hif_event_indication()
130 schedule_delayed_work(&wvif->beacon_loss_work, 0); in wfx_hif_event_indication()
133 cancel_delayed_work(&wvif->beacon_loss_work); in wfx_hif_event_indication()
134 dev_dbg(wdev->dev, "ignore BSSREGAINED indication\n"); in wfx_hif_event_indication()
137 dev_warn(wdev->dev, "error while processing power save request: %d\n", in wfx_hif_event_indication()
138 le32_to_cpu(body->event_data.ps_mode_error)); in wfx_hif_event_indication()
141 dev_warn(wdev->dev, "unhandled event indication: %.2x\n", type); in wfx_hif_event_indication()
150 struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_pm_mode_complete_indication()
153 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_pm_mode_complete_indication()
154 return -EIO; in wfx_hif_pm_mode_complete_indication()
156 complete(&wvif->set_pm_mode_complete); in wfx_hif_pm_mode_complete_indication()
164 struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_scan_complete_indication()
168 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_scan_complete_indication()
169 return -EIO; in wfx_hif_scan_complete_indication()
172 wfx_scan_complete(wvif, body->num_channels_completed); in wfx_hif_scan_complete_indication()
180 struct wfx_vif *wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_join_complete_indication()
183 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_join_complete_indication()
184 return -EIO; in wfx_hif_join_complete_indication()
186 dev_warn(wdev->dev, "unattended JoinCompleteInd\n"); in wfx_hif_join_complete_indication()
197 if (body->bc_mc_only) { in wfx_hif_suspend_resume_indication()
198 wvif = wdev_to_wvif(wdev, hif->interface); in wfx_hif_suspend_resume_indication()
200 dev_warn(wdev->dev, "%s: received event for non-existent vif\n", __func__); in wfx_hif_suspend_resume_indication()
201 return -EIO; in wfx_hif_suspend_resume_indication()
203 if (body->resume) in wfx_hif_suspend_resume_indication()
208 WARN(body->peer_sta_set, "misunderstood indication"); in wfx_hif_suspend_resume_indication()
209 WARN(hif->interface != 2, "misunderstood indication"); in wfx_hif_suspend_resume_indication()
210 if (body->resume) in wfx_hif_suspend_resume_indication()
223 int type = le32_to_cpu(body->type); in wfx_hif_generic_indication()
229 dev_info(wdev->dev, "firmware says: %s\n", (char *)&body->data); in wfx_hif_generic_indication()
232 mutex_lock(&wdev->rx_stats_lock); in wfx_hif_generic_indication()
233 /* Older firmware send a generic indication beside RxStats */ in wfx_hif_generic_indication()
235 dev_info(wdev->dev, "Rx test ongoing. Temperature: %d degrees C\n", in wfx_hif_generic_indication()
236 body->data.rx_stats.current_temp); in wfx_hif_generic_indication()
237 memcpy(&wdev->rx_stats, &body->data.rx_stats, sizeof(wdev->rx_stats)); in wfx_hif_generic_indication()
238 mutex_unlock(&wdev->rx_stats_lock); in wfx_hif_generic_indication()
241 mutex_lock(&wdev->tx_power_loop_info_lock); in wfx_hif_generic_indication()
242 memcpy(&wdev->tx_power_loop_info, &body->data.tx_power_loop_info, in wfx_hif_generic_indication()
243 sizeof(wdev->tx_power_loop_info)); in wfx_hif_generic_indication()
244 mutex_unlock(&wdev->tx_power_loop_info_lock); in wfx_hif_generic_indication()
247 dev_err(wdev->dev, "generic_indication: unknown indication type: %#.8x\n", type); in wfx_hif_generic_indication()
248 return -EIO; in wfx_hif_generic_indication()
266 "out-of-range power supply voltage", true },
268 "out-of-range temperature", true },
270 "secure link does not expect request during key exchange" },
272 "secure link session key is invalid" },
274 "secure link overflow" },
276 "secure link messages list does not match message encryption" },
278 "secure link not yet configured" },
283 /* Following errors only exists in old firmware versions: */
289 "secure link does not support multi-tx confirmations" },
291 "secure link session key is outdated" },
293 "secure link params (nonce or tag) mismatch" },
300 int type = le32_to_cpu(body->type); in wfx_hif_error_indication()
301 int param = (s8)body->data[0]; in wfx_hif_error_indication()
309 dev_err(wdev->dev, "asynchronous error: %s: %d\n", in wfx_hif_error_indication()
312 dev_err(wdev->dev, "asynchronous error: %s\n", hif_errors[i].str); in wfx_hif_error_indication()
314 dev_err(wdev->dev, "asynchronous error: unknown: %08x\n", type); in wfx_hif_error_indication()
316 16, 1, hif, le16_to_cpu(hif->len), false); in wfx_hif_error_indication()
317 wdev->chip_frozen = true; in wfx_hif_error_indication()
326 int type = le32_to_cpu(body->type); in wfx_hif_exception_indication()
329 dev_err(wdev->dev, "firmware assert %d\n", le32_to_cpup((__le32 *)body->data)); in wfx_hif_exception_indication()
331 dev_err(wdev->dev, "firmware exception\n"); in wfx_hif_exception_indication()
333 16, 1, hif, le16_to_cpu(hif->len), false); in wfx_hif_exception_indication()
334 wdev->chip_frozen = true; in wfx_hif_exception_indication()
336 return -1; in wfx_hif_exception_indication()
364 const struct wfx_hif_msg *hif = (const struct wfx_hif_msg *)skb->data; in wfx_handle_rx()
365 int hif_id = hif->id; in wfx_handle_rx()
369 wfx_hif_receive_indication(wdev, hif, hif->body, skb); in wfx_handle_rx()
373 if (mutex_is_locked(&wdev->hif_cmd.lock) && in wfx_handle_rx()
374 wdev->hif_cmd.buf_send && wdev->hif_cmd.buf_send->id == hif_id) { in wfx_handle_rx()
375 wfx_hif_generic_confirm(wdev, hif, hif->body); in wfx_handle_rx()
381 hif_handlers[i].handler(wdev, hif, hif->body); in wfx_handle_rx()
386 dev_err(wdev->dev, "unsupported HIF indication: ID %02x\n", hif_id); in wfx_handle_rx()
388 dev_err(wdev->dev, "unexpected HIF confirmation: ID %02x\n", hif_id); in wfx_handle_rx()