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 = 2,
  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        /* NL80211_BAND_2GHZ */
  48        if (chan == 14)
  49                return 2484;
  50        else if (chan < 14)
  51                return 2407 + chan * 5;
  52        else
  53                return 0;       /* not supported */
  54}
  55
  56static void _rtw_reg_apply_flags(struct wiphy *wiphy)
  57{
  58        struct adapter *padapter = wiphy_to_adapter(wiphy);
  59        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  60        struct rt_channel_info *channel_set = pmlmeext->channel_set;
  61        u8 max_chan_nums = pmlmeext->max_chan_nums;
  62
  63        struct ieee80211_supported_band *sband;
  64        struct ieee80211_channel *ch;
  65        unsigned int i, j;
  66        u16 channel;
  67        u32 freq;
  68
  69        /* all channels disable */
  70        for (i = 0; i < NUM_NL80211_BANDS; i++) {
  71                sband = wiphy->bands[i];
  72
  73                if (sband) {
  74                        for (j = 0; j < sband->n_channels; j++) {
  75                                ch = &sband->channels[j];
  76
  77                                if (ch)
  78                                        ch->flags = IEEE80211_CHAN_DISABLED;
  79                        }
  80                }
  81        }
  82
  83        /* channels apply by channel plans. */
  84        for (i = 0; i < max_chan_nums; i++) {
  85                channel = channel_set[i].ChannelNum;
  86                freq =
  87                    rtw_ieee80211_channel_to_frequency(channel,
  88                                                       NL80211_BAND_2GHZ);
  89
  90                ch = ieee80211_get_channel(wiphy, freq);
  91                if (ch) {
  92                        if (channel_set[i].ScanType == SCAN_PASSIVE)
  93                                ch->flags = IEEE80211_CHAN_NO_IR;
  94                        else
  95                                ch->flags = 0;
  96                }
  97        }
  98}
  99
 100static int _rtw_reg_notifier_apply(struct wiphy *wiphy,
 101                                   struct regulatory_request *request,
 102                                   struct rtw_regulatory *reg)
 103{
 104        /* Hard code flags */
 105        _rtw_reg_apply_flags(wiphy);
 106        return 0;
 107}
 108
 109static const struct ieee80211_regdomain *_rtw_regdomain_select(struct
 110                                                               rtw_regulatory
 111                                                               *reg)
 112{
 113        return &rtw_regdom_rd;
 114}
 115
 116static void _rtw_regd_init_wiphy(struct rtw_regulatory *reg,
 117                                 struct wiphy *wiphy,
 118                                 void (*reg_notifier)(struct wiphy *wiphy,
 119                                                      struct
 120                                                      regulatory_request *
 121                                                      request))
 122{
 123        const struct ieee80211_regdomain *regd;
 124
 125        wiphy->reg_notifier = reg_notifier;
 126
 127        wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
 128        wiphy->regulatory_flags &= ~REGULATORY_STRICT_REG;
 129        wiphy->regulatory_flags &= ~REGULATORY_DISABLE_BEACON_HINTS;
 130
 131        regd = _rtw_regdomain_select(reg);
 132        wiphy_apply_custom_regulatory(wiphy, regd);
 133
 134        /* Hard code flags */
 135        _rtw_reg_apply_flags(wiphy);
 136}
 137
 138void rtw_regd_init(struct wiphy *wiphy,
 139                   void (*reg_notifier)(struct wiphy *wiphy,
 140                                        struct regulatory_request *request))
 141{
 142        _rtw_regd_init_wiphy(NULL, wiphy, reg_notifier);
 143}
 144
 145void rtw_reg_notifier(struct wiphy *wiphy, struct regulatory_request *request)
 146{
 147        struct rtw_regulatory *reg = NULL;
 148
 149        _rtw_reg_notifier_apply(wiphy, request, reg);
 150}
 151