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/rtw88/mac80211.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) 2018-2019  Realtek Corporation
    3  */
    4 
    5 #include "main.h"
    6 #include "sec.h"
    7 #include "tx.h"
    8 #include "fw.h"
    9 #include "mac.h"
   10 #include "coex.h"
   11 #include "ps.h"
   12 #include "reg.h"
   13 #include "bf.h"
   14 #include "debug.h"
   15 #include "wow.h"
   16 #include "sar.h"
   17 
   18 static void rtw_ops_tx(struct ieee80211_hw *hw,
   19                        struct ieee80211_tx_control *control,
   20                        struct sk_buff *skb)
   21 {
   22         struct rtw_dev *rtwdev = hw->priv;
   23 
   24         if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags)) {
   25                 ieee80211_free_txskb(hw, skb);
   26                 return;
   27         }
   28 
   29         rtw_tx(rtwdev, control, skb);
   30 }
   31 
   32 static void rtw_ops_wake_tx_queue(struct ieee80211_hw *hw,
   33                                   struct ieee80211_txq *txq)
   34 {
   35         struct rtw_dev *rtwdev = hw->priv;
   36         struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv;
   37 
   38         if (!test_bit(RTW_FLAG_RUNNING, rtwdev->flags))
   39                 return;
   40 
   41         spin_lock_bh(&rtwdev->txq_lock);
   42         if (list_empty(&rtwtxq->list))
   43                 list_add_tail(&rtwtxq->list, &rtwdev->txqs);
   44         spin_unlock_bh(&rtwdev->txq_lock);
   45 
   46         queue_work(rtwdev->tx_wq, &rtwdev->tx_work);
   47 }
   48 
   49 static int rtw_ops_start(struct ieee80211_hw *hw)
   50 {
   51         struct rtw_dev *rtwdev = hw->priv;
   52         int ret;
   53 
   54         mutex_lock(&rtwdev->mutex);
   55         ret = rtw_core_start(rtwdev);
   56         mutex_unlock(&rtwdev->mutex);
   57 
   58         return ret;
   59 }
   60 
   61 static void rtw_ops_stop(struct ieee80211_hw *hw)
   62 {
   63         struct rtw_dev *rtwdev = hw->priv;
   64 
   65         mutex_lock(&rtwdev->mutex);
   66         rtw_core_stop(rtwdev);
   67         mutex_unlock(&rtwdev->mutex);
   68 }
   69 
   70 static int rtw_ops_config(struct ieee80211_hw *hw, u32 changed)
   71 {
   72         struct rtw_dev *rtwdev = hw->priv;
   73         int ret = 0;
   74 
   75         /* let previous ips work finish to ensure we don't leave ips twice */
   76         cancel_work_sync(&rtwdev->ips_work);
   77 
   78         mutex_lock(&rtwdev->mutex);
   79 
   80         rtw_leave_lps_deep(rtwdev);
   81 
   82         if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
   83             !(hw->conf.flags & IEEE80211_CONF_IDLE)) {
   84                 ret = rtw_leave_ips(rtwdev);
   85                 if (ret) {
   86                         rtw_err(rtwdev, "failed to leave idle state\n");
   87                         goto out;
   88                 }
   89         }
   90 
   91         if (changed & IEEE80211_CONF_CHANGE_PS) {
   92                 if (hw->conf.flags & IEEE80211_CONF_PS) {
   93                         rtwdev->ps_enabled = true;
   94                 } else {
   95                         rtwdev->ps_enabled = false;
   96                         rtw_leave_lps(rtwdev);
   97                 }
   98         }
   99 
  100         if (changed & IEEE80211_CONF_CHANGE_CHANNEL)
  101                 rtw_set_channel(rtwdev);
  102 
  103         if ((changed & IEEE80211_CONF_CHANGE_IDLE) &&
  104             (hw->conf.flags & IEEE80211_CONF_IDLE))
  105                 rtw_enter_ips(rtwdev);
  106 
  107 out:
  108         mutex_unlock(&rtwdev->mutex);
  109         return ret;
  110 }
  111 
  112 static const struct rtw_vif_port rtw_vif_port[] = {
  113         [0] = {
  114                 .mac_addr       = {.addr = 0x0610},
  115                 .bssid          = {.addr = 0x0618},
  116                 .net_type       = {.addr = 0x0100, .mask = 0x30000},
  117                 .aid            = {.addr = 0x06a8, .mask = 0x7ff},
  118                 .bcn_ctrl       = {.addr = 0x0550, .mask = 0xff},
  119         },
  120         [1] = {
  121                 .mac_addr       = {.addr = 0x0700},
  122                 .bssid          = {.addr = 0x0708},
  123                 .net_type       = {.addr = 0x0100, .mask = 0xc0000},
  124                 .aid            = {.addr = 0x0710, .mask = 0x7ff},
  125                 .bcn_ctrl       = {.addr = 0x0551, .mask = 0xff},
  126         },
  127         [2] = {
  128                 .mac_addr       = {.addr = 0x1620},
  129                 .bssid          = {.addr = 0x1628},
  130                 .net_type       = {.addr = 0x1100, .mask = 0x3},
  131                 .aid            = {.addr = 0x1600, .mask = 0x7ff},
  132                 .bcn_ctrl       = {.addr = 0x0578, .mask = 0xff},
  133         },
  134         [3] = {
  135                 .mac_addr       = {.addr = 0x1630},
  136                 .bssid          = {.addr = 0x1638},
  137                 .net_type       = {.addr = 0x1100, .mask = 0xc},
  138                 .aid            = {.addr = 0x1604, .mask = 0x7ff},
  139                 .bcn_ctrl       = {.addr = 0x0579, .mask = 0xff},
  140         },
  141         [4] = {
  142                 .mac_addr       = {.addr = 0x1640},
  143                 .bssid          = {.addr = 0x1648},
  144                 .net_type       = {.addr = 0x1100, .mask = 0x30},
  145                 .aid            = {.addr = 0x1608, .mask = 0x7ff},
  146                 .bcn_ctrl       = {.addr = 0x057a, .mask = 0xff},
  147         },
  148 };
  149 
  150 static int rtw_ops_add_interface(struct ieee80211_hw *hw,
  151                                  struct ieee80211_vif *vif)
  152 {
  153         struct rtw_dev *rtwdev = hw->priv;
  154         struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
  155         enum rtw_net_type net_type;
  156         u32 config = 0;
  157         u8 port = 0;
  158         u8 bcn_ctrl = 0;
  159 
  160         if (rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_BCN_FILTER))
  161                 vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER |
  162                                      IEEE80211_VIF_SUPPORTS_CQM_RSSI;
  163         rtwvif->port = port;
  164         rtwvif->stats.tx_unicast = 0;
  165         rtwvif->stats.rx_unicast = 0;
  166         rtwvif->stats.tx_cnt = 0;
  167         rtwvif->stats.rx_cnt = 0;
  168         rtwvif->scan_req = NULL;
  169         memset(&rtwvif->bfee, 0, sizeof(struct rtw_bfee));
  170         rtwvif->conf = &rtw_vif_port[port];
  171         rtw_txq_init(rtwdev, vif->txq);
  172         INIT_LIST_HEAD(&rtwvif->rsvd_page_list);
  173 
  174         mutex_lock(&rtwdev->mutex);
  175 
  176         rtw_leave_lps_deep(rtwdev);
  177 
  178         switch (vif->type) {
  179         case NL80211_IFTYPE_AP:
  180         case NL80211_IFTYPE_MESH_POINT:
  181                 rtw_add_rsvd_page_bcn(rtwdev, rtwvif);
  182                 net_type = RTW_NET_AP_MODE;
  183                 bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT;
  184                 break;
  185         case NL80211_IFTYPE_ADHOC:
  186                 rtw_add_rsvd_page_bcn(rtwdev, rtwvif);
  187                 net_type = RTW_NET_AD_HOC;
  188                 bcn_ctrl = BIT_EN_BCN_FUNCTION | BIT_DIS_TSF_UDT;
  189                 break;
  190         case NL80211_IFTYPE_STATION:
  191                 rtw_add_rsvd_page_sta(rtwdev, rtwvif);
  192                 net_type = RTW_NET_NO_LINK;
  193                 bcn_ctrl = BIT_EN_BCN_FUNCTION;
  194                 break;
  195         default:
  196                 WARN_ON(1);
  197                 mutex_unlock(&rtwdev->mutex);
  198                 return -EINVAL;
  199         }
  200 
  201         ether_addr_copy(rtwvif->mac_addr, vif->addr);
  202         config |= PORT_SET_MAC_ADDR;
  203         rtwvif->net_type = net_type;
  204         config |= PORT_SET_NET_TYPE;
  205         rtwvif->bcn_ctrl = bcn_ctrl;
  206         config |= PORT_SET_BCN_CTRL;
  207         rtw_vif_port_config(rtwdev, rtwvif, config);
  208 
  209         mutex_unlock(&rtwdev->mutex);
  210 
  211 #if defined(__linux__)
  212         rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %pM on port %d\n", vif->addr, rtwvif->port);
  213 #elif defined(__FreeBSD__)
  214         rtw_dbg(rtwdev, RTW_DBG_STATE, "start vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
  215 #endif
  216         return 0;
  217 }
  218 
  219 static void rtw_ops_remove_interface(struct ieee80211_hw *hw,
  220                                      struct ieee80211_vif *vif)
  221 {
  222         struct rtw_dev *rtwdev = hw->priv;
  223         struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
  224         u32 config = 0;
  225 
  226 #if defined(__linux__)
  227         rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %pM on port %d\n", vif->addr, rtwvif->port);
  228 #elif defined(__FreeBSD__)
  229         rtw_dbg(rtwdev, RTW_DBG_STATE, "stop vif %6D on port %d\n", vif->addr, ":", rtwvif->port);
  230 #endif
  231 
  232         mutex_lock(&rtwdev->mutex);
  233 
  234         rtw_leave_lps_deep(rtwdev);
  235 
  236         rtw_txq_cleanup(rtwdev, vif->txq);
  237         rtw_remove_rsvd_page(rtwdev, rtwvif);
  238 
  239         eth_zero_addr(rtwvif->mac_addr);
  240         config |= PORT_SET_MAC_ADDR;
  241         rtwvif->net_type = RTW_NET_NO_LINK;
  242         config |= PORT_SET_NET_TYPE;
  243         rtwvif->bcn_ctrl = 0;
  244         config |= PORT_SET_BCN_CTRL;
  245         rtw_vif_port_config(rtwdev, rtwvif, config);
  246 
  247         mutex_unlock(&rtwdev->mutex);
  248 }
  249 
  250 static int rtw_ops_change_interface(struct ieee80211_hw *hw,
  251                                     struct ieee80211_vif *vif,
  252                                     enum nl80211_iftype type, bool p2p)
  253 {
  254         struct rtw_dev *rtwdev = hw->priv;
  255 
  256 #if defined(__linux__)
  257         rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %pM (%d)->(%d), p2p (%d)->(%d)\n",
  258                 vif->addr, vif->type, type, vif->p2p, p2p);
  259 #elif defined(__FreeBSD__)
  260         rtw_dbg(rtwdev, RTW_DBG_STATE, "change vif %6D (%d)->(%d), p2p (%d)->(%d)\n",
  261                 vif->addr, ":", vif->type, type, vif->p2p, p2p);
  262 #endif
  263 
  264         rtw_ops_remove_interface(hw, vif);
  265 
  266         vif->type = type;
  267         vif->p2p = p2p;
  268 
  269         return rtw_ops_add_interface(hw, vif);
  270 }
  271 
  272 static void rtw_ops_configure_filter(struct ieee80211_hw *hw,
  273                                      unsigned int changed_flags,
  274                                      unsigned int *new_flags,
  275                                      u64 multicast)
  276 {
  277         struct rtw_dev *rtwdev = hw->priv;
  278 
  279         *new_flags &= FIF_ALLMULTI | FIF_OTHER_BSS | FIF_FCSFAIL |
  280                       FIF_BCN_PRBRESP_PROMISC;
  281 
  282         mutex_lock(&rtwdev->mutex);
  283 
  284         rtw_leave_lps_deep(rtwdev);
  285 
  286         if (changed_flags & FIF_ALLMULTI) {
  287                 if (*new_flags & FIF_ALLMULTI)
  288                         rtwdev->hal.rcr |= BIT_AM | BIT_AB;
  289                 else
  290                         rtwdev->hal.rcr &= ~(BIT_AM | BIT_AB);
  291         }
  292         if (changed_flags & FIF_FCSFAIL) {
  293                 if (*new_flags & FIF_FCSFAIL)
  294                         rtwdev->hal.rcr |= BIT_ACRC32;
  295                 else
  296                         rtwdev->hal.rcr &= ~(BIT_ACRC32);
  297         }
  298         if (changed_flags & FIF_OTHER_BSS) {
  299                 if (*new_flags & FIF_OTHER_BSS)
  300                         rtwdev->hal.rcr |= BIT_AAP;
  301                 else
  302                         rtwdev->hal.rcr &= ~(BIT_AAP);
  303         }
  304         if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
  305                 if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
  306                         rtwdev->hal.rcr &= ~(BIT_CBSSID_BCN | BIT_CBSSID_DATA);
  307                 else
  308                         rtwdev->hal.rcr |= BIT_CBSSID_BCN;
  309         }
  310 
  311         rtw_dbg(rtwdev, RTW_DBG_RX,
  312                 "config rx filter, changed=0x%08x, new=0x%08x, rcr=0x%08x\n",
  313                 changed_flags, *new_flags, rtwdev->hal.rcr);
  314 
  315         rtw_write32(rtwdev, REG_RCR, rtwdev->hal.rcr);
  316 
  317         mutex_unlock(&rtwdev->mutex);
  318 }
  319 
  320 /* Only have one group of EDCA parameters now */
  321 static const u32 ac_to_edca_param[IEEE80211_NUM_ACS] = {
  322         [IEEE80211_AC_VO] = REG_EDCA_VO_PARAM,
  323         [IEEE80211_AC_VI] = REG_EDCA_VI_PARAM,
  324         [IEEE80211_AC_BE] = REG_EDCA_BE_PARAM,
  325         [IEEE80211_AC_BK] = REG_EDCA_BK_PARAM,
  326 };
  327 
  328 static u8 rtw_aifsn_to_aifs(struct rtw_dev *rtwdev,
  329                             struct rtw_vif *rtwvif, u8 aifsn)
  330 {
  331         struct ieee80211_vif *vif = rtwvif_to_vif(rtwvif);
  332         u8 slot_time;
  333         u8 sifs;
  334 
  335         slot_time = vif->bss_conf.use_short_slot ? 9 : 20;
  336         sifs = rtwdev->hal.current_band_type == RTW_BAND_5G ? 16 : 10;
  337 
  338         return aifsn * slot_time + sifs;
  339 }
  340 
  341 static void __rtw_conf_tx(struct rtw_dev *rtwdev,
  342                           struct rtw_vif *rtwvif, u16 ac)
  343 {
  344         struct ieee80211_tx_queue_params *params = &rtwvif->tx_params[ac];
  345         u32 edca_param = ac_to_edca_param[ac];
  346         u8 ecw_max, ecw_min;
  347         u8 aifs;
  348 
  349         /* 2^ecw - 1 = cw; ecw = log2(cw + 1) */
  350         ecw_max = ilog2(params->cw_max + 1);
  351         ecw_min = ilog2(params->cw_min + 1);
  352         aifs = rtw_aifsn_to_aifs(rtwdev, rtwvif, params->aifs);
  353         rtw_write32_mask(rtwdev, edca_param, BIT_MASK_TXOP_LMT, params->txop);
  354         rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMAX, ecw_max);
  355         rtw_write32_mask(rtwdev, edca_param, BIT_MASK_CWMIN, ecw_min);
  356         rtw_write32_mask(rtwdev, edca_param, BIT_MASK_AIFS, aifs);
  357 }
  358 
  359 static void rtw_conf_tx(struct rtw_dev *rtwdev,
  360                         struct rtw_vif *rtwvif)
  361 {
  362         u16 ac;
  363 
  364         for (ac = 0; ac < IEEE80211_NUM_ACS; ac++)
  365                 __rtw_conf_tx(rtwdev, rtwvif, ac);
  366 }
  367 
  368 static void rtw_ops_bss_info_changed(struct ieee80211_hw *hw,
  369                                      struct ieee80211_vif *vif,
  370                                      struct ieee80211_bss_conf *conf,
  371                                      u64 changed)
  372 {
  373         struct rtw_dev *rtwdev = hw->priv;
  374         struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
  375         struct rtw_coex *coex = &rtwdev->coex;
  376         struct rtw_coex_stat *coex_stat = &coex->stat;
  377         u32 config = 0;
  378 
  379         mutex_lock(&rtwdev->mutex);
  380 
  381         rtw_leave_lps_deep(rtwdev);
  382 
  383         if (changed & BSS_CHANGED_ASSOC) {
  384                 rtw_vif_assoc_changed(rtwvif, conf);
  385                 if (conf->assoc) {
  386                         rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_FINISH);
  387 
  388                         rtw_fw_download_rsvd_page(rtwdev);
  389                         rtw_send_rsvd_page_h2c(rtwdev);
  390                         rtw_coex_media_status_notify(rtwdev, conf->assoc);
  391                         if (rtw_bf_support)
  392                                 rtw_bf_assoc(rtwdev, vif, conf);
  393                         rtw_store_op_chan(rtwdev);
  394                 } else {
  395                         rtw_leave_lps(rtwdev);
  396                         rtw_bf_disassoc(rtwdev, vif, conf);
  397                         /* Abort ongoing scan if cancel_scan isn't issued
  398                          * when disconnected by peer
  399                          */
  400                         if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
  401                                 rtw_hw_scan_abort(rtwdev, vif);
  402                 }
  403 
  404                 config |= PORT_SET_NET_TYPE;
  405                 config |= PORT_SET_AID;
  406         }
  407 
  408         if (changed & BSS_CHANGED_BSSID) {
  409                 ether_addr_copy(rtwvif->bssid, conf->bssid);
  410                 config |= PORT_SET_BSSID;
  411         }
  412 
  413         if (changed & BSS_CHANGED_BEACON_INT) {
  414                 if (ieee80211_vif_type_p2p(vif) == NL80211_IFTYPE_STATION)
  415                         coex_stat->wl_beacon_interval = conf->beacon_int;
  416         }
  417 
  418         if (changed & BSS_CHANGED_BEACON) {
  419                 rtw_set_dtim_period(rtwdev, conf->dtim_period);
  420                 rtw_fw_download_rsvd_page(rtwdev);
  421         }
  422 
  423         if (changed & BSS_CHANGED_BEACON_ENABLED) {
  424                 if (conf->enable_beacon)
  425                         rtw_write32_set(rtwdev, REG_FWHW_TXQ_CTRL,
  426                                         BIT_EN_BCNQ_DL);
  427                 else
  428                         rtw_write32_clr(rtwdev, REG_FWHW_TXQ_CTRL,
  429                                         BIT_EN_BCNQ_DL);
  430         }
  431         if (changed & BSS_CHANGED_CQM)
  432                 rtw_fw_beacon_filter_config(rtwdev, true, vif);
  433 
  434         if (changed & BSS_CHANGED_MU_GROUPS)
  435                 rtw_chip_set_gid_table(rtwdev, vif, conf);
  436 
  437         if (changed & BSS_CHANGED_ERP_SLOT)
  438                 rtw_conf_tx(rtwdev, rtwvif);
  439 
  440         rtw_vif_port_config(rtwdev, rtwvif, config);
  441 
  442         mutex_unlock(&rtwdev->mutex);
  443 }
  444 
  445 static int rtw_ops_start_ap(struct ieee80211_hw *hw,
  446                             struct ieee80211_vif *vif,
  447                             struct ieee80211_bss_conf *link_conf)
  448 {
  449         struct rtw_dev *rtwdev = hw->priv;
  450         struct rtw_chip_info *chip = rtwdev->chip;
  451 
  452         mutex_lock(&rtwdev->mutex);
  453         chip->ops->phy_calibration(rtwdev);
  454         mutex_unlock(&rtwdev->mutex);
  455 
  456         return 0;
  457 }
  458 
  459 static int rtw_ops_conf_tx(struct ieee80211_hw *hw,
  460                            struct ieee80211_vif *vif,
  461                            unsigned int link_id, u16 ac,
  462                            const struct ieee80211_tx_queue_params *params)
  463 {
  464         struct rtw_dev *rtwdev = hw->priv;
  465         struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
  466 
  467         mutex_lock(&rtwdev->mutex);
  468 
  469         rtw_leave_lps_deep(rtwdev);
  470 
  471         rtwvif->tx_params[ac] = *params;
  472         __rtw_conf_tx(rtwdev, rtwvif, ac);
  473 
  474         mutex_unlock(&rtwdev->mutex);
  475 
  476         return 0;
  477 }
  478 
  479 static int rtw_ops_sta_add(struct ieee80211_hw *hw,
  480                            struct ieee80211_vif *vif,
  481                            struct ieee80211_sta *sta)
  482 {
  483         struct rtw_dev *rtwdev = hw->priv;
  484         int ret = 0;
  485 
  486         mutex_lock(&rtwdev->mutex);
  487         ret = rtw_sta_add(rtwdev, sta, vif);
  488         mutex_unlock(&rtwdev->mutex);
  489 
  490         return ret;
  491 }
  492 
  493 static int rtw_ops_sta_remove(struct ieee80211_hw *hw,
  494                               struct ieee80211_vif *vif,
  495                               struct ieee80211_sta *sta)
  496 {
  497         struct rtw_dev *rtwdev = hw->priv;
  498 
  499         rtw_fw_beacon_filter_config(rtwdev, false, vif);
  500         mutex_lock(&rtwdev->mutex);
  501         rtw_sta_remove(rtwdev, sta, true);
  502         mutex_unlock(&rtwdev->mutex);
  503 
  504         return 0;
  505 }
  506 
  507 static int rtw_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
  508                            bool set)
  509 {
  510         struct rtw_dev *rtwdev = hw->priv;
  511 
  512         ieee80211_queue_work(hw, &rtwdev->update_beacon_work);
  513 
  514         return 0;
  515 }
  516 
  517 static int rtw_ops_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
  518                            struct ieee80211_vif *vif, struct ieee80211_sta *sta,
  519                            struct ieee80211_key_conf *key)
  520 {
  521         struct rtw_dev *rtwdev = hw->priv;
  522         struct rtw_sec_desc *sec = &rtwdev->sec;
  523         u8 hw_key_type;
  524         u8 hw_key_idx;
  525         int ret = 0;
  526 
  527         switch (key->cipher) {
  528         case WLAN_CIPHER_SUITE_WEP40:
  529                 hw_key_type = RTW_CAM_WEP40;
  530                 break;
  531         case WLAN_CIPHER_SUITE_WEP104:
  532                 hw_key_type = RTW_CAM_WEP104;
  533                 break;
  534         case WLAN_CIPHER_SUITE_TKIP:
  535                 hw_key_type = RTW_CAM_TKIP;
  536                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
  537                 break;
  538         case WLAN_CIPHER_SUITE_CCMP:
  539                 hw_key_type = RTW_CAM_AES;
  540                 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
  541                 break;
  542         case WLAN_CIPHER_SUITE_AES_CMAC:
  543         case WLAN_CIPHER_SUITE_BIP_CMAC_256:
  544         case WLAN_CIPHER_SUITE_BIP_GMAC_128:
  545         case WLAN_CIPHER_SUITE_BIP_GMAC_256:
  546         case WLAN_CIPHER_SUITE_CCMP_256:
  547         case WLAN_CIPHER_SUITE_GCMP:
  548         case WLAN_CIPHER_SUITE_GCMP_256:
  549                 /* suppress error messages */
  550                 return -EOPNOTSUPP;
  551         default:
  552                 return -ENOTSUPP;
  553         }
  554 
  555         mutex_lock(&rtwdev->mutex);
  556 
  557         rtw_leave_lps_deep(rtwdev);
  558 
  559         if (key->flags & IEEE80211_KEY_FLAG_PAIRWISE) {
  560                 hw_key_idx = rtw_sec_get_free_cam(sec);
  561         } else {
  562                 /* multiple interfaces? */
  563                 hw_key_idx = key->keyidx;
  564         }
  565 
  566         if (hw_key_idx > sec->total_cam_num) {
  567                 ret = -ENOSPC;
  568                 goto out;
  569         }
  570 
  571         switch (cmd) {
  572         case SET_KEY:
  573                 /* need sw generated IV */
  574                 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
  575                 key->hw_key_idx = hw_key_idx;
  576                 rtw_sec_write_cam(rtwdev, sec, sta, key,
  577                                   hw_key_type, hw_key_idx);
  578                 break;
  579         case DISABLE_KEY:
  580                 rtw_hci_flush_all_queues(rtwdev, false);
  581                 rtw_mac_flush_all_queues(rtwdev, false);
  582                 rtw_sec_clear_cam(rtwdev, sec, key->hw_key_idx);
  583                 break;
  584         }
  585 
  586         /* download new cam settings for PG to backup */
  587         if (rtw_get_lps_deep_mode(rtwdev) == LPS_DEEP_MODE_PG)
  588                 rtw_fw_download_rsvd_page(rtwdev);
  589 
  590 out:
  591         mutex_unlock(&rtwdev->mutex);
  592 
  593         return ret;
  594 }
  595 
  596 static int rtw_ops_ampdu_action(struct ieee80211_hw *hw,
  597                                 struct ieee80211_vif *vif,
  598                                 struct ieee80211_ampdu_params *params)
  599 {
  600         struct ieee80211_sta *sta = params->sta;
  601         u16 tid = params->tid;
  602         struct ieee80211_txq *txq = sta->txq[tid];
  603         struct rtw_txq *rtwtxq = (struct rtw_txq *)txq->drv_priv;
  604 
  605         switch (params->action) {
  606         case IEEE80211_AMPDU_TX_START:
  607                 return IEEE80211_AMPDU_TX_START_IMMEDIATE;
  608         case IEEE80211_AMPDU_TX_STOP_CONT:
  609         case IEEE80211_AMPDU_TX_STOP_FLUSH:
  610         case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
  611                 clear_bit(RTW_TXQ_AMPDU, &rtwtxq->flags);
  612                 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
  613                 break;
  614         case IEEE80211_AMPDU_TX_OPERATIONAL:
  615                 set_bit(RTW_TXQ_AMPDU, &rtwtxq->flags);
  616                 break;
  617         case IEEE80211_AMPDU_RX_START:
  618         case IEEE80211_AMPDU_RX_STOP:
  619                 break;
  620         default:
  621                 WARN_ON(1);
  622                 return -ENOTSUPP;
  623         }
  624 
  625         return 0;
  626 }
  627 
  628 static bool rtw_ops_can_aggregate_in_amsdu(struct ieee80211_hw *hw,
  629                                            struct sk_buff *head,
  630                                            struct sk_buff *skb)
  631 {
  632         struct rtw_dev *rtwdev = hw->priv;
  633         struct rtw_hal *hal = &rtwdev->hal;
  634 
  635         /* we don't want to enable TX AMSDU on 2.4G */
  636         if (hal->current_band_type == RTW_BAND_2G)
  637                 return false;
  638 
  639         return true;
  640 }
  641 
  642 static void rtw_ops_sw_scan_start(struct ieee80211_hw *hw,
  643                                   struct ieee80211_vif *vif,
  644                                   const u8 *mac_addr)
  645 {
  646         struct rtw_dev *rtwdev = hw->priv;
  647         struct rtw_vif *rtwvif = (struct rtw_vif *)vif->drv_priv;
  648 
  649         mutex_lock(&rtwdev->mutex);
  650         rtw_core_scan_start(rtwdev, rtwvif, mac_addr, false);
  651         mutex_unlock(&rtwdev->mutex);
  652 }
  653 
  654 static void rtw_ops_sw_scan_complete(struct ieee80211_hw *hw,
  655                                      struct ieee80211_vif *vif)
  656 {
  657         struct rtw_dev *rtwdev = hw->priv;
  658 
  659         mutex_lock(&rtwdev->mutex);
  660         rtw_core_scan_complete(rtwdev, vif, false);
  661         mutex_unlock(&rtwdev->mutex);
  662 }
  663 
  664 static void rtw_ops_mgd_prepare_tx(struct ieee80211_hw *hw,
  665                                    struct ieee80211_vif *vif,
  666                                    struct ieee80211_prep_tx_info *info)
  667 {
  668         struct rtw_dev *rtwdev = hw->priv;
  669 
  670         mutex_lock(&rtwdev->mutex);
  671         rtw_leave_lps_deep(rtwdev);
  672         rtw_coex_connect_notify(rtwdev, COEX_ASSOCIATE_START);
  673         rtw_chip_prepare_tx(rtwdev);
  674         mutex_unlock(&rtwdev->mutex);
  675 }
  676 
  677 static int rtw_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
  678 {
  679         struct rtw_dev *rtwdev = hw->priv;
  680 
  681         mutex_lock(&rtwdev->mutex);
  682         rtwdev->rts_threshold = value;
  683         mutex_unlock(&rtwdev->mutex);
  684 
  685         return 0;
  686 }
  687 
  688 static void rtw_ops_sta_statistics(struct ieee80211_hw *hw,
  689                                    struct ieee80211_vif *vif,
  690                                    struct ieee80211_sta *sta,
  691                                    struct station_info *sinfo)
  692 {
  693         struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
  694 
  695         sinfo->txrate = si->ra_report.txrate;
  696         sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
  697 }
  698 
  699 static void rtw_ops_flush(struct ieee80211_hw *hw,
  700                           struct ieee80211_vif *vif,
  701                           u32 queues, bool drop)
  702 {
  703         struct rtw_dev *rtwdev = hw->priv;
  704 
  705         mutex_lock(&rtwdev->mutex);
  706         rtw_leave_lps_deep(rtwdev);
  707 
  708         rtw_hci_flush_queues(rtwdev, queues, drop);
  709         rtw_mac_flush_queues(rtwdev, queues, drop);
  710         mutex_unlock(&rtwdev->mutex);
  711 }
  712 
  713 struct rtw_iter_bitrate_mask_data {
  714         struct rtw_dev *rtwdev;
  715         struct ieee80211_vif *vif;
  716         const struct cfg80211_bitrate_mask *mask;
  717 };
  718 
  719 static void rtw_ra_mask_info_update_iter(void *data, struct ieee80211_sta *sta)
  720 {
  721         struct rtw_iter_bitrate_mask_data *br_data = data;
  722         struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
  723 
  724         if (si->vif != br_data->vif)
  725                 return;
  726 
  727         /* free previous mask setting */
  728         kfree(si->mask);
  729         si->mask = kmemdup(br_data->mask, sizeof(struct cfg80211_bitrate_mask),
  730                            GFP_ATOMIC);
  731         if (!si->mask) {
  732                 si->use_cfg_mask = false;
  733                 return;
  734         }
  735 
  736         si->use_cfg_mask = true;
  737         rtw_update_sta_info(br_data->rtwdev, si, true);
  738 }
  739 
  740 static void rtw_ra_mask_info_update(struct rtw_dev *rtwdev,
  741                                     struct ieee80211_vif *vif,
  742                                     const struct cfg80211_bitrate_mask *mask)
  743 {
  744         struct rtw_iter_bitrate_mask_data br_data;
  745 
  746         br_data.rtwdev = rtwdev;
  747         br_data.vif = vif;
  748         br_data.mask = mask;
  749         rtw_iterate_stas_atomic(rtwdev, rtw_ra_mask_info_update_iter, &br_data);
  750 }
  751 
  752 static int rtw_ops_set_bitrate_mask(struct ieee80211_hw *hw,
  753                                     struct ieee80211_vif *vif,
  754                                     const struct cfg80211_bitrate_mask *mask)
  755 {
  756         struct rtw_dev *rtwdev = hw->priv;
  757 
  758         rtw_ra_mask_info_update(rtwdev, vif, mask);
  759 
  760         return 0;
  761 }
  762 
  763 static int rtw_ops_set_antenna(struct ieee80211_hw *hw,
  764                                u32 tx_antenna,
  765                                u32 rx_antenna)
  766 {
  767         struct rtw_dev *rtwdev = hw->priv;
  768         struct rtw_chip_info *chip = rtwdev->chip;
  769         int ret;
  770 
  771         if (!chip->ops->set_antenna)
  772                 return -EOPNOTSUPP;
  773 
  774         mutex_lock(&rtwdev->mutex);
  775         ret = chip->ops->set_antenna(rtwdev, tx_antenna, rx_antenna);
  776         mutex_unlock(&rtwdev->mutex);
  777 
  778         return ret;
  779 }
  780 
  781 static int rtw_ops_get_antenna(struct ieee80211_hw *hw,
  782                                u32 *tx_antenna,
  783                                u32 *rx_antenna)
  784 {
  785         struct rtw_dev *rtwdev = hw->priv;
  786         struct rtw_hal *hal = &rtwdev->hal;
  787 
  788         *tx_antenna = hal->antenna_tx;
  789         *rx_antenna = hal->antenna_rx;
  790 
  791         return 0;
  792 }
  793 
  794 #ifdef CONFIG_PM
  795 static int rtw_ops_suspend(struct ieee80211_hw *hw,
  796                            struct cfg80211_wowlan *wowlan)
  797 {
  798         struct rtw_dev *rtwdev = hw->priv;
  799         int ret;
  800 
  801         mutex_lock(&rtwdev->mutex);
  802         ret = rtw_wow_suspend(rtwdev, wowlan);
  803         if (ret)
  804                 rtw_err(rtwdev, "failed to suspend for wow %d\n", ret);
  805         mutex_unlock(&rtwdev->mutex);
  806 
  807         return ret ? 1 : 0;
  808 }
  809 
  810 static int rtw_ops_resume(struct ieee80211_hw *hw)
  811 {
  812         struct rtw_dev *rtwdev = hw->priv;
  813         int ret;
  814 
  815         mutex_lock(&rtwdev->mutex);
  816         ret = rtw_wow_resume(rtwdev);
  817         if (ret)
  818                 rtw_err(rtwdev, "failed to resume for wow %d\n", ret);
  819         mutex_unlock(&rtwdev->mutex);
  820 
  821         return ret ? 1 : 0;
  822 }
  823 
  824 static void rtw_ops_set_wakeup(struct ieee80211_hw *hw, bool enabled)
  825 {
  826         struct rtw_dev *rtwdev = hw->priv;
  827 
  828         device_set_wakeup_enable(rtwdev->dev, enabled);
  829 }
  830 #endif
  831 
  832 static void rtw_reconfig_complete(struct ieee80211_hw *hw,
  833                                   enum ieee80211_reconfig_type reconfig_type)
  834 {
  835         struct rtw_dev *rtwdev = hw->priv;
  836 
  837         mutex_lock(&rtwdev->mutex);
  838         if (reconfig_type == IEEE80211_RECONFIG_TYPE_RESTART)
  839                 clear_bit(RTW_FLAG_RESTARTING, rtwdev->flags);
  840         mutex_unlock(&rtwdev->mutex);
  841 }
  842 
  843 static int rtw_ops_hw_scan(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
  844                            struct ieee80211_scan_request *req)
  845 {
  846         struct rtw_dev *rtwdev = hw->priv;
  847         int ret;
  848 
  849         if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD))
  850                 return 1;
  851 
  852         if (test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
  853                 return -EBUSY;
  854 
  855         mutex_lock(&rtwdev->mutex);
  856         rtw_hw_scan_start(rtwdev, vif, req);
  857         ret = rtw_hw_scan_offload(rtwdev, vif, true);
  858         if (ret) {
  859                 rtw_hw_scan_abort(rtwdev, vif);
  860                 rtw_err(rtwdev, "HW scan failed with status: %d\n", ret);
  861         }
  862         mutex_unlock(&rtwdev->mutex);
  863 
  864         return ret;
  865 }
  866 
  867 static void rtw_ops_cancel_hw_scan(struct ieee80211_hw *hw,
  868                                    struct ieee80211_vif *vif)
  869 {
  870         struct rtw_dev *rtwdev = hw->priv;
  871 
  872         if (!rtw_fw_feature_check(&rtwdev->fw, FW_FEATURE_SCAN_OFFLOAD))
  873                 return;
  874 
  875         if (!test_bit(RTW_FLAG_SCANNING, rtwdev->flags))
  876                 return;
  877 
  878         mutex_lock(&rtwdev->mutex);
  879         rtw_hw_scan_abort(rtwdev, vif);
  880         mutex_unlock(&rtwdev->mutex);
  881 }
  882 
  883 static int rtw_ops_set_sar_specs(struct ieee80211_hw *hw,
  884                                  const struct cfg80211_sar_specs *sar)
  885 {
  886         struct rtw_dev *rtwdev = hw->priv;
  887 
  888         rtw_set_sar_specs(rtwdev, sar);
  889 
  890         return 0;
  891 }
  892 
  893 static void rtw_ops_sta_rc_update(struct ieee80211_hw *hw,
  894                                   struct ieee80211_vif *vif,
  895                                   struct ieee80211_sta *sta, u32 changed)
  896 {
  897         struct rtw_dev *rtwdev = hw->priv;
  898         struct rtw_sta_info *si = (struct rtw_sta_info *)sta->drv_priv;
  899 
  900         if (changed & IEEE80211_RC_BW_CHANGED)
  901                 rtw_update_sta_info(rtwdev, si, true);
  902 }
  903 
  904 const struct ieee80211_ops rtw_ops = {
  905         .tx                     = rtw_ops_tx,
  906         .wake_tx_queue          = rtw_ops_wake_tx_queue,
  907         .start                  = rtw_ops_start,
  908         .stop                   = rtw_ops_stop,
  909         .config                 = rtw_ops_config,
  910         .add_interface          = rtw_ops_add_interface,
  911         .remove_interface       = rtw_ops_remove_interface,
  912         .change_interface       = rtw_ops_change_interface,
  913         .configure_filter       = rtw_ops_configure_filter,
  914         .bss_info_changed       = rtw_ops_bss_info_changed,
  915         .start_ap               = rtw_ops_start_ap,
  916         .conf_tx                = rtw_ops_conf_tx,
  917         .sta_add                = rtw_ops_sta_add,
  918         .sta_remove             = rtw_ops_sta_remove,
  919         .set_tim                = rtw_ops_set_tim,
  920         .set_key                = rtw_ops_set_key,
  921         .ampdu_action           = rtw_ops_ampdu_action,
  922         .can_aggregate_in_amsdu = rtw_ops_can_aggregate_in_amsdu,
  923         .sw_scan_start          = rtw_ops_sw_scan_start,
  924         .sw_scan_complete       = rtw_ops_sw_scan_complete,
  925         .mgd_prepare_tx         = rtw_ops_mgd_prepare_tx,
  926         .set_rts_threshold      = rtw_ops_set_rts_threshold,
  927         .sta_statistics         = rtw_ops_sta_statistics,
  928         .flush                  = rtw_ops_flush,
  929         .set_bitrate_mask       = rtw_ops_set_bitrate_mask,
  930         .set_antenna            = rtw_ops_set_antenna,
  931         .get_antenna            = rtw_ops_get_antenna,
  932         .reconfig_complete      = rtw_reconfig_complete,
  933         .hw_scan                = rtw_ops_hw_scan,
  934         .cancel_hw_scan         = rtw_ops_cancel_hw_scan,
  935         .sta_rc_update          = rtw_ops_sta_rc_update,
  936         .set_sar_specs          = rtw_ops_set_sar_specs,
  937 #ifdef CONFIG_PM
  938         .suspend                = rtw_ops_suspend,
  939         .resume                 = rtw_ops_resume,
  940         .set_wakeup             = rtw_ops_set_wakeup,
  941 #endif
  942 };
  943 EXPORT_SYMBOL(rtw_ops);

Cache object: 8eda9a9583a92f046a25669b79158463


[ 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.