int32 wl_set_ba(struct cfg_struct *cfg, uint8 *buf)
{
    struct aggre_cfg_param      *param;
    int32                    ret;

    HWIFI_ASSERT((NULL != cfg) && (NULL != buf));

    param = (struct aggre_cfg_param *)buf;

    HWIFI_DEBUG("\naggre_cfg_param->ba_action_type = %d\n"
                "\naggre_cfg_param->TID              = %d\n"
                "\naggre_cfg_param->max_num        = %d\n",
                param->ba_action_type, param->TID, param->max_num);

    HWIFI_DEBUG("Mac address:" MACFMT, MAC2STR(param->mac_addr));

    if(IS_STA(cfg))
    {
        if (!IS_CONNECTED(cfg))
        {
            HWIFI_WARNING("STATUS is not Connected, ba info is not supported");
            return -EFAIL;
        }
    }

    ret = hwifi_set_ba(cfg, param);
    if (SUCC != ret)
    {
        HWIFI_WARNING("Failed to set ba!");
        return ret;
    }

    return SUCC;
}
Beispiel #2
0
/*****************************************************************************
 函 数 名  : dmac_config_11i_remove_wep_key
 功能描述  : 删除 wep密钥key信息
 输入参数  : mac_vap_stru *pst_mac_vap, oal_uint8 uc_len, oal_uint8 *puc_param
 输出参数  : 无
 返 回 值  :
 调用函数  :
 被调函数  :

 修改历史      :
  1.日    期   : 2014年1月4日
    作    者   : g00260350
    修改内容   : 新生成函数

*****************************************************************************/
oal_uint32  dmac_config_wep_remove_key(mac_vap_stru *pst_mac_vap, oal_uint8 uc_len, oal_uint8 *puc_param)
{
    oal_uint8                  uc_key_id;
    mac_removekey_param_stru  *puc_wep_key_prarm;

    puc_wep_key_prarm = (mac_removekey_param_stru *)puc_param;
    uc_key_id = puc_wep_key_prarm->uc_key_index;

	/*初始化wep相关MIB信息*/
    mac_mib_set_wep(pst_mac_vap, uc_key_id);

    /*从硬件Lut表删除 wep key */
    if(IS_STA(pst_mac_vap))
    {
        dmac_wep_remove_key(pst_mac_vap,uc_key_id);
    }

    return OAL_SUCC;

}
int32  hwifi_set_ampdu(struct cfg_struct *cfg, struct aggre_cfg_param *param)
{
    struct set_start_ampdu_msg  *start_msg;
    struct set_end_ampdu_msg    *end_msg;
    struct sk_buff        *skb;
    uint16                 msg_size;
    int32                  ret;

    HWIFI_ASSERT((NULL != cfg) && (NULL != param));

    if(param->ampdu_action_type == A_MPDU_START)
    {
        msg_size = sizeof(struct set_start_ampdu_msg);
        if (msg_size > MAX_MSG_LEN)
        {
            HWIFI_WARNING("Invalid too long start ampdu msg size:%d",msg_size);
            return -EFAIL;
        }

        skb = hwifi_alloc_skb_for_cmd(msg_size);
        if (NULL == skb)
        {
            return -ENOMEM;
        }

        start_msg = (struct set_start_ampdu_msg *)skb_put(skb, sizeof(struct set_start_ampdu_msg));

        /* add msg header */
        hwifi_fill_msg_hdr(&start_msg->msg_header, HOST_CMD_CONFIG, msg_size);
        /*add ampdu wid */
        hwifi_fill_start_ampdu(&start_msg->set_ampdu, param);

        if (is_zero_mac_addr(param->mac_addr))
        {    /* use user data */
            memcpy(start_msg->set_ampdu.ampdu_wid.bssid, param->mac_addr, MAC_LEN);
        }
        else if (IS_AP(cfg))
        {
            /* AP mode */
            memcpy(start_msg->set_ampdu.ampdu_wid.bssid, cfg->ap_info.sta_mgmt.stations[CONNECTED_STA_PRE].mac, MAC_LEN);
        }
        else if (IS_STA(cfg))
        {
            /* STA mode copy mac address fill ba and ampdu struct*/
            memcpy(start_msg->set_ampdu.ampdu_wid.bssid, cfg->conn.bss.bssid, MAC_LEN);
        }
    }
    else
    {
        msg_size = sizeof(struct set_end_ampdu_msg);
        if (msg_size > MAX_MSG_LEN)
        {
            HWIFI_WARNING("Invalid too long end ampdu msg size:%d",msg_size);
            return -EFAIL;
        }

        skb = hwifi_alloc_skb_for_cmd(msg_size);
        if (NULL == skb)
        {
            return -ENOMEM;
        }

        end_msg = (struct set_end_ampdu_msg *)skb_put(skb, sizeof(struct set_end_ampdu_msg));

        /* add msg header */
        hwifi_fill_msg_hdr(&end_msg->msg_header, HOST_CMD_CONFIG, msg_size);
        /*add ampdu wid */
        hwifi_fill_end_ampdu(&end_msg->set_ampdu, param);

        if (is_zero_mac_addr(param->mac_addr))
        {    /* use user data */
            memcpy(end_msg->set_ampdu.bssid, param->mac_addr, MAC_LEN);
        }
        else if (IS_AP(cfg))
        {
            /* AP mode */
            memcpy(end_msg->set_ampdu.bssid, cfg->ap_info.sta_mgmt.stations[CONNECTED_STA_PRE].mac, MAC_LEN);
        }
        else if (IS_STA(cfg))
        {
            /* STA mode copy mac address fill ba and ampdu struct*/
            memcpy(end_msg->set_ampdu.bssid, cfg->conn.bss.bssid, MAC_LEN);
        }
    }

    ret = hwifi_send_cmd(cfg, skb);
    PRINT_SEND_CMD_RET("set ampdu", ret);

    return ret;
}
int32  hwifi_set_ba(struct cfg_struct *cfg, struct aggre_cfg_param *param)
{
    struct set_addba_msg      *adb_msg;
    struct set_delba_msg      *del_msg;

    struct sk_buff            *skb;
    uint16                    msg_size;
    int32                     ret;

    HWIFI_ASSERT((NULL != cfg) && (NULL != param));

    if(param->ba_action_type == MLME_ADDBA_REQ_TYPE)
    {
        msg_size = sizeof(struct set_addba_msg);

        if (msg_size > MAX_MSG_LEN)
        {
            HWIFI_WARNING("Invalid too long set addba msg size:%d!",msg_size);
            return -EFAIL;
        }

        skb = hwifi_alloc_skb_for_cmd(msg_size);
        if (NULL == skb)
        {
            return -ENOMEM;
        }

        adb_msg = (struct set_addba_msg *)skb_put(skb, sizeof(struct set_addba_msg));

        /* add msg header */
        hwifi_fill_msg_hdr(&adb_msg->msg_header, HOST_CMD_CONFIG, msg_size);

        /* add ba wid */
        hwifi_fill_addba(&adb_msg->set_ba, param);

        if (is_zero_mac_addr(param->mac_addr))
        {    /* use user data */
            memcpy(adb_msg->set_ba.ba_wid.bssid, param->mac_addr, MAC_LEN);
        }
        else if (IS_AP(cfg))
        {
            /* AP mode */
            memcpy(adb_msg->set_ba.ba_wid.bssid,
                   cfg->ap_info.sta_mgmt.stations[CONNECTED_STA_PRE].mac,
                   MAC_LEN);
        }
        else if (IS_STA(cfg))
        {
            /* STA mode copy mac address fill ba and ampdu struct*/
            memcpy(adb_msg->set_ba.ba_wid.bssid, cfg->conn.bss.bssid, MAC_LEN);
        }
    }
    else
    {
        msg_size = sizeof(struct set_delba_msg);

        if (msg_size > MAX_MSG_LEN)
        {
            HWIFI_WARNING("Invalid too long delba msg size:%d",msg_size);
            return -EFAIL;
        }

        skb = hwifi_alloc_skb_for_cmd(msg_size);
        if (NULL == skb)
        {
            return -ENOMEM;
        }

        del_msg = (struct set_delba_msg *)skb_put(skb, sizeof(struct set_delba_msg));

        /* add msg header */
        hwifi_fill_msg_hdr(&del_msg->msg_header, HOST_CMD_CONFIG, msg_size);

        /* add ba wid */
        hwifi_fill_delba(&del_msg->set_ba, param);

        if (is_zero_mac_addr(param->mac_addr))
        {    /* use user data */
            memcpy(del_msg->set_ba.ba_wid.bssid, param->mac_addr, MAC_LEN);
        }
        else if (IS_AP(cfg))
        {
            /* AP mode */
            memcpy(del_msg->set_ba.ba_wid.bssid, cfg->ap_info.sta_mgmt.stations[CONNECTED_STA_PRE].mac, MAC_LEN);
        }
        else if (IS_STA(cfg))
        {
            /* STA mode copy mac address fill ba and ampdu struct*/
            memcpy(del_msg->set_ba.ba_wid.bssid, cfg->conn.bss.bssid, MAC_LEN);
        }
    }

    ret = hwifi_send_cmd(cfg, skb);
    PRINT_SEND_CMD_RET("set ba", ret);

    return ret;
}
/*
 * Prototype    : hwifi_data_rate_timeout
 * Description  : count data rate
 * Input        : None
 * Output       : None
 * Return Value : int32
 * Calls        :
 * Called By    :
 *
 *   History        :
 *   1.Date         : 2013/6/14
 *     Author       : xudayong
 *     Modification : Created function
 *
 */
