Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Device probe and register.
0004  *
0005  * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
0006  * Copyright (c) 2010, ST-Ericsson
0007  * Copyright (c) 2008, Johannes Berg <johannes@sipsolutions.net>
0008  * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
0009  * Copyright (c) 2007-2009, Christian Lamparter <chunkeey@web.de>
0010  * Copyright (c) 2006, Michael Wu <flamingice@sourmilk.net>
0011  * Copyright (c) 2004-2006 Jean-Baptiste Note <jbnote@gmail.com>, et al.
0012  */
0013 #include <linux/module.h>
0014 #include <linux/of.h>
0015 #include <linux/of_net.h>
0016 #include <linux/gpio/consumer.h>
0017 #include <linux/mmc/sdio_func.h>
0018 #include <linux/spi/spi.h>
0019 #include <linux/etherdevice.h>
0020 #include <linux/firmware.h>
0021 
0022 #include "main.h"
0023 #include "wfx.h"
0024 #include "fwio.h"
0025 #include "hwio.h"
0026 #include "bus.h"
0027 #include "bh.h"
0028 #include "sta.h"
0029 #include "key.h"
0030 #include "scan.h"
0031 #include "debug.h"
0032 #include "data_tx.h"
0033 #include "hif_tx_mib.h"
0034 #include "hif_api_cmd.h"
0035 
0036 #define WFX_PDS_TLV_TYPE 0x4450 // "PD" (Platform Data) in ascii little-endian
0037 #define WFX_PDS_MAX_CHUNK_SIZE 1500
0038 
0039 MODULE_DESCRIPTION("Silicon Labs 802.11 Wireless LAN driver for WF200");
0040 MODULE_AUTHOR("Jérôme Pouiller <jerome.pouiller@silabs.com>");
0041 MODULE_LICENSE("GPL");
0042 
0043 #define RATETAB_ENT(_rate, _rateid, _flags) { \
0044     .bitrate  = (_rate),   \
0045     .hw_value = (_rateid), \
0046     .flags    = (_flags),  \
0047 }
0048 
0049 static struct ieee80211_rate wfx_rates[] = {
0050     RATETAB_ENT(10,  0,  0),
0051     RATETAB_ENT(20,  1,  IEEE80211_RATE_SHORT_PREAMBLE),
0052     RATETAB_ENT(55,  2,  IEEE80211_RATE_SHORT_PREAMBLE),
0053     RATETAB_ENT(110, 3,  IEEE80211_RATE_SHORT_PREAMBLE),
0054     RATETAB_ENT(60,  6,  0),
0055     RATETAB_ENT(90,  7,  0),
0056     RATETAB_ENT(120, 8,  0),
0057     RATETAB_ENT(180, 9,  0),
0058     RATETAB_ENT(240, 10, 0),
0059     RATETAB_ENT(360, 11, 0),
0060     RATETAB_ENT(480, 12, 0),
0061     RATETAB_ENT(540, 13, 0),
0062 };
0063 
0064 #define CHAN2G(_channel, _freq, _flags) { \
0065     .band = NL80211_BAND_2GHZ, \
0066     .center_freq = (_freq),    \
0067     .hw_value = (_channel),    \
0068     .flags = (_flags),         \
0069     .max_antenna_gain = 0,     \
0070     .max_power = 30,           \
0071 }
0072 
0073 static struct ieee80211_channel wfx_2ghz_chantable[] = {
0074     CHAN2G(1,  2412, 0),
0075     CHAN2G(2,  2417, 0),
0076     CHAN2G(3,  2422, 0),
0077     CHAN2G(4,  2427, 0),
0078     CHAN2G(5,  2432, 0),
0079     CHAN2G(6,  2437, 0),
0080     CHAN2G(7,  2442, 0),
0081     CHAN2G(8,  2447, 0),
0082     CHAN2G(9,  2452, 0),
0083     CHAN2G(10, 2457, 0),
0084     CHAN2G(11, 2462, 0),
0085     CHAN2G(12, 2467, 0),
0086     CHAN2G(13, 2472, 0),
0087     CHAN2G(14, 2484, 0),
0088 };
0089 
0090 static const struct ieee80211_supported_band wfx_band_2ghz = {
0091     .channels = wfx_2ghz_chantable,
0092     .n_channels = ARRAY_SIZE(wfx_2ghz_chantable),
0093     .bitrates = wfx_rates,
0094     .n_bitrates = ARRAY_SIZE(wfx_rates),
0095     .ht_cap = {
0096         /* Receive caps */
0097         .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 |
0098                IEEE80211_HT_CAP_MAX_AMSDU | (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT),
0099         .ht_supported = 1,
0100         .ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K,
0101         .ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE,
0102         .mcs = {
0103             .rx_mask = { 0xFF }, /* MCS0 to MCS7 */
0104             .rx_highest = cpu_to_le16(72),
0105             .tx_params = IEEE80211_HT_MCS_TX_DEFINED,
0106         },
0107     },
0108 };
0109 
0110 static const struct ieee80211_iface_limit wdev_iface_limits[] = {
0111     { .max = 1, .types = BIT(NL80211_IFTYPE_STATION) },
0112     { .max = 1, .types = BIT(NL80211_IFTYPE_AP) },
0113 };
0114 
0115 static const struct ieee80211_iface_combination wfx_iface_combinations[] = {
0116     {
0117         .num_different_channels = 2,
0118         .max_interfaces = 2,
0119         .limits = wdev_iface_limits,
0120         .n_limits = ARRAY_SIZE(wdev_iface_limits),
0121     }
0122 };
0123 
0124 static const struct ieee80211_ops wfx_ops = {
0125     .start                   = wfx_start,
0126     .stop                    = wfx_stop,
0127     .add_interface           = wfx_add_interface,
0128     .remove_interface        = wfx_remove_interface,
0129     .config                  = wfx_config,
0130     .tx                      = wfx_tx,
0131     .join_ibss               = wfx_join_ibss,
0132     .leave_ibss              = wfx_leave_ibss,
0133     .conf_tx                 = wfx_conf_tx,
0134     .hw_scan                 = wfx_hw_scan,
0135     .cancel_hw_scan          = wfx_cancel_hw_scan,
0136     .start_ap                = wfx_start_ap,
0137     .stop_ap                 = wfx_stop_ap,
0138     .sta_add                 = wfx_sta_add,
0139     .sta_remove              = wfx_sta_remove,
0140     .set_tim                 = wfx_set_tim,
0141     .set_key                 = wfx_set_key,
0142     .set_rts_threshold       = wfx_set_rts_threshold,
0143     .set_default_unicast_key = wfx_set_default_unicast_key,
0144     .bss_info_changed        = wfx_bss_info_changed,
0145     .configure_filter        = wfx_configure_filter,
0146     .ampdu_action            = wfx_ampdu_action,
0147     .flush                   = wfx_flush,
0148     .add_chanctx             = wfx_add_chanctx,
0149     .remove_chanctx          = wfx_remove_chanctx,
0150     .change_chanctx          = wfx_change_chanctx,
0151     .assign_vif_chanctx      = wfx_assign_vif_chanctx,
0152     .unassign_vif_chanctx    = wfx_unassign_vif_chanctx,
0153 };
0154 
0155 bool wfx_api_older_than(struct wfx_dev *wdev, int major, int minor)
0156 {
0157     if (wdev->hw_caps.api_version_major < major)
0158         return true;
0159     if (wdev->hw_caps.api_version_major > major)
0160         return false;
0161     if (wdev->hw_caps.api_version_minor < minor)
0162         return true;
0163     return false;
0164 }
0165 
0166 /* The device needs data about the antenna configuration. This information in provided by PDS
0167  * (Platform Data Set, this is the wording used in WF200 documentation) files. For hardware
0168  * integrators, the full process to create PDS files is described here:
0169  *   https://github.com/SiliconLabs/wfx-firmware/blob/master/PDS/README.md
0170  *
0171  * The PDS file is an array of Time-Length-Value structs.
0172  */
0173 int wfx_send_pds(struct wfx_dev *wdev, u8 *buf, size_t len)
0174 {
0175     int ret, chunk_type, chunk_len, chunk_num = 0;
0176 
0177     if (*buf == '{') {
0178         dev_err(wdev->dev, "PDS: malformed file (legacy format?)\n");
0179         return -EINVAL;
0180     }
0181     while (len > 0) {
0182         chunk_type = get_unaligned_le16(buf + 0);
0183         chunk_len = get_unaligned_le16(buf + 2);
0184         if (chunk_len > len) {
0185             dev_err(wdev->dev, "PDS:%d: corrupted file\n", chunk_num);
0186             return -EINVAL;
0187         }
0188         if (chunk_type != WFX_PDS_TLV_TYPE) {
0189             dev_info(wdev->dev, "PDS:%d: skip unknown data\n", chunk_num);
0190             goto next;
0191         }
0192         if (chunk_len > WFX_PDS_MAX_CHUNK_SIZE)
0193             dev_warn(wdev->dev, "PDS:%d: unexpectedly large chunk\n", chunk_num);
0194         if (buf[4] != '{' || buf[chunk_len - 1] != '}')
0195             dev_warn(wdev->dev, "PDS:%d: unexpected content\n", chunk_num);
0196 
0197         ret = wfx_hif_configuration(wdev, buf + 4, chunk_len - 4);
0198         if (ret > 0) {
0199             dev_err(wdev->dev, "PDS:%d: invalid data (unsupported options?)\n", chunk_num);
0200             return -EINVAL;
0201         }
0202         if (ret == -ETIMEDOUT) {
0203             dev_err(wdev->dev, "PDS:%d: chip didn't reply (corrupted file?)\n", chunk_num);
0204             return ret;
0205         }
0206         if (ret) {
0207             dev_err(wdev->dev, "PDS:%d: chip returned an unknown error\n", chunk_num);
0208             return -EIO;
0209         }
0210 next:
0211         chunk_num++;
0212         len -= chunk_len;
0213         buf += chunk_len;
0214     }
0215     return 0;
0216 }
0217 
0218 static int wfx_send_pdata_pds(struct wfx_dev *wdev)
0219 {
0220     int ret = 0;
0221     const struct firmware *pds;
0222     u8 *tmp_buf;
0223 
0224     ret = request_firmware(&pds, wdev->pdata.file_pds, wdev->dev);
0225     if (ret) {
0226         dev_err(wdev->dev, "can't load antenna parameters (PDS file %s). The device may be unstable.\n",
0227             wdev->pdata.file_pds);
0228         return ret;
0229     }
0230     tmp_buf = kmemdup(pds->data, pds->size, GFP_KERNEL);
0231     if (!tmp_buf) {
0232         ret = -ENOMEM;
0233         goto release_fw;
0234     }
0235     ret = wfx_send_pds(wdev, tmp_buf, pds->size);
0236     kfree(tmp_buf);
0237 release_fw:
0238     release_firmware(pds);
0239     return ret;
0240 }
0241 
0242 static void wfx_free_common(void *data)
0243 {
0244     struct wfx_dev *wdev = data;
0245 
0246     mutex_destroy(&wdev->tx_power_loop_info_lock);
0247     mutex_destroy(&wdev->rx_stats_lock);
0248     mutex_destroy(&wdev->conf_mutex);
0249     ieee80211_free_hw(wdev->hw);
0250 }
0251 
0252 struct wfx_dev *wfx_init_common(struct device *dev, const struct wfx_platform_data *pdata,
0253                 const struct wfx_hwbus_ops *hwbus_ops, void *hwbus_priv)
0254 {
0255     struct ieee80211_hw *hw;
0256     struct wfx_dev *wdev;
0257 
0258     hw = ieee80211_alloc_hw(sizeof(struct wfx_dev), &wfx_ops);
0259     if (!hw)
0260         return NULL;
0261 
0262     SET_IEEE80211_DEV(hw, dev);
0263 
0264     ieee80211_hw_set(hw, TX_AMPDU_SETUP_IN_HW);
0265     ieee80211_hw_set(hw, AMPDU_AGGREGATION);
0266     ieee80211_hw_set(hw, CONNECTION_MONITOR);
0267     ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
0268     ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
0269     ieee80211_hw_set(hw, SIGNAL_DBM);
0270     ieee80211_hw_set(hw, SUPPORTS_PS);
0271     ieee80211_hw_set(hw, MFP_CAPABLE);
0272 
0273     hw->vif_data_size = sizeof(struct wfx_vif);
0274     hw->sta_data_size = sizeof(struct wfx_sta_priv);
0275     hw->queues = 4;
0276     hw->max_rates = 8;
0277     hw->max_rate_tries = 8;
0278     hw->extra_tx_headroom = sizeof(struct wfx_hif_msg) + sizeof(struct wfx_hif_req_tx) +
0279                 4 /* alignment */ + 8 /* TKIP IV */;
0280     hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
0281                      BIT(NL80211_IFTYPE_ADHOC) |
0282                      BIT(NL80211_IFTYPE_AP);
0283     hw->wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
0284                     NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
0285                     NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
0286                     NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
0287     hw->wiphy->features |= NL80211_FEATURE_AP_SCAN;
0288     hw->wiphy->flags |= WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
0289     hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
0290     hw->wiphy->max_ap_assoc_sta = HIF_LINK_ID_MAX;
0291     hw->wiphy->max_scan_ssids = 2;
0292     hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
0293     hw->wiphy->n_iface_combinations = ARRAY_SIZE(wfx_iface_combinations);
0294     hw->wiphy->iface_combinations = wfx_iface_combinations;
0295     hw->wiphy->bands[NL80211_BAND_2GHZ] = devm_kmalloc(dev, sizeof(wfx_band_2ghz), GFP_KERNEL);
0296     if (!hw->wiphy->bands[NL80211_BAND_2GHZ])
0297         goto err;
0298 
0299     /* FIXME: also copy wfx_rates and wfx_2ghz_chantable */
0300     memcpy(hw->wiphy->bands[NL80211_BAND_2GHZ], &wfx_band_2ghz, sizeof(wfx_band_2ghz));
0301 
0302     wdev = hw->priv;
0303     wdev->hw = hw;
0304     wdev->dev = dev;
0305     wdev->hwbus_ops = hwbus_ops;
0306     wdev->hwbus_priv = hwbus_priv;
0307     memcpy(&wdev->pdata, pdata, sizeof(*pdata));
0308     of_property_read_string(dev->of_node, "silabs,antenna-config-file", &wdev->pdata.file_pds);
0309     wdev->pdata.gpio_wakeup = devm_gpiod_get_optional(dev, "wakeup", GPIOD_OUT_LOW);
0310     if (IS_ERR(wdev->pdata.gpio_wakeup))
0311         goto err;
0312 
0313     if (wdev->pdata.gpio_wakeup)
0314         gpiod_set_consumer_name(wdev->pdata.gpio_wakeup, "wfx wakeup");
0315 
0316     mutex_init(&wdev->conf_mutex);
0317     mutex_init(&wdev->rx_stats_lock);
0318     mutex_init(&wdev->tx_power_loop_info_lock);
0319     init_completion(&wdev->firmware_ready);
0320     INIT_DELAYED_WORK(&wdev->cooling_timeout_work, wfx_cooling_timeout_work);
0321     skb_queue_head_init(&wdev->tx_pending);
0322     init_waitqueue_head(&wdev->tx_dequeue);
0323     wfx_init_hif_cmd(&wdev->hif_cmd);
0324 
0325     if (devm_add_action_or_reset(dev, wfx_free_common, wdev))
0326         return NULL;
0327 
0328     return wdev;
0329 
0330 err:
0331     ieee80211_free_hw(hw);
0332     return NULL;
0333 }
0334 
0335 int wfx_probe(struct wfx_dev *wdev)
0336 {
0337     int i;
0338     int err;
0339     struct gpio_desc *gpio_saved;
0340 
0341     /* During first part of boot, gpio_wakeup cannot yet been used. So prevent bh() to touch
0342      * it.
0343      */
0344     gpio_saved = wdev->pdata.gpio_wakeup;
0345     wdev->pdata.gpio_wakeup = NULL;
0346     wdev->poll_irq = true;
0347 
0348     wdev->bh_wq = alloc_workqueue("wfx_bh_wq", WQ_HIGHPRI, 0);
0349     if (!wdev->bh_wq)
0350         return -ENOMEM;
0351 
0352     wfx_bh_register(wdev);
0353 
0354     err = wfx_init_device(wdev);
0355     if (err)
0356         goto bh_unregister;
0357 
0358     wfx_bh_poll_irq(wdev);
0359     err = wait_for_completion_timeout(&wdev->firmware_ready, 1 * HZ);
0360     if (err <= 0) {
0361         if (err == 0) {
0362             dev_err(wdev->dev, "timeout while waiting for startup indication\n");
0363             err = -ETIMEDOUT;
0364         } else if (err == -ERESTARTSYS) {
0365             dev_info(wdev->dev, "probe interrupted by user\n");
0366         }
0367         goto bh_unregister;
0368     }
0369 
0370     /* FIXME: fill wiphy::hw_version */
0371     dev_info(wdev->dev, "started firmware %d.%d.%d \"%s\" (API: %d.%d, keyset: %02X, caps: 0x%.8X)\n",
0372          wdev->hw_caps.firmware_major, wdev->hw_caps.firmware_minor,
0373          wdev->hw_caps.firmware_build, wdev->hw_caps.firmware_label,
0374          wdev->hw_caps.api_version_major, wdev->hw_caps.api_version_minor,
0375          wdev->keyset, wdev->hw_caps.link_mode);
0376     snprintf(wdev->hw->wiphy->fw_version,
0377          sizeof(wdev->hw->wiphy->fw_version),
0378          "%d.%d.%d",
0379          wdev->hw_caps.firmware_major,
0380          wdev->hw_caps.firmware_minor,
0381          wdev->hw_caps.firmware_build);
0382 
0383     if (wfx_api_older_than(wdev, 1, 0)) {
0384         dev_err(wdev->dev, "unsupported firmware API version (expect 1 while firmware returns %d)\n",
0385             wdev->hw_caps.api_version_major);
0386         err = -EOPNOTSUPP;
0387         goto bh_unregister;
0388     }
0389 
0390     if (wdev->hw_caps.link_mode == SEC_LINK_ENFORCED) {
0391         dev_err(wdev->dev, "chip require secure_link, but can't negotiate it\n");
0392         goto bh_unregister;
0393     }
0394 
0395     if (wdev->hw_caps.region_sel_mode) {
0396         wdev->hw->wiphy->regulatory_flags |= REGULATORY_DISABLE_BEACON_HINTS;
0397         wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[11].flags |=
0398             IEEE80211_CHAN_NO_IR;
0399         wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[12].flags |=
0400             IEEE80211_CHAN_NO_IR;
0401         wdev->hw->wiphy->bands[NL80211_BAND_2GHZ]->channels[13].flags |=
0402             IEEE80211_CHAN_DISABLED;
0403     }
0404 
0405     dev_dbg(wdev->dev, "sending configuration file %s\n", wdev->pdata.file_pds);
0406     err = wfx_send_pdata_pds(wdev);
0407     if (err < 0 && err != -ENOENT)
0408         goto bh_unregister;
0409 
0410     wdev->poll_irq = false;
0411     err = wdev->hwbus_ops->irq_subscribe(wdev->hwbus_priv);
0412     if (err)
0413         goto bh_unregister;
0414 
0415     err = wfx_hif_use_multi_tx_conf(wdev, true);
0416     if (err)
0417         dev_err(wdev->dev, "misconfigured IRQ?\n");
0418 
0419     wdev->pdata.gpio_wakeup = gpio_saved;
0420     if (wdev->pdata.gpio_wakeup) {
0421         dev_dbg(wdev->dev, "enable 'quiescent' power mode with wakeup GPIO and PDS file %s\n",
0422             wdev->pdata.file_pds);
0423         gpiod_set_value_cansleep(wdev->pdata.gpio_wakeup, 1);
0424         wfx_control_reg_write(wdev, 0);
0425         wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_QUIESCENT);
0426     } else {
0427         wfx_hif_set_operational_mode(wdev, HIF_OP_POWER_MODE_DOZE);
0428     }
0429 
0430     for (i = 0; i < ARRAY_SIZE(wdev->addresses); i++) {
0431         eth_zero_addr(wdev->addresses[i].addr);
0432         err = of_get_mac_address(wdev->dev->of_node, wdev->addresses[i].addr);
0433         if (!err)
0434             wdev->addresses[i].addr[ETH_ALEN - 1] += i;
0435         else
0436             ether_addr_copy(wdev->addresses[i].addr, wdev->hw_caps.mac_addr[i]);
0437         if (!is_valid_ether_addr(wdev->addresses[i].addr)) {
0438             dev_warn(wdev->dev, "using random MAC address\n");
0439             eth_random_addr(wdev->addresses[i].addr);
0440         }
0441         dev_info(wdev->dev, "MAC address %d: %pM\n", i, wdev->addresses[i].addr);
0442     }
0443     wdev->hw->wiphy->n_addresses = ARRAY_SIZE(wdev->addresses);
0444     wdev->hw->wiphy->addresses = wdev->addresses;
0445 
0446     if (!wfx_api_older_than(wdev, 3, 8))
0447         wdev->hw->wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
0448 
0449     err = ieee80211_register_hw(wdev->hw);
0450     if (err)
0451         goto irq_unsubscribe;
0452 
0453     err = wfx_debug_init(wdev);
0454     if (err)
0455         goto ieee80211_unregister;
0456 
0457     return 0;
0458 
0459 ieee80211_unregister:
0460     ieee80211_unregister_hw(wdev->hw);
0461 irq_unsubscribe:
0462     wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
0463 bh_unregister:
0464     wfx_bh_unregister(wdev);
0465     destroy_workqueue(wdev->bh_wq);
0466     return err;
0467 }
0468 
0469 void wfx_release(struct wfx_dev *wdev)
0470 {
0471     ieee80211_unregister_hw(wdev->hw);
0472     wfx_hif_shutdown(wdev);
0473     wdev->hwbus_ops->irq_unsubscribe(wdev->hwbus_priv);
0474     wfx_bh_unregister(wdev);
0475     destroy_workqueue(wdev->bh_wq);
0476 }
0477 
0478 static int __init wfx_core_init(void)
0479 {
0480     int ret = 0;
0481 
0482     if (IS_ENABLED(CONFIG_SPI))
0483         ret = spi_register_driver(&wfx_spi_driver);
0484     if (IS_ENABLED(CONFIG_MMC) && !ret)
0485         ret = sdio_register_driver(&wfx_sdio_driver);
0486     return ret;
0487 }
0488 module_init(wfx_core_init);
0489 
0490 static void __exit wfx_core_exit(void)
0491 {
0492     if (IS_ENABLED(CONFIG_MMC))
0493         sdio_unregister_driver(&wfx_sdio_driver);
0494     if (IS_ENABLED(CONFIG_SPI))
0495         spi_unregister_driver(&wfx_spi_driver);
0496 }
0497 module_exit(wfx_core_exit);