📄 wmi.c
字号:
bss->ni_cie.ie_chan = bih->channel;
AR_DEBUG_ASSERT(bss->ni_buf != NULL);
A_MEMCPY(bss->ni_buf, buf, len);
wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);
return A_OK;
}
static A_STATUS
wmi_pstream_timeout_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_PSTREAM_TIMEOUT_EVENT *ev;
if (len < sizeof(WMI_PSTREAM_TIMEOUT_EVENT)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: pstream timeout event\n");
ev = (WMI_PSTREAM_TIMEOUT_EVENT *)datap;
wmi_delete_pstream_cmd(wmip, ev->txQueueNumber, ev->rxQueueNumber, ev->trafficDirection);
return A_OK;
}
static A_STATUS
wmi_bitrate_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_BIT_RATE_CMD *reply;
A_INT32 rate;
if (len < sizeof(WMI_BIT_RATE_CMD)) {
return A_EINVAL;
}
reply = (WMI_BIT_RATE_CMD *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: get bit rate reply %d\n", reply->rateIndex);
if (reply->rateIndex == RATE_AUTO) {
rate = RATE_AUTO;
} else {
rate = wmi_rateTable[reply->rateIndex];
}
ar6000_bitrate_rx(wmip->wmi_devt, rate);
return A_OK;
}
static A_STATUS
wmi_channelList_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_CHANNEL_LIST_REPLY *reply;
if (len < sizeof(WMI_CHANNEL_LIST_REPLY)) {
return A_EINVAL;
}
reply = (WMI_CHANNEL_LIST_REPLY *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: get channel list reply\n");
ar6000_channelList_rx(wmip->wmi_devt, reply->numChannels,
reply->channelList);
return A_OK;
}
static A_STATUS
wmi_txPwr_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_TX_PWR_REPLY *reply;
if (len < sizeof(*reply)) {
return A_EINVAL;
}
reply = (WMI_TX_PWR_REPLY *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: get tx pwr reply\n");
ar6000_txPwr_rx(wmip->wmi_devt, reply->dbM);
return A_OK;
}
static A_STATUS
wmi_dset_open_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMIX_DSETOPENREQ_EVENT *dsetopenreq;
if (len < sizeof(WMIX_DSETOPENREQ_EVENT)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi_dset_open_req_rx: DataSet Open Request event\n");
dsetopenreq = (WMIX_DSETOPENREQ_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi_dset_open_req_rx: dset_id=0x%x\n", dsetopenreq->dset_id);
ar6000_dset_open_req(wmip->wmi_devt,
dsetopenreq->dset_id,
dsetopenreq->targ_dset_handle,
dsetopenreq->targ_reply_fn,
dsetopenreq->targ_reply_arg);
return A_OK;
}
#if CONFIG_HOST_DSET_SUPPORT
static A_STATUS
wmi_dset_close_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMIX_DSETCLOSE_EVENT *dsetclose;
if (len < sizeof(WMIX_DSETCLOSE_EVENT)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: DataSet Close event\n");
dsetclose = (WMIX_DSETCLOSE_EVENT *)datap;
ar6000_dset_close(wmip->wmi_devt, dsetclose->access_cookie);
return A_OK;
}
static A_STATUS
wmi_dset_data_req_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMIX_DSETDATAREQ_EVENT *dsetdatareq;
if (len < sizeof(WMIX_DSETDATAREQ_EVENT)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi: DataSet Data Request event\n");
dsetdatareq = (WMIX_DSETDATAREQ_EVENT *)datap;
ar6000_dset_data_req(wmip->wmi_devt,
dsetdatareq->access_cookie,
dsetdatareq->offset,
dsetdatareq->length,
dsetdatareq->targ_buf,
dsetdatareq->targ_reply_fn,
dsetdatareq->targ_reply_arg);
return A_OK;
}
#endif /* CONFIG_HOST_DSET_SUPPORT */
static A_STATUS
wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
ar6000_scanComplete_event(wmip->wmi_devt);
return A_OK;
}
/*
* Target is reporting a programming error. This is for
* developer aid only. Target only checks a few common violations
* and it is responsibility of host to do all error checking.
* Behavior of target after wmi error event is undefined.
* A reset is recommended.
*/
static A_STATUS
wmi_errorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_CMD_ERROR_EVENT *ev;
ev = (WMI_CMD_ERROR_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF, "Programming Error: cmd=%d ", ev->commandId);
switch (ev->errorCode) {
case (INVALID_PARAM):
WMI_DEBUG_PRINTF(ATH_LOG_INF,"Illegal Parameter\n");
break;
case (ILLEGAL_STATE):
WMI_DEBUG_PRINTF(ATH_LOG_INF,"Illegal State\n");
break;
case (INTERNAL_ERROR):
WMI_DEBUG_PRINTF(ATH_LOG_INF,"Internal Error\n");
break;
}
return A_OK;
}
static A_STATUS
wmi_statsEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_TARGET_STATS *reply;
if (len < sizeof(*reply)) {
return A_EINVAL;
}
reply = (WMI_TARGET_STATS *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: target stats event\n");
ar6000_targetStats_event(wmip->wmi_devt, reply);
return A_OK;
}
static A_STATUS
wmi_rssiThresholdEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_RSSI_THRESHOLD_EVENT *reply;
if (len < sizeof(*reply)) {
return A_EINVAL;
}
reply = (WMI_RSSI_THRESHOLD_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: rssi threshold event\n");
ar6000_rssiThreshold_event(wmip->wmi_devt, reply->range);
return A_OK;
}
static A_STATUS
wmi_reportErrorEvent_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_TARGET_ERROR_REPORT_EVENT *reply;
if (len < sizeof(*reply)) {
return A_EINVAL;
}
reply = (WMI_TARGET_ERROR_REPORT_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: report error event\n");
ar6000_reportError_event(wmip->wmi_devt, reply->errorVal);
return A_OK;
}
#ifndef AR6K_FIRMWARE_1_0
static A_STATUS
wmi_roam_tbl_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
if (len < sizeof(WMI_TARGET_ROAM_TBL)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: report roam table event\n");
ar6000_roam_tbl_event(wmip->wmi_devt, (WMI_TARGET_ROAM_TBL *)datap);
return A_OK;
}
static A_STATUS
wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_CAC_EVENT *reply;
if (len < sizeof(WMI_CAC_EVENT)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: report cac event \n");
reply = (WMI_CAC_EVENT *)datap;
ar6000_cac_event(wmip->wmi_devt, reply->ac,
reply->cac_indication, reply->statusCode,
reply->tspecSuggestion);
return A_OK;
}
static A_STATUS
wmi_road_data_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
if (len < sizeof(WMI_TARGET_ROAM_DATA)) {
return A_EINVAL;
}
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi: report roam data event \n");
ar6000_roam_data_event(wmip->wmi_devt, (WMI_TARGET_ROAM_DATA *)datap);
return A_OK;
}
#endif
#if CONFIG_HOST_GPIO_SUPPORT
static A_STATUS
wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMIX_GPIO_INTR_EVENT *gpio_intr = (WMIX_GPIO_INTR_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,
"wmi GPIO interrupt received intrmask=0x%x input=0x%x.\n",
gpio_intr->intr_mask, gpio_intr->input_values);
ar6000_gpio_intr_rx(gpio_intr->intr_mask, gpio_intr->input_values);
return A_OK;
}
static A_STATUS
wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMIX_GPIO_DATA_EVENT *gpio_data = (WMIX_GPIO_DATA_EVENT *)datap;
WMI_DEBUG_PRINTF(ATH_LOG_INF,
"wmi GPIO data received reg=%d value=0x%x.\n",
gpio_data->reg_id, gpio_data->value);
ar6000_gpio_data_rx(gpio_data->reg_id, gpio_data->value);
return A_OK;
}
static A_STATUS
wmi_gpio_ack_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
{
WMI_DEBUG_PRINTF(ATH_LOG_INF, "wmi GPIO ACK received.\n");
ar6000_gpio_ack_rx();
return A_OK;
}
#endif /* CONFIG_HOST_GPIO_SUPPORT */
/*
* Called to send a wmi command. Command specific data is already built
* on osbuf and current osbuf->data points to it.
*/
A_STATUS
wmi_cmd_send(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
WMI_SYNC_FLAG syncflag)
{
#define IS_LONG_CMD(cmdId) (cmdId == WMI_OPT_TX_FRAME_CMDID)
WMI_CMD_HDR *cHdr;
A_UINT8 mbox = WMI_CONTROL_MBOX;
AR_DEBUG_ASSERT(osbuf != NULL);
if (syncflag >= END_WMIFLAG) {
return A_EINVAL;
}
if ((syncflag == SYNC_BEFORE_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
/*
* We want to make sure all data currently queued is transmitted before
* the cmd execution. Establish a new sync point.
*/
wmi_sync_point(wmip);
}
if (a_netbuf_push(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {
return A_NO_MEMORY;
}
cHdr = (WMI_CMD_HDR *)a_netbuf_to_data(osbuf);
cHdr->commandId = cmdId;
/*
* Send cmd, some via control pipe, others via data pipe
*/
if (IS_LONG_CMD(cmdId)) {
wmi_data_hdr_add(wmip, osbuf, CNTL_MSGTYPE);
mbox = WMI_BEST_EFFORT_MBOX;
}
ar6000_control_tx(wmip->wmi_devt, osbuf, mbox);
if ((syncflag == SYNC_AFTER_WMIFLAG) || (syncflag == SYNC_BOTH_WMIFLAG)) {
/*
* We want to make sure all new data queued waits for the command to
* execute. Establish a new sync point.
*/
wmi_sync_point(wmip);
}
return (A_OK);
#undef IS_LONG_CMD
}
A_STATUS
wmi_cmd_send_xtnd(struct wmi_t *wmip, void *osbuf, WMI_COMMAND_ID cmdId,
WMI_SYNC_FLAG syncflag)
{
WMIX_CMD_HDR *cHdr;
if (a_netbuf_push(osbuf, sizeof(WMIX_CMD_HDR)) != A_OK) {
return A_NO_MEMORY;
}
cHdr = (WMIX_CMD_HDR *)a_netbuf_to_data(osbuf);
cHdr->commandId = cmdId;
return wmi_cmd_send(wmip, osbuf, WMI_EXTENSION_CMDID, syncflag);
}
A_STATUS
wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
DOT11_AUTH_MODE dot11AuthMode,
AUTH_MODE authMode,
CRYPTO_TYPE pairwiseCrypto, A_UINT8 pairCryptoLen,
CRYPTO_TYPE groupCrypto, A_UINT8 groupCryptoLen,
int ssidLength, A_UCHAR *ssid,
A_UINT8 *bssid, A_UINT16 channel)
{
void *osbuf;
WMI_CONNECT_CMD *cc;
if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
return A_EINVAL;
}
if ((pairwiseCrypto != NONE_CRYPT) && (groupCrypto == NONE_CRYPT)) {
return A_EINVAL;
}
osbuf = a_netbuf_alloc(sizeof(WMI_CONNECT_CMD));
if (osbuf == NULL) {
return A_NO_MEMORY;
}
a_netbuf_put(osbuf, sizeof(WMI_CONNECT_CMD));
cc = (WMI_CONNECT_CMD *)(a_netbuf_to_data(osbuf));
A_MEMZERO(cc, sizeof(*cc));
if (ssidLength <= 0) {
ssidLength = 0;
} else {
if (ssidLength > sizeof(cc->ssid)) {
ssidLength = sizeof(cc->ssid);
}
A_MEMCPY(cc->ssid, ssid, ssidLength);
}
cc->ssidLength = ssidLength;
cc->networkType = netType;
cc->dot11AuthMode = dot11AuthMode;
cc->authMode = authMode;
cc->pairwiseCryptoType = pairwiseCrypto;
cc->groupCryptoType = groupCrypto;
#ifndef AR6K_FIRMWARE_1_0
cc->pairwiseCryptoLen = pairCryptoLen;
cc->groupCryptoLen = groupCryptoLen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -