mac80211解析六

本文详细介绍了mac80211驱动中的扫描过程,从用户空间通过nl80211发起请求,到选择扫描接口,接着调用`start_scan()`与`schedule_scan()`实现硬件或软件扫描。当硬件扫描不可用时,采用`finish_scan()`进行软件扫描。此外,还涉及到延时唤醒功能和扫描状态机的管理。
摘要由CSDN通过智能技术生成

mac80211的扫描请求由用户空间通过nl80211发起,调用了mac80211中的ieee80211_scan,该函数内容如下:


static int ieee80211_scan(struct wiphy *wiphy,
              struct cfg80211_scan_request *req)
{
    struct ieee80211_sub_if_data *sdata;

    sdata = IEEE80211_WDEV_TO_SUB_IF(req->wdev);

    switch (ieee80211_vif_type_p2p(&sdata->vif)) {
    case NL80211_IFTYPE_STATION:
    case NL80211_IFTYPE_ADHOC:
    case NL80211_IFTYPE_MESH_POINT:
    case NL80211_IFTYPE_P2P_CLIENT:
    case NL80211_IFTYPE_P2P_DEVICE:
        break;
    case NL80211_IFTYPE_P2P_GO:
        if (sdata->local->ops->hw_scan)
            break;
        /*
         * FIXME: implement NoA while scanning in software,
         * for now fall through to allow scanning only when
         * beaconing hasn't been configured yet
         */
    case NL80211_IFTYPE_AP:
        /*
         * If the scan has been forced (and the driver supports
         * forcing), don't care about being beaconing already.
         * This will create problems to the attached stations (e.g. all
         * the  frames sent while scanning on other channel will be
         * lost)
         */
        if (sdata->u.ap.beacon &&
            (!(wiphy->features & NL80211_FEATURE_AP_SCAN) ||
             !(req->flags & NL80211_SCAN_FLAG_AP)))
            return -EOPNOTSUPP;
        break;
    default:
        return -EOPNOTSUPP;
    }

    return ieee80211_request_scan(sdata, req);
}

经过选择扫描接口类型之后,调用ieee80211_request_scan函数,在进一步使用__ieee80211_start_scan 函数实现扫描:


static int __ieee80211_start_scan(struct ieee80211_sub_if_data *sdata,
                  struct cfg80211_scan_request *req)
{
    struct ieee80211_local *local = sdata->local;
    int rc;

    lockdep_assert_held(&local->mtx);

    if (local->scan_req)
        return -EBUSY;

    if (!ieee80211_can_scan(local, sdata)) {
        /* wait for the work to finish/time out */
        local->scan_req = req;
        rcu_assign_pointer(local->scan_sdata, sdata);
        return 0;
    }

    if (local->ops->hw_scan) {
        u8 *ies;

        local->hw_scan_ies_bufsize = local->scan_ies_len + req->ie_len;
        local->hw_scan_req = kmalloc(
                sizeof(*local->hw_scan_req) +
                req->n_channels * sizeof(req->channels[0]) +
                local->hw_scan_ies_bufsize, GFP_KERNEL);
        if (!local->hw_scan_req)
            return -ENOMEM;

        local->hw_scan_req->ssids = req->ssids;
        local->hw_scan_req->n_ssids = req->n_ssids;
        ies = (u8 *)local->hw_scan_req +
            sizeof(*local->hw_scan_req) +
            req->n_channels * sizeof(req->channels[0]);
        local->hw_scan_req->ie = ies;
        local->hw_scan_req->flags = req->flags;

        local->hw_scan
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值