static void p54_parse_default_country(struct ieee80211_hw *dev, void *data, int len) { struct pda_country *country; if (len != sizeof(*country)) { wiphy_err(dev->wiphy, "found possible invalid default country eeprom entry. (entry size: %d)\n", len); print_hex_dump_bytes("country:", DUMP_PREFIX_NONE, data, len); wiphy_err(dev->wiphy, "please report this issue.\n"); return; } country = (struct pda_country *) data; if (country->flags == PDR_COUNTRY_CERT_CODE_PSEUDO) regulatory_hint(dev->wiphy, country->alpha2); else { /* TODO: * write a shared/common function that converts * "Regulatory domain codes" (802.11-2007 14.8.2.2) * into ISO/IEC 3166-1 alpha2 for regulatory_hint. */ } }
int rtl_init_core(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); /* <1> init mac80211 */ _rtl_init_mac80211(hw); rtlmac->hw = hw; /* <2> rate control register */ if (rtl_rate_control_register()) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("rtl: Unable to register rtl_rc," "use default RC !!\n")); } else { hw->rate_control_algorithm = "rtl_rc"; } /* * <3> init CRDA must come after init * mac80211 hw in _rtl_init_mac80211. */ if (rtl_regd_init(hw, rtl_reg_notifier)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("REGD init failed\n")); return 1; } else { /* CRDA regd hint must after init CRDA */ if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, ("regulatory_hint fail\n")); } } /* <4> locks */ mutex_init(&rtlpriv->locks.conf_mutex); spin_lock_init(&rtlpriv->locks.ips_lock); spin_lock_init(&rtlpriv->locks.irq_th_lock); spin_lock_init(&rtlpriv->locks.h2c_lock); spin_lock_init(&rtlpriv->locks.rf_ps_lock); spin_lock_init(&rtlpriv->locks.rf_lock); spin_lock_init(&rtlpriv->locks.lps_lock); rtlmac->link_state = MAC80211_NOLINK; /* <5> init deferred work */ _rtl_init_deferred_work(hw); return 0; }
int rtl_init_core(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw)); _rtl_init_mac80211(hw); rtlmac->hw = hw; hw->rate_control_algorithm = "rtl_rc"; if (rtl_regd_init(hw, rtl_reg_notifier)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "REGD init failed\n"); return 1; } else { if (regulatory_hint(hw->wiphy, rtlpriv->regd.alpha2)) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "regulatory_hint fail\n"); } } mutex_init(&rtlpriv->locks.conf_mutex); mutex_init(&rtlpriv->locks.ps_mutex); spin_lock_init(&rtlpriv->locks.ips_lock); spin_lock_init(&rtlpriv->locks.irq_th_lock); spin_lock_init(&rtlpriv->locks.h2c_lock); spin_lock_init(&rtlpriv->locks.rf_ps_lock); spin_lock_init(&rtlpriv->locks.rf_lock); spin_lock_init(&rtlpriv->locks.waitq_lock); spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock); rtlmac->link_state = MAC80211_NOLINK; _rtl_init_deferred_work(hw); return 0; }
/** * attach to the WL device. * * Attach to the WL device identified by vendor and device parameters. * regs is a host accessible memory address pointing to WL device registers. * * is called in brcms_bcma_probe() context, therefore no locking required. */ static struct brcms_info *brcms_attach(struct bcma_device *pdev) { struct brcms_info *wl = NULL; int unit, err; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; unit = n_adapters_found; err = 0; if (unit < 0) return NULL; /* allocate private info */ hw = bcma_get_drvdata(pdev); if (hw != NULL) wl = hw->priv; if (WARN_ON(hw == NULL) || WARN_ON(wl == NULL)) return NULL; wl->wiphy = hw->wiphy; atomic_set(&wl->callbacks, 0); init_waitqueue_head(&wl->tx_flush_wq); /* setup the bottom half handler */ tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); if (!wl->wlc) { wiphy_err(wl->wiphy, "%s: attach() failed with code %d\n", KBUILD_MODNAME, err); goto fail; } wl->pub = brcms_c_pub(wl->wlc); wl->pub->ieee_hw = hw; /* register our interrupt handler */ if (request_irq(pdev->irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = pdev->irq; /* register module */ brcms_c_module_register(wl->pub, "linux", wl, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, __func__); goto fail; } brcms_c_regd_init(wl->wlc); memcpy(perm, &wl->pub->cur_etheraddr, ETH_ALEN); if (WARN_ON(!is_valid_ether_addr(perm))) goto fail; SET_IEEE80211_PERM_ADDR(hw, perm); err = ieee80211_register_hw(hw); if (err) wiphy_err(wl->wiphy, "%s: ieee80211_register_hw failed, status" "%d\n", __func__, err); if (wl->pub->srom_ccode[0] && regulatory_hint(wl->wiphy, wl->pub->srom_ccode)) wiphy_err(wl->wiphy, "%s: regulatory hint failed\n", __func__); brcms_debugfs_attach(wl->pub); brcms_debugfs_create_files(wl->pub); n_adapters_found++; return wl; fail: brcms_free(wl); return NULL; }
/* * is called in brcms_bcma_probe() context, therefore no locking required. */ static int brcms_set_hint(struct brcms_info *wl, char *abbrev) { return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); }
int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; struct ath_common *common; struct ath_hw *ah; int error = 0; struct ath_regulatory *reg; /* Bring up device */ error = ath9k_init_softc(devid, sc, bus_ops); if (error != 0) goto error_init; ah = sc->sc_ah; common = ath9k_hw_common(ah); ath9k_set_hw_capab(sc, hw); /* Initialize regulatory */ error = ath_regd_init(&common->regulatory, sc->hw->wiphy, ath9k_reg_notifier); if (error) goto error_regd; reg = &common->regulatory; /* Setup TX DMA */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) goto error_tx; /* Setup RX DMA */ error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) goto error_rx; ath9k_init_txpower_limits(sc); #ifdef CONFIG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, ARRAY_SIZE(ath9k_tpt_blink)); #endif INIT_WORK(&sc->hw_reset_work, ath_reset_work); INIT_WORK(&sc->hw_check_work, ath_hw_check); INIT_WORK(&sc->paprd_work, ath_paprd_calibrate); INIT_DELAYED_WORK(&sc->hw_pll_work, ath_hw_pll_work); /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) goto error_register; error = ath9k_init_debug(ah); if (error) { ath_err(common, "Unable to create debugfs files\n"); goto error_world; } /* Handle world regulatory */ if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto error_world; } setup_timer(&sc->rx_poll_timer, ath_rx_poll, (unsigned long)sc); sc->last_rssi = ATH_RSSI_DUMMY_MARKER; ath_init_leds(sc); ath_start_rfkill_poll(sc); return 0; error_world: ieee80211_unregister_hw(hw); error_register: ath_rx_cleanup(sc); error_rx: ath_tx_cleanup(sc); error_tx: /* Nothing */ error_regd: ath9k_deinit_softc(sc); error_init: return error; }
int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; struct ath_common *common; struct ath_hw *ah; int error = 0; struct ath_regulatory *reg; /* Bring up device */ error = ath9k_init_softc(devid, sc, subsysid, bus_ops); if (error != 0) goto error_init; ah = sc->sc_ah; common = ath9k_hw_common(ah); ath9k_set_hw_capab(sc, hw); /* Initialize regulatory */ error = ath_regd_init(&common->regulatory, sc->hw->wiphy, ath9k_reg_notifier); if (error) goto error_regd; reg = &common->regulatory; /* Setup TX DMA */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) goto error_tx; /* Setup RX DMA */ error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) goto error_rx; /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) goto error_register; /* Handle world regulatory */ if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto error_world; } INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work); INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work); sc->wiphy_scheduler_int = msecs_to_jiffies(500); ath_init_leds(sc); ath_start_rfkill_poll(sc); return 0; error_world: ieee80211_unregister_hw(hw); error_register: ath_rx_cleanup(sc); error_rx: ath_tx_cleanup(sc); error_tx: /* Nothing */ error_regd: ath9k_deinit_softc(sc); error_init: return error; }
int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter) { int ret; void *wdev_priv; struct wiphy *wiphy; struct mwifiex_private *priv = adapter->priv[MWIFIEX_BSS_TYPE_STA]; u8 *country_code; /* create a new wiphy for use with cfg80211 */ wiphy = wiphy_new(&mwifiex_cfg80211_ops, sizeof(struct mwifiex_adapter *)); if (!wiphy) { dev_err(adapter->dev, "%s: creating new wiphy\n", __func__); return -ENOMEM; } wiphy->max_scan_ssids = MWIFIEX_MAX_SSID_LIST_LENGTH; wiphy->max_scan_ie_len = MWIFIEX_MAX_VSIE_LEN; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP); wiphy->bands[IEEE80211_BAND_2GHZ] = &mwifiex_band_2ghz; if (adapter->config_bands & BAND_A) wiphy->bands[IEEE80211_BAND_5GHZ] = &mwifiex_band_5ghz; else wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; wiphy->iface_combinations = &mwifiex_iface_comb_ap_sta; wiphy->n_iface_combinations = 1; /* Initialize cipher suits */ wiphy->cipher_suites = mwifiex_cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(mwifiex_cipher_suites); memcpy(wiphy->perm_addr, priv->curr_addr, ETH_ALEN); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_CUSTOM_REGULATORY; /* Reserve space for mwifiex specific private data for BSS */ wiphy->bss_priv_size = sizeof(struct mwifiex_bss_priv); wiphy->reg_notifier = mwifiex_reg_notifier; /* Set struct mwifiex_adapter pointer in wiphy_priv */ wdev_priv = wiphy_priv(wiphy); *(unsigned long *)wdev_priv = (unsigned long)adapter; set_wiphy_dev(wiphy, (struct device *)priv->adapter->dev); ret = wiphy_register(wiphy); if (ret < 0) { dev_err(adapter->dev, "%s: wiphy_register failed: %d\n", __func__, ret); wiphy_free(wiphy); return ret; } country_code = mwifiex_11d_code_2_region(priv->adapter->region_code); if (country_code && regulatory_hint(wiphy, country_code)) dev_err(adapter->dev, "regulatory_hint() failed\n"); adapter->wiphy = wiphy; return ret; }
int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { struct ieee80211_hw *hw = sc->hw; struct ath_common *common; struct ath_hw *ah; int error = 0; struct ath_regulatory *reg; /* Bring up device */ error = ath9k_init_softc(devid, sc, bus_ops); if (error) return error; ah = sc->sc_ah; common = ath9k_hw_common(ah); ath9k_set_hw_capab(sc, hw); /* Initialize regulatory */ error = ath_regd_init(&common->regulatory, sc->hw->wiphy, ath9k_reg_notifier); if (error) goto deinit; reg = &common->regulatory; /* Setup TX DMA */ error = ath_tx_init(sc, ATH_TXBUF); if (error != 0) goto deinit; /* Setup RX DMA */ error = ath_rx_init(sc, ATH_RXBUF); if (error != 0) goto deinit; ath9k_init_txpower_limits(sc); #ifdef CONFIG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw, IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink, ARRAY_SIZE(ath9k_tpt_blink)); #endif /* Register with mac80211 */ error = ieee80211_register_hw(hw); if (error) goto rx_cleanup; error = ath9k_init_debug(ah); if (error) { ath_err(common, "Unable to create debugfs files\n"); goto unregister; } /* Handle world regulatory */ if (!ath_is_world_regd(reg)) { error = regulatory_hint(hw->wiphy, reg->alpha2); if (error) goto debug_cleanup; } ath_init_leds(sc); ath_start_rfkill_poll(sc); return 0; debug_cleanup: ath9k_deinit_debug(sc); unregister: ieee80211_unregister_hw(hw); rx_cleanup: ath_rx_cleanup(sc); deinit: ath9k_deinit_softc(sc); return error; }
int qtnf_wiphy_register(struct qtnf_hw_info *hw_info, struct qtnf_wmac *mac) { struct wiphy *wiphy = priv_to_wiphy(mac); struct ieee80211_iface_combination *iface_comb = NULL; int ret; if (!wiphy) { pr_err("invalid wiphy pointer\n"); return -EFAULT; } iface_comb = kzalloc(sizeof(*iface_comb), GFP_KERNEL); if (!iface_comb) return -ENOMEM; ret = qtnf_wiphy_setup_if_comb(wiphy, iface_comb, &mac->macinfo); if (ret) goto out; pr_info("MAC%u: phymode=%#x radar=%#x\n", mac->macid, mac->macinfo.phymode_cap, mac->macinfo.radar_detect_widths); wiphy->frag_threshold = mac->macinfo.frag_thr; wiphy->rts_threshold = mac->macinfo.rts_thr; wiphy->retry_short = mac->macinfo.sretry_limit; wiphy->retry_long = mac->macinfo.lretry_limit; wiphy->coverage_class = mac->macinfo.coverage_class; wiphy->max_scan_ssids = QTNF_MAX_SSID_LIST_LENGTH; wiphy->max_scan_ie_len = QTNF_MAX_VSIE_LEN; wiphy->mgmt_stypes = qtnf_mgmt_stypes; wiphy->max_remain_on_channel_duration = 5000; wiphy->iface_combinations = iface_comb; wiphy->n_iface_combinations = 1; wiphy->max_num_csa_counters = 2; /* Initialize cipher suits */ wiphy->cipher_suites = qtnf_cipher_suites; wiphy->n_cipher_suites = ARRAY_SIZE(qtnf_cipher_suites); wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD | WIPHY_FLAG_AP_UAPSD | WIPHY_FLAG_HAS_CHANNEL_SWITCH; wiphy->probe_resp_offload = NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2; wiphy->available_antennas_tx = mac->macinfo.num_tx_chain; wiphy->available_antennas_rx = mac->macinfo.num_rx_chain; wiphy->max_ap_assoc_sta = mac->macinfo.max_ap_assoc_sta; ether_addr_copy(wiphy->perm_addr, mac->macaddr); if (hw_info->hw_capab & QLINK_HW_SUPPORTS_REG_UPDATE) { wiphy->regulatory_flags |= REGULATORY_STRICT_REG | REGULATORY_CUSTOM_REG; wiphy->reg_notifier = qtnf_cfg80211_reg_notifier; wiphy_apply_custom_regulatory(wiphy, hw_info->rd); } else { wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED; } ret = wiphy_register(wiphy); if (ret < 0) goto out; if (wiphy->regulatory_flags & REGULATORY_WIPHY_SELF_MANAGED) ret = regulatory_set_wiphy_regd(wiphy, hw_info->rd); else if (isalpha(hw_info->rd->alpha2[0]) && isalpha(hw_info->rd->alpha2[1])) ret = regulatory_hint(wiphy, hw_info->rd->alpha2); out: if (ret) { kfree(iface_comb); return ret; } return 0; }
/* * is called in wl_pci_probe() context, therefore no locking required. */ static int wl_set_hint(struct wl_info *wl, char *abbrev) { WL_NONE("%s: Sending country code %c%c to MAC80211\n", __func__, abbrev[0], abbrev[1]); return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); }
/** * cds_get_reg_domain_from_country_code() - get the regulatory domain * @reg_domain_ptr: ptr to store regulatory domain * * Return: CDF_STATUS_SUCCESS on success * CDF_STATUS_E_FAULT on error * CDF_STATUS_E_EMPTY country table empty */ CDF_STATUS cds_get_reg_domain_from_country_code(v_REGDOMAIN_t *reg_domain_ptr, const country_code_t country_code, v_CountryInfoSource_t source) { v_CONTEXT_t cds_context = NULL; hdd_context_t *hdd_ctx = NULL; struct wiphy *wiphy = NULL; int i; if (NULL == reg_domain_ptr) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, ("Invalid reg domain pointer")); return CDF_STATUS_E_FAULT; } *reg_domain_ptr = REGDOMAIN_COUNT; if (NULL == country_code) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, ("Country code array is NULL")); return CDF_STATUS_E_FAULT; } if (0 == country_info_table.countryCount) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, ("Reg domain table is empty")); return CDF_STATUS_E_EMPTY; } cds_context = cds_get_global_context(); if (NULL != cds_context) hdd_ctx = cds_get_context(CDF_MODULE_ID_HDD); else return CDF_STATUS_E_EXISTS; if (NULL == hdd_ctx) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, ("Invalid pHddCtx pointer")); return CDF_STATUS_E_FAULT; } wiphy = hdd_ctx->wiphy; if (cds_is_logp_in_progress()) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, "SSR in progress, return"); *reg_domain_ptr = temp_reg_domain; return CDF_STATUS_SUCCESS; } temp_reg_domain = REGDOMAIN_COUNT; for (i = 0; i < country_info_table.countryCount && REGDOMAIN_COUNT == temp_reg_domain; i++) { if (memcmp(country_code, country_info_table.countryInfo[i].countryCode, CDS_COUNTRY_CODE_LEN) == 0) { temp_reg_domain = country_info_table.countryInfo[i].regDomain; break; } } if (REGDOMAIN_COUNT == temp_reg_domain) { CDF_TRACE(CDF_MODULE_ID_CDF, CDF_TRACE_LEVEL_ERROR, ("Country does not map to any Regulatory domain")); temp_reg_domain = REGDOMAIN_WORLD; } if (COUNTRY_QUERY == source) { *reg_domain_ptr = temp_reg_domain; return CDF_STATUS_SUCCESS; } if ((COUNTRY_INIT == source) && (false == init_by_reg_core)) { init_by_driver = true; if (('0' != country_code[0]) || ('0' != country_code[1])) { INIT_COMPLETION(hdd_ctx->reg_init); regulatory_hint(wiphy, country_code); wait_for_completion_timeout(&hdd_ctx->reg_init, msecs_to_jiffies(REG_WAIT_TIME)); } } else if (COUNTRY_IE == source || COUNTRY_USER == source) { regulatory_hint_user(country_code, NL80211_USER_REG_HINT_USER); } *reg_domain_ptr = temp_reg_domain; return CDF_STATUS_SUCCESS; }