Example #1
0
void rtl_fw_cb(const struct firmware *firmware, void *context)
{
	struct ieee80211_hw *hw = context;
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	int err;

	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
			 "Firmware callback routine entered!\n");
	complete(&rtlpriv->firmware_loading_complete);
	if (!firmware) {
		if (rtlpriv->cfg->alt_fw_name) {
			err = request_firmware(&firmware,
					       rtlpriv->cfg->alt_fw_name,
					       rtlpriv->io.dev);
			pr_info("Loading alternative firmware %s\n",
				rtlpriv->cfg->alt_fw_name);
			if (!err)
				goto found_alt;
		}
		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
		rtlpriv->max_fw_size = 0;
		return;
	}
found_alt:
	if (firmware->size > rtlpriv->max_fw_size) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Firmware is too big!\n");
		release_firmware(firmware);
		return;
	}
	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
	rtlpriv->rtlhal.fwsize = firmware->size;
	release_firmware(firmware);

	err = ieee80211_register_hw(hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Can't register mac80211 hw\n");
		return;
	} else {
		rtlpriv->mac80211.mac80211_registered = 1;
	}
	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);

	/*init rfkill */
	rtl_init_rfkill(hw);
}
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
{
	struct hw_mode_spec *spec = &rt2x00dev->spec;
	int status;

	if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
		return 0;

	/*
	 * Initialize HW modes.
	 */
	status = rt2x00lib_probe_hw_modes(rt2x00dev, spec);
	if (status)
		return status;

	/*
	 * Initialize HW fields.
	 */
	rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;

	/*
	 * Initialize extra TX headroom required.
	 */
	rt2x00dev->hw->extra_tx_headroom =
		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
		      rt2x00dev->ops->extra_tx_headroom);

	/*
	 * Take TX headroom required for alignment into account.
	 */
	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
	else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;

	/*
	 * Register HW.
	 */
	status = ieee80211_register_hw(rt2x00dev->hw);
	if (status)
		return status;

	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);

	return 0;
}
Example #3
0
static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
{
	struct ieee80211_hw *hw = context;
	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
	struct rtl_priv *rtlpriv = rtl_priv(hw);
	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
	struct rt_firmware *pfirmware = NULL;
	int err;

	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
			 "Firmware callback routine entered!\n");
	complete(&rtlpriv->firmware_loading_complete);
	if (!firmware) {
		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
		rtlpriv->max_fw_size = 0;
		return;
	}
	if (firmware->size > rtlpriv->max_fw_size) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Firmware is too big!\n");
		rtlpriv->max_fw_size = 0;
		release_firmware(firmware);
		return;
	}
	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
	pfirmware->sz_fw_tmpbufferlen = firmware->size;
	release_firmware(firmware);

	err = ieee80211_register_hw(hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 "Can't register mac80211 hw\n");
		return;
	} else {
		rtlpriv->mac80211.mac80211_registered = 1;
		rtl_mac80211_init(hw);
	}
	rtlpci->irq_alloc = 1;
	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);

	/*init rfkill */
	rtl_init_rfkill(hw);
}
int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
{
	struct p54_common __maybe_unused *priv = dev->priv;
	int err;

	err = ieee80211_register_hw(dev);
	if (err) {
		dev_err(pdev, "Cannot register device (%d).\n", err);
		return err;
	}

#ifdef CONFIG_P54_LEDS
	err = p54_init_leds(priv);
	if (err)
		return err;
#endif /* CONFIG_P54_LEDS */

	dev_info(pdev, "is registered as '%s'\n", wiphy_name(dev->wiphy));
	return 0;
}
Example #5
0
static int wl1271_register_hw(struct wl1271 *wl)
{
	int ret;

	if (wl->mac80211_registered)
		return 0;

	SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);

	ret = ieee80211_register_hw(wl->hw);
	if (ret < 0) {
		wl1271_error("unable to register mac80211 hw: %d", ret);
		return ret;
	}

	wl->mac80211_registered = true;

	wl1271_notice("loaded");

	return 0;
}
Example #6
0
int iwl_setup_mac(struct iwl_priv *priv)
{
	int ret;
	struct ieee80211_hw *hw = priv->hw;
	hw->rate_control_algorithm = "iwl-agn-rs";

	/* Tell mac80211 our characteristics */
	hw->flags = IEEE80211_HW_SIGNAL_DBM |
		    IEEE80211_HW_NOISE_DBM;
	hw->wiphy->interface_modes =
		BIT(NL80211_IFTYPE_AP) |
		BIT(NL80211_IFTYPE_STATION) |
		BIT(NL80211_IFTYPE_ADHOC);
	/* Default value; 4 EDCA QOS priorities */
	hw->queues = 4;
	/* queues to support 11n aggregation */
	if (priv->cfg->sku & IWL_SKU_N)
		hw->ampdu_queues = priv->cfg->mod_params->num_of_ampdu_queues;

	hw->conf.beacon_int = 100;
	hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;

	if (priv->bands[IEEE80211_BAND_2GHZ].n_channels)
		priv->hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
			&priv->bands[IEEE80211_BAND_2GHZ];
	if (priv->bands[IEEE80211_BAND_5GHZ].n_channels)
		priv->hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
			&priv->bands[IEEE80211_BAND_5GHZ];

	ret = ieee80211_register_hw(priv->hw);
	if (ret) {
		IWL_ERROR("Failed to register hw (error %d)\n", ret);
		return ret;
	}
	priv->mac80211_registered = 1;

	return 0;
}
Example #7
0
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
{
	struct hw_mode_spec *spec = &rt2x00dev->spec;
	int status;

	if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
		return 0;

	/*
	 * Initialize HW modes.
	 */
	status = rt2x00lib_probe_hw_modes(rt2x00dev, spec);
	if (status)
		return status;

	/*
	 * Initialize HW fields.
	 */
	rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;

	/*
	 * Initialize extra TX headroom required.
	 */
	rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom;

	/*
	 * Register HW.
	 */
	status = ieee80211_register_hw(rt2x00dev->hw);
	if (status)
		return status;

	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);

	return 0;
}
Example #8
0
File: p54pci.c Project: 274914765/C
static int __devinit p54p_probe(struct pci_dev *pdev,
                const struct pci_device_id *id)
{
    struct p54p_priv *priv;
    struct ieee80211_hw *dev;
    unsigned long mem_addr, mem_len;
    int err;
    DECLARE_MAC_BUF(mac);

    err = pci_enable_device(pdev);
    if (err) {
        printk(KERN_ERR "%s (prism54pci): Cannot enable new PCI device\n",
               pci_name(pdev));
        return err;
    }

    mem_addr = pci_resource_start(pdev, 0);
    mem_len = pci_resource_len(pdev, 0);
    if (mem_len < sizeof(struct p54p_csr)) {
        printk(KERN_ERR "%s (prism54pci): Too short PCI resources\n",
               pci_name(pdev));
        pci_disable_device(pdev);
        return err;
    }

    err = pci_request_regions(pdev, "prism54pci");
    if (err) {
        printk(KERN_ERR "%s (prism54pci): Cannot obtain PCI resources\n",
               pci_name(pdev));
        return err;
    }

    if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) ||
        pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
        printk(KERN_ERR "%s (prism54pci): No suitable DMA available\n",
               pci_name(pdev));
        goto err_free_reg;
    }

    pci_set_master(pdev);
    pci_try_set_mwi(pdev);

    pci_write_config_byte(pdev, 0x40, 0);
    pci_write_config_byte(pdev, 0x41, 0);

    dev = p54_init_common(sizeof(*priv));
    if (!dev) {
        printk(KERN_ERR "%s (prism54pci): ieee80211 alloc failed\n",
               pci_name(pdev));
        err = -ENOMEM;
        goto err_free_reg;
    }

    priv = dev->priv;
    priv->pdev = pdev;

    SET_IEEE80211_DEV(dev, &pdev->dev);
    pci_set_drvdata(pdev, dev);

    priv->map = ioremap(mem_addr, mem_len);
    if (!priv->map) {
        printk(KERN_ERR "%s (prism54pci): Cannot map device memory\n",
               pci_name(pdev));
        err = -EINVAL;    // TODO: use a better error code?
        goto err_free_dev;
    }

    priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control),
                          &priv->ring_control_dma);
    if (!priv->ring_control) {
        printk(KERN_ERR "%s (prism54pci): Cannot allocate rings\n",
               pci_name(pdev));
        err = -ENOMEM;
        goto err_iounmap;
    }
    memset(priv->ring_control, 0, sizeof(*priv->ring_control));

    err = p54p_upload_firmware(dev);
    if (err)
        goto err_free_desc;

    err = p54p_read_eeprom(dev);
    if (err)
        goto err_free_desc;

    priv->common.open = p54p_open;
    priv->common.stop = p54p_stop;
    priv->common.tx = p54p_tx;

    spin_lock_init(&priv->lock);

    err = ieee80211_register_hw(dev);
    if (err) {
        printk(KERN_ERR "%s (prism54pci): Cannot register netdevice\n",
               pci_name(pdev));
        goto err_free_common;
    }

    printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
           wiphy_name(dev->wiphy),
           print_mac(mac, dev->wiphy->perm_addr),
           priv->common.version);

    return 0;

 err_free_common:
    p54_free_common(dev);

 err_free_desc:
    pci_free_consistent(pdev, sizeof(*priv->ring_control),
                priv->ring_control, priv->ring_control_dma);

 err_iounmap:
    iounmap(priv->map);

 err_free_dev:
    pci_set_drvdata(pdev, NULL);
    ieee80211_free_hw(dev);

 err_free_reg:
    pci_release_regions(pdev);
    pci_disable_device(pdev);
    return err;
}
Example #9
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.
 *
 * 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,
				       resource_size_t regs,
				       struct pci_dev *btparam, uint irq)
{
	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 = 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);

	wl->regsva = ioremap_nocache(regs, 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, 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(btparam);
		return NULL;
	}

	/* common load-time initialization */
	wl->wlc = brcms_c_attach(wl, vendor, device, unit, false,
				 wl->regsva, 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;

	/* disable mpc */
	brcms_c_set_radio_mpc(wl->wlc, false);

	/* 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, 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;
}
Example #10
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;
}
Example #11
0
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;
}
static int __devinit p54u_probe(struct usb_interface *intf,
				const struct usb_device_id *id)
{
	struct usb_device *udev = interface_to_usbdev(intf);
	struct ieee80211_hw *dev;
	struct p54u_priv *priv;
	int err;
	unsigned int i, recognized_pipes;
	DECLARE_MAC_BUF(mac);

	dev = p54_init_common(sizeof(*priv));
	if (!dev) {
		printk(KERN_ERR "prism54usb: ieee80211 alloc failed\n");
		return -ENOMEM;
	}

	priv = dev->priv;

	SET_IEEE80211_DEV(dev, &intf->dev);
	usb_set_intfdata(intf, dev);
	priv->udev = udev;

	usb_get_dev(udev);

	/* really lazy and simple way of figuring out if we're a 3887 */
	/* TODO: should just stick the identification in the device table */
	i = intf->altsetting->desc.bNumEndpoints;
	recognized_pipes = 0;
	while (i--) {
		switch (intf->altsetting->endpoint[i].desc.bEndpointAddress) {
		case P54U_PIPE_DATA:
		case P54U_PIPE_MGMT:
		case P54U_PIPE_BRG:
		case P54U_PIPE_DEV:
		case P54U_PIPE_DATA | USB_DIR_IN:
		case P54U_PIPE_MGMT | USB_DIR_IN:
		case P54U_PIPE_BRG | USB_DIR_IN:
		case P54U_PIPE_DEV | USB_DIR_IN:
		case P54U_PIPE_INT | USB_DIR_IN:
			recognized_pipes++;
		}
	}
	priv->common.open = p54u_open;

	if (recognized_pipes < P54U_PIPE_NUMBER) {
		priv->hw_type = P54U_3887;
		priv->common.tx = p54u_tx_3887;
	} else {
		dev->extra_tx_headroom += sizeof(struct net2280_tx_hdr);
		priv->common.tx_hdr_len = sizeof(struct net2280_tx_hdr);
		priv->common.tx = p54u_tx_net2280;
	}
	priv->common.stop = p54u_stop;

	if (priv->hw_type)
		err = p54u_upload_firmware_3887(dev);
	else
		err = p54u_upload_firmware_net2280(dev);
	if (err)
		goto err_free_dev;

	err = p54u_read_eeprom(dev);
	if (err)
		goto err_free_dev;

	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
		u8 perm_addr[ETH_ALEN];

		printk(KERN_WARNING "prism54usb: Invalid hwaddr! Using randomly generated MAC addr\n");
		random_ether_addr(perm_addr);
		SET_IEEE80211_PERM_ADDR(dev, perm_addr);
	}

	skb_queue_head_init(&priv->rx_queue);

	err = ieee80211_register_hw(dev);
	if (err) {
		printk(KERN_ERR "prism54usb: Cannot register netdevice\n");
		goto err_free_dev;
	}

	printk(KERN_INFO "%s: hwaddr %s, isl38%02x\n",
	       wiphy_name(dev->wiphy),
	       print_mac(mac, dev->wiphy->perm_addr),
	       priv->common.version);

	return 0;

 err_free_dev:
	ieee80211_free_hw(dev);
	usb_set_intfdata(intf, NULL);
	usb_put_dev(udev);
	return err;
}
Example #13
0
int ath9k_wiphy_add(struct ath_softc *sc)
{
	int i, error;
	struct ath_wiphy *aphy;
	struct ieee80211_hw *hw;
	u8 addr[ETH_ALEN];

	hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy), &ath9k_ops);
	if (hw == NULL)
		return -ENOMEM;

	spin_lock_bh(&sc->wiphy_lock);
	for (i = 0; i < sc->num_sec_wiphy; i++) {
		if (sc->sec_wiphy[i] == NULL)
			break;
	}

	if (i == sc->num_sec_wiphy) {
		/* No empty slot available; increase array length */
		struct ath_wiphy **n;
		n = krealloc(sc->sec_wiphy,
			     (sc->num_sec_wiphy + 1) *
			     sizeof(struct ath_wiphy *),
			     GFP_ATOMIC);
		if (n == NULL) {
			spin_unlock_bh(&sc->wiphy_lock);
			ieee80211_free_hw(hw);
			return -ENOMEM;
		}
		n[i] = NULL;
		sc->sec_wiphy = n;
		sc->num_sec_wiphy++;
	}

	SET_IEEE80211_DEV(hw, sc->dev);

	aphy = hw->priv;
	aphy->sc = sc;
	aphy->hw = hw;
	sc->sec_wiphy[i] = aphy;
	spin_unlock_bh(&sc->wiphy_lock);

	memcpy(addr, sc->sc_ah->macaddr, ETH_ALEN);
	addr[0] |= 0x02; /* Locally managed address */
	/*
	 * XOR virtual wiphy index into the least significant bits to generate
	 * a different MAC address for each virtual wiphy.
	 */
	addr[5] ^= i & 0xff;
	addr[4] ^= (i & 0xff00) >> 8;
	addr[3] ^= (i & 0xff0000) >> 16;

	SET_IEEE80211_PERM_ADDR(hw, addr);

	ath_set_hw_capab(sc, hw);

	error = ieee80211_register_hw(hw);

	if (error == 0) {
		/* Make sure wiphy scheduler is started (if enabled) */
		ath9k_wiphy_set_scheduler(sc, sc->wiphy_scheduler_int);
	}

	return error;
}
Example #14
0
int mt76_register_device(struct mt76_dev *dev, bool vht,
			 struct ieee80211_rate *rates, int n_rates)
{
	struct ieee80211_hw *hw = dev->hw;
	struct wiphy *wiphy = hw->wiphy;
	int ret;

