diff options
author | Kalle Valo <kvalo@codeaurora.org> | 2015-11-18 09:57:18 +0200 |
---|---|---|
committer | Kalle Valo <kvalo@codeaurora.org> | 2015-11-18 14:28:31 +0200 |
commit | 2be45b66dee080326d0f240aa4f18ef932cc3deb (patch) | |
tree | 2892a95ff9ae89065f3d554c8b72e704bdeec679 /drivers/net/wireless/intersil | |
parent | d3466830c165a298419788b88086ea99974e63ff (diff) |
orinoco: move under intersil vendor directory
Part of reorganising wireless drivers directory and Kconfig.
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Diffstat (limited to 'drivers/net/wireless/intersil')
33 files changed, 12762 insertions, 0 deletions
diff --git a/drivers/net/wireless/intersil/Kconfig b/drivers/net/wireless/intersil/Kconfig index 4bc3688bfa93..2b056b6daef8 100644 --- a/drivers/net/wireless/intersil/Kconfig +++ b/drivers/net/wireless/intersil/Kconfig @@ -12,6 +12,7 @@ config WLAN_VENDOR_INTERSIL if WLAN_VENDOR_INTERSIL source "drivers/net/wireless/intersil/hostap/Kconfig" +source "drivers/net/wireless/intersil/orinoco/Kconfig" source "drivers/net/wireless/intersil/p54/Kconfig" endif # WLAN_VENDOR_INTERSIL diff --git a/drivers/net/wireless/intersil/Makefile b/drivers/net/wireless/intersil/Makefile index 90a72830b1ae..aedb713da746 100644 --- a/drivers/net/wireless/intersil/Makefile +++ b/drivers/net/wireless/intersil/Makefile @@ -1,2 +1,3 @@ obj-$(CONFIG_HOSTAP) += hostap/ +obj-$(CONFIG_HERMES) += orinoco/ obj-$(CONFIG_P54_COMMON) += p54/ diff --git a/drivers/net/wireless/intersil/orinoco/Kconfig b/drivers/net/wireless/intersil/orinoco/Kconfig new file mode 100644 index 000000000000..f6fa3f4e294f --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/Kconfig @@ -0,0 +1,142 @@ +config HERMES + tristate "Hermes chipset 802.11b support (Orinoco/Prism2/Symbol)" + depends on (PPC_PMAC || PCI || PCMCIA) + depends on CFG80211 + select CFG80211_WEXT_EXPORT + select WIRELESS_EXT + select WEXT_SPY + select WEXT_PRIV + select FW_LOADER + select CRYPTO + select CRYPTO_MICHAEL_MIC + ---help--- + A driver for 802.11b wireless cards based on the "Hermes" or + Intersil HFA384x (Prism 2) MAC controller. This includes the vast + majority of the PCMCIA 802.11b cards (which are nearly all rebadges) + - except for the Cisco/Aironet cards. Cards supported include the + Apple Airport (not a PCMCIA card), WavelanIEEE/Orinoco, + Cabletron/EnteraSys Roamabout, ELSA AirLancer, MELCO Buffalo, Avaya, + IBM High Rate Wireless, Farralon Syyline, Samsung MagicLAN, Netgear + MA401, LinkSys WPC-11, D-Link DWL-650, 3Com AirConnect, Intel + IPW2011, and Symbol Spectrum24 High Rate amongst others. + + This option includes the guts of the driver, but in order to + actually use a card you will also need to enable support for PCMCIA + Hermes cards, PLX9052 based PCI adaptors or the Apple Airport below. + + You will also very likely also need the Wireless Tools in order to + configure your card and that /etc/pcmcia/wireless.opts works : + <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html> + +config HERMES_PRISM + bool "Support Prism 2/2.5 chipset" + depends on HERMES + ---help--- + + Say Y to enable support for Prism 2 and 2.5 chipsets. These + chipsets are better handled by the hostap driver. This driver + would not support WPA or firmware download for Prism chipset. + + If you are not sure, say N. + +config HERMES_CACHE_FW_ON_INIT + bool "Cache Hermes firmware on driver initialisation" + depends on HERMES + default y + ---help--- + Say Y to cache any firmware required by the Hermes drivers + on startup. The firmware will remain cached until the + driver is unloaded. The cache uses 64K of RAM. + + Otherwise load the firmware from userspace as required. In + this case the driver should be unloaded and restarted + whenever the firmware is changed. + + If you are not sure, say Y. + +config APPLE_AIRPORT + tristate "Apple Airport support (built-in)" + depends on PPC_PMAC && HERMES + help + Say Y here to support the Airport 802.11b wireless Ethernet hardware + built into the Macintosh iBook and other recent PowerPC-based + Macintosh machines. This is essentially a Lucent Orinoco card with + a non-standard interface. + + This driver does not support the Airport Extreme (802.11b/g). Use + the BCM43xx driver for Airport Extreme cards. + +config PLX_HERMES + tristate "Hermes in PLX9052 based PCI adaptor support (Netgear MA301 etc.)" + depends on PCI && HERMES + help + Enable support for PCMCIA cards supported by the "Hermes" (aka + orinoco) driver when used in PLX9052 based PCI adaptors. These + adaptors are not a full PCMCIA controller but act as a more limited + PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that + 802.11b PCMCIA cards can be used in desktop machines. The Netgear + MA301 is such an adaptor. + +config TMD_HERMES + tristate "Hermes in TMD7160 based PCI adaptor support" + depends on PCI && HERMES + help + Enable support for PCMCIA cards supported by the "Hermes" (aka + orinoco) driver when used in TMD7160 based PCI adaptors. These + adaptors are not a full PCMCIA controller but act as a more limited + PCI <-> PCMCIA bridge. Several vendors sell such adaptors so that + 802.11b PCMCIA cards can be used in desktop machines. + +config NORTEL_HERMES + tristate "Nortel emobility PCI adaptor support" + depends on PCI && HERMES + help + Enable support for PCMCIA cards supported by the "Hermes" (aka + orinoco) driver when used in Nortel emobility PCI adaptors. These + adaptors are not full PCMCIA controllers, but act as a more limited + PCI <-> PCMCIA bridge. + +config PCI_HERMES + tristate "Prism 2.5 PCI 802.11b adaptor support" + depends on PCI && HERMES && HERMES_PRISM + help + Enable support for PCI and mini-PCI 802.11b wireless NICs based on + the Prism 2.5 chipset. These are true PCI cards, not the 802.11b + PCMCIA cards bundled with PCI<->PCMCIA adaptors which are also + common. Some of the built-in wireless adaptors in laptops are of + this variety. + +config PCMCIA_HERMES + tristate "Hermes PCMCIA card support" + depends on PCMCIA && HERMES && HAS_IOPORT_MAP + ---help--- + A driver for "Hermes" chipset based PCMCIA wireless adaptors, such + as the Lucent WavelanIEEE/Orinoco cards and their OEM (Cabletron/ + EnteraSys RoamAbout 802.11, ELSA Airlancer, Melco Buffalo and + others). It should also be usable on various Prism II based cards + such as the Linksys, D-Link and Farallon Skyline. It should also + work on Symbol cards such as the 3Com AirConnect and Ericsson WLAN. + + You will very likely need the Wireless Tools in order to + configure your card and that /etc/pcmcia/wireless.opts works: + <http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/Tools.html>. + +config PCMCIA_SPECTRUM + tristate "Symbol Spectrum24 Trilogy PCMCIA card support" + depends on PCMCIA && HERMES && HAS_IOPORT_MAP + ---help--- + + This is a driver for 802.11b cards using RAM-loadable Symbol + firmware, such as Symbol Wireless Networker LA4100, CompactFlash + cards by Socket Communications and Intel PRO/Wireless 2011B. + + This driver requires firmware download on startup. Utilities + for downloading Symbol firmware are available at + <http://sourceforge.net/projects/orinoco/> + +config ORINOCO_USB + tristate "Agere Orinoco USB support" + depends on USB && HERMES + select FW_LOADER + ---help--- + This driver is for USB versions of the Agere Orinoco card. diff --git a/drivers/net/wireless/intersil/orinoco/Makefile b/drivers/net/wireless/intersil/orinoco/Makefile new file mode 100644 index 000000000000..bfdefb85abcd --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/Makefile @@ -0,0 +1,17 @@ +# +# Makefile for the orinoco wireless device drivers. +# +orinoco-objs := main.o fw.o hw.o mic.o scan.o wext.o hermes_dld.o hermes.o cfg.o + +obj-$(CONFIG_HERMES) += orinoco.o +obj-$(CONFIG_PCMCIA_HERMES) += orinoco_cs.o +obj-$(CONFIG_APPLE_AIRPORT) += airport.o +obj-$(CONFIG_PLX_HERMES) += orinoco_plx.o +obj-$(CONFIG_PCI_HERMES) += orinoco_pci.o +obj-$(CONFIG_TMD_HERMES) += orinoco_tmd.o +obj-$(CONFIG_NORTEL_HERMES) += orinoco_nortel.o +obj-$(CONFIG_PCMCIA_SPECTRUM) += spectrum_cs.o +obj-$(CONFIG_ORINOCO_USB) += orinoco_usb.o + +# Orinoco should be endian clean. +ccflags-y += -D__CHECK_ENDIAN__ diff --git a/drivers/net/wireless/intersil/orinoco/airport.c b/drivers/net/wireless/intersil/orinoco/airport.c new file mode 100644 index 000000000000..77e6c53040a3 --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/airport.c @@ -0,0 +1,267 @@ +/* airport.c + * + * A driver for "Hermes" chipset based Apple Airport wireless + * card. + * + * Copyright notice & release notes in file main.c + * + * Note specific to airport stub: + * + * 0.05 : first version of the new split driver + * 0.06 : fix possible hang on powerup, add sleep support + */ + +#define DRIVER_NAME "airport" +#define PFX DRIVER_NAME ": " + +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/delay.h> +#include <asm/pmac_feature.h> + +#include "orinoco.h" + +#define AIRPORT_IO_LEN (0x1000) /* one page */ + +struct airport { + struct macio_dev *mdev; + void __iomem *vaddr; + unsigned int irq; + int irq_requested; + int ndev_registered; +}; + +static int +airport_suspend(struct macio_dev *mdev, pm_message_t state) +{ + struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); + struct net_device *dev = priv->ndev; + struct airport *card = priv->card; + unsigned long flags; + int err; + + printk(KERN_DEBUG "%s: Airport entering sleep mode\n", dev->name); + + err = orinoco_lock(priv, &flags); + if (err) { + printk(KERN_ERR "%s: hw_unavailable on PBOOK_SLEEP_NOW\n", + dev->name); + return 0; + } + + orinoco_down(priv); + orinoco_unlock(priv, &flags); + + disable_irq(card->irq); + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(mdev), 0, 0); + + return 0; +} + +static int +airport_resume(struct macio_dev *mdev) +{ + struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); + struct net_device *dev = priv->ndev; + struct airport *card = priv->card; + unsigned long flags; + int err; + + printk(KERN_DEBUG "%s: Airport waking up\n", dev->name); + + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(mdev), 0, 1); + msleep(200); + + enable_irq(card->irq); + + priv->hw.ops->lock_irqsave(&priv->lock, &flags); + err = orinoco_up(priv); + priv->hw.ops->unlock_irqrestore(&priv->lock, &flags); + + return err; +} + +static int +airport_detach(struct macio_dev *mdev) +{ + struct orinoco_private *priv = dev_get_drvdata(&mdev->ofdev.dev); + struct airport *card = priv->card; + + if (card->ndev_registered) + orinoco_if_del(priv); + card->ndev_registered = 0; + + if (card->irq_requested) + free_irq(card->irq, priv); + card->irq_requested = 0; + + if (card->vaddr) + iounmap(card->vaddr); + card->vaddr = NULL; + + macio_release_resource(mdev, 0); + + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(mdev), 0, 0); + ssleep(1); + + macio_set_drvdata(mdev, NULL); + free_orinocodev(priv); + + return 0; +} + +static int airport_hard_reset(struct orinoco_private *priv) +{ + /* It would be nice to power cycle the Airport for a real hard + * reset, but for some reason although it appears to + * re-initialize properly, it falls in a screaming heap + * shortly afterwards. */ +#if 0 + struct airport *card = priv->card; + + /* Vitally important. If we don't do this it seems we get an + * interrupt somewhere during the power cycle, since + * hw_unavailable is already set it doesn't get ACKed, we get + * into an interrupt loop and the PMU decides to turn us + * off. */ + disable_irq(card->irq); + + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(card->mdev), 0, 0); + ssleep(1); + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(card->mdev), 0, 1); + ssleep(1); + + enable_irq(card->irq); + ssleep(1); +#endif + + return 0; +} + +static int +airport_attach(struct macio_dev *mdev, const struct of_device_id *match) +{ + struct orinoco_private *priv; + struct airport *card; + unsigned long phys_addr; + struct hermes *hw; + + if (macio_resource_count(mdev) < 1 || macio_irq_count(mdev) < 1) { + printk(KERN_ERR PFX "Wrong interrupt/addresses in OF tree\n"); + return -ENODEV; + } + + /* Allocate space for private device-specific data */ + priv = alloc_orinocodev(sizeof(*card), &mdev->ofdev.dev, + airport_hard_reset, NULL); + if (!priv) { + printk(KERN_ERR PFX "Cannot allocate network device\n"); + return -ENODEV; + } + card = priv->card; + + hw = &priv->hw; + card->mdev = mdev; + + if (macio_request_resource(mdev, 0, DRIVER_NAME)) { + printk(KERN_ERR PFX "can't request IO resource !\n"); + free_orinocodev(priv); + return -EBUSY; + } + + macio_set_drvdata(mdev, priv); + + /* Setup interrupts & base address */ + card->irq = macio_irq(mdev, 0); + phys_addr = macio_resource_start(mdev, 0); /* Physical address */ + printk(KERN_DEBUG PFX "Physical address %lx\n", phys_addr); + card->vaddr = ioremap(phys_addr, AIRPORT_IO_LEN); + if (!card->vaddr) { + printk(KERN_ERR PFX "ioremap() failed\n"); + goto failed; + } + + hermes_struct_init(hw, card->vaddr, HERMES_16BIT_REGSPACING); + + /* Power up card */ + pmac_call_feature(PMAC_FTR_AIRPORT_ENABLE, + macio_get_of_node(mdev), 0, 1); + ssleep(1); + + /* Reset it before we get the interrupt */ + hw->ops->init(hw); + + if (request_irq(card->irq, orinoco_interrupt, 0, DRIVER_NAME, priv)) { + printk(KERN_ERR PFX "Couldn't get IRQ %d\n", card->irq); + goto failed; + } + card->irq_requested = 1; + + /* Initialise the main driver */ + if (orinoco_init(priv) != 0) { + printk(KERN_ERR PFX "orinoco_init() failed\n"); + goto failed; + } + + /* Register an interface with the stack */ + if (orinoco_if_add(priv, phys_addr, card->irq, NULL) != 0) { + printk(KERN_ERR PFX "orinoco_if_add() failed\n"); + goto failed; + } + card->ndev_registered = 1; + return 0; + failed: + airport_detach(mdev); + return -ENODEV; +} /* airport_attach */ + + +static char version[] __initdata = DRIVER_NAME " " DRIVER_VERSION + " (Benjamin Herrenschmidt <benh@kernel.crashing.org>)"; +MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>"); +MODULE_DESCRIPTION("Driver for the Apple Airport wireless card."); +MODULE_LICENSE("Dual MPL/GPL"); + +static const struct of_device_id airport_match[] = { + { + .name = "radio", + }, + {}, +}; + +MODULE_DEVICE_TABLE(of, airport_match); + +static struct macio_driver airport_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = airport_match, + }, + .probe = airport_attach, + .remove = airport_detach, + .suspend = airport_suspend, + .resume = airport_resume, +}; + +static int __init +init_airport(void) +{ + printk(KERN_DEBUG "%s\n", version); + + return macio_register_driver(&airport_driver); +} + +static void __exit +exit_airport(void) +{ + macio_unregister_driver(&airport_driver); +} + +module_init(init_airport); +module_exit(exit_airport); diff --git a/drivers/net/wireless/intersil/orinoco/cfg.c b/drivers/net/wireless/intersil/orinoco/cfg.c new file mode 100644 index 000000000000..0f6ea316e38e --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/cfg.c @@ -0,0 +1,291 @@ +/* cfg80211 support + * + * See copyright notice in main.c + */ +#include <linux/ieee80211.h> +#include <net/cfg80211.h> +#include "hw.h" +#include "main.h" +#include "orinoco.h" + +#include "cfg.h" + +/* Supported bitrates. Must agree with hw.c */ +static struct ieee80211_rate orinoco_rates[] = { + { .bitrate = 10 }, + { .bitrate = 20 }, + { .bitrate = 55 }, + { .bitrate = 110 }, +}; + +static const void * const orinoco_wiphy_privid = &orinoco_wiphy_privid; + +/* Called after orinoco_private is allocated. */ +void orinoco_wiphy_init(struct wiphy *wiphy) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + + wiphy->privid = orinoco_wiphy_privid; + + set_wiphy_dev(wiphy, priv->dev); +} + +/* Called after firmware is initialised */ +int orinoco_wiphy_register(struct wiphy *wiphy) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + int i, channels = 0; + + if (priv->firmware_type == FIRMWARE_TYPE_AGERE) + wiphy->max_scan_ssids = 1; + else + wiphy->max_scan_ssids = 0; + + wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); + + /* TODO: should we set if we only have demo ad-hoc? + * (priv->has_port3) + */ + if (priv->has_ibss) + wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC); + + if (!priv->broken_monitor || force_monitor) + wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR); + + priv->band.bitrates = orinoco_rates; + priv->band.n_bitrates = ARRAY_SIZE(orinoco_rates); + + /* Only support channels allowed by the card EEPROM */ + for (i = 0; i < NUM_CHANNELS; i++) { + if (priv->channel_mask & (1 << i)) { + priv->channels[i].center_freq = + ieee80211_channel_to_frequency(i + 1, + IEEE80211_BAND_2GHZ); + channels++; + } + } + priv->band.channels = priv->channels; + priv->band.n_channels = channels; + + wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band; + wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; + + i = 0; + if (priv->has_wep) { + priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP40; + i++; + + if (priv->has_big_wep) { + priv->cipher_suites[i] = WLAN_CIPHER_SUITE_WEP104; + i++; + } + } + if (priv->has_wpa) { + priv->cipher_suites[i] = WLAN_CIPHER_SUITE_TKIP; + i++; + } + wiphy->cipher_suites = priv->cipher_suites; + wiphy->n_cipher_suites = i; + + wiphy->rts_threshold = priv->rts_thresh; + if (!priv->has_mwo) + wiphy->frag_threshold = priv->frag_thresh + 1; + wiphy->retry_short = priv->short_retry_limit; + wiphy->retry_long = priv->long_retry_limit; + + return wiphy_register(wiphy); +} + +static int orinoco_change_vif(struct wiphy *wiphy, struct net_device *dev, + enum nl80211_iftype type, u32 *flags, + struct vif_params *params) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + int err = 0; + unsigned long lock; + + if (orinoco_lock(priv, &lock) != 0) + return -EBUSY; + + switch (type) { + case NL80211_IFTYPE_ADHOC: + if (!priv->has_ibss && !priv->has_port3) + err = -EINVAL; + break; + + case NL80211_IFTYPE_STATION: + break; + + case NL80211_IFTYPE_MONITOR: + if (priv->broken_monitor && !force_monitor) { + wiphy_warn(wiphy, + "Monitor mode support is buggy in this firmware, not enabling\n"); + err = -EINVAL; + } + break; + + default: + err = -EINVAL; + } + + if (!err) { + priv->iw_mode = type; + set_port_type(priv); + err = orinoco_commit(priv); + } + + orinoco_unlock(priv, &lock); + + return err; +} + +static int orinoco_scan(struct wiphy *wiphy, + struct cfg80211_scan_request *request) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + int err; + + if (!request) + return -EINVAL; + + if (priv->scan_request && priv->scan_request != request) + return -EBUSY; + + priv->scan_request = request; + + err = orinoco_hw_trigger_scan(priv, request->ssids); + /* On error the we aren't processing the request */ + if (err) + priv->scan_request = NULL; + + return err; +} + +static int orinoco_set_monitor_channel(struct wiphy *wiphy, + struct cfg80211_chan_def *chandef) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + int err = 0; + unsigned long flags; + int channel; + + if (!chandef->chan) + return -EINVAL; + + if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT) + return -EINVAL; + + if (chandef->chan->band != IEEE80211_BAND_2GHZ) + return -EINVAL; + + channel = ieee80211_frequency_to_channel(chandef->chan->center_freq); + + if ((channel < 1) || (channel > NUM_CHANNELS) || + !(priv->channel_mask & (1 << (channel - 1)))) + return -EINVAL; + + if (orinoco_lock(priv, &flags) != 0) + return -EBUSY; + + priv->channel = channel; + if (priv->iw_mode == NL80211_IFTYPE_MONITOR) { + /* Fast channel change - no commit if successful */ + struct hermes *hw = &priv->hw; + err = hw->ops->cmd_wait(hw, HERMES_CMD_TEST | + HERMES_TEST_SET_CHANNEL, + channel, NULL); + } + orinoco_unlock(priv, &flags); + + return err; +} + +static int orinoco_set_wiphy_params(struct wiphy *wiphy, u32 changed) +{ + struct orinoco_private *priv = wiphy_priv(wiphy); + int frag_value = -1; + int rts_value = -1; + int err = 0; + + if (changed & WIPHY_PARAM_RETRY_SHORT) { + /* Setting short retry not supported */ + err = -EINVAL; + } + + if (changed & WIPHY_PARAM_RETRY_LONG) { + /* Setting long retry not supported */ + err = -EINVAL; + } + + if (changed & WIPHY_PARAM_FRAG_THRESHOLD) { + /* Set fragmentation */ + if (priv->has_mwo) { + if (wiphy->frag_threshold == -1) + frag_value = 0; + else { + printk(KERN_WARNING "%s: Fixed fragmentation " + "is not supported on this firmware. " + "Using MWO robust instead.\n", + priv->ndev->name); + frag_value = 1; + } + } else { + if (wiphy->frag_threshold == -1) + frag_value = 2346; + else if ((wiphy->frag_threshold < 257) || + (wiphy->frag_threshold > 2347)) + err = -EINVAL; + else + /* cfg80211 value is 257-2347 (odd only) + * orinoco rid has range 256-2346 (even only) */ + frag_value = wiphy->frag_threshold & ~0x1; + } + } + + if (changed & WIPHY_PARAM_RTS_THRESHOLD) { + /* Set RTS. + * + * Prism documentation suggests default of 2432, + * and a range of 0-3000. + * + * Current implementation uses 2347 as the default and + * the upper limit. + */ + + if (wiphy->rts_threshold == -1) + rts_value = 2347; + else if (wiphy->rts_threshold > 2347) + err = -EINVAL; + else + rts_value = wiphy->rts_threshold; + } + + if (!err) { + unsigned long flags; + + if (orinoco_lock(priv, &flags) != 0) + return -EBUSY; + + if (frag_value >= 0) { + if (priv->has_mwo) + priv->mwo_robust = frag_value; + else + priv->frag_thresh = frag_value; + } + if (rts_value >= 0) + priv->rts_thresh = rts_value; + + err = orinoco_commit(priv); + + orinoco_unlock(priv, &flags); + } + + return err; +} + +const struct cfg80211_ops orinoco_cfg_ops = { + .change_virtual_intf = orinoco_change_vif, + .set_monitor_channel = orinoco_set_monitor_channel, + .scan = orinoco_scan, + .set_wiphy_params = orinoco_set_wiphy_params, +}; diff --git a/drivers/net/wireless/intersil/orinoco/cfg.h b/drivers/net/wireless/intersil/orinoco/cfg.h new file mode 100644 index 000000000000..3ddc96a06cd7 --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/cfg.h @@ -0,0 +1,15 @@ +/* cfg80211 support. + * + * See copyright notice in main.c + */ +#ifndef ORINOCO_CFG_H +#define ORINOCO_CFG_H + +#include <net/cfg80211.h> + +extern const struct cfg80211_ops orinoco_cfg_ops; + +void orinoco_wiphy_init(struct wiphy *wiphy); +int orinoco_wiphy_register(struct wiphy *wiphy); + +#endif /* ORINOCO_CFG_H */ diff --git a/drivers/net/wireless/intersil/orinoco/fw.c b/drivers/net/wireless/intersil/orinoco/fw.c new file mode 100644 index 000000000000..400a35217644 --- /dev/null +++ b/drivers/net/wireless/intersil/orinoco/fw.c @@ -0,0 +1,387 @@ +/* Firmware file reading and download helpers + * + * See copyright notice in main.c + */ +#include <linux/kernel.h> +#include <linux/slab.h> +#include <linux/firmware.h> +#include <linux/device.h> +#include <linux/module.h> + +#include "hermes.h" +#include "hermes_dld.h" +#include "orinoco.h" + +#include "fw.h" + +/* End markers (for Symbol firmware only) */ +#define TEXT_END 0x1A /* End of text header */ + +struct fw_info { + char *pri_fw; + char *sta_fw; + char *ap_fw; + u32 pda_addr; + u16 pda_size; +}; + +static const struct fw_info orinoco_fw[] = { + { NULL, "agere_sta_fw.bin", "agere_ap_fw.bin", 0x00390000, 1000 }, + { NULL, "prism_sta_fw.bin", "prism_ap_fw.bin", 0, 1024 }, + { "symbol_sp24t_prim_fw", "symbol_sp24t_sec_fw", NULL, 0x00003100, 512 } +}; +MODULE_FIRMWARE("agere_sta_fw.bin"); +MODULE_FIRMWARE("agere_ap_fw.bin"); +MODULE_FIRMWARE("prism_sta_fw.bin"); +MODULE_FIRMWARE("prism_ap_fw.bin"); +MODULE_FIRMWARE("symbol_sp24t_prim_fw"); +MODULE_FIRMWARE("symbol_sp24t_sec_fw"); + +/* Structure used to access fields in FW + * Make sure LE decoding macros are used + */ +struct orinoco_fw_header { + char hdr_vers[6]; /* ASCII string for header version */ + __le16 headersize; /* Total length of header */ + __le32 entry_point; /* NIC entry point */ + __le32 blocks; /* Number of blocks to program */ + __le32 block_offset; /* Offset of block data from eof header */ + __le32 pdr_offset; /* Offset to PDR data from eof header */ + __le32 pri_offset; /* Offset to primary plug data */ + __le32 compat_offset; /* Offset to compatibility data*/ + char signature[0]; /* FW signature length headersize-20 */ +} __packed; + +/* Check th |