struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) { struct zd_mac *mac; struct ieee80211_hw *hw; int i; hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); if (!hw) { dev_dbg_f(&intf->dev, "out of memory\n"); return NULL; } mac = zd_hw_mac(hw); memset(mac, 0, sizeof(*mac)); spin_lock_init(&mac->lock); mac->hw = hw; mac->type = IEEE80211_IF_TYPE_INVALID; memcpy(mac->channels, zd_channels, sizeof(zd_channels)); memcpy(mac->rates, zd_rates, sizeof(zd_rates)); mac->modes[0].mode = MODE_IEEE80211G; mac->modes[0].num_rates = ARRAY_SIZE(zd_rates); mac->modes[0].rates = mac->rates; mac->modes[0].num_channels = ARRAY_SIZE(zd_channels); mac->modes[0].channels = mac->channels; mac->modes[1].mode = MODE_IEEE80211B; mac->modes[1].num_rates = 4; mac->modes[1].rates = mac->rates; mac->modes[1].num_channels = ARRAY_SIZE(zd_channels); mac->modes[1].channels = mac->channels; hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_DEFAULT_REG_DOMAIN_CONFIGURED; hw->max_rssi = 100; hw->max_signal = 100; hw->queues = 1; hw->extra_tx_headroom = sizeof(struct zd_ctrlset); skb_queue_head_init(&mac->ack_wait_queue); for (i = 0; i < 2; i++) { if (ieee80211_register_hwmode(hw, &mac->modes[i])) { dev_dbg_f(&intf->dev, "cannot register hwmode\n"); ieee80211_free_hw(hw); return NULL; } } zd_chip_init(&mac->chip, hw, intf); housekeeping_init(mac); INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); SET_IEEE80211_DEV(hw, &intf->dev); return hw; }
/** * determines if a device is a WL device, and if so, attaches it. * * This function determines if a device pointed to by pdev is a WL device, * and if so, performs a brcms_attach() on it. * * Perimeter lock is initialized in the course of this function. */ static int brcms_bcma_probe(struct bcma_device *pdev) { struct brcms_info *wl; struct ieee80211_hw *hw; dev_info(&pdev->dev, "mfg %x core %x rev %d class %d irq %d\n", pdev->id.manuf, pdev->id.id, pdev->id.rev, pdev->id.class, pdev->irq); if ((pdev->id.manuf != BCMA_MANUF_BCM) || (pdev->id.id != BCMA_CORE_80211)) return -ENODEV; hw = ieee80211_alloc_hw(sizeof(struct brcms_info), &brcms_ops); if (!hw) { pr_err("%s: ieee80211_alloc_hw failed\n", __func__); return -ENOMEM; } SET_IEEE80211_DEV(hw, &pdev->dev); bcma_set_drvdata(pdev, hw); memset(hw->priv, 0, sizeof(*wl)); wl = brcms_attach(pdev); if (!wl) { pr_err("%s: brcms_attach failed!\n", __func__); return -ENODEV; } brcms_led_register(wl); return 0; }
static int ar9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct ar9170_usb *aru; struct ar9170 *ar; struct usb_device *udev; int err; aru = ar9170_alloc(sizeof(*aru)); if (IS_ERR(aru)) { err = PTR_ERR(aru); goto out; } udev = interface_to_usbdev(intf); usb_get_dev(udev); aru->udev = udev; aru->intf = intf; ar = &aru->common; aru->req_one_stage_fw = ar9170_requires_one_stage(id); usb_set_intfdata(intf, aru); SET_IEEE80211_DEV(ar->hw, &intf->dev); init_usb_anchor(&aru->rx_submitted); init_usb_anchor(&aru->tx_pending); init_usb_anchor(&aru->tx_submitted); init_completion(&aru->cmd_wait); init_completion(&aru->firmware_loading_complete); spin_lock_init(&aru->tx_urb_lock); aru->tx_pending_urbs = 0; atomic_set(&aru->tx_submitted_urbs, 0); aru->common.stop = ar9170_usb_stop; aru->common.flush = ar9170_usb_flush; aru->common.open = ar9170_usb_open; aru->common.tx = ar9170_usb_tx; aru->common.exec_cmd = ar9170_usb_exec_cmd; aru->common.callback_cmd = ar9170_usb_callback_cmd; #ifdef CONFIG_PM udev->reset_resume = 1; #endif /* CONFIG_PM */ err = ar9170_usb_reset(aru); if (err) goto err_freehw; usb_get_dev(aru->udev); return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw", &aru->udev->dev, GFP_KERNEL, aru, ar9170_usb_firmware_step2); err_freehw: usb_set_intfdata(intf, NULL); usb_put_dev(udev); ieee80211_free_hw(ar->hw); out: return err; }
/** * determines if a device is a WL device, and if so, attaches it. * * This function determines if a device pointed to by pdev is a WL device, * and if so, performs a wl_attach() on it. * * Perimeter lock is initialized in the course of this function. */ static int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; struct wl_info *wl; struct ieee80211_hw *hw; u32 val; ASSERT(pdev); WL_TRACE("%s: bus %d slot %d func %d irq %d\n", __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq); if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || (((pdev->device & 0xff00) != 0x4300) && ((pdev->device & 0xff00) != 0x4700) && ((pdev->device < 43000) || (pdev->device > 43999)))) return -ENODEV; rc = pci_enable_device(pdev); if (rc) { WL_ERROR("%s: Cannot enable device %d-%d_%d\n", __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn)); return -ENODEV; } pci_set_master(pdev); pci_read_config_dword(pdev, 0x40, &val); if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); if (!hw) { WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); rc = -ENOMEM; goto err_1; } SET_IEEE80211_DEV(hw, &pdev->dev); pci_set_drvdata(pdev, hw); memset(hw->priv, 0, sizeof(*wl)); wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), PCI_BUS, pdev, pdev->irq); if (!wl) { WL_ERROR("%s: %s: wl_attach failed!\n", KBUILD_MODNAME, __func__); return -ENODEV; } return 0; err_1: WL_ERROR("%s: err_1: Major hoarkage\n", __func__); return 0; }
static int carl9170_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct ar9170 *ar; struct usb_device *udev; int err; err = usb_reset_device(interface_to_usbdev(intf)); if (err) return err; ar = carl9170_alloc(sizeof(*ar)); if (IS_ERR(ar)) return PTR_ERR(ar); udev = interface_to_usbdev(intf); usb_get_dev(udev); ar->udev = udev; ar->intf = intf; ar->features = id->driver_info; usb_set_intfdata(intf, ar); SET_IEEE80211_DEV(ar->hw, &intf->dev); init_usb_anchor(&ar->rx_anch); init_usb_anchor(&ar->rx_pool); init_usb_anchor(&ar->rx_work); init_usb_anchor(&ar->tx_wait); init_usb_anchor(&ar->tx_anch); init_usb_anchor(&ar->tx_cmd); init_usb_anchor(&ar->tx_err); init_completion(&ar->cmd_wait); init_completion(&ar->fw_boot_wait); init_completion(&ar->fw_load_wait); tasklet_init(&ar->usb_tasklet, carl9170_usb_tasklet, (unsigned long)ar); atomic_set(&ar->tx_cmd_urbs, 0); atomic_set(&ar->tx_anch_urbs, 0); atomic_set(&ar->rx_work_urbs, 0); atomic_set(&ar->rx_anch_urbs, 0); atomic_set(&ar->rx_pool_urbs, 0); usb_get_dev(ar->udev); carl9170_set_state(ar, CARL9170_STOPPED); err = request_firmware_nowait(THIS_MODULE, 1, CARL9170FW_NAME, &ar->udev->dev, GFP_KERNEL, ar, carl9170_usb_firmware_step2); if (err) { usb_put_dev(udev); usb_put_dev(udev); carl9170_free(ar); } return err; }
int mt7601u_register_device(struct mt7601u_dev *dev) { struct ieee80211_hw *hw = dev->hw; struct wiphy *wiphy = hw->wiphy; int ret; /* Reserve WCID 0 for mcast - thanks to this APs WCID will go to * entry no. 1 like it does in the vendor driver. */ dev->wcid_mask[0] |= 1; /* init fake wcid for monitor interfaces */ dev->mon_wcid = devm_kmalloc(dev->dev, sizeof(*dev->mon_wcid), GFP_KERNEL); if (!dev->mon_wcid) return -ENOMEM; dev->mon_wcid->idx = 0xff; dev->mon_wcid->hw_key_idx = -1; SET_IEEE80211_DEV(hw, dev->dev); hw->queues = 4; ieee80211_hw_set(hw, SIGNAL_DBM); ieee80211_hw_set(hw, PS_NULLFUNC_STACK); ieee80211_hw_set(hw, SUPPORTS_HT_CCK_RATES); ieee80211_hw_set(hw, AMPDU_AGGREGATION); ieee80211_hw_set(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); SET_IEEE80211_PERM_ADDR(hw, dev->macaddr); wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); ret = mt76_init_sband_2g(dev); if (ret) return ret; INIT_DELAYED_WORK(&dev->mac_work, mt7601u_mac_work); INIT_DELAYED_WORK(&dev->stat_work, mt7601u_tx_stat); ret = ieee80211_register_hw(hw); if (ret) return ret; mt7601u_init_debugfs(dev); return 0; }
struct ieee80211_hw *zd_mac_alloc_hw(struct usb_interface *intf) { struct zd_mac *mac; struct ieee80211_hw *hw; hw = ieee80211_alloc_hw(sizeof(struct zd_mac), &zd_ops); if (!hw) { dev_dbg_f(&intf->dev, "out of memory\n"); return NULL; } mac = zd_hw_mac(hw); memset(mac, 0, sizeof(*mac)); spin_lock_init(&mac->lock); mac->hw = hw; mac->type = IEEE80211_IF_TYPE_INVALID; memcpy(mac->channels, zd_channels, sizeof(zd_channels)); memcpy(mac->rates, zd_rates, sizeof(zd_rates)); mac->band.n_bitrates = ARRAY_SIZE(zd_rates); mac->band.bitrates = mac->rates; mac->band.n_channels = ARRAY_SIZE(zd_channels); mac->band.channels = mac->channels; hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &mac->band; hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE; hw->max_rssi = 100; hw->max_signal = 100; hw->queues = 1; hw->extra_tx_headroom = sizeof(struct zd_ctrlset); skb_queue_head_init(&mac->ack_wait_queue); zd_chip_init(&mac->chip, hw, intf); housekeeping_init(mac); INIT_WORK(&mac->set_multicast_hash_work, set_multicast_hash_handler); INIT_WORK(&mac->set_rts_cts_work, set_rts_cts_work); INIT_WORK(&mac->set_rx_filter_work, set_rx_filter_handler); INIT_WORK(&mac->process_intr, zd_process_intr); SET_IEEE80211_DEV(hw, &intf->dev); return hw; }
static int rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; struct channel_info *info; char *tx_power; unsigned int i; /* * Initialize all hw fields. */ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING | IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_SUPPORTS_PS | IEEE80211_HW_PS_NULLFUNC_STACK; SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); /* * Initialize hw_mode information. */ spec->supported_bands = SUPPORT_BAND_2GHZ; spec->supported_rates = SUPPORT_RATE_CCK; spec->num_channels = ARRAY_SIZE(rf_vals_b); spec->channels = rf_vals_b; /* * Create channel information array */ info = kcalloc(spec->num_channels, sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; spec->channels_info = info; tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); for (i = 0; i < 14; i++) { info[i].max_power = TXPOWER_FROM_DEV(MAX_TXPOWER); info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); } return 0; }
int cw1200_core_probe(const struct sbus_ops *sbus_ops, struct sbus_priv *sbus, struct device *pdev, struct cw1200_common **pself) { int err = -EINVAL; struct ieee80211_hw *dev; struct cw1200_common *priv; dev = cw1200_init_common(sizeof(struct cw1200_common)); if (!dev) goto err; priv = dev->priv; priv->sbus_ops = sbus_ops; priv->sbus_priv = sbus; priv->pdev = pdev; SET_IEEE80211_DEV(priv->hw, pdev); err = cw1200_register_common(dev); if (err) { cw1200_free_common(dev); goto err; } *pself = dev->priv; /* Realtime workqueue */ priv->bh_workqueue = alloc_workqueue("cw1200_bh", WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_CPU_INTENSIVE, 1); if(!priv->bh_workqueue) { cw1200_unregister_common(dev); cw1200_free_common(dev); err = -ENOMEM; goto err; } INIT_WORK(&priv->bh_work, cw1200_bh_work); err: return err; }
static int wl1271_init_ieee80211(struct wl1271 *wl) { wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE; wl->hw->channel_change_time = 10000; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); return 0; }
static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) { struct hw_mode_spec *spec = &rt2x00dev->spec; u8 *txpower; unsigned int i; /* * Initialize all hw fields. */ rt2x00dev->hw->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING; rt2x00dev->hw->extra_tx_headroom = 0; rt2x00dev->hw->max_signal = MAX_SIGNAL; rt2x00dev->hw->max_rssi = MAX_RX_SSI; rt2x00dev->hw->queues = 2; SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0)); /* * Convert tx_power array in eeprom. */ txpower = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_START); for (i = 0; i < 14; i++) txpower[i] = TXPOWER_FROM_DEV(txpower[i]); /* * Initialize hw_mode information. */ spec->supported_bands = SUPPORT_BAND_2GHZ; spec->supported_rates = SUPPORT_RATE_CCK; spec->tx_power_a = NULL; spec->tx_power_bg = txpower; spec->tx_power_default = DEFAULT_TXPOWER; spec->num_channels = ARRAY_SIZE(rf_vals_bg); spec->channels = rf_vals_bg; }
void cw1200_core_release(struct cw1200_common *self) { if (self->sdd) { release_firmware(self->sdd); self->sdd = NULL; } if (self->firmware) { release_firmware(self->firmware); self->firmware = NULL; } cw1200_unregister_common(self->hw); cw1200_free_common(self->hw); destroy_workqueue(self->bh_workqueue); self->bh_workqueue = NULL; SET_IEEE80211_DEV(self->hw, NULL); self->pdev = NULL; return; }
static int wl1271_init_ieee80211(struct wl1271 *wl) { /* * The tx descriptor buffer and the TKIP space. * * FIXME: add correct 1271 descriptor size */ wl->hw->extra_tx_headroom = WL1271_TKIP_IV_SPACE; /* unit us */ /* FIXME: find a proper value */ wl->hw->channel_change_time = 10000; wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); wl->hw->wiphy->max_scan_ssids = 1; wl->hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl1271_band_2ghz; SET_IEEE80211_DEV(wl->hw, &wl->spi->dev); return 0; }
static int wl1251_spi_probe(struct spi_device *spi) { struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev); struct device_node *np = spi->dev.of_node; struct ieee80211_hw *hw; struct wl1251 *wl; int ret; if (!np && !pdata) { wl1251_error("no platform data"); return -ENODEV; } hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; SET_IEEE80211_DEV(hw, &spi->dev); spi_set_drvdata(spi, wl); wl->if_priv = spi; wl->if_ops = &wl1251_spi_ops; /* This is the only SPI value that we need to set here, the rest * comes from the board-peripherals file */ spi->bits_per_word = 32; ret = spi_setup(spi); if (ret < 0) { wl1251_error("spi_setup failed"); goto out_free; } if (np) { wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom"); wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0); } else if (pdata) { wl->power_gpio = pdata->power_gpio; wl->use_eeprom = pdata->use_eeprom; } if (wl->power_gpio == -EPROBE_DEFER) { ret = -EPROBE_DEFER; goto out_free; } if (gpio_is_valid(wl->power_gpio)) { ret = devm_gpio_request_one(&spi->dev, wl->power_gpio, GPIOF_OUT_INIT_LOW, "wl1251 power"); if (ret) { wl1251_error("Failed to request gpio: %d\n", ret); goto out_free; } } else { wl1251_error("set power gpio missing in platform data"); ret = -ENODEV; goto out_free; } wl->irq = spi->irq; if (wl->irq < 0) { wl1251_error("irq missing in platform data"); ret = -ENODEV; goto out_free; } irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto out_free; } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); wl->vio = devm_regulator_get(&spi->dev, "vio"); if (IS_ERR(wl->vio)) { ret = PTR_ERR(wl->vio); wl1251_error("vio regulator missing: %d", ret); goto out_free; } ret = regulator_enable(wl->vio); if (ret) goto out_free; ret = wl1251_init_ieee80211(wl); if (ret) goto disable_regulator; return 0; disable_regulator: regulator_disable(wl->vio); out_free: ieee80211_free_hw(hw); return ret; }
static int __devinit p54spi_probe(struct spi_device *spi) { struct p54s_priv *priv = NULL; struct ieee80211_hw *hw; int ret = -EINVAL; hw = p54_init_common(sizeof(*priv)); if (!hw) { dev_err(&spi->dev, "could not alloc ieee80211_hw"); return -ENOMEM; } priv = hw->priv; priv->hw = hw; dev_set_drvdata(&spi->dev, priv); priv->spi = spi; spi->bits_per_word = 16; spi->max_speed_hz = 24000000; ret = spi_setup(spi); if (ret < 0) { dev_err(&priv->spi->dev, "spi_setup failed"); goto err_free_common; } ret = gpio_request(p54spi_gpio_power, "p54spi power"); if (ret < 0) { dev_err(&priv->spi->dev, "power GPIO request failed: %d", ret); goto err_free_common; } ret = gpio_request(p54spi_gpio_irq, "p54spi irq"); if (ret < 0) { dev_err(&priv->spi->dev, "irq GPIO request failed: %d", ret); goto err_free_common; } gpio_direction_output(p54spi_gpio_power, 0); gpio_direction_input(p54spi_gpio_irq); ret = request_irq(gpio_to_irq(p54spi_gpio_irq), p54spi_interrupt, IRQF_DISABLED, "p54spi", priv->spi); if (ret < 0) { dev_err(&priv->spi->dev, "request_irq() failed"); goto err_free_common; } set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING); disable_irq(gpio_to_irq(p54spi_gpio_irq)); INIT_WORK(&priv->work, p54spi_work); init_completion(&priv->fw_comp); INIT_LIST_HEAD(&priv->tx_pending); mutex_init(&priv->mutex); spin_lock_init(&priv->tx_lock); SET_IEEE80211_DEV(hw, &spi->dev); priv->common.open = p54spi_op_start; priv->common.stop = p54spi_op_stop; priv->common.tx = p54spi_op_tx; ret = p54spi_request_firmware(hw); if (ret < 0) goto err_free_common; ret = p54spi_request_eeprom(hw); if (ret) goto err_free_common; ret = p54_register_common(hw, &priv->spi->dev); if (ret) goto err_free_common; return 0; err_free_common: p54_free_common(priv->hw); return ret; }
int cw1200_core_probe(const struct sbus_ops *sbus_ops, struct sbus_priv *sbus, struct device *pdev, struct cw1200_common **pself, u8 *mac_addr) { int err = -ENOMEM; u16 ctrl_reg; struct ieee80211_hw *dev; struct cw1200_common *priv; struct wsm_operational_mode mode = { .power_mode = wsm_power_mode_quiescent, .disableMoreFlagUsage = true, }; dev = cw1200_init_common(sizeof(struct cw1200_common), mac_addr); if (!dev) goto err; priv = dev->priv; priv->sbus_ops = sbus_ops; priv->sbus_priv = sbus; priv->pdev = pdev; SET_IEEE80211_DEV(priv->hw, pdev); /* WSM callbacks. */ priv->wsm_cbc.scan_complete = cw1200_scan_complete_cb; priv->wsm_cbc.tx_confirm = cw1200_tx_confirm_cb; priv->wsm_cbc.rx = cw1200_rx_cb; priv->wsm_cbc.suspend_resume = cw1200_suspend_resume; /* priv->wsm_cbc.set_pm_complete = cw1200_set_pm_complete_cb; */ priv->wsm_cbc.channel_switch = cw1200_channel_switch_cb; err = cw1200_register_bh(priv); if (err) goto err1; err = cw1200_load_firmware(priv); if (err) goto err2; priv->sbus_ops->lock(priv->sbus_priv); WARN_ON(priv->sbus_ops->set_block_size(priv->sbus_priv, SDIO_BLOCK_SIZE)); priv->sbus_ops->unlock(priv->sbus_priv); if (wait_event_interruptible_timeout(priv->wsm_startup_done, priv->wsm_caps.firmwareReady, 3*HZ) <= 0) { /* TODO: Needs to find how to reset device */ /* in QUEUE mode properly. */ goto err3; } WARN_ON(cw1200_reg_write_16(priv, ST90TDS_CONTROL_REG_ID, ST90TDS_CONT_WUP_BIT)); if (cw1200_reg_read_16(priv,ST90TDS_CONTROL_REG_ID, &ctrl_reg)) WARN_ON(cw1200_reg_read_16(priv,ST90TDS_CONTROL_REG_ID, &ctrl_reg)); WARN_ON(!(ctrl_reg & ST90TDS_CONT_RDY_BIT)); /* Set low-power mode. */ WARN_ON(wsm_set_operational_mode(priv, &mode)); /* Enable multi-TX confirmation */ WARN_ON(wsm_use_multi_tx_conf(priv, true)); err = cw1200_register_common(dev); if (err) { priv->sbus_ops->irq_unsubscribe(priv->sbus_priv); goto err3; } *pself = dev->priv; return err; err3: sbus_ops->reset(sbus); err2: cw1200_unregister_bh(priv); err1: cw1200_free_common(dev); err: return err; } EXPORT_SYMBOL_GPL(cw1200_core_probe); void cw1200_core_release(struct cw1200_common *self) { cw1200_unregister_common(self->hw); cw1200_free_common(self->hw); return; }
static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) { void __iomem *mem; struct ath_softc *sc; struct ieee80211_hw *hw; u8 csz; u32 val; int ret = 0; char hw_name[64]; if (pci_enable_device(pdev)) return -EIO; ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); goto err_dma; } ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (ret) { printk(KERN_ERR "ath9k: 32-bit DMA consistent " "DMA enable failed\n"); goto err_dma; } /* * Cache line size is used to size and align various * structures used to communicate with the hardware. */ pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz); if (csz == 0) { /* * Linux 2.4.18 (at least) writes the cache line size * register as a 16-bit wide register which is wrong. * We must have this setup properly for rx buffer * DMA to work so force a reasonable value here if it * comes up zero. */ csz = L1_CACHE_BYTES / sizeof(u32); pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz); } /* * The default setting of latency timer yields poor results, * set it to the value used by other systems. It may be worth * tweaking this setting more. */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8); pci_set_master(pdev); /* * Disable the RETRY_TIMEOUT register (0x41) to keep * PCI Tx retries from interfering with C3 CPU state. */ pci_read_config_dword(pdev, 0x40, &val); if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); ret = pci_request_region(pdev, 0, "ath9k"); if (ret) { dev_err(&pdev->dev, "PCI memory region reserve error\n"); ret = -ENODEV; goto err_region; } mem = pci_iomap(pdev, 0, 0); if (!mem) { printk(KERN_ERR "PCI memory map error\n") ; ret = -EIO; goto err_iomap; } hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops); if (!hw) { dev_err(&pdev->dev, "No memory for ieee80211_hw\n"); ret = -ENOMEM; goto err_alloc_hw; } SET_IEEE80211_DEV(hw, &pdev->dev); pci_set_drvdata(pdev, hw); sc = hw->priv; sc->hw = hw; sc->dev = &pdev->dev; sc->mem = mem; /* Will be cleared in ath9k_start() */ sc->sc_flags |= SC_OP_INVALID; ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); if (ret) { dev_err(&pdev->dev, "request_irq failed\n"); goto err_irq; } sc->irq = pdev->irq; ret = ath9k_init_device(id->device, sc, &ath_pci_bus_ops); if (ret) { dev_err(&pdev->dev, "Failed to initialize device\n"); goto err_init; } ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name)); wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", hw_name, (unsigned long)mem, pdev->irq); return 0; err_init: free_irq(sc->irq, sc); err_irq: ieee80211_free_hw(hw); err_alloc_hw: pci_iounmap(pdev, mem); err_iomap: pci_release_region(pdev, 0); err_region: /* Nothing */ err_dma: pci_disable_device(pdev); return ret; }
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; }
static int 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; pci_dev_get(pdev); err = pci_enable_device(pdev); if (err) { dev_err(&pdev->dev, "Cannot enable new PCI device\n"); return err; } mem_addr = pci_resource_start(pdev, 0); mem_len = pci_resource_len(pdev, 0); if (mem_len < sizeof(struct p54p_csr)) { dev_err(&pdev->dev, "Too short PCI resources\n"); err = -ENODEV; goto err_disable_dev; } err = pci_request_regions(pdev, "p54pci"); if (err) { dev_err(&pdev->dev, "Cannot obtain PCI resources\n"); goto err_disable_dev; } err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); if (!err) err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); if (err) { dev_err(&pdev->dev, "No suitable DMA available\n"); 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) { dev_err(&pdev->dev, "ieee80211 alloc failed\n"); err = -ENOMEM; goto err_free_reg; } priv = dev->priv; priv->pdev = pdev; init_completion(&priv->fw_loaded); SET_IEEE80211_DEV(dev, &pdev->dev); pci_set_drvdata(pdev, dev); priv->map = ioremap(mem_addr, mem_len); if (!priv->map) { dev_err(&pdev->dev, "Cannot map device memory\n"); err = -ENOMEM; goto err_free_dev; } priv->ring_control = pci_alloc_consistent(pdev, sizeof(*priv->ring_control), &priv->ring_control_dma); if (!priv->ring_control) { dev_err(&pdev->dev, "Cannot allocate rings\n"); err = -ENOMEM; goto err_iounmap; } priv->common.open = p54p_open; priv->common.stop = p54p_stop; priv->common.tx = p54p_tx; spin_lock_init(&priv->lock); tasklet_init(&priv->tasklet, p54p_tasklet, (unsigned long)dev); err = request_firmware_nowait(THIS_MODULE, 1, "isl3886pci", &priv->pdev->dev, GFP_KERNEL, priv, p54p_firmware_step2); if (!err) return 0; pci_free_consistent(pdev, sizeof(*priv->ring_control), priv->ring_control, priv->ring_control_dma); err_iounmap: iounmap(priv->map); err_free_dev: p54_free_common(dev); err_free_reg: pci_release_regions(pdev); err_disable_dev: pci_disable_device(pdev); pci_dev_put(pdev); return err; }
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; }
static int wl1251_spi_probe(struct spi_device *spi) { struct wl12xx_platform_data *pdata; struct ieee80211_hw *hw; struct wl1251 *wl; int ret; pdata = spi->dev.platform_data; if (!pdata) { wl1251_error("no platform data"); return -ENODEV; } hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; SET_IEEE80211_DEV(hw, &spi->dev); spi_set_drvdata(spi, wl); wl->if_priv = spi; wl->if_ops = &wl1251_spi_ops; /* This is the only SPI value that we need to set here, the rest * comes from the board-peripherals file */ spi->bits_per_word = 32; ret = spi_setup(spi); if (ret < 0) { wl1251_error("spi_setup failed"); goto out_free; } wl->set_power = pdata->set_power; if (!wl->set_power) { wl1251_error("set power function missing in platform data"); return -ENODEV; } wl->irq = spi->irq; if (wl->irq < 0) { wl1251_error("irq missing in platform data"); return -ENODEV; } wl->use_eeprom = pdata->use_eeprom; irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_irq(wl->irq, wl1251_irq, 0, DRIVER_NAME, wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto out_free; } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); ret = wl1251_init_ieee80211(wl); if (ret) goto out_irq; return 0; out_irq: free_irq(wl->irq, wl); out_free: ieee80211_free_hw(hw); return ret; }
static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret, t; struct wl1251 *wl; struct ieee80211_hw *hw; struct wl1251_sdio *wl_sdio; const struct wl12xx_platform_data *wl12xx_board_data; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; wl_sdio = kzalloc(sizeof(*wl_sdio), GFP_KERNEL); if (wl_sdio == NULL) { ret = -ENOMEM; goto out_free_hw; } sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; sdio_set_block_size(func, 512); sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); wl_sdio->func = func; wl->if_priv = wl_sdio; wl->if_ops = &wl1251_sdio_ops; wl12xx_board_data = wl12xx_get_platform_data(); if (!IS_ERR(wl12xx_board_data)) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; wl->use_eeprom = wl12xx_board_data->use_eeprom; } if (force_nvs_file) wl->use_eeprom = false; wl->dump_eeprom = dump_eeprom; if (wl->irq) { irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); ret = request_threaded_irq(wl->irq, NULL, wl1251_irq, IRQF_ONESHOT, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; } irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_info("using dedicated interrupt line"); } else { wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; wl1251_info("using SDIO interrupt"); } ret = wl1251_init_ieee80211(wl); if (ret) goto out_free_irq; sdio_set_drvdata(func, wl); for (t = 0; t < ARRAY_SIZE(wl1251_attrs); t++) { ret = device_create_file(&func->dev, &wl1251_attrs[t]); if (ret) { while (--t >= 0) device_remove_file(&func->dev, &wl1251_attrs[t]); goto out_free_irq; } } /* Tell PM core that we don't need the card to be powered now */ pm_runtime_put_noidle(&func->dev); return ret; out_free_irq: if (wl->irq) free_irq(wl->irq, wl); disable: sdio_claim_host(func); sdio_disable_func(func); release: sdio_release_host(func); kfree(wl_sdio); out_free_hw: wl1251_free_hw(wl); return ret; }
int cw1200_core_probe(const struct hwbus_ops *hwbus_ops, struct hwbus_priv *hwbus, struct device *pdev, struct cw1200_common **core, int ref_clk, const u8 *macaddr, const char *sdd_path, bool have_5ghz) { int err = -EINVAL; struct ieee80211_hw *dev; struct cw1200_common *priv; struct wsm_operational_mode mode = { .power_mode = cw1200_power_mode, .disable_more_flag_usage = true, }; dev = cw1200_init_common(macaddr, have_5ghz); if (!dev) goto err; priv = dev->priv; priv->hw_refclk = ref_clk; if (cw1200_refclk) priv->hw_refclk = cw1200_refclk; priv->sdd_path = (char *)sdd_path; if (cw1200_sdd_path) priv->sdd_path = cw1200_sdd_path; priv->hwbus_ops = hwbus_ops; priv->hwbus_priv = hwbus; priv->pdev = pdev; SET_IEEE80211_DEV(priv->hw, pdev); /* Pass struct cw1200_common back up */ *core = priv; err = cw1200_register_bh(priv); if (err) goto err1; err = cw1200_load_firmware(priv); if (err) goto err2; if (wait_event_interruptible_timeout(priv->wsm_startup_done, priv->firmware_ready, 3*HZ) <= 0) { /* TODO: Need to find how to reset device in QUEUE mode properly. */ pr_err("Timeout waiting on device startup\n"); err = -ETIMEDOUT; goto err2; } /* Set low-power mode. */ wsm_set_operational_mode(priv, &mode); /* Enable multi-TX confirmation */ wsm_use_multi_tx_conf(priv, true); err = cw1200_register_common(dev); if (err) goto err2; return err; err2: cw1200_unregister_bh(priv); err1: cw1200_free_common(dev); err: *core = NULL; return err; } EXPORT_SYMBOL_GPL(cw1200_core_probe); void cw1200_core_release(struct cw1200_common *self) { /* Disable device interrupts */ self->hwbus_ops->lock(self->hwbus_priv); __cw1200_irq_enable(self, 0); self->hwbus_ops->unlock(self->hwbus_priv); /* And then clean up */ cw1200_unregister_common(self->hw); cw1200_free_common(self->hw); return; }
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.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 = rtl_mac80211_init(hw); if (err) goto error_out; set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status); return 0; error_out: rtl_mac80211_deinit(hw); rtl_deinit_core(hw); _rtl_usb_io_handler_release(hw); usb_put_dev(udev); complete(&rtlpriv->firmware_loading_complete); return -ENODEV; }
static int wl1251_sdio_probe(struct sdio_func *func, const struct sdio_device_id *id) { int ret; struct wl1251 *wl; struct ieee80211_hw *hw; hw = wl1251_alloc_hw(); if (IS_ERR(hw)) return PTR_ERR(hw); wl = hw->priv; sdio_claim_host(func); ret = sdio_enable_func(func); if (ret) goto release; sdio_set_block_size(func, 512); sdio_release_host(func); SET_IEEE80211_DEV(hw, &func->dev); wl->if_priv = func; wl->if_ops = &wl1251_sdio_ops; wl->set_power = wl1251_sdio_set_power; if (wl12xx_board_data != NULL) { wl->set_power = wl12xx_board_data->set_power; wl->irq = wl12xx_board_data->irq; wl->use_eeprom = wl12xx_board_data->use_eeprom; } if (wl->irq) { ret = request_irq(wl->irq, wl1251_line_irq, 0, "wl1251", wl); if (ret < 0) { wl1251_error("request_irq() failed: %d", ret); goto disable; } set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); disable_irq(wl->irq); wl1251_sdio_ops.enable_irq = wl1251_enable_line_irq; wl1251_sdio_ops.disable_irq = wl1251_disable_line_irq; wl1251_info("using dedicated interrupt line"); } else { wl1251_sdio_ops.enable_irq = wl1251_sdio_enable_irq; wl1251_sdio_ops.disable_irq = wl1251_sdio_disable_irq; wl1251_info("using SDIO interrupt"); } ret = wl1251_init_ieee80211(wl); if (ret) goto out_free_irq; sdio_set_drvdata(func, wl); return ret; out_free_irq: if (wl->irq) free_irq(wl->irq, wl); disable: sdio_claim_host(func); sdio_disable_func(func); release: sdio_release_host(func); wl1251_free_hw(wl); return ret; }
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; }
static struct iwl_op_mode * iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, const struct iwl_fw *fw, struct dentry *dbgfs_dir) { struct ieee80211_hw *hw; struct iwl_op_mode *op_mode; struct iwl_mvm *mvm; struct iwl_trans_config trans_cfg = {}; static const u8 no_reclaim_cmds[] = { TX_CMD, }; int err, scan_size; u32 min_backoff; /* * We use IWL_MVM_STATION_COUNT to check the validity of the station * index all over the driver - check that its value corresponds to the * array size. */ BUILD_BUG_ON(ARRAY_SIZE(mvm->fw_id_to_mac_id) != IWL_MVM_STATION_COUNT); /******************************** * 1. Allocating and configuring HW data ********************************/ hw = ieee80211_alloc_hw(sizeof(struct iwl_op_mode) + sizeof(struct iwl_mvm), &iwl_mvm_hw_ops); if (!hw) return NULL; op_mode = hw->priv; op_mode->ops = &iwl_mvm_ops; mvm = IWL_OP_MODE_GET_MVM(op_mode); mvm->dev = trans->dev; mvm->trans = trans; mvm->cfg = cfg; mvm->fw = fw; mvm->hw = hw; mvm->restart_fw = iwlwifi_mod_params.restart_fw ? -1 : 0; mvm->aux_queue = 15; mvm->first_agg_queue = 16; mvm->last_agg_queue = mvm->cfg->base_params->num_of_queues - 1; if (mvm->cfg->base_params->num_of_queues == 16) { mvm->aux_queue = 11; mvm->first_agg_queue = 12; } mvm->sf_state = SF_UNINIT; mutex_init(&mvm->mutex); mutex_init(&mvm->d0i3_suspend_mutex); spin_lock_init(&mvm->async_handlers_lock); INIT_LIST_HEAD(&mvm->time_event_list); INIT_LIST_HEAD(&mvm->async_handlers_list); spin_lock_init(&mvm->time_event_lock); INIT_WORK(&mvm->async_handlers_wk, iwl_mvm_async_handlers_wk); INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); spin_lock_init(&mvm->d0i3_tx_lock); skb_queue_head_init(&mvm->d0i3_tx); init_waitqueue_head(&mvm->d0i3_exit_waitq); SET_IEEE80211_DEV(mvm->hw, mvm->trans->dev); /* * Populate the state variables that the transport layer needs * to know about. */ trans_cfg.op_mode = op_mode; trans_cfg.no_reclaim_cmds = no_reclaim_cmds; trans_cfg.n_no_reclaim_cmds = ARRAY_SIZE(no_reclaim_cmds); trans_cfg.rx_buf_size_8k = iwlwifi_mod_params.amsdu_size_8K; if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_DW_BC_TABLE) trans_cfg.bc_table_dword = true; if (!iwlwifi_mod_params.wd_disable) trans_cfg.queue_watchdog_timeout = cfg->base_params->wd_timeout; else trans_cfg.queue_watchdog_timeout = IWL_WATCHDOG_DISABLED; trans_cfg.command_names = iwl_mvm_cmd_strings; trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; trans_cfg.cmd_fifo = IWL_MVM_CMD_FIFO; snprintf(mvm->hw->wiphy->fw_version, sizeof(mvm->hw->wiphy->fw_version), "%s", fw->fw_version); /* Configure transport layer */ iwl_trans_configure(mvm->trans, &trans_cfg); trans->rx_mpdu_cmd = REPLY_RX_MPDU_CMD; trans->rx_mpdu_cmd_hdr_size = sizeof(struct iwl_rx_mpdu_res_start); /* set up notification wait support */ iwl_notification_wait_init(&mvm->notif_wait); /* Init phy db */ mvm->phy_db = iwl_phy_db_init(trans); if (!mvm->phy_db) { IWL_ERR(mvm, "Cannot init phy_db\n"); goto out_free; } IWL_INFO(mvm, "Detected %s, REV=0x%X\n", mvm->cfg->name, mvm->trans->hw_rev); min_backoff = calc_min_backoff(trans, cfg); iwl_mvm_tt_initialize(mvm, min_backoff); /* set the nvm_file_name according to priority */ if (iwlwifi_mod_params.nvm_file) mvm->nvm_file_name = iwlwifi_mod_params.nvm_file; else mvm->nvm_file_name = mvm->cfg->default_nvm_file; if (WARN(cfg->no_power_up_nic_in_init && !mvm->nvm_file_name, "not allowing power-up and not having nvm_file\n")) goto out_free; /* * Even if nvm exists in the nvm_file driver should read agin the nvm * from the nic because there might be entries that exist in the OTP * and not in the file. * for nics with no_power_up_nic_in_init: rely completley on nvm_file */ if (cfg->no_power_up_nic_in_init && mvm->nvm_file_name) { err = iwl_nvm_init(mvm, false); if (err) goto out_free; } else { err = iwl_trans_start_hw(mvm->trans); if (err) goto out_free; mutex_lock(&mvm->mutex); err = iwl_run_init_mvm_ucode(mvm, true); iwl_trans_stop_device(trans); mutex_unlock(&mvm->mutex); /* returns 0 if successful, 1 if success but in rfkill */ if (err < 0 && !iwlmvm_mod_params.init_dbg) { IWL_ERR(mvm, "Failed to run INIT ucode: %d\n", err); goto out_free; } } scan_size = sizeof(struct iwl_scan_cmd) + mvm->fw->ucode_capa.max_probe_length + (MAX_NUM_SCAN_CHANNELS * sizeof(struct iwl_scan_channel)); mvm->scan_cmd = kmalloc(scan_size, GFP_KERNEL); if (!mvm->scan_cmd) goto out_free; err = iwl_mvm_mac_setup_register(mvm); if (err) goto out_free; err = iwl_mvm_dbgfs_register(mvm, dbgfs_dir); if (err) goto out_unregister; memset(&mvm->rx_stats, 0, sizeof(struct mvm_statistics_rx)); /* rpm starts with a taken ref. only set the appropriate bit here. */ set_bit(IWL_MVM_REF_UCODE_DOWN, mvm->ref_bitmap); return op_mode; out_unregister: ieee80211_unregister_hw(mvm->hw); iwl_mvm_leds_exit(mvm); out_free: iwl_phy_db_free(mvm->phy_db); kfree(mvm->scan_cmd); if (!cfg->no_power_up_nic_in_init || !mvm->nvm_file_name) iwl_trans_op_mode_leave(trans); ieee80211_free_hw(mvm->hw); return NULL; }
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*/
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 __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; }