	dev_set_drvdata(dev->dev, dev);

	INIT_LIST_HEAD(&dev->txwi_cache);

	SET_IEEE80211_DEV(hw, dev->dev);
	SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);

	wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;

	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);

	wiphy->available_antennas_tx = dev->antenna_mask;
	wiphy->available_antennas_rx = dev->antenna_mask;

	hw->txq_data_size = sizeof(struct mt76_txq);
	hw->max_tx_fragments = 16;

	ieee80211_hw_set(hw, SIGNAL_DBM);
	ieee80211_hw_set(hw, PS_NULLFUNC_STACK);
	ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
	ieee80211_hw_set(hw, AMPDU_AGGREGATION);
	ieee80211_hw_set(hw, SUPPORTS_RC_TABLE);
	ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
	ieee80211_hw_set(hw, SUPPORTS_CLONED_SKBS);
	ieee80211_hw_set(hw, SUPPORTS_AMSDU_IN_AMPDU);
	ieee80211_hw_set(hw, TX_AMSDU);
	ieee80211_hw_set(hw, TX_FRAG_LIST);
	ieee80211_hw_set(hw, MFP_CAPABLE);
	ieee80211_hw_set(hw, AP_LINK_PS);
	ieee80211_hw_set(hw, REPORTS_TX_ACK_STATUS);
	ieee80211_hw_set(hw, NEEDS_UNIQUE_STA_ADDR);

	wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

	if (dev->cap.has_2ghz) {
		ret = mt76_init_sband_2g(dev, rates, n_rates);
		if (ret)
			return ret;
	}

	if (dev->cap.has_5ghz) {
		ret = mt76_init_sband_5g(dev, rates + 4, n_rates - 4, vht);
		if (ret)
			return ret;
	}

	wiphy_read_of_freq_limits(dev->hw->wiphy);
	mt76_check_sband(dev, NL80211_BAND_2GHZ);
	mt76_check_sband(dev, NL80211_BAND_5GHZ);

	if (IS_ENABLED(CONFIG_MT76_LEDS)) {
		ret = mt76_led_init(dev);
		if (ret)
			return ret;
	}

	return ieee80211_register_hw(hw);
}
Example #15
0
static int __devinit rtl8180_probe(struct pci_dev *pdev,
				   const struct pci_device_id *id)
{
	struct ieee80211_hw *dev;
	struct rtl8180_priv *priv;
	unsigned long mem_addr, mem_len;
	unsigned int io_addr, io_len;
	int err, i;
	struct eeprom_93cx6 eeprom;
	const char *chip_name, *rf_name = NULL;
	u32 reg;
	u16 eeprom_val;

	err = pci_enable_device(pdev);
	if (err) {
		printk(KERN_ERR "%s (rtl8180): Cannot enable new PCI device\n",
		       pci_name(pdev));
		return err;
	}

	err = pci_request_regions(pdev, KBUILD_MODNAME);
	if (err) {
		printk(KERN_ERR "%s (rtl8180): Cannot obtain PCI resources\n",
		       pci_name(pdev));
		return err;
	}

	io_addr = pci_resource_start(pdev, 0);
	io_len = pci_resource_len(pdev, 0);
	mem_addr = pci_resource_start(pdev, 1);
	mem_len = pci_resource_len(pdev, 1);

	if (mem_len < sizeof(struct rtl818x_csr) ||
	    io_len < sizeof(struct rtl818x_csr)) {
		printk(KERN_ERR "%s (rtl8180): Too short PCI resources\n",
		       pci_name(pdev));
		err = -ENOMEM;
		goto err_free_reg;
	}

	if ((err = pci_set_dma_mask(pdev, 0xFFFFFF00ULL)) ||
	    (err = pci_set_consistent_dma_mask(pdev, 0xFFFFFF00ULL))) {
		printk(KERN_ERR "%s (rtl8180): No suitable DMA available\n",
		       pci_name(pdev));
		goto err_free_reg;
	}

	pci_set_master(pdev);

	dev = ieee80211_alloc_hw(sizeof(*priv), &rtl8180_ops);
	if (!dev) {
		printk(KERN_ERR "%s (rtl8180): ieee80211 alloc failed\n",
		       pci_name(pdev));
		err = -ENOMEM;
		goto err_free_reg;
	}

	priv = dev->priv;
	priv->pdev = pdev;

	dev->max_rates = 2;
	SET_IEEE80211_DEV(dev, &pdev->dev);
	pci_set_drvdata(pdev, dev);

	priv->map = pci_iomap(pdev, 1, mem_len);
	if (!priv->map)
		priv->map = pci_iomap(pdev, 0, io_len);

	if (!priv->map) {
		printk(KERN_ERR "%s (rtl8180): Cannot map device memory\n",
		       pci_name(pdev));
		goto err_free_dev;
	}

	BUILD_BUG_ON(sizeof(priv->channels) != sizeof(rtl818x_channels));
	BUILD_BUG_ON(sizeof(priv->rates) != sizeof(rtl818x_rates));

	memcpy(priv->channels, rtl818x_channels, sizeof(rtl818x_channels));
	memcpy(priv->rates, rtl818x_rates, sizeof(rtl818x_rates));

	priv->band.band = IEEE80211_BAND_2GHZ;
	priv->band.channels = priv->channels;
	priv->band.n_channels = ARRAY_SIZE(rtl818x_channels);
	priv->band.bitrates = priv->rates;
	priv->band.n_bitrates = 4;
	dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;

	dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
		     IEEE80211_HW_RX_INCLUDES_FCS |
		     IEEE80211_HW_SIGNAL_UNSPEC;
	dev->queues = 1;
	dev->max_signal = 65;

	reg = rtl818x_ioread32(priv, &priv->map->TX_CONF);
	reg &= RTL818X_TX_CONF_HWVER_MASK;
	switch (reg) {
	case RTL818X_TX_CONF_R8180_ABCD:
		chip_name = "RTL8180";
		break;
	case RTL818X_TX_CONF_R8180_F:
		chip_name = "RTL8180vF";
		break;
	case RTL818X_TX_CONF_R8185_ABC:
		chip_name = "RTL8185";
		break;
	case RTL818X_TX_CONF_R8185_D:
		chip_name = "RTL8185vD";
		break;
	default:
		printk(KERN_ERR "%s (rtl8180): Unknown chip! (0x%x)\n",
		       pci_name(pdev), reg >> 25);
		goto err_iounmap;
	}

	priv->r8185 = reg & RTL818X_TX_CONF_R8185_ABC;
	if (priv->r8185) {
		priv->band.n_bitrates = ARRAY_SIZE(rtl818x_rates);
		pci_try_set_mwi(pdev);
	}

	eeprom.data = dev;
	eeprom.register_read = rtl8180_eeprom_register_read;
	eeprom.register_write = rtl8180_eeprom_register_write;
	if (rtl818x_ioread32(priv, &priv->map->RX_CONF) & (1 << 6))
		eeprom.width = PCI_EEPROM_WIDTH_93C66;
	else
		eeprom.width = PCI_EEPROM_WIDTH_93C46;

	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_PROGRAM);
	rtl818x_ioread8(priv, &priv->map->EEPROM_CMD);
	udelay(10);

	eeprom_93cx6_read(&eeprom, 0x06, &eeprom_val);
	eeprom_val &= 0xFF;
	switch (eeprom_val) {
	case 1:	rf_name = "Intersil";
		break;
	case 2:	rf_name = "RFMD";
		break;
	case 3:	priv->rf = &sa2400_rf_ops;
		break;
	case 4:	priv->rf = &max2820_rf_ops;
		break;
	case 5:	priv->rf = &grf5101_rf_ops;
		break;
	case 9:	priv->rf = rtl8180_detect_rf(dev);
		break;
	case 10:
		rf_name = "RTL8255";
		break;
	default:
		printk(KERN_ERR "%s (rtl8180): Unknown RF! (0x%x)\n",
		       pci_name(pdev), eeprom_val);
		goto err_iounmap;
	}

	if (!priv->rf) {
		printk(KERN_ERR "%s (rtl8180): %s RF frontend not supported!\n",
		       pci_name(pdev), rf_name);
		goto err_iounmap;
	}

	eeprom_93cx6_read(&eeprom, 0x17, &eeprom_val);
	priv->csthreshold = eeprom_val >> 8;
	if (!priv->r8185) {
		__le32 anaparam;
		eeprom_93cx6_multiread(&eeprom, 0xD, (__le16 *)&anaparam, 2);
		priv->anaparam = le32_to_cpu(anaparam);
		eeprom_93cx6_read(&eeprom, 0x19, &priv->rfparam);
	}

	eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)dev->wiphy->perm_addr, 3);
	if (!is_valid_ether_addr(dev->wiphy->perm_addr)) {
		printk(KERN_WARNING "%s (rtl8180): Invalid hwaddr! Using"
		       " randomly generated MAC addr\n", pci_name(pdev));
		random_ether_addr(dev->wiphy->perm_addr);
	}

	/* CCK TX power */
	for (i = 0; i < 14; i += 2) {
		u16 txpwr;
		eeprom_93cx6_read(&eeprom, 0x10 + (i >> 1), &txpwr);
		priv->channels[i].hw_value = txpwr & 0xFF;
		priv->channels[i + 1].hw_value = txpwr >> 8;
	}

	/* OFDM TX power */
	if (priv->r8185) {
		for (i = 0; i < 14; i += 2) {
			u16 txpwr;
			eeprom_93cx6_read(&eeprom, 0x20 + (i >> 1), &txpwr);
			priv->channels[i].hw_value |= (txpwr & 0xFF) << 8;
			priv->channels[i + 1].hw_value |= txpwr & 0xFF00;
		}
	}

	rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_NORMAL);

	spin_lock_init(&priv->lock);

	err = ieee80211_register_hw(dev);
	if (err) {
		printk(KERN_ERR "%s (rtl8180): Cannot register device\n",
		       pci_name(pdev));
		goto err_iounmap;
	}

	printk(KERN_INFO "%s: hwaddr %pM, %s + %s\n",
	       wiphy_name(dev->wiphy), dev->wiphy->perm_addr,
	       chip_name, priv->rf->name);

	return 0;

 err_iounmap:
	iounmap(priv->map);

 err_free_dev:
	pci_set_drvdata(pdev, NULL);
	ieee80211_free_hw(dev);

 err_free_reg:
	pci_release_regions(pdev);
	pci_disable_device(pdev);
	return err;
}
Example #16
0
int mt76_register_device(struct mt76_dev *dev)
{
	struct ieee80211_hw *hw = dev->hw;
	struct wiphy *wiphy = hw->wiphy;
	void *status_fifo;
	int fifo_size;
	int i, ret;

	fifo_size = roundup_pow_of_two(32 * sizeof(struct mt76_tx_status));
	status_fifo = devm_kzalloc(dev->dev, fifo_size, GFP_KERNEL);
	if (!status_fifo)
		return -ENOMEM;

	kfifo_init(&dev->txstatus_fifo, status_fifo, fifo_size);

	ret = mt76_init_hardware(dev);
	if (ret)
		return ret;

	SET_IEEE80211_DEV(hw, dev->dev);

	hw->queues = 4;
	hw->flags = IEEE80211_HW_SIGNAL_DBM |
		    IEEE80211_HW_PS_NULLFUNC_STACK |
		    IEEE80211_HW_SUPPORTS_HT_CCK_RATES |
		    IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
		    IEEE80211_HW_AMPDU_AGGREGATION |
		    IEEE80211_HW_SUPPORTS_RC_TABLE;
	hw->max_rates = 1;
	hw->max_report_rates = 7;
	hw->max_rate_tries = 1;

	hw->sta_data_size = sizeof(struct mt76_sta);
	hw->vif_data_size = sizeof(struct mt76_vif);
	hw->txq_data_size = sizeof(struct mt76_txq);

	dev->macaddr[0] &= ~BIT(1);
	SET_IEEE80211_PERM_ADDR(hw, dev->macaddr);

	for (i = 0; i < ARRAY_SIZE(dev->macaddr_list); i++) {
		u8 *addr = dev->macaddr_list[i].addr;
		memcpy(addr, dev->macaddr, ETH_ALEN);

		if (!i)
			continue;

		addr[0] |= BIT(1);
		addr[0] ^= ((i - 1) << 2);
	}
	wiphy->addresses = dev->macaddr_list;
	wiphy->n_addresses = ARRAY_SIZE(dev->macaddr_list);

	wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;

	wiphy->interface_modes =
		BIT(NL80211_IFTYPE_STATION) |
		BIT(NL80211_IFTYPE_AP) |
#ifdef CONFIG_MAC80211_MESH
		BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
		BIT(NL80211_IFTYPE_ADHOC);

	wiphy->iface_combinations = if_comb;
	wiphy->n_iface_combinations = ARRAY_SIZE(if_comb);

	ret = mt76_init_sband_2g(dev);
	if (ret)
		goto fail;

	ret = mt76_init_sband_5g(dev);
	if (ret)
		goto fail;

	INIT_LIST_HEAD(&dev->txwi_cache);
	INIT_DELAYED_WORK(&dev->cal_work, mt76_phy_calibrate);
	INIT_DELAYED_WORK(&dev->mac_work, mt76_mac_work);

	ret = ieee80211_register_hw(hw);
	if (ret)
		goto fail;

	mt76_init_debugfs(dev);

	return 0;

fail:
	mt76_stop_hardware(dev);
	return ret;
}
Example #17
0
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
{
	struct hw_mode_spec *spec = &rt2x00dev->spec;
	int status;

	if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
		return 0;

	/*
	 * Initialize HW modes.
	 */
	status = rt2x00lib_probe_hw_modes(rt2x00dev, spec);
	if (status)
		return status;

	/*
	 * Initialize HW fields.
	 */
	rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;

	/*
	 * Initialize extra TX headroom required.
	 */
	rt2x00dev->hw->extra_tx_headroom =
		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
		      rt2x00dev->ops->extra_tx_headroom);

	/*
	 * Take TX headroom required for alignment into account.
	 */
	if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
	else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;

	/*
	 * Allocate tx status FIFO for driver use.
	 */
	if (test_bit(DRIVER_REQUIRE_TXSTATUS_FIFO, &rt2x00dev->flags) &&
	    rt2x00dev->ops->lib->txstatus_tasklet) {
		/*
		 * Allocate txstatus fifo and tasklet, we use a size of 512
		 * for the kfifo which is big enough to store 512/4=128 tx
		 * status reports. In the worst case (tx status for all tx
		 * queues gets reported before we've got a chance to handle
		 * them) 24*4=384 tx status reports need to be cached.
		 */
		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, 512,
				     GFP_KERNEL);
		if (status)
			return status;

		/* tasklet for processing the tx status reports. */
		tasklet_init(&rt2x00dev->txstatus_tasklet,
			     rt2x00dev->ops->lib->txstatus_tasklet,
			     (unsigned long)rt2x00dev);

	}

	/*
	 * Register HW.
	 */
	status = ieee80211_register_hw(rt2x00dev->hw);
	if (status)
		return status;

	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);

	return 0;
}
Example #18
0
static int __devinit agnx_pci_probe(struct pci_dev *pdev,
				    const struct pci_device_id *id)
{
	struct ieee80211_hw *dev;
	struct agnx_priv *priv;
	int err;

	err = pci_enable_device(pdev);
	if (err) {
		dev_err(&pdev->dev, "can't enable pci device\n");
		return err;
	}

	err = pci_request_regions(pdev, "agnx-pci");
	if (err) {
		dev_err(&pdev->dev, "can't reserve PCI resources\n");
		return err;
	}

	if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) ||
	    pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
		dev_err(&pdev->dev, "no suitable DMA available\n");
		err = -EIO;
		goto err_free_reg;
	}

	pci_set_master(pdev);

	dev = ieee80211_alloc_hw(sizeof(*priv), &agnx_ops);
	if (!dev) {
		dev_err(&pdev->dev, "ieee80211 alloc failed\n");
		err = -ENOMEM;
		goto err_free_reg;
	}
	priv = dev->priv;
	memset(priv, 0, sizeof(*priv));
	priv->mode = NL80211_IFTYPE_MONITOR;
	priv->pdev = pdev;
	priv->hw = dev;
	spin_lock_init(&priv->lock);
	priv->init_status = AGNX_UNINIT;

	priv->ctl = pci_iomap(pdev, 0, 0);
