static int brcms_ops_start(struct ieee80211_hw *hw) { struct brcms_info *wl = hw->priv; bool blocked; int err; ieee80211_wake_queues(hw); spin_lock_bh(&wl->lock); blocked = brcms_rfkill_set_hw_state(wl); spin_unlock_bh(&wl->lock); if (!blocked) wiphy_rfkill_stop_polling(wl->pub->ieee_hw->wiphy); if (!wl->ucode.bcm43xx_bomminor) { err = brcms_request_fw(wl, wl->wlc->hw->d11core); if (err) { brcms_remove(wl->wlc->hw->d11core); return -ENOENT; } } spin_lock_bh(&wl->lock); /* avoid acknowledging frames before a non-monitor device is added */ wl->mute_tx = true; if (!wl->pub->up) if (!blocked) err = brcms_up(wl); else err = -ERFKILL; else err = -ENODEV; spin_unlock_bh(&wl->lock); if (err != 0) brcms_err(wl->wlc->hw->d11core, "%s: brcms_up() returned %d\n", __func__, err); bcma_core_pci_power_save(wl->wlc->hw->d11core->bus, true); return err; }
/** * 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. * * brcms_attach is not defined as static because in the case where no bus * is defined, wl_attach will never be called, and thus, gcc will issue * a warning that this function is defined but not used if we declare * it as static. * * * 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); /* 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); /* prepare ucode */ if (brcms_request_fw(wl, pdev->bus->host_pci) < 0) { wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); brcms_release_fw(wl); brcms_remove(pdev); return NULL; } /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, pdev, unit, false, &err); brcms_release_fw(wl); 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->bus->host_pci->irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = pdev->bus->host_pci->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; } 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]) err = brcms_set_hint(wl, wl->pub->srom_ccode); else err = brcms_set_hint(wl, "US"); if (err) wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", __func__, err); n_adapters_found++; return wl; fail: brcms_free(wl); return NULL; }
/** * 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. * * brcms_attach is not defined as static because in the case where no bus * is defined, wl_attach will never be called, and thus, gcc will issue * a warning that this function is defined but not used if we declare * it as static. * * * is called in brcms_pci_probe() context, therefore no locking required. */ static struct brcms_info *brcms_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) { struct brcms_info *wl = NULL; int unit, err; unsigned long base_addr; struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; unit = n_adapters_found; err = 0; if (unit < 0) { return NULL; } /* allocate private info */ hw = pci_get_drvdata(btparam); /* btparam == 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); /* setup the bottom half handler */ tasklet_init(&wl->tasklet, brcms_dpc, (unsigned long) wl); base_addr = regs; if (bustype == PCI_BUS || bustype == RPC_BUS) { /* Do nothing */ } else { bustype = PCI_BUS; BCMMSG(wl->wiphy, "force to PCI\n"); } wl->bcm_bustype = bustype; wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); if (wl->regsva == NULL) { wiphy_err(wl->wiphy, "wl%d: ioremap() failed\n", unit); goto fail; } spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); /* prepare ucode */ if (brcms_request_fw(wl, (struct pci_dev *)btparam) < 0) { wiphy_err(wl->wiphy, "%s: Failed to find firmware usually in " "%s\n", KBUILD_MODNAME, "/lib/firmware/brcm"); brcms_release_fw(wl); brcms_remove((struct pci_dev *)btparam); return NULL; } /* common load-time initialization */ wl->wlc = brcms_c_attach((void *)wl, vendor, device, unit, false, wl->regsva, wl->bcm_bustype, btparam, &err); brcms_release_fw(wl); 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; if (brcms_c_set_par(wl->wlc, IOV_MPC, 0) < 0) { wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n", unit); } /* register our interrupt handler */ if (request_irq(irq, brcms_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = irq; /* register module */ brcms_c_module_register(wl->pub, "linux", wl, wl_linux_watchdog, NULL); if (ieee_hw_init(hw)) { wiphy_err(wl->wiphy, "wl%d: %s: ieee_hw_init failed!\n", unit, __func__); goto fail; } 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]) err = brcms_set_hint(wl, wl->pub->srom_ccode); else err = brcms_set_hint(wl, "US"); if (err) { wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n", __func__, err); } n_adapters_found++; return wl; fail: brcms_free(wl); return NULL; }