oal_void  hmac_data_acq_down_vap(mac_vap_stru *pst_mac_vap)
{
    oal_uint32                   ul_ret;
    mac_device_stru             *pst_device;
    oal_uint8                    uc_vap_idx;
    mac_cfg_down_vap_param_stru  st_down_vap;
    hmac_vap_stru               *pst_hmac_vap;

    pst_device = mac_res_get_dev(pst_mac_vap->uc_device_id);

    if (OAL_PTR_NULL == pst_device)
    {
        OAM_WARNING_LOG0(pst_mac_vap->uc_vap_id, OAM_SF_ANY, "{hmac_data_acq_down_vap::pst_device null.}");
        return;
    }

    /* 遍历device下所有vap,设置vap 下的信道号 */
    for (uc_vap_idx = 0; uc_vap_idx < pst_device->uc_vap_num; uc_vap_idx++)
    {
        pst_hmac_vap = mac_res_get_hmac_vap(pst_device->auc_vap_id[uc_vap_idx]);
        if (OAL_PTR_NULL == pst_hmac_vap)
        {
            OAM_WARNING_LOG0(pst_mac_vap->uc_vap_id, OAM_SF_ANY, "{hmac_data_acq_down_vap::pst_hmac_vap null.}");
            continue;
        }

        st_down_vap.pst_net_dev = pst_hmac_vap->pst_net_device;

        ul_ret = hmac_config_down_vap(&pst_hmac_vap->st_vap_base_info, OAL_SIZEOF(mac_cfg_down_vap_param_stru), (oal_uint8 *)&st_down_vap);

        if (OAL_UNLIKELY(OAL_SUCC != ul_ret))
        {
            OAM_WARNING_LOG0(pst_mac_vap->uc_vap_id, OAM_SF_ANY, "{hmac_data_acq_down_vap::hmac_config_down_vap failed.}");
        }
    }

    g_uc_data_acq_used = OAL_TRUE;
    OAM_INFO_LOG1(pst_mac_vap->uc_vap_id, OAM_SF_ANY, "{hmac_data_acq_down_vap::g_uc_data_acq_used=%d.}", g_uc_data_acq_used);
}
oal_uint32  hmac_frag_process_proc(hmac_vap_stru *pst_hmac_vap, hmac_user_stru *pst_hmac_user, oal_netbuf_stru *pst_netbuf, mac_tx_ctl_stru *pst_tx_ctl)
{
    oal_uint32          ul_threshold    = 0;
    oal_uint8           uc_ic_header    = 0;
    oal_uint32          ul_ret          = OAL_SUCC;
#if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC != _PRE_MULTI_CORE_MODE)
    oal_uint32          uc_last_frag    = 0;
#endif

    /* 获取分片门限 */
    ul_threshold = pst_hmac_vap->st_vap_base_info.pst_mib_info->st_wlan_mib_operation.ul_dot11FragmentationThreshold;

    /* TBD调用加密接口在使用TKIP时对MSDU进行加密后在进行分片 */
    ul_ret = hmac_en_mic(pst_hmac_vap, pst_hmac_user, pst_netbuf, &uc_ic_header);
    if (OAL_SUCC != ul_ret)
    {
        OAM_ERROR_LOG1(pst_hmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_frag_process::hmac_en_mic failed[%d].}", ul_ret);
        return ul_ret;
    }
    ul_threshold = (ul_threshold & (~(BIT0|BIT1))) + 2;

    /* 规避1151硬件bug,调整分片门限:TKIP加密时,当最后一个分片的payload长度小于等于8时,无法进行加密 */
#if (_PRE_MULTI_CORE_MODE_OFFLOAD_DMAC != _PRE_MULTI_CORE_MODE)
    if (WLAN_80211_CIPHER_SUITE_TKIP == pst_hmac_user->st_user_base_info.st_key_info.en_cipher_type)
    {
        uc_last_frag = OAL_NETBUF_LEN(pst_netbuf) % (ul_threshold - (oal_uint32)uc_ic_header - pst_tx_ctl->uc_frame_header_length);
        if ((uc_last_frag > 0) && (uc_last_frag <= 8))
        {
            ul_threshold = ul_threshold + 8;
            OAM_INFO_LOG1(pst_hmac_vap->st_vap_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_frag_process_proc::adjust the frag threshold to %d.}", ul_threshold);
        }
    }
#endif
    /* 进行分片处理 */
    ul_ret = hmac_frag_process(pst_hmac_vap, pst_netbuf, pst_tx_ctl, (oal_uint32)uc_ic_header, ul_threshold);

    return ul_ret;

}
oal_netbuf_stru* hmac_defrag_process(hmac_user_stru *pst_hmac_user, oal_netbuf_stru *pst_netbuf, oal_uint32 ul_hrdsize)
{
    mac_ieee80211_frame_stru *pst_mac_hdr   = OAL_PTR_NULL;
    mac_ieee80211_frame_stru *pst_last_hdr  = OAL_PTR_NULL;
    oal_uint16                us_rx_seq     = 0;
    oal_uint16                us_last_seq   = 0;
    oal_uint8                 uc_frag_num   = 0;
    oal_uint8                 uc_last_frag_num  = 0;
    oal_bool_enum_uint8       en_more_frag      = OAL_FALSE;
    oal_netbuf_stru          *pst_new_buf       = OAL_PTR_NULL;
    mac_rx_ctl_stru          *pst_rx_ctl;
    oal_uint32                ul_ret;
    oal_uint8                 uc_device_id;
    mac_device_stru          *pst_mac_device;
    oal_uint32                ul_core_id;


    pst_mac_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(pst_netbuf);
    us_rx_seq   = pst_mac_hdr->bit_seq_num;
    uc_frag_num = (oal_uint8)pst_mac_hdr->bit_frag_num;

    en_more_frag = (oal_bool_enum_uint8)pst_mac_hdr->st_frame_control.bit_more_frag;

    /* 如果没有什么可以去分片的则直接返回 */
    if (!en_more_frag && 0 == uc_frag_num && OAL_PTR_NULL == pst_hmac_user->pst_defrag_netbuf)
    {
        return pst_netbuf;
    }

    OAL_MEM_NETBUF_TRACE(pst_netbuf, OAL_FALSE);

    /* 首先检查到来的分片报文是不是属于正在重组的分片报文 */
    if (pst_hmac_user->pst_defrag_netbuf)
    {
        frw_timer_restart_timer(&pst_hmac_user->st_defrag_timer, HMAC_FRAG_TIMEOUT, OAL_FALSE);

        pst_last_hdr = (mac_ieee80211_frame_stru *)oal_netbuf_data(pst_hmac_user->pst_defrag_netbuf);

        us_last_seq  = pst_last_hdr->bit_seq_num;
        uc_last_frag_num = (oal_uint8)pst_last_hdr->bit_frag_num;

        /* 如果地址不匹配,序列号不匹配,分片号不匹配则释放现在正在重组的报文 */
        if (us_rx_seq != us_last_seq ||
            uc_frag_num != (uc_last_frag_num + 1) ||
            oal_compare_mac_addr(pst_last_hdr->auc_address1, pst_mac_hdr->auc_address1) ||
            oal_compare_mac_addr(pst_last_hdr->auc_address2, pst_mac_hdr->auc_address2))
        {
            oal_netbuf_free(pst_hmac_user->pst_defrag_netbuf);
            FRW_TIMER_IMMEDIATE_DESTROY_TIMER(&pst_hmac_user->st_defrag_timer);

            pst_hmac_user->pst_defrag_netbuf = OAL_PTR_NULL;
        }
    }

    /* 判断到来的分片报文是否是第一个分片 */
    if (OAL_PTR_NULL == pst_hmac_user->pst_defrag_netbuf)
    {
        /* 首片分片的分片号不为0则释放 */
        if (uc_frag_num != 0)
        {
            oal_netbuf_free(pst_netbuf);
            OAM_STAT_VAP_INCR(pst_hmac_user->st_user_base_info.uc_vap_id, rx_defrag_process_dropped, 1);
            OAM_INFO_LOG3(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY,
                        "{hmac_defrag_process::The first frag_num is not Zero(%d), seq_num[%d], mor_frag[%d].}",
                           uc_frag_num, us_rx_seq, en_more_frag);

            return OAL_PTR_NULL;
        }

        /* 没有分片,直接返回 */
        if (0 == en_more_frag && 0 == uc_frag_num)
        {
            return pst_netbuf;
        }

        uc_device_id   = pst_hmac_user->st_user_base_info.uc_device_id;
        pst_mac_device = mac_res_get_dev((oal_uint32)uc_device_id);
        if (OAL_PTR_NULL == pst_mac_device)
        {
            OAM_ERROR_LOG4(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY,
                        "{hmac_defrag_process::user index[%d] user mac:XX:XX:XX:%02X:%02X:%02X}",
                        pst_hmac_user->st_user_base_info.us_assoc_id,
                        pst_hmac_user->st_user_base_info.auc_user_mac_addr[3],
                        pst_hmac_user->st_user_base_info.auc_user_mac_addr[4],
                        pst_hmac_user->st_user_base_info.auc_user_mac_addr[5]);
            /* user异常,丢弃报文 */
            oal_netbuf_free(pst_netbuf);
            OAM_STAT_VAP_INCR(pst_hmac_user->st_user_base_info.uc_vap_id, rx_defrag_process_dropped, 1);
            return OAL_PTR_NULL;
        }
        ul_core_id     = pst_mac_device->ul_core_id;

        /* 启动超时定时器,超时释放重组报文 */
        FRW_TIMER_CREATE_TIMER(&pst_hmac_user->st_defrag_timer,
                                hmac_defrag_timeout_fn,
                                HMAC_FRAG_TIMEOUT,
                                pst_hmac_user,
                                OAL_FALSE,
                                OAM_MODULE_ID_HMAC,
                                ul_core_id);

        /* 内存池netbuf只有1600 可能不够,参照A公司申请2500操作系统原生态报文 */
        pst_new_buf = OAL_MEM_NETBUF_ALLOC(OAL_NORMAL_NETBUF, HMAC_MAX_FRAG_SIZE, OAL_NETBUF_PRIORITY_MID);
        if (OAL_PTR_NULL == pst_new_buf)
        {
            OAM_ERROR_LOG1(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_defrag_process::Alloc new_buf null,size[%d].}", HMAC_MAX_FRAG_SIZE);
            return OAL_PTR_NULL;
        }
        OAL_MEM_NETBUF_TRACE(pst_new_buf, OAL_FALSE);

        /* 将分片报文拷贝到新申请的报文中并挂接到用户结构体下,释放原有的报文 */
        oal_netbuf_init(pst_new_buf, OAL_NETBUF_LEN(pst_netbuf));
        oal_netbuf_copydata(pst_netbuf, 0, oal_netbuf_data(pst_new_buf), OAL_NETBUF_LEN(pst_netbuf));
        oal_memcopy(OAL_NETBUF_CB(pst_new_buf), OAL_NETBUF_CB(pst_netbuf), MAC_TX_CTL_SIZE);
        pst_rx_ctl = (mac_rx_ctl_stru *)OAL_NETBUF_CB(pst_new_buf);
        pst_rx_ctl->pul_mac_hdr_start_addr = (oal_uint32 *)OAL_NETBUF_HEADER(pst_new_buf);
        pst_hmac_user->pst_defrag_netbuf = pst_new_buf;

        oal_netbuf_free(pst_netbuf);

        pst_netbuf = pst_new_buf;
    }
    else
    {
        if (OAL_UNLIKELY(OAL_PTR_NULL == pst_last_hdr))
        {
            OAM_ERROR_LOG0(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_defrag_process::pst_last_hdr is NULL.}");
            return OAL_PTR_NULL;
        }

        /* 此分片是期望的到来的分片,重启定时器,并进行重组 */
        frw_timer_restart_timer(&pst_hmac_user->st_defrag_timer, HMAC_FRAG_TIMEOUT, OAL_FALSE);

        oal_netbuf_pull(pst_netbuf, ul_hrdsize);

        /* 记录最新分片报文的分片号 */
        pst_last_hdr->bit_seq_num   = pst_mac_hdr->bit_seq_num;
        pst_last_hdr->bit_frag_num  = pst_mac_hdr->bit_frag_num;

        /*此接口内会调用dev_kfree_skb*/
        oal_netbuf_concat(pst_hmac_user->pst_defrag_netbuf, pst_netbuf);
    }

    /* 判断是否重组完毕,存在更多报文返回空指针,重组完毕返回组好的报文 */
    if (en_more_frag)
    {
        pst_netbuf = OAL_PTR_NULL;
    }
    else
    {
        if (OAL_UNLIKELY(OAL_PTR_NULL == pst_last_hdr))
        {
            OAM_ERROR_LOG0(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_defrag_process::pst_last_hdr is NULL.}");
            oal_netbuf_free(pst_netbuf);
            pst_hmac_user->pst_defrag_netbuf = OAL_PTR_NULL;
            return OAL_PTR_NULL;
        }

        pst_netbuf = pst_hmac_user->pst_defrag_netbuf;
        /* 对重组好的报文进行mic检查 */
        ul_ret = hmac_de_mic(pst_hmac_user, pst_netbuf);
        if (OAL_SUCC != ul_ret)
        {
            oal_netbuf_free(pst_netbuf);

            OAM_STAT_VAP_INCR(pst_hmac_user->st_user_base_info.uc_vap_id, rx_de_mic_fail_dropped, 1);
            pst_netbuf = OAL_PTR_NULL;

            OAM_INFO_LOG1(pst_hmac_user->st_user_base_info.uc_vap_id, OAM_SF_ANY, "{hmac_defrag_process::hmac_de_mic failed[%d].}", ul_ret);
        }

        pst_hmac_user->pst_defrag_netbuf = OAL_PTR_NULL;

        pst_last_hdr->bit_frag_num = 0;

        FRW_TIMER_IMMEDIATE_DESTROY_TIMER(&pst_hmac_user->st_defrag_timer);
    }

    return pst_netbuf;
}
示例#4
0
OAL_STATIC ssize_t dmac_scan_proc_write(struct file *file,
        const char __user *buffer, size_t count, loff_t *ppos)
{
    oal_uint8   auc_buffer[64];
    oal_int8    ac_cmd[128], c_size;
    oal_uint8   uc_bidx = 0;
    oal_uint8   uc_state, uc_tmp, uc_device_id;
    oal_uint32  ul_cnt;
    oal_uint8   uc_band, uc_num, uc_chan_cnt = 0;
    mac_scan_req_stru  st_scan_req;
    mac_device_stru   *pst_mac_device;

    c_size = count;
    if (count > 127)
    {
        c_size = 127;
    }

    if (copy_from_user(ac_cmd, buffer, c_size) != 0)
    {
        return -EFAULT;
    }
    ac_cmd[c_size] = '\0';

    uc_state = 0;
    uc_tmp   = 0;
    OAL_MEMZERO(&st_scan_req, OAL_SIZEOF(st_scan_req));
    g_st_scanner_record.uc_write_cnt += 1;
    for (ul_cnt = 0; ul_cnt < count; ul_cnt++)
    {
        if (0 == uc_state)
        {
            if (' ' == ac_cmd[ul_cnt])
            {
                continue;
            }
            else if ((ac_cmd[ul_cnt] >= '0') && (ac_cmd[ul_cnt] <= '9'))
            {
                uc_state = 1;
                ul_cnt  -= 1;
            }
            else if (('\0' == ac_cmd[ul_cnt]) || ('\n' == ac_cmd[ul_cnt]))
            {
                g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_ALL_OK;
                break;
            }
            else
            {
                g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INVALID_CHAR;
                break;
            }
        }
        else if (1 == uc_state)
        {

            if (' ' == ac_cmd[ul_cnt])
            {
                uc_state = 0;
                auc_buffer[uc_bidx++] = uc_tmp;
                uc_tmp = 0;
            }
            else
            {
                if ((ac_cmd[ul_cnt] >= '0') && (ac_cmd[ul_cnt] <= '9'))
                {
                    uc_tmp = uc_tmp * 10 + ac_cmd[ul_cnt] - '0';
                }
                else if (('\0' == ac_cmd[ul_cnt]) || ('\n' == ac_cmd[ul_cnt]))
                {
                    auc_buffer[uc_bidx++] = uc_tmp;
                    uc_state = 0;
                    g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_ALL_OK;
                    break;
                }
                else
                {
                    g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INVALID_CHAR;
                    uc_state = 0;
                    break;
                }
            }
        }
    }

    if (uc_state)
    {
        auc_buffer[uc_bidx++] = uc_tmp;
    }

#if 1
    OAM_INFO_LOG0(0, OAM_SF_ANY,"%d numbers.\n", uc_bidx);
    for (ul_cnt = 0; ul_cnt < uc_bidx; ul_cnt++)
    {

        OAL_IO_PRINT("..[%d].\n", auc_buffer[ul_cnt]);
    }
#endif

    /* 解析命令 */
    /* 命令格式(以字节为单位) */
    /* scan_mode(1 byte) + scan_type(1 byte) + func_mode(1 byte) + band(1 byte) + channel_num(1byte) + 具体的信道列表(variable) */
    st_scan_req.en_scan_mode = auc_buffer[1];
    st_scan_req.en_scan_type = auc_buffer[2];
    if (auc_buffer[3] & 0xf0)
    {
        g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INVALID_MODE;
        OAM_INFO_LOG1(0, OAM_SF_ANY,"abnormal, auc_buffer[3] is %d\n", auc_buffer[3]);
        goto out;
    }
    st_scan_req.uc_scan_func = auc_buffer[3];
    ul_cnt = 4;
    uc_bidx -= 4;
    while(1)
    {
        if (uc_bidx && (uc_bidx < 2))
        {
            g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INCOMP_CMD;
            OAM_INFO_LOG1(0, OAM_SF_ANY,"abnormal, uc_bidx is %d\n", uc_bidx);
            goto out;
        }

        uc_band = auc_buffer[ul_cnt++];
        uc_num  = auc_buffer[ul_cnt++];
        OAM_INFO_LOG2(0, OAM_SF_ANY,"Add %d channels for band %d.\n", uc_num, uc_band);

        if ((PROC_SCANNER_BAND_2G != uc_band) && (PROC_SCANNER_BAND_5G != uc_band))
        {
            g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INVALID_BAND;
            OAM_INFO_LOG1(0, OAM_SF_ANY,"abnormal, uc_band is %d\n", uc_band);
            goto out;
        }

        if (PROC_SCANNER_BAND_2G == uc_band)
        {
            uc_band = WLAN_BAND_2G;
        }
        else
        {
            uc_band = WLAN_BAND_5G;
        }

        uc_bidx -= 2;
        if (uc_bidx < uc_num)
        {
            g_st_scanner_record.uc_curr_status = PROC_ERROR_TYPE_INCOMP_CMD;
            break;
        }

        /* 提取信道列表 */
        if (uc_num)
        {
            st_scan_req.uc_channel_nums += uc_num;
            uc_tmp = 0;
            while(uc_tmp < uc_num)
            {
                st_scan_req.ast_channel_list[uc_chan_cnt].en_band      = uc_band;
                st_scan_req.ast_channel_list[uc_chan_cnt].en_bandwidth = WLAN_BAND_WIDTH_20M;
                st_scan_req.ast_channel_list[uc_chan_cnt].uc_chan_number = auc_buffer[ul_cnt + uc_tmp];
                mac_get_channel_idx_from_num(uc_band, auc_buffer[ul_cnt + uc_tmp], &st_scan_req.ast_channel_list[uc_chan_cnt].uc_idx);

                uc_tmp++;
                uc_chan_cnt++;
            }

            ul_cnt += uc_num;
        }

        uc_bidx -= uc_num;

        /* 提交扫描请求 */
        if (!uc_bidx)
        {
            oal_uint8  uc_tmp_i;
            for (uc_tmp_i = 0; uc_tmp_i < st_scan_req.uc_channel_nums; uc_tmp_i++)
            {
                OAM_INFO_LOG4(0, OAM_SF_ANY,"[%-6s:%4d]\n",
                st_scan_req.ast_channel_list[uc_tmp_i].en_band == WLAN_BAND_2G?"2.4G":"5G",
                st_scan_req.ast_channel_list[uc_tmp_i].uc_chan_number);
            }

            break;
        }
    }

    st_scan_req.p_fn_cb = dmac_scan_verify_cb;
    uc_device_id   = auc_buffer[0];
    pst_mac_device = mac_res_get_dev(uc_device_id);
    dmac_scan_add_req(pst_mac_device, &st_scan_req);

out:

    return count;
}