/*	dev_dbg(&pdev->dev, "MEM1 mapped address is 0x%p\n", priv->ctl); */
	if (!priv->ctl) {
		dev_err(&pdev->dev, "can't map device memory\n");
		err = -ENOMEM;
		goto err_free_dev;
	}
	priv->data = pci_iomap(pdev, 1, 0);
	if (!priv->data) {
		dev_err(&pdev->dev, "can't map device memory\n");
		err = -ENOMEM;
		goto err_iounmap2;
	}

	pci_read_config_byte(pdev, PCI_REVISION_ID, &priv->revid);

	priv->band.channels   = (struct ieee80211_channel *)agnx_channels;
	priv->band.n_channels = ARRAY_SIZE(agnx_channels);
	priv->band.bitrates   = (struct ieee80211_rate *)agnx_rates_80211g;
	priv->band.n_bitrates = ARRAY_SIZE(agnx_rates_80211g);

	/* Init ieee802.11 dev  */
	SET_IEEE80211_DEV(dev, &pdev->dev);
	pci_set_drvdata(pdev, dev);
	dev->extra_tx_headroom = sizeof(struct agnx_hdr);

	/* FIXME It only include FCS in promious mode but not manage mode */
/*      dev->flags =  IEEE80211_HW_RX_INCLUDES_FCS; */
	dev->channel_change_time = 5000;
	dev->max_signal = 100;
	/* FIXME */
	dev->queues = 1;

	agnx_get_mac_address(priv);

	SET_IEEE80211_PERM_ADDR(dev, priv->mac_addr);