STATIC void hwifi_data_rate_timeout(unsigned long data)
{
    struct cfg_struct *cfg;
    struct timer_list *_timer;
    struct host_ba_aggre_num_param ba_param;
    /*struct scanned_bss_info     *bss;
    uint8                       *probe_resp;
    uint32                       probe_resp_len;
    uint8                       *htc_ie;*/
    uint8                       ht_40M_flag;

    cfg = (struct cfg_struct *)data;

    if(IS_STA(cfg))
    {
        if ((cfg->aggre_info.rate <= g_data_rate_down) && (cfg->aggre_info.short_frame_pps) <= g_data_rate_pps_down)
        {
            HWIFI_DEBUG("Rate Slow Down,Try to Stop aggre");
             /* stop aggre by device */
            wl_aggre_mode_lock_set(cfg, TRUE);
        }
        else if ((cfg->aggre_info.rate > g_data_rate_up) || (cfg->aggre_info.short_frame_pps) >= g_data_rate_pps_up)
        {
            if(hcc_net_streams_connected(cfg->hi110x_dev->hcc))
            {
                HWIFI_DEBUG("Can not start agree yet, some special stream connected.");
            } else{
            	HWIFI_DEBUG("Rate Go Up,Try to Start aggre");
            	/* start aggre by device */
            	wl_aggre_mode_lock_set(cfg, FALSE);
            }
        }
    }
    else if(IS_AP(cfg))
    {
        if (cfg->aggre_info.rate <= g_ap_data_rate_down)
        {
            HWIFI_DEBUG("Rate Slow Down,Try to Stop aggre");

            /* stop aggre by device */
            wl_aggre_mode_lock_set(cfg, TRUE);
        }
        else if(cfg->aggre_info.rate > g_ap_data_rate_up)
        {
            if(hcc_net_streams_connected(cfg->hi110x_dev->hcc))
            {
                HWIFI_DEBUG("Can not start agree yet, some special stream connected.");
            } else{
                HWIFI_DEBUG("Rate Go Up,Try to Start aggre");
                /* start aggre by device */
                wl_aggre_mode_lock_set(cfg, FALSE);
            }
        }
    }

    HWIFI_DEBUG("g_use_dync_16vs8:%u",g_use_dync_16vs8);
    if((cfg->aggre_info.rate > g_data_rate_up) && (IS_STA(cfg)) && (g_use_dync_16vs8))
    {
        ht_40M_flag = cfg->rate.flags & RATE_INFO_FLAGS_40_MHZ_WIDTH;

        /* ˵\C3\F7֧\B3\D640M\D0ŵ\C0 */
        if (ht_40M_flag && cfg->sta_info.fc_enabled)
        {
            g_aggr_num_rate_up    = (M40M_AGGR_NUM_RATE_UP * 1000000 / 8)*10;
            g_aggr_num_rate_down  = (M40M_AGGR_NUM_RATE_DOWN * 1000000 / 8)*10;
        }
        else
        {
            g_aggr_num_rate_up    = (M20M_AGGR_NUM_RATE_UP * 1000000 / 8)*10;
            g_aggr_num_rate_down  = (M20M_AGGR_NUM_RATE_DOWN * 1000000 / 8)*10;
        }

        /* \B0\B410sͳ\BC\C6 */
        if(g_count_aggre < 10)
        {
            g_count_aggre++;
            g_rate_sum += cfg->aggre_info.rate;

            cfg->aggre_info.rate = 0;
            cfg->aggre_info.short_frame_pps = 0;
            _timer = &cfg->aggre_info.data_rate_timer;
            mod_timer(_timer, (jiffies + AGREE_DATE_TIMOUT*HZ));

            return;
        }

        // HWIFI_INFO("rate:%lu, max_aggre_num:%u",cfg->aggre_info.rate,cfg->aggre_info.host_ba_cfg.max_retry);
        HWIFI_DEBUG("rate:%lu, max_aggre_num:%u",g_rate_sum,cfg->aggre_info.host_ba_cfg.max_retry);
        HWIFI_DEBUG("g_aggr_num_rate_down:%lu, g_aggr_num_rate_up:%lu",g_aggr_num_rate_down,g_aggr_num_rate_up);
        if ((g_rate_sum < g_aggr_num_rate_down) && (MAX_AGGR_NUM_16 != cfg->aggre_info.host_ba_cfg.max_retry))
        {
            // set aggr num 16
            hwifi_prepare_aggr_parm(&ba_param, MAX_AGGR_NUM_16, g_method);
            // wl_aggre_cfg_set(cfg, &ba_param);
            hwifi_dyn_aggre_num_set(cfg, &ba_param);
            cfg->aggre_info.host_ba_cfg.max_retry = MAX_AGGR_NUM_16;

            HWIFI_DEBUG("send max aggre num:%d",MAX_AGGR_NUM_16);
        }
        else if ((g_rate_sum > g_aggr_num_rate_up) && (MAX_AGGR_NUM_8 != cfg->aggre_info.host_ba_cfg.max_retry))
        {
            // set aggr num 8
            hwifi_prepare_aggr_parm(&ba_param, MAX_AGGR_NUM_8, g_method);
            hwifi_dyn_aggre_num_set(cfg, &ba_param);
            cfg->aggre_info.host_ba_cfg.max_retry = MAX_AGGR_NUM_8;

            HWIFI_DEBUG("send max aggre num:%d",MAX_AGGR_NUM_8);
        }

        g_rate_sum    = 0;
        g_count_aggre = 0;

    }

    cfg->aggre_info.rate = 0;
    cfg->aggre_info.short_frame_pps = 0;
    _timer = &cfg->aggre_info.data_rate_timer;

    mod_timer(_timer, (jiffies + AGREE_DATE_TIMOUT*HZ));
}
/*
 * Prototype    : wl_query_ba_set
 * Description  : query ba session info
 * Input        : struct cfg_struct *cfg,struct query_ba_param *param
 * Output       : NONE
 * Return Value : int32
 * Calls        :
 * Called By    : hwifi_ioctl_cmd()
 *
 *   History        :
 *   1.Date         : 2013/03/19
 *     Author       : ywx164715
 *     Modification : Created function
 *
 */
