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

📄 wmi.c

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 C
📖 第 1 页 / 共 5 页
字号:

A_STATUS
wmi_setPmkid_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT8 *pmkId,
                 A_BOOL set)
{
    void *osbuf;
    WMI_SET_PMKID_CMD *cmd;

    if (bssid == NULL) {
        return A_EINVAL;
    }

    if ((set == TRUE) && (pmkId == NULL)) {
        return A_EINVAL;
    }

    osbuf = a_netbuf_alloc(sizeof(*cmd));
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    a_netbuf_put(osbuf, sizeof(*cmd));

    cmd = (WMI_SET_PMKID_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMCPY(cmd->bssid, bssid, sizeof(cmd->bssid));
    if (set == TRUE) {
        A_MEMCPY(cmd->pmkid, pmkId, sizeof(cmd->pmkid));
        cmd->enable = PMKID_ENABLE;
    } else {
        A_MEMZERO(cmd->pmkid, sizeof(cmd->pmkid));
        cmd->enable = PMKID_DISABLE;
    }

    return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMKID_CMDID, NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_set_tkip_countermeasures_cmd(struct wmi_t *wmip, A_BOOL en)
{
    void *osbuf;
    WMI_SET_TKIP_COUNTERMEASURES_CMD *cmd;

    osbuf = a_netbuf_alloc(sizeof(*cmd));
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    a_netbuf_put(osbuf, sizeof(*cmd));

    cmd = (WMI_SET_TKIP_COUNTERMEASURES_CMD *)(a_netbuf_to_data(osbuf));
    cmd->cm_en = (en == TRUE)? WMI_TKIP_CM_ENABLE : WMI_TKIP_CM_DISABLE;

    return (wmi_cmd_send(wmip, osbuf, WMI_SET_TKIP_COUNTERMEASURES_CMDID, 
            NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_dataSync_send(struct wmi_t *wmip, void *osbuf, int endPoint)
{
    WMI_DATA_HDR     *dtHdr;

    AR_DEBUG_ASSERT(endPoint != WMI_CONTROL_MBOX);
    AR_DEBUG_ASSERT(osbuf != NULL);

    if (a_netbuf_push(osbuf, sizeof(WMI_DATA_HDR)) != A_OK) {
        return A_NO_MEMORY;
    }

    dtHdr = (WMI_DATA_HDR *)a_netbuf_to_data(osbuf);
#ifndef AR6K_FIRMWARE_1_0
    dtHdr->rssi = 0;
#else
    dtHdr->reserved1 = 0;
#endif
    WMI_DATA_HDR_SET_MSG_TYPE( dtHdr, SYNC_MSGTYPE);

    WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi sync pkt sent on mbox %d\n", endPoint);

    return (ar6000_control_tx(wmip->wmi_devt, osbuf, endPoint));
}

static A_STATUS
wmi_sync_point(struct wmi_t *wmip)
{
    void *cmd_osbuf, *be_osbuf, *pri_osbuf[WMI_MAX_NUM_PRI_STREAMS];
    A_UINT8 i;
    A_STATUS status;

    WMI_DEBUG_PRINTF(ATH_LOG_INF,"wmi_sync_point\n");
    /*
     * We allocate all network buffers needed so we will be able to
     * send all required frames.
     */
    cmd_osbuf = a_netbuf_alloc(0);      /* no payload */
    if (cmd_osbuf == NULL) {
        return A_NO_MEMORY;
    }
    be_osbuf = a_netbuf_alloc(0);      /* no payload */
    if (be_osbuf == NULL) {
        a_netbuf_free(cmd_osbuf);
        return A_NO_MEMORY;
    }

    for (i = 0; i < wmip->wmi_numQoSStream; i++) {
        pri_osbuf[i] = a_netbuf_alloc(0);      /* no payload */
        if (pri_osbuf[i] == NULL) {
            A_UINT8 j;        
            a_netbuf_free(be_osbuf);
            a_netbuf_free(cmd_osbuf);
            /* free previously allocated bufs */
            for (j = 0; j < i; j++) {
                a_netbuf_free(pri_osbuf[j]);
            }
            return A_NO_MEMORY;
        }
    }

    /*
     * Send sync cmd followed by sync data messages on all endpoints being
     * used
     */
    status = wmi_cmd_send(wmip, cmd_osbuf, WMI_SYNCHRONIZE_CMDID,
                          NO_SYNC_WMIFLAG);

    if (status == A_OK) {
        status = wmi_dataSync_send(wmip, be_osbuf, WMI_BEST_EFFORT_MBOX);
    }

    if (status == A_OK) {
        A_UINT8 priIndex = 0;
        for (i = 0; i < wmip->wmi_numQoSStream; i++) {
            while (priIndex < WMI_MAX_NUM_PRI_STREAMS &&
                  (!wmip->wmi_priority[priIndex].inUse)) {
                priIndex++;
            }
            if (priIndex >= WMI_MAX_NUM_PRI_STREAMS) {
                break;
            }
            status = wmi_dataSync_send(wmip, pri_osbuf[i], wmip->wmi_priority[priIndex].mbox);
            if (status != A_OK) {
                break;
            }
            priIndex++;
        }
    }

    return (status);
}

A_STATUS
wmi_create_pstream_cmd(struct wmi_t *wmip, WMI_CREATE_PSTREAM_CMD *params)
{
    void *osbuf;
    WMI_CREATE_PSTREAM_CMD *cmd;

#ifndef AR6K_FIRMWARE_1_0
    /* Validate all the parameters. */
    if( !((params->userPriority < 8) &&
         (params->trafficDirection == BIDIR_TRAFFIC ||
            params->trafficDirection == UPLINK_TRAFFIC ||
            params->trafficDirection == DNLINK_TRAFFIC ) &&
         (params->userPriority <= 0x7) &&
                  (params->trafficClass != WMM_AC_BE)  &&
         (params->trafficType == TRAFFIC_TYPE_APERIODIC ||
            params->trafficType == TRAFFIC_TYPE_PERIODIC ) &&
         (params->voicePSCapability == DISABLE_FOR_THIS_AC  ||
            params->voicePSCapability == ENABLE_FOR_THIS_AC ||
            params->voicePSCapability == ENABLE_FOR_ALL_AC) &&
         (params->tsid < 15)) )
    {
        return  A_EINVAL;
    }
#endif

    if (params->trafficDirection == BIDIR_TRAFFIC) {
        if (wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][params->trafficClass]
          || wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][params->trafficClass]
          || wmip->wmi_cpstreamCmdInProgress) {
            WMI_DEBUG_PRINTF(ATH_LOG_ERR,"create %d too busy !\n",params->trafficClass);
            return A_EBUSY;
        }
        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][params->trafficClass] = TRUE;
        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][params->trafficClass] = TRUE;
    } else {
        if (wmip->wmi_pstreamCmdInProgress[params->trafficDirection][params->trafficClass]
         || wmip->wmi_cpstreamCmdInProgress) {
            WMI_DEBUG_PRINTF(ATH_LOG_ERR,"create %d too busy !\n",params->trafficClass);
            return A_EBUSY;
        }
        wmip->wmi_pstreamCmdInProgress[params->trafficDirection][params->trafficClass] = TRUE;
    }

    osbuf = a_netbuf_alloc(sizeof(*cmd));
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    wmip->wmi_cpstreamCmdInProgress = TRUE;
    a_netbuf_put(osbuf, sizeof(*cmd));

    WMI_DEBUG_PRINTF(ATH_LOG_INF,"Sending create_pstream_cmd: ac=%d, rxQ=%d, dir=%d\n", 
                     params->trafficClass, params->rxQueueNum, params->trafficDirection);

    cmd = (WMI_CREATE_PSTREAM_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMZERO(cmd, sizeof(*cmd));
    A_MEMCPY(cmd, params, sizeof(*cmd));

    if (params->rxQueueNum == 0xFF) {
        if(wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][params->trafficClass] != WMI_NOT_MAPPED)
            cmd->rxQueueNum = wmip->wmi_trafficClassMap[DNLINK_TRAFFIC][params->trafficClass];
        else
            cmd->rxQueueNum = wmip->wmi_olderPriRxMbox;
    } else {
        cmd->rxQueueNum = params->rxQueueNum;
    }
    
    /* mike: should be SYNC_BEFORE_WMIFLAG */
    return (wmi_cmd_send(wmip, osbuf, WMI_CREATE_PSTREAM_CMDID,
                         NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_delete_pstream_cmd(struct wmi_t *wmip, A_UINT8 txQueueNumber, A_UINT8 rxQueueNumber, A_UINT8 dir)
{
    void *osbuf;
    WMI_DELETE_PSTREAM_CMD *cmd;
    A_STATUS status;
    A_UINT8 class;

    osbuf = a_netbuf_alloc(sizeof(*cmd));
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    if (dir == BIDIR_TRAFFIC) {
        class = wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass;
        if (wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][class]
         || wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][class]) {
            return A_EBUSY;
        }
        wmip->wmi_pstreamCmdInProgress[UPLINK_TRAFFIC][class] = TRUE;
        wmip->wmi_pstreamCmdInProgress[DNLINK_TRAFFIC][class] = TRUE;
    } else {
        if (dir == UPLINK_TRAFFIC) {
            class = wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass;
        } else {
            class = wmip->wmi_mboxMap[DNLINK_TRAFFIC][rxQueueNumber].trafficClass;
        }
        if (wmip->wmi_pstreamCmdInProgress[dir][class]) {
            return A_EBUSY;
        }
        wmip->wmi_pstreamCmdInProgress[dir][class] = TRUE;
    }

    a_netbuf_put(osbuf, sizeof(*cmd));

    cmd = (WMI_DELETE_PSTREAM_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMZERO(cmd, sizeof(*cmd));
    cmd->txQueueNumber = txQueueNumber;
    cmd->rxQueueNumber = rxQueueNumber;
    cmd->trafficDirection = dir;
    cmd->trafficClass = class;
    WMI_DEBUG_PRINTF(ATH_LOG_INF,"Sending delete_pstream_cmd: txQ=%d, rxQ=%d, dir=%d\n", 
                     txQueueNumber, rxQueueNumber, dir);
    status = (wmi_cmd_send(wmip, osbuf, WMI_DELETE_PSTREAM_CMDID,
                         (dir == UPLINK_TRAFFIC || dir == BIDIR_TRAFFIC) ? SYNC_BEFORE_WMIFLAG : NO_SYNC_WMIFLAG));

    if (class != WMM_AC_BE) {
        /* Update internal states */
        if (dir == UPLINK_TRAFFIC || dir == BIDIR_TRAFFIC) {
            wmip->wmi_numQoSStream--;
            ar6000_set_numdataendpts(wmip->wmi_devt, wmip->wmi_numQoSStream+1);
            wmip->wmi_priority[wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].priorityNum].inUse = 0;
            wmip->wmi_trafficClassMap[UPLINK_TRAFFIC][class] = WMI_NOT_MAPPED;
            wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].priorityNum = WMI_NOT_MAPPED;
            wmip->wmi_mboxMap[UPLINK_TRAFFIC][txQueueNumber].trafficClass = WMM_AC_BE;
        }
    }

    return status;
}


/*
 * used to set the bit rate.  rate is in Kbps.  If rate == -1
 * then auto selection is used.
 */
A_STATUS
wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 rate)
{
    void *osbuf;
    WMI_BIT_RATE_CMD *cmd;
    A_INT8 i;

    if (rate != -1) {
        for (i=0;;i++) {
            if (wmi_rateTable[i] == 0) {
                return A_EINVAL;
            }
            if (wmi_rateTable[i] == rate) {
                break;
            }
        }
    } else {
        i = -1;
    }

    osbuf = a_netbuf_alloc(sizeof(*cmd));
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    a_netbuf_put(osbuf, sizeof(*cmd));

    cmd = (WMI_BIT_RATE_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMZERO(cmd, sizeof(*cmd));

    cmd->rateIndex = i;

    return (wmi_cmd_send(wmip, osbuf, WMI_SET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_get_bitrate_cmd(struct wmi_t *wmip)
{
    void *osbuf;

    osbuf = a_netbuf_alloc(0);      /* no payload */
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    return (wmi_cmd_send(wmip, osbuf, WMI_GET_BITRATE_CMDID, NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_get_channelList_cmd(struct wmi_t *wmip)
{
    void *osbuf;

    osbuf = a_netbuf_alloc(0);      /* no payload */
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    return (wmi_cmd_send(wmip, osbuf, WMI_GET_CHANNEL_LIST_CMDID,
                         NO_SYNC_WMIFLAG));
}

/*
 * used to generate a wmi sey channel Parameters cmd.
 * mode should always be specified and corresponds to the phy mode of the
 * wlan.
 * numChan should alway sbe specified. If zero indicates that all available
 * channels should be used.
 * channelList is an array of channel frequencies (in Mhz) which the radio
 * should limit its operation to.  It should be NULL if numChan == 0.  Size of
 * array should correspond to numChan entries.
 */
A_STATUS
wmi_set_channelParams_cmd(struct wmi_t *wmip, WMI_PHY_MODE mode, A_INT8 numChan,
                          A_UINT16 *channelList)
{
    void *osbuf;
    WMI_CHANNEL_PARAMS_CMD *cmd;
    A_INT8 size;

    if ((mode <= WMI_MIN_PHY_MODE) || (mode >= WMI_MAX_PHY_MODE)) {
       return A_EINVAL;
    }

    size = sizeof (*cmd);

    if (numChan) {
        if (numChan > WMI_MAX_CHANNELS) {
            return A_EINVAL;
        }
        size += sizeof(A_UINT16) * (numChan - 1);
    }

    osbuf = a_netbuf_alloc(size);
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    a_netbuf_put(osbuf, size);

    cmd = (WMI_CHANNEL_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMZERO(cmd, size);

    cmd->phyMode     = mode;
    cmd->numChannels = numChan;
    A_MEMCPY(cmd->channelList, channelList, numChan * sizeof(A_UINT16));

    return (wmi_cmd_send(wmip, osbuf, WMI_SET_CHANNEL_PARAMS_CMDID,
                         NO_SYNC_WMIFLAG));
}

A_STATUS
wmi_set_link_threshold_params(struct wmi_t *wmip, 
                                A_UINT8     highThreshold_upperVal,
                                A_UINT8     highThreshold_lowerVal,
                                A_UINT8     lowThreshold_upperVal,
                                A_UINT8     lowThreshold_lowerVal,
                                A_UINT32    pollTime)
{
    void    *osbuf;
    A_INT8  size;
    WMI_RSSI_THRESHOLD_PARAMS_CMD *cmd;

    /* These values are in ascending order */
    if( highThreshold_upperVal <= highThreshold_lowerVal ||
        lowThreshold_upperVal  <= lowThreshold_lowerVal  ||
        highThreshold_lowerVal <= lowThreshold_upperVal)
        return A_EINVAL;

    size = sizeof (*cmd);

    osbuf = a_netbuf_alloc(size);
    if (osbuf == NULL) {
        return A_NO_MEMORY;
    }

    a_netbuf_put(osbuf, size);

    cmd = (WMI_RSSI_THRESHOLD_PARAMS_CMD *)(a_netbuf_to_data(osbuf));
    A_MEMZERO(cmd, size);

    cmd->highThreshold_upperVal = highThreshold_upperVal;
    cmd->highThreshold_lowerVal = highThreshold_lowerVal;
    cmd->lowThreshold_upperVal  = lowThreshold_upperVal;
    cmd->lowThreshold_lowerVal  = lowThreshold_lowerV

⌨️ 快捷键说明

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