/* 	/\* FIXME *\/ */
/* 	for (i = 1; i < NUM_DRIVE_MODES; i++) { */
/* 		err = ieee80211_register_hwmode(dev, &priv->modes[i]); */
/* 		if (err) { */
/* 			printk(KERN_ERR PFX "Can't register hwmode\n"); */
/* 			goto  err_iounmap; */
/* 		} */
/* 	} */

	priv->channel = 1;
	dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;

	err = ieee80211_register_hw(dev);
	if (err) {
		dev_err(&pdev->dev, "can't register hardware\n");
		goto err_iounmap;
	}

	agnx_hw_reset(priv);

	dev_info(&pdev->dev, "%s: hwaddr %pM, Rev 0x%02x\n",
		wiphy_name(dev->wiphy),
		dev->wiphy->perm_addr, priv->revid);
	return 0;

 err_iounmap:
	pci_iounmap(pdev, priv->data);

 err_iounmap2:
	pci_iounmap(pdev, priv->ctl);

 err_free_dev:
	pci_set_drvdata(pdev, NULL);
	ieee80211_free_hw(dev);

 err_free_reg:
	pci_release_regions(pdev);

	pci_disable_device(pdev);
	return err;
} /* agnx_pci_probe*/
Example #19
0
int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
{
    struct ieee80211_hw *hw = mvm->hw;
    int num_mac, ret;

    /* Tell mac80211 our characteristics */
    hw->flags = IEEE80211_HW_SIGNAL_DBM |
                IEEE80211_HW_SPECTRUM_MGMT |
                IEEE80211_HW_REPORTS_TX_ACK_STATUS |
                IEEE80211_HW_QUEUE_CONTROL |
                IEEE80211_HW_WANT_MONITOR_VIF |
                IEEE80211_HW_SUPPORTS_PS |
                IEEE80211_HW_SUPPORTS_DYNAMIC_PS |
                IEEE80211_HW_AMPDU_AGGREGATION |
                IEEE80211_HW_TIMING_BEACON_ONLY;

    hw->queues = IWL_FIRST_AMPDU_QUEUE;
    hw->offchannel_tx_hw_queue = IWL_OFFCHANNEL_QUEUE;
    hw->rate_control_algorithm = "iwl-mvm-rs";

    /*
     * Enable 11w if advertised by firmware and software crypto
     * is not enabled (as the firmware will interpret some mgmt
     * packets, so enabling it with software crypto isn't safe)
     */
    if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_MFP &&
            !iwlwifi_mod_params.sw_crypto)
        hw->flags |= IEEE80211_HW_MFP_CAPABLE;

    hw->sta_data_size = sizeof(struct iwl_mvm_sta);
    hw->vif_data_size = sizeof(struct iwl_mvm_vif);
    hw->chanctx_data_size = sizeof(struct iwl_mvm_phy_ctxt);

    hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
                                 BIT(NL80211_IFTYPE_P2P_CLIENT) |
                                 BIT(NL80211_IFTYPE_AP) |
                                 BIT(NL80211_IFTYPE_P2P_GO) |
                                 BIT(NL80211_IFTYPE_P2P_DEVICE);

    hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
                        WIPHY_FLAG_DISABLE_BEACON_HINTS |
                        WIPHY_FLAG_IBSS_RSN;

    hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
    hw->wiphy->n_iface_combinations =
        ARRAY_SIZE(iwl_mvm_iface_combinations);

    hw->wiphy->max_remain_on_channel_duration = 500;
    hw->max_listen_interval = IWL_CONN_MAX_LISTEN_INTERVAL;

    /* Extract MAC address */
    memcpy(mvm->addresses[0].addr, mvm->nvm_data->hw_addr, ETH_ALEN);
    hw->wiphy->addresses = mvm->addresses;
    hw->wiphy->n_addresses = 1;
    num_mac = mvm->nvm_data->n_hw_addrs;
    if (num_mac > 1) {
        memcpy(mvm->addresses[1].addr, mvm->addresses[0].addr,
               ETH_ALEN);
        mvm->addresses[1].addr[5]++;
        hw->wiphy->n_addresses++;
    }

    /* we create the 802.11 header and a max-length SSID element */
    hw->wiphy->max_scan_ie_len =
        mvm->fw->ucode_capa.max_probe_length - 24 - 34;
    hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX;

    if (mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels)
        hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
            &mvm->nvm_data->bands[IEEE80211_BAND_2GHZ];
    if (mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels)
        hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
            &mvm->nvm_data->bands[IEEE80211_BAND_5GHZ];

    hw->wiphy->hw_version = mvm->trans->hw_id;

    if (iwlwifi_mod_params.power_save)
        hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
    else
        hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;

    hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
                           NL80211_FEATURE_P2P_GO_OPPPS;

    mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;

