⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wmi.c

📁 Linux下SDIO设备的驱动程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        break;    case (WMIX_GPIO_ACK_EVENTID):        wmi_gpio_ack_rx(wmip, datap, len);        break;#endif /* CONFIG_HOST_GPIO_SUPPORT */    default:        WMI_DEBUG_PRINTF("Host received unknown extended reply/event with id 0x%x\n",                         id);        wmip->wmi_stats.cmd_id_err++;        status = A_ERROR;        break;    }    return status;}/* * Control Path */A_STATUSwmi_control_rx(struct wmi_t *wmip, void *osbuf){    WMI_CMD_HDR *cmd;    A_UINT16 id;    A_UINT8 *datap;    A_UINT32 len;    A_STATUS status = A_OK;    A_ASSERT(osbuf != NULL);    if (a_netbuf_to_len(osbuf) < sizeof(WMI_CMD_HDR)) {        WMI_DEBUG_PRINTF("wmi event rx: bad packet\n");        wmip->wmi_stats.cmd_len_err++;        a_netbuf_free(osbuf);        return A_ERROR;    }    cmd = (WMI_CMD_HDR *)a_netbuf_to_data(osbuf);    id = cmd->commandId;    if (a_netbuf_pull(osbuf, sizeof(WMI_CMD_HDR)) != A_OK) {        WMI_DEBUG_PRINTF("wmi event rx: bad packet\n");        wmip->wmi_stats.cmd_len_err++;        a_netbuf_free(osbuf);        return A_ERROR;    }    datap = a_netbuf_to_data(osbuf);    len = a_netbuf_to_len(osbuf);    switch (id) {    case (WMI_CREATE_PSTREAM_CMDID):        status = wmi_create_pstream_reply_rx(wmip, datap, len);        break;    case (WMI_DELETE_PSTREAM_CMDID):        status = wmi_delete_pstream_reply_rx(wmip, datap, len);        break;    case (WMI_GET_BITRATE_CMDID):        status = wmi_bitrate_reply_rx(wmip, datap, len);        break;    case (WMI_GET_CHANNEL_LIST_CMDID):        status = wmi_channelList_reply_rx(wmip, datap, len);        break;    case (WMI_GET_TX_PWR_CMDID):        status = wmi_txPwr_reply_rx(wmip, datap, len);        break;    case (WMI_READY_EVENTID):        status = wmi_ready_event_rx(wmip, datap, len);        break;    case (WMI_CONNECT_EVENTID):        status = wmi_connect_event_rx(wmip, datap, len);        break;    case (WMI_DISCONNECT_EVENTID):        status = wmi_disconnect_event_rx(wmip, datap, len);        break;    case (WMI_TKIP_MICERR_EVENTID):        status = wmi_tkip_micerr_event_rx(wmip, datap, len);        break;    case (WMI_BSSINFO_EVENTID):        status = wmi_bssInfo_event_rx(wmip, datap, len);        break;    case (WMI_REGDOMAIN_EVENTID):        status = wmi_regDomain_event_rx(wmip, datap, len);        break;    case (WMI_PSTREAM_TIMEOUT_EVENTID):        status = wmi_pstream_timeout_event_rx(wmip, datap, len);        break;    case (WMI_NEIGHBOR_REPORT_EVENTID):        status = wmi_neighborReport_event_rx(wmip, datap, len);        break;    case (WMI_SCAN_COMPLETE_EVENTID):        status = wmi_scanComplete_rx(wmip, datap, len);        break;    case (WMI_CMDERROR_EVENTID):        status = wmi_errorEvent_rx(wmip, datap, len);        break;    case (WMI_REPORT_STATISTICS_EVENTID):        status = wmi_statsEvent_rx(wmip, datap, len);        break;    case (WMI_RSSI_THRESHOLD_EVENTID):        status = wmi_rssiThresholdEvent_rx(wmip, datap, len);        break;    case (WMI_ERROR_REPORT_EVENTID):        status = wmi_reportErrorEvent_rx(wmip, datap, len);        break;    case (WMI_OPT_RX_FRAME_EVENTID):        status = wmi_opt_frame_event_rx(wmip, datap, len);        break;    case (WMI_REPORT_ROAM_TBL_EVENTID):        status = wmi_roam_tbl_event_rx(wmip, datap, len);        break;    case (WMI_EXTENSION_EVENTID):        status = wmi_control_rx_xtnd(wmip, osbuf);        break;    case (WMI_CAC_EVENTID):        status = wmi_cac_event_rx(wmip, datap, len);        break;    case (WMI_REPORT_ROAM_DATA_EVENTID):        status = wmi_roam_data_event_rx(wmip, datap, len);        break;    default:        WMI_DEBUG_PRINTF("Host received unknown reply/event with id 0x%x\n",                         id);        wmip->wmi_stats.cmd_id_err++;        status = A_ERROR;        break;    }    a_netbuf_free(osbuf);    return status;}static A_STATUSwmi_create_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_CRE_PRIORITY_STREAM_REPLY *reply;    A_INT8 priNum = 0, i;    A_UINT8 dir;    if (len < sizeof(WMI_CRE_PRIORITY_STREAM_REPLY)) {        WMI_DEBUG_PRINTF ("wmi: create pstream reply too short (%d)!!\n", len);        return A_EINVAL;    }    reply = (WMI_CRE_PRIORITY_STREAM_REPLY *)datap;    WMI_DEBUG_PRINTF("wmi: create pstream reply: status = %d, tx mbox = %d rx mbox %d\n",            reply->status, reply->txQueueNumber, reply->rxQueueNumber);    dir = reply->trafficDirection;    if (dir == BIDIR_TRAFFIC) {        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][reply->trafficClass] = FALSE;        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][reply->trafficClass] = FALSE;    } else {        wmip->wmi_pstreamCmdInProgress[dir][reply->trafficClass] = FALSE;    }    wmip->wmi_cpstreamCmdInProgress = FALSE;    if (reply->status == A_FAILED_CREATE_REMOVE_PSTREAM_FIRST) {        /* do nothing */        return A_OK;    }    if (reply->status == A_SUCCEEDED) {        if (reply->trafficDirection == DNLINK_TRAFFIC ||            reply->trafficDirection == BIDIR_TRAFFIC) {            wmip->wmi_olderPriRxMbox = wmip->wmi_newerPriRxMbox;            wmip->wmi_newerPriRxMbox = reply->rxQueueNumber;            wmip->wmi_mboxMap[DNLINK_TRAFFIC][reply->rxQueueNumber].trafficClass = reply->trafficClass;            wmip->wmi_mboxMap[DNLINK_TRAFFIC][reply->rxQueueNumber].priorityNum = 0;            wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][reply->trafficClass] = reply->rxQueueNumber;        }        if (reply->trafficDirection == UPLINK_TRAFFIC ||            reply->trafficDirection == BIDIR_TRAFFIC) {            wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][reply->trafficClass] = reply->txQueueNumber;            /* In case  of 3rd pstreams being created, target automatically deletes the old pstream             * and accomodates the this one. Though, the host does not know of this implicit             * deletion,             */            if (wmip->wmi_numQoSStream < WMI_MAX_NUM_PRI_STREAMS)                wmip->wmi_numQoSStream++;            for (i = 0; i < WMI_MAX_NUM_PRI_STREAMS; i++) {                if (!wmip->wmi_priority[i].inUse) {                    priNum = i;                    wmip->wmi_priority[i].inUse = 1;                    wmip->wmi_priority[i].mbox = reply->txQueueNumber;                    break;                }            }            wmip->wmi_mboxMap[UPLINK_TRAFFIC][reply->txQueueNumber].trafficClass = reply->trafficClass;            wmip->wmi_mboxMap[UPLINK_TRAFFIC][reply->txQueueNumber].priorityNum = priNum;            ar6000_set_numdataendpts(wmip->wmi_devt, wmip->wmi_numQoSStream+1);        }    }    return reply->status;}static A_STATUSwmi_delete_pstream_reply_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_DEL_PRIORITY_STREAM_REPLY *reply;    A_UINT8 dir;    if (len < sizeof(WMI_DEL_PRIORITY_STREAM_REPLY)) {        return A_EINVAL;    }    reply = (WMI_DEL_PRIORITY_STREAM_REPLY *)datap;    WMI_DEBUG_PRINTF("wmi: delete pstream reply: status = %d, rx mbox = %d tx mbox = %d\n", reply->status,            reply->rxQueueNumber, reply->txQueueNumber);    dir = reply->trafficDirection;    if (dir == BIDIR_TRAFFIC) {        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][reply->trafficClass] = FALSE;        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][reply->trafficClass] = FALSE;    } else {        wmip->wmi_pstreamCmdInProgress[dir][reply->trafficClass] = FALSE;    }    if (reply->status == A_OK) {        /* update internal states for Rx Path */        if (reply->trafficDirection == DNLINK_TRAFFIC || reply->trafficDirection == BIDIR_TRAFFIC) {            A_UINT8 qNum = reply->rxQueueNumber;            A_UINT8 class = wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].trafficClass;            wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][class] = WMI_NOT_MAPPED;            wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].priorityNum = WMI_NOT_MAPPED;            wmip->wmi_mboxMap[DNLINK_TRAFFIC][qNum].trafficClass = WMM_AC_BE;            if (wmip->wmi_newerPriRxMbox == qNum) {                wmip->wmi_newerPriRxMbox = wmip->wmi_olderPriRxMbox;                wmip->wmi_olderPriRxMbox = qNum;            }        }    }    return reply->status;}static A_STATUSwmi_ready_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_READY_EVENT *ev = (WMI_READY_EVENT *)datap;    if (len < sizeof(WMI_READY_EVENT)) {        return A_EINVAL;    }    WMI_DEBUG_PRINTF("wmi: ready event\n");    wmip->wmi_ready = TRUE;    ar6000_ready_event(wmip->wmi_devt, ev->macaddr, ev->phyCapability);    return A_OK;}static A_STATUSwmi_connect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_CONNECT_EVENT *ev;    if (len < sizeof(WMI_CONNECT_EVENT)) {        return A_EINVAL;    }    ev = (WMI_CONNECT_EVENT *)datap;#ifdef DEBUG    WMI_DEBUG_PRINTF("wmi: connected event at freq %d ", ev->channel);    WMI_DEBUG_PRINTF("with bssid %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",                     ev->bssid[0], ev->bssid[1], ev->bssid[2],                     ev->bssid[3], ev->bssid[4], ev->bssid[5]);#endif /* DEBUG */    A_MEMCPY(wmip->wmi_bssid, ev->bssid, ATH_MAC_LEN);    ar6000_connect_event(wmip->wmi_devt, ev->channel, ev->bssid,                         ev->listenInterval, ev->beaconIeLen, ev->assocReqLen,                         ev->assocRespLen, ev->assocInfo);    return A_OK;}static A_STATUSwmi_regDomain_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_REG_DOMAIN_EVENT *ev;    if (len < sizeof(*ev)) {        return A_EINVAL;    }    ev = (WMI_REG_DOMAIN_EVENT *)datap;    ar6000_regDomain_event(wmip->wmi_devt, ev->regDomain);    return A_OK;}static A_STATUSwmi_neighborReport_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_NEIGHBOR_REPORT_EVENT *ev;    int numAps;    if (len < sizeof(*ev)) {        return A_EINVAL;    }    ev = (WMI_NEIGHBOR_REPORT_EVENT *)datap;    numAps = ev->numberOfAps;    if (len < (sizeof(*ev) + ((numAps - 1) * sizeof(WMI_NEIGHBOR_INFO)))) {        return A_EINVAL;    }    ar6000_neighborReport_event(wmip->wmi_devt, numAps, ev->neighbor);    return A_OK;}static A_STATUSwmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_DISCONNECT_EVENT *ev;    if (len < sizeof(WMI_DISCONNECT_EVENT)) {        return A_EINVAL;    }    WMI_DEBUG_PRINTF("wmi: disconnected event\n");    ev = (WMI_DISCONNECT_EVENT *)datap;    A_MEMZERO(wmip->wmi_bssid, sizeof(wmip->wmi_bssid));    ar6000_disconnect_event(wmip->wmi_devt, ev->disconnectReason, ev->bssid,                            ev->assocRespLen, ev->assocInfo);    return A_OK;}static A_STATUSwmi_tkip_micerr_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    WMI_TKIP_MICERR_EVENT *ev;    if (len < sizeof(*ev)) {        return A_EINVAL;    }    WMI_DEBUG_PRINTF("wmi: tkip micerr event\n");    ev = (WMI_TKIP_MICERR_EVENT *)datap;    ar6000_tkip_micerr_event(wmip->wmi_devt, ev->keyid, ev->ismcast);    return A_OK;}static A_STATUSwmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    bss_t *bss;    WMI_BSS_INFO_HDR *bih;    A_UINT8 *buf;    if (len <= sizeof(WMI_BSS_INFO_HDR)) {        return A_EINVAL;    }    bih = (WMI_BSS_INFO_HDR *)datap;    buf = datap + sizeof(WMI_BSS_INFO_HDR);    len -= sizeof(WMI_BSS_INFO_HDR);    WMI_DEBUG_PRINTF2("wmi: bssInfo event %2.2x:%2.2x\n",                      bih->bssid[4], bih->bssid[5]);    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);    if (bss != NULL) {        /*         * Free up the node.  Not the most efficient process given         * we are about to allocate a new node but it is simple and should be         * adequate.         */        wlan_node_reclaim(&wmip->wmi_scan_table, bss);    }    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);    if (bss == NULL) {        return A_NO_MEMORY;    }    bss->ni_rssi        = bih->rssi;    A_ASSERT(bss->ni_buf != NULL);    A_MEMCPY(bss->ni_buf, buf, len);    if (wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie) != A_OK) {        wlan_node_free(bss);        return A_EINVAL;    }    /*     * Update the frequency in ie_chan, overwriting of channel number     * which is done in wlan_parse_beacon     */    bss->ni_cie.ie_chan = bih->channel;    wlan_setup_node(&wmip->wmi_scan_table, bss, bih->bssid);    return A_OK;}static A_STATUSwmi_opt_frame_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len){    bss_t *bss;    WMI_OPT_RX_INFO_HDR *bih;    A_UINT8 *buf;    if (len <= sizeof(WMI_OPT_RX_INFO_HDR)) {        return A_EINVAL;    }    bih = (WMI_OPT_RX_INFO_HDR *)datap;    buf = datap + sizeof(WMI_OPT_RX_INFO_HDR);    len -= sizeof(WMI_OPT_RX_INFO_HDR);    WMI_DEBUG_PRINTF2("wmi: opt frame event %2.2x:%2.2x\n",                      bih->bssid[4], bih->bssid[5]);    bss = wlan_find_node(&wmip->wmi_scan_table, bih->bssid);    if (bss != NULL) {        /*         * Free up the node.  Not the most efficient process given         * we are about to allocate a new node but it is simple and should be         * adequate.         */        wlan_node_reclaim(&wmip->wmi_scan_table, bss);    }    bss = wlan_node_alloc(&wmip->wmi_scan_table, len);    if (bss == NULL) {        return A_NO_MEMORY;    }    bss->ni_rssi        = bih->rssi;    bss->ni_cie.ie_chan = bih->channel;    A_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_STATUSwmi_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("wmi: pstream timeout event\n");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -