mac80211解析一

解析mac80211从ieee80211_alloc_hw函数分配 和ieee80211_register_hw 函数注册开始。

以pci无线网络设备为例,底层pci实现连接并注册pci设备之后,开始在ieee80211_alloc_hw函数中实现无线网络设备的一些列初始化和设备分配,并关联ieee80211_ops操作函数,实现mac层的操作。

struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
                    const struct ieee80211_ops *ops)
{
    struct ieee80211_local *local;
    int priv_size, i;
    struct wiphy *wiphy;
    bool use_chanctx;

    if (WARN_ON(!ops->tx || !ops->start || !ops->stop || !ops->config ||
            !ops->add_interface || !ops->remove_interface ||
            !ops->configure_filter))
        return NULL;

    if (WARN_ON(ops->sta_state && (ops->sta_add || ops->sta_remove)))
        return NULL;

    /* check all or no channel context operations exist */
    i = !!ops->add_chanctx + !!ops->remove_chanctx +
        !!ops->change_chanctx + !!ops->assign_vif_chanctx +
        !!ops->unassign_vif_chanctx;
    if (WARN_ON(i != 0 && i != 5))
        return NULL;
    use_chanctx = i == 5;

    /* Ensure 32-byte alignment of our private data and hw private data.
     * We use the wiphy priv data for both our ieee80211_local and for
     * the driver's private data
     *
     * In memory it'll be like this:
     *
     * +-------------------------+
     * | struct wiphy       |
     * +-------------------------+
     * | struct ieee80211_local  |
     * +-------------------------+
     * | driver's private data   |
     * +-------------------------+
     *
     */
    priv_size = ALIGN(sizeof(*local), NETDEV_ALIGN) + priv_data_len;

    wiphy = wiphy_new(&mac80211_config_ops, priv_size);//分配一个新的wiphy

    if (!wiphy)
        return NULL;

    wiphy->mgmt_stypes = ieee80211_default_mgmt_stypes;

    wiphy->privid = mac80211_wiphy_privid;

    wiphy->flags |= WIPHY_FLAG_NETNS_OK |
            WIPHY_FLAG_4ADDR_AP |
            WIPHY_FLAG_4ADDR_STATION |
            WIPHY_FLAG_REPORTS_OBSS |
            WIPHY_FLAG_OFFCHAN_TX;

    wiphy->extended_capabilities = extended_capabilities;
    wiphy->extended_capabilities_mask = extended_capabilities;
    wiphy->extended_capabilities_len = ARRAY_SIZE(extended_capabilities);

    if (ops->remain_on_channel)
        wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;

    wiphy->features |= NL80211_FEATURE_SK_TX_STATUS |
               NL80211_FEATURE_SAE |
               NL80211_FEATURE_HT_IBSS |
               NL80211_FEATURE_VIF_TXPOWER |
               NL80211_FEATURE_USERSPACE_MPM;

    if (!ops->hw_scan)
        wiphy->features |= NL80211_FEATURE_LOW_PRIORITY_SCAN |
                   NL80211_FEATURE_AP_SCAN;


    if (!ops->set_key)
        wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

    wiphy->bss_priv_size = sizeof(struct ieee80211_bss);

    local = wiphy_priv(wiphy);

    local->hw.wiphy = wiphy;

    local->hw.priv = (char *)local + ALIGN(sizeof(*local), NETDEV_ALIGN);

    local->ops = ops;
    local->use_chanctx = use_chanctx;

    /* set up some defaults */
    local->hw.queues = 1;
    local->hw.max_rates = 1;
    local->hw.max_report_rates = 0;
    local->hw.max_rx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
    local->hw.max_tx_aggregation_subframes = IEEE80211_MAX_AMPDU_BUF;
    local->hw.offchannel_tx_hw_queue = IEEE80211_INVAL_HW_QUEUE;
    local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
    local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
    local->hw.radiotap_mcs_details = IEEE80211_RADIOTAP_MCS_HAVE_MCS |
                     IEEE80211_RADIOTAP_MCS_HAVE_GI |
                     IEEE80211_RADIOTAP_MCS_HAVE_BW;
    local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
                     IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
    local->hw.uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
    local->hw.uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
    local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
    wiphy->ht_capa_mod_mask = &mac80211_ht_capa_mod_mask;
    wiphy->vht_capa_mod_mask = &mac80211_vht_capa_mod_mask;

    INIT_LIST_HEAD(&local->interfaces);

    __hw_addr_init(&local->mc_list);

    mutex_init(&local->iflist_mtx);
    mutex_in
  • 1
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值