#ifdef CONFIG_PM_SLEEP
    if (mvm->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
            mvm->trans->ops->d3_suspend &&
            mvm->trans->ops->d3_resume &&
            device_can_wakeup(mvm->trans->dev)) {
        hw->wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
                                  WIPHY_WOWLAN_DISCONNECT |
                                  WIPHY_WOWLAN_EAP_IDENTITY_REQ |
                                  WIPHY_WOWLAN_RFKILL_RELEASE;
        if (!iwlwifi_mod_params.sw_crypto)
            hw->wiphy->wowlan.flags |=
                WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
                WIPHY_WOWLAN_GTK_REKEY_FAILURE |
                WIPHY_WOWLAN_4WAY_HANDSHAKE;

        hw->wiphy->wowlan.n_patterns = IWL_WOWLAN_MAX_PATTERNS;
        hw->wiphy->wowlan.pattern_min_len = IWL_WOWLAN_MIN_PATTERN_LEN;
        hw->wiphy->wowlan.pattern_max_len = IWL_WOWLAN_MAX_PATTERN_LEN;
    }
#endif

    ret = iwl_mvm_leds_init(mvm);
    if (ret)
        return ret;

    return ieee80211_register_hw(mvm->hw);
}
Example #20
0
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;
}
Example #21
0
static int ar5523_probe(struct usb_interface *intf,
			const struct usb_device_id *id)
{
	struct usb_device *dev = interface_to_usbdev(intf);
	struct ieee80211_hw *hw;
	struct ar5523 *ar;
	int error = -ENOMEM;

	/*
	 * Load firmware if the device requires it.  This will return
	 * -ENXIO on success and we'll get called back afer the usb
	 * id changes to indicate that the firmware is present.
	 */
	if (id->driver_info & AR5523_FLAG_PRE_FIRMWARE)
		return ar5523_load_firmware(dev);


	hw = ieee80211_alloc_hw(sizeof(*ar), &ar5523_ops);
	if (!hw)
		goto out;
	SET_IEEE80211_DEV(hw, &intf->dev);

	ar = hw->priv;
	ar->hw = hw;
	ar->dev = dev;
	mutex_init(&ar->mutex);

	INIT_DELAYED_WORK(&ar->stat_work, ar5523_stat_work);
	init_timer(&ar->tx_wd_timer);
	setup_timer(&ar->tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar);
	INIT_WORK(&ar->tx_wd_work, ar5523_tx_wd_work);
	INIT_WORK(&ar->tx_work, ar5523_tx_work);
	INIT_LIST_HEAD(&ar->tx_queue_pending);
	INIT_LIST_HEAD(&ar->tx_queue_submitted);
	spin_lock_init(&ar->tx_data_list_lock);
	atomic_set(&ar->tx_nr_total, 0);
	atomic_set(&ar->tx_nr_pending, 0);
	init_waitqueue_head(&ar->tx_flush_waitq);

	atomic_set(&ar->rx_data_free_cnt, 0);
	INIT_WORK(&ar->rx_refill_work, ar5523_rx_refill_work);
	INIT_LIST_HEAD(&ar->rx_data_free);
	INIT_LIST_HEAD(&ar->rx_data_used);
	spin_lock_init(&ar->rx_data_list_lock);

	ar->wq = create_singlethread_workqueue("ar5523");
	if (!ar->wq) {
		ar5523_err(ar, "Could not create wq\n");
		goto out_free_ar;
	}

	error = ar5523_alloc_rx_bufs(ar);
	if (error) {
		ar5523_err(ar, "Could not allocate rx buffers\n");
		goto out_free_wq;
	}

	error = ar5523_alloc_rx_cmd(ar);
	if (error) {
		ar5523_err(ar, "Could not allocate rx command buffers\n");
		goto out_free_rx_bufs;
	}

	error = ar5523_alloc_tx_cmd(ar);
	if (error) {
		ar5523_err(ar, "Could not allocate tx command buffers\n");
		goto out_free_rx_cmd;
	}

	error = ar5523_submit_rx_cmd(ar);
	if (error) {
		ar5523_err(ar, "Failed to submit rx cmd\n");
		goto out_free_tx_cmd;
	}

	/*
	 * We're now ready to send/receive firmware commands.
	 */
	error = ar5523_host_available(ar);
	if (error) {
		ar5523_err(ar, "could not initialize adapter\n");
		goto out_cancel_rx_cmd;
	}

	error = ar5523_get_max_rxsz(ar);
	if (error) {
		ar5523_err(ar, "could not get caps from adapter\n");
		goto out_cancel_rx_cmd;
	}

	error = ar5523_get_devcap(ar);
	if (error) {
		ar5523_err(ar, "could not get caps from adapter\n");
		goto out_cancel_rx_cmd;
	}

	error = ar5523_get_devstatus(ar);
	if (error != 0) {
		ar5523_err(ar, "could not get device status\n");
		goto out_cancel_rx_cmd;
	}

	ar5523_info(ar, "MAC/BBP AR5523, RF AR%c112\n",
			(id->driver_info & AR5523_FLAG_ABG) ? '5' : '2');

	ar->vif = NULL;
	hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
		    IEEE80211_HW_SIGNAL_DBM |
		    IEEE80211_HW_HAS_RATE_CONTROL;
	hw->extra_tx_headroom = sizeof(struct ar5523_tx_desc) +
				sizeof(struct ar5523_chunk);
	hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
	hw->queues = 1;

	error = ar5523_init_modes(ar);
	if (error)
		goto out_cancel_rx_cmd;

	usb_set_intfdata(intf, hw);

	error = ieee80211_register_hw(hw);
	if (error) {
		ar5523_err(ar, "could not register device\n");
		goto out_cancel_rx_cmd;
	}

	ar5523_info(ar, "Found and initialized AR5523 device\n");
	return 0;

out_cancel_rx_cmd:
	ar5523_cancel_rx_cmd(ar);
out_free_tx_cmd:
	ar5523_free_tx_cmd(ar);
out_free_rx_cmd:
	ar5523_free_rx_cmd(ar);
out_free_rx_bufs:
	ar5523_free_rx_bufs(ar);
out_free_wq:
	destroy_workqueue(ar->wq);
out_free_ar:
	ieee80211_free_hw(hw);
out:
	return error;
}
static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
{
	struct hw_mode_spec *spec = &rt2x00dev->spec;
	int status;

	if (test_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags))
		return 0;

	/*
	 * Initialize HW modes.
	 */
	status = rt2x00lib_probe_hw_modes(rt2x00dev, spec);
	if (status)
		return status;

	/*
	 * Initialize HW fields.
	 */
	rt2x00dev->hw->queues = rt2x00dev->ops->tx_queues;

	/*
	 * Initialize extra TX headroom required.
	 */
	rt2x00dev->hw->extra_tx_headroom =
		max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
		      rt2x00dev->ops->extra_tx_headroom);

	/*
	 * Take TX headroom required for alignment into account.
	 */
	if (test_bit(REQUIRE_L2PAD, &rt2x00dev->cap_flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
	else if (test_bit(REQUIRE_DMA, &rt2x00dev->cap_flags))
		rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;

	/*
	 * Tell mac80211 about the size of our private STA structure.
	 */
	rt2x00dev->hw->sta_data_size = sizeof(struct rt2x00_sta);

	/*
	 * Allocate tx status FIFO for driver use.
	 */
	if (test_bit(REQUIRE_TXSTATUS_FIFO, &rt2x00dev->cap_flags)) {
		/*
		 * Allocate the txstatus fifo. In the worst case the tx
		 * status fifo has to hold the tx status of all entries
		 * in all tx queues. Hence, calculate the kfifo size as
		 * tx_queues * entry_num and round up to the nearest
		 * power of 2.
		 */
		int kfifo_size =
			roundup_pow_of_two(rt2x00dev->ops->tx_queues *
					   rt2x00dev->ops->tx->entry_num *
					   sizeof(u32));

		status = kfifo_alloc(&rt2x00dev->txstatus_fifo, kfifo_size,
				     GFP_KERNEL);
		if (status)
			return status;
	}

	/*
	 * Initialize tasklets if used by the driver. Tasklets are
	 * disabled until the interrupts are turned on. The driver
	 * has to handle that.
	 */
#define RT2X00_TASKLET_INIT(taskletname) \
	if (rt2x00dev->ops->lib->taskletname) { \
		tasklet_init(&rt2x00dev->taskletname, \
			     rt2x00dev->ops->lib->taskletname, \
			     (unsigned long)rt2x00dev); \
	}

	RT2X00_TASKLET_INIT(txstatus_tasklet);
	RT2X00_TASKLET_INIT(pretbtt_tasklet);
	RT2X00_TASKLET_INIT(tbtt_tasklet);
	RT2X00_TASKLET_INIT(rxdone_tasklet);
	RT2X00_TASKLET_INIT(autowake_tasklet);

#undef RT2X00_TASKLET_INIT

	/*
	 * Register HW.
	 */
	status = ieee80211_register_hw(rt2x00dev->hw);
	if (status)
		return status;

	set_bit(DEVICE_STATE_REGISTERED_HW, &rt2x00dev->flags);

	return 0;
}
Example #23
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.
 *
 * wl_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 wl_pci_probe() context, therefore no locking required.
 */
static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs,
			    uint bustype, void *btparam, uint irq)
{
	struct wl_info *wl = NULL;
	int unit, err;

	unsigned long base_addr;
	struct ieee80211_hw *hw;
	u8 perm[ETH_ALEN];

	unit = wl_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, wl_dpc, (unsigned long) wl);



	base_addr = regs;

	if (bustype == PCI_BUS) {
		wl->piomode = false;
	} else if (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 (wl_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");
		wl_release_fw(wl);
		wl_remove((struct pci_dev *)btparam);
		return NULL;
	}

	/* common load-time initialization */
	wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode,
			     wl->regsva, wl->bcm_bustype, btparam, &err);
	wl_release_fw(wl);
	if (!wl->wlc) {
		wiphy_err(wl->wiphy, "%s: wlc_attach() failed with code %d\n",
			  KBUILD_MODNAME, err);
		goto fail;
	}
	wl->pub = wlc_pub(wl->wlc);

	wl->pub->ieee_hw = hw;

	if (wlc_iovar_setint(wl->wlc, "mpc", 0)) {
		wiphy_err(wl->wiphy, "wl%d: Error setting MPC variable to 0\n",
			  unit);
	}

	/* register our interrupt handler */
	if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) {
		wiphy_err(wl->wiphy, "wl%d: request_irq() failed\n", unit);
		goto fail;
	}
	wl->irq = irq;

	/* register module */
	wlc_module_register(wl->pub, NULL, "linux", wl, NULL, 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 = wl_set_hint(wl, wl->pub->srom_ccode);
	else
		err = wl_set_hint(wl, "US");
	if (err) {
		wiphy_err(wl->wiphy, "%s: regulatory_hint failed, status %d\n",
			  __func__, err);
	}

	wl_found++;
	return wl;

fail:
	wl_free(wl);
	return NULL;
}
Example #24
0
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;
}
Example #25
0
int rtl_usb_probe(struct usb_interface *intf,
                  const struct usb_device_id *id,
                  struct rtl_hal_cfg *rtl_hal_cfg)
{
    int err;
    struct ieee80211_hw *hw = NULL;
    struct rtl_priv *rtlpriv = NULL;
    struct usb_device	*udev;
    struct rtl_usb_priv *usb_priv;

