···11config ATH6KL22- tristate "Atheros mobile chipsets support"33-44-config ATH6KL_SDIO55- tristate "Atheros ath6kl SDIO support"66- depends on ATH6KL22+ tristate "Atheros ath6kl support"73 depends on MMC84 depends on CFG8021195 ---help---106 This module adds support for wireless adapters based on1111- Atheros AR6003 and AR6004 chipsets running over SDIO. If you1212- choose to build it as a module, it will be called ath6kl_sdio.1313- Please note that AR6002 and AR6001 are not supported by this1414- driver.1515-1616-config ATH6KL_USB1717- tristate "Atheros ath6kl USB support"1818- depends on ATH6KL1919- depends on USB2020- depends on CFG802112121- depends on EXPERIMENTAL2222- ---help---2323- This module adds support for wireless adapters based on2424- Atheros AR6004 chipset running over USB. This is still under2525- implementation and it isn't functional. If you choose to2626- build it as a module, it will be called ath6kl_usb.77+ Atheros AR6003 chipset running over SDIO. If you choose to88+ build it as a module, it will be called ath6kl. Pls note99+ that AR6002 and AR6001 are not supported by this driver.27102811config ATH6KL_DEBUG2912 bool "Atheros ath6kl debugging"
···689689 ath6kl_dbg(ATH6KL_DBG_HIF, "hif block size %d mbox addr 0x%x\n",690690 dev->htc_cnxt->block_sz, dev->ar->mbox_info.htc_addr);691691692692- /* usb doesn't support enabling interrupts */693693- /* FIXME: remove check once USB support is implemented */694694- if (dev->ar->hif_type == ATH6KL_HIF_TYPE_USB)695695- return 0;696696-697692 status = ath6kl_hif_disable_intrs(dev);698693699694fail_setup:
+1-9
drivers/net/wireless/ath/ath6kl/htc.c
···25432543 struct htc_service_connect_resp resp;25442544 int status;2545254525462546- /* FIXME: remove once USB support is implemented */25472547- if (target->dev->ar->hif_type == ATH6KL_HIF_TYPE_USB) {25482548- ath6kl_err("HTC doesn't support USB yet. Patience!\n");25492549- return -EOPNOTSUPP;25502550- }25512551-25522546 /* we should be getting 1 control message that the target is ready */25532547 packet = htc_wait_for_ctrl_msg(target);25542548···27722778{27732779 struct htc_packet *packet, *tmp_packet;2774278027752775- /* FIXME: remove check once USB support is implemented */27762776- if (target->dev->ar->hif_type != ATH6KL_HIF_TYPE_USB)27772777- ath6kl_hif_cleanup_scatter(target->dev->ar);27812781+ ath6kl_hif_cleanup_scatter(target->dev->ar);2778278227792783 list_for_each_entry_safe(packet, tmp_packet,27802784 &target->free_ctrl_txbuf, list) {
···560560 u8 algorithm;561561};562562563563+#define B43legacy_QOS_QUEUE_NUM 4564564+563565struct b43legacy_wldev;566566+567567+/* QOS parameters for a queue. */568568+struct b43legacy_qos_params {569569+ /* The QOS parameters */570570+ struct ieee80211_tx_queue_params p;571571+};564572565573/* Data structure for the WLAN parts (802.11 cores) of the b43legacy chip. */566574struct b43legacy_wl {···619611 bool beacon1_uploaded;620612 bool beacon_templates_virgin; /* Never wrote the templates? */621613 struct work_struct beacon_update_trigger;614614+ /* The current QOS parameters for the 4 queues. */615615+ struct b43legacy_qos_params qos_params[B43legacy_QOS_QUEUE_NUM];616616+617617+ /* Packet transmit work */618618+ struct work_struct tx_work;619619+620620+ /* Queue of packets to be transmitted. */621621+ struct sk_buff_head tx_queue[B43legacy_QOS_QUEUE_NUM];622622+623623+ /* Flag that implement the queues stopping. */624624+ bool tx_queue_stopped[B43legacy_QOS_QUEUE_NUM];625625+622626};623627624628/* Pointers to the firmware data and meta information about it. */
+37-30
drivers/net/wireless/b43legacy/dma.c
···727727 } else728728 B43legacy_WARN_ON(1);729729 }730730- spin_lock_init(&ring->lock);731730#ifdef CONFIG_B43LEGACY_DEBUG732731 ring->last_injected_overflow = jiffies;733732#endif···11431144{11441145 struct b43legacy_dmaring *ring;11451146 int err = 0;11461146- unsigned long flags;1147114711481148 ring = priority_to_txring(dev, skb_get_queue_mapping(skb));11491149- spin_lock_irqsave(&ring->lock, flags);11501149 B43legacy_WARN_ON(!ring->tx);1151115011521151 if (unlikely(ring->stopped)) {···11541157 * For now, just refuse the transmit. */11551158 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))11561159 b43legacyerr(dev->wl, "Packet after queue stopped\n");11571157- err = -ENOSPC;11581158- goto out_unlock;11601160+ return -ENOSPC;11591161 }1160116211611163 if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) {11621164 /* If we get here, we have a real error with the queue11631165 * full, but queues not stopped. */11641166 b43legacyerr(dev->wl, "DMA queue overflow\n");11651165- err = -ENOSPC;11661166- goto out_unlock;11671167+ return -ENOSPC;11671168 }1168116911691170 /* dma_tx_fragment might reallocate the skb, so invalidate pointers pointing···11711176 /* Drop this packet, as we don't have the encryption key11721177 * anymore and must not transmit it unencrypted. */11731178 dev_kfree_skb_any(skb);11741174- err = 0;11751175- goto out_unlock;11791179+ return 0;11761180 }11771181 if (unlikely(err)) {11781182 b43legacyerr(dev->wl, "DMA tx mapping failure\n");11791179- goto out_unlock;11831183+ return err;11801184 }11811185 if ((free_slots(ring) < SLOTS_PER_PACKET) ||11821186 should_inject_overflow(ring)) {11831187 /* This TX ring is full. */11841184- ieee80211_stop_queue(dev->wl->hw, txring_to_priority(ring));11881188+ unsigned int skb_mapping = skb_get_queue_mapping(skb);11891189+ ieee80211_stop_queue(dev->wl->hw, skb_mapping);11901190+ dev->wl->tx_queue_stopped[skb_mapping] = 1;11851191 ring->stopped = true;11861192 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))11871193 b43legacydbg(dev->wl, "Stopped TX ring %d\n",11881194 ring->index);11891195 }11901190-out_unlock:11911191- spin_unlock_irqrestore(&ring->lock, flags);11921192-11931196 return err;11941197}11951198···11981205 struct b43legacy_dmadesc_meta *meta;11991206 int retry_limit;12001207 int slot;12081208+ int firstused;1201120912021210 ring = parse_cookie(dev, status->cookie, &slot);12031211 if (unlikely(!ring))12041212 return;12051205- B43legacy_WARN_ON(!irqs_disabled());12061206- spin_lock(&ring->lock);12071207-12081213 B43legacy_WARN_ON(!ring->tx);12141214+12151215+ /* Sanity check: TX packets are processed in-order on one ring.12161216+ * Check if the slot deduced from the cookie really is the first12171217+ * used slot. */12181218+ firstused = ring->current_slot - ring->used_slots + 1;12191219+ if (firstused < 0)12201220+ firstused = ring->nr_slots + firstused;12211221+ if (unlikely(slot != firstused)) {12221222+ /* This possibly is a firmware bug and will result in12231223+ * malfunction, memory leaks and/or stall of DMA functionality.12241224+ */12251225+ b43legacydbg(dev->wl, "Out of order TX status report on DMA "12261226+ "ring %d. Expected %d, but got %d\n",12271227+ ring->index, firstused, slot);12281228+ return;12291229+ }12301230+12091231 while (1) {12101232 B43legacy_WARN_ON(!(slot >= 0 && slot < ring->nr_slots));12111233 op32_idx2desc(ring, slot, &meta);···12931285 dev->stats.last_tx = jiffies;12941286 if (ring->stopped) {12951287 B43legacy_WARN_ON(free_slots(ring) < SLOTS_PER_PACKET);12961296- ieee80211_wake_queue(dev->wl->hw, txring_to_priority(ring));12971288 ring->stopped = false;12981298- if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))12991299- b43legacydbg(dev->wl, "Woke up TX ring %d\n",13001300- ring->index);13011289 }1302129013031303- spin_unlock(&ring->lock);12911291+ if (dev->wl->tx_queue_stopped[ring->queue_prio]) {12921292+ dev->wl->tx_queue_stopped[ring->queue_prio] = 0;12931293+ } else {12941294+ /* If the driver queue is running wake the corresponding12951295+ * mac80211 queue. */12961296+ ieee80211_wake_queue(dev->wl->hw, ring->queue_prio);12971297+ if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))12981298+ b43legacydbg(dev->wl, "Woke up TX ring %d\n",12991299+ ring->index);13001300+ }13011301+ /* Add work to the queue. */13021302+ ieee80211_queue_work(dev->wl->hw, &dev->wl->tx_work);13041303}1305130413061305static void dma_rx(struct b43legacy_dmaring *ring,···1430141514311416static void b43legacy_dma_tx_suspend_ring(struct b43legacy_dmaring *ring)14321417{14331433- unsigned long flags;14341434-14351435- spin_lock_irqsave(&ring->lock, flags);14361418 B43legacy_WARN_ON(!ring->tx);14371419 op32_tx_suspend(ring);14381438- spin_unlock_irqrestore(&ring->lock, flags);14391420}1440142114411422static void b43legacy_dma_tx_resume_ring(struct b43legacy_dmaring *ring)14421423{14431443- unsigned long flags;14441444-14451445- spin_lock_irqsave(&ring->lock, flags);14461424 B43legacy_WARN_ON(!ring->tx);14471425 op32_tx_resume(ring);14481448- spin_unlock_irqrestore(&ring->lock, flags);14491426}1450142714511428void b43legacy_dma_tx_suspend(struct b43legacy_wldev *dev)
+3-2
drivers/net/wireless/b43legacy/dma.h
···150150 enum b43legacy_dmatype type;151151 /* Boolean. Is this ring stopped at ieee80211 level? */152152 bool stopped;153153- /* Lock, only used for TX. */154154- spinlock_t lock;153153+ /* The QOS priority assigned to this ring. Only used for TX rings.154154+ * This is the mac80211 "queue" value. */155155+ u8 queue_prio;155156 struct b43legacy_wldev *dev;156157#ifdef CONFIG_B43LEGACY_DEBUG157158 /* Maximum number of used slots. */
+67-19
drivers/net/wireless/b43legacy/main.c
···24402440 return err;24412441}2442244224432443+static void b43legacy_tx_work(struct work_struct *work)24442444+{24452445+ struct b43legacy_wl *wl = container_of(work, struct b43legacy_wl,24462446+ tx_work);24472447+ struct b43legacy_wldev *dev;24482448+ struct sk_buff *skb;24492449+ int queue_num;24502450+ int err = 0;24512451+24522452+ mutex_lock(&wl->mutex);24532453+ dev = wl->current_dev;24542454+ if (unlikely(!dev || b43legacy_status(dev) < B43legacy_STAT_STARTED)) {24552455+ mutex_unlock(&wl->mutex);24562456+ return;24572457+ }24582458+24592459+ for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {24602460+ while (skb_queue_len(&wl->tx_queue[queue_num])) {24612461+ skb = skb_dequeue(&wl->tx_queue[queue_num]);24622462+ if (b43legacy_using_pio(dev))24632463+ err = b43legacy_pio_tx(dev, skb);24642464+ else24652465+ err = b43legacy_dma_tx(dev, skb);24662466+ if (err == -ENOSPC) {24672467+ wl->tx_queue_stopped[queue_num] = 1;24682468+ ieee80211_stop_queue(wl->hw, queue_num);24692469+ skb_queue_head(&wl->tx_queue[queue_num], skb);24702470+ break;24712471+ }24722472+ if (unlikely(err))24732473+ dev_kfree_skb(skb); /* Drop it */24742474+ err = 0;24752475+ }24762476+24772477+ if (!err)24782478+ wl->tx_queue_stopped[queue_num] = 0;24792479+ }24802480+24812481+ mutex_unlock(&wl->mutex);24822482+}24832483+24432484static void b43legacy_op_tx(struct ieee80211_hw *hw,24442485 struct sk_buff *skb)24452486{24462487 struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);24472447- struct b43legacy_wldev *dev = wl->current_dev;24482448- int err = -ENODEV;24492449- unsigned long flags;2450248824512451- if (unlikely(!dev))24522452- goto out;24532453- if (unlikely(b43legacy_status(dev) < B43legacy_STAT_STARTED))24542454- goto out;24552455- /* DMA-TX is done without a global lock. */24562456- if (b43legacy_using_pio(dev)) {24572457- spin_lock_irqsave(&wl->irq_lock, flags);24582458- err = b43legacy_pio_tx(dev, skb);24592459- spin_unlock_irqrestore(&wl->irq_lock, flags);24602460- } else24612461- err = b43legacy_dma_tx(dev, skb);24622462-out:24632463- if (unlikely(err)) {24642464- /* Drop the packet. */24892489+ if (unlikely(skb->len < 2 + 2 + 6)) {24902490+ /* Too short, this can't be a valid frame. */24652491 dev_kfree_skb_any(skb);24922492+ return;24662493 }24942494+ B43legacy_WARN_ON(skb_shinfo(skb)->nr_frags);24952495+24962496+ skb_queue_tail(&wl->tx_queue[skb->queue_mapping], skb);24972497+ if (!wl->tx_queue_stopped[skb->queue_mapping])24982498+ ieee80211_queue_work(wl->hw, &wl->tx_work);24992499+ else25002500+ ieee80211_stop_queue(wl->hw, skb->queue_mapping);24672501}2468250224692503static int b43legacy_op_conf_tx(struct ieee80211_hw *hw,···29132879{29142880 struct b43legacy_wl *wl = dev->wl;29152881 unsigned long flags;28822882+ int queue_num;2916288329172884 if (b43legacy_status(dev) < B43legacy_STAT_STARTED)29182885 return;···29332898 /* Must unlock as it would otherwise deadlock. No races here.29342899 * Cancel the possibly running self-rearming periodic work. */29352900 cancel_delayed_work_sync(&dev->periodic_work);29012901+ cancel_work_sync(&wl->tx_work);29362902 mutex_lock(&wl->mutex);2937290329382938- ieee80211_stop_queues(wl->hw); /* FIXME this could cause a deadlock */29042904+ /* Drain all TX queues. */29052905+ for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {29062906+ while (skb_queue_len(&wl->tx_queue[queue_num]))29072907+ dev_kfree_skb(skb_dequeue(&wl->tx_queue[queue_num]));29082908+ }2939290929402940- b43legacy_mac_suspend(dev);29102910+b43legacy_mac_suspend(dev);29412911 free_irq(dev->dev->irq, dev);29422912 b43legacydbg(wl, "Wireless interface stopped\n");29432913}···37883748 struct ieee80211_hw *hw;37893749 struct b43legacy_wl *wl;37903750 int err = -ENOMEM;37513751+ int queue_num;3791375237923753 b43legacy_sprom_fixup(dev->bus);37933754···38233782 mutex_init(&wl->mutex);38243783 INIT_LIST_HEAD(&wl->devlist);38253784 INIT_WORK(&wl->beacon_update_trigger, b43legacy_beacon_update_trigger_work);37853785+ INIT_WORK(&wl->tx_work, b43legacy_tx_work);37863786+37873787+ /* Initialize queues and flags. */37883788+ for (queue_num = 0; queue_num < B43legacy_QOS_QUEUE_NUM; queue_num++) {37893789+ skb_queue_head_init(&wl->tx_queue[queue_num]);37903790+ wl->tx_queue_stopped[queue_num] = 0;37913791+ }3826379238273793 ssb_set_devtypedata(dev, wl);38283794 b43legacyinfo(wl, "Broadcom %04X WLAN found (core revision %u)\n",
-4
drivers/net/wireless/ipw2x00/libipw.h
···805805 /* WEP and other encryption related settings at the device level */806806 int open_wep; /* Set to 1 to allow unencrypted frames */807807808808- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on809809- * WEP key changes */810810-811808 /* If the host performs {en,de}cryption, then set to 1 */812809 int host_encrypt;813810 int host_encrypt_msdu;···857860 struct libipw_security * sec);858861 netdev_tx_t (*hard_start_xmit) (struct libipw_txb * txb,859862 struct net_device * dev, int pri);860860- int (*reset_port) (struct net_device * dev);861863 int (*is_queue_full) (struct net_device * dev, int pri);862864863865 int (*handle_management) (struct net_device * dev,
-25
drivers/net/wireless/ipw2x00/libipw_wx.c
···474474 if (ieee->set_security)475475 ieee->set_security(dev, &sec);476476477477- /* Do not reset port if card is in Managed mode since resetting will478478- * generate new IEEE 802.11 authentication which may end up in looping479479- * with IEEE 802.1X. If your hardware requires a reset after WEP480480- * configuration (for example... Prism2), implement the reset_port in481481- * the callbacks structures used to initialize the 802.11 stack. */482482- if (ieee->reset_on_keychange &&483483- ieee->iw_mode != IW_MODE_INFRA &&484484- ieee->reset_port && ieee->reset_port(dev)) {485485- printk(KERN_DEBUG "%s: reset_port failed\n", dev->name);486486- return -EINVAL;487487- }488477 return 0;489478}490479···676687 done:677688 if (ieee->set_security)678689 ieee->set_security(ieee->dev, &sec);679679-680680- /*681681- * Do not reset port if card is in Managed mode since resetting will682682- * generate new IEEE 802.11 authentication which may end up in looping683683- * with IEEE 802.1X. If your hardware requires a reset after WEP684684- * configuration (for example... Prism2), implement the reset_port in685685- * the callbacks structures used to initialize the 802.11 stack.686686- */687687- if (ieee->reset_on_keychange &&688688- ieee->iw_mode != IW_MODE_INFRA &&689689- ieee->reset_port && ieee->reset_port(dev)) {690690- LIBIPW_DEBUG_WX("%s: reset_port failed\n", dev->name);691691- return -EINVAL;692692- }693690694691 return ret;695692}
+5-6
drivers/net/wireless/iwlegacy/3945-mac.c
···570570 /* TODO need this for burst mode later on */571571 il3945_build_tx_cmd_basic(il, out_cmd, info, hdr, sta_id);572572573573- /* set is_hcca to 0; it probably will never be implemented */574574- il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id, 0);573573+ il3945_hw_build_tx_cmd_rate(il, out_cmd, info, hdr, sta_id);575574576575 /* Total # bytes to be transmitted */577576 len = (u16) skb->len;···26232624 }2624262526252626 /*26262626- * If active scaning is requested but a certain channel26272627- * is marked passive, we can do active scanning if we26282628- * detect transmissions.26272627+ * If active scaning is requested but a certain channel is marked26282628+ * passive, we can do active scanning if we detect transmissions. For26292629+ * passive only scanning disable switching to active on any channel.26292630 */26302631 scan->good_CRC_th =26312631- is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_DISABLED;26322632+ is_active ? IL_GOOD_CRC_TH_DEFAULT : IL_GOOD_CRC_TH_NEVER;2632263326332634 len =26342635 il_fill_probe_req(il, (struct ieee80211_mgmt *)scan->data,
···42424343#include "common.h"44444545+int4646+_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout)4747+{4848+ const int interval = 10; /* microseconds */4949+ int t = 0;5050+5151+ do {5252+ if ((_il_rd(il, addr) & mask) == (bits & mask))5353+ return t;5454+ udelay(interval);5555+ t += interval;5656+ } while (t < timeout);5757+5858+ return -ETIMEDOUT;5959+}6060+EXPORT_SYMBOL(_il_poll_bit);6161+6262+void6363+il_set_bit(struct il_priv *p, u32 r, u32 m)6464+{6565+ unsigned long reg_flags;6666+6767+ spin_lock_irqsave(&p->reg_lock, reg_flags);6868+ _il_set_bit(p, r, m);6969+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);7070+}7171+EXPORT_SYMBOL(il_set_bit);7272+7373+void7474+il_clear_bit(struct il_priv *p, u32 r, u32 m)7575+{7676+ unsigned long reg_flags;7777+7878+ spin_lock_irqsave(&p->reg_lock, reg_flags);7979+ _il_clear_bit(p, r, m);8080+ spin_unlock_irqrestore(&p->reg_lock, reg_flags);8181+}8282+EXPORT_SYMBOL(il_clear_bit);8383+8484+int8585+_il_grab_nic_access(struct il_priv *il)8686+{8787+ int ret;8888+ u32 val;8989+9090+ /* this bit wakes up the NIC */9191+ _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);9292+9393+ /*9494+ * These bits say the device is running, and should keep running for9595+ * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),9696+ * but they do not indicate that embedded SRAM is restored yet;9797+ * 3945 and 4965 have volatile SRAM, and must save/restore contents9898+ * to/from host DRAM when sleeping/waking for power-saving.9999+ * Each direction takes approximately 1/4 millisecond; with this100100+ * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a101101+ * series of register accesses are expected (e.g. reading Event Log),102102+ * to keep device from sleeping.103103+ *104104+ * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that105105+ * SRAM is okay/restored. We don't check that here because this call106106+ * is just for hardware register access; but GP1 MAC_SLEEP check is a107107+ * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).108108+ *109109+ */110110+ ret =111111+ _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,112112+ (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |113113+ CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);114114+ if (ret < 0) {115115+ val = _il_rd(il, CSR_GP_CNTRL);116116+ IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);117117+ _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);118118+ return -EIO;119119+ }120120+121121+ return 0;122122+}123123+EXPORT_SYMBOL_GPL(_il_grab_nic_access);124124+125125+int126126+il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout)127127+{128128+ const int interval = 10; /* microseconds */129129+ int t = 0;130130+131131+ do {132132+ if ((il_rd(il, addr) & mask) == mask)133133+ return t;134134+ udelay(interval);135135+ t += interval;136136+ } while (t < timeout);137137+138138+ return -ETIMEDOUT;139139+}140140+EXPORT_SYMBOL(il_poll_bit);141141+142142+u32143143+il_rd_prph(struct il_priv *il, u32 reg)144144+{145145+ unsigned long reg_flags;146146+ u32 val;147147+148148+ spin_lock_irqsave(&il->reg_lock, reg_flags);149149+ _il_grab_nic_access(il);150150+ val = _il_rd_prph(il, reg);151151+ _il_release_nic_access(il);152152+ spin_unlock_irqrestore(&il->reg_lock, reg_flags);153153+ return val;154154+}155155+EXPORT_SYMBOL(il_rd_prph);156156+157157+void158158+il_wr_prph(struct il_priv *il, u32 addr, u32 val)159159+{160160+ unsigned long reg_flags;161161+162162+ spin_lock_irqsave(&il->reg_lock, reg_flags);163163+ if (!_il_grab_nic_access(il)) {164164+ _il_wr_prph(il, addr, val);165165+ _il_release_nic_access(il);166166+ }167167+ spin_unlock_irqrestore(&il->reg_lock, reg_flags);168168+}169169+EXPORT_SYMBOL(il_wr_prph);170170+171171+u32172172+il_read_targ_mem(struct il_priv *il, u32 addr)173173+{174174+ unsigned long reg_flags;175175+ u32 value;176176+177177+ spin_lock_irqsave(&il->reg_lock, reg_flags);178178+ _il_grab_nic_access(il);179179+180180+ _il_wr(il, HBUS_TARG_MEM_RADDR, addr);181181+ rmb();182182+ value = _il_rd(il, HBUS_TARG_MEM_RDAT);183183+184184+ _il_release_nic_access(il);185185+ spin_unlock_irqrestore(&il->reg_lock, reg_flags);186186+ return value;187187+}188188+EXPORT_SYMBOL(il_read_targ_mem);189189+190190+void191191+il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)192192+{193193+ unsigned long reg_flags;194194+195195+ spin_lock_irqsave(&il->reg_lock, reg_flags);196196+ if (!_il_grab_nic_access(il)) {197197+ _il_wr(il, HBUS_TARG_MEM_WADDR, addr);198198+ wmb();199199+ _il_wr(il, HBUS_TARG_MEM_WDAT, val);200200+ _il_release_nic_access(il);201201+ }202202+ spin_unlock_irqrestore(&il->reg_lock, reg_flags);203203+}204204+EXPORT_SYMBOL(il_write_targ_mem);205205+45206const char *46207il_get_cmd_string(u8 cmd)47208{
+14-192
drivers/net/wireless/iwlegacy/common.h
···3131#include <linux/kernel.h>3232#include <linux/leds.h>3333#include <linux/wait.h>3434+#include <linux/io.h>3435#include <net/mac80211.h>3536#include <net/ieee80211_radiotap.h>3637···2164216321652164irqreturn_t il_isr(int irq, void *data);2166216521672167-#include <linux/io.h>21662166+extern void il_set_bit(struct il_priv *p, u32 r, u32 m);21672167+extern void il_clear_bit(struct il_priv *p, u32 r, u32 m);21682168+extern int _il_grab_nic_access(struct il_priv *il);21692169+extern int _il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout);21702170+extern int il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout);21712171+extern u32 il_rd_prph(struct il_priv *il, u32 reg);21722172+extern void il_wr_prph(struct il_priv *il, u32 addr, u32 val);21732173+extern u32 il_read_targ_mem(struct il_priv *il, u32 addr);21742174+extern void il_write_targ_mem(struct il_priv *il, u32 addr, u32 val);2168217521692176static inline void21702177_il_write8(struct il_priv *il, u32 ofs, u8 val)···21932184 return ioread32(il->hw_base + ofs);21942185}2195218621962196-#define IL_POLL_INTERVAL 10 /* microseconds */21972197-static inline int21982198-_il_poll_bit(struct il_priv *il, u32 addr, u32 bits, u32 mask, int timeout)21992199-{22002200- int t = 0;22012201-22022202- do {22032203- if ((_il_rd(il, addr) & mask) == (bits & mask))22042204- return t;22052205- udelay(IL_POLL_INTERVAL);22062206- t += IL_POLL_INTERVAL;22072207- } while (t < timeout);22082208-22092209- return -ETIMEDOUT;22102210-}22112211-22122212-static inline void22132213-_il_set_bit(struct il_priv *il, u32 reg, u32 mask)22142214-{22152215- _il_wr(il, reg, _il_rd(il, reg) | mask);22162216-}22172217-22182218-static inline void22192219-il_set_bit(struct il_priv *p, u32 r, u32 m)22202220-{22212221- unsigned long reg_flags;22222222-22232223- spin_lock_irqsave(&p->reg_lock, reg_flags);22242224- _il_set_bit(p, r, m);22252225- spin_unlock_irqrestore(&p->reg_lock, reg_flags);22262226-}22272227-22282187static inline void22292188_il_clear_bit(struct il_priv *il, u32 reg, u32 mask)22302189{···22002223}2201222422022225static inline void22032203-il_clear_bit(struct il_priv *p, u32 r, u32 m)22262226+_il_set_bit(struct il_priv *il, u32 reg, u32 mask)22042227{22052205- unsigned long reg_flags;22062206-22072207- spin_lock_irqsave(&p->reg_lock, reg_flags);22082208- _il_clear_bit(p, r, m);22092209- spin_unlock_irqrestore(&p->reg_lock, reg_flags);22102210-}22112211-22122212-static inline int22132213-_il_grab_nic_access(struct il_priv *il)22142214-{22152215- int ret;22162216- u32 val;22172217-22182218- /* this bit wakes up the NIC */22192219- _il_set_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);22202220-22212221- /*22222222- * These bits say the device is running, and should keep running for22232223- * at least a short while (at least as long as MAC_ACCESS_REQ stays 1),22242224- * but they do not indicate that embedded SRAM is restored yet;22252225- * 3945 and 4965 have volatile SRAM, and must save/restore contents22262226- * to/from host DRAM when sleeping/waking for power-saving.22272227- * Each direction takes approximately 1/4 millisecond; with this22282228- * overhead, it's a good idea to grab and hold MAC_ACCESS_REQUEST if a22292229- * series of register accesses are expected (e.g. reading Event Log),22302230- * to keep device from sleeping.22312231- *22322232- * CSR_UCODE_DRV_GP1 register bit MAC_SLEEP == 0 indicates that22332233- * SRAM is okay/restored. We don't check that here because this call22342234- * is just for hardware register access; but GP1 MAC_SLEEP check is a22352235- * good idea before accessing 3945/4965 SRAM (e.g. reading Event Log).22362236- *22372237- */22382238- ret =22392239- _il_poll_bit(il, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_VAL_MAC_ACCESS_EN,22402240- (CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY |22412241- CSR_GP_CNTRL_REG_FLAG_GOING_TO_SLEEP), 15000);22422242- if (ret < 0) {22432243- val = _il_rd(il, CSR_GP_CNTRL);22442244- IL_ERR("MAC is in deep sleep!. CSR_GP_CNTRL = 0x%08X\n", val);22452245- _il_wr(il, CSR_RESET, CSR_RESET_REG_FLAG_FORCE_NMI);22462246- return -EIO;22472247- }22482248-22492249- return 0;22282228+ _il_wr(il, reg, _il_rd(il, reg) | mask);22502229}2251223022522231static inline void···22232290 _il_release_nic_access(il);22242291 spin_unlock_irqrestore(&il->reg_lock, reg_flags);22252292 return value;22262226-22272293}2228229422292295static inline void···22382306 spin_unlock_irqrestore(&il->reg_lock, reg_flags);22392307}2240230822412241-static inline void22422242-il_write_reg_buf(struct il_priv *il, u32 reg, u32 len, u32 * values)22432243-{22442244- u32 count = sizeof(u32);22452245-22462246- if (il != NULL && values != NULL) {22472247- for (; 0 < len; len -= count, reg += count, values++)22482248- il_wr(il, reg, *values);22492249- }22502250-}22512251-22522252-static inline int22532253-il_poll_bit(struct il_priv *il, u32 addr, u32 mask, int timeout)22542254-{22552255- int t = 0;22562256-22572257- do {22582258- if ((il_rd(il, addr) & mask) == mask)22592259- return t;22602260- udelay(IL_POLL_INTERVAL);22612261- t += IL_POLL_INTERVAL;22622262- } while (t < timeout);22632263-22642264- return -ETIMEDOUT;22652265-}22662266-22672309static inline u3222682310_il_rd_prph(struct il_priv *il, u32 reg)22692311{22702312 _il_wr(il, HBUS_TARG_PRPH_RADDR, reg | (3 << 24));22712313 rmb();22722314 return _il_rd(il, HBUS_TARG_PRPH_RDAT);22732273-}22742274-22752275-static inline u3222762276-il_rd_prph(struct il_priv *il, u32 reg)22772277-{22782278- unsigned long reg_flags;22792279- u32 val;22802280-22812281- spin_lock_irqsave(&il->reg_lock, reg_flags);22822282- _il_grab_nic_access(il);22832283- val = _il_rd_prph(il, reg);22842284- _il_release_nic_access(il);22852285- spin_unlock_irqrestore(&il->reg_lock, reg_flags);22862286- return val;22872315}2288231622892317static inline void···22552363}2256236422572365static inline void22582258-il_wr_prph(struct il_priv *il, u32 addr, u32 val)22592259-{22602260- unsigned long reg_flags;22612261-22622262- spin_lock_irqsave(&il->reg_lock, reg_flags);22632263- if (!_il_grab_nic_access(il)) {22642264- _il_wr_prph(il, addr, val);22652265- _il_release_nic_access(il);22662266- }22672267- spin_unlock_irqrestore(&il->reg_lock, reg_flags);22682268-}22692269-22702270-#define _il_set_bits_prph(il, reg, mask) \22712271-_il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask))22722272-22732273-static inline void22742366il_set_bits_prph(struct il_priv *il, u32 reg, u32 mask)22752367{22762368 unsigned long reg_flags;2277236922782370 spin_lock_irqsave(&il->reg_lock, reg_flags);22792371 _il_grab_nic_access(il);22802280- _il_set_bits_prph(il, reg, mask);23722372+ _il_wr_prph(il, reg, (_il_rd_prph(il, reg) | mask));22812373 _il_release_nic_access(il);22822374 spin_unlock_irqrestore(&il->reg_lock, reg_flags);22832375}22842284-22852285-#define _il_set_bits_mask_prph(il, reg, bits, mask) \22862286-_il_wr_prph(il, reg, \22872287- ((_il_rd_prph(il, reg) & mask) | bits))2288237622892377static inline void22902378il_set_bits_mask_prph(struct il_priv *il, u32 reg, u32 bits, u32 mask)···2273240122742402 spin_lock_irqsave(&il->reg_lock, reg_flags);22752403 _il_grab_nic_access(il);22762276- _il_set_bits_mask_prph(il, reg, bits, mask);24042404+ _il_wr_prph(il, reg, ((_il_rd_prph(il, reg) & mask) | bits));22772405 _il_release_nic_access(il);22782406 spin_unlock_irqrestore(&il->reg_lock, reg_flags);22792407}···22892417 val = _il_rd_prph(il, reg);22902418 _il_wr_prph(il, reg, (val & ~mask));22912419 _il_release_nic_access(il);22922292- spin_unlock_irqrestore(&il->reg_lock, reg_flags);22932293-}22942294-22952295-static inline u3222962296-il_read_targ_mem(struct il_priv *il, u32 addr)22972297-{22982298- unsigned long reg_flags;22992299- u32 value;23002300-23012301- spin_lock_irqsave(&il->reg_lock, reg_flags);23022302- _il_grab_nic_access(il);23032303-23042304- _il_wr(il, HBUS_TARG_MEM_RADDR, addr);23052305- rmb();23062306- value = _il_rd(il, HBUS_TARG_MEM_RDAT);23072307-23082308- _il_release_nic_access(il);23092309- spin_unlock_irqrestore(&il->reg_lock, reg_flags);23102310- return value;23112311-}23122312-23132313-static inline void23142314-il_write_targ_mem(struct il_priv *il, u32 addr, u32 val)23152315-{23162316- unsigned long reg_flags;23172317-23182318- spin_lock_irqsave(&il->reg_lock, reg_flags);23192319- if (!_il_grab_nic_access(il)) {23202320- _il_wr(il, HBUS_TARG_MEM_WADDR, addr);23212321- wmb();23222322- _il_wr(il, HBUS_TARG_MEM_WDAT, val);23232323- _il_release_nic_access(il);23242324- }23252325- spin_unlock_irqrestore(&il->reg_lock, reg_flags);23262326-}23272327-23282328-static inline void23292329-il_write_targ_mem_buf(struct il_priv *il, u32 addr, u32 len, u32 * values)23302330-{23312331- unsigned long reg_flags;23322332-23332333- spin_lock_irqsave(&il->reg_lock, reg_flags);23342334- if (!_il_grab_nic_access(il)) {23352335- _il_wr(il, HBUS_TARG_MEM_WADDR, addr);23362336- wmb();23372337- for (; 0 < len; len -= sizeof(u32), values++)23382338- _il_wr(il, HBUS_TARG_MEM_WDAT, *values);23392339-23402340- _il_release_nic_access(il);23412341- }23422420 spin_unlock_irqrestore(&il->reg_lock, reg_flags);23432421}23442422
-817
drivers/net/wireless/iwlegacy/iwl-sta.c
···11-/******************************************************************************22- *33- * Copyright(c) 2003 - 2011 Intel Corporation. All rights reserved.44- *55- * Portions of this file are derived from the ipw3945 project, as well66- * as portions of the ieee80211 subsystem header files.77- *88- * This program is free software; you can redistribute it and/or modify it99- * under the terms of version 2 of the GNU General Public License as1010- * published by the Free Software Foundation.1111- *1212- * This program is distributed in the hope that it will be useful, but WITHOUT1313- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or1414- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for1515- * more details.1616- *1717- * You should have received a copy of the GNU General Public License along with1818- * this program; if not, write to the Free Software Foundation, Inc.,1919- * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA2020- *2121- * The full GNU General Public License is included in this distribution in the2222- * file called LICENSE.2323- *2424- * Contact Information:2525- * Intel Linux Wireless <ilw@linux.intel.com>2626- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-64972727- *2828- *****************************************************************************/2929-3030-#include <net/mac80211.h>3131-#include <linux/etherdevice.h>3232-#include <linux/sched.h>3333-#include <linux/lockdep.h>3434-#include <linux/export.h>3535-3636-#include "iwl-dev.h"3737-#include "iwl-core.h"3838-#include "iwl-sta.h"3939-4040-/* il->sta_lock must be held */4141-static void il_sta_ucode_activate(struct il_priv *il, u8 sta_id)4242-{4343-4444- if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE))4545- IL_ERR(4646- "ACTIVATE a non DRIVER active station id %u addr %pM\n",4747- sta_id, il->stations[sta_id].sta.sta.addr);4848-4949- if (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) {5050- D_ASSOC(5151- "STA id %u addr %pM already present"5252- " in uCode (according to driver)\n",5353- sta_id, il->stations[sta_id].sta.sta.addr);5454- } else {5555- il->stations[sta_id].used |= IL_STA_UCODE_ACTIVE;5656- D_ASSOC("Added STA id %u addr %pM to uCode\n",5757- sta_id, il->stations[sta_id].sta.sta.addr);5858- }5959-}6060-6161-static int il_process_add_sta_resp(struct il_priv *il,6262- struct il_addsta_cmd *addsta,6363- struct il_rx_pkt *pkt,6464- bool sync)6565-{6666- u8 sta_id = addsta->sta.sta_id;6767- unsigned long flags;6868- int ret = -EIO;6969-7070- if (pkt->hdr.flags & IL_CMD_FAILED_MSK) {7171- IL_ERR("Bad return from C_ADD_STA (0x%08X)\n",7272- pkt->hdr.flags);7373- return ret;7474- }7575-7676- D_INFO("Processing response for adding station %u\n",7777- sta_id);7878-7979- spin_lock_irqsave(&il->sta_lock, flags);8080-8181- switch (pkt->u.add_sta.status) {8282- case ADD_STA_SUCCESS_MSK:8383- D_INFO("C_ADD_STA PASSED\n");8484- il_sta_ucode_activate(il, sta_id);8585- ret = 0;8686- break;8787- case ADD_STA_NO_ROOM_IN_TBL:8888- IL_ERR("Adding station %d failed, no room in table.\n",8989- sta_id);9090- break;9191- case ADD_STA_NO_BLOCK_ACK_RESOURCE:9292- IL_ERR(9393- "Adding station %d failed, no block ack resource.\n",9494- sta_id);9595- break;9696- case ADD_STA_MODIFY_NON_EXIST_STA:9797- IL_ERR("Attempting to modify non-existing station %d\n",9898- sta_id);9999- break;100100- default:101101- D_ASSOC("Received C_ADD_STA:(0x%08X)\n",102102- pkt->u.add_sta.status);103103- break;104104- }105105-106106- D_INFO("%s station id %u addr %pM\n",107107- il->stations[sta_id].sta.mode ==108108- STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",109109- sta_id, il->stations[sta_id].sta.sta.addr);110110-111111- /*112112- * XXX: The MAC address in the command buffer is often changed from113113- * the original sent to the device. That is, the MAC address114114- * written to the command buffer often is not the same MAC address115115- * read from the command buffer when the command returns. This116116- * issue has not yet been resolved and this debugging is left to117117- * observe the problem.118118- */119119- D_INFO("%s station according to cmd buffer %pM\n",120120- il->stations[sta_id].sta.mode ==121121- STA_CONTROL_MODIFY_MSK ? "Modified" : "Added",122122- addsta->sta.addr);123123- spin_unlock_irqrestore(&il->sta_lock, flags);124124-125125- return ret;126126-}127127-128128-static void il_add_sta_callback(struct il_priv *il,129129- struct il_device_cmd *cmd,130130- struct il_rx_pkt *pkt)131131-{132132- struct il_addsta_cmd *addsta =133133- (struct il_addsta_cmd *)cmd->cmd.payload;134134-135135- il_process_add_sta_resp(il, addsta, pkt, false);136136-137137-}138138-139139-int il_send_add_sta(struct il_priv *il,140140- struct il_addsta_cmd *sta, u8 flags)141141-{142142- struct il_rx_pkt *pkt = NULL;143143- int ret = 0;144144- u8 data[sizeof(*sta)];145145- struct il_host_cmd cmd = {146146- .id = C_ADD_STA,147147- .flags = flags,148148- .data = data,149149- };150150- u8 sta_id __maybe_unused = sta->sta.sta_id;151151-152152- D_INFO("Adding sta %u (%pM) %ssynchronously\n",153153- sta_id, sta->sta.addr, flags & CMD_ASYNC ? "a" : "");154154-155155- if (flags & CMD_ASYNC)156156- cmd.callback = il_add_sta_callback;157157- else {158158- cmd.flags |= CMD_WANT_SKB;159159- might_sleep();160160- }161161-162162- cmd.len = il->cfg->ops->utils->build_addsta_hcmd(sta, data);163163- ret = il_send_cmd(il, &cmd);164164-165165- if (ret || (flags & CMD_ASYNC))166166- return ret;167167-168168- if (ret == 0) {169169- pkt = (struct il_rx_pkt *)cmd.reply_page;170170- ret = il_process_add_sta_resp(il, sta, pkt, true);171171- }172172- il_free_pages(il, cmd.reply_page);173173-174174- return ret;175175-}176176-EXPORT_SYMBOL(il_send_add_sta);177177-178178-static void il_set_ht_add_station(struct il_priv *il, u8 idx,179179- struct ieee80211_sta *sta,180180- struct il_rxon_context *ctx)181181-{182182- struct ieee80211_sta_ht_cap *sta_ht_inf = &sta->ht_cap;183183- __le32 sta_flags;184184- u8 mimo_ps_mode;185185-186186- if (!sta || !sta_ht_inf->ht_supported)187187- goto done;188188-189189- mimo_ps_mode = (sta_ht_inf->cap & IEEE80211_HT_CAP_SM_PS) >> 2;190190- D_ASSOC("spatial multiplexing power save mode: %s\n",191191- (mimo_ps_mode == WLAN_HT_CAP_SM_PS_STATIC) ?192192- "static" :193193- (mimo_ps_mode == WLAN_HT_CAP_SM_PS_DYNAMIC) ?194194- "dynamic" : "disabled");195195-196196- sta_flags = il->stations[idx].sta.station_flags;197197-198198- sta_flags &= ~(STA_FLG_RTS_MIMO_PROT_MSK | STA_FLG_MIMO_DIS_MSK);199199-200200- switch (mimo_ps_mode) {201201- case WLAN_HT_CAP_SM_PS_STATIC:202202- sta_flags |= STA_FLG_MIMO_DIS_MSK;203203- break;204204- case WLAN_HT_CAP_SM_PS_DYNAMIC:205205- sta_flags |= STA_FLG_RTS_MIMO_PROT_MSK;206206- break;207207- case WLAN_HT_CAP_SM_PS_DISABLED:208208- break;209209- default:210210- IL_WARN("Invalid MIMO PS mode %d\n", mimo_ps_mode);211211- break;212212- }213213-214214- sta_flags |= cpu_to_le32(215215- (u32)sta_ht_inf->ampdu_factor << STA_FLG_MAX_AGG_SIZE_POS);216216-217217- sta_flags |= cpu_to_le32(218218- (u32)sta_ht_inf->ampdu_density << STA_FLG_AGG_MPDU_DENSITY_POS);219219-220220- if (il_is_ht40_tx_allowed(il, ctx, &sta->ht_cap))221221- sta_flags |= STA_FLG_HT40_EN_MSK;222222- else223223- sta_flags &= ~STA_FLG_HT40_EN_MSK;224224-225225- il->stations[idx].sta.station_flags = sta_flags;226226- done:227227- return;228228-}229229-230230-/**231231- * il_prep_station - Prepare station information for addition232232- *233233- * should be called with sta_lock held234234- */235235-u8 il_prep_station(struct il_priv *il, struct il_rxon_context *ctx,236236- const u8 *addr, bool is_ap, struct ieee80211_sta *sta)237237-{238238- struct il_station_entry *station;239239- int i;240240- u8 sta_id = IL_INVALID_STATION;241241- u16 rate;242242-243243- if (is_ap)244244- sta_id = ctx->ap_sta_id;245245- else if (is_broadcast_ether_addr(addr))246246- sta_id = ctx->bcast_sta_id;247247- else248248- for (i = IL_STA_ID; i < il->hw_params.max_stations; i++) {249249- if (!compare_ether_addr(il->stations[i].sta.sta.addr,250250- addr)) {251251- sta_id = i;252252- break;253253- }254254-255255- if (!il->stations[i].used &&256256- sta_id == IL_INVALID_STATION)257257- sta_id = i;258258- }259259-260260- /*261261- * These two conditions have the same outcome, but keep them262262- * separate263263- */264264- if (unlikely(sta_id == IL_INVALID_STATION))265265- return sta_id;266266-267267- /*268268- * uCode is not able to deal with multiple requests to add a269269- * station. Keep track if one is in progress so that we do not send270270- * another.271271- */272272- if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) {273273- D_INFO(274274- "STA %d already in process of being added.\n",275275- sta_id);276276- return sta_id;277277- }278278-279279- if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&280280- (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE) &&281281- !compare_ether_addr(il->stations[sta_id].sta.sta.addr, addr)) {282282- D_ASSOC(283283- "STA %d (%pM) already added, not adding again.\n",284284- sta_id, addr);285285- return sta_id;286286- }287287-288288- station = &il->stations[sta_id];289289- station->used = IL_STA_DRIVER_ACTIVE;290290- D_ASSOC("Add STA to driver ID %d: %pM\n",291291- sta_id, addr);292292- il->num_stations++;293293-294294- /* Set up the C_ADD_STA command to send to device */295295- memset(&station->sta, 0, sizeof(struct il_addsta_cmd));296296- memcpy(station->sta.sta.addr, addr, ETH_ALEN);297297- station->sta.mode = 0;298298- station->sta.sta.sta_id = sta_id;299299- station->sta.station_flags = ctx->station_flags;300300- station->ctxid = ctx->ctxid;301301-302302- if (sta) {303303- struct il_station_priv_common *sta_priv;304304-305305- sta_priv = (void *)sta->drv_priv;306306- sta_priv->ctx = ctx;307307- }308308-309309- /*310310- * OK to call unconditionally, since local stations (IBSS BSSID311311- * STA and broadcast STA) pass in a NULL sta, and mac80211312312- * doesn't allow HT IBSS.313313- */314314- il_set_ht_add_station(il, sta_id, sta, ctx);315315-316316- /* 3945 only */317317- rate = (il->band == IEEE80211_BAND_5GHZ) ?318318- RATE_6M_PLCP : RATE_1M_PLCP;319319- /* Turn on both antennas for the station... */320320- station->sta.rate_n_flags = cpu_to_le16(rate | RATE_MCS_ANT_AB_MSK);321321-322322- return sta_id;323323-324324-}325325-EXPORT_SYMBOL_GPL(il_prep_station);326326-327327-#define STA_WAIT_TIMEOUT (HZ/2)328328-329329-/**330330- * il_add_station_common -331331- */332332-int333333-il_add_station_common(struct il_priv *il,334334- struct il_rxon_context *ctx,335335- const u8 *addr, bool is_ap,336336- struct ieee80211_sta *sta, u8 *sta_id_r)337337-{338338- unsigned long flags_spin;339339- int ret = 0;340340- u8 sta_id;341341- struct il_addsta_cmd sta_cmd;342342-343343- *sta_id_r = 0;344344- spin_lock_irqsave(&il->sta_lock, flags_spin);345345- sta_id = il_prep_station(il, ctx, addr, is_ap, sta);346346- if (sta_id == IL_INVALID_STATION) {347347- IL_ERR("Unable to prepare station %pM for addition\n",348348- addr);349349- spin_unlock_irqrestore(&il->sta_lock, flags_spin);350350- return -EINVAL;351351- }352352-353353- /*354354- * uCode is not able to deal with multiple requests to add a355355- * station. Keep track if one is in progress so that we do not send356356- * another.357357- */358358- if (il->stations[sta_id].used & IL_STA_UCODE_INPROGRESS) {359359- D_INFO(360360- "STA %d already in process of being added.\n",361361- sta_id);362362- spin_unlock_irqrestore(&il->sta_lock, flags_spin);363363- return -EEXIST;364364- }365365-366366- if ((il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE) &&367367- (il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) {368368- D_ASSOC(369369- "STA %d (%pM) already added, not adding again.\n",370370- sta_id, addr);371371- spin_unlock_irqrestore(&il->sta_lock, flags_spin);372372- return -EEXIST;373373- }374374-375375- il->stations[sta_id].used |= IL_STA_UCODE_INPROGRESS;376376- memcpy(&sta_cmd, &il->stations[sta_id].sta,377377- sizeof(struct il_addsta_cmd));378378- spin_unlock_irqrestore(&il->sta_lock, flags_spin);379379-380380- /* Add station to device's station table */381381- ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC);382382- if (ret) {383383- spin_lock_irqsave(&il->sta_lock, flags_spin);384384- IL_ERR("Adding station %pM failed.\n",385385- il->stations[sta_id].sta.sta.addr);386386- il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE;387387- il->stations[sta_id].used &= ~IL_STA_UCODE_INPROGRESS;388388- spin_unlock_irqrestore(&il->sta_lock, flags_spin);389389- }390390- *sta_id_r = sta_id;391391- return ret;392392-}393393-EXPORT_SYMBOL(il_add_station_common);394394-395395-/**396396- * il_sta_ucode_deactivate - deactivate ucode status for a station397397- *398398- * il->sta_lock must be held399399- */400400-static void il_sta_ucode_deactivate(struct il_priv *il, u8 sta_id)401401-{402402- /* Ucode must be active and driver must be non active */403403- if ((il->stations[sta_id].used &404404- (IL_STA_UCODE_ACTIVE | IL_STA_DRIVER_ACTIVE)) !=405405- IL_STA_UCODE_ACTIVE)406406- IL_ERR("removed non active STA %u\n", sta_id);407407-408408- il->stations[sta_id].used &= ~IL_STA_UCODE_ACTIVE;409409-410410- memset(&il->stations[sta_id], 0, sizeof(struct il_station_entry));411411- D_ASSOC("Removed STA %u\n", sta_id);412412-}413413-414414-static int il_send_remove_station(struct il_priv *il,415415- const u8 *addr, int sta_id,416416- bool temporary)417417-{418418- struct il_rx_pkt *pkt;419419- int ret;420420-421421- unsigned long flags_spin;422422- struct il_rem_sta_cmd rm_sta_cmd;423423-424424- struct il_host_cmd cmd = {425425- .id = C_REM_STA,426426- .len = sizeof(struct il_rem_sta_cmd),427427- .flags = CMD_SYNC,428428- .data = &rm_sta_cmd,429429- };430430-431431- memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));432432- rm_sta_cmd.num_sta = 1;433433- memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);434434-435435- cmd.flags |= CMD_WANT_SKB;436436-437437- ret = il_send_cmd(il, &cmd);438438-439439- if (ret)440440- return ret;441441-442442- pkt = (struct il_rx_pkt *)cmd.reply_page;443443- if (pkt->hdr.flags & IL_CMD_FAILED_MSK) {444444- IL_ERR("Bad return from C_REM_STA (0x%08X)\n",445445- pkt->hdr.flags);446446- ret = -EIO;447447- }448448-449449- if (!ret) {450450- switch (pkt->u.rem_sta.status) {451451- case REM_STA_SUCCESS_MSK:452452- if (!temporary) {453453- spin_lock_irqsave(&il->sta_lock, flags_spin);454454- il_sta_ucode_deactivate(il, sta_id);455455- spin_unlock_irqrestore(&il->sta_lock,456456- flags_spin);457457- }458458- D_ASSOC("C_REM_STA PASSED\n");459459- break;460460- default:461461- ret = -EIO;462462- IL_ERR("C_REM_STA failed\n");463463- break;464464- }465465- }466466- il_free_pages(il, cmd.reply_page);467467-468468- return ret;469469-}470470-471471-/**472472- * il_remove_station - Remove driver's knowledge of station.473473- */474474-int il_remove_station(struct il_priv *il, const u8 sta_id,475475- const u8 *addr)476476-{477477- unsigned long flags;478478-479479- if (!il_is_ready(il)) {480480- D_INFO(481481- "Unable to remove station %pM, device not ready.\n",482482- addr);483483- /*484484- * It is typical for stations to be removed when we are485485- * going down. Return success since device will be down486486- * soon anyway487487- */488488- return 0;489489- }490490-491491- D_ASSOC("Removing STA from driver:%d %pM\n",492492- sta_id, addr);493493-494494- if (WARN_ON(sta_id == IL_INVALID_STATION))495495- return -EINVAL;496496-497497- spin_lock_irqsave(&il->sta_lock, flags);498498-499499- if (!(il->stations[sta_id].used & IL_STA_DRIVER_ACTIVE)) {500500- D_INFO("Removing %pM but non DRIVER active\n",501501- addr);502502- goto out_err;503503- }504504-505505- if (!(il->stations[sta_id].used & IL_STA_UCODE_ACTIVE)) {506506- D_INFO("Removing %pM but non UCODE active\n",507507- addr);508508- goto out_err;509509- }510510-511511- if (il->stations[sta_id].used & IL_STA_LOCAL) {512512- kfree(il->stations[sta_id].lq);513513- il->stations[sta_id].lq = NULL;514514- }515515-516516- il->stations[sta_id].used &= ~IL_STA_DRIVER_ACTIVE;517517-518518- il->num_stations--;519519-520520- BUG_ON(il->num_stations < 0);521521-522522- spin_unlock_irqrestore(&il->sta_lock, flags);523523-524524- return il_send_remove_station(il, addr, sta_id, false);525525-out_err:526526- spin_unlock_irqrestore(&il->sta_lock, flags);527527- return -EINVAL;528528-}529529-EXPORT_SYMBOL_GPL(il_remove_station);530530-531531-/**532532- * il_clear_ucode_stations - clear ucode station table bits533533- *534534- * This function clears all the bits in the driver indicating535535- * which stations are active in the ucode. Call when something536536- * other than explicit station management would cause this in537537- * the ucode, e.g. unassociated RXON.538538- */539539-void il_clear_ucode_stations(struct il_priv *il,540540- struct il_rxon_context *ctx)541541-{542542- int i;543543- unsigned long flags_spin;544544- bool cleared = false;545545-546546- D_INFO("Clearing ucode stations in driver\n");547547-548548- spin_lock_irqsave(&il->sta_lock, flags_spin);549549- for (i = 0; i < il->hw_params.max_stations; i++) {550550- if (ctx && ctx->ctxid != il->stations[i].ctxid)551551- continue;552552-553553- if (il->stations[i].used & IL_STA_UCODE_ACTIVE) {554554- D_INFO(555555- "Clearing ucode active for station %d\n", i);556556- il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;557557- cleared = true;558558- }559559- }560560- spin_unlock_irqrestore(&il->sta_lock, flags_spin);561561-562562- if (!cleared)563563- D_INFO(564564- "No active stations found to be cleared\n");565565-}566566-EXPORT_SYMBOL(il_clear_ucode_stations);567567-568568-/**569569- * il_restore_stations() - Restore driver known stations to device570570- *571571- * All stations considered active by driver, but not present in ucode, is572572- * restored.573573- *574574- * Function sleeps.575575- */576576-void577577-il_restore_stations(struct il_priv *il, struct il_rxon_context *ctx)578578-{579579- struct il_addsta_cmd sta_cmd;580580- struct il_link_quality_cmd lq;581581- unsigned long flags_spin;582582- int i;583583- bool found = false;584584- int ret;585585- bool send_lq;586586-587587- if (!il_is_ready(il)) {588588- D_INFO(589589- "Not ready yet, not restoring any stations.\n");590590- return;591591- }592592-593593- D_ASSOC("Restoring all known stations ... start.\n");594594- spin_lock_irqsave(&il->sta_lock, flags_spin);595595- for (i = 0; i < il->hw_params.max_stations; i++) {596596- if (ctx->ctxid != il->stations[i].ctxid)597597- continue;598598- if ((il->stations[i].used & IL_STA_DRIVER_ACTIVE) &&599599- !(il->stations[i].used & IL_STA_UCODE_ACTIVE)) {600600- D_ASSOC("Restoring sta %pM\n",601601- il->stations[i].sta.sta.addr);602602- il->stations[i].sta.mode = 0;603603- il->stations[i].used |= IL_STA_UCODE_INPROGRESS;604604- found = true;605605- }606606- }607607-608608- for (i = 0; i < il->hw_params.max_stations; i++) {609609- if ((il->stations[i].used & IL_STA_UCODE_INPROGRESS)) {610610- memcpy(&sta_cmd, &il->stations[i].sta,611611- sizeof(struct il_addsta_cmd));612612- send_lq = false;613613- if (il->stations[i].lq) {614614- memcpy(&lq, il->stations[i].lq,615615- sizeof(struct il_link_quality_cmd));616616- send_lq = true;617617- }618618- spin_unlock_irqrestore(&il->sta_lock, flags_spin);619619- ret = il_send_add_sta(il, &sta_cmd, CMD_SYNC);620620- if (ret) {621621- spin_lock_irqsave(&il->sta_lock, flags_spin);622622- IL_ERR("Adding station %pM failed.\n",623623- il->stations[i].sta.sta.addr);624624- il->stations[i].used &=625625- ~IL_STA_DRIVER_ACTIVE;626626- il->stations[i].used &=627627- ~IL_STA_UCODE_INPROGRESS;628628- spin_unlock_irqrestore(&il->sta_lock,629629- flags_spin);630630- }631631- /*632632- * Rate scaling has already been initialized, send633633- * current LQ command634634- */635635- if (send_lq)636636- il_send_lq_cmd(il, ctx, &lq,637637- CMD_SYNC, true);638638- spin_lock_irqsave(&il->sta_lock, flags_spin);639639- il->stations[i].used &= ~IL_STA_UCODE_INPROGRESS;640640- }641641- }642642-643643- spin_unlock_irqrestore(&il->sta_lock, flags_spin);644644- if (!found)645645- D_INFO("Restoring all known stations"646646- " .... no stations to be restored.\n");647647- else648648- D_INFO("Restoring all known stations"649649- " .... complete.\n");650650-}651651-EXPORT_SYMBOL(il_restore_stations);652652-653653-int il_get_free_ucode_key_idx(struct il_priv *il)654654-{655655- int i;656656-657657- for (i = 0; i < il->sta_key_max_num; i++)658658- if (!test_and_set_bit(i, &il->ucode_key_table))659659- return i;660660-661661- return WEP_INVALID_OFFSET;662662-}663663-EXPORT_SYMBOL(il_get_free_ucode_key_idx);664664-665665-void il_dealloc_bcast_stations(struct il_priv *il)666666-{667667- unsigned long flags;668668- int i;669669-670670- spin_lock_irqsave(&il->sta_lock, flags);671671- for (i = 0; i < il->hw_params.max_stations; i++) {672672- if (!(il->stations[i].used & IL_STA_BCAST))673673- continue;674674-675675- il->stations[i].used &= ~IL_STA_UCODE_ACTIVE;676676- il->num_stations--;677677- BUG_ON(il->num_stations < 0);678678- kfree(il->stations[i].lq);679679- il->stations[i].lq = NULL;680680- }681681- spin_unlock_irqrestore(&il->sta_lock, flags);682682-}683683-EXPORT_SYMBOL_GPL(il_dealloc_bcast_stations);684684-685685-#ifdef CONFIG_IWLEGACY_DEBUG686686-static void il_dump_lq_cmd(struct il_priv *il,687687- struct il_link_quality_cmd *lq)688688-{689689- int i;690690- D_RATE("lq station id 0x%x\n", lq->sta_id);691691- D_RATE("lq ant 0x%X 0x%X\n",692692- lq->general_params.single_stream_ant_msk,693693- lq->general_params.dual_stream_ant_msk);694694-695695- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++)696696- D_RATE("lq idx %d 0x%X\n",697697- i, lq->rs_table[i].rate_n_flags);698698-}699699-#else700700-static inline void il_dump_lq_cmd(struct il_priv *il,701701- struct il_link_quality_cmd *lq)702702-{703703-}704704-#endif705705-706706-/**707707- * il_is_lq_table_valid() - Test one aspect of LQ cmd for validity708708- *709709- * It sometimes happens when a HT rate has been in use and we710710- * loose connectivity with AP then mac80211 will first tell us that the711711- * current channel is not HT anymore before removing the station. In such a712712- * scenario the RXON flags will be updated to indicate we are not713713- * communicating HT anymore, but the LQ command may still contain HT rates.714714- * Test for this to prevent driver from sending LQ command between the time715715- * RXON flags are updated and when LQ command is updated.716716- */717717-static bool il_is_lq_table_valid(struct il_priv *il,718718- struct il_rxon_context *ctx,719719- struct il_link_quality_cmd *lq)720720-{721721- int i;722722-723723- if (ctx->ht.enabled)724724- return true;725725-726726- D_INFO("Channel %u is not an HT channel\n",727727- ctx->active.channel);728728- for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {729729- if (le32_to_cpu(lq->rs_table[i].rate_n_flags) &730730- RATE_MCS_HT_MSK) {731731- D_INFO(732732- "idx %d of LQ expects HT channel\n",733733- i);734734- return false;735735- }736736- }737737- return true;738738-}739739-740740-/**741741- * il_send_lq_cmd() - Send link quality command742742- * @init: This command is sent as part of station initialization right743743- * after station has been added.744744- *745745- * The link quality command is sent as the last step of station creation.746746- * This is the special case in which init is set and we call a callback in747747- * this case to clear the state indicating that station creation is in748748- * progress.749749- */750750-int il_send_lq_cmd(struct il_priv *il, struct il_rxon_context *ctx,751751- struct il_link_quality_cmd *lq, u8 flags, bool init)752752-{753753- int ret = 0;754754- unsigned long flags_spin;755755-756756- struct il_host_cmd cmd = {757757- .id = C_TX_LINK_QUALITY_CMD,758758- .len = sizeof(struct il_link_quality_cmd),759759- .flags = flags,760760- .data = lq,761761- };762762-763763- if (WARN_ON(lq->sta_id == IL_INVALID_STATION))764764- return -EINVAL;765765-766766-767767- spin_lock_irqsave(&il->sta_lock, flags_spin);768768- if (!(il->stations[lq->sta_id].used & IL_STA_DRIVER_ACTIVE)) {769769- spin_unlock_irqrestore(&il->sta_lock, flags_spin);770770- return -EINVAL;771771- }772772- spin_unlock_irqrestore(&il->sta_lock, flags_spin);773773-774774- il_dump_lq_cmd(il, lq);775775- BUG_ON(init && (cmd.flags & CMD_ASYNC));776776-777777- if (il_is_lq_table_valid(il, ctx, lq))778778- ret = il_send_cmd(il, &cmd);779779- else780780- ret = -EINVAL;781781-782782- if (cmd.flags & CMD_ASYNC)783783- return ret;784784-785785- if (init) {786786- D_INFO("init LQ command complete,"787787- " clearing sta addition status for sta %d\n",788788- lq->sta_id);789789- spin_lock_irqsave(&il->sta_lock, flags_spin);790790- il->stations[lq->sta_id].used &= ~IL_STA_UCODE_INPROGRESS;791791- spin_unlock_irqrestore(&il->sta_lock, flags_spin);792792- }793793- return ret;794794-}795795-EXPORT_SYMBOL(il_send_lq_cmd);796796-797797-int il_mac_sta_remove(struct ieee80211_hw *hw,798798- struct ieee80211_vif *vif,799799- struct ieee80211_sta *sta)800800-{801801- struct il_priv *il = hw->priv;802802- struct il_station_priv_common *sta_common = (void *)sta->drv_priv;803803- int ret;804804-805805- D_INFO("received request to remove station %pM\n",806806- sta->addr);807807- mutex_lock(&il->mutex);808808- D_INFO("proceeding to remove station %pM\n",809809- sta->addr);810810- ret = il_remove_station(il, sta_common->sta_id, sta->addr);811811- if (ret)812812- IL_ERR("Error removing station %pM\n",813813- sta->addr);814814- mutex_unlock(&il->mutex);815815- return ret;816816-}817817-EXPORT_SYMBOL(il_mac_sta_remove);
+4-6
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
···8888 return -EINVAL;89899090 /* Allocate the circular buffer of Read Buffer Descriptors (RBDs) */9191- rxq->bd = dma_alloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,9292- &rxq->bd_dma, GFP_KERNEL);9191+ rxq->bd = dma_zalloc_coherent(dev, sizeof(__le32) * RX_QUEUE_SIZE,9292+ &rxq->bd_dma, GFP_KERNEL);9393 if (!rxq->bd)9494 goto err_bd;9595- memset(rxq->bd, 0, sizeof(__le32) * RX_QUEUE_SIZE);96959796 /*Allocate the driver's pointer to receive buffer status */9898- rxq->rb_stts = dma_alloc_coherent(dev, sizeof(*rxq->rb_stts),9999- &rxq->rb_stts_dma, GFP_KERNEL);9797+ rxq->rb_stts = dma_zalloc_coherent(dev, sizeof(*rxq->rb_stts),9898+ &rxq->rb_stts_dma, GFP_KERNEL);10099 if (!rxq->rb_stts)101100 goto err_rb_stts;102102- memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));103101104102 return 0;105103
+130-8
drivers/net/wireless/mwl8k.c
···28282929#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"3030#define MWL8K_NAME KBUILD_MODNAME3131-#define MWL8K_VERSION "0.12"3131+#define MWL8K_VERSION "0.13"32323333/* Module parameters */3434static bool ap_mode_default;···198198 /* firmware access */199199 struct mutex fw_mutex;200200 struct task_struct *fw_mutex_owner;201201+ struct task_struct *hw_restart_owner;201202 int fw_mutex_depth;202203 struct completion *hostcmd_wait;203204···262261 * the firmware image is swapped.263262 */264263 struct ieee80211_tx_queue_params wmm_params[MWL8K_TX_WMM_QUEUES];264264+265265+ /* To perform the task of reloading the firmware */266266+ struct work_struct fw_reload;267267+ bool hw_restart_in_progress;265268266269 /* async firmware loading state */267270 unsigned fw_state;···1503149815041499 might_sleep();1505150015011501+ /* Since fw restart is in progress, allow only the firmware15021502+ * commands from the restart code and block the other15031503+ * commands since they are going to fail in any case since15041504+ * the firmware has crashed15051505+ */15061506+ if (priv->hw_restart_in_progress) {15071507+ if (priv->hw_restart_owner == current)15081508+ return 0;15091509+ else15101510+ return -EBUSY;15111511+ }15121512+15061513 /*15071514 * The TX queues are stopped at this point, so this test15081515 * doesn't need to take ->tx_lock.···15581541 wiphy_err(hw->wiphy, "tx rings stuck for %d ms\n",15591542 MWL8K_TX_WAIT_TIMEOUT_MS);15601543 mwl8k_dump_tx_rings(hw);15441544+ priv->hw_restart_in_progress = true;15451545+ ieee80211_queue_work(hw, &priv->fw_reload);1561154615621547 rc = -ETIMEDOUT;15631548 }···2077205820782059 rc = mwl8k_tx_wait_empty(hw);20792060 if (rc) {20802080- ieee80211_wake_queues(hw);20612061+ if (!priv->hw_restart_in_progress)20622062+ ieee80211_wake_queues(hw);20632063+20812064 mutex_unlock(&priv->fw_mutex);2082206520832066 return rc;···20982077 struct mwl8k_priv *priv = hw->priv;2099207821002079 if (!--priv->fw_mutex_depth) {21012101- ieee80211_wake_queues(hw);20802080+ if (!priv->hw_restart_in_progress)20812081+ ieee80211_wake_queues(hw);20822082+21022083 priv->fw_mutex_owner = NULL;21032084 mutex_unlock(&priv->fw_mutex);21042085 }···44214398 struct mwl8k_priv *priv = hw->priv;44224399 int i;4423440044244424- mwl8k_cmd_radio_disable(hw);44014401+ if (!priv->hw_restart_in_progress)44024402+ mwl8k_cmd_radio_disable(hw);4425440344264404 ieee80211_stop_queues(hw);44274405···45234499 return 0;45244500}4525450145024502+static void mwl8k_remove_vif(struct mwl8k_priv *priv, struct mwl8k_vif *vif)45034503+{45044504+ /* Has ieee80211_restart_hw re-added the removed interfaces? */45054505+ if (!priv->macids_used)45064506+ return;45074507+45084508+ priv->macids_used &= ~(1 << vif->macid);45094509+ list_del(&vif->list);45104510+}45114511+45264512static void mwl8k_remove_interface(struct ieee80211_hw *hw,45274513 struct ieee80211_vif *vif)45284514{···4544451045454511 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");4546451245474547- priv->macids_used &= ~(1 << mwl8k_vif->macid);45484548- list_del(&mwl8k_vif->list);45134513+ mwl8k_remove_vif(priv, mwl8k_vif);45144514+}45154515+45164516+static void mwl8k_hw_restart_work(struct work_struct *work)45174517+{45184518+ struct mwl8k_priv *priv =45194519+ container_of(work, struct mwl8k_priv, fw_reload);45204520+ struct ieee80211_hw *hw = priv->hw;45214521+ struct mwl8k_device_info *di;45224522+ int rc;45234523+45244524+ /* If some command is waiting for a response, clear it */45254525+ if (priv->hostcmd_wait != NULL) {45264526+ complete(priv->hostcmd_wait);45274527+ priv->hostcmd_wait = NULL;45284528+ }45294529+45304530+ priv->hw_restart_owner = current;45314531+ di = priv->device_info;45324532+ mwl8k_fw_lock(hw);45334533+45344534+ if (priv->ap_fw)45354535+ rc = mwl8k_reload_firmware(hw, di->fw_image_ap);45364536+ else45374537+ rc = mwl8k_reload_firmware(hw, di->fw_image_sta);45384538+45394539+ if (rc)45404540+ goto fail;45414541+45424542+ priv->hw_restart_owner = NULL;45434543+ priv->hw_restart_in_progress = false;45444544+45454545+ /*45464546+ * This unlock will wake up the queues and45474547+ * also opens the command path for other45484548+ * commands45494549+ */45504550+ mwl8k_fw_unlock(hw);45514551+45524552+ ieee80211_restart_hw(hw);45534553+45544554+ wiphy_err(hw->wiphy, "Firmware restarted successfully\n");45554555+45564556+ return;45574557+fail:45584558+ mwl8k_fw_unlock(hw);45594559+45604560+ wiphy_err(hw->wiphy, "Firmware restart failed\n");45494561}4550456245514563static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)···51045024 for (i = 0; i < MAX_AMPDU_ATTEMPTS; i++) {51055025 rc = mwl8k_check_ba(hw, stream);5106502651075107- if (!rc)50275027+ /* If HW restart is in progress mwl8k_post_cmd will50285028+ * return -EBUSY. Avoid retrying mwl8k_check_ba in50295029+ * such cases50305030+ */50315031+ if (!rc || rc == -EBUSY)51085032 break;51095033 /*51105034 * HW queues take time to be flushed, give them···53475263 mwl8k_release_firmware(priv);53485264}5349526552665266+#define MAX_RESTART_ATTEMPTS 153505267static int mwl8k_init_firmware(struct ieee80211_hw *hw, char *fw_image,53515268 bool nowait)53525269{53535270 struct mwl8k_priv *priv = hw->priv;53545271 int rc;52725272+ int count = MAX_RESTART_ATTEMPTS;5355527352745274+retry:53565275 /* Reset firmware and hardware */53575276 mwl8k_hw_reset(priv);53585277···5376528953775290 /* Reclaim memory once firmware is successfully loaded */53785291 mwl8k_release_firmware(priv);52925292+52935293+ if (rc && count) {52945294+ /* FW did not start successfully;52955295+ * lets try one more time52965296+ */52975297+ count--;52985298+ wiphy_err(hw->wiphy, "Trying to reload the firmware again\n");52995299+ msleep(20);53005300+ goto retry;53015301+ }5379530253805303 return rc;53815304}···54625365 goto err_free_queues;54635366 }5464536754655465- memset(priv->ampdu, 0, sizeof(priv->ampdu));53685368+ /*53695369+ * When hw restart is requested,53705370+ * mac80211 will take care of clearing53715371+ * the ampdu streams, so do not clear53725372+ * the ampdu state here53735373+ */53745374+ if (!priv->hw_restart_in_progress)53755375+ memset(priv->ampdu, 0, sizeof(priv->ampdu));5466537654675377 /*54685378 * Temporarily enable interrupts. Initial firmware host···55435439{55445440 int i, rc = 0;55455441 struct mwl8k_priv *priv = hw->priv;54425442+ struct mwl8k_vif *vif, *tmp_vif;5546544355475444 mwl8k_stop(hw);55485445 mwl8k_rxq_deinit(hw, 0);54465446+54475447+ /*54485448+ * All the existing interfaces are re-added by the ieee80211_reconfig;54495449+ * which means driver should remove existing interfaces before calling54505450+ * ieee80211_restart_hw54515451+ */54525452+ if (priv->hw_restart_in_progress)54535453+ list_for_each_entry_safe(vif, tmp_vif, &priv->vif_list, list)54545454+ mwl8k_remove_vif(priv, vif);5549545555505456 for (i = 0; i < mwl8k_tx_queues(priv); i++)55515457 mwl8k_txq_deinit(hw, i);···55675453 rc = mwl8k_probe_hw(hw);55685454 if (rc)55695455 goto fail;54565456+54575457+ if (priv->hw_restart_in_progress)54585458+ return rc;5570545955715460 rc = mwl8k_start(hw);55725461 if (rc)···56415524 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);56425525 /* Handle watchdog ba events */56435526 INIT_WORK(&priv->watchdog_ba_handle, mwl8k_watchdog_ba_events);55275527+ /* To reload the firmware if it crashes */55285528+ INIT_WORK(&priv->fw_reload, mwl8k_hw_restart_work);5644552956455530 /* TX reclaim and RX tasklets. */56465531 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);···57865667 rc = mwl8k_init_firmware(hw, priv->fw_pref, true);57875668 if (rc)57885669 goto err_stop_firmware;56705670+56715671+ priv->hw_restart_in_progress = false;56725672+57895673 return rc;5790567457915675err_stop_firmware:
···298298 return false;299299300300 /*301301- * USB devices cannot blindly pass the skb->len as the302302- * length of the data to usb_fill_bulk_urb. Pass the skb303303- * to the driver to determine what the length should be.301301+ * USB devices require certain padding at the end of each frame302302+ * and urb. Those paddings are not included in skbs. Pass entry303303+ * to the driver to determine what the overall length should be.304304 */305305 length = rt2x00dev->ops->lib->get_tx_data_len(entry);306306+307307+ status = skb_padto(entry->skb, length);308308+ if (unlikely(status)) {309309+ /* TODO: report something more appropriate than IO_FAILED. */310310+ WARNING(rt2x00dev, "TX SKB padding error, out of memory\n");311311+ set_bit(ENTRY_DATA_IO_FAILED, &entry->flags);312312+ rt2x00lib_dmadone(entry);313313+314314+ return false;315315+ }306316307317 usb_fill_bulk_urb(entry_priv->urb, usb_dev,308318 usb_sndbulkpipe(usb_dev, entry->queue->usb_endpoint),
+2
include/linux/nfc.h
···8888 * @NFC_ATTR_TARGET_SENS_RES: NFC-A targets extra information such as NFCID8989 * @NFC_ATTR_TARGET_SEL_RES: NFC-A targets extra information (useful if the9090 * target is not NFC-Forum compliant)9191+ * @NFC_ATTR_TARGET_NFCID1: NFC-A targets identifier, max 10 bytes9192 * @NFC_ATTR_COMM_MODE: Passive or active mode9293 * @NFC_ATTR_RF_MODE: Initiator or target9394 */···10099 NFC_ATTR_TARGET_INDEX,101100 NFC_ATTR_TARGET_SENS_RES,102101 NFC_ATTR_TARGET_SEL_RES,102102+ NFC_ATTR_TARGET_NFCID1,103103 NFC_ATTR_COMM_MODE,104104 NFC_ATTR_RF_MODE,105105/* private: internal use only */
···138138 mutex_unlock(&local->iflist_mtx);139139}140140141141-void ieee80211_offchannel_enable_all_ps(struct ieee80211_local *local,142142- bool tell_ap)143143-{144144- struct ieee80211_sub_if_data *sdata;145145-146146- mutex_lock(&local->iflist_mtx);147147- list_for_each_entry(sdata, &local->interfaces, list) {148148- if (!ieee80211_sdata_running(sdata))149149- continue;150150-151151- if (sdata->vif.type == NL80211_IFTYPE_STATION &&152152- sdata->u.mgd.associated)153153- ieee80211_offchannel_ps_enable(sdata, tell_ap);154154- }155155- mutex_unlock(&local->iflist_mtx);156156-}157157-158141void ieee80211_offchannel_return(struct ieee80211_local *local,159142 bool offchannel_ps_disable)160143{···145162146163 mutex_lock(&local->iflist_mtx);147164 list_for_each_entry(sdata, &local->interfaces, list) {165165+ if (sdata->vif.type != NL80211_IFTYPE_MONITOR)166166+ clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);167167+148168 if (!ieee80211_sdata_running(sdata))149169 continue;150170···159173 }160174161175 if (sdata->vif.type != NL80211_IFTYPE_MONITOR) {162162- clear_bit(SDATA_STATE_OFFCHANNEL, &sdata->state);163176 /*164177 * This may wake up queues even though the driver165178 * currently has them stopped. This is not very
-20
net/mac80211/rx.c
···15761576 return RX_CONTINUE;15771577}1578157815791579-static ieee80211_rx_result debug_noinline15801580-ieee80211_rx_h_remove_qos_control(struct ieee80211_rx_data *rx)15811581-{15821582- u8 *data = rx->skb->data;15831583- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)data;15841584-15851585- if (!ieee80211_is_data_qos(hdr->frame_control))15861586- return RX_CONTINUE;15871587-15881588- /* remove the qos control field, update frame type and meta-data */15891589- memmove(data + IEEE80211_QOS_CTL_LEN, data,15901590- ieee80211_hdrlen(hdr->frame_control) - IEEE80211_QOS_CTL_LEN);15911591- hdr = (struct ieee80211_hdr *)skb_pull(rx->skb, IEEE80211_QOS_CTL_LEN);15921592- /* change frame type to non QOS */15931593- hdr->frame_control &= ~cpu_to_le16(IEEE80211_STYPE_QOS_DATA);15941594-15951595- return RX_CONTINUE;15961596-}15971597-15981579static int15991580ieee80211_802_1x_port_control(struct ieee80211_rx_data *rx)16001581{···26992718 if (ieee80211_vif_is_mesh(&rx->sdata->vif))27002719 CALL_RXH(ieee80211_rx_h_mesh_fwding);27012720#endif27022702- CALL_RXH(ieee80211_rx_h_remove_qos_control)27032721 CALL_RXH(ieee80211_rx_h_amsdu)27042722 CALL_RXH(ieee80211_rx_h_data)27052723 CALL_RXH(ieee80211_rx_h_ctrl);
+1-1
net/mac80211/scan.c
···625625 local->leave_oper_channel_time = jiffies;626626627627 /* advance to the next channel to be scanned */628628- local->next_scan_state = SCAN_DECISION;628628+ local->next_scan_state = SCAN_SET_CHANNEL;629629}630630631631void ieee80211_scan_work(struct work_struct *work)
···7777 case NCI_STATUS_NFCEE_TIMEOUT_ERROR:7878 return -ETIMEDOUT;79798080- case NCI_STATUS_MAX_ACTIVE_NFCEE_INTERFACES_REACHED:8181- return -EDQUOT;8282-8380 case NCI_STATUS_FAILED:8481 default:8582 return -ENOSYS;
+42-8
net/nfc/nci/ntf.c
···52525353 /* update the credits */5454 for (i = 0; i < ntf->num_entries; i++) {5555+ ntf->conn_entries[i].conn_id =5656+ nci_conn_id(&ntf->conn_entries[i].conn_id);5757+5558 pr_debug("entry[%d]: conn_id %d, credits %d\n",5659 i, ntf->conn_entries[i].conn_id,5760 ntf->conn_entries[i].credits);···6966 /* trigger the next tx */7067 if (!skb_queue_empty(&ndev->tx_q))7168 queue_work(ndev->tx_wq, &ndev->tx_work);6969+}7070+7171+static void nci_core_conn_intf_error_ntf_packet(struct nci_dev *ndev,7272+ struct sk_buff *skb)7373+{7474+ struct nci_core_intf_error_ntf *ntf = (void *) skb->data;7575+7676+ ntf->conn_id = nci_conn_id(&ntf->conn_id);7777+7878+ pr_debug("status 0x%x, conn_id %d\n", ntf->status, ntf->conn_id);7979+8080+ /* complete the data exchange transaction, if exists */8181+ if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))8282+ nci_data_exchange_complete(ndev, NULL, -EIO);7283}73847485static __u8 *nci_extract_rf_params_nfca_passive_poll(struct nci_dev *ndev,···154137155138 nfc_tgt.sens_res = ntf->rf_tech_specific_params.nfca_poll.sens_res;156139 nfc_tgt.sel_res = ntf->rf_tech_specific_params.nfca_poll.sel_res;140140+ nfc_tgt.nfcid1_len = ntf->rf_tech_specific_params.nfca_poll.nfcid1_len;141141+ if (nfc_tgt.nfcid1_len > 0) {142142+ memcpy(nfc_tgt.nfcid1,143143+ ntf->rf_tech_specific_params.nfca_poll.nfcid1,144144+ nfc_tgt.nfcid1_len);145145+ }157146158147 if (!(nfc_tgt.supported_protocols & ndev->poll_prots)) {159148 pr_debug("the target found does not have the desired protocol\n");···170147 nfc_tgt.supported_protocols);171148172149 ndev->target_available_prots = nfc_tgt.supported_protocols;150150+ ndev->max_data_pkt_payload_size = ntf->max_data_pkt_payload_size;151151+ ndev->initial_num_credits = ntf->initial_num_credits;152152+153153+ /* set the available credits to initial value */154154+ atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);173155174156 nfc_targets_found(ndev->nfc_dev, &nfc_tgt, 1);175157}···190162 set_bit(NCI_POLL_ACTIVE, &ndev->flags);191163192164 ntf.rf_discovery_id = *data++;193193- ntf.rf_interface_type = *data++;165165+ ntf.rf_interface = *data++;194166 ntf.rf_protocol = *data++;195167 ntf.activation_rf_tech_and_mode = *data++;168168+ ntf.max_data_pkt_payload_size = *data++;169169+ ntf.initial_num_credits = *data++;196170 ntf.rf_tech_specific_params_len = *data++;197171198172 pr_debug("rf_discovery_id %d\n", ntf.rf_discovery_id);199199- pr_debug("rf_interface_type 0x%x\n", ntf.rf_interface_type);173173+ pr_debug("rf_interface 0x%x\n", ntf.rf_interface);200174 pr_debug("rf_protocol 0x%x\n", ntf.rf_protocol);201175 pr_debug("activation_rf_tech_and_mode 0x%x\n",202176 ntf.activation_rf_tech_and_mode);177177+ pr_debug("max_data_pkt_payload_size 0x%x\n",178178+ ntf.max_data_pkt_payload_size);179179+ pr_debug("initial_num_credits 0x%x\n", ntf.initial_num_credits);203180 pr_debug("rf_tech_specific_params_len %d\n",204181 ntf.rf_tech_specific_params_len);205182···237204 ntf.activation_params_len);238205239206 if (ntf.activation_params_len > 0) {240240- switch (ntf.rf_interface_type) {207207+ switch (ntf.rf_interface) {241208 case NCI_RF_INTERFACE_ISO_DEP:242209 err = nci_extract_activation_params_iso_dep(ndev,243210 &ntf, data);···248215 break;249216250217 default:251251- pr_err("unsupported rf_interface_type 0x%x\n",252252- ntf.rf_interface_type);218218+ pr_err("unsupported rf_interface 0x%x\n",219219+ ntf.rf_interface);253220 return;254221 }255222 }···277244 ndev->rx_data_reassembly = 0;278245 }279246280280- /* set the available credits to initial value */281281- atomic_set(&ndev->credits_cnt, ndev->initial_num_credits);282282-283247 /* complete the data exchange transaction, if exists */284248 if (test_bit(NCI_DATA_EXCHANGE, &ndev->flags))285249 nci_data_exchange_complete(ndev, NULL, -EIO);···298268 switch (ntf_opcode) {299269 case NCI_OP_CORE_CONN_CREDITS_NTF:300270 nci_core_conn_credits_ntf_packet(ndev, skb);271271+ break;272272+273273+ case NCI_OP_CORE_INTF_ERROR_NTF:274274+ nci_core_conn_intf_error_ntf_packet(ndev, skb);301275 break;302276303277 case NCI_OP_RF_INTF_ACTIVATED_NTF:
···105105 ret = pdata->gpio_runtime_setup(pdev);106106 if (ret) {107107 pr_warn("%s: can't set up gpio\n", __func__);108108- return ret;108108+ goto fail_alloc;109109 }110110 }111111
+10-3
net/wireless/genregdb.awk
···77#88# Copyright 2009 John W. Linville <linville@tuxdriver.com>99#1010-# This program is free software; you can redistribute it and/or modify1111-# it under the terms of the GNU General Public License version 2 as1212-# published by the Free Software Foundation.1010+# Permission to use, copy, modify, and/or distribute this software for any1111+# purpose with or without fee is hereby granted, provided that the above1212+# copyright notice and this permission notice appear in all copies.1313#1414+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES1515+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1616+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1717+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1818+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1919+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF2020+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.14211522BEGIN {1623 active = 0
+26-14
net/wireless/reg.c
···22 * Copyright 2002-2005, Instant802 Networks, Inc.33 * Copyright 2005-2006, Devicescape Software, Inc.44 * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>55- * Copyright 2008 Luis R. Rodriguez <lrodriguz@atheros.com>55+ * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>66 *77- * This program is free software; you can redistribute it and/or modify88- * it under the terms of the GNU General Public License version 2 as99- * published by the Free Software Foundation.77+ * Permission to use, copy, modify, and/or distribute this software for any88+ * purpose with or without fee is hereby granted, provided that the above99+ * copyright notice and this permission notice appear in all copies.1010+ *1111+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES1212+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1313+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1414+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1515+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1616+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1717+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1018 */1919+11201221/**1322 * DOC: Wireless regulatory infrastructure···14891480}1490148114911482/* This processes *all* regulatory hints */14921492-static void reg_process_hint(struct regulatory_request *reg_request)14831483+static void reg_process_hint(struct regulatory_request *reg_request,14841484+ enum nl80211_reg_initiator reg_initiator)14931485{14941486 int r = 0;14951487 struct wiphy *wiphy = NULL;14961496- enum nl80211_reg_initiator initiator = reg_request->initiator;1497148814981489 BUG_ON(!reg_request->alpha2);1499149015001491 if (wiphy_idx_valid(reg_request->wiphy_idx))15011492 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);1502149315031503- if (reg_request->initiator == NL80211_REGDOM_SET_BY_DRIVER &&14941494+ if (reg_initiator == NL80211_REGDOM_SET_BY_DRIVER &&15041495 !wiphy) {15051496 kfree(reg_request);15061497 return;···15101501 /* This is required so that the orig_* parameters are saved */15111502 if (r == -EALREADY && wiphy &&15121503 wiphy->flags & WIPHY_FLAG_STRICT_REGULATORY) {15131513- wiphy_update_regulatory(wiphy, initiator);15041504+ wiphy_update_regulatory(wiphy, reg_initiator);15141505 return;15151506 }15161507···15191510 * source of bogus requests.15201511 */15211512 if (r != -EALREADY &&15221522- reg_request->initiator == NL80211_REGDOM_SET_BY_USER)15131513+ reg_initiator == NL80211_REGDOM_SET_BY_USER)15231514 schedule_delayed_work(®_timeout, msecs_to_jiffies(3142));15241515}15251516···1556154715571548 spin_unlock(®_requests_lock);1558154915591559- reg_process_hint(reg_request);15501550+ reg_process_hint(reg_request, reg_request->initiator);1560155115611552out:15621553 mutex_unlock(®_mutex);···18391830static void restore_regulatory_settings(bool reset_user)18401831{18411832 char alpha2[2];18331833+ char world_alpha2[2];18421834 struct reg_beacon *reg_beacon, *btmp;18431835 struct regulatory_request *reg_request, *tmp;18441836 LIST_HEAD(tmp_reg_req_list);···1891188118921882 /* First restore to the basic regulatory settings */18931883 cfg80211_regdomain = cfg80211_world_regdom;18841884+ world_alpha2[0] = cfg80211_regdomain->alpha2[0];18851885+ world_alpha2[1] = cfg80211_regdomain->alpha2[1];1894188618951887 list_for_each_entry(rdev, &cfg80211_rdev_list, list) {18961888 if (rdev->wiphy.flags & WIPHY_FLAG_CUSTOM_REGULATORY)···19021890 mutex_unlock(®_mutex);19031891 mutex_unlock(&cfg80211_mutex);1904189219051905- regulatory_hint_core(cfg80211_regdomain->alpha2);18931893+ regulatory_hint_core(world_alpha2);1906189419071895 /*19081896 * This restores the ieee80211_regdom module parameter···19991987 const struct ieee80211_freq_range *freq_range = NULL;20001988 const struct ieee80211_power_rule *power_rule = NULL;2001198920022002- pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n");19901990+ pr_info(" (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp)\n");2003199120041992 for (i = 0; i < rd->n_reg_rules; i++) {20051993 reg_rule = &rd->reg_rules[i];···20111999 * in certain regions20122000 */20132001 if (power_rule->max_antenna_gain)20142014- pr_info(" (%d KHz - %d KHz @ %d KHz), (%d mBi, %d mBm)\n",20022002+ pr_info(" (%d KHz - %d KHz @ %d KHz), (%d mBi, %d mBm)\n",20152003 freq_range->start_freq_khz,20162004 freq_range->end_freq_khz,20172005 freq_range->max_bandwidth_khz,20182006 power_rule->max_antenna_gain,20192007 power_rule->max_eirp);20202008 else20212021- pr_info(" (%d KHz - %d KHz @ %d KHz), (N/A, %d mBm)\n",20092009+ pr_info(" (%d KHz - %d KHz @ %d KHz), (N/A, %d mBm)\n",20222010 freq_range->start_freq_khz,20232011 freq_range->end_freq_khz,20242012 freq_range->max_bandwidth_khz,
+15
net/wireless/reg.h
···11#ifndef __NET_WIRELESS_REG_H22#define __NET_WIRELESS_REG_H33+/*44+ * Copyright 2008-2011 Luis R. Rodriguez <mcgrof@qca.qualcomm.com>55+ *66+ * Permission to use, copy, modify, and/or distribute this software for any77+ * purpose with or without fee is hereby granted, provided that the above88+ * copyright notice and this permission notice appear in all copies.99+ *1010+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES1111+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1212+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1313+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1414+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1515+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1616+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1717+ */318419extern const struct ieee80211_regdomain *cfg80211_regdomain;520
+16
net/wireless/regdb.h
···11#ifndef __REGDB_H__22#define __REGDB_H__3344+/*55+ * Copyright 2009 John W. Linville <linville@tuxdriver.com>66+ *77+ * Permission to use, copy, modify, and/or distribute this software for any88+ * purpose with or without fee is hereby granted, provided that the above99+ * copyright notice and this permission notice appear in all copies.1010+ *1111+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES1212+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1313+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR1414+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1515+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN1616+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF1717+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1818+ */1919+420extern const struct ieee80211_regdomain *reg_regdb[];521extern int reg_regdb_size;622