static u32 wfx_rate_mask_to_hw(struct wfx_dev *wdev, u32 rates)
{ int i;
u32 ret = 0; /* The device only supports 2GHz */ struct ieee80211_supported_band *sband = wdev->hw->wiphy->bands[NL80211_BAND_2GHZ];
for (i = 0; i < sband->n_bitrates; i++) { if (rates & BIT(i)) { if (i >= sband->n_bitrates)
dev_warn(wdev->dev, "unsupported basic rate\n"); else
ret |= BIT(sband->bitrates[i].hw_value);
}
} return ret;
}
int wfx_cmd_send(struct wfx_dev *wdev, struct wfx_hif_msg *request, void *reply, size_t reply_len, bool no_reply)
{ constchar *mib_name = ""; constchar *mib_sep = ""; int cmd = request->id; int vif = request->interface; int ret;
/* Do not wait for any reply if chip is frozen */ if (wdev->chip_frozen) return -ETIMEDOUT;
/* Note: call to complete() below has an implicit memory barrier that hopefully protect * buf_send
*/
wdev->hif_cmd.buf_send = request;
wdev->hif_cmd.buf_recv = reply;
wdev->hif_cmd.len_recv = reply_len;
complete(&wdev->hif_cmd.ready);
wfx_bh_request_tx(wdev);
if (no_reply) { /* Chip won't reply. Ensure the wq has send the buffer before to continue. */
flush_workqueue(wdev->bh_wq);
ret = 0; goto end;
}
if (wdev->poll_irq)
wfx_bh_poll_irq(wdev);
ret = wait_for_completion_timeout(&wdev->hif_cmd.done, 1 * HZ); if (!ret) {
dev_err(wdev->dev, "chip is abnormally long to answer\n");
reinit_completion(&wdev->hif_cmd.ready);
ret = wait_for_completion_timeout(&wdev->hif_cmd.done, 3 * HZ);
} if (!ret) {
dev_err(wdev->dev, "chip did not answer\n");
wfx_pending_dump_old_frames(wdev, 3000);
wdev->chip_frozen = true;
reinit_completion(&wdev->hif_cmd.done);
ret = -ETIMEDOUT;
} else {
ret = wdev->hif_cmd.ret;
}
if (ret &&
(cmd == HIF_REQ_ID_READ_MIB || cmd == HIF_REQ_ID_WRITE_MIB)) {
mib_name = wfx_get_mib_name(((u16 *)request)[2]);
mib_sep = "/";
} if (ret < 0)
dev_err(wdev->dev, "hardware request %s%s%s (%#.2x) on vif %d returned error %d\n",
wfx_get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret); if (ret > 0)
dev_warn(wdev->dev, "hardware request %s%s%s (%#.2x) on vif %d returned status %d\n",
wfx_get_hif_name(cmd), mib_sep, mib_name, cmd, vif, ret);
return ret;
}
/* This function is special. After HIF_REQ_ID_SHUT_DOWN, chip won't reply to any request anymore. * Obviously, only call this function during device unregister.
*/ int wfx_hif_shutdown(struct wfx_dev *wdev)
{ int ret; struct wfx_hif_msg *hif;
wfx_alloc_hif(0, &hif); if (!hif) return -ENOMEM;
wfx_fill_header(hif, -1, HIF_REQ_ID_SHUT_DOWN, 0);
ret = wfx_cmd_send(wdev, hif, NULL, 0, true); if (wdev->pdata.gpio_wakeup)
gpiod_set_value(wdev->pdata.gpio_wakeup, 0); else
wfx_control_reg_write(wdev, 0);
kfree(hif); return ret;
}
int wfx_hif_stop_scan(struct wfx_vif *wvif)
{ int ret; struct wfx_hif_msg *hif; /* body associated to HIF_REQ_ID_STOP_SCAN is empty */
wfx_alloc_hif(0, &hif);
if (!hif) return -ENOMEM;
wfx_fill_header(hif, wvif->id, HIF_REQ_ID_STOP_SCAN, 0);
ret = wfx_cmd_send(wvif->wdev, hif, NULL, 0, false);
kfree(hif); return ret;
}
int wfx_hif_set_bss_params(struct wfx_vif *wvif, int aid, int beacon_lost_count)
{ int ret; struct wfx_hif_msg *hif; struct wfx_hif_req_set_bss_params *body = wfx_alloc_hif(sizeof(*body), &hif);
int wfx_hif_add_key(struct wfx_dev *wdev, conststruct wfx_hif_req_add_key *arg)
{ int ret; struct wfx_hif_msg *hif; /* FIXME: only send necessary bits */ struct wfx_hif_req_add_key *body = wfx_alloc_hif(sizeof(*body), &hif);
if (!hif) return -ENOMEM; /* FIXME: swap bytes as necessary in body */
memcpy(body, arg, sizeof(*body)); if (wfx_api_older_than(wdev, 1, 5)) /* Legacy firmwares expect that add_key to be sent on right interface. */
wfx_fill_header(hif, arg->int_id, HIF_REQ_ID_ADD_KEY, sizeof(*body)); else
wfx_fill_header(hif, -1, HIF_REQ_ID_ADD_KEY, sizeof(*body));
ret = wfx_cmd_send(wdev, hif, NULL, 0, false);
kfree(hif); return ret;
}
int wfx_hif_remove_key(struct wfx_dev *wdev, int idx)
{ int ret; struct wfx_hif_msg *hif; struct wfx_hif_req_remove_key *body = wfx_alloc_hif(sizeof(*body), &hif);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.