    hw = ieee80211_alloc_hw(sizeof(struct rtl_priv) +
                            sizeof(struct rtl_usb_priv), &rtl_ops);
    if (!hw) {
        RT_ASSERT(false, "ieee80211 alloc failed\n");
        return -ENOMEM;
    }
    rtlpriv = hw->priv;
    rtlpriv->usb_data = kzalloc(RTL_USB_MAX_RX_COUNT * sizeof(u32),
                                GFP_KERNEL);
    if (!rtlpriv->usb_data)
        return -ENOMEM;

    /* this spin lock must be initialized early */
    spin_lock_init(&rtlpriv->locks.usb_lock);
    INIT_WORK(&rtlpriv->works.fill_h2c_cmd,
              rtl_fill_h2c_cmd_work_callback);
    INIT_WORK(&rtlpriv->works.lps_change_work,
              rtl_lps_change_work_callback);

    rtlpriv->usb_data_index = 0;
    init_completion(&rtlpriv->firmware_loading_complete);
    SET_IEEE80211_DEV(hw, &intf->dev);
    udev = interface_to_usbdev(intf);
    usb_get_dev(udev);
    usb_priv = rtl_usbpriv(hw);
    memset(usb_priv, 0, sizeof(*usb_priv));
    usb_priv->dev.intf = intf;
    usb_priv->dev.udev = udev;
    usb_set_intfdata(intf, hw);
    /* init cfg & intf_ops */
    rtlpriv->rtlhal.interface = INTF_USB;
    rtlpriv->cfg = rtl_hal_cfg;
    rtlpriv->intf_ops = &rtl_usb_ops;
    rtl_dbgp_flag_init(hw);
    /* Init IO handler */
    _rtl_usb_io_handler_init(&udev->dev, hw);
    rtlpriv->cfg->ops->read_chip_version(hw);
    /*like read eeprom and so on */
    rtlpriv->cfg->ops->read_eeprom_info(hw);
    err = _rtl_usb_init(hw);
    if (err)
        goto error_out;
    rtl_usb_init_sw(hw);
    /* Init mac80211 sw */
    err = rtl_init_core(hw);
    if (err) {
        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                 "Can't allocate sw for mac80211\n");
        goto error_out;
    }
    if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n");
        goto error_out;
    }
    rtlpriv->cfg->ops->init_sw_leds(hw);

    err = ieee80211_register_hw(hw);
    if (err) {
        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
                 "Can't register mac80211 hw.\n");
        err = -ENODEV;
        goto error_out;
    }
    rtlpriv->mac80211.mac80211_registered = 1;

    set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
    return 0;

