The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/dev/rtw89/chan.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
    2 /* Copyright(c) 2020-2022  Realtek Corporation
    3  */
    4 
    5 #include "chan.h"
    6 #include "debug.h"
    7 
    8 static enum rtw89_subband rtw89_get_subband_type(enum rtw89_band band,
    9                                                  u8 center_chan)
   10 {
   11         switch (band) {
   12         default:
   13         case RTW89_BAND_2G:
   14                 switch (center_chan) {
   15                 default:
   16                 case 1 ... 14:
   17                         return RTW89_CH_2G;
   18                 }
   19         case RTW89_BAND_5G:
   20                 switch (center_chan) {
   21                 default:
   22                 case 36 ... 64:
   23                         return RTW89_CH_5G_BAND_1;
   24                 case 100 ... 144:
   25                         return RTW89_CH_5G_BAND_3;
   26                 case 149 ... 177:
   27                         return RTW89_CH_5G_BAND_4;
   28                 }
   29         case RTW89_BAND_6G:
   30                 switch (center_chan) {
   31                 default:
   32                 case 1 ... 29:
   33                         return RTW89_CH_6G_BAND_IDX0;
   34                 case 33 ... 61:
   35                         return RTW89_CH_6G_BAND_IDX1;
   36                 case 65 ... 93:
   37                         return RTW89_CH_6G_BAND_IDX2;
   38                 case 97 ... 125:
   39                         return RTW89_CH_6G_BAND_IDX3;
   40                 case 129 ... 157:
   41                         return RTW89_CH_6G_BAND_IDX4;
   42                 case 161 ... 189:
   43                         return RTW89_CH_6G_BAND_IDX5;
   44                 case 193 ... 221:
   45                         return RTW89_CH_6G_BAND_IDX6;
   46                 case 225 ... 253:
   47                         return RTW89_CH_6G_BAND_IDX7;
   48                 }
   49         }
   50 }
   51 
   52 static enum rtw89_sc_offset rtw89_get_primary_chan_idx(enum rtw89_bandwidth bw,
   53                                                        u32 center_freq,
   54                                                        u32 primary_freq)
   55 {
   56         u8 primary_chan_idx;
   57         u32 offset;
   58 
   59         switch (bw) {
   60         default:
   61         case RTW89_CHANNEL_WIDTH_20:
   62                 primary_chan_idx = RTW89_SC_DONT_CARE;
   63                 break;
   64         case RTW89_CHANNEL_WIDTH_40:
   65                 if (primary_freq > center_freq)
   66                         primary_chan_idx = RTW89_SC_20_UPPER;
   67                 else
   68                         primary_chan_idx = RTW89_SC_20_LOWER;
   69                 break;
   70         case RTW89_CHANNEL_WIDTH_80:
   71         case RTW89_CHANNEL_WIDTH_160:
   72                 if (primary_freq > center_freq) {
   73                         offset = (primary_freq - center_freq - 10) / 20;
   74                         primary_chan_idx = RTW89_SC_20_UPPER + offset * 2;
   75                 } else {
   76                         offset = (center_freq - primary_freq - 10) / 20;
   77                         primary_chan_idx = RTW89_SC_20_LOWER + offset * 2;
   78                 }
   79                 break;
   80         }
   81 
   82         return primary_chan_idx;
   83 }
   84 
   85 void rtw89_chan_create(struct rtw89_chan *chan, u8 center_chan, u8 primary_chan,
   86                        enum rtw89_band band, enum rtw89_bandwidth bandwidth)
   87 {
   88         enum nl80211_band nl_band = rtw89_hw_to_nl80211_band(band);
   89         u32 center_freq, primary_freq;
   90 
   91         memset(chan, 0, sizeof(*chan));
   92         chan->channel = center_chan;
   93         chan->primary_channel = primary_chan;
   94         chan->band_type = band;
   95         chan->band_width = bandwidth;
   96 
   97         center_freq = ieee80211_channel_to_frequency(center_chan, nl_band);
   98         primary_freq = ieee80211_channel_to_frequency(primary_chan, nl_band);
   99 
  100         chan->freq = center_freq;
  101         chan->subband_type = rtw89_get_subband_type(band, center_chan);
  102         chan->pri_ch_idx = rtw89_get_primary_chan_idx(bandwidth, center_freq,
  103                                                       primary_freq);
  104 }
  105 
  106 bool rtw89_assign_entity_chan(struct rtw89_dev *rtwdev,
  107                               enum rtw89_sub_entity_idx idx,
  108                               const struct rtw89_chan *new)
  109 {
  110         struct rtw89_hal *hal = &rtwdev->hal;
  111         struct rtw89_chan *chan = &hal->chan[idx];
  112         struct rtw89_chan_rcd *rcd = &hal->chan_rcd[idx];
  113         bool band_changed;
  114 
  115         rcd->prev_primary_channel = chan->primary_channel;
  116         rcd->prev_band_type = chan->band_type;
  117         band_changed = new->band_type != chan->band_type;
  118 
  119         *chan = *new;
  120         return band_changed;
  121 }
  122 
  123 static void __rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
  124                                           enum rtw89_sub_entity_idx idx,
  125                                           const struct cfg80211_chan_def *chandef,
  126                                           bool from_stack)
  127 {
  128         struct rtw89_hal *hal = &rtwdev->hal;
  129 
  130         hal->chandef[idx] = *chandef;
  131 
  132         if (from_stack)
  133                 set_bit(idx, hal->entity_map);
  134 }
  135 
  136 void rtw89_config_entity_chandef(struct rtw89_dev *rtwdev,
  137                                  enum rtw89_sub_entity_idx idx,
  138                                  const struct cfg80211_chan_def *chandef)
  139 {
  140         __rtw89_config_entity_chandef(rtwdev, idx, chandef, true);
  141 }
  142 
  143 static void rtw89_config_default_chandef(struct rtw89_dev *rtwdev)
  144 {
  145         struct cfg80211_chan_def chandef = {0};
  146 
  147         rtw89_get_default_chandef(&chandef);
  148         __rtw89_config_entity_chandef(rtwdev, RTW89_SUB_ENTITY_0, &chandef, false);
  149 }
  150 
  151 void rtw89_entity_init(struct rtw89_dev *rtwdev)
  152 {
  153         struct rtw89_hal *hal = &rtwdev->hal;
  154 
  155         bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  156         rtw89_config_default_chandef(rtwdev);
  157 }
  158 
  159 enum rtw89_entity_mode rtw89_entity_recalc(struct rtw89_dev *rtwdev)
  160 {
  161         struct rtw89_hal *hal = &rtwdev->hal;
  162         enum rtw89_entity_mode mode;
  163         u8 weight;
  164 
  165         weight = bitmap_weight(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  166         switch (weight) {
  167         default:
  168                 rtw89_warn(rtwdev, "unknown ent chan weight: %d\n", weight);
  169                 bitmap_zero(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  170                 fallthrough;
  171         case 0:
  172                 rtw89_config_default_chandef(rtwdev);
  173                 fallthrough;
  174         case 1:
  175                 mode = RTW89_ENTITY_MODE_SCC;
  176                 break;
  177         }
  178 
  179         rtw89_set_entity_mode(rtwdev, mode);
  180         return mode;
  181 }
  182 
  183 int rtw89_chanctx_ops_add(struct rtw89_dev *rtwdev,
  184                           struct ieee80211_chanctx_conf *ctx)
  185 {
  186         struct rtw89_hal *hal = &rtwdev->hal;
  187         struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  188         const struct rtw89_chip_info *chip = rtwdev->chip;
  189         u8 idx;
  190 
  191         idx = find_first_zero_bit(hal->entity_map, NUM_OF_RTW89_SUB_ENTITY);
  192         if (idx >= chip->support_chanctx_num)
  193                 return -ENOENT;
  194 
  195         rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
  196         rtw89_set_channel(rtwdev);
  197         cfg->idx = idx;
  198         return 0;
  199 }
  200 
  201 void rtw89_chanctx_ops_remove(struct rtw89_dev *rtwdev,
  202                               struct ieee80211_chanctx_conf *ctx)
  203 {
  204         struct rtw89_hal *hal = &rtwdev->hal;
  205         struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  206 
  207         clear_bit(cfg->idx, hal->entity_map);
  208         rtw89_set_channel(rtwdev);
  209 }
  210 
  211 void rtw89_chanctx_ops_change(struct rtw89_dev *rtwdev,
  212                               struct ieee80211_chanctx_conf *ctx,
  213                               u32 changed)
  214 {
  215         struct rtw89_chanctx_cfg *cfg = (struct rtw89_chanctx_cfg *)ctx->drv_priv;
  216         u8 idx = cfg->idx;
  217 
  218         if (changed & IEEE80211_CHANCTX_CHANGE_WIDTH) {
  219                 rtw89_config_entity_chandef(rtwdev, idx, &ctx->def);
  220                 rtw89_set_channel(rtwdev);
  221         }
  222 }
  223 
  224 int rtw89_chanctx_ops_assign_vif(struct rtw89_dev *rtwdev,
  225                                  struct rtw89_vif *rtwvif,
  226                                  struct ieee80211_chanctx_conf *ctx)
  227 {
  228         return 0;
  229 }
  230 
  231 void rtw89_chanctx_ops_unassign_vif(struct rtw89_dev *rtwdev,
  232                                     struct rtw89_vif *rtwvif,
  233                                     struct ieee80211_chanctx_conf *ctx)
  234 {
  235 }

Cache object: b1a0b8d1fcb3df6803200c7ff60a8802


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.