LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - init.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 318 479 66.4 %
Date: 2022-03-28 13:20:08 Functions: 15 22 68.2 %
Branches: 88 192 45.8 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008-2011 Atheros Communications Inc.
       3                 :            :  *
       4                 :            :  * Permission to use, copy, modify, and/or distribute this software for any
       5                 :            :  * purpose with or without fee is hereby granted, provided that the above
       6                 :            :  * copyright notice and this permission notice appear in all copies.
       7                 :            :  *
       8                 :            :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       9                 :            :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10                 :            :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11                 :            :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12                 :            :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13                 :            :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14                 :            :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15                 :            :  */
      16                 :            : 
      17                 :            : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
      18                 :            : 
      19                 :            : #include <linux/dma-mapping.h>
      20                 :            : #include <linux/slab.h>
      21                 :            : #include <linux/ath9k_platform.h>
      22                 :            : #include <linux/module.h>
      23                 :            : #include <linux/of.h>
      24                 :            : #include <linux/of_net.h>
      25                 :            : #include <linux/relay.h>
      26                 :            : #include <linux/dmi.h>
      27                 :            : #include <net/ieee80211_radiotap.h>
      28                 :            : 
      29                 :            : #include "ath9k.h"
      30                 :            : 
      31                 :            : struct ath9k_eeprom_ctx {
      32                 :            :         struct completion complete;
      33                 :            :         struct ath_hw *ah;
      34                 :            : };
      35                 :            : 
      36                 :            : static char *dev_info = "ath9k";
      37                 :            : 
      38                 :            : MODULE_AUTHOR("Atheros Communications");
      39                 :            : MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
      40                 :            : MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
      41                 :            : MODULE_LICENSE("Dual BSD/GPL");
      42                 :            : 
      43                 :            : static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
      44                 :            : module_param_named(debug, ath9k_debug, uint, 0);
      45                 :            : MODULE_PARM_DESC(debug, "Debugging mask");
      46                 :            : 
      47                 :            : int ath9k_modparam_nohwcrypt;
      48                 :            : module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
      49                 :            : MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
      50                 :            : 
      51                 :            : int ath9k_led_blink;
      52                 :            : module_param_named(blink, ath9k_led_blink, int, 0444);
      53                 :            : MODULE_PARM_DESC(blink, "Enable LED blink on activity");
      54                 :            : 
      55                 :            : static int ath9k_led_active_high = -1;
      56                 :            : module_param_named(led_active_high, ath9k_led_active_high, int, 0444);
      57                 :            : MODULE_PARM_DESC(led_active_high, "Invert LED polarity");
      58                 :            : 
      59                 :            : static int ath9k_btcoex_enable;
      60                 :            : module_param_named(btcoex_enable, ath9k_btcoex_enable, int, 0444);
      61                 :            : MODULE_PARM_DESC(btcoex_enable, "Enable wifi-BT coexistence");
      62                 :            : 
      63                 :            : static int ath9k_bt_ant_diversity;
      64                 :            : module_param_named(bt_ant_diversity, ath9k_bt_ant_diversity, int, 0444);
      65                 :            : MODULE_PARM_DESC(bt_ant_diversity, "Enable WLAN/BT RX antenna diversity");
      66                 :            : 
      67                 :            : static int ath9k_ps_enable;
      68                 :            : module_param_named(ps_enable, ath9k_ps_enable, int, 0444);
      69                 :            : MODULE_PARM_DESC(ps_enable, "Enable WLAN PowerSave");
      70                 :            : 
      71                 :            : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
      72                 :            : 
      73                 :            : int ath9k_use_chanctx;
      74                 :            : module_param_named(use_chanctx, ath9k_use_chanctx, int, 0444);
      75                 :            : MODULE_PARM_DESC(use_chanctx, "Enable channel context for concurrency");
      76                 :            : 
      77                 :            : #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
      78                 :            : 
      79                 :            : int ath9k_use_msi;
      80                 :            : module_param_named(use_msi, ath9k_use_msi, int, 0444);
      81                 :            : MODULE_PARM_DESC(use_msi, "Use MSI instead of INTx if possible");
      82                 :            : 
      83                 :            : bool is_ath9k_unloaded;
      84                 :            : 
      85                 :            : #ifdef CONFIG_MAC80211_LEDS
      86                 :            : static const struct ieee80211_tpt_blink ath9k_tpt_blink[] = {
      87                 :            :         { .throughput = 0 * 1024, .blink_time = 334 },
      88                 :            :         { .throughput = 1 * 1024, .blink_time = 260 },
      89                 :            :         { .throughput = 5 * 1024, .blink_time = 220 },
      90                 :            :         { .throughput = 10 * 1024, .blink_time = 190 },
      91                 :            :         { .throughput = 20 * 1024, .blink_time = 170 },
      92                 :            :         { .throughput = 50 * 1024, .blink_time = 150 },
      93                 :            :         { .throughput = 70 * 1024, .blink_time = 130 },
      94                 :            :         { .throughput = 100 * 1024, .blink_time = 110 },
      95                 :            :         { .throughput = 200 * 1024, .blink_time = 80 },
      96                 :            :         { .throughput = 300 * 1024, .blink_time = 50 },
      97                 :            : };
      98                 :            : #endif
      99                 :            : 
     100                 :          0 : static int __init set_use_msi(const struct dmi_system_id *dmi)
     101                 :            : {
     102                 :          0 :         ath9k_use_msi = 1;
     103                 :          0 :         return 1;
     104                 :            : }
     105                 :            : 
     106                 :            : static const struct dmi_system_id ath9k_quirks[] __initconst = {
     107                 :            :         {
     108                 :            :                 .callback = set_use_msi,
     109                 :            :                 .ident = "Dell Inspiron 24-3460",
     110                 :            :                 .matches = {
     111                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
     112                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 24-3460"),
     113                 :            :                 },
     114                 :            :         },
     115                 :            :         {
     116                 :            :                 .callback = set_use_msi,
     117                 :            :                 .ident = "Dell Vostro 3262",
     118                 :            :                 .matches = {
     119                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
     120                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 3262"),
     121                 :            :                 },
     122                 :            :         },
     123                 :            :         {
     124                 :            :                 .callback = set_use_msi,
     125                 :            :                 .ident = "Dell Inspiron 3472",
     126                 :            :                 .matches = {
     127                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
     128                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 3472"),
     129                 :            :                 },
     130                 :            :         },
     131                 :            :         {
     132                 :            :                 .callback = set_use_msi,
     133                 :            :                 .ident = "Dell Vostro 15-3572",
     134                 :            :                 .matches = {
     135                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
     136                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Vostro 15-3572"),
     137                 :            :                 },
     138                 :            :         },
     139                 :            :         {
     140                 :            :                 .callback = set_use_msi,
     141                 :            :                 .ident = "Dell Inspiron 14-3473",
     142                 :            :                 .matches = {
     143                 :            :                         DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
     144                 :            :                         DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 14-3473"),
     145                 :            :                 },
     146                 :            :         },
     147                 :            :         {}
     148                 :            : };
     149                 :            : 
     150                 :            : static void ath9k_deinit_softc(struct ath_softc *sc);
     151                 :            : 
     152                 :          0 : static void ath9k_op_ps_wakeup(struct ath_common *common)
     153                 :            : {
     154                 :          0 :         ath9k_ps_wakeup((struct ath_softc *) common->priv);
     155                 :          0 : }
     156                 :            : 
     157                 :          0 : static void ath9k_op_ps_restore(struct ath_common *common)
     158                 :            : {
     159                 :          0 :         ath9k_ps_restore((struct ath_softc *) common->priv);
     160                 :          0 : }
     161                 :            : 
     162                 :            : static const struct ath_ps_ops ath9k_ps_ops = {
     163                 :            :         .wakeup = ath9k_op_ps_wakeup,
     164                 :            :         .restore = ath9k_op_ps_restore,
     165                 :            : };
     166                 :            : 
     167                 :            : /*
     168                 :            :  * Read and write, they both share the same lock. We do this to serialize
     169                 :            :  * reads and writes on Atheros 802.11n PCI devices only. This is required
     170                 :            :  * as the FIFO on these devices can only accept sanely 2 requests.
     171                 :            :  */
     172                 :            : 
     173                 :      88351 : static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
     174                 :            : {
     175                 :      88351 :         struct ath_hw *ah = hw_priv;
     176         [ -  + ]:      88351 :         struct ath_common *common = ath9k_hw_common(ah);
     177                 :      88351 :         struct ath_softc *sc = (struct ath_softc *) common->priv;
     178                 :            : 
     179         [ -  + ]:      88351 :         if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
     180                 :          0 :                 unsigned long flags;
     181                 :          0 :                 spin_lock_irqsave(&sc->sc_serial_rw, flags);
     182                 :          0 :                 iowrite32(val, sc->mem + reg_offset);
     183                 :          0 :                 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
     184                 :            :         } else
     185                 :      88351 :                 iowrite32(val, sc->mem + reg_offset);
     186                 :      88351 : }
     187                 :            : 
     188                 :      62216 : static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
     189                 :            : {
     190                 :      62216 :         struct ath_hw *ah = hw_priv;
     191         [ -  + ]:      62216 :         struct ath_common *common = ath9k_hw_common(ah);
     192                 :      62216 :         struct ath_softc *sc = (struct ath_softc *) common->priv;
     193                 :      62216 :         u32 val;
     194                 :            : 
     195         [ -  + ]:      62216 :         if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
     196                 :          0 :                 unsigned long flags;
     197                 :          0 :                 spin_lock_irqsave(&sc->sc_serial_rw, flags);
     198                 :          0 :                 val = ioread32(sc->mem + reg_offset);
     199                 :          0 :                 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
     200                 :            :         } else
     201                 :      62216 :                 val = ioread32(sc->mem + reg_offset);
     202                 :      62216 :         return val;
     203                 :            : }
     204                 :            : 
     205                 :        183 : static void ath9k_multi_ioread32(void *hw_priv, u32 *addr,
     206                 :            :                                 u32 *val, u16 count)
     207                 :            : {
     208                 :        183 :         int i;
     209                 :            : 
     210         [ +  + ]:       1098 :         for (i = 0; i < count; i++)
     211                 :        915 :                 val[i] = ath9k_ioread32(hw_priv, addr[i]);
     212                 :        183 : }
     213                 :            : 
     214                 :            : 
     215                 :            : static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
     216                 :            :                                     u32 set, u32 clr)
     217                 :            : {
     218                 :            :         u32 val;
     219                 :            : 
     220                 :            :         val = ioread32(sc->mem + reg_offset);
     221                 :            :         val &= ~clr;
     222                 :            :         val |= set;
     223                 :            :         iowrite32(val, sc->mem + reg_offset);
     224                 :            : 
     225                 :            :         return val;
     226                 :            : }
     227                 :            : 
     228                 :       8214 : static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
     229                 :            : {
     230                 :       8214 :         struct ath_hw *ah = hw_priv;
     231         [ -  + ]:       8214 :         struct ath_common *common = ath9k_hw_common(ah);
     232                 :       8214 :         struct ath_softc *sc = (struct ath_softc *) common->priv;
     233                 :       8214 :         unsigned long uninitialized_var(flags);
     234                 :       8214 :         u32 val;
     235                 :            : 
     236         [ -  + ]:       8214 :         if (NR_CPUS > 1 && ah->config.serialize_regmode == SER_REG_MODE_ON) {
     237                 :          0 :                 spin_lock_irqsave(&sc->sc_serial_rw, flags);
     238                 :          0 :                 val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
     239                 :          0 :                 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
     240                 :            :         } else
     241                 :       8214 :                 val = __ath9k_reg_rmw(sc, reg_offset, set, clr);
     242                 :            : 
     243                 :       8214 :         return val;
     244                 :            : }
     245                 :            : 
     246                 :            : /**************************/
     247                 :            : /*     Initialization     */
     248                 :            : /**************************/
     249                 :            : 
     250                 :          6 : static void ath9k_reg_notifier(struct wiphy *wiphy,
     251                 :            :                                struct regulatory_request *request)
     252                 :            : {
     253                 :          6 :         struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
     254                 :          6 :         struct ath_softc *sc = hw->priv;
     255                 :          6 :         struct ath_hw *ah = sc->sc_ah;
     256                 :          6 :         struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
     257                 :            : 
     258                 :          6 :         ath_reg_notifier_apply(wiphy, request, reg);
     259                 :            : 
     260                 :            :         /* synchronize DFS detector if regulatory domain changed */
     261         [ -  + ]:          6 :         if (sc->dfs_detector != NULL)
     262                 :          0 :                 sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
     263                 :            :                                                  request->dfs_region);
     264                 :            : 
     265                 :            :         /* Set tx power */
     266         [ -  + ]:          6 :         if (!ah->curchan)
     267                 :            :                 return;
     268                 :            : 
     269                 :          0 :         sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
     270                 :          0 :         ath9k_ps_wakeup(sc);
     271                 :          0 :         ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
     272                 :          0 :         ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
     273                 :          0 :                                sc->cur_chan->txpower,
     274                 :          0 :                                &sc->cur_chan->cur_txpower);
     275                 :          0 :         ath9k_ps_restore(sc);
     276                 :            : }
     277                 :            : 
     278                 :            : /*
     279                 :            :  *  This function will allocate both the DMA descriptor structure, and the
     280                 :            :  *  buffers it contains.  These are used to contain the descriptors used
     281                 :            :  *  by the system.
     282                 :            : */
     283                 :         14 : int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
     284                 :            :                       struct list_head *head, const char *name,
     285                 :            :                       int nbuf, int ndesc, bool is_tx)
     286                 :            : {
     287         [ -  + ]:         14 :         struct ath_common *common = ath9k_hw_common(sc->sc_ah);
     288                 :         14 :         u8 *ds;
     289                 :         14 :         int i, bsize, desc_len;
     290                 :            : 
     291         [ -  + ]:         14 :         ath_dbg(common, CONFIG, "%s DMA: %u buffers %u desc/buf\n",
     292                 :            :                 name, nbuf, ndesc);
     293                 :            : 
     294         [ +  + ]:         14 :         INIT_LIST_HEAD(head);
     295                 :            : 
     296         [ +  + ]:         14 :         if (is_tx)
     297                 :         12 :                 desc_len = sc->sc_ah->caps.tx_desc_len;
     298                 :            :         else
     299                 :            :                 desc_len = sizeof(struct ath_desc);
     300                 :            : 
     301                 :            :         /* ath_desc must be a multiple of DWORDs */
     302         [ -  + ]:         14 :         if ((desc_len % 4) != 0) {
     303                 :          0 :                 ath_err(common, "ath_desc not DWORD aligned\n");
     304                 :          0 :                 BUG_ON((desc_len % 4) != 0);
     305                 :            :                 return -ENOMEM;
     306                 :            :         }
     307                 :            : 
     308                 :         14 :         dd->dd_desc_len = desc_len * nbuf * ndesc;
     309                 :            : 
     310                 :            :         /*
     311                 :            :          * Need additional DMA memory because we can't use
     312                 :            :          * descriptors that cross the 4K page boundary. Assume
     313                 :            :          * one skipped descriptor per 4K page.
     314                 :            :          */
     315         [ -  + ]:         14 :         if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
     316                 :          0 :                 u32 ndesc_skipped =
     317                 :            :                         ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
     318                 :          0 :                 u32 dma_len;
     319                 :            : 
     320         [ #  # ]:          0 :                 while (ndesc_skipped) {
     321                 :          0 :                         dma_len = ndesc_skipped * desc_len;
     322                 :          0 :                         dd->dd_desc_len += dma_len;
     323                 :            : 
     324                 :          0 :                         ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
     325                 :            :                 }
     326                 :            :         }
     327                 :            : 
     328                 :            :         /* allocate descriptors */
     329                 :         14 :         dd->dd_desc = dmam_alloc_coherent(sc->dev, dd->dd_desc_len,
     330                 :            :                                           &dd->dd_desc_paddr, GFP_KERNEL);
     331         [ +  - ]:         14 :         if (!dd->dd_desc)
     332                 :            :                 return -ENOMEM;
     333                 :            : 
     334                 :         14 :         ds = dd->dd_desc;
     335         [ -  + ]:         14 :         ath_dbg(common, CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
     336                 :            :                 name, ds, (u32) dd->dd_desc_len,
     337                 :            :                 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
     338                 :            : 
     339                 :            :         /* allocate buffers */
     340         [ +  + ]:         14 :         if (is_tx) {
     341                 :         12 :                 struct ath_buf *bf;
     342                 :            : 
     343                 :         12 :                 bsize = sizeof(struct ath_buf) * nbuf;
     344                 :         12 :                 bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
     345         [ +  - ]:         12 :                 if (!bf)
     346                 :            :                         return -ENOMEM;
     347                 :            : 
     348         [ +  + ]:       3132 :                 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
     349                 :       3120 :                         bf->bf_desc = ds;
     350                 :       3120 :                         bf->bf_daddr = DS2PHYS(dd, ds);
     351                 :            : 
     352         [ -  + ]:       3120 :                         if (!(sc->sc_ah->caps.hw_caps &
     353                 :            :                                   ATH9K_HW_CAP_4KB_SPLITTRANS)) {
     354                 :            :                                 /*
     355                 :            :                                  * Skip descriptor addresses which can cause 4KB
     356                 :            :                                  * boundary crossing (addr + length) with a 32 dword
     357                 :            :                                  * descriptor fetch.
     358                 :            :                                  */
     359         [ #  # ]:          0 :                                 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
     360         [ #  # ]:          0 :                                         BUG_ON((caddr_t) bf->bf_desc >=
     361                 :            :                                                    ((caddr_t) dd->dd_desc +
     362                 :            :                                                 dd->dd_desc_len));
     363                 :            : 
     364                 :          0 :                                         ds += (desc_len * ndesc);
     365                 :          0 :                                         bf->bf_desc = ds;
     366                 :          0 :                                         bf->bf_daddr = DS2PHYS(dd, ds);
     367                 :            :                                 }
     368                 :            :                         }
     369                 :       3120 :                         list_add_tail(&bf->list, head);
     370                 :            :                 }
     371                 :            :         } else {
     372                 :          2 :                 struct ath_rxbuf *bf;
     373                 :            : 
     374                 :          2 :                 bsize = sizeof(struct ath_rxbuf) * nbuf;
     375                 :          2 :                 bf = devm_kzalloc(sc->dev, bsize, GFP_KERNEL);
     376         [ +  - ]:          2 :                 if (!bf)
     377                 :            :                         return -ENOMEM;
     378                 :            : 
     379         [ +  + ]:       1026 :                 for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
     380                 :       1024 :                         bf->bf_desc = ds;
     381                 :       1024 :                         bf->bf_daddr = DS2PHYS(dd, ds);
     382                 :            : 
     383         [ -  + ]:       1024 :                         if (!(sc->sc_ah->caps.hw_caps &
     384                 :            :                                   ATH9K_HW_CAP_4KB_SPLITTRANS)) {
     385                 :            :                                 /*
     386                 :            :                                  * Skip descriptor addresses which can cause 4KB
     387                 :            :                                  * boundary crossing (addr + length) with a 32 dword
     388                 :            :                                  * descriptor fetch.
     389                 :            :                                  */
     390         [ #  # ]:          0 :                                 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
     391         [ #  # ]:          0 :                                         BUG_ON((caddr_t) bf->bf_desc >=
     392                 :            :                                                    ((caddr_t) dd->dd_desc +
     393                 :            :                                                 dd->dd_desc_len));
     394                 :            : 
     395                 :          0 :                                         ds += (desc_len * ndesc);
     396                 :          0 :                                         bf->bf_desc = ds;
     397                 :          0 :                                         bf->bf_daddr = DS2PHYS(dd, ds);
     398                 :            :                                 }
     399                 :            :                         }
     400                 :       1024 :                         list_add_tail(&bf->list, head);
     401                 :            :                 }
     402                 :            :         }
     403                 :            :         return 0;
     404                 :            : }
     405                 :            : 
     406                 :          6 : static int ath9k_init_queues(struct ath_softc *sc)
     407                 :            : {
     408                 :          6 :         int i = 0;
     409                 :            : 
     410                 :          6 :         sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
     411                 :          6 :         sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
     412                 :          6 :         ath_cabq_update(sc);
     413                 :            : 
     414                 :          6 :         sc->tx.uapsdq = ath_txq_setup(sc, ATH9K_TX_QUEUE_UAPSD, 0);
     415                 :            : 
     416         [ +  + ]:         30 :         for (i = 0; i < IEEE80211_NUM_ACS; i++) {
     417                 :         24 :                 sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
     418                 :         24 :                 sc->tx.txq_map[i]->mac80211_qnum = i;
     419                 :            :         }
     420                 :          6 :         return 0;
     421                 :            : }
     422                 :            : 
     423                 :          6 : static void ath9k_init_misc(struct ath_softc *sc)
     424                 :            : {
     425                 :          6 :         struct ath_common *common = ath9k_hw_common(sc->sc_ah);
     426                 :          6 :         int i = 0;
     427                 :            : 
     428                 :          6 :         timer_setup(&common->ani.timer, ath_ani_calibrate, 0);
     429                 :            : 
     430                 :          6 :         common->last_rssi = ATH_RSSI_DUMMY_MARKER;
     431                 :          6 :         eth_broadcast_addr(common->bssidmask);
     432                 :          6 :         sc->beacon.slottime = 9;
     433                 :            : 
     434         [ +  + ]:         54 :         for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++)
     435                 :         48 :                 sc->beacon.bslot[i] = NULL;
     436                 :            : 
     437         [ -  + ]:          6 :         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
     438                 :          0 :                 sc->ant_comb.count = ATH_ANT_DIV_COMB_INIT_COUNT;
     439                 :            : 
     440                 :          6 :         sc->spec_priv.ah = sc->sc_ah;
     441                 :          6 :         sc->spec_priv.spec_config.enabled = 0;
     442                 :          6 :         sc->spec_priv.spec_config.short_repeat = true;
     443                 :          6 :         sc->spec_priv.spec_config.count = 8;
     444                 :          6 :         sc->spec_priv.spec_config.endless = false;
     445                 :          6 :         sc->spec_priv.spec_config.period = 0xFF;
     446                 :          6 :         sc->spec_priv.spec_config.fft_period = 0xF;
     447                 :          6 : }
     448                 :            : 
     449                 :         30 : static void ath9k_init_pcoem_platform(struct ath_softc *sc)
     450                 :            : {
     451                 :         30 :         struct ath_hw *ah = sc->sc_ah;
     452                 :         30 :         struct ath9k_hw_capabilities *pCap = &ah->caps;
     453         [ +  - ]:         30 :         struct ath_common *common = ath9k_hw_common(ah);
     454                 :            : 
     455                 :         30 :         if (!IS_ENABLED(CONFIG_ATH9K_PCOEM))
     456                 :            :                 return;
     457                 :            : 
     458         [ +  - ]:         30 :         if (common->bus_ops->ath_bus_type != ATH_PCI)
     459                 :            :                 return;
     460                 :            : 
     461         [ -  + ]:         30 :         if (sc->driver_data & (ATH9K_PCI_CUS198 |
     462                 :            :                                ATH9K_PCI_CUS230)) {
     463                 :          0 :                 ah->config.xlna_gpio = 9;
     464                 :          0 :                 ah->config.xatten_margin_cfg = true;
     465                 :          0 :                 ah->config.alt_mingainidx = true;
     466                 :          0 :                 ah->config.ant_ctrl_comm2g_switch_enable = 0x000BBB88;
     467                 :          0 :                 sc->ant_comb.low_rssi_thresh = 20;
     468                 :          0 :                 sc->ant_comb.fast_div_bias = 3;
     469                 :            : 
     470         [ #  # ]:          0 :                 ath_info(common, "Set parameters for %s\n",
     471                 :            :                          (sc->driver_data & ATH9K_PCI_CUS198) ?
     472                 :            :                          "CUS198" : "CUS230");
     473                 :            :         }
     474                 :            : 
     475         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_CUS217)
     476                 :          0 :                 ath_info(common, "CUS217 card detected\n");
     477                 :            : 
     478         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_CUS252)
     479                 :          0 :                 ath_info(common, "CUS252 card detected\n");
     480                 :            : 
     481         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_AR9565_1ANT)
     482                 :          0 :                 ath_info(common, "WB335 1-ANT card detected\n");
     483                 :            : 
     484         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_AR9565_2ANT)
     485                 :          0 :                 ath_info(common, "WB335 2-ANT card detected\n");
     486                 :            : 
     487         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_KILLER)
     488                 :          0 :                 ath_info(common, "Killer Wireless card detected\n");
     489                 :            : 
     490                 :            :         /*
     491                 :            :          * Some WB335 cards do not support antenna diversity. Since
     492                 :            :          * we use a hardcoded value for AR9565 instead of using the
     493                 :            :          * EEPROM/OTP data, remove the combining feature from
     494                 :            :          * the HW capabilities bitmap.
     495                 :            :          */
     496         [ -  + ]:         30 :         if (sc->driver_data & (ATH9K_PCI_AR9565_1ANT | ATH9K_PCI_AR9565_2ANT)) {
     497         [ #  # ]:          0 :                 if (!(sc->driver_data & ATH9K_PCI_BT_ANT_DIV))
     498                 :          0 :                         pCap->hw_caps &= ~ATH9K_HW_CAP_ANT_DIV_COMB;
     499                 :            :         }
     500                 :            : 
     501         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_BT_ANT_DIV) {
     502                 :          0 :                 pCap->hw_caps |= ATH9K_HW_CAP_BT_ANT_DIV;
     503                 :          0 :                 ath_info(common, "Set BT/WLAN RX diversity capability\n");
     504                 :            :         }
     505                 :            : 
     506         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_D3_L1_WAR) {
     507                 :          0 :                 ah->config.pcie_waen = 0x0040473b;
     508                 :          0 :                 ath_info(common, "Enable WAR for ASPM D3/L1\n");
     509                 :            :         }
     510                 :            : 
     511                 :            :         /*
     512                 :            :          * The default value of pll_pwrsave is 1.
     513                 :            :          * For certain AR9485 cards, it is set to 0.
     514                 :            :          * For AR9462, AR9565 it's set to 7.
     515                 :            :          */
     516                 :         30 :         ah->config.pll_pwrsave = 1;
     517                 :            : 
     518         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) {
     519                 :          0 :                 ah->config.pll_pwrsave = 0;
     520                 :          0 :                 ath_info(common, "Disable PLL PowerSave\n");
     521                 :            :         }
     522                 :            : 
     523         [ -  + ]:         30 :         if (sc->driver_data & ATH9K_PCI_LED_ACT_HI)
     524                 :          0 :                 ah->config.led_active_high = true;
     525                 :            : }
     526                 :            : 
     527                 :          0 : static void ath9k_eeprom_request_cb(const struct firmware *eeprom_blob,
     528                 :            :                                     void *ctx)
     529                 :            : {
     530                 :          0 :         struct ath9k_eeprom_ctx *ec = ctx;
     531                 :            : 
     532         [ #  # ]:          0 :         if (eeprom_blob)
     533                 :          0 :                 ec->ah->eeprom_blob = eeprom_blob;
     534                 :            : 
     535                 :          0 :         complete(&ec->complete);
     536                 :          0 : }
     537                 :            : 
     538                 :            : static int ath9k_eeprom_request(struct ath_softc *sc, const char *name)
     539                 :            : {
     540                 :            :         struct ath9k_eeprom_ctx ec;
     541                 :            :         struct ath_hw *ah = sc->sc_ah;
     542                 :            :         int err;
     543                 :            : 
     544                 :            :         /* try to load the EEPROM content asynchronously */
     545                 :            :         init_completion(&ec.complete);
     546                 :            :         ec.ah = sc->sc_ah;
     547                 :            : 
     548                 :            :         err = request_firmware_nowait(THIS_MODULE, 1, name, sc->dev, GFP_KERNEL,
     549                 :            :                                       &ec, ath9k_eeprom_request_cb);
     550                 :            :         if (err < 0) {
     551                 :            :                 ath_err(ath9k_hw_common(ah),
     552                 :            :                         "EEPROM request failed\n");
     553                 :            :                 return err;
     554                 :            :         }
     555                 :            : 
     556                 :            :         wait_for_completion(&ec.complete);
     557                 :            : 
     558                 :            :         if (!ah->eeprom_blob) {
     559                 :            :                 ath_err(ath9k_hw_common(ah),
     560                 :            :                         "Unable to load EEPROM file %s\n", name);
     561                 :            :                 return -EINVAL;
     562                 :            :         }
     563                 :            : 
     564                 :            :         return 0;
     565                 :            : }
     566                 :            : 
     567                 :         24 : static void ath9k_eeprom_release(struct ath_softc *sc)
     568                 :            : {
     569                 :         24 :         release_firmware(sc->sc_ah->eeprom_blob);
     570                 :            : }
     571                 :            : 
     572                 :         30 : static int ath9k_init_platform(struct ath_softc *sc)
     573                 :            : {
     574                 :         30 :         struct ath9k_platform_data *pdata = sc->dev->platform_data;
     575                 :         30 :         struct ath_hw *ah = sc->sc_ah;
     576         [ -  + ]:         30 :         struct ath_common *common = ath9k_hw_common(ah);
     577                 :         30 :         int ret;
     578                 :            : 
     579         [ -  + ]:         30 :         if (!pdata)
     580                 :            :                 return 0;
     581                 :            : 
     582         [ #  # ]:          0 :         if (!pdata->use_eeprom) {
     583                 :          0 :                 ah->ah_flags &= ~AH_USE_EEPROM;
     584                 :          0 :                 ah->gpio_mask = pdata->gpio_mask;
     585                 :          0 :                 ah->gpio_val = pdata->gpio_val;
     586                 :          0 :                 ah->led_pin = pdata->led_pin;
     587                 :          0 :                 ah->is_clk_25mhz = pdata->is_clk_25mhz;
     588                 :          0 :                 ah->get_mac_revision = pdata->get_mac_revision;
     589                 :          0 :                 ah->external_reset = pdata->external_reset;
     590                 :          0 :                 ah->disable_2ghz = pdata->disable_2ghz;
     591                 :          0 :                 ah->disable_5ghz = pdata->disable_5ghz;
     592                 :            : 
     593         [ #  # ]:          0 :                 if (!pdata->endian_check)
     594                 :          0 :                         ah->ah_flags |= AH_NO_EEP_SWAP;
     595                 :            :         }
     596                 :            : 
     597         [ #  # ]:          0 :         if (pdata->eeprom_name) {
     598                 :          0 :                 ret = ath9k_eeprom_request(sc, pdata->eeprom_name);
     599         [ #  # ]:          0 :                 if (ret)
     600                 :            :                         return ret;
     601                 :            :         }
     602                 :            : 
     603         [ #  # ]:          0 :         if (pdata->led_active_high)
     604                 :          0 :                 ah->config.led_active_high = true;
     605                 :            : 
     606         [ #  # ]:          0 :         if (pdata->tx_gain_buffalo)
     607                 :          0 :                 ah->config.tx_gain_buffalo = true;
     608                 :            : 
     609         [ #  # ]:          0 :         if (pdata->macaddr)
     610                 :          0 :                 ether_addr_copy(common->macaddr, pdata->macaddr);
     611                 :            : 
     612                 :            :         return 0;
     613                 :            : }
     614                 :            : 
     615                 :         30 : static int ath9k_of_init(struct ath_softc *sc)
     616                 :            : {
     617                 :         30 :         struct device_node *np = sc->dev->of_node;
     618                 :         30 :         struct ath_hw *ah = sc->sc_ah;
     619                 :         30 :         struct ath_common *common = ath9k_hw_common(ah);
     620                 :         30 :         enum ath_bus_type bus_type = common->bus_ops->ath_bus_type;
     621                 :         30 :         const char *mac;
     622                 :         30 :         char eeprom_name[100];
     623                 :         30 :         int ret;
     624                 :            : 
     625         [ -  + ]:         30 :         if (!of_device_is_available(np))
     626                 :         30 :                 return 0;
     627                 :            : 
     628                 :            :         ath_dbg(common, CONFIG, "parsing configuration from OF node\n");
     629                 :            : 
     630                 :            :         if (of_property_read_bool(np, "qca,no-eeprom")) {
     631                 :            :                 /* ath9k-eeprom-<bus>-<id>.bin */
     632                 :            :                 scnprintf(eeprom_name, sizeof(eeprom_name),
     633                 :            :                           "ath9k-eeprom-%s-%s.bin",
     634                 :            :                           ath_bus_type_to_string(bus_type), dev_name(ah->dev));
     635                 :            : 
     636                 :            :                 ret = ath9k_eeprom_request(sc, eeprom_name);
     637                 :            :                 if (ret)
     638                 :            :                         return ret;
     639                 :            : 
     640                 :            :                 ah->ah_flags &= ~AH_USE_EEPROM;
     641                 :            :                 ah->ah_flags |= AH_NO_EEP_SWAP;
     642                 :            :         }
     643                 :            : 
     644                 :            :         mac = of_get_mac_address(np);
     645                 :            :         if (!IS_ERR(mac))
     646                 :            :                 ether_addr_copy(common->macaddr, mac);
     647                 :            : 
     648                 :            :         return 0;
     649                 :            : }
     650                 :            : 
     651                 :         30 : static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
     652                 :            :                             const struct ath_bus_ops *bus_ops)
     653                 :            : {
     654                 :         30 :         struct ath_hw *ah = NULL;
     655                 :         30 :         struct ath9k_hw_capabilities *pCap;
     656                 :         30 :         struct ath_common *common;
     657                 :         30 :         int ret = 0, i;
     658                 :         30 :         int csz = 0;
     659                 :            : 
     660                 :         30 :         ah = devm_kzalloc(sc->dev, sizeof(struct ath_hw), GFP_KERNEL);
     661         [ +  - ]:         30 :         if (!ah)
     662                 :            :                 return -ENOMEM;
     663                 :            : 
     664                 :         30 :         ah->dev = sc->dev;
     665                 :         30 :         ah->hw = sc->hw;
     666                 :         30 :         ah->hw_version.devid = devid;
     667                 :         30 :         ah->ah_flags |= AH_USE_EEPROM;
     668                 :         30 :         ah->led_pin = -1;
     669                 :         30 :         ah->reg_ops.read = ath9k_ioread32;
     670                 :         30 :         ah->reg_ops.multi_read = ath9k_multi_ioread32;
     671                 :         30 :         ah->reg_ops.write = ath9k_iowrite32;
     672                 :         30 :         ah->reg_ops.rmw = ath9k_reg_rmw;
     673                 :         30 :         pCap = &ah->caps;
     674                 :            : 
     675                 :         30 :         common = ath9k_hw_common(ah);
     676                 :            : 
     677                 :            :         /* Will be cleared in ath9k_start() */
     678                 :         30 :         set_bit(ATH_OP_INVALID, &common->op_flags);
     679                 :            : 
     680                 :         30 :         sc->sc_ah = ah;
     681                 :         30 :         sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
     682                 :         30 :         sc->tx99_power = MAX_RATE_POWER + 1;
     683                 :         30 :         init_waitqueue_head(&sc->tx_wait);
     684                 :         30 :         sc->cur_chan = &sc->chanctx[0];
     685                 :         30 :         if (!ath9k_is_chanctx_enabled())
     686                 :         30 :                 sc->cur_chan->hw_queue_base = 0;
     687                 :            : 
     688                 :         30 :         common->ops = &ah->reg_ops;
     689                 :         30 :         common->bus_ops = bus_ops;
     690                 :         30 :         common->ps_ops = &ath9k_ps_ops;
     691                 :         30 :         common->ah = ah;
     692                 :         30 :         common->hw = sc->hw;
     693                 :         30 :         common->priv = sc;
     694                 :         30 :         common->debug_mask = ath9k_debug;
     695                 :         30 :         common->btcoex_enabled = ath9k_btcoex_enable == 1;
     696                 :         30 :         common->disable_ani = false;
     697                 :            : 
     698                 :            :         /*
     699                 :            :          * Platform quirks.
     700                 :            :          */
     701                 :         30 :         ath9k_init_pcoem_platform(sc);
     702                 :            : 
     703                 :         30 :         ret = ath9k_init_platform(sc);
     704         [ +  - ]:         30 :         if (ret)
     705                 :            :                 return ret;
     706                 :            : 
     707         [ -  + ]:         30 :         ret = ath9k_of_init(sc);
     708                 :         30 :         if (ret)
     709                 :            :                 return ret;
     710                 :            : 
     711         [ -  + ]:         30 :         if (ath9k_led_active_high != -1)
     712                 :          0 :                 ah->config.led_active_high = ath9k_led_active_high == 1;
     713                 :            : 
     714                 :            :         /*
     715                 :            :          * Enable WLAN/BT RX Antenna diversity only when:
     716                 :            :          *
     717                 :            :          * - BTCOEX is disabled.
     718                 :            :          * - the user manually requests the feature.
     719                 :            :          * - the HW cap is set using the platform data.
     720                 :            :          */
     721   [ +  -  -  + ]:         30 :         if (!common->btcoex_enabled && ath9k_bt_ant_diversity &&
     722         [ #  # ]:          0 :             (pCap->hw_caps & ATH9K_HW_CAP_BT_ANT_DIV))
     723                 :          0 :                 common->bt_ant_diversity = 1;
     724                 :            : 
     725                 :         30 :         spin_lock_init(&common->cc_lock);
     726                 :         30 :         spin_lock_init(&sc->intr_lock);
     727                 :         30 :         spin_lock_init(&sc->sc_serial_rw);
     728                 :         30 :         spin_lock_init(&sc->sc_pm_lock);
     729                 :         30 :         spin_lock_init(&sc->chan_lock);
     730                 :         30 :         mutex_init(&sc->mutex);
     731                 :         30 :         tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
     732                 :         30 :         tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
     733                 :            :                      (unsigned long)sc);
     734                 :            : 
     735                 :         30 :         timer_setup(&sc->sleep_timer, ath_ps_full_sleep, 0);
     736                 :         30 :         INIT_WORK(&sc->hw_reset_work, ath_reset_work);
     737                 :         30 :         INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
     738                 :         30 :         INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work);
     739                 :         30 :         INIT_DELAYED_WORK(&sc->hw_check_work, ath_hw_check_work);
     740                 :            : 
     741                 :         30 :         ath9k_init_channel_context(sc);
     742                 :            : 
     743                 :            :         /*
     744                 :            :          * Cache line size is used to size and align various
     745                 :            :          * structures used to communicate with the hardware.
     746                 :            :          */
     747                 :         30 :         ath_read_cachesize(common, &csz);
     748                 :         30 :         common->cachelsz = csz << 2; /* convert to bytes */
     749                 :            : 
     750                 :            :         /* Initializes the hardware for all supported chipsets */
     751                 :         30 :         ret = ath9k_hw_init(ah);
     752         [ +  + ]:         30 :         if (ret)
     753                 :         24 :                 goto err_hw;
     754                 :            : 
     755                 :          6 :         ret = ath9k_init_queues(sc);
     756         [ -  + ]:          6 :         if (ret)
     757                 :          0 :                 goto err_queues;
     758                 :            : 
     759                 :          6 :         ret =  ath9k_init_btcoex(sc);
     760         [ -  + ]:          6 :         if (ret)
     761                 :          0 :                 goto err_btcoex;
     762                 :            : 
     763                 :          6 :         ret = ath9k_cmn_init_channels_rates(common);
     764         [ -  + ]:          6 :         if (ret)
     765                 :          0 :                 goto err_btcoex;
     766                 :            : 
     767                 :          6 :         ret = ath9k_init_p2p(sc);
     768                 :          6 :         if (ret)
     769                 :            :                 goto err_btcoex;
     770                 :            : 
     771                 :          6 :         ath9k_cmn_init_crypto(sc->sc_ah);
     772                 :          6 :         ath9k_init_misc(sc);
     773                 :          6 :         ath_chanctx_init(sc);
     774         [ +  - ]:          6 :         ath9k_offchannel_init(sc);
     775                 :            : 
     776         [ +  - ]:          6 :         if (common->bus_ops->aspm_init)
     777                 :          6 :                 common->bus_ops->aspm_init(common);
     778                 :            : 
     779                 :            :         return 0;
     780                 :            : 
     781                 :          0 : err_btcoex:
     782         [ #  # ]:          0 :         for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
     783         [ #  # ]:          0 :                 if (ATH_TXQ_SETUP(sc, i))
     784                 :          0 :                         ath_tx_cleanupq(sc, &sc->tx.txq[i]);
     785                 :          0 : err_queues:
     786                 :          0 :         ath9k_hw_deinit(ah);
     787                 :         24 : err_hw:
     788                 :         24 :         ath9k_eeprom_release(sc);
     789                 :         24 :         dev_kfree_skb_any(sc->tx99_skb);
     790                 :         24 :         return ret;
     791                 :            : }
     792                 :            : 
     793                 :            : static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
     794                 :            : {
     795                 :            :         struct ieee80211_supported_band *sband;
     796                 :            :         struct ieee80211_channel *chan;
     797                 :            :         struct ath_hw *ah = sc->sc_ah;
     798                 :            :         struct ath_common *common = ath9k_hw_common(ah);
     799                 :            :         struct cfg80211_chan_def chandef;
     800                 :            :         int i;
     801                 :            : 
     802                 :            :         sband = &common->sbands[band];
     803                 :            :         for (i = 0; i < sband->n_channels; i++) {
     804                 :            :                 chan = &sband->channels[i];
     805                 :            :                 ah->curchan = &ah->channels[chan->hw_value];
     806                 :            :                 cfg80211_chandef_create(&chandef, chan, NL80211_CHAN_HT20);
     807                 :            :                 ath9k_cmn_get_channel(sc->hw, ah, &chandef);
     808                 :            :                 ath9k_hw_set_txpowerlimit(ah, MAX_COMBINED_POWER, true);
     809                 :            :         }
     810                 :            : }
     811                 :            : 
     812                 :          6 : static void ath9k_init_txpower_limits(struct ath_softc *sc)
     813                 :            : {
     814                 :          6 :         struct ath_hw *ah = sc->sc_ah;
     815                 :          6 :         struct ath9k_channel *curchan = ah->curchan;
     816                 :            : 
     817         [ +  - ]:          6 :         if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
     818                 :          6 :                 ath9k_init_band_txpower(sc, NL80211_BAND_2GHZ);
     819         [ +  + ]:          6 :         if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
     820                 :          4 :                 ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ);
     821                 :            : 
     822                 :          6 :         ah->curchan = curchan;
     823                 :          6 : }
     824                 :            : 
     825                 :            : static const struct ieee80211_iface_limit if_limits[] = {
     826                 :            :         { .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) },
     827                 :            :         { .max = 8,     .types =
     828                 :            : #ifdef CONFIG_MAC80211_MESH
     829                 :            :                                  BIT(NL80211_IFTYPE_MESH_POINT) |
     830                 :            : #endif
     831                 :            :                                  BIT(NL80211_IFTYPE_AP) },
     832                 :            :         { .max = 1,     .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
     833                 :            :                                  BIT(NL80211_IFTYPE_P2P_GO) },
     834                 :            : };
     835                 :            : 
     836                 :            : #ifdef CONFIG_WIRELESS_WDS
     837                 :            : static const struct ieee80211_iface_limit wds_limits[] = {
     838                 :            :         { .max = 2048,  .types = BIT(NL80211_IFTYPE_WDS) },
     839                 :            : };
     840                 :            : #endif
     841                 :            : 
     842                 :            : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
     843                 :            : 
     844                 :            : static const struct ieee80211_iface_limit if_limits_multi[] = {
     845                 :            :         { .max = 2,     .types = BIT(NL80211_IFTYPE_STATION) |
     846                 :            :                                  BIT(NL80211_IFTYPE_AP) |
     847                 :            :                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
     848                 :            :                                  BIT(NL80211_IFTYPE_P2P_GO) },
     849                 :            :         { .max = 1,     .types = BIT(NL80211_IFTYPE_ADHOC) },
     850                 :            :         { .max = 1,     .types = BIT(NL80211_IFTYPE_P2P_DEVICE) },
     851                 :            : };
     852                 :            : 
     853                 :            : static const struct ieee80211_iface_combination if_comb_multi[] = {
     854                 :            :         {
     855                 :            :                 .limits = if_limits_multi,
     856                 :            :                 .n_limits = ARRAY_SIZE(if_limits_multi),
     857                 :            :                 .max_interfaces = 3,
     858                 :            :                 .num_different_channels = 2,
     859                 :            :                 .beacon_int_infra_match = true,
     860                 :            :         },
     861                 :            : };
     862                 :            : 
     863                 :            : #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
     864                 :            : 
     865                 :            : static const struct ieee80211_iface_combination if_comb[] = {
     866                 :            :         {
     867                 :            :                 .limits = if_limits,
     868                 :            :                 .n_limits = ARRAY_SIZE(if_limits),
     869                 :            :                 .max_interfaces = 2048,
     870                 :            :                 .num_different_channels = 1,
     871                 :            :                 .beacon_int_infra_match = true,
     872                 :            : #ifdef CONFIG_ATH9K_DFS_CERTIFIED
     873                 :            :                 .radar_detect_widths =  BIT(NL80211_CHAN_WIDTH_20_NOHT) |
     874                 :            :                                         BIT(NL80211_CHAN_WIDTH_20) |
     875                 :            :                                         BIT(NL80211_CHAN_WIDTH_40),
     876                 :            : #endif
     877                 :            :         },
     878                 :            : #ifdef CONFIG_WIRELESS_WDS
     879                 :            :         {
     880                 :            :                 .limits = wds_limits,
     881                 :            :                 .n_limits = ARRAY_SIZE(wds_limits),
     882                 :            :                 .max_interfaces = 2048,
     883                 :            :                 .num_different_channels = 1,
     884                 :            :                 .beacon_int_infra_match = true,
     885                 :            :         },
     886                 :            : #endif
     887                 :            : };
     888                 :            : 
     889                 :            : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
     890                 :            : static void ath9k_set_mcc_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
     891                 :            : {
     892                 :            :         struct ath_hw *ah = sc->sc_ah;
     893                 :            :         struct ath_common *common = ath9k_hw_common(ah);
     894                 :            : 
     895                 :            :         if (!ath9k_is_chanctx_enabled())
     896                 :            :                 return;
     897                 :            : 
     898                 :            :         ieee80211_hw_set(hw, QUEUE_CONTROL);
     899                 :            :         hw->queues = ATH9K_NUM_TX_QUEUES;
     900                 :            :         hw->offchannel_tx_hw_queue = hw->queues - 1;
     901                 :            :         hw->wiphy->interface_modes &= ~ BIT(NL80211_IFTYPE_WDS);
     902                 :            :         hw->wiphy->iface_combinations = if_comb_multi;
     903                 :            :         hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb_multi);
     904                 :            :         hw->wiphy->max_scan_ssids = 255;
     905                 :            :         hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
     906                 :            :         hw->wiphy->max_remain_on_channel_duration = 10000;
     907                 :            :         hw->chanctx_data_size = sizeof(void *);
     908                 :            :         hw->extra_beacon_tailroom =
     909                 :            :                 sizeof(struct ieee80211_p2p_noa_attr) + 9;
     910                 :            : 
     911                 :            :         ath_dbg(common, CHAN_CTX, "Use channel contexts\n");
     912                 :            : }
     913                 :            : #endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
     914                 :            : 
     915                 :          6 : static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
     916                 :            : {
     917                 :          6 :         struct ath_hw *ah = sc->sc_ah;
     918                 :          6 :         struct ath_common *common = ath9k_hw_common(ah);
     919                 :            : 
     920                 :          6 :         ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES);
     921                 :          6 :         ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
     922                 :          6 :         ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
     923                 :          6 :         ieee80211_hw_set(hw, SPECTRUM_MGMT);
     924                 :          6 :         ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
     925                 :          6 :         ieee80211_hw_set(hw, SIGNAL_DBM);
     926                 :          6 :         ieee80211_hw_set(hw, RX_INCLUDES_FCS);
     927                 :          6 :         ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
     928                 :          6 :         ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
     929                 :          6 :         ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
     930                 :            : 
     931         [ -  + ]:          6 :         if (ath9k_ps_enable)
     932                 :          0 :                 ieee80211_hw_set(hw, SUPPORTS_PS);
     933                 :            : 
     934         [ +  - ]:          6 :         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
     935                 :          6 :                 ieee80211_hw_set(hw, AMPDU_AGGREGATION);
     936                 :            : 
     937         [ +  + ]:          6 :                 if (AR_SREV_9280_20_OR_LATER(ah))
     938                 :          4 :                         hw->radiotap_mcs_details |=
     939                 :            :                                 IEEE80211_RADIOTAP_MCS_HAVE_STBC;
     940                 :            :         }
     941                 :            : 
     942   [ +  +  -  + ]:          6 :         if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
     943                 :          4 :                 ieee80211_hw_set(hw, MFP_CAPABLE);
     944                 :            : 
     945                 :          6 :         hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
     946                 :            :                                NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
     947                 :            :                                NL80211_FEATURE_P2P_GO_CTWIN;
     948                 :            : 
     949                 :          6 :         if (!IS_ENABLED(CONFIG_ATH9K_TX99)) {
     950                 :          6 :                 hw->wiphy->interface_modes =
     951                 :            :                         BIT(NL80211_IFTYPE_P2P_GO) |
     952                 :            :                         BIT(NL80211_IFTYPE_P2P_CLIENT) |
     953                 :            :                         BIT(NL80211_IFTYPE_AP) |
     954                 :            :                         BIT(NL80211_IFTYPE_STATION) |
     955                 :            :                         BIT(NL80211_IFTYPE_ADHOC) |
     956                 :            :                         BIT(NL80211_IFTYPE_MESH_POINT) |
     957                 :            : #ifdef CONFIG_WIRELESS_WDS
     958                 :            :                         BIT(NL80211_IFTYPE_WDS) |
     959                 :            : #endif
     960                 :            :                         BIT(NL80211_IFTYPE_OCB);
     961                 :            : 
     962         [ -  + ]:          6 :                 if (ath9k_is_chanctx_enabled())
     963                 :            :                         hw->wiphy->interface_modes |=
     964                 :            :                                         BIT(NL80211_IFTYPE_P2P_DEVICE);
     965                 :            : 
     966                 :          6 :                 hw->wiphy->iface_combinations = if_comb;
     967                 :          6 :                 hw->wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);
     968                 :            :         }
     969                 :            : 
     970                 :          6 :         hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
     971                 :            : 
     972                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
     973                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
     974                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
     975                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_5_10_MHZ;
     976                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
     977                 :          6 :         hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
     978                 :            : 
     979                 :          6 :         hw->queues = 4;
     980                 :          6 :         hw->max_rates = 4;
     981                 :          6 :         hw->max_listen_interval = 10;
     982                 :          6 :         hw->max_rate_tries = 10;
     983                 :          6 :         hw->sta_data_size = sizeof(struct ath_node);
     984                 :          6 :         hw->vif_data_size = sizeof(struct ath_vif);
     985                 :          6 :         hw->txq_data_size = sizeof(struct ath_atx_tid);
     986                 :          6 :         hw->extra_tx_headroom = 4;
     987                 :            : 
     988                 :          6 :         hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
     989                 :          6 :         hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;
     990                 :            : 
     991                 :            :         /* single chain devices with rx diversity */
     992         [ -  + ]:          6 :         if (ah->caps.hw_caps & ATH9K_HW_CAP_ANT_DIV_COMB)
     993                 :          0 :                 hw->wiphy->available_antennas_rx = BIT(0) | BIT(1);
     994                 :            : 
     995                 :          6 :         sc->ant_rx = hw->wiphy->available_antennas_rx;
     996                 :          6 :         sc->ant_tx = hw->wiphy->available_antennas_tx;
     997                 :            : 
     998         [ +  - ]:          6 :         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
     999                 :          6 :                 hw->wiphy->bands[NL80211_BAND_2GHZ] =
    1000                 :          6 :                         &common->sbands[NL80211_BAND_2GHZ];
    1001         [ +  + ]:          6 :         if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
    1002                 :          4 :                 hw->wiphy->bands[NL80211_BAND_5GHZ] =
    1003                 :          4 :                         &common->sbands[NL80211_BAND_5GHZ];
    1004                 :            : 
    1005                 :            : #ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
    1006                 :            :         ath9k_set_mcc_capab(sc, hw);
    1007                 :            : #endif
    1008                 :          6 :         ath9k_init_wow(hw);
    1009                 :          6 :         ath9k_cmn_reload_chainmask(ah);
    1010                 :            : 
    1011                 :          6 :         SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
    1012                 :            : 
    1013                 :          6 :         wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
    1014                 :          6 :         wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS);
    1015                 :          6 : }
    1016                 :            : 
    1017                 :         30 : int ath9k_init_device(u16 devid, struct ath_softc *sc,
    1018                 :            :                     const struct ath_bus_ops *bus_ops)
    1019                 :            : {
    1020                 :         30 :         struct ieee80211_hw *hw = sc->hw;
    1021                 :         30 :         struct ath_common *common;
    1022                 :         30 :         struct ath_hw *ah;
    1023                 :         30 :         int error = 0;
    1024                 :         30 :         struct ath_regulatory *reg;
    1025                 :            : 
    1026                 :            :         /* Bring up device */
    1027                 :         30 :         error = ath9k_init_softc(devid, sc, bus_ops);
    1028         [ +  + ]:         30 :         if (error)
    1029                 :            :                 return error;
    1030                 :            : 
    1031                 :          6 :         ah = sc->sc_ah;
    1032                 :          6 :         common = ath9k_hw_common(ah);
    1033                 :          6 :         ath9k_set_hw_capab(sc, hw);
    1034                 :            : 
    1035                 :            :         /* Initialize regulatory */
    1036                 :          6 :         error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
    1037                 :            :                               ath9k_reg_notifier);
    1038         [ -  + ]:          6 :         if (error)
    1039                 :          0 :                 goto deinit;
    1040                 :            : 
    1041                 :          6 :         reg = &common->regulatory;
    1042                 :            : 
    1043                 :            :         /* Setup TX DMA */
    1044                 :          6 :         error = ath_tx_init(sc, ATH_TXBUF);
    1045         [ -  + ]:          6 :         if (error != 0)
    1046                 :          0 :                 goto deinit;
    1047                 :            : 
    1048                 :            :         /* Setup RX DMA */
    1049                 :          6 :         error = ath_rx_init(sc, ATH_RXBUF);
    1050         [ -  + ]:          6 :         if (error != 0)
    1051                 :          0 :                 goto deinit;
    1052                 :            : 
    1053                 :          6 :         ath9k_init_txpower_limits(sc);
    1054                 :            : 
    1055                 :            : #ifdef CONFIG_MAC80211_LEDS
    1056                 :            :         /* must be initialized before ieee80211_register_hw */
    1057                 :          6 :         sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
    1058                 :            :                 IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
    1059                 :            :                 ARRAY_SIZE(ath9k_tpt_blink));
    1060                 :            : #endif
    1061                 :            : 
    1062                 :            :         /* Register with mac80211 */
    1063                 :          6 :         error = ieee80211_register_hw(hw);
    1064         [ -  + ]:          6 :         if (error)
    1065                 :          0 :                 goto rx_cleanup;
    1066                 :            : 
    1067                 :          6 :         error = ath9k_init_debug(ah);
    1068         [ -  + ]:          6 :         if (error) {
    1069                 :          0 :                 ath_err(common, "Unable to create debugfs files\n");
    1070                 :          0 :                 goto unregister;
    1071                 :            :         }
    1072                 :            : 
    1073                 :            :         /* Handle world regulatory */
    1074         [ -  + ]:          6 :         if (!ath_is_world_regd(reg)) {
    1075                 :          0 :                 error = regulatory_hint(hw->wiphy, reg->alpha2);
    1076         [ #  # ]:          0 :                 if (error)
    1077                 :          0 :                         goto debug_cleanup;
    1078                 :            :         }
    1079                 :            : 
    1080                 :          6 :         ath_init_leds(sc);
    1081                 :          6 :         ath_start_rfkill_poll(sc);
    1082                 :            : 
    1083                 :          6 :         return 0;
    1084                 :            : 
    1085                 :            : debug_cleanup:
    1086                 :          0 :         ath9k_deinit_debug(sc);
    1087                 :          0 : unregister:
    1088                 :          0 :         ieee80211_unregister_hw(hw);
    1089                 :          0 : rx_cleanup:
    1090                 :          0 :         ath_rx_cleanup(sc);
    1091                 :          0 : deinit:
    1092                 :          0 :         ath9k_deinit_softc(sc);
    1093                 :          0 :         return error;
    1094                 :            : }
    1095                 :            : 
    1096                 :            : /*****************************/
    1097                 :            : /*     De-Initialization     */
    1098                 :            : /*****************************/
    1099                 :            : 
    1100                 :          0 : static void ath9k_deinit_softc(struct ath_softc *sc)
    1101                 :            : {
    1102                 :          0 :         int i = 0;
    1103                 :            : 
    1104                 :          0 :         ath9k_deinit_p2p(sc);
    1105                 :          0 :         ath9k_deinit_btcoex(sc);
    1106                 :            : 
    1107         [ #  # ]:          0 :         for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
    1108         [ #  # ]:          0 :                 if (ATH_TXQ_SETUP(sc, i))
    1109                 :          0 :                         ath_tx_cleanupq(sc, &sc->tx.txq[i]);
    1110                 :            : 
    1111                 :          0 :         del_timer_sync(&sc->sleep_timer);
    1112                 :          0 :         ath9k_hw_deinit(sc->sc_ah);
    1113         [ #  # ]:          0 :         if (sc->dfs_detector != NULL)
    1114                 :          0 :                 sc->dfs_detector->exit(sc->dfs_detector);
    1115                 :            : 
    1116                 :          0 :         ath9k_eeprom_release(sc);
    1117                 :          0 : }
    1118                 :            : 
    1119                 :          0 : void ath9k_deinit_device(struct ath_softc *sc)
    1120                 :            : {
    1121                 :          0 :         struct ieee80211_hw *hw = sc->hw;
    1122                 :            : 
    1123                 :          0 :         ath9k_ps_wakeup(sc);
    1124                 :            : 
    1125                 :          0 :         wiphy_rfkill_stop_polling(sc->hw->wiphy);
    1126                 :          0 :         ath_deinit_leds(sc);
    1127                 :            : 
    1128                 :          0 :         ath9k_ps_restore(sc);
    1129                 :            : 
    1130                 :          0 :         ath9k_deinit_debug(sc);
    1131                 :          0 :         ath9k_deinit_wow(hw);
    1132                 :          0 :         ieee80211_unregister_hw(hw);
    1133                 :          0 :         ath_rx_cleanup(sc);
    1134                 :          0 :         ath9k_deinit_softc(sc);
    1135                 :          0 : }
    1136                 :            : 
    1137                 :            : /************************/
    1138                 :            : /*     Module Hooks     */
    1139                 :            : /************************/
    1140                 :            : 
    1141                 :         30 : static int __init ath9k_init(void)
    1142                 :            : {
    1143                 :         30 :         int error;
    1144                 :            : 
    1145                 :         30 :         error = ath_pci_init();
    1146         [ -  + ]:         30 :         if (error < 0) {
    1147                 :          0 :                 pr_err("No PCI devices found, driver not installed\n");
    1148                 :          0 :                 error = -ENODEV;
    1149                 :          0 :                 goto err_out;
    1150                 :            :         }
    1151                 :            : 
    1152                 :         30 :         error = ath_ahb_init();
    1153                 :         30 :         if (error < 0) {
    1154                 :            :                 error = -ENODEV;
    1155                 :            :                 goto err_pci_exit;
    1156                 :            :         }
    1157                 :            : 
    1158                 :         30 :         dmi_check_system(ath9k_quirks);
    1159                 :            : 
    1160                 :         30 :         return 0;
    1161                 :            : 
    1162                 :            :  err_pci_exit:
    1163                 :            :         ath_pci_exit();
    1164                 :            :  err_out:
    1165                 :          0 :         return error;
    1166                 :            : }
    1167                 :            : module_init(ath9k_init);
    1168                 :            : 
    1169                 :          0 : static void __exit ath9k_exit(void)
    1170                 :            : {
    1171                 :          0 :         is_ath9k_unloaded = true;
    1172                 :          0 :         ath_ahb_exit();
    1173                 :          0 :         ath_pci_exit();
    1174                 :          0 :         pr_info("%s: Driver unloaded\n", dev_info);
    1175                 :          0 : }
    1176                 :            : module_exit(ath9k_exit);

Generated by: LCOV version 1.14