···390390rfkill input line is active. Only if none of the rfkill input lines are391391active, will it return RFKILL_STATE_UNBLOCKED.392392393393-If it doesn't implement the get_state() hook, it must make sure that its calls394394-to rfkill_force_state() are enough to keep the status always up-to-date, and it395395-must do a rfkill_force_state() on resume from sleep.393393+Since the device has a hardware rfkill line, it IS subject to state changes394394+external to rfkill. Therefore, the driver must make sure that it calls395395+rfkill_force_state() to keep the status always up-to-date, and it must do a396396+rfkill_force_state() on resume from sleep.396397397398Every time the driver gets a notification from the card that one of its rfkill398399lines changed state (polling might be needed on badly designed cards that don't···423422about its current state).424423425424The rfkill class will call the get_state hook of a device every time it needs426426-to know the *real* current state of the hardware. This can happen often.425425+to know the *real* current state of the hardware. This can happen often, but426426+it does not do any polling, so it is not enough on hardware that is subject427427+to state changes outside of the rfkill subsystem.428428+429429+Therefore, calling rfkill_force_state() when a state change happens is430430+mandatory when the device has a hardware rfkill line, or when something else431431+like the firmware could cause its state to be changed without going through the432432+rfkill class.427433428434Some hardware provides events when its status changes. In these cases, it is429435best for the driver to not provide a get_state hook, and instead register the430436rfkill class *already* with the correct status, and keep it updated using431437rfkill_force_state() when it gets an event from the hardware.438438+439439+rfkill_force_state() must be used on the device resume handlers to update the440440+rfkill status, should there be any chance of the device status changing during441441+the sleep.432442433443There is no provision for a statically-allocated rfkill struct. You must434444use rfkill_allocate() to allocate one.
+6-6
drivers/net/ps3_gelic_wireless.c
···10241024 struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));10251025 struct iw_point *enc = &data->encoding;10261026 __u16 flags;10271027- unsigned int irqflag;10271027+ unsigned long irqflag;10281028 int key_index, index_specified;10291029 int ret = 0;10301030···10971097{10981098 struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));10991099 struct iw_point *enc = &data->encoding;11001100- unsigned int irqflag;11001100+ unsigned long irqflag;11011101 unsigned int key_index, index_specified;11021102 int ret = 0;11031103···12151215 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;12161216 __u16 alg;12171217 __u16 flags;12181218- unsigned int irqflag;12181218+ unsigned long irqflag;12191219 int key_index;12201220 int ret = 0;12211221···13031303 struct gelic_wl_info *wl = port_wl(netdev_priv(netdev));13041304 struct iw_point *enc = &data->encoding;13051305 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;13061306- unsigned int irqflag;13061306+ unsigned long irqflag;13071307 int key_index;13081308 int ret = 0;13091309 int max_key_len;···14261426{14271427 struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));14281428 unsigned int len;14291429- unsigned int irqflag;14291429+ unsigned long irqflag;14301430 int ret = 0;1431143114321432 pr_debug("%s:<- len=%d\n", __func__, data->data.length);···14671467{14681468 struct gelic_wl_info *wl = port_wl(netdev_priv(net_dev));14691469 char *p;14701470- unsigned int irqflag;14701470+ unsigned long irqflag;14711471 unsigned int i;1472147214731473 pr_debug("%s:<-\n", __func__);
+63-36
drivers/net/wireless/ath5k/base.c
···4343#include <linux/version.h>4444#include <linux/module.h>4545#include <linux/delay.h>4646+#include <linux/hardirq.h>4647#include <linux/if.h>4848+#include <linux/io.h>4749#include <linux/netdevice.h>4850#include <linux/cache.h>4951#include <linux/pci.h>···473471 /* Set private data */474472 pci_set_drvdata(pdev, hw);475473476476- /* Enable msi for devices that support it */477477- pci_enable_msi(pdev);478478-479474 /* Setup interrupt handler */480475 ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);481476 if (ret) {···550551err_irq:551552 free_irq(pdev->irq, sc);552553err_free:553553- pci_disable_msi(pdev);554554 ieee80211_free_hw(hw);555555err_map:556556 pci_iounmap(pdev, mem);···571573 ath5k_detach(pdev, hw);572574 ath5k_hw_detach(sc->ah);573575 free_irq(pdev->irq, sc);574574- pci_disable_msi(pdev);575576 pci_iounmap(pdev, sc->iobase);576577 pci_release_region(pdev, 0);577578 pci_disable_device(pdev);···587590 ath5k_led_off(sc);588591589592 ath5k_stop_hw(sc);593593+594594+ free_irq(pdev->irq, sc);595595+ pci_disable_msi(pdev);590596 pci_save_state(pdev);591597 pci_disable_device(pdev);592598 pci_set_power_state(pdev, PCI_D3hot);···605605 struct ath5k_hw *ah = sc->ah;606606 int i, err;607607608608- err = pci_set_power_state(pdev, PCI_D0);609609- if (err)610610- return err;608608+ pci_restore_state(pdev);611609612610 err = pci_enable_device(pdev);613611 if (err)614612 return err;615613616616- pci_restore_state(pdev);617614 /*618615 * Suspend/Resume resets the PCI configuration space, so we have to619616 * re-disable the RETRY_TIMEOUT register (0x41) to keep···618621 */619622 pci_write_config_byte(pdev, 0x41, 0);620623621621- ath5k_init(sc);624624+ pci_enable_msi(pdev);625625+626626+ err = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);627627+ if (err) {628628+ ATH5K_ERR(sc, "request_irq failed\n");629629+ goto err_msi;630630+ }631631+632632+ err = ath5k_init(sc);633633+ if (err)634634+ goto err_irq;622635 ath5k_led_enable(sc);623636624637 /*···642635 ath5k_hw_reset_key(ah, i);643636644637 return 0;638638+err_irq:639639+ free_irq(pdev->irq, sc);640640+err_msi:641641+ pci_disable_msi(pdev);642642+ pci_disable_device(pdev);643643+ return err;645644}646645#endif /* CONFIG_PM */647646···1237122412381225 pktlen = skb->len;1239122612401240- if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)) {12271227+ if (info->control.hw_key) {12411228 keyidx = info->control.hw_key->hw_key_idx;12421229 pktlen += info->control.icv_len;12431230 }···1262124912631250 txq->link = &ds->ds_link;12641251 ath5k_hw_tx_start(ah, txq->qnum);12521252+ mmiowb();12651253 spin_unlock_bh(&txq->lock);1266125412671255 return 0;···15971583 ath5k_hw_stop_pcu_recv(ah); /* disable PCU */15981584 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */15991585 ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */16001600- mdelay(3); /* 3ms is long enough for 1 frame */1601158616021587 ath5k_debug_printrxbuffs(sc, ah);16031588···16951682 struct ath5k_rx_status rs = {};16961683 struct sk_buff *skb;16971684 struct ath5k_softc *sc = (void *)data;16981698- struct ath5k_buf *bf;16851685+ struct ath5k_buf *bf, *bf_last;16991686 struct ath5k_desc *ds;17001687 int ret;17011688 int hdrlen;17021689 int pad;1703169017041691 spin_lock(&sc->rxbuflock);16921692+ if (list_empty(&sc->rxbuf)) {16931693+ ATH5K_WARN(sc, "empty rx buf pool\n");16941694+ goto unlock;16951695+ }16961696+ bf_last = list_entry(sc->rxbuf.prev, struct ath5k_buf, list);17051697 do {17061698 rxs.flag = 0;1707169917081708- if (unlikely(list_empty(&sc->rxbuf))) {17091709- ATH5K_WARN(sc, "empty rx buf pool\n");17101710- break;17111711- }17121700 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);17131701 BUG_ON(bf->skb == NULL);17141702 skb = bf->skb;17151703 ds = bf->desc;1716170417171717- /* TODO only one segment */17181718- pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,17191719- sc->desc_len, PCI_DMA_FROMDEVICE);17201720-17211721- if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */17221722- break;17051705+ /*17061706+ * last buffer must not be freed to ensure proper hardware17071707+ * function. When the hardware finishes also a packet next to17081708+ * it, we are sure, it doesn't use it anymore and we can go on.17091709+ */17101710+ if (bf_last == bf)17111711+ bf->flags |= 1;17121712+ if (bf->flags) {17131713+ struct ath5k_buf *bf_next = list_entry(bf->list.next,17141714+ struct ath5k_buf, list);17151715+ ret = sc->ah->ah_proc_rx_desc(sc->ah, bf_next->desc,17161716+ &rs);17171717+ if (ret)17181718+ break;17191719+ bf->flags &= ~1;17201720+ /* skip the overwritten one (even status is martian) */17211721+ goto next;17221722+ }1723172317241724 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds, &rs);17251725 if (unlikely(ret == -EINPROGRESS))···17781752 goto next;17791753 }17801754accept:17811781- pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr,17821782- rs.rs_datalen, PCI_DMA_FROMDEVICE);17831755 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,17841756 PCI_DMA_FROMDEVICE);17851757 bf->skb = NULL;···18401816next:18411817 list_move_tail(&bf->list, &sc->rxbuf);18421818 } while (ath5k_rxbuf_setup(sc, bf) == 0);18191819+unlock:18431820 spin_unlock(&sc->rxbuflock);18441821}18451822···18651840 list_for_each_entry_safe(bf, bf0, &txq->q, list) {18661841 ds = bf->desc;1867184218681868- /* TODO only one segment */18691869- pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,18701870- sc->desc_len, PCI_DMA_FROMDEVICE);18711843 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds, &ts);18721844 if (unlikely(ret == -EINPROGRESS))18731845 break;···20372015 ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);20382016 /* NB: hw still stops DMA, so proceed */20392017 }20402040- pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len,20412041- PCI_DMA_TODEVICE);2042201820432019 ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);20442020 ath5k_hw_tx_start(ah, sc->bhalq);···2260224022612241 ret = 0;22622242done:22432243+ mmiowb();22632244 mutex_unlock(&sc->lock);22642245 return ret;22652246}···22932272 if (!test_bit(ATH_STAT_INVALID, sc->status)) {22942273 ath5k_led_off(sc);22952274 ath5k_hw_set_intr(ah, 0);22752275+ synchronize_irq(sc->pdev->irq);22962276 }22972277 ath5k_txq_cleanup(sc);22982278 if (!test_bit(ATH_STAT_INVALID, sc->status)) {···23432321 }23442322 }23452323 ath5k_txbuf_free(sc, sc->bbuf);23242324+ mmiowb();23462325 mutex_unlock(&sc->lock);2347232623482327 del_timer_sync(&sc->calib_tim);23282328+ tasklet_kill(&sc->rxtq);23292329+ tasklet_kill(&sc->txtq);23302330+ tasklet_kill(&sc->restq);2349233123502332 return ret;23512333}···25762550 struct pci_dev *pdev = sc->pdev;25772551 char name[ATH5K_LED_MAX_NAME_LEN + 1];2578255225792579- sc->led_on = 0; /* active low */25802580-25812553 /*25822554 * Auto-enable soft led processing for IBM cards and for25832555 * 5211 minipci cards.···25842560 pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {25852561 __set_bit(ATH_STAT_LEDSOFT, sc->status);25862562 sc->led_pin = 0;25632563+ sc->led_on = 0; /* active low */25872564 }25882565 /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */25892566 if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {25902567 __set_bit(ATH_STAT_LEDSOFT, sc->status);25912568 sc->led_pin = 1;25692569+ sc->led_on = 1; /* active high */25922570 }25932571 if (!test_bit(ATH_STAT_LEDSOFT, sc->status))25942572 goto out;···28092783 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have28102784 * a clean way of letting us retrieve this yet. */28112785 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);27862786+ mmiowb();28122787 }2813278828142789 if (conf->changed & IEEE80211_IFCC_BEACON &&···29982971 }2999297230002973unlock:29742974+ mmiowb();30012975 mutex_unlock(&sc->lock);30022976 return ret;30032977}···3060303230613033 ath5k_debug_dump_skb(sc, skb, "BC ", 1);3062303430633063- mutex_lock(&sc->lock);30643064-30653035 if (sc->opmode != IEEE80211_IF_TYPE_IBSS) {30663036 ret = -EIO;30673037 goto end;···30703044 ret = ath5k_beacon_setup(sc, sc->bbuf);30713045 if (ret)30723046 sc->bbuf->skb = NULL;30733073- else30473047+ else {30743048 ath5k_beacon_config(sc);30493049+ mmiowb();30503050+ }3075305130763052end:30773077- mutex_unlock(&sc->lock);30783053 return ret;30793054}30803055
+1-1
drivers/net/wireless/ath5k/base.h
···56565757struct ath5k_buf {5858 struct list_head list;5959- unsigned int flags; /* tx descriptor flags */5959+ unsigned int flags; /* rx descriptor flags */6060 struct ath5k_desc *desc; /* virtual addr of desc */6161 dma_addr_t daddr; /* physical addr of desc */6262 struct sk_buff *skb; /* skbuff for buf */
···906906 * first entry */907907 iwl_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);908908909909- if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))909909+ if (info->control.hw_key)910910 iwl_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);911911912912 /* Set up TFD's 2nd entry to point directly to remainder of skb,
+2-3
drivers/net/wireless/iwlwifi/iwl3945-base.c
···26672667 * first entry */26682668 iwl3945_hw_txq_attach_buf_to_tfd(priv, tfd, txcmd_phys, len);2669266926702670- if (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT))26702670+ if (info->control.hw_key)26712671 iwl3945_build_tx_cmd_hwcrypto(priv, info, out_cmd, skb, 0);2672267226732673 /* Set up TFD's 2nd entry to point directly to remainder of skb,···78997899 priv->ibss_beacon = NULL;7900790079017901 /* Tell mac80211 our characteristics */79027902- hw->flags = IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |79037903- IEEE80211_HW_SIGNAL_DBM |79027902+ hw->flags = IEEE80211_HW_SIGNAL_DBM |79047903 IEEE80211_HW_NOISE_DBM;7905790479067905 /* 4 EDCA QOS priorities */
+15-15
drivers/net/wireless/libertas/persistcfg.c
···4848 if (ret)4949 return ret;50505151- return snprintf(buf, 12, "0x%x\n", le32_to_cpu(defs.bootflag));5151+ return snprintf(buf, 12, "%d\n", le32_to_cpu(defs.bootflag));5252}53535454/**···6363 int ret;64646565 memset(&cmd, 0, sizeof(cmd));6666- ret = sscanf(buf, "%x", &datum);6767- if (ret != 1)6666+ ret = sscanf(buf, "%d", &datum);6767+ if ((ret != 1) || (datum > 1))6868 return -EINVAL;69697070 *((__le32 *)&cmd.data[0]) = cpu_to_le32(!!datum);···9191 if (ret)9292 return ret;93939494- return snprintf(buf, 12, "0x%x\n", defs.boottime);9494+ return snprintf(buf, 12, "%d\n", defs.boottime);9595}96969797/**···106106 int ret;107107108108 memset(&cmd, 0, sizeof(cmd));109109- ret = sscanf(buf, "%x", &datum);110110- if (ret != 1)109109+ ret = sscanf(buf, "%d", &datum);110110+ if ((ret != 1) || (datum > 255))111111 return -EINVAL;112112113113 /* A too small boot time will result in the device booting into···143143 if (ret)144144 return ret;145145146146- return snprintf(buf, 12, "0x%x\n", le16_to_cpu(defs.channel));146146+ return snprintf(buf, 12, "%d\n", le16_to_cpu(defs.channel));147147}148148149149/**···154154{155155 struct lbs_private *priv = to_net_dev(dev)->priv;156156 struct cmd_ds_mesh_config cmd;157157- uint16_t datum;157157+ uint32_t datum;158158 int ret;159159160160 memset(&cmd, 0, sizeof(cmd));161161- ret = sscanf(buf, "%hx", &datum);161161+ ret = sscanf(buf, "%d", &datum);162162 if (ret != 1 || datum < 1 || datum > 11)163163 return -EINVAL;164164···274274 int ret;275275276276 memset(&cmd, 0, sizeof(cmd));277277- ret = sscanf(buf, "%x", &datum);278278- if (ret != 1)277277+ ret = sscanf(buf, "%d", &datum);278278+ if ((ret != 1) || (datum > 255))279279 return -EINVAL;280280281281 /* fetch all other Information Element parameters */···328328 int ret;329329330330 memset(&cmd, 0, sizeof(cmd));331331- ret = sscanf(buf, "%x", &datum);332332- if (ret != 1)331331+ ret = sscanf(buf, "%d", &datum);332332+ if ((ret != 1) || (datum > 255))333333 return -EINVAL;334334335335 /* fetch all other Information Element parameters */···382382 int ret;383383384384 memset(&cmd, 0, sizeof(cmd));385385- ret = sscanf(buf, "%x", &datum);386386- if (ret != 1)385385+ ret = sscanf(buf, "%d", &datum);386386+ if ((ret != 1) || (datum > 255))387387 return -EINVAL;388388389389 /* fetch all other Information Element parameters */
···11211121 int pipe = usb_sndbulkpipe(usb_dev, 1);11221122 int length;11231123 u16 reg;11241124+ u32 word, len;1124112511251126 /*11261127 * Add the descriptor in front of the skb.···11291128 skb_push(entry->skb, entry->queue->desc_size);11301129 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);11311130 skbdesc->desc = entry->skb->data;11311131+11321132+ /*11331133+ * Adjust the beacon databyte count. The current number is11341134+ * calculated before this function gets called, but falsely11351135+ * assumes that the descriptor was already present in the SKB.11361136+ */11371137+ rt2x00_desc_read(skbdesc->desc, 0, &word);11381138+ len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);11391139+ len += skbdesc->desc_len;11401140+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);11411141+ rt2x00_desc_write(skbdesc->desc, 0, word);1132114211331143 /*11341144 * Disable beaconing while we are reloading the beacon data,···16621650 * Initialize all hw fields.16631651 */16641652 rt2x00dev->hw->flags =16651665- IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |16661653 IEEE80211_HW_RX_INCLUDES_FCS |16671654 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |16681655 IEEE80211_HW_SIGNAL_DBM;
···10131013 rt2x00dev->intf_associated = 0;1014101410151015 __set_bit(DEVICE_STARTED, &rt2x00dev->flags);10161016+ __set_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);1016101710171018 return 0;10181019}···12381237 /*12391238 * Reconfigure device.12401239 */12411241- rt2x00lib_config(rt2x00dev, &rt2x00dev->hw->conf, 1);12421242- if (!rt2x00dev->hw->conf.radio_enabled)12431243- rt2x00lib_disable_radio(rt2x00dev);12401240+ retval = rt2x00mac_config(rt2x00dev->hw, &rt2x00dev->hw->conf);12411241+ if (retval)12421242+ goto exit;1244124312451244 /*12461245 * Iterator over each active interface to
-7
drivers/net/wireless/rt2x00/rt2x00lib.h
···125125void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);126126127127/**128128- * rt2x00queue_free_skb - free a skb129129- * @rt2x00dev: Pointer to &struct rt2x00_dev.130130- * @skb: The skb to free.131131- */132132-void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb);133133-134134-/**135128 * rt2x00queue_write_tx_frame - Write TX frame to hardware136129 * @queue: Queue over which the frame should be send137130 * @skb: The skb to send
+14-15
drivers/net/wireless/rt2x00/rt2x00mac.c
···6363 */6464 memcpy(skb->cb, frag_skb->cb, sizeof(skb->cb));6565 rts_info = IEEE80211_SKB_CB(skb);6666- rts_info->flags |= IEEE80211_TX_CTL_DO_NOT_ENCRYPT;6666+ rts_info->control.hw_key = NULL;6767 rts_info->flags &= ~IEEE80211_TX_CTL_USE_RTS_CTS;6868 rts_info->flags &= ~IEEE80211_TX_CTL_USE_CTS_PROTECT;6969 rts_info->flags &= ~IEEE80211_TX_CTL_REQ_TX_STATUS;···8383 (struct ieee80211_rts *)(skb->data));84848585 if (rt2x00queue_write_tx_frame(queue, skb)) {8686+ dev_kfree_skb_any(skb);8687 WARNING(rt2x00dev, "Failed to send RTS/CTS frame.\n");8788 return NETDEV_TX_BUSY;8889 }···9796 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);9897 struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;9998 enum data_queue_qid qid = skb_get_queue_mapping(skb);100100- struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);10199 struct data_queue *queue;102100 u16 frame_control;103101···150150 ieee80211_stop_queue(rt2x00dev->hw, qid);151151 return NETDEV_TX_BUSY;152152 }153153- }154154-155155- /*156156- * XXX: This is as wrong as the old mac80211 code was,157157- * due to beacons not getting sequence numbers assigned158158- * properly.159159- */160160- if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {161161- if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)162162- intf->seqno += 0x10;163163- ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);164164- ieee80211hdr->seq_ctrl |= cpu_to_le16(intf->seqno);165153 }166154167155 if (rt2x00queue_write_tx_frame(queue, skb)) {···310322int rt2x00mac_config(struct ieee80211_hw *hw, struct ieee80211_conf *conf)311323{312324 struct rt2x00_dev *rt2x00dev = hw->priv;325325+ int force_reconfig;313326314327 /*315328 * Mac80211 might be calling this function while we are trying···330341 rt2x00lib_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);331342 }332343333333- rt2x00lib_config(rt2x00dev, conf, 0);344344+ /*345345+ * When the DEVICE_DIRTY_CONFIG flag is set, the device has recently346346+ * been started and the configuration must be forced upon the hardware.347347+ * Otherwise registers will not be intialized correctly and could348348+ * result in non-working hardware because essential registers aren't349349+ * initialized.350350+ */351351+ force_reconfig =352352+ __test_and_clear_bit(DEVICE_DIRTY_CONFIG, &rt2x00dev->flags);353353+354354+ rt2x00lib_config(rt2x00dev, conf, force_reconfig);334355335356 /*336357 * Reenable RX only if the radio should be on.
+34-2
drivers/net/wireless/rt2x00/rt2x00queue.c
···120120{121121 struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev;122122 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb);123123+ struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);123124 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)entry->skb->data;124125 struct ieee80211_rate *rate =125126 ieee80211_get_tx_rate(rt2x00dev->hw, tx_info);···198197 txdesc->ifs = IFS_BACKOFF;199198 } else {200199 txdesc->ifs = IFS_SIFS;200200+ }201201+202202+ /*203203+ * Hardware should insert sequence counter.204204+ * FIXME: We insert a software sequence counter first for205205+ * hardware that doesn't support hardware sequence counting.206206+ *207207+ * This is wrong because beacons are not getting sequence208208+ * numbers assigned properly.209209+ *210210+ * A secondary problem exists for drivers that cannot toggle211211+ * sequence counting per-frame, since those will override the212212+ * sequence counter given by mac80211.213213+ */214214+ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {215215+ spin_lock(&intf->lock);216216+217217+ if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))218218+ intf->seqno += 0x10;219219+ hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);220220+ hdr->seq_ctrl |= cpu_to_le16(intf->seqno);221221+222222+ spin_unlock(&intf->lock);223223+224224+ __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags);201225 }202226203227 /*···492466 if (!rt2x00dev->ops->lib->init_rxentry)493467 return;494468495495- for (i = 0; i < queue->limit; i++)469469+ for (i = 0; i < queue->limit; i++) {470470+ queue->entries[i].flags = 0;471471+496472 rt2x00dev->ops->lib->init_rxentry(rt2x00dev,497473 &queue->entries[i]);474474+ }498475}499476500477void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev)···511482 if (!rt2x00dev->ops->lib->init_txentry)512483 continue;513484514514- for (i = 0; i < queue->limit; i++)485485+ for (i = 0; i < queue->limit; i++) {486486+ queue->entries[i].flags = 0;487487+515488 rt2x00dev->ops->lib->init_txentry(rt2x00dev,516489 &queue->entries[i]);490490+ }517491 }518492}519493
+2
drivers/net/wireless/rt2x00/rt2x00queue.h
···199199 * @ENTRY_TXD_RTS_FRAME: This frame is a RTS frame.200200 * @ENTRY_TXD_CTS_FRAME: This frame is a CTS-to-self frame.201201 * @ENTRY_TXD_OFDM_RATE: This frame is send out with an OFDM rate.202202+ * @ENTRY_TXD_GENERATE_SEQ: This frame requires sequence counter.202203 * @ENTRY_TXD_FIRST_FRAGMENT: This is the first frame.203204 * @ENTRY_TXD_MORE_FRAG: This frame is followed by another fragment.204205 * @ENTRY_TXD_REQ_TIMESTAMP: Require timestamp to be inserted.···211210 ENTRY_TXD_RTS_FRAME,212211 ENTRY_TXD_CTS_FRAME,213212 ENTRY_TXD_OFDM_RATE,213213+ ENTRY_TXD_GENERATE_SEQ,214214 ENTRY_TXD_FIRST_FRAGMENT,215215 ENTRY_TXD_MORE_FRAG,216216 ENTRY_TXD_REQ_TIMESTAMP,
+32
drivers/net/wireless/rt2x00/rt2x00usb.c
···122122}123123EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_buff);124124125125+int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,126126+ const u8 request, const u8 requesttype,127127+ const u16 offset, void *buffer,128128+ const u16 buffer_length,129129+ const int timeout)130130+{131131+ int status = 0;132132+ unsigned char *tb;133133+ u16 off, len, bsize;134134+135135+ mutex_lock(&rt2x00dev->usb_cache_mutex);136136+137137+ tb = buffer;138138+ off = offset;139139+ len = buffer_length;140140+ while (len && !status) {141141+ bsize = min_t(u16, CSR_CACHE_SIZE, len);142142+ status = rt2x00usb_vendor_req_buff_lock(rt2x00dev, request,143143+ requesttype, off, tb,144144+ bsize, timeout);145145+146146+ tb += bsize;147147+ len -= bsize;148148+ off += bsize;149149+ }150150+151151+ mutex_unlock(&rt2x00dev->usb_cache_mutex);152152+153153+ return status;154154+}155155+EXPORT_SYMBOL_GPL(rt2x00usb_vendor_request_large_buff);156156+125157/*126158 * TX data handlers.127159 */
+20-2
drivers/net/wireless/rt2x00/rt2x00usb.h
···7070/*7171 * Cache size7272 */7373-#define CSR_CACHE_SIZE 87474-#define CSR_CACHE_SIZE_FIRMWARE 647373+#define CSR_CACHE_SIZE 6475747675/*7776 * USB request types.···169170 const u8 request, const u8 requesttype,170171 const u16 offset, void *buffer,171172 const u16 buffer_length, const int timeout);173173+174174+/**175175+ * rt2x00usb_vendor_request_large_buff - Send register command to device (buffered)176176+ * @rt2x00dev: Pointer to &struct rt2x00_dev177177+ * @request: USB vendor command (See &enum rt2x00usb_vendor_request)178178+ * @requesttype: Request type &USB_VENDOR_REQUEST_*179179+ * @offset: Register start offset to perform action on180180+ * @buffer: Buffer where information will be read/written to by device181181+ * @buffer_length: Size of &buffer182182+ * @timeout: Operation timeout183183+ *184184+ * This function is used to transfer register data in blocks larger185185+ * then CSR_CACHE_SIZE. Use for firmware upload, keys and beacons.186186+ */187187+int rt2x00usb_vendor_request_large_buff(struct rt2x00_dev *rt2x00dev,188188+ const u8 request, const u8 requesttype,189189+ const u16 offset, void *buffer,190190+ const u16 buffer_length,191191+ const int timeout);172192173193/**174194 * rt2x00usb_vendor_request_sw - Send single register command to device
···890890 unsigned int i;891891 int status;892892 u32 reg;893893- const char *ptr = data;894894- char *cache;895895- int buflen;896893897894 /*898895 * Wait for stable hardware.···908911909912 /*910913 * Write firmware to device.911911- * We setup a seperate cache for this action,912912- * since we are going to write larger chunks of data913913- * then normally used cache size.914914 */915915- cache = kmalloc(CSR_CACHE_SIZE_FIRMWARE, GFP_KERNEL);916916- if (!cache) {917917- ERROR(rt2x00dev, "Failed to allocate firmware cache.\n");918918- return -ENOMEM;919919- }920920-921921- for (i = 0; i < len; i += CSR_CACHE_SIZE_FIRMWARE) {922922- buflen = min_t(int, len - i, CSR_CACHE_SIZE_FIRMWARE);923923-924924- memcpy(cache, ptr, buflen);925925-926926- rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,927927- USB_VENDOR_REQUEST_OUT,928928- FIRMWARE_IMAGE_BASE + i, 0,929929- cache, buflen,930930- REGISTER_TIMEOUT32(buflen));931931-932932- ptr += buflen;933933- }934934-935935- kfree(cache);915915+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,916916+ USB_VENDOR_REQUEST_OUT,917917+ FIRMWARE_IMAGE_BASE,918918+ data, len,919919+ REGISTER_TIMEOUT32(len));936920937921 /*938922 * Send firmware request to device to load firmware,···12811303 rt2x00_set_field32(&word, TXD_W1_CWMIN, txdesc->cw_min);12821304 rt2x00_set_field32(&word, TXD_W1_CWMAX, txdesc->cw_max);12831305 rt2x00_set_field32(&word, TXD_W1_IV_OFFSET, IEEE80211_HEADER);12841284- rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE, 1);13061306+ rt2x00_set_field32(&word, TXD_W1_HW_SEQUENCE,13071307+ test_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags));12851308 rt2x00_desc_write(txd, 1, word);1286130912871310 rt2x00_desc_read(txd, 2, &word);···13311352 struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb);13321353 unsigned int beacon_base;13331354 u32 reg;13551355+ u32 word, len;1334135613351357 /*13361358 * Add the descriptor in front of the skb.···13391359 skb_push(entry->skb, entry->queue->desc_size);13401360 memcpy(entry->skb->data, skbdesc->desc, skbdesc->desc_len);13411361 skbdesc->desc = entry->skb->data;13621362+13631363+ /*13641364+ * Adjust the beacon databyte count. The current number is13651365+ * calculated before this function gets called, but falsely13661366+ * assumes that the descriptor was already present in the SKB.13671367+ */13681368+ rt2x00_desc_read(skbdesc->desc, 0, &word);13691369+ len = rt2x00_get_field32(word, TXD_W0_DATABYTE_COUNT);13701370+ len += skbdesc->desc_len;13711371+ rt2x00_set_field32(&word, TXD_W0_DATABYTE_COUNT, len);13721372+ rt2x00_desc_write(skbdesc->desc, 0, word);1342137313431374 /*13441375 * Disable beaconing while we are reloading the beacon data,···13651374 * Write entire beacon with descriptor to register.13661375 */13671376 beacon_base = HW_BEACON_OFFSET(entry->entry_idx);13681368- rt2x00usb_vendor_request(rt2x00dev, USB_MULTI_WRITE,13691369- USB_VENDOR_REQUEST_OUT, beacon_base, 0,13701370- entry->skb->data, entry->skb->len,13711371- REGISTER_TIMEOUT32(entry->skb->len));13771377+ rt2x00usb_vendor_request_large_buff(rt2x00dev, USB_MULTI_WRITE,13781378+ USB_VENDOR_REQUEST_OUT, beacon_base,13791379+ entry->skb->data, entry->skb->len,13801380+ REGISTER_TIMEOUT32(entry->skb->len));1372138113731382 /*13741383 * Clean up the beacon skb.···18621871 * Initialize all hw fields.18631872 */18641873 rt2x00dev->hw->flags =18651865- IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE |18661874 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |18671875 IEEE80211_HW_SIGNAL_DBM;18681876 rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE;
···169169{170170 struct rtl8187_priv *priv = dev->priv;171171 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);172172+ struct ieee80211_hdr *ieee80211hdr = (struct ieee80211_hdr *)skb->data;172173 unsigned int ep;173174 void *buf;174175 struct urb *urb;···235234 ep = epmap[skb_get_queue_mapping(skb)];236235 }237236237237+ /* FIXME: The sequence that follows is needed for this driver to238238+ * work with mac80211 since "mac80211: fix TX sequence numbers".239239+ * As with the temporary code in rt2x00, changes will be needed240240+ * to get proper sequence numbers on beacons. In addition, this241241+ * patch places the sequence number in the hardware state, which242242+ * limits us to a single virtual state.243243+ */244244+ if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {245245+ if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT)246246+ priv->seqno += 0x10;247247+ ieee80211hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);248248+ ieee80211hdr->seq_ctrl |= cpu_to_le16(priv->seqno);249249+ }250250+238251 info->driver_data[0] = dev;239252 info->driver_data[1] = urb;240253···272257 struct ieee80211_rx_status rx_status = { 0 };273258 int rate, signal;274259 u32 flags;260260+ u32 quality;275261276262 spin_lock(&priv->rx_queue.lock);277263 if (skb->next)···296280 flags = le32_to_cpu(hdr->flags);297281 signal = hdr->signal & 0x7f;298282 rx_status.antenna = (hdr->signal >> 7) & 1;299299- rx_status.signal = signal;300283 rx_status.noise = hdr->noise;301284 rx_status.mactime = le64_to_cpu(hdr->mac_time);302302- priv->signal = signal;303285 priv->quality = signal;286286+ rx_status.qual = priv->quality;304287 priv->noise = hdr->noise;288288+ rate = (flags >> 20) & 0xF;289289+ if (rate > 3) { /* OFDM rate */290290+ if (signal > 90)291291+ signal = 90;292292+ else if (signal < 25)293293+ signal = 25;294294+ signal = 90 - signal;295295+ } else { /* CCK rate */296296+ if (signal > 95)297297+ signal = 95;298298+ else if (signal < 30)299299+ signal = 30;300300+ signal = 95 - signal;301301+ }302302+ rx_status.signal = signal;303303+ priv->signal = signal;305304 } else {306305 struct rtl8187b_rx_hdr *hdr =307306 (typeof(hdr))(skb_tail_pointer(skb) - sizeof(*hdr));307307+ /* The Realtek datasheet for the RTL8187B shows that the RX308308+ * header contains the following quantities: signal quality,309309+ * RSSI, AGC, the received power in dB, and the measured SNR.310310+ * In testing, none of these quantities show qualitative311311+ * agreement with AP signal strength, except for the AGC,312312+ * which is inversely proportional to the strength of the313313+ * signal. In the following, the quality and signal strength314314+ * are derived from the AGC. The arbitrary scaling constants315315+ * are chosen to make the results close to the values obtained316316+ * for a BCM4312 using b43 as the driver. The noise is ignored317317+ * for now.318318+ */308319 flags = le32_to_cpu(hdr->flags);309309- signal = hdr->agc >> 1;310310- rx_status.antenna = (hdr->signal >> 7) & 1;311311- rx_status.signal = 64 - min(hdr->noise, (u8)64);312312- rx_status.noise = hdr->noise;320320+ quality = 170 - hdr->agc;321321+ if (quality > 100)322322+ quality = 100;323323+ signal = 14 - hdr->agc / 2;324324+ rx_status.qual = quality;325325+ priv->quality = quality;326326+ rx_status.signal = signal;327327+ priv->signal = signal;328328+ rx_status.antenna = (hdr->rssi >> 7) & 1;313329 rx_status.mactime = le64_to_cpu(hdr->mac_time);314314- priv->signal = hdr->signal;315315- priv->quality = hdr->agc >> 1;316316- priv->noise = hdr->noise;330330+ rate = (flags >> 20) & 0xF;317331 }318332319333 skb_trim(skb, flags & 0x0FFF);320320- rate = (flags >> 20) & 0xF;321321- if (rate > 3) { /* OFDM rate */322322- if (signal > 90)323323- signal = 90;324324- else if (signal < 25)325325- signal = 25;326326- signal = 90 - signal;327327- } else { /* CCK rate */328328- if (signal > 95)329329- signal = 95;330330- else if (signal < 30)331331- signal = 30;332332- signal = 95 - signal;333333- }334334-335335- rx_status.qual = priv->quality;336336- rx_status.signal = signal;337334 rx_status.rate_idx = rate;338335 rx_status.freq = dev->conf.channel->center_freq;339336 rx_status.band = dev->conf.channel->band;···1044101510451016 priv->mode = IEEE80211_IF_TYPE_MNTR;10461017 dev->flags = IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |10471047- IEEE80211_HW_RX_INCLUDES_FCS |10481048- IEEE80211_HW_SIGNAL_UNSPEC;10491049- dev->max_signal = 65;10181018+ IEEE80211_HW_RX_INCLUDES_FCS;1050101910511020 eeprom.data = dev;10521021 eeprom.register_read = rtl8187_eeprom_register_read;···11591132 (*channel++).hw_value = txpwr >> 8;11601133 }1161113411621162- if (priv->is_rtl8187b)11351135+ if (priv->is_rtl8187b) {11631136 printk(KERN_WARNING "rtl8187: 8187B chip detected. Support "11641137 "is EXPERIMENTAL, and could damage your\n"11651138 " hardware, use at your own risk\n");11391139+ dev->flags |= IEEE80211_HW_SIGNAL_DBM;11401140+ } else {11411141+ dev->flags |= IEEE80211_HW_SIGNAL_UNSPEC;11421142+ dev->max_signal = 65;11431143+ }11441144+11661145 if ((id->driver_info == DEVICE_RTL8187) && priv->is_rtl8187b)11671146 printk(KERN_INFO "rtl8187: inconsistency between id with OEM"11681147 " info!\n");
···6868 * @user_claim_unsupported: Whether the hardware supports exclusive6969 * RF-kill control by userspace. Set this before registering.7070 * @user_claim: Set when the switch is controlled exlusively by userspace.7171- * @mutex: Guards switch state transitions7171+ * @mutex: Guards switch state transitions. It serializes callbacks7272+ * and also protects the state.7273 * @data: Pointer to the RF button drivers private data which will be7374 * passed along when toggling radio state.7475 * @toggle_radio(): Mandatory handler to control state of the radio.···9089 const char *name;9190 enum rfkill_type type;92919393- enum rfkill_state state;9492 bool user_claim_unsupported;9593 bool user_claim;96949595+ /* the mutex serializes callbacks and also protects9696+ * the state */9797 struct mutex mutex;9898-9898+ enum rfkill_state state;9999 void *data;100100 int (*toggle_radio)(void *data, enum rfkill_state state);101101 int (*get_state)(void *data, enum rfkill_state *state);
···206206 * These flags are used with the @flags member of &ieee80211_tx_info.207207 *208208 * @IEEE80211_TX_CTL_REQ_TX_STATUS: request TX status callback for this frame.209209- * @IEEE80211_TX_CTL_DO_NOT_ENCRYPT: send this frame without encryption;210210- * e.g., for EAPOL frame211209 * @IEEE80211_TX_CTL_USE_RTS_CTS: use RTS-CTS before sending frame212210 * @IEEE80211_TX_CTL_USE_CTS_PROTECT: use CTS protection for the frame (e.g.,213211 * for combined 802.11g / 802.11b networks)···218220 * @IEEE80211_TX_CTL_SHORT_PREAMBLE: TBD219221 * @IEEE80211_TX_CTL_LONG_RETRY_LIMIT: this frame should be send using the220222 * through set_retry_limit configured long retry value221221- * @IEEE80211_TX_CTL_EAPOL_FRAME: internal to mac80211222223 * @IEEE80211_TX_CTL_SEND_AFTER_DTIM: send this frame after DTIM beacon223224 * @IEEE80211_TX_CTL_AMPDU: this frame should be sent as part of an A-MPDU224225 * @IEEE80211_TX_CTL_OFDM_HT: this frame can be sent in HT OFDM rates. number···250253 */251254enum mac80211_tx_control_flags {252255 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),253253- IEEE80211_TX_CTL_DO_NOT_ENCRYPT = BIT(1),254256 IEEE80211_TX_CTL_USE_RTS_CTS = BIT(2),255257 IEEE80211_TX_CTL_USE_CTS_PROTECT = BIT(3),256258 IEEE80211_TX_CTL_NO_ACK = BIT(4),···259263 IEEE80211_TX_CTL_FIRST_FRAGMENT = BIT(8),260264 IEEE80211_TX_CTL_SHORT_PREAMBLE = BIT(9),261265 IEEE80211_TX_CTL_LONG_RETRY_LIMIT = BIT(10),262262- IEEE80211_TX_CTL_EAPOL_FRAME = BIT(11),263266 IEEE80211_TX_CTL_SEND_AFTER_DTIM = BIT(12),264267 IEEE80211_TX_CTL_AMPDU = BIT(13),265268 IEEE80211_TX_CTL_OFDM_HT = BIT(14),···318323 struct ieee80211_vif *vif;319324 struct ieee80211_key_conf *hw_key;320325 unsigned long jiffies;321321- int ifindex;322326 u16 aid;323327 s8 rts_cts_rate_idx, alt_retry_rate_idx;324328 u8 retry_limit;···740746 * Measurement, Channel Switch, Quieting, TPC741747 */742748enum ieee80211_hw_flags {743743- IEEE80211_HW_HOST_GEN_BEACON_TEMPLATE = 1<<0,744749 IEEE80211_HW_RX_INCLUDES_FCS = 1<<1,745750 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING = 1<<2,746751 IEEE80211_HW_2GHZ_SHORT_SLOT_INCAPABLE = 1<<3,
···12331233/* Remove added headers (e.g., QoS control), encryption header/MIC, etc. to12341234 * make a prepared TX frame (one that has been given to hw) to look like brand12351235 * new IEEE 802.11 frame that is ready to go through TX processing again.12361236- * Also, tx_packet_data in cb is restored from tx_control. */12361236+ */12371237static void ieee80211_remove_tx_extra(struct ieee80211_local *local,12381238 struct ieee80211_key *key,12391239 struct sk_buff *skb)12401240{12411241 int hdrlen, iv_len, mic_len;12421242- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);12431243-12441244- info->flags &= IEEE80211_TX_CTL_REQ_TX_STATUS |12451245- IEEE80211_TX_CTL_DO_NOT_ENCRYPT |12461246- IEEE80211_TX_CTL_REQUEUE |12471247- IEEE80211_TX_CTL_EAPOL_FRAME;1248124212491243 hdrlen = ieee80211_get_hdrlen_from_skb(skb);12501244···17251731 result = ieee80211_wep_init(local);1726173217271733 if (result < 0) {17281728- printk(KERN_DEBUG "%s: Failed to initialize wep\n",17291729- wiphy_name(local->hw.wiphy));17341734+ printk(KERN_DEBUG "%s: Failed to initialize wep: %d\n",17351735+ wiphy_name(local->hw.wiphy), result);17301736 goto fail_wep;17311737 }17321738
···188188{189189 int i;190190191191+ /* XXX: currently broken due to cb/requeue use */192192+ return -EPERM;193193+191194 /* prepare the filter and save it for the SW queue192195 * matching the received HW queue */193196
+39-23
net/rfkill/rfkill.c
···130130131131/**132132 * rfkill_toggle_radio - wrapper for toggle_radio hook133133- *134133 * @rfkill: the rfkill struct to use135134 * @force: calls toggle_radio even if cache says it is not needed,136135 * and also makes sure notifications of the state will be···140141 * calls and handling all the red tape such as issuing notifications141142 * if the call is successful.142143 *143143- * Note that @force cannot override a (possibly cached) state of144144- * RFKILL_STATE_HARD_BLOCKED. Any device making use of144144+ * Note that the @force parameter cannot override a (possibly cached)145145+ * state of RFKILL_STATE_HARD_BLOCKED. Any device making use of145146 * RFKILL_STATE_HARD_BLOCKED implements either get_state() or146147 * rfkill_force_state(), so the cache either is bypassed or valid.147148 *···149150 * even if the radio is in RFKILL_STATE_HARD_BLOCKED state, so as to150151 * give the driver a hint that it should double-BLOCK the transmitter.151152 *152152- * Caller must have aquired rfkill_mutex.153153+ * Caller must have acquired rfkill->mutex.153154 */154155static int rfkill_toggle_radio(struct rfkill *rfkill,155156 enum rfkill_state state,···199200200201/**201202 * rfkill_switch_all - Toggle state of all switches of given type202202- * @type: type of interfaces to be affeceted203203+ * @type: type of interfaces to be affected203204 * @state: the new state204205 *205205- * This function toggles state of all switches of given type unless206206- * a specific switch is claimed by userspace in which case it is207207- * left alone.206206+ * This function toggles the state of all switches of given type,207207+ * unless a specific switch is claimed by userspace (in which case,208208+ * that switch is left alone).208209 */209210void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)210211{···215216 rfkill_states[type] = state;216217217218 list_for_each_entry(rfkill, &rfkill_list, node) {218218- if ((!rfkill->user_claim) && (rfkill->type == type))219219+ if ((!rfkill->user_claim) && (rfkill->type == type)) {220220+ mutex_lock(&rfkill->mutex);219221 rfkill_toggle_radio(rfkill, state, 0);222222+ mutex_unlock(&rfkill->mutex);223223+ }220224 }221225222226 mutex_unlock(&rfkill_mutex);···230228 * rfkill_epo - emergency power off all transmitters231229 *232230 * This kicks all rfkill devices to RFKILL_STATE_SOFT_BLOCKED, ignoring233233- * everything in its path but rfkill_mutex.231231+ * everything in its path but rfkill_mutex and rfkill->mutex.234232 */235233void rfkill_epo(void)236234{···238236239237 mutex_lock(&rfkill_mutex);240238 list_for_each_entry(rfkill, &rfkill_list, node) {239239+ mutex_lock(&rfkill->mutex);241240 rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);241241+ mutex_unlock(&rfkill->mutex);242242 }243243 mutex_unlock(&rfkill_mutex);244244}···256252 * a notification by the firmware/hardware of the current *real*257253 * state of the radio rfkill switch.258254 *259259- * It may not be called from an atomic context.255255+ * Devices which are subject to external changes on their rfkill256256+ * state (such as those caused by a hardware rfkill line) MUST257257+ * have their driver arrange to call rfkill_force_state() as soon258258+ * as possible after such a change.259259+ *260260+ * This function may not be called from an atomic context.260261 */261262int rfkill_force_state(struct rfkill *rfkill, enum rfkill_state state)262263{···376367 if (!capable(CAP_NET_ADMIN))377368 return -EPERM;378369370370+ if (rfkill->user_claim_unsupported)371371+ return -EOPNOTSUPP;372372+379373 /*380374 * Take the global lock to make sure the kernel is not in381375 * the middle of rfkill_switch_all···387375 if (error)388376 return error;389377390390- if (rfkill->user_claim_unsupported) {391391- error = -EOPNOTSUPP;392392- goto out_unlock;393393- }394378 if (rfkill->user_claim != claim) {395395- if (!claim)379379+ if (!claim) {380380+ mutex_lock(&rfkill->mutex);396381 rfkill_toggle_radio(rfkill,397382 rfkill_states[rfkill->type],398383 0);384384+ mutex_unlock(&rfkill->mutex);385385+ }399386 rfkill->user_claim = claim;400387 }401388402402-out_unlock:403389 mutex_unlock(&rfkill_mutex);404390405391 return error ? error : count;···526516{527517 mutex_lock(&rfkill_mutex);528518 list_del_init(&rfkill->node);529529- rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);530519 mutex_unlock(&rfkill_mutex);520520+521521+ mutex_lock(&rfkill->mutex);522522+ rfkill_toggle_radio(rfkill, RFKILL_STATE_SOFT_BLOCKED, 1);523523+ mutex_unlock(&rfkill->mutex);531524}532525533526/**···539526 * @type: type of the switch (RFKILL_TYPE_*)540527 *541528 * This function should be called by the network driver when it needs542542- * rfkill structure. Once the structure is allocated the driver shoud543543- * finish its initialization by setting name, private data, enable_radio529529+ * rfkill structure. Once the structure is allocated the driver should530530+ * finish its initialization by setting the name, private data, enable_radio544531 * and disable_radio methods and then register it with rfkill_register().532532+ *545533 * NOTE: If registration fails the structure shoudl be freed by calling546534 * rfkill_free() otherwise rfkill_unregister() should be used.547535 */···574560 * rfkill_free - Mark rfkill structure for deletion575561 * @rfkill: rfkill structure to be destroyed576562 *577577- * Decrements reference count of rfkill structure so it is destroyed.563563+ * Decrements reference count of the rfkill structure so it is destroyed.578564 * Note that rfkill_free() should _not_ be called after rfkill_unregister().579565 */580566void rfkill_free(struct rfkill *rfkill)···599585static void rfkill_led_trigger_unregister(struct rfkill *rfkill)600586{601587#ifdef CONFIG_RFKILL_LEDS602602- if (rfkill->led_trigger.name)588588+ if (rfkill->led_trigger.name) {603589 led_trigger_unregister(&rfkill->led_trigger);590590+ rfkill->led_trigger.name = NULL;591591+ }604592#endif605593}606594···638622639623 error = device_add(dev);640624 if (error) {641641- rfkill_led_trigger_unregister(rfkill);642625 rfkill_remove_switch(rfkill);626626+ rfkill_led_trigger_unregister(rfkill);643627 return error;644628 }645629
+155-124
net/wireless/nl80211.c
···2929};30303131/* internal helper: get drv and dev */3232-static int get_drv_dev_by_info_ifindex(struct genl_info *info,3232+static int get_drv_dev_by_info_ifindex(struct nlattr **attrs,3333 struct cfg80211_registered_device **drv,3434 struct net_device **dev)3535{3636 int ifindex;37373838- if (!info->attrs[NL80211_ATTR_IFINDEX])3838+ if (!attrs[NL80211_ATTR_IFINDEX])3939 return -EINVAL;40404141- ifindex = nla_get_u32(info->attrs[NL80211_ATTR_IFINDEX]);4141+ ifindex = nla_get_u32(attrs[NL80211_ATTR_IFINDEX]);4242 *dev = dev_get_by_index(&init_net, ifindex);4343 if (!*dev)4444 return -ENODEV;···291291292292 mutex_lock(&cfg80211_drv_mutex);293293 list_for_each_entry(dev, &cfg80211_drv_list, list) {294294- if (++wp_idx < wp_start)294294+ if (wp_idx < wp_start) {295295+ wp_idx++;295296 continue;297297+ }296298 if_idx = 0;297299298300 mutex_lock(&dev->devlist_mtx);299301 list_for_each_entry(wdev, &dev->netdev_list, list) {300300- if (++if_idx < if_start)302302+ if (if_idx < if_start) {303303+ if_idx++;301304 continue;305305+ }302306 if (nl80211_send_iface(skb, NETLINK_CB(cb->skb).pid,303307 cb->nlh->nlmsg_seq, NLM_F_MULTI,304304- wdev->netdev) < 0)305305- break;308308+ wdev->netdev) < 0) {309309+ mutex_unlock(&dev->devlist_mtx);310310+ goto out;311311+ }312312+ if_idx++;306313 }307314 mutex_unlock(&dev->devlist_mtx);315315+316316+ wp_idx++;308317 }318318+ out:309319 mutex_unlock(&cfg80211_drv_mutex);310320311321 cb->args[0] = wp_idx;···331321 struct net_device *netdev;332322 int err;333323334334- err = get_drv_dev_by_info_ifindex(info, &dev, &netdev);324324+ err = get_drv_dev_by_info_ifindex(info->attrs, &dev, &netdev);335325 if (err)336326 return err;337327···402392 } else403393 return -EINVAL;404394405405- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);395395+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);406396 if (err)407397 return err;408398 ifindex = dev->ifindex;···487477 int ifindex, err;488478 struct net_device *dev;489479490490- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);480480+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);491481 if (err)492482 return err;493483 ifindex = dev->ifindex;···555545 if (info->attrs[NL80211_ATTR_MAC])556546 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);557547558558- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);548548+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);559549 if (err)560550 return err;561551···628618 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT])629619 return -EINVAL;630620631631- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);621621+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);632622 if (err)633623 return err;634624···709699 return -EINVAL;710700 }711701712712- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);702702+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);713703 if (err)714704 return err;715705···745735 if (info->attrs[NL80211_ATTR_MAC])746736 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);747737748748- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);738738+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);749739 if (err)750740 return err;751741···774764 struct beacon_parameters params;775765 int haveinfo = 0;776766777777- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);767767+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);778768 if (err)779769 return err;780770···853843 int err;854844 struct net_device *dev;855845856856- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);846846+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);857847 if (err)858848 return err;859849···947937}948938949939static int nl80211_dump_station(struct sk_buff *skb,950950- struct netlink_callback *cb)940940+ struct netlink_callback *cb)951941{952952- int wp_idx = 0;953953- int if_idx = 0;954954- int sta_idx = cb->args[2];955955- int wp_start = cb->args[0];956956- int if_start = cb->args[1];957942 struct station_info sinfo;958943 struct cfg80211_registered_device *dev;959959- struct wireless_dev *wdev;944944+ struct net_device *netdev;960945 u8 mac_addr[ETH_ALEN];946946+ int ifidx = cb->args[0];947947+ int sta_idx = cb->args[1];961948 int err;962962- int exit = 0;963949964964- /* TODO: filter by device */965965- mutex_lock(&cfg80211_drv_mutex);966966- list_for_each_entry(dev, &cfg80211_drv_list, list) {967967- if (exit)968968- break;969969- if (++wp_idx < wp_start)970970- continue;971971- if_idx = 0;950950+ if (!ifidx) {951951+ err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,952952+ nl80211_fam.attrbuf, nl80211_fam.maxattr,953953+ nl80211_policy);954954+ if (err)955955+ return err;972956973973- mutex_lock(&dev->devlist_mtx);974974- list_for_each_entry(wdev, &dev->netdev_list, list) {975975- if (exit)976976- break;977977- if (++if_idx < if_start)978978- continue;979979- if (!dev->ops->dump_station)980980- continue;957957+ if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])958958+ return -EINVAL;981959982982- for (;; ++sta_idx) {983983- rtnl_lock();984984- err = dev->ops->dump_station(&dev->wiphy,985985- wdev->netdev, sta_idx, mac_addr,986986- &sinfo);987987- rtnl_unlock();988988- if (err) {989989- sta_idx = 0;990990- break;991991- }992992- if (nl80211_send_station(skb,993993- NETLINK_CB(cb->skb).pid,994994- cb->nlh->nlmsg_seq, NLM_F_MULTI,995995- wdev->netdev, mac_addr,996996- &sinfo) < 0) {997997- exit = 1;998998- break;999999- }10001000- }10011001- }10021002- mutex_unlock(&dev->devlist_mtx);960960+ ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);961961+ if (!ifidx)962962+ return -EINVAL;1003963 }10041004- mutex_unlock(&cfg80211_drv_mutex);100596410061006- cb->args[0] = wp_idx;10071007- cb->args[1] = if_idx;10081008- cb->args[2] = sta_idx;965965+ netdev = dev_get_by_index(&init_net, ifidx);966966+ if (!netdev)967967+ return -ENODEV;100996810101010- return skb->len;969969+ dev = cfg80211_get_dev_from_ifindex(ifidx);970970+ if (IS_ERR(dev)) {971971+ err = PTR_ERR(dev);972972+ goto out_put_netdev;973973+ }974974+975975+ if (!dev->ops->dump_station) {976976+ err = -ENOSYS;977977+ goto out_err;978978+ }979979+980980+ rtnl_lock();981981+982982+ while (1) {983983+ err = dev->ops->dump_station(&dev->wiphy, netdev, sta_idx,984984+ mac_addr, &sinfo);985985+ if (err == -ENOENT)986986+ break;987987+ if (err)988988+ goto out_err_rtnl;989989+990990+ if (nl80211_send_station(skb,991991+ NETLINK_CB(cb->skb).pid,992992+ cb->nlh->nlmsg_seq, NLM_F_MULTI,993993+ netdev, mac_addr,994994+ &sinfo) < 0)995995+ goto out;996996+997997+ sta_idx++;998998+ }999999+10001000+10011001+ out:10021002+ cb->args[1] = sta_idx;10031003+ err = skb->len;10041004+ out_err_rtnl:10051005+ rtnl_unlock();10061006+ out_err:10071007+ cfg80211_put_dev(dev);10081008+ out_put_netdev:10091009+ dev_put(netdev);10101010+10111011+ return err;10111012}1012101310131014static int nl80211_get_station(struct sk_buff *skb, struct genl_info *info)···1037101610381017 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);1039101810401040- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);10191019+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);10411020 if (err)10421021 return err;10431022···11331112 params.plink_action =11341113 nla_get_u8(info->attrs[NL80211_ATTR_STA_PLINK_ACTION]);1135111411361136- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);11151115+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);11371116 if (err)11381117 return err;11391118···11931172 ¶ms.station_flags))11941173 return -EINVAL;1195117411961196- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);11751175+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);11971176 if (err)11981177 return err;11991178···12281207 if (info->attrs[NL80211_ATTR_MAC])12291208 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);1230120912311231- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);12101210+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);12321211 if (err)12331212 return err;12341213···12981277}1299127813001279static int nl80211_dump_mpath(struct sk_buff *skb,13011301- struct netlink_callback *cb)12801280+ struct netlink_callback *cb)13021281{13031303- int wp_idx = 0;13041304- int if_idx = 0;13051305- int sta_idx = cb->args[2];13061306- int wp_start = cb->args[0];13071307- int if_start = cb->args[1];13081282 struct mpath_info pinfo;13091283 struct cfg80211_registered_device *dev;13101310- struct wireless_dev *wdev;12841284+ struct net_device *netdev;13111285 u8 dst[ETH_ALEN];13121286 u8 next_hop[ETH_ALEN];12871287+ int ifidx = cb->args[0];12881288+ int path_idx = cb->args[1];13131289 int err;13141314- int exit = 0;1315129013161316- /* TODO: filter by device */13171317- mutex_lock(&cfg80211_drv_mutex);13181318- list_for_each_entry(dev, &cfg80211_drv_list, list) {13191319- if (exit)13201320- break;13211321- if (++wp_idx < wp_start)13221322- continue;13231323- if_idx = 0;12911291+ if (!ifidx) {12921292+ err = nlmsg_parse(cb->nlh, GENL_HDRLEN + nl80211_fam.hdrsize,12931293+ nl80211_fam.attrbuf, nl80211_fam.maxattr,12941294+ nl80211_policy);12951295+ if (err)12961296+ return err;1324129713251325- mutex_lock(&dev->devlist_mtx);13261326- list_for_each_entry(wdev, &dev->netdev_list, list) {13271327- if (exit)13281328- break;13291329- if (++if_idx < if_start)13301330- continue;13311331- if (!dev->ops->dump_mpath)13321332- continue;12981298+ if (!nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX])12991299+ return -EINVAL;1333130013341334- for (;; ++sta_idx) {13351335- rtnl_lock();13361336- err = dev->ops->dump_mpath(&dev->wiphy,13371337- wdev->netdev, sta_idx, dst,13381338- next_hop, &pinfo);13391339- rtnl_unlock();13401340- if (err) {13411341- sta_idx = 0;13421342- break;13431343- }13441344- if (nl80211_send_mpath(skb,13451345- NETLINK_CB(cb->skb).pid,13461346- cb->nlh->nlmsg_seq, NLM_F_MULTI,13471347- wdev->netdev, dst, next_hop,13481348- &pinfo) < 0) {13491349- exit = 1;13501350- break;13511351- }13521352- }13531353- }13541354- mutex_unlock(&dev->devlist_mtx);13011301+ ifidx = nla_get_u32(nl80211_fam.attrbuf[NL80211_ATTR_IFINDEX]);13021302+ if (!ifidx)13031303+ return -EINVAL;13551304 }13561356- mutex_unlock(&cfg80211_drv_mutex);1357130513581358- cb->args[0] = wp_idx;13591359- cb->args[1] = if_idx;13601360- cb->args[2] = sta_idx;13061306+ netdev = dev_get_by_index(&init_net, ifidx);13071307+ if (!netdev)13081308+ return -ENODEV;1361130913621362- return skb->len;13101310+ dev = cfg80211_get_dev_from_ifindex(ifidx);13111311+ if (IS_ERR(dev)) {13121312+ err = PTR_ERR(dev);13131313+ goto out_put_netdev;13141314+ }13151315+13161316+ if (!dev->ops->dump_mpath) {13171317+ err = -ENOSYS;13181318+ goto out_err;13191319+ }13201320+13211321+ rtnl_lock();13221322+13231323+ while (1) {13241324+ err = dev->ops->dump_mpath(&dev->wiphy, netdev, path_idx,13251325+ dst, next_hop, &pinfo);13261326+ if (err == -ENOENT)13271327+ break;13281328+ if (err)13291329+ goto out_err_rtnl;13301330+13311331+ if (nl80211_send_mpath(skb, NETLINK_CB(cb->skb).pid,13321332+ cb->nlh->nlmsg_seq, NLM_F_MULTI,13331333+ netdev, dst, next_hop,13341334+ &pinfo) < 0)13351335+ goto out;13361336+13371337+ path_idx++;13381338+ }13391339+13401340+13411341+ out:13421342+ cb->args[1] = path_idx;13431343+ err = skb->len;13441344+ out_err_rtnl:13451345+ rtnl_unlock();13461346+ out_err:13471347+ cfg80211_put_dev(dev);13481348+ out_put_netdev:13491349+ dev_put(netdev);13501350+13511351+ return err;13631352}1364135313651354static int nl80211_get_mpath(struct sk_buff *skb, struct genl_info *info)···1389135813901359 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);1391136013921392- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);13611361+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);13931362 if (err)13941363 return err;13951364···14421411 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);14431412 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);1444141314451445- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);14141414+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);14461415 if (err)14471416 return err;14481417···14771446 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);14781447 next_hop = nla_data(info->attrs[NL80211_ATTR_MPATH_NEXT_HOP]);1479144814801480- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);14491449+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);14811450 if (err)14821451 return err;14831452···15061475 if (info->attrs[NL80211_ATTR_MAC])15071476 dst = nla_data(info->attrs[NL80211_ATTR_MAC]);1508147715091509- err = get_drv_dev_by_info_ifindex(info, &drv, &dev);14781478+ err = get_drv_dev_by_info_ifindex(info->attrs, &drv, &dev);15101479 if (err)15111480 return err;15121481