linux/drivers/staging/rtl8723bs/os_dep/wifi_regd.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2009-2010  Realtek Corporation.
   5 *
   6 *****************************************************************************/
   7
   8#include <drv_types.h>
   9#include <rtw_debug.h>
  10
  11#include <rtw_wifi_regd.h>
  12
  13/*
  14 * REG_RULE(freq start, freq end, bandwidth, max gain, eirp, reg_flags)
  15 */
  16
  17/*
  18 * Only these channels all allow active
  19 * scan on all world regulatory domains
  20 */
  21
  22/* 2G chan 01 - chan 11 */
  23#define RTW_2GHZ_CH01_11        \
  24        REG_RULE(2412 - 10, 2462 + 10, 40, 0, 20, 0)
  25
  26/*
  27 * We enable active scan on these a case
  28 * by case basis by regulatory domain
  29 */
  30
  31/* 2G chan 12 - chan 13, PASSIV SCAN */
  32#define RTW_2GHZ_CH12_13        \
  33        REG_RULE(2467 - 10, 2472 + 10, 40, 0, 20,       \
  34        NL80211_RRF_PASSIVE_SCAN)
  35
  36static const struct ieee80211_regdomain rtw_regdom_rd = {
  37        .n_reg_rules = 3,
  38        .alpha2 = "99",
  39        .reg_rules = {
  40                RTW_2GHZ_CH01_11,
  41                RTW_2GHZ_CH12_13,
  42        }
  43};
  44
  45static int rtw_ieee80211_channel_to_frequency(int chan, int band)
  46{
  47        /* see 802.11 17.3.8.3.2 and Annex J
  48         * there are overlapping channel numbers in 5GHz and 2GHz bands
  49         */
  50
  51        /* NL80211_BAND_2GHZ */
  52        if (chan == 14)
  53                return 2484;
  54        else if (chan < 14)
  55                return 2407 + chan * 5;
  56        else
  57                return 0;       /* not supported */
  58}
  59
  60static void _rtw_reg_apply_flags(struct wiphy *wiphy)
  61{
  62        struct adapter *padapter = wiphy_to_adapter(wiphy);
  63        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  64        RT_CHANNEL_INFO *channel_set = pmlmeext->channel_set;
  65        u8 max_chan_nums = pmlmeext->max_chan_nums;
  66
  67        struct ieee80211_supported_band *sband;
  68        struct ieee80211_channel *ch;
  69        unsigned int i, j;
  70        u16 channel;
  71        u32 freq;
  72
  73        /* all channels disable */
  74        for (i = 0; i < NUM_NL80211_BANDS; i++) {
  75                sband = wiphy->bands[i];
  76
  77                if (sband) {
  78                        for (j = 0; j < sband->n_channels; j++) {
  79                                ch = &sband->channels[j];
  80
  81                                if (ch)
  82                                        ch->flags = IEEE80211_CHAN_DISABLED;
  83                        }
  84                }
  85        }
  86
  87        /* channels apply by channel plans. */
  88        for (i = 0; i < max_chan_nums; i++) {
  89                channel = channel_set[i].ChannelNum;
  90                freq =
  91                    rtw_ieee80211_channel_to_frequency(channel,
  92                                                       NL80211_BAND_2GHZ);
  93
  94                ch = ieee80211_get_channel(wiphy, freq);
  95                if (ch) {
  96                        if (channel_set[i].ScanType == SCAN_PASSIVE)
  97                                ch->flags = IEEE80211_CHAN_NO_IR;
  98                        else
  99                                ch->flags = 0;
 100                }
 101        }
 102}
 103
 104static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
 105                                   struct regulatory_request *request,
 106                                   struct rtw_regulatory *reg)
 107{
 108        /* Hard code flags */
 109        _rtw_reg_apply_flags(wiphy);
 110        return 0;
 111}
 112
 113static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
 114                                                               rtw_regulatory
 115                                                               *reg)
 116{
 117        return &rtw_regdom_rd;
 118}
 119
 120static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
 121                                 struct wiphy *wiphy,
 122                                 void (*reg_notifier)(struct wiphy *wiphy,
 123                                                      struct
 124                                                      regulatory_request *
 125                                                      request))
 126{
 127        const struct ieee80211_regdomain *regd;
 128
 129        wiphy->reg_notifier = reg_notifier;
 130
 131        wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
 132        wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
 133        wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
 134
 135        regd = _rtw_regdomain_select(reg);
 136        wiphy_apply_custom_regulatory(wiphy, regd);
 137
 138        /* Hard code flags */
 139        _rtw_reg_apply_flags(wiphy);
 140}
 141
 142int rtw_regd_init(struct adapter *padapter,
 143                  void (*reg_notifier)(struct wiphy *wiphy,
 144                                       struct regulatory_request *request))
 145{
 146        struct wiphy *wiphy = padapter->rtw_wdev->wiphy;
 147
 148        _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
 149
 150        return 0;
 151}
 152
 153void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 154{
 155        struct rtw_regulatory *reg = NULL;
 156
 157        DBG_8192C("%s\n", __func__);
 158
 159        _rtw_reg_notifier_apply(wiphy, request, reg);
 160}
 161