int32 wl_query_ba_set(struct cfg_struct *cfg, struct query_ba_param *param)
{
    struct sk_buff          *skb;
    struct set_query_ba_msg *query_ba_msg;
    uint16                   msg_size;
    int32                    ret;

    HWIFI_DEBUG("Mac address:" MACFMT, MAC2STR(param->mac_addr));

    msg_size = sizeof(struct set_query_ba_msg);
    skb = hwifi_alloc_skb_for_cmd(msg_size);
    if (NULL == skb)
    {
        return -ENOMEM;
    }

    /* fill the msg header */
    query_ba_msg = (struct set_query_ba_msg*)skb_put(skb, sizeof(struct set_query_ba_msg));
    hwifi_fill_msg_hdr(&query_ba_msg->msg_header, HOST_CMD_CONFIG, msg_size);
    hwifi_fill_query_ba_wid(&query_ba_msg->set_query_ba, param);

    if (is_zero_mac_addr(param->mac_addr))
    {    /* use user data */
        memcpy(query_ba_msg->set_query_ba.bssid, param->mac_addr, MAC_LEN);
    }else if (IS_AP(cfg) && param->flag == 0){      /* AP mode */
        memcpy(query_ba_msg->set_query_ba.bssid, cfg->ap_info.sta_mgmt.stations[CONNECTED_STA_PRE].mac, MAC_LEN);
    }else if (IS_STA(cfg)){     /* STA mode copy mac address fill ba and ampdu struct*/
        memcpy(query_ba_msg->set_query_ba.bssid, cfg->conn.bss.bssid, MAC_LEN);
    }

    /* init for wait event */
    cfg->aggre_info.ba_param_res.ba_sess_res[ZERO_INDEX].id = 0xFE;

    ret = hwifi_send_cmd(cfg, skb);
    if (SUCC != ret)
    {
        HWIFI_WARNING("Failed to send aggreagtion mode set msg!");
        return -EFAIL;
    }



    ret = wait_event_interruptible_timeout(cfg->wait_queue, (0xFE != cfg->aggre_info.ba_param_res.ba_sess_res[ZERO_INDEX].id), 5 * HZ);

    if (0 == ret)
    {
        HWIFI_WARNING("Wait_event_queue time out!");
        return -EFAIL;
    }
    else if (ret < 0)
    {
        HWIFI_WARNING("Wait_event_queue internal error,ret=%d", ret);
        return -EFAIL;
    }
    else if (cfg->aggre_info.ba_param_res.ba_sess_res[ZERO_INDEX].id == 0xFF)
    {
        HWIFI_WARNING("Cann't find the mac address or no any connected!");
        return -EFAIL;
    }

    memcpy((uint8 *)param, (uint8 *)&cfg->aggre_info.ba_param_res, sizeof(*param));

    HWIFI_DEBUG("Succeed to query ba session!");

    return SUCC;
}