error_out:
    rtl_deinit_core(hw);
    _rtl_usb_io_handler_release(hw);
    usb_put_dev(udev);
    complete(&rtlpriv->firmware_loading_complete);
    return -ENODEV;
}
Example #26
0
int __devinit rtl_pci_probe(struct pci_dev *pdev,
			    const struct pci_device_id *id)
{
	struct ieee80211_hw *hw = NULL;

	struct rtl_priv *rtlpriv = NULL;
	struct rtl_pci_priv *pcipriv = NULL;
	struct rtl_pci *rtlpci;
	unsigned long pmem_start, pmem_len, pmem_flags;
	int err;

	err = pci_enable_device(pdev);
	if (err) {
		RT_ASSERT(false,
			  ("%s : Cannot enable new PCI device\n",
			   pci_name(pdev)));
		return err;
	}

	if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) {
		if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) {
			RT_ASSERT(false, ("Unable to obtain 32bit DMA "
					  "for consistent allocations\n"));
			pci_disable_device(pdev);
			return -ENOMEM;
		}
	}

	pci_set_master(pdev);

	hw = ieee80211_alloc_hw(sizeof(struct rtl_pci_priv) +
				sizeof(struct rtl_priv), &rtl_ops);
	if (!hw) {
		RT_ASSERT(false,
			  ("%s : ieee80211 alloc failed\n", pci_name(pdev)));
		err = -ENOMEM;
		goto fail1;
	}

	SET_IEEE80211_DEV(hw, &pdev->dev);
	pci_set_drvdata(pdev, hw);

	rtlpriv = hw->priv;
	pcipriv = (void *)rtlpriv->priv;
	pcipriv->dev.pdev = pdev;

	/*
	 *init dbgp flags before all
	 *other functions, because we will
	 *use it in other funtions like
	 *RT_TRACE/RT_PRINT/RTL_PRINT_DATA
	 *you can not use these macro
	 *before this
	 */
	rtl_dbgp_flag_init(hw);

	/* MEM map */
	err = pci_request_regions(pdev, KBUILD_MODNAME);
	if (err) {
		RT_ASSERT(false, ("Can't obtain PCI resources\n"));
		return err;
	}

	pmem_start = pci_resource_start(pdev, 2);
	pmem_len = pci_resource_len(pdev, 2);
	pmem_flags = pci_resource_flags(pdev, 2);

	/*shared mem start */
	rtlpriv->io.pci_mem_start =
			(unsigned long)pci_iomap(pdev, 2, pmem_len);
	if (rtlpriv->io.pci_mem_start == 0) {
		RT_ASSERT(false, ("Can't map PCI mem\n"));
		goto fail2;
	}

	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
		 ("mem mapped space: start: 0x%08lx len:%08lx "
		  "flags:%08lx, after map:0x%08lx\n",
		  pmem_start, pmem_len, pmem_flags,
		  rtlpriv->io.pci_mem_start));

	/* Disable Clk Request */
	pci_write_config_byte(pdev, 0x81, 0);
	/* leave D3 mode */
	pci_write_config_byte(pdev, 0x44, 0);
	pci_write_config_byte(pdev, 0x04, 0x06);
	pci_write_config_byte(pdev, 0x04, 0x07);

	/* init cfg & intf_ops */
	rtlpriv->rtlhal.interface = INTF_PCI;
	rtlpriv->cfg = (struct rtl_hal_cfg *)(id->driver_data);
	rtlpriv->intf_ops = &rtl_pci_ops;

	/* find adapter */
	_rtl_pci_find_adapter(pdev, hw);

	/* Init IO handler */
	_rtl_pci_io_handler_init(&pdev->dev, hw);

	/*like read eeprom and so on */
	rtlpriv->cfg->ops->read_eeprom_info(hw);

	if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Can't init_sw_vars.\n"));
		goto fail3;
	}

	rtlpriv->cfg->ops->init_sw_leds(hw);

	/*aspm */
	rtl_pci_init_aspm(hw);

	/* Init mac80211 sw */
	err = rtl_init_core(hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Can't allocate sw for mac80211.\n"));
		goto fail3;
	}

	/* Init PCI sw */
	err = !rtl_pci_init(hw, pdev);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Failed to init PCI.\n"));
		goto fail3;
	}

	err = ieee80211_register_hw(hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("Can't register mac80211 hw.\n"));
		goto fail3;
	} else {
		rtlpriv->mac80211.mac80211_registered = 1;
	}

	err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
	if (err) {
		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
			 ("failed to create sysfs device attributes\n"));
		goto fail3;
	}

	/*init rfkill */
	rtl_init_rfkill(hw);

	rtlpci = rtl_pcidev(pcipriv);
	err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
			  IRQF_SHARED, KBUILD_MODNAME, hw);
	if (err) {
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
			 ("%s: failed to register IRQ handler\n",
			  wiphy_name(hw->wiphy)));
		goto fail3;
	} else {
		rtlpci->irq_alloc = 1;
	}

	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
	return 0;

fail3:
	pci_set_drvdata(pdev, NULL);
	rtl_deinit_core(hw);
	_rtl_pci_io_handler_release(hw);
	ieee80211_free_hw(hw);

	if (rtlpriv->io.pci_mem_start != 0)
		pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);

fail2:
	pci_release_regions(pdev);

fail1:

	pci_disable_device(pdev);

	return -ENODEV;

}
static int __init init_mac80211_hwsim(void)
{
	int i, err = 0;
	u8 addr[ETH_ALEN];
	struct mac80211_hwsim_data *data;
	struct ieee80211_hw *hw;
	DECLARE_MAC_BUF(mac);

	if (radios < 1 || radios > 65535)
		return -EINVAL;

	hwsim_radio_count = radios;
	hwsim_radios = kcalloc(hwsim_radio_count,
			       sizeof(struct ieee80211_hw *), GFP_KERNEL);
	if (hwsim_radios == NULL)
		return -ENOMEM;

	hwsim_class = class_create(THIS_MODULE, "mac80211_hwsim");
	if (IS_ERR(hwsim_class)) {
		kfree(hwsim_radios);
		return PTR_ERR(hwsim_class);
	}

	memset(addr, 0, ETH_ALEN);
	addr[0] = 0x02;

	for (i = 0; i < hwsim_radio_count; i++) {
		printk(KERN_DEBUG "mac80211_hwsim: Initializing radio %d\n",
		       i);
		hw = ieee80211_alloc_hw(sizeof(*data), &mac80211_hwsim_ops);
		if (hw == NULL) {
			printk(KERN_DEBUG "mac80211_hwsim: ieee80211_alloc_hw "
			       "failed\n");
			err = -ENOMEM;
			goto failed;
		}
		hwsim_radios[i] = hw;

		data = hw->priv;
		data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
						"hwsim%d", i);
		if (IS_ERR(data->dev)) {
			printk(KERN_DEBUG
			       "mac80211_hwsim: device_create_drvdata "
			       "failed (%ld)\n", PTR_ERR(data->dev));
			err = -ENOMEM;
			goto failed_drvdata;
		}
		data->dev->driver = &mac80211_hwsim_driver;

		SET_IEEE80211_DEV(hw, data->dev);
		addr[3] = i >> 8;
		addr[4] = i;
		SET_IEEE80211_PERM_ADDR(hw, addr);

		hw->channel_change_time = 1;
		hw->queues = 1;

		memcpy(data->channels, hwsim_channels, sizeof(hwsim_channels));
		memcpy(data->rates, hwsim_rates, sizeof(hwsim_rates));
		data->band.channels = data->channels;
		data->band.n_channels = ARRAY_SIZE(hwsim_channels);
		data->band.bitrates = data->rates;
		data->band.n_bitrates = ARRAY_SIZE(hwsim_rates);
		hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &data->band;

		err = ieee80211_register_hw(hw);
		if (err < 0) {
			printk(KERN_DEBUG "mac80211_hwsim: "
			       "ieee80211_register_hw failed (%d)\n", err);
			goto failed_hw;
		}

		printk(KERN_DEBUG "%s: hwaddr %s registered\n",
		       wiphy_name(hw->wiphy),
		       print_mac(mac, hw->wiphy->perm_addr));

		setup_timer(&data->beacon_timer, mac80211_hwsim_beacon,
			    (unsigned long) hw);
	}

	hwsim_mon = alloc_netdev(0, "hwsim%d", hwsim_mon_setup);
	if (hwsim_mon == NULL)
		goto failed;

	rtnl_lock();

	err = dev_alloc_name(hwsim_mon, hwsim_mon->name);
	if (err < 0)
		goto failed_mon;


	err = register_netdevice(hwsim_mon);
	if (err < 0)
		goto failed_mon;

	rtnl_unlock();

	return 0;

failed_mon:
	rtnl_unlock();
	free_netdev(hwsim_mon);
	mac80211_hwsim_free();
	return err;

failed_hw:
	device_unregister(data->dev);
failed_drvdata:
	ieee80211_free_hw(hw);
	hwsim_radios[i] = NULL;
failed:
	mac80211_hwsim_free();
	return err;
}