···59785978F: drivers/input/misc/wistron_btns.c5979597959805980WL1251 WIRELESS DRIVER59815981-M: Kalle Valo <kalle.valo@nokia.com>59815981+M: Kalle Valo <kalle.valo@iki.fi>59825982L: linux-wireless@vger.kernel.org59835983W: http://wireless.kernel.org59845984T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
···668668 struct ieee80211_tx_rate *rates = tx_info->control.rates;669669 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;670670 __le16 fc = hdr->frame_control;671671- u8 try_per_rate, i = 0, rix, nrix;671671+ u8 try_per_rate, i = 0, rix;672672 int is_probe = 0;673673674674 if (rate_control_send_low(sta, priv_sta, txrc))···688688689689 rate_table = sc->cur_rate_table;690690 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);691691- nrix = rix;692691693692 if (is_probe) {694693 /* set one try for probe rates. For the695694 * probes don't enable rts */696695 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,697697- 1, nrix, 0);696696+ 1, rix, 0);698697699698 /* Get the next tried/allowed rate. No RTS for the next series700699 * after the probe rate701700 */702702- ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);701701+ ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);703702 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,704704- try_per_rate, nrix, 0);703703+ try_per_rate, rix, 0);705704706705 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;707706 } else {708707 /* Set the choosen rate. No RTS for first series entry. */709708 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,710710- try_per_rate, nrix, 0);709709+ try_per_rate, rix, 0);711710 }712711713712 /* Fill in the other rates for multirate retry */···715716 if (i + 1 == 4)716717 try_per_rate = 8;717718718718- ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);719719+ ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);719720 /* All other rates in the series have RTS enabled */720721 ath_rc_rate_set_series(rate_table, &rates[i], txrc,721721- try_per_rate, nrix, 1);722722+ try_per_rate, rix, 1);722723 }723724724725 /*
+1-1
drivers/net/wireless/b43legacy/leds.h
···4545void b43legacy_leds_init(struct b43legacy_wldev *dev);4646void b43legacy_leds_exit(struct b43legacy_wldev *dev);47474848-#else /* CONFIG_B43EGACY_LEDS */4848+#else /* CONFIG_B43LEGACY_LEDS */4949/* LED support disabled */50505151struct b43legacy_led {
···581581582582 iwl4965_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);583583584584+ /* make sure all queue are not stopped */585585+ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));586586+ for (i = 0; i < 4; i++)587587+ atomic_set(&priv->queue_stop_count[i], 0);588588+589589+ /* reset to 0 to enable all the queue first */590590+ priv->txq_ctx_active_msk = 0;584591 /* Map each Tx/cmd queue to its corresponding fifo */585592 for (i = 0; i < ARRAY_SIZE(default_queue_to_tx_fifo); i++) {586593 int ac = default_queue_to_tx_fifo[i];
+7
drivers/net/wireless/iwlwifi/iwl-5000.c
···648648649649 iwl5000_set_wr_ptrs(priv, IWL_CMD_QUEUE_NUM, 0);650650651651+ /* make sure all queue are not stopped */652652+ memset(&priv->queue_stopped[0], 0, sizeof(priv->queue_stopped));653653+ for (i = 0; i < 4; i++)654654+ atomic_set(&priv->queue_stop_count[i], 0);655655+656656+ /* reset to 0 to enable all the queue first */657657+ priv->txq_ctx_active_msk = 0;651658 /* map qos queues to fifos one-to-one */652659 for (i = 0; i < ARRAY_SIZE(iwl5000_default_queue_to_tx_fifo); i++) {653660 int ac = iwl5000_default_queue_to_tx_fifo[i];
···298298 struct iwl_lq_sta *lq_data, u8 tid,299299 struct ieee80211_sta *sta)300300{301301+ int ret;302302+301303 if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) {302304 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",303305 sta->addr, tid);304304- ieee80211_start_tx_ba_session(sta, tid);306306+ ret = ieee80211_start_tx_ba_session(sta, tid);307307+ if (ret == -EAGAIN) {308308+ /*309309+ * driver and mac80211 is out of sync310310+ * this might be cause by reloading firmware311311+ * stop the tx ba session here312312+ */313313+ IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n",314314+ tid);315315+ ret = ieee80211_stop_tx_ba_session(sta, tid,316316+ WLAN_BACK_INITIATOR);317317+ }305318 }306319}307320
+28-1
drivers/net/wireless/iwlwifi/iwl-agn.c
···29412941 return ret;29422942 case IEEE80211_AMPDU_TX_START:29432943 IWL_DEBUG_HT(priv, "start Tx\n");29442944- return iwl_tx_agg_start(priv, sta->addr, tid, ssn);29442944+ ret = iwl_tx_agg_start(priv, sta->addr, tid, ssn);29452945+ if (ret == 0) {29462946+ priv->agg_tids_count++;29472947+ IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",29482948+ priv->agg_tids_count);29492949+ }29502950+ return ret;29452951 case IEEE80211_AMPDU_TX_STOP:29462952 IWL_DEBUG_HT(priv, "stop Tx\n");29472953 ret = iwl_tx_agg_stop(priv, sta->addr, tid);29542954+ if ((ret == 0) && (priv->agg_tids_count > 0)) {29552955+ priv->agg_tids_count--;29562956+ IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",29572957+ priv->agg_tids_count);29582958+ }29482959 if (test_bit(STATUS_EXIT_PENDING, &priv->status))29492960 return 0;29502961 else···33643353 INIT_LIST_HEAD(&priv->free_frames);3365335433663355 mutex_init(&priv->mutex);33563356+ mutex_init(&priv->sync_cmd_mutex);3367335733683358 /* Clear the driver's (not device's) station table */33693359 iwl_clear_stations_table(priv);···33763364 priv->iw_mode = NL80211_IFTYPE_STATION;33773365 priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;33783366 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;33673367+ priv->agg_tids_count = 0;33683368+33693369+ /* initialize force reset */33703370+ priv->force_reset[IWL_RF_RESET].reset_duration =33713371+ IWL_DELAY_NEXT_FORCE_RF_RESET;33723372+ priv->force_reset[IWL_FW_RESET].reset_duration =33733373+ IWL_DELAY_NEXT_FORCE_FW_RELOAD;3379337433803375 /* Choose which receivers/antennas to use */33813376 if (priv->cfg->ops->hcmd->set_rxon_chain)···35593540 */35603541 spin_lock_init(&priv->reg_lock);35613542 spin_lock_init(&priv->lock);35433543+35443544+ /*35453545+ * stop and reset the on-board processor just in case it is in a35463546+ * strange state ... like being left stranded by a primary kernel35473547+ * and this is now the kdump kernel trying to start up35483548+ */35493549+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);35503550+35623551 iwl_hw_detect(priv);35633552 IWL_INFO(priv, "Detected Intel Wireless WiFi Link %s REV=0x%X\n",35643553 priv->cfg->name, priv->hw_rev);
···10331033#define IWL_MAX_PLCP_ERR_THRESHOLD_MIN (0)10341034#define IWL_MAX_PLCP_ERR_THRESHOLD_DEF (50)10351035#define IWL_MAX_PLCP_ERR_LONG_THRESHOLD_DEF (100)10361036+#define IWL_MAX_PLCP_ERR_EXT_LONG_THRESHOLD_DEF (200)10361037#define IWL_MAX_PLCP_ERR_THRESHOLD_MAX (255)10381038+10391039+#define IWL_DELAY_NEXT_FORCE_RF_RESET (HZ*3)10401040+#define IWL_DELAY_NEXT_FORCE_FW_RELOAD (HZ*5)10411041+10421042+enum iwl_reset {10431043+ IWL_RF_RESET = 0,10441044+ IWL_FW_RESET,10451045+ IWL_MAX_FORCE_RESET,10461046+};10471047+10481048+struct iwl_force_reset {10491049+ int reset_request_count;10501050+ int reset_success_count;10511051+ int reset_reject_count;10521052+ unsigned long reset_duration;10531053+ unsigned long last_force_reset_jiffies;10541054+};1037105510381056struct iwl_priv {10391057···10841066 /* storing the jiffies when the plcp error rate is received */10851067 unsigned long plcp_jiffies;1086106810691069+ /* reporting the number of tids has AGG on. 0 means no AGGREGATION */10701070+ u8 agg_tids_count;10711071+10721072+ /* force reset */10731073+ struct iwl_force_reset force_reset[IWL_MAX_FORCE_RESET];10741074+10871075 /* we allocate array of iwl4965_channel_info for NIC's valid channels.10881076 * Access via channel # using indirect index array */10891077 struct iwl_channel_info *channel_info; /* channel info array */···11111087 unsigned long scan_start;11121088 unsigned long scan_pass_start;11131089 unsigned long scan_start_tsf;11141114- unsigned long last_internal_scan_jiffies;11151090 void *scan;11161091 int scan_bands;11171092 struct cfg80211_scan_request *scan_request;···11231100 spinlock_t hcmd_lock; /* protect hcmd */11241101 spinlock_t reg_lock; /* protect hw register access */11251102 struct mutex mutex;11031103+ struct mutex sync_cmd_mutex; /* enable serialization of sync commands */1126110411271105 /* basic pci-network driver stuff */11281106 struct pci_dev *pci_dev;
+7-7
drivers/net/wireless/iwlwifi/iwl-hcmd.c
···164164 /* A synchronous command can not have a callback set. */165165 BUG_ON(cmd->callback);166166167167- if (test_and_set_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status)) {168168- IWL_ERR(priv,169169- "Error sending %s: Already sending a host command\n",167167+ IWL_DEBUG_INFO(priv, "Attempting to send sync command %s\n",170168 get_cmd_string(cmd->id));171171- ret = -EBUSY;172172- goto out;173173- }169169+ mutex_lock(&priv->sync_cmd_mutex);174170175171 set_bit(STATUS_HCMD_ACTIVE, &priv->status);172172+ IWL_DEBUG_INFO(priv, "Setting HCMD_ACTIVE for command %s \n",173173+ get_cmd_string(cmd->id));176174177175 cmd_idx = iwl_enqueue_hcmd(priv, cmd);178176 if (cmd_idx < 0) {···191193 jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));192194193195 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);196196+ IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",197197+ get_cmd_string(cmd->id));194198 ret = -ETIMEDOUT;195199 goto cancel;196200 }···237237 cmd->reply_page = 0;238238 }239239out:240240- clear_bit(STATUS_HCMD_SYNC_ACTIVE, &priv->status);240240+ mutex_unlock(&priv->sync_cmd_mutex);241241 return ret;242242}243243EXPORT_SYMBOL(iwl_send_cmd_sync);
···123123/**124124 * iwl_rx_queue_update_write_ptr - Update the write pointer for the RX queue125125 */126126-int iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)126126+void iwl_rx_queue_update_write_ptr(struct iwl_priv *priv, struct iwl_rx_queue *q)127127{128128 unsigned long flags;129129 u32 rx_wrt_ptr_reg = priv->hw_params.rx_wrt_ptr_reg;130130 u32 reg;131131- int ret = 0;132131133132 spin_lock_irqsave(&q->lock, flags);134133···160161161162 exit_unlock:162163 spin_unlock_irqrestore(&q->lock, flags);163163- return ret;164164}165165EXPORT_SYMBOL(iwl_rx_queue_update_write_ptr);166166/**···182184 * also updates the memory address in the firmware to reference the new183185 * target buffer.184186 */185185-int iwl_rx_queue_restock(struct iwl_priv *priv)187187+void iwl_rx_queue_restock(struct iwl_priv *priv)186188{187189 struct iwl_rx_queue *rxq = &priv->rxq;188190 struct list_head *element;189191 struct iwl_rx_mem_buffer *rxb;190192 unsigned long flags;191193 int write;192192- int ret = 0;193194194195 spin_lock_irqsave(&rxq->lock, flags);195196 write = rxq->write & ~0x7;···217220 spin_lock_irqsave(&rxq->lock, flags);218221 rxq->need_update = 1;219222 spin_unlock_irqrestore(&rxq->lock, flags);220220- ret = iwl_rx_queue_update_write_ptr(priv, rxq);223223+ iwl_rx_queue_update_write_ptr(priv, rxq);221224 }222222-223223- return ret;224225}225226EXPORT_SYMBOL(iwl_rx_queue_restock);226227···345350 }346351 }347352348348- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,349349- rxq->dma_addr);350350- pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),351351- rxq->rb_stts, rxq->rb_stts_dma);353353+ dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,354354+ rxq->dma_addr);355355+ dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),356356+ rxq->rb_stts, rxq->rb_stts_dma);352357 rxq->bd = NULL;353358 rxq->rb_stts = NULL;354359}···357362int iwl_rx_queue_alloc(struct iwl_priv *priv)358363{359364 struct iwl_rx_queue *rxq = &priv->rxq;360360- struct pci_dev *dev = priv->pci_dev;365365+ struct device *dev = &priv->pci_dev->dev;361366 int i;362367363368 spin_lock_init(&rxq->lock);···365370 INIT_LIST_HEAD(&rxq->rx_used);366371367372 /* Alloc the circular buffer of Read Buffer Descriptors (RBDs) */368368- rxq->bd = pci_alloc_consistent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr);373373+ rxq->bd = dma_alloc_coherent(dev, 4 * RX_QUEUE_SIZE, &rxq->dma_addr,374374+ GFP_KERNEL);369375 if (!rxq->bd)370376 goto err_bd;371377372372- rxq->rb_stts = pci_alloc_consistent(dev, sizeof(struct iwl_rb_status),373373- &rxq->rb_stts_dma);378378+ rxq->rb_stts = dma_alloc_coherent(dev, sizeof(struct iwl_rb_status),379379+ &rxq->rb_stts_dma, GFP_KERNEL);374380 if (!rxq->rb_stts)375381 goto err_rb;376382···388392 return 0;389393390394err_rb:391391- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,392392- rxq->dma_addr);395395+ dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,396396+ rxq->dma_addr);393397err_bd:394398 return -ENOMEM;395399}···616620617621#define REG_RECALIB_PERIOD (60)618622623623+/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */624624+#define ACK_CNT_RATIO (50)625625+#define BA_TIMEOUT_CNT (5)626626+#define BA_TIMEOUT_MAX (16)627627+619628#define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"620629void iwl_rx_statistics(struct iwl_priv *priv,621630 struct iwl_rx_mem_buffer *rxb)···630629 int combined_plcp_delta;631630 unsigned int plcp_msec;632631 unsigned long plcp_received_jiffies;632632+ int actual_ack_cnt_delta;633633+ int expected_ack_cnt_delta;634634+ int ba_timeout_delta;633635634636 IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",635637 (int)sizeof(priv->statistics),···647643#ifdef CONFIG_IWLWIFI_DEBUG648644 iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);649645#endif646646+ actual_ack_cnt_delta = le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -647647+ le32_to_cpu(priv->statistics.tx.actual_ack_cnt);648648+ expected_ack_cnt_delta = le32_to_cpu(649649+ pkt->u.stats.tx.expected_ack_cnt) -650650+ le32_to_cpu(priv->statistics.tx.expected_ack_cnt);651651+ ba_timeout_delta = le32_to_cpu(652652+ pkt->u.stats.tx.agg.ba_timeout) -653653+ le32_to_cpu(priv->statistics.tx.agg.ba_timeout);654654+ if ((priv->agg_tids_count > 0) &&655655+ (expected_ack_cnt_delta > 0) &&656656+ (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) <657657+ ACK_CNT_RATIO) &&658658+ (ba_timeout_delta > BA_TIMEOUT_CNT)) {659659+ IWL_DEBUG_RADIO(priv,660660+ "actual_ack_cnt delta = %d, expected_ack_cnt = %d\n",661661+ actual_ack_cnt_delta, expected_ack_cnt_delta);662662+663663+#ifdef CONFIG_IWLWIFI_DEBUG664664+ IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",665665+ priv->delta_statistics.tx.rx_detected_cnt);666666+ IWL_DEBUG_RADIO(priv,667667+ "ack_or_ba_timeout_collision delta = %d\n",668668+ priv->delta_statistics.tx.ack_or_ba_timeout_collision);669669+#endif670670+ IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",671671+ ba_timeout_delta);672672+ if ((actual_ack_cnt_delta == 0) &&673673+ (ba_timeout_delta >=674674+ BA_TIMEOUT_MAX)) {675675+ IWL_DEBUG_RADIO(priv,676676+ "call iwl_force_reset(IWL_FW_RESET)\n");677677+ iwl_force_reset(priv, IWL_FW_RESET);678678+ } else {679679+ IWL_DEBUG_RADIO(priv,680680+ "call iwl_force_reset(IWL_RF_RESET)\n");681681+ iwl_force_reset(priv, IWL_RF_RESET);682682+ }683683+ }650684 /*651685 * check for plcp_err and trigger radio reset if it exceeds652686 * the plcp error threshold plcp_delta.···731689 * Reset the RF radio due to the high plcp732690 * error rate733691 */734734- iwl_force_rf_reset(priv);692692+ iwl_force_reset(priv, IWL_RF_RESET);735693 }736694 }737695
+12-25
drivers/net/wireless/iwlwifi/iwl-scan.c
···250250251251 if (!priv->is_internal_short_scan)252252 priv->next_scan_jiffies = 0;253253- else254254- priv->last_internal_scan_jiffies = jiffies;255253256254 IWL_DEBUG_INFO(priv, "Setting scan to off\n");257255···469471470472static int iwl_scan_initiate(struct iwl_priv *priv)471473{472472- if (!iwl_is_ready_rf(priv)) {473473- IWL_DEBUG_SCAN(priv, "Aborting scan due to not ready.\n");474474- return -EIO;475475- }476476-477477- if (test_bit(STATUS_SCANNING, &priv->status)) {478478- IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");479479- return -EAGAIN;480480- }481481-482482- if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {483483- IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");484484- return -EAGAIN;485485- }486486-487474 IWL_DEBUG_INFO(priv, "Starting scan...\n");488475 set_bit(STATUS_SCANNING, &priv->status);489476 priv->is_internal_short_scan = false;···497514 if (!iwl_is_ready_rf(priv)) {498515 ret = -EIO;499516 IWL_DEBUG_MAC80211(priv, "leave - not ready or exit pending\n");517517+ goto out_unlock;518518+ }519519+520520+ if (test_bit(STATUS_SCANNING, &priv->status)) {521521+ IWL_DEBUG_SCAN(priv, "Scan already in progress.\n");522522+ ret = -EAGAIN;523523+ goto out_unlock;524524+ }525525+526526+ if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {527527+ IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");528528+ ret = -EAGAIN;500529 goto out_unlock;501530 }502531···546551 * internal short scan, this function should only been called while associated.547552 * It will reset and tune the radio to prevent possible RF related problem548553 */549549-#define IWL_DELAY_NEXT_INTERNAL_SCAN (HZ*1)550550-551554int iwl_internal_short_hw_scan(struct iwl_priv *priv)552555{553556 int ret = 0;···563570 if (test_bit(STATUS_SCAN_ABORTING, &priv->status)) {564571 IWL_DEBUG_SCAN(priv, "Scan request while abort pending\n");565572 ret = -EAGAIN;566566- goto out;567567- }568568- if (priv->last_internal_scan_jiffies &&569569- time_after(priv->last_internal_scan_jiffies +570570- IWL_DELAY_NEXT_INTERNAL_SCAN, jiffies)) {571571- IWL_DEBUG_SCAN(priv, "internal scan rejected\n");572573 goto out;573574 }574575
+33-31
drivers/net/wireless/iwlwifi/iwl-tx.c
···6060static inline int iwl_alloc_dma_ptr(struct iwl_priv *priv,6161 struct iwl_dma_ptr *ptr, size_t size)6262{6363- ptr->addr = pci_alloc_consistent(priv->pci_dev, size, &ptr->dma);6363+ ptr->addr = dma_alloc_coherent(&priv->pci_dev->dev, size, &ptr->dma,6464+ GFP_KERNEL);6465 if (!ptr->addr)6566 return -ENOMEM;6667 ptr->size = size;···7473 if (unlikely(!ptr->addr))7574 return;76757777- pci_free_consistent(priv->pci_dev, ptr->size, ptr->addr, ptr->dma);7676+ dma_free_coherent(&priv->pci_dev->dev, ptr->size, ptr->addr, ptr->dma);7877 memset(ptr, 0, sizeof(*ptr));7978}80798180/**8281 * iwl_txq_update_write_ptr - Send new write index to hardware8382 */8484-int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)8383+void iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq)8584{8685 u32 reg = 0;8787- int ret = 0;8886 int txq_id = txq->q.id;89879088 if (txq->need_update == 0)9191- return ret;8989+ return;92909391 /* if we're trying to save power */9492 if (test_bit(STATUS_POWER_PMI, &priv->status)) {···101101 txq_id, reg);102102 iwl_set_bit(priv, CSR_GP_CNTRL,103103 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);104104- return ret;104104+ return;105105 }106106107107 iwl_write_direct32(priv, HBUS_TARG_WRPTR,···114114 txq->q.write_ptr | (txq_id << 8));115115116116 txq->need_update = 0;117117-118118- return ret;119117}120118EXPORT_SYMBOL(iwl_txq_update_write_ptr);121119···144146{145147 struct iwl_tx_queue *txq = &priv->txq[txq_id];146148 struct iwl_queue *q = &txq->q;147147- struct pci_dev *dev = priv->pci_dev;149149+ struct device *dev = &priv->pci_dev->dev;148150 int i;149151150152 if (q->n_bd == 0)···161163162164 /* De-alloc circular buffer of TFDs */163165 if (txq->q.n_bd)164164- pci_free_consistent(dev, priv->hw_params.tfd_size *165165- txq->q.n_bd, txq->tfds, txq->q.dma_addr);166166+ dma_free_coherent(dev, priv->hw_params.tfd_size *167167+ txq->q.n_bd, txq->tfds, txq->q.dma_addr);166168167169 /* De-alloc array of per-TFD driver data */168170 kfree(txq->txb);···191193{192194 struct iwl_tx_queue *txq = &priv->txq[IWL_CMD_QUEUE_NUM];193195 struct iwl_queue *q = &txq->q;194194- struct pci_dev *dev = priv->pci_dev;196196+ struct device *dev = &priv->pci_dev->dev;195197 int i;196198197199 if (q->n_bd == 0)···203205204206 /* De-alloc circular buffer of TFDs */205207 if (txq->q.n_bd)206206- pci_free_consistent(dev, priv->hw_params.tfd_size *207207- txq->q.n_bd, txq->tfds, txq->q.dma_addr);208208+ dma_free_coherent(dev, priv->hw_params.tfd_size * txq->q.n_bd,209209+ txq->tfds, txq->q.dma_addr);208210209211 /* deallocate arrays */210212 kfree(txq->cmd);···295297static int iwl_tx_queue_alloc(struct iwl_priv *priv,296298 struct iwl_tx_queue *txq, u32 id)297299{298298- struct pci_dev *dev = priv->pci_dev;300300+ struct device *dev = &priv->pci_dev->dev;299301 size_t tfd_sz = priv->hw_params.tfd_size * TFD_QUEUE_SIZE_MAX;300302301303 /* Driver private data, only for Tx (not command) queues,···314316315317 /* Circular buffer of transmit frame descriptors (TFDs),316318 * shared with device */317317- txq->tfds = pci_alloc_consistent(dev, tfd_sz, &txq->q.dma_addr);318318-319319+ txq->tfds = dma_alloc_coherent(dev, tfd_sz, &txq->q.dma_addr,320320+ GFP_KERNEL);319321 if (!txq->tfds) {320322 IWL_ERR(priv, "pci_alloc_consistent(%zd) failed\n", tfd_sz);321323 goto error;···743745 u8 tid = 0;744746 u8 *qc = NULL;745747 unsigned long flags;746746- int ret;747748748749 spin_lock_irqsave(&priv->lock, flags);749750 if (iwl_is_rfkill(priv)) {···817820 hdr->seq_ctrl |= cpu_to_le16(seq_number);818821 seq_number += 0x10;819822 /* aggregation is on for this <sta,tid> */820820- if (info->flags & IEEE80211_TX_CTL_AMPDU)823823+ if (info->flags & IEEE80211_TX_CTL_AMPDU &&824824+ priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) {821825 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id;826826+ }822827 }823828824829 txq = &priv->txq[txq_id];···962963963964 /* Tell device the write index *just past* this latest filled TFD */964965 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);965965- ret = iwl_txq_update_write_ptr(priv, txq);966966+ iwl_txq_update_write_ptr(priv, txq);966967 spin_unlock_irqrestore(&priv->lock, flags);967968968969 /*···975976 /* avoid atomic ops if it isn't an associated client */976977 if (sta_priv && sta_priv->client)977978 atomic_inc(&sta_priv->pending_frames);978978-979979- if (ret)980980- return ret;981979982980 if ((iwl_queue_space(q) < q->high_mark) && priv->mac80211_registered) {983981 if (wait_write_ptr) {···10141018 struct iwl_cmd_meta *out_meta;10151019 dma_addr_t phys_addr;10161020 unsigned long flags;10171017- int len, ret;10211021+ int len;10181022 u32 idx;10191023 u16 fix_size;10201024···1111111511121116 /* Increment and update queue's write index */11131117 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);11141114- ret = iwl_txq_update_write_ptr(priv, txq);11181118+ iwl_txq_update_write_ptr(priv, txq);1115111911161120 spin_unlock_irqrestore(&priv->hcmd_lock, flags);11171117- return ret ? ret : idx;11211121+ return idx;11181122}1119112311201124static void iwl_tx_status(struct iwl_priv *priv, struct sk_buff *skb)···1256126012571261 if (!(meta->flags & CMD_ASYNC)) {12581262 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);12631263+ IWL_DEBUG_INFO(priv, "Clearing HCMD_ACTIVE for command %s \n",12641264+ get_cmd_string(cmd->hdr.cmd));12591265 wake_up_interruptible(&priv->wait_command_queue);12601266 }12611267}···13441346{13451347 int tx_fifo_id, txq_id, sta_id, ssn = -1;13461348 struct iwl_tid_data *tid_data;13471347- int ret, write_ptr, read_ptr;13491349+ int write_ptr, read_ptr;13481350 unsigned long flags;1349135113501352 if (!ra) {···13961398 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;1397139913981400 spin_lock_irqsave(&priv->lock, flags);13991399- ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,14011401+ /*14021402+ * the only reason this call can fail is queue number out of range,14031403+ * which can happen if uCode is reloaded and all the station14041404+ * information are lost. if it is outside the range, there is no need14051405+ * to deactivate the uCode queue, just return "success" to allow14061406+ * mac80211 to clean up it own data.14071407+ */14081408+ priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn,14001409 tx_fifo_id);14011410 spin_unlock_irqrestore(&priv->lock, flags);14021402-14031403- if (ret)14041404- return ret;1405141114061412 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid);14071413
+21-21
drivers/net/wireless/iwlwifi/iwl3945-base.c
···5353#include "iwl-commands.h"5454#include "iwl-sta.h"5555#include "iwl-3945.h"5656-#include "iwl-helpers.h"5756#include "iwl-core.h"5757+#include "iwl-helpers.h"5858#include "iwl-dev.h"5959#include "iwl-spectrum.h"6060···352352static void iwl3945_unset_hw_params(struct iwl_priv *priv)353353{354354 if (priv->shared_virt)355355- pci_free_consistent(priv->pci_dev,356356- sizeof(struct iwl3945_shared),357357- priv->shared_virt,358358- priv->shared_phys);355355+ dma_free_coherent(&priv->pci_dev->dev,356356+ sizeof(struct iwl3945_shared),357357+ priv->shared_virt,358358+ priv->shared_phys);359359}360360361361static void iwl3945_build_tx_cmd_hwcrypto(struct iwl_priv *priv,···478478 u8 wait_write_ptr = 0;479479 u8 *qc = NULL;480480 unsigned long flags;481481- int rc;482481483482 spin_lock_irqsave(&priv->lock, flags);484483 if (iwl_is_rfkill(priv)) {···662663663664 /* Tell device the write index *just past* this latest filled TFD */664665 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd);665665- rc = iwl_txq_update_write_ptr(priv, txq);666666+ iwl_txq_update_write_ptr(priv, txq);666667 spin_unlock_irqrestore(&priv->lock, flags);667667-668668- if (rc)669669- return rc;670668671669 if ((iwl_queue_space(q) < q->high_mark)672670 && priv->mac80211_registered) {···10591063 * also updates the memory address in the firmware to reference the new10601064 * target buffer.10611065 */10621062-static int iwl3945_rx_queue_restock(struct iwl_priv *priv)10661066+static void iwl3945_rx_queue_restock(struct iwl_priv *priv)10631067{10641068 struct iwl_rx_queue *rxq = &priv->rxq;10651069 struct list_head *element;10661070 struct iwl_rx_mem_buffer *rxb;10671071 unsigned long flags;10681068- int write, rc;10721072+ int write;1069107310701074 spin_lock_irqsave(&rxq->lock, flags);10711075 write = rxq->write & ~0x7;···10951099 spin_lock_irqsave(&rxq->lock, flags);10961100 rxq->need_update = 1;10971101 spin_unlock_irqrestore(&rxq->lock, flags);10981098- rc = iwl_rx_queue_update_write_ptr(priv, rxq);10991099- if (rc)11001100- return rc;11021102+ iwl_rx_queue_update_write_ptr(priv, rxq);11011103 }11021102-11031103- return 0;11041104}1105110511061106/**···12411249 }12421250 }1243125112441244- pci_free_consistent(priv->pci_dev, 4 * RX_QUEUE_SIZE, rxq->bd,12451245- rxq->dma_addr);12461246- pci_free_consistent(priv->pci_dev, sizeof(struct iwl_rb_status),12471247- rxq->rb_stts, rxq->rb_stts_dma);12521252+ dma_free_coherent(&priv->pci_dev->dev, 4 * RX_QUEUE_SIZE, rxq->bd,12531253+ rxq->dma_addr);12541254+ dma_free_coherent(&priv->pci_dev->dev, sizeof(struct iwl_rb_status),12551255+ rxq->rb_stts, rxq->rb_stts_dma);12481256 rxq->bd = NULL;12491257 rxq->rb_stts = NULL;12501258}···38473855 INIT_LIST_HEAD(&priv->free_frames);3848385638493857 mutex_init(&priv->mutex);38583858+ mutex_init(&priv->sync_cmd_mutex);3850385938513860 /* Clear the driver's (not device's) station table */38523861 iwl_clear_stations_table(priv);···40394046 */40404047 spin_lock_init(&priv->reg_lock);40414048 spin_lock_init(&priv->lock);40494049+40504050+ /*40514051+ * stop and reset the on-board processor just in case it is in a40524052+ * strange state ... like being left stranded by a primary kernel40534053+ * and this is now the kdump kernel trying to start up40544054+ */40554055+ iwl_write32(priv, CSR_RESET, CSR_RESET_REG_FLAG_NEVO_RESET);4042405640434057 /***********************40444058 * 4. Read EEPROM
+26-6
drivers/net/wireless/mac80211_hwsim.c
···771771 }772772}773773774774+static int mac80211_hwsim_sta_add(struct ieee80211_hw *hw,775775+ struct ieee80211_vif *vif,776776+ struct ieee80211_sta *sta)777777+{778778+ hwsim_check_magic(vif);779779+ hwsim_set_sta_magic(sta);780780+781781+ return 0;782782+}783783+784784+static int mac80211_hwsim_sta_remove(struct ieee80211_hw *hw,785785+ struct ieee80211_vif *vif,786786+ struct ieee80211_sta *sta)787787+{788788+ hwsim_check_magic(vif);789789+ hwsim_clear_sta_magic(sta);790790+791791+ return 0;792792+}793793+774794static void mac80211_hwsim_sta_notify(struct ieee80211_hw *hw,775795 struct ieee80211_vif *vif,776796 enum sta_notify_cmd cmd,777797 struct ieee80211_sta *sta)778798{779799 hwsim_check_magic(vif);800800+780801 switch (cmd) {781781- case STA_NOTIFY_ADD:782782- hwsim_set_sta_magic(sta);783783- break;784784- case STA_NOTIFY_REMOVE:785785- hwsim_clear_sta_magic(sta);786786- break;787802 case STA_NOTIFY_SLEEP:788803 case STA_NOTIFY_AWAKE:789804 /* TODO: make good use of these flags */805805+ break;806806+ default:807807+ WARN(1, "Invalid sta notify: %d\n", cmd);790808 break;791809 }792810}···976958 .config = mac80211_hwsim_config,977959 .configure_filter = mac80211_hwsim_configure_filter,978960 .bss_info_changed = mac80211_hwsim_bss_info_changed,961961+ .sta_add = mac80211_hwsim_sta_add,962962+ .sta_remove = mac80211_hwsim_sta_remove,979963 .sta_notify = mac80211_hwsim_sta_notify,980964 .set_tim = mac80211_hwsim_set_tim,981965 .conf_tx = mac80211_hwsim_conf_tx,
···186186 struct p54_tx_queue_stats *queue;187187 unsigned long flags;188188189189- if (WARN_ON(p54_queue > P54_QUEUE_NUM))189189+ if (WARN_ON(p54_queue >= P54_QUEUE_NUM))190190 return -EINVAL;191191192192 queue = &priv->tx_stats[p54_queue];
+65-2
drivers/net/wireless/rt2x00/Kconfig
···6464 default y65656666config RT2800PCI6767- tristate "Ralink rt2800 (PCI/PCMCIA) support (VERY EXPERIMENTAL)"6767+ tristate "Ralink rt28xx/rt30xx/rt35xx (PCI/PCIe/PCMCIA) support (EXPERIMENTAL)"6868 depends on (RT2800PCI_PCI || RT2800PCI_SOC) && EXPERIMENTAL6969 select RT2800_LIB7070 select RT2X00_LIB_PCI if RT2800PCI_PCI···7575 select CRC_CCITT7676 select EEPROM_93CX67777 ---help---7878- This adds support for rt2800 wireless chipset family.7878+ This adds support for rt2800/rt3000/rt3500 wireless chipset family.7979 Supported chips: RT2760, RT2790, RT2860, RT2880, RT2890 & RT305280808181 This driver is non-functional at the moment and is intended for8282 developers.83838484 When compiled as a module, this driver will be called "rt2800pci.ko".8585+8686+if RT2800PCI8787+8888+config RT2800PCI_RT30XX8989+ bool "rt2800pci - Include support for rt30xx (PCI/PCIe/PCMCIA) devices"9090+ default n9191+ ---help---9292+ This adds support for rt30xx wireless chipset family to the9393+ rt2800pci driver.9494+ Supported chips: RT3090, RT3091 & RT30929595+9696+ Support for these devices is non-functional at the moment and is9797+ intended for testers and developers.9898+9999+config RT2800PCI_RT35XX100100+ bool "rt2800pci - Include support for rt35xx (PCI/PCIe/PCMCIA) devices"101101+ default n102102+ ---help---103103+ This adds support for rt35xx wireless chipset family to the104104+ rt2800pci driver.105105+ Supported chips: RT3060, RT3062, RT3562, RT3592106106+107107+ Support for these devices is non-functional at the moment and is108108+ intended for testers and developers.109109+110110+endif8511186112config RT2500USB87113 tristate "Ralink rt2500 (USB) support"···151125 - support for RT3070 chips is non-functional at the moment152126153127 When compiled as a module, this driver will be called "rt2800usb.ko".128128+129129+if RT2800USB130130+131131+config RT2800USB_RT30XX132132+ bool "rt2800usb - Include support for rt30xx (USB) devices"133133+ default n134134+ ---help---135135+ This adds support for rt30xx wireless chipset family to the136136+ rt2800usb driver.137137+ Supported chips: RT3070, RT3071 & RT3072138138+139139+ Support for these devices is non-functional at the moment and is140140+ intended for testers and developers.141141+142142+config RT2800USB_RT35XX143143+ bool "rt2800usb - Include support for rt35xx (USB) devices"144144+ default n145145+ ---help---146146+ This adds support for rt35xx wireless chipset family to the147147+ rt2800usb driver.148148+ Supported chips: RT3572149149+150150+ Support for these devices is non-functional at the moment and is151151+ intended for testers and developers.152152+153153+config RT2800USB_UNKNOWN154154+ bool "rt2800usb - Include support for unknown (USB) devices"155155+ default n156156+ ---help---157157+ This adds support for rt2800 family devices that are known to158158+ have a rt2800 family chipset, but for which the exact chipset159159+ is unknown.160160+161161+ Support status for these devices is unknown, and enabling these162162+ devices may or may not work.163163+164164+endif154165155166config RT2800_LIB156167 tristate
···735735 CONF_DUAL_BAND736736};737737738738-739739-#define CONF_MAX_SMART_REFLEX_PARAMS 16740740-741741-struct conf_general_parms {742742- /*743743- * RF Reference Clock type / speed744744- *745745- * Range: CONF_REF_CLK_*746746- */747747- u8 ref_clk;748748-749749- /*750750- * Settling time of the reference clock after boot.751751- *752752- * Range: u8753753- */754754- u8 settling_time;755755-756756- /*757757- * Flag defining whether clock is valid on wakeup.758758- *759759- * Range: 0 - not valid on wakeup, 1 - valid on wakeup760760- */761761- u8 clk_valid_on_wakeup;762762-763763- /*764764- * DC-to-DC mode.765765- *766766- * Range: Unknown767767- */768768- u8 dc2dcmode;769769-770770- /*771771- * Flag defining whether used as single or dual-band.772772- *773773- * Range: CONF_SINGLE_BAND, CONF_DUAL_BAND774774- */775775- u8 single_dual_band;776776-777777- /*778778- * TX bip fem autodetect flag.779779- *780780- * Range: Unknown781781- */782782- u8 tx_bip_fem_autodetect;783783-784784- /*785785- * TX bip gem manufacturer.786786- *787787- * Range: Unknown788788- */789789- u8 tx_bip_fem_manufacturer;790790-791791- /*792792- * Settings flags.793793- *794794- * Range: Unknown795795- */796796- u8 settings;797797-798798- /* Smart reflex settings */799799- u8 sr_state;800800-801801- s8 srf1[CONF_MAX_SMART_REFLEX_PARAMS];802802- s8 srf2[CONF_MAX_SMART_REFLEX_PARAMS];803803- s8 srf3[CONF_MAX_SMART_REFLEX_PARAMS];804804-805805- s8 sr_debug_table[CONF_MAX_SMART_REFLEX_PARAMS];806806-807807- u8 sr_sen_n_p;808808- u8 sr_sen_n_p_gain;809809- u8 sr_sen_nrn;810810- u8 sr_sen_prn;811811-};812812-813738#define CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE 15814739#define CONF_NUMBER_OF_SUB_BANDS_5 7815740#define CONF_NUMBER_OF_RATE_GROUPS 6···743818744819struct conf_radio_parms {745820 /*746746- * Static radio parameters for 2.4GHz821821+ * FEM parameter set to use747822 *748748- * Range: unknown823823+ * Range: 0 or 1749824 */750750- u8 rx_trace_loss;751751- u8 tx_trace_loss;752752- s8 rx_rssi_and_proc_compens[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];753753-754754- /*755755- * Static radio parameters for 5GHz756756- *757757- * Range: unknown758758- */759759- u8 rx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];760760- u8 tx_trace_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];761761- s8 rx_rssi_and_proc_compens_5[CONF_RSSI_AND_PROCESS_COMPENSATION_SIZE];762762-763763- /*764764- * Dynamic radio parameters for 2.4GHz765765- *766766- * Range: unknown767767- */768768- u16 tx_ref_pd_voltage;769769- u8 tx_ref_power;770770- s8 tx_offset_db;771771-772772- s8 tx_rate_limits_normal[CONF_NUMBER_OF_RATE_GROUPS];773773- s8 tx_rate_limits_degraded[CONF_NUMBER_OF_RATE_GROUPS];774774- s8 tx_rate_limits_extreme[CONF_NUMBER_OF_RATE_GROUPS];775775-776776- s8 tx_channel_limits_11b[CONF_NUMBER_OF_CHANNELS_2_4];777777- s8 tx_channel_limits_ofdm[CONF_NUMBER_OF_CHANNELS_2_4];778778- s8 tx_pdv_rate_offsets[CONF_NUMBER_OF_RATE_GROUPS];779779-780780- u8 tx_ibias[CONF_NUMBER_OF_RATE_GROUPS];781781- u8 rx_fem_insertion_loss;782782-783783- u8 degraded_low_to_normal_threshold;784784- u8 degraded_normal_to_high_threshold;785785-786786-787787- /*788788- * Dynamic radio parameters for 5GHz789789- *790790- * Range: unknown791791- */792792- u16 tx_ref_pd_voltage_5[CONF_NUMBER_OF_SUB_BANDS_5];793793- u8 tx_ref_power_5[CONF_NUMBER_OF_SUB_BANDS_5];794794- s8 tx_offset_db_5[CONF_NUMBER_OF_SUB_BANDS_5];795795-796796- s8 tx_rate_limits_normal_5[CONF_NUMBER_OF_RATE_GROUPS];797797- s8 tx_rate_limits_degraded_5[CONF_NUMBER_OF_RATE_GROUPS];798798- s8 tx_rate_limits_extreme_5[CONF_NUMBER_OF_RATE_GROUPS];799799-800800- s8 tx_channel_limits_ofdm_5[CONF_NUMBER_OF_CHANNELS_5];801801- s8 tx_pdv_rate_offsets_5[CONF_NUMBER_OF_RATE_GROUPS];802802-803803- /* FIXME: this is inconsistent with the types for 2.4GHz */804804- s8 tx_ibias_5[CONF_NUMBER_OF_RATE_GROUPS];805805- s8 rx_fem_insertion_loss_5[CONF_NUMBER_OF_SUB_BANDS_5];806806-807807- u8 degraded_low_to_normal_threshold_5;808808- u8 degraded_normal_to_high_threshold_5;825825+ u8 fem;809826};810827811828struct conf_init_settings {812812- /*813813- * Configure general parameters.814814- */815815- struct conf_general_parms genparam;816816-817829 /*818830 * Configure radio parameters.819831 */
+44-6
drivers/net/wireless/wl12xx/wl1271_event.c
···2424#include "wl1271.h"2525#include "wl1271_reg.h"2626#include "wl1271_spi.h"2727+#include "wl1271_io.h"2728#include "wl1271_event.h"2829#include "wl1271_ps.h"2930#include "wl12xx_80211.h"···79788079 switch (mbox->ps_status) {8180 case EVENT_ENTER_POWER_SAVE_FAIL:8181+ wl1271_debug(DEBUG_PSM, "PSM entry failed");8282+8283 if (!test_bit(WL1271_FLAG_PSM, &wl->flags)) {8484+ /* remain in active mode */8385 wl->psm_entry_retry = 0;8486 break;8587 }86888789 if (wl->psm_entry_retry < wl->conf.conn.psm_entry_retries) {8890 wl->psm_entry_retry++;8989- ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);9191+ ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,9292+ true);9093 } else {9194 wl1271_error("PSM entry failed, giving up.\n");9595+ /* FIXME: this may need to be reconsidered. for now it9696+ is not possible to indicate to the mac802119797+ afterwards that PSM entry failed. To maximize9898+ functionality (receiving data and remaining9999+ associated) make sure that we are in sync with the100100+ AP in regard of PSM mode. */101101+ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,102102+ false);92103 wl->psm_entry_retry = 0;93104 }94105 break;95106 case EVENT_ENTER_POWER_SAVE_SUCCESS:96107 wl->psm_entry_retry = 0;108108+109109+ /* enable beacon filtering */110110+ ret = wl1271_acx_beacon_filter_opt(wl, true);111111+ if (ret < 0)112112+ break;113113+114114+ /* enable beacon early termination */115115+ ret = wl1271_acx_bet_enable(wl, true);116116+ if (ret < 0)117117+ break;118118+119119+ /* go to extremely low power mode */120120+ wl1271_ps_elp_sleep(wl);121121+ if (ret < 0)122122+ break;97123 break;98124 case EVENT_EXIT_POWER_SAVE_FAIL:9999- wl1271_info("PSM exit failed");125125+ wl1271_debug(DEBUG_PSM, "PSM exit failed");126126+127127+ if (test_bit(WL1271_FLAG_PSM, &wl->flags)) {128128+ wl->psm_entry_retry = 0;129129+ break;130130+ }131131+132132+ /* make sure the firmware goes to active mode - the frame to133133+ be sent next will indicate to the AP, that we are active. */134134+ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,135135+ false);100136 break;101137 case EVENT_EXIT_POWER_SAVE_SUCCESS:102138 default:···215177216178void wl1271_event_mbox_config(struct wl1271 *wl)217179{218218- wl->mbox_ptr[0] = wl1271_spi_read32(wl, REG_EVENT_MAILBOX_PTR);180180+ wl->mbox_ptr[0] = wl1271_read32(wl, REG_EVENT_MAILBOX_PTR);219181 wl->mbox_ptr[1] = wl->mbox_ptr[0] + sizeof(struct event_mailbox);220182221183 wl1271_debug(DEBUG_EVENT, "MBOX ptrs: 0x%x 0x%x",···233195 return -EINVAL;234196235197 /* first we read the mbox descriptor */236236- wl1271_spi_read(wl, wl->mbox_ptr[mbox_num], &mbox,237237- sizeof(struct event_mailbox), false);198198+ wl1271_read(wl, wl->mbox_ptr[mbox_num], &mbox,199199+ sizeof(struct event_mailbox), false);238200239201 /* process the descriptor */240202 ret = wl1271_event_process(wl, &mbox);···242204 return ret;243205244206 /* then we let the firmware know it can go on...*/245245- wl1271_spi_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);207207+ wl1271_write32(wl, ACX_REG_INTERRUPT_TRIG, INTR_TRIG_EVENT_ACK);246208247209 return 0;248210}
+27-11
drivers/net/wireless/wl12xx/wl1271_init.c
···4949 return 0;5050}51515252-static int wl1271_init_templates_config(struct wl1271 *wl)5252+int wl1271_init_templates_config(struct wl1271 *wl)5353{5454 int ret;5555···113113 return 0;114114}115115116116-static int wl1271_init_phy_config(struct wl1271 *wl)116116+int wl1271_init_phy_config(struct wl1271 *wl)117117{118118 int ret;119119···156156 return 0;157157}158158159159-static int wl1271_init_pta(struct wl1271 *wl)159159+int wl1271_init_pta(struct wl1271 *wl)160160{161161 int ret;162162···171171 return 0;172172}173173174174-static int wl1271_init_energy_detection(struct wl1271 *wl)174174+int wl1271_init_energy_detection(struct wl1271 *wl)175175{176176 int ret;177177···195195196196int wl1271_hw_init(struct wl1271 *wl)197197{198198- int ret;198198+ struct conf_tx_ac_category *conf_ac;199199+ struct conf_tx_tid *conf_tid;200200+ int ret, i;199201200202 ret = wl1271_cmd_general_parms(wl);201203 if (ret < 0)···276274 goto out_free_memmap;277275278276 /* Default TID configuration */279279- ret = wl1271_acx_tid_cfg(wl);280280- if (ret < 0)281281- goto out_free_memmap;277277+ for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {278278+ conf_tid = &wl->conf.tx.tid_conf[i];279279+ ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,280280+ conf_tid->channel_type,281281+ conf_tid->tsid,282282+ conf_tid->ps_scheme,283283+ conf_tid->ack_policy,284284+ conf_tid->apsd_conf[0],285285+ conf_tid->apsd_conf[1]);286286+ if (ret < 0)287287+ goto out_free_memmap;288288+ }282289283290 /* Default AC configuration */284284- ret = wl1271_acx_ac_cfg(wl);285285- if (ret < 0)286286- goto out_free_memmap;291291+ for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {292292+ conf_ac = &wl->conf.tx.ac_conf[i];293293+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,294294+ conf_ac->cw_max, conf_ac->aifsn,295295+ conf_ac->tx_op_limit);296296+ if (ret < 0)297297+ goto out_free_memmap;298298+ }287299288300 /* Configure TX rate classes */289301 ret = wl1271_acx_rate_policies(wl);
···11+/*22+ * This file is part of wl127133+ *44+ * Copyright (C) 2008-2010 Nokia Corporation55+ *66+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License1010+ * version 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful, but1313+ * WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1515+ * General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA2020+ * 02110-1301 USA2121+ *2222+ */2323+2424+#include <linux/module.h>2525+#include <linux/platform_device.h>2626+#include <linux/crc7.h>2727+#include <linux/spi/spi.h>2828+2929+#include "wl1271.h"3030+#include "wl12xx_80211.h"3131+#include "wl1271_spi.h"3232+#include "wl1271_io.h"3333+3434+static int wl1271_translate_addr(struct wl1271 *wl, int addr)3535+{3636+ /*3737+ * To translate, first check to which window of addresses the3838+ * particular address belongs. Then subtract the starting address3939+ * of that window from the address. Then, add offset of the4040+ * translated region.4141+ *4242+ * The translated regions occur next to each other in physical device4343+ * memory, so just add the sizes of the preceeding address regions to4444+ * get the offset to the new region.4545+ *4646+ * Currently, only the two first regions are addressed, and the4747+ * assumption is that all addresses will fall into either of those4848+ * two.4949+ */5050+ if ((addr >= wl->part.reg.start) &&5151+ (addr < wl->part.reg.start + wl->part.reg.size))5252+ return addr - wl->part.reg.start + wl->part.mem.size;5353+ else5454+ return addr - wl->part.mem.start;5555+}5656+5757+/* Set the SPI partitions to access the chip addresses5858+ *5959+ * To simplify driver code, a fixed (virtual) memory map is defined for6060+ * register and memory addresses. Because in the chipset, in different stages6161+ * of operation, those addresses will move around, an address translation6262+ * mechanism is required.6363+ *6464+ * There are four partitions (three memory and one register partition),6565+ * which are mapped to two different areas of the hardware memory.6666+ *6767+ * Virtual address6868+ * space6969+ *7070+ * | |7171+ * ...+----+--> mem.start7272+ * Physical address ... | |7373+ * space ... | | [PART_0]7474+ * ... | |7575+ * 00000000 <--+----+... ...+----+--> mem.start + mem.size7676+ * | | ... | |7777+ * |MEM | ... | |7878+ * | | ... | |7979+ * mem.size <--+----+... | | {unused area)8080+ * | | ... | |8181+ * |REG | ... | |8282+ * mem.size | | ... | |8383+ * + <--+----+... ...+----+--> reg.start8484+ * reg.size | | ... | |8585+ * |MEM2| ... | | [PART_1]8686+ * | | ... | |8787+ * ...+----+--> reg.start + reg.size8888+ * | |8989+ *9090+ */9191+int wl1271_set_partition(struct wl1271 *wl,9292+ struct wl1271_partition_set *p)9393+{9494+ /* copy partition info */9595+ memcpy(&wl->part, p, sizeof(*p));9696+9797+ wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",9898+ p->mem.start, p->mem.size);9999+ wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",100100+ p->reg.start, p->reg.size);101101+ wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",102102+ p->mem2.start, p->mem2.size);103103+ wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",104104+ p->mem3.start, p->mem3.size);105105+106106+ /* write partition info to the chipset */107107+ wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);108108+ wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);109109+ wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);110110+ wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);111111+ wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);112112+ wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);113113+ wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);114114+115115+ return 0;116116+}117117+118118+void wl1271_io_reset(struct wl1271 *wl)119119+{120120+ wl1271_spi_reset(wl);121121+}122122+123123+void wl1271_io_init(struct wl1271 *wl)124124+{125125+ wl1271_spi_init(wl);126126+}127127+128128+void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,129129+ size_t len, bool fixed)130130+{131131+ wl1271_spi_raw_write(wl, addr, buf, len, fixed);132132+}133133+134134+void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,135135+ size_t len, bool fixed)136136+{137137+ wl1271_spi_raw_read(wl, addr, buf, len, fixed);138138+}139139+140140+void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,141141+ bool fixed)142142+{143143+ int physical;144144+145145+ physical = wl1271_translate_addr(wl, addr);146146+147147+ wl1271_spi_raw_read(wl, physical, buf, len, fixed);148148+}149149+150150+void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,151151+ bool fixed)152152+{153153+ int physical;154154+155155+ physical = wl1271_translate_addr(wl, addr);156156+157157+ wl1271_spi_raw_write(wl, physical, buf, len, fixed);158158+}159159+160160+u32 wl1271_read32(struct wl1271 *wl, int addr)161161+{162162+ return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));163163+}164164+165165+void wl1271_write32(struct wl1271 *wl, int addr, u32 val)166166+{167167+ wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);168168+}169169+170170+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)171171+{172172+ /* write address >> 1 + 0x30000 to OCP_POR_CTR */173173+ addr = (addr >> 1) + 0x30000;174174+ wl1271_write32(wl, OCP_POR_CTR, addr);175175+176176+ /* write value to OCP_POR_WDATA */177177+ wl1271_write32(wl, OCP_DATA_WRITE, val);178178+179179+ /* write 1 to OCP_CMD */180180+ wl1271_write32(wl, OCP_CMD, OCP_CMD_WRITE);181181+}182182+183183+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)184184+{185185+ u32 val;186186+ int timeout = OCP_CMD_LOOP;187187+188188+ /* write address >> 1 + 0x30000 to OCP_POR_CTR */189189+ addr = (addr >> 1) + 0x30000;190190+ wl1271_write32(wl, OCP_POR_CTR, addr);191191+192192+ /* write 2 to OCP_CMD */193193+ wl1271_write32(wl, OCP_CMD, OCP_CMD_READ);194194+195195+ /* poll for data ready */196196+ do {197197+ val = wl1271_read32(wl, OCP_DATA_READ);198198+ } while (!(val & OCP_READY_MASK) && --timeout);199199+200200+ if (!timeout) {201201+ wl1271_warning("Top register access timed out.");202202+ return 0xffff;203203+ }204204+205205+ /* check data status and return if OK */206206+ if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)207207+ return val & 0xffff;208208+ else {209209+ wl1271_warning("Top register access returned error.");210210+ return 0xffff;211211+ }212212+}213213+
+68
drivers/net/wireless/wl12xx/wl1271_io.h
···11+/*22+ * This file is part of wl127133+ *44+ * Copyright (C) 1998-2009 Texas Instruments. All rights reserved.55+ * Copyright (C) 2008-2010 Nokia Corporation66+ *77+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>88+ *99+ * This program is free software; you can redistribute it and/or1010+ * modify it under the terms of the GNU General Public License1111+ * version 2 as published by the Free Software Foundation.1212+ *1313+ * This program is distributed in the hope that it will be useful, but1414+ * WITHOUT ANY WARRANTY; without even the implied warranty of1515+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1616+ * General Public License for more details.1717+ *1818+ * You should have received a copy of the GNU General Public License1919+ * along with this program; if not, write to the Free Software2020+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA2121+ * 02110-1301 USA2222+ *2323+ */2424+2525+#ifndef __WL1271_IO_H__2626+#define __WL1271_IO_H__2727+2828+struct wl1271;2929+3030+void wl1271_io_reset(struct wl1271 *wl);3131+void wl1271_io_init(struct wl1271 *wl);3232+3333+/* Raw target IO, address is not translated */3434+void wl1271_raw_write(struct wl1271 *wl, int addr, void *buf,3535+ size_t len, bool fixed);3636+void wl1271_raw_read(struct wl1271 *wl, int addr, void *buf,3737+ size_t len, bool fixed);3838+3939+/* Translated target IO */4040+void wl1271_read(struct wl1271 *wl, int addr, void *buf, size_t len,4141+ bool fixed);4242+void wl1271_write(struct wl1271 *wl, int addr, void *buf, size_t len,4343+ bool fixed);4444+u32 wl1271_read32(struct wl1271 *wl, int addr);4545+void wl1271_write32(struct wl1271 *wl, int addr, u32 val);4646+4747+/* Top Register IO */4848+void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);4949+u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);5050+5151+int wl1271_set_partition(struct wl1271 *wl,5252+ struct wl1271_partition_set *p);5353+5454+static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)5555+{5656+ wl1271_raw_read(wl, addr, &wl->buffer_32,5757+ sizeof(wl->buffer_32), false);5858+5959+ return wl->buffer_32;6060+}6161+6262+static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)6363+{6464+ wl->buffer_32 = val;6565+ wl1271_raw_write(wl, addr, &wl->buffer_32,6666+ sizeof(wl->buffer_32), false);6767+}6868+#endif
+303-178
drivers/net/wireless/wl12xx/wl1271_main.c
···11/*22 * This file is part of wl127133 *44- * Copyright (C) 2008-2009 Nokia Corporation44+ * Copyright (C) 2008-2010 Nokia Corporation55 *66 * Contact: Luciano Coelho <luciano.coelho@nokia.com>77 *···3838#include "wl12xx_80211.h"3939#include "wl1271_reg.h"4040#include "wl1271_spi.h"4141+#include "wl1271_io.h"4142#include "wl1271_event.h"4243#include "wl1271_tx.h"4344#include "wl1271_rx.h"···4746#include "wl1271_debugfs.h"4847#include "wl1271_cmd.h"4948#include "wl1271_boot.h"4949+#include "wl1271_testmode.h"50505151#define WL1271_BOOT_RETRIES 35252···231229 .psm_entry_retries = 3232230 },233231 .init = {234234- .genparam = {235235- .ref_clk = CONF_REF_CLK_38_4_E,236236- .settling_time = 5,237237- .clk_valid_on_wakeup = 0,238238- .dc2dcmode = 0,239239- .single_dual_band = CONF_SINGLE_BAND,240240- .tx_bip_fem_autodetect = 1,241241- .tx_bip_fem_manufacturer = 1,242242- .settings = 1,243243- .sr_state = 1,244244- .srf1 = { 0x07, 0x03, 0x18, 0x10, 0x05, 0xfb, 0xf0,245245- 0xe8, 0, 0, 0, 0, 0, 0, 0, 0 },246246- .srf2 = { 0x07, 0x03, 0x18, 0x10, 0x05, 0xfb, 0xf0,247247- 0xe8, 0, 0, 0, 0, 0, 0, 0, 0 },248248- .srf3 = { 0x07, 0x03, 0x18, 0x10, 0x05, 0xfb, 0xf0,249249- 0xe8, 0, 0, 0, 0, 0, 0, 0, 0 },250250- .sr_debug_table = { 0, 0, 0, 0, 0, 0, 0, 0,251251- 0, 0, 0, 0, 0, 0, 0, 0 },252252- .sr_sen_n_p = 0,253253- .sr_sen_n_p_gain = 0,254254- .sr_sen_nrn = 0,255255- .sr_sen_prn = 0,256256- },257232 .radioparam = {258258- .rx_trace_loss = 0x24,259259- .tx_trace_loss = 0x0,260260- .rx_rssi_and_proc_compens = {261261- 0xec, 0xf6, 0x00, 0x0c, 0x18, 0xf8,262262- 0xfc, 0x00, 0x80, 0x10, 0xf0, 0xf8,263263- 0x00, 0x0a, 0x14 },264264- .rx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },265265- .tx_trace_loss_5 = { 0, 0, 0, 0, 0, 0, 0 },266266- .rx_rssi_and_proc_compens_5 = {267267- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,268268- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,269269- 0x00, 0x00, 0x00 },270270- .tx_ref_pd_voltage = 0x1a9,271271- .tx_ref_power = 0x80,272272- .tx_offset_db = 0x0,273273- .tx_rate_limits_normal = {274274- 0x1d, 0x1f, 0x24, 0x28, 0x28, 0x29 },275275- .tx_rate_limits_degraded = {276276- 0x19, 0x1f, 0x22, 0x23, 0x27, 0x28 },277277- .tx_rate_limits_extreme = {278278- 0x19, 0x1c, 0x1e, 0x20, 0x24, 0x25 },279279- .tx_channel_limits_11b = {280280- 0x22, 0x50, 0x50, 0x50, 0x50, 0x50,281281- 0x50, 0x50, 0x50, 0x50, 0x22, 0x50,282282- 0x22, 0x50 },283283- .tx_channel_limits_ofdm = {284284- 0x20, 0x50, 0x50, 0x50, 0x50, 0x50,285285- 0x50, 0x50, 0x50, 0x50, 0x20, 0x50,286286- 0x20, 0x50 },287287- .tx_pdv_rate_offsets = {288288- 0x07, 0x08, 0x04, 0x02, 0x02, 0x00 },289289- .tx_ibias = {290290- 0x11, 0x11, 0x15, 0x11, 0x15, 0x0f },291291- .rx_fem_insertion_loss = 0x0e,292292- .degraded_low_to_normal_threshold = 0x1e,293293- .degraded_normal_to_high_threshold = 0x2d,294294- .tx_ref_pd_voltage_5 = {295295- 0x0190, 0x01a4, 0x01c3, 0x01d8,296296- 0x020a, 0x021c },297297- .tx_ref_power_5 = {298298- 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 },299299- .tx_offset_db_5 = {300300- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },301301- .tx_rate_limits_normal_5 = {302302- 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },303303- .tx_rate_limits_degraded_5 = {304304- 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },305305- .tx_rate_limits_extreme_5 = {306306- 0x1b, 0x1e, 0x21, 0x23, 0x27, 0x00 },307307- .tx_channel_limits_ofdm_5 = {308308- 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,309309- 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,310310- 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,311311- 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50, 0x50,312312- 0x50, 0x50, 0x50 },313313- .tx_pdv_rate_offsets_5 = {314314- 0x01, 0x02, 0x02, 0x02, 0x02, 0x00 },315315- .tx_ibias_5 = {316316- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },317317- .rx_fem_insertion_loss_5 = {318318- 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10 },319319- .degraded_low_to_normal_threshold_5 = 0x00,320320- .degraded_normal_to_high_threshold_5 = 0x00233233+ .fem = 1,321234 }322235 },323236 .itrim = {···262345263346 /* apply driver default configuration */264347 memcpy(&wl->conf, &default_conf, sizeof(default_conf));265265-266266- if (wl1271_11a_enabled())267267- wl->conf.init.genparam.single_dual_band = CONF_DUAL_BAND;268348}269349270350271351static int wl1271_plt_init(struct wl1271 *wl)272352{273273- int ret;353353+ struct conf_tx_ac_category *conf_ac;354354+ struct conf_tx_tid *conf_tid;355355+ int ret, i;274356275357 ret = wl1271_cmd_general_parms(wl);276358 if (ret < 0)···279363 if (ret < 0)280364 return ret;281365366366+ ret = wl1271_init_templates_config(wl);367367+ if (ret < 0)368368+ return ret;369369+282370 ret = wl1271_acx_init_mem_config(wl);283371 if (ret < 0)284372 return ret;285373374374+ /* PHY layer config */375375+ ret = wl1271_init_phy_config(wl);376376+ if (ret < 0)377377+ goto out_free_memmap;378378+379379+ ret = wl1271_acx_dco_itrim_params(wl);380380+ if (ret < 0)381381+ goto out_free_memmap;382382+383383+ /* Initialize connection monitoring thresholds */384384+ ret = wl1271_acx_conn_monit_params(wl);385385+ if (ret < 0)386386+ goto out_free_memmap;387387+388388+ /* Bluetooth WLAN coexistence */389389+ ret = wl1271_init_pta(wl);390390+ if (ret < 0)391391+ goto out_free_memmap;392392+393393+ /* Energy detection */394394+ ret = wl1271_init_energy_detection(wl);395395+ if (ret < 0)396396+ goto out_free_memmap;397397+398398+ /* Default fragmentation threshold */399399+ ret = wl1271_acx_frag_threshold(wl);400400+ if (ret < 0)401401+ goto out_free_memmap;402402+403403+ /* Default TID configuration */404404+ for (i = 0; i < wl->conf.tx.tid_conf_count; i++) {405405+ conf_tid = &wl->conf.tx.tid_conf[i];406406+ ret = wl1271_acx_tid_cfg(wl, conf_tid->queue_id,407407+ conf_tid->channel_type,408408+ conf_tid->tsid,409409+ conf_tid->ps_scheme,410410+ conf_tid->ack_policy,411411+ conf_tid->apsd_conf[0],412412+ conf_tid->apsd_conf[1]);413413+ if (ret < 0)414414+ goto out_free_memmap;415415+ }416416+417417+ /* Default AC configuration */418418+ for (i = 0; i < wl->conf.tx.ac_conf_count; i++) {419419+ conf_ac = &wl->conf.tx.ac_conf[i];420420+ ret = wl1271_acx_ac_cfg(wl, conf_ac->ac, conf_ac->cw_min,421421+ conf_ac->cw_max, conf_ac->aifsn,422422+ conf_ac->tx_op_limit);423423+ if (ret < 0)424424+ goto out_free_memmap;425425+ }426426+427427+ /* Enable data path */286428 ret = wl1271_cmd_data_path(wl, 1);287429 if (ret < 0)288288- return ret;430430+ goto out_free_memmap;431431+432432+ /* Configure for CAM power saving (ie. always active) */433433+ ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);434434+ if (ret < 0)435435+ goto out_free_memmap;436436+437437+ /* configure PM */438438+ ret = wl1271_acx_pm_config(wl);439439+ if (ret < 0)440440+ goto out_free_memmap;289441290442 return 0;443443+444444+ out_free_memmap:445445+ kfree(wl->target_mem_map);446446+ wl->target_mem_map = NULL;447447+448448+ return ret;291449}292450293451static void wl1271_disable_interrupts(struct wl1271 *wl)···387397 u32 total = 0;388398 int i;389399390390- wl1271_spi_read(wl, FW_STATUS_ADDR, status,391391- sizeof(*status), false);400400+ wl1271_read(wl, FW_STATUS_ADDR, status, sizeof(*status), false);392401393402 wl1271_debug(DEBUG_IRQ, "intr: 0x%x (fw_rx_counter = %d, "394403 "drv_rx_counter = %d, tx_results_counter = %d)",···434445 if (ret < 0)435446 goto out;436447437437- wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);448448+ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK, WL1271_ACX_INTR_ALL);438449439450 wl1271_fw_status(wl, wl->fw_status);440451 intr = le32_to_cpu(wl->fw_status->intr);···476487 }477488478489out_sleep:479479- wl1271_spi_write32(wl, ACX_REG_INTERRUPT_MASK,480480- WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));490490+ wl1271_write32(wl, ACX_REG_INTERRUPT_MASK,491491+ WL1271_ACX_INTR_ALL & ~(WL1271_INTR_MASK));481492 wl1271_ps_elp_sleep(wl);482493483494out:···544555 return ret;545556}546557558558+static int wl1271_update_mac_addr(struct wl1271 *wl)559559+{560560+ int ret = 0;561561+ u8 *nvs_ptr = (u8 *)wl->nvs->nvs;562562+563563+ /* get mac address from the NVS */564564+ wl->mac_addr[0] = nvs_ptr[11];565565+ wl->mac_addr[1] = nvs_ptr[10];566566+ wl->mac_addr[2] = nvs_ptr[6];567567+ wl->mac_addr[3] = nvs_ptr[5];568568+ wl->mac_addr[4] = nvs_ptr[4];569569+ wl->mac_addr[5] = nvs_ptr[3];570570+571571+ /* FIXME: if it is a zero-address, we should bail out. Now, instead,572572+ we randomize an address */573573+ if (is_zero_ether_addr(wl->mac_addr)) {574574+ static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};575575+ memcpy(wl->mac_addr, nokia_oui, 3);576576+ get_random_bytes(wl->mac_addr + 3, 3);577577+578578+ /* update this address to the NVS */579579+ nvs_ptr[11] = wl->mac_addr[0];580580+ nvs_ptr[10] = wl->mac_addr[1];581581+ nvs_ptr[6] = wl->mac_addr[2];582582+ nvs_ptr[5] = wl->mac_addr[3];583583+ nvs_ptr[4] = wl->mac_addr[4];584584+ nvs_ptr[3] = wl->mac_addr[5];585585+ }586586+587587+ SET_IEEE80211_PERM_ADDR(wl->hw, wl->mac_addr);588588+589589+ return ret;590590+}591591+547592static int wl1271_fetch_nvs(struct wl1271 *wl)548593{549594 const struct firmware *fw;···590567 return ret;591568 }592569593593- if (fw->size % 4) {594594- wl1271_error("nvs size is not multiple of 32 bits: %zu",595595- fw->size);570570+ if (fw->size != sizeof(struct wl1271_nvs_file)) {571571+ wl1271_error("nvs size is not as expected: %zu != %zu",572572+ fw->size, sizeof(struct wl1271_nvs_file));596573 ret = -EILSEQ;597574 goto out;598575 }599576600600- wl->nvs_len = fw->size;601601- wl->nvs = kmalloc(wl->nvs_len, GFP_KERNEL);577577+ wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);602578603579 if (!wl->nvs) {604580 wl1271_error("could not allocate memory for the nvs file");···605583 goto out;606584 }607585608608- memcpy(wl->nvs, fw->data, wl->nvs_len);586586+ memcpy(wl->nvs, fw->data, sizeof(struct wl1271_nvs_file));609587610610- ret = 0;588588+ ret = wl1271_update_mac_addr(wl);611589612590out:613591 release_firmware(fw);···648626 msleep(WL1271_PRE_POWER_ON_SLEEP);649627 wl1271_power_on(wl);650628 msleep(WL1271_POWER_ON_SLEEP);651651- wl1271_spi_reset(wl);652652- wl1271_spi_init(wl);629629+ wl1271_io_reset(wl);630630+ wl1271_io_init(wl);653631654632 /* We don't need a real memory partition here, because we only want655633 * to use the registers at this point. */···664642 /* whal_FwCtrl_BootSm() */665643666644 /* 0. read chip id from CHIP_ID */667667- wl->chip.id = wl1271_spi_read32(wl, CHIP_ID_B);645645+ wl->chip.id = wl1271_read32(wl, CHIP_ID_B);668646669647 /* 1. check if chip id is valid */670648···735713 goto power_off;736714737715 ret = wl1271_plt_init(wl);738738- if (ret < 0)739739- goto irq_disable;740740-741741- /* Make sure power saving is disabled */742742- ret = wl1271_acx_sleep_auth(wl, WL1271_PSM_CAM);743716 if (ret < 0)744717 goto irq_disable;745718···12511234 }1252123512531236 /* if the channel changes while joined, join again */12541254- if (channel != wl->channel && test_bit(WL1271_FLAG_JOINED, &wl->flags))12551255- wl1271_join_channel(wl, channel);12371237+ if (channel != wl->channel &&12381238+ test_bit(WL1271_FLAG_JOINED, &wl->flags)) {12391239+ wl->channel = channel;12401240+ /* FIXME: maybe use CMD_CHANNEL_SWITCH for this? */12411241+ ret = wl1271_cmd_join(wl);12421242+ if (ret < 0)12431243+ wl1271_warning("cmd join to update channel failed %d",12441244+ ret);12451245+ } else12461246+ wl->channel = channel;1256124712571248 if (conf->flags & IEEE80211_CONF_PS &&12581249 !test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {···12731248 */12741249 if (test_bit(WL1271_FLAG_STA_ASSOCIATED, &wl->flags)) {12751250 wl1271_info("psm enabled");12761276- ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE);12511251+ ret = wl1271_ps_set_mode(wl, STATION_POWER_SAVE_MODE,12521252+ true);12771253 }12781254 } else if (!(conf->flags & IEEE80211_CONF_PS) &&12791255 test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags)) {···12831257 clear_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags);1284125812851259 if (test_bit(WL1271_FLAG_PSM, &wl->flags))12861286- ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE);12601260+ ret = wl1271_ps_set_mode(wl, STATION_ACTIVE_MODE,12611261+ true);12871262 }1288126312891264 if (conf->power_level != wl->power_level) {···14761449 wl1271_error("Could not add or replace key");14771450 goto out_sleep;14781451 }14521452+14531453+ /* the default WEP key needs to be configured at least once */14541454+ if (key_type == KEY_WEP) {14551455+ ret = wl1271_cmd_set_default_wep_key(wl,14561456+ wl->default_key);14571457+ if (ret < 0)14581458+ goto out_sleep;14591459+ }14791460 break;1480146114811462 case DISABLE_KEY:14631463+ /* The wl1271 does not allow to remove unicast keys - they14641464+ will be cleared automatically on next CMD_JOIN. Ignore the14651465+ request silently, as we dont want the mac80211 to emit14661466+ an error message. */14671467+ if (!is_broadcast_ether_addr(addr))14681468+ break;14691469+14821470 ret = wl1271_cmd_set_key(wl, KEY_REMOVE,14831471 key_conf->keyidx, key_type,14841472 key_conf->keylen, key_conf->key,···15811539 return ret;15821540}1583154115421542+static void wl1271_ssid_set(struct wl1271 *wl, struct sk_buff *beacon)15431543+{15441544+ u8 *ptr = beacon->data +15451545+ offsetof(struct ieee80211_mgmt, u.beacon.variable);15461546+15471547+ /* find the location of the ssid in the beacon */15481548+ while (ptr < beacon->data + beacon->len) {15491549+ if (ptr[0] == WLAN_EID_SSID) {15501550+ wl->ssid_len = ptr[1];15511551+ memcpy(wl->ssid, ptr+2, wl->ssid_len);15521552+ return;15531553+ }15541554+ ptr += ptr[1];15551555+ }15561556+ wl1271_error("ad-hoc beacon template has no SSID!\n");15571557+}15581558+15841559static void wl1271_op_bss_info_changed(struct ieee80211_hw *hw,15851560 struct ieee80211_vif *vif,15861561 struct ieee80211_bss_conf *bss_conf,···16051546{16061547 enum wl1271_cmd_ps_mode mode;16071548 struct wl1271 *wl = hw->priv;15491549+ bool do_join = false;16081550 int ret;1609155116101552 wl1271_debug(DEBUG_MAC80211, "mac80211 bss info changed");···16161556 if (ret < 0)16171557 goto out;1618155816191619- if ((changed & BSS_CHANGED_BSSID) &&16201620- /*16211621- * Now we know the correct bssid, so we send a new join command16221622- * and enable the BSSID filter16231623- */16241624- memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {16251625- wl->rx_config |= CFG_BSSID_FILTER_EN;16261626- memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);16271627- ret = wl1271_cmd_build_null_data(wl);16281628- if (ret < 0) {16291629- wl1271_warning("cmd buld null data failed %d",16301630- ret);16311631- goto out_sleep;16321632- }16331633- ret = wl1271_cmd_join(wl);16341634- if (ret < 0) {16351635- wl1271_warning("cmd join failed %d", ret);16361636- goto out_sleep;16371637- }16381638- set_bit(WL1271_FLAG_JOINED, &wl->flags);16391639- }16401640-16411559 if (wl->bss_type == BSS_TYPE_IBSS) {16421560 /* FIXME: This implements rudimentary ad-hoc support -16431561 proper templates are on the wish list and notification16441562 on when they change. This patch will update the templates16451645- on every call to this function. Also, the firmware will not16461646- answer to probe-requests as it does not have the proper16471647- SSID set in the JOIN command. The probe-response template16481648- is set nevertheless, as the FW will ASSERT without it */15631563+ on every call to this function. */16491564 struct sk_buff *beacon = ieee80211_beacon_get(hw, vif);1650156516511566 if (beacon) {16521567 struct ieee80211_hdr *hdr;15681568+15691569+ wl1271_ssid_set(wl, beacon);16531570 ret = wl1271_cmd_template_set(wl, CMD_TEMPL_BEACON,16541571 beacon->data,16551572 beacon->len);···16481611 dev_kfree_skb(beacon);16491612 if (ret < 0)16501613 goto out_sleep;16141614+16151615+ /* Need to update the SSID (for filtering etc) */16161616+ do_join = true;16511617 }16181618+ }16191619+16201620+ if ((changed & BSS_CHANGED_BSSID) &&16211621+ /*16221622+ * Now we know the correct bssid, so we send a new join command16231623+ * and enable the BSSID filter16241624+ */16251625+ memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {16261626+ wl->rx_config |= CFG_BSSID_FILTER_EN;16271627+ memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);16281628+ ret = wl1271_cmd_build_null_data(wl);16291629+ if (ret < 0) {16301630+ wl1271_warning("cmd buld null data failed %d",16311631+ ret);16321632+ goto out_sleep;16331633+ }16341634+16351635+ /* Need to update the BSSID (for filtering etc) */16361636+ do_join = true;16521637 }1653163816541639 if (changed & BSS_CHANGED_ASSOC) {···16961637 if (test_bit(WL1271_FLAG_PSM_REQUESTED, &wl->flags) &&16971638 !test_bit(WL1271_FLAG_PSM, &wl->flags)) {16981639 mode = STATION_POWER_SAVE_MODE;16991699- ret = wl1271_ps_set_mode(wl, mode);16401640+ ret = wl1271_ps_set_mode(wl, mode, true);17001641 if (ret < 0)17011642 goto out_sleep;17021643 }···17371678 }17381679 }1739168016811681+ if (do_join) {16821682+ ret = wl1271_cmd_join(wl);16831683+ if (ret < 0) {16841684+ wl1271_warning("cmd join failed %d", ret);16851685+ goto out_sleep;16861686+ }16871687+ set_bit(WL1271_FLAG_JOINED, &wl->flags);16881688+ }16891689+17401690out_sleep:17411691 wl1271_ps_elp_sleep(wl);1742169217431693out:17441694 mutex_unlock(&wl->mutex);16951695+}16961696+16971697+static int wl1271_op_conf_tx(struct ieee80211_hw *hw, u16 queue,16981698+ const struct ieee80211_tx_queue_params *params)16991699+{17001700+ struct wl1271 *wl = hw->priv;17011701+ int ret;17021702+17031703+ mutex_lock(&wl->mutex);17041704+17051705+ wl1271_debug(DEBUG_MAC80211, "mac80211 conf tx %d", queue);17061706+17071707+ ret = wl1271_ps_elp_wakeup(wl, false);17081708+ if (ret < 0)17091709+ goto out;17101710+17111711+ ret = wl1271_acx_ac_cfg(wl, wl1271_tx_get_queue(queue),17121712+ params->cw_min, params->cw_max,17131713+ params->aifs, params->txop);17141714+ if (ret < 0)17151715+ goto out_sleep;17161716+17171717+ ret = wl1271_acx_tid_cfg(wl, wl1271_tx_get_queue(queue),17181718+ CONF_CHANNEL_TYPE_EDCF,17191719+ wl1271_tx_get_queue(queue),17201720+ CONF_PS_SCHEME_LEGACY_PSPOLL,17211721+ CONF_ACK_POLICY_LEGACY, 0, 0);17221722+ if (ret < 0)17231723+ goto out_sleep;17241724+17251725+out_sleep:17261726+ wl1271_ps_elp_sleep(wl);17271727+17281728+out:17291729+ mutex_unlock(&wl->mutex);17301730+17311731+ return ret;17451732}1746173317471734···19551850 .hw_scan = wl1271_op_hw_scan,19561851 .bss_info_changed = wl1271_op_bss_info_changed,19571852 .set_rts_threshold = wl1271_op_set_rts_threshold,18531853+ .conf_tx = wl1271_op_conf_tx,18541854+ CFG80211_TESTMODE_CMD(wl1271_tm_cmd)19581855};1959185619601857static int wl1271_register_hw(struct wl1271 *wl)···20251918};2026191920271920#define WL1271_DEFAULT_CHANNEL 020282028-static int __devinit wl1271_probe(struct spi_device *spi)19211921+19221922+static struct ieee80211_hw *wl1271_alloc_hw(void)20291923{20302030- struct wl12xx_platform_data *pdata;20311924 struct ieee80211_hw *hw;20321925 struct wl1271 *wl;20332033- int ret, i;20342034- static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf};20352035-20362036- pdata = spi->dev.platform_data;20372037- if (!pdata) {20382038- wl1271_error("no platform data");20392039- return -ENODEV;20402040- }19261926+ int i;2041192720421928 hw = ieee80211_alloc_hw(sizeof(*wl), &wl1271_ops);20431929 if (!hw) {20441930 wl1271_error("could not alloc ieee80211_hw");20452045- return -ENOMEM;19311931+ return ERR_PTR(-ENOMEM);20461932 }2047193320481934 wl = hw->priv;···20441944 INIT_LIST_HEAD(&wl->list);2045194520461946 wl->hw = hw;20472047- dev_set_drvdata(&spi->dev, wl);20482048- wl->spi = spi;2049194720501948 skb_queue_head_init(&wl->tx_queue);20511949···2067196920681970 spin_lock_init(&wl->wl_lock);2069197120702070- /*20712071- * In case our MAC address is not correctly set,20722072- * we use a random but Nokia MAC.20732073- */20742074- memcpy(wl->mac_addr, nokia_oui, 3);20752075- get_random_bytes(wl->mac_addr + 3, 3);20762076-20771972 wl->state = WL1271_STATE_OFF;20781973 mutex_init(&wl->mutex);19741974+19751975+ /* Apply default driver configuration. */19761976+ wl1271_conf_init(wl);19771977+19781978+ return hw;19791979+}19801980+19811981+int wl1271_free_hw(struct wl1271 *wl)19821982+{19831983+ ieee80211_unregister_hw(wl->hw);19841984+19851985+ wl1271_debugfs_exit(wl);19861986+19871987+ kfree(wl->target_mem_map);19881988+ vfree(wl->fw);19891989+ wl->fw = NULL;19901990+ kfree(wl->nvs);19911991+ wl->nvs = NULL;19921992+19931993+ kfree(wl->fw_status);19941994+ kfree(wl->tx_res_if);19951995+19961996+ ieee80211_free_hw(wl->hw);19971997+19981998+ return 0;19991999+}20002000+20012001+static int __devinit wl1271_probe(struct spi_device *spi)20022002+{20032003+ struct wl12xx_platform_data *pdata;20042004+ struct ieee80211_hw *hw;20052005+ struct wl1271 *wl;20062006+ int ret;20072007+20082008+ pdata = spi->dev.platform_data;20092009+ if (!pdata) {20102010+ wl1271_error("no platform data");20112011+ return -ENODEV;20122012+ }20132013+20142014+ hw = wl1271_alloc_hw();20152015+ if (IS_ERR(hw))20162016+ return PTR_ERR(hw);20172017+20182018+ wl = hw->priv;20192019+20202020+ dev_set_drvdata(&spi->dev, wl);20212021+ wl->spi = spi;2079202220802023 /* This is the only SPI value that we need to set here, the rest20812024 * comes from the board-peripherals file */···21592020 }21602021 dev_set_drvdata(&wl1271_device.dev, wl);2161202221622162- /* Apply default driver configuration. */21632163- wl1271_conf_init(wl);21642164-21652023 ret = wl1271_init_ieee80211(wl);21662024 if (ret)21672025 goto out_platform;···21892053{21902054 struct wl1271 *wl = dev_get_drvdata(&spi->dev);2191205521922192- ieee80211_unregister_hw(wl->hw);21932193-21942194- wl1271_debugfs_exit(wl);21952056 platform_device_unregister(&wl1271_device);21962057 free_irq(wl->irq, wl);21972197- kfree(wl->target_mem_map);21982198- vfree(wl->fw);21992199- wl->fw = NULL;22002200- kfree(wl->nvs);22012201- wl->nvs = NULL;2202205822032203- kfree(wl->fw_status);22042204- kfree(wl->tx_res_if);22052205-22062206- ieee80211_free_hw(wl->hw);20592059+ wl1271_free_hw(wl);2207206022082061 return 0;22092062}
+5-17
drivers/net/wireless/wl12xx/wl1271_ps.c
···2424#include "wl1271_reg.h"2525#include "wl1271_ps.h"2626#include "wl1271_spi.h"2727+#include "wl1271_io.h"27282829#define WL1271_WAKEUP_TIMEOUT 5002930···119118 return 0;120119}121120122122-int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode)121121+int wl1271_ps_set_mode(struct wl1271 *wl, enum wl1271_cmd_ps_mode mode,122122+ bool send)123123{124124 int ret;125125···128126 case STATION_POWER_SAVE_MODE:129127 wl1271_debug(DEBUG_PSM, "entering psm");130128131131- /* enable beacon filtering */132132- ret = wl1271_acx_beacon_filter_opt(wl, true);133133- if (ret < 0)134134- return ret;135135-136136- /* enable beacon early termination */137137- ret = wl1271_acx_bet_enable(wl, true);138138- if (ret < 0)139139- return ret;140140-141141- ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE);142142- if (ret < 0)143143- return ret;144144-145145- wl1271_ps_elp_sleep(wl);129129+ ret = wl1271_cmd_ps_mode(wl, STATION_POWER_SAVE_MODE, send);146130 if (ret < 0)147131 return ret;148132···151163 if (ret < 0)152164 return ret;153165154154- ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE);166166+ ret = wl1271_cmd_ps_mode(wl, STATION_ACTIVE_MODE, send);155167 if (ret < 0)156168 return ret;157169
···3030#include "wl12xx_80211.h"3131#include "wl1271_spi.h"32323333-static int wl1271_translate_addr(struct wl1271 *wl, int addr)3434-{3535- /*3636- * To translate, first check to which window of addresses the3737- * particular address belongs. Then subtract the starting address3838- * of that window from the address. Then, add offset of the3939- * translated region.4040- *4141- * The translated regions occur next to each other in physical device4242- * memory, so just add the sizes of the preceeding address regions to4343- * get the offset to the new region.4444- *4545- * Currently, only the two first regions are addressed, and the4646- * assumption is that all addresses will fall into either of those4747- * two.4848- */4949- if ((addr >= wl->part.reg.start) &&5050- (addr < wl->part.reg.start + wl->part.reg.size))5151- return addr - wl->part.reg.start + wl->part.mem.size;5252- else5353- return addr - wl->part.mem.start;5454-}55335634void wl1271_spi_reset(struct wl1271 *wl)5735{···109131 spi_sync(wl->spi, &m);110132111133 wl1271_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN);112112-}113113-114114-/* Set the SPI partitions to access the chip addresses115115- *116116- * To simplify driver code, a fixed (virtual) memory map is defined for117117- * register and memory addresses. Because in the chipset, in different stages118118- * of operation, those addresses will move around, an address translation119119- * mechanism is required.120120- *121121- * There are four partitions (three memory and one register partition),122122- * which are mapped to two different areas of the hardware memory.123123- *124124- * Virtual address125125- * space126126- *127127- * | |128128- * ...+----+--> mem.start129129- * Physical address ... | |130130- * space ... | | [PART_0]131131- * ... | |132132- * 00000000 <--+----+... ...+----+--> mem.start + mem.size133133- * | | ... | |134134- * |MEM | ... | |135135- * | | ... | |136136- * mem.size <--+----+... | | {unused area)137137- * | | ... | |138138- * |REG | ... | |139139- * mem.size | | ... | |140140- * + <--+----+... ...+----+--> reg.start141141- * reg.size | | ... | |142142- * |MEM2| ... | | [PART_1]143143- * | | ... | |144144- * ...+----+--> reg.start + reg.size145145- * | |146146- *147147- */148148-int wl1271_set_partition(struct wl1271 *wl,149149- struct wl1271_partition_set *p)150150-{151151- /* copy partition info */152152- memcpy(&wl->part, p, sizeof(*p));153153-154154- wl1271_debug(DEBUG_SPI, "mem_start %08X mem_size %08X",155155- p->mem.start, p->mem.size);156156- wl1271_debug(DEBUG_SPI, "reg_start %08X reg_size %08X",157157- p->reg.start, p->reg.size);158158- wl1271_debug(DEBUG_SPI, "mem2_start %08X mem2_size %08X",159159- p->mem2.start, p->mem2.size);160160- wl1271_debug(DEBUG_SPI, "mem3_start %08X mem3_size %08X",161161- p->mem3.start, p->mem3.size);162162-163163- /* write partition info to the chipset */164164- wl1271_raw_write32(wl, HW_PART0_START_ADDR, p->mem.start);165165- wl1271_raw_write32(wl, HW_PART0_SIZE_ADDR, p->mem.size);166166- wl1271_raw_write32(wl, HW_PART1_START_ADDR, p->reg.start);167167- wl1271_raw_write32(wl, HW_PART1_SIZE_ADDR, p->reg.size);168168- wl1271_raw_write32(wl, HW_PART2_START_ADDR, p->mem2.start);169169- wl1271_raw_write32(wl, HW_PART2_SIZE_ADDR, p->mem2.size);170170- wl1271_raw_write32(wl, HW_PART3_START_ADDR, p->mem3.start);171171-172172- return 0;173134}174135175136#define WL1271_BUSY_WORD_TIMEOUT 1000···254337255338 wl1271_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd));256339 wl1271_dump(DEBUG_SPI, "spi_write buf -> ", buf, len);257257-}258258-259259-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,260260- bool fixed)261261-{262262- int physical;263263-264264- physical = wl1271_translate_addr(wl, addr);265265-266266- wl1271_spi_raw_read(wl, physical, buf, len, fixed);267267-}268268-269269-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,270270- bool fixed)271271-{272272- int physical;273273-274274- physical = wl1271_translate_addr(wl, addr);275275-276276- wl1271_spi_raw_write(wl, physical, buf, len, fixed);277277-}278278-279279-u32 wl1271_spi_read32(struct wl1271 *wl, int addr)280280-{281281- return wl1271_raw_read32(wl, wl1271_translate_addr(wl, addr));282282-}283283-284284-void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val)285285-{286286- wl1271_raw_write32(wl, wl1271_translate_addr(wl, addr), val);287287-}288288-289289-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val)290290-{291291- /* write address >> 1 + 0x30000 to OCP_POR_CTR */292292- addr = (addr >> 1) + 0x30000;293293- wl1271_spi_write32(wl, OCP_POR_CTR, addr);294294-295295- /* write value to OCP_POR_WDATA */296296- wl1271_spi_write32(wl, OCP_DATA_WRITE, val);297297-298298- /* write 1 to OCP_CMD */299299- wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_WRITE);300300-}301301-302302-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)303303-{304304- u32 val;305305- int timeout = OCP_CMD_LOOP;306306-307307- /* write address >> 1 + 0x30000 to OCP_POR_CTR */308308- addr = (addr >> 1) + 0x30000;309309- wl1271_spi_write32(wl, OCP_POR_CTR, addr);310310-311311- /* write 2 to OCP_CMD */312312- wl1271_spi_write32(wl, OCP_CMD, OCP_CMD_READ);313313-314314- /* poll for data ready */315315- do {316316- val = wl1271_spi_read32(wl, OCP_DATA_READ);317317- } while (!(val & OCP_READY_MASK) && --timeout);318318-319319- if (!timeout) {320320- wl1271_warning("Top register access timed out.");321321- return 0xffff;322322- }323323-324324- /* check data status and return if OK */325325- if ((val & OCP_STATUS_MASK) == OCP_STATUS_OK)326326- return val & 0xffff;327327- else {328328- wl1271_warning("Top register access returned error.");329329- return 0xffff;330330- }331340}
-30
drivers/net/wireless/wl12xx/wl1271_spi.h
···9090void wl1271_spi_raw_read(struct wl1271 *wl, int addr, void *buf,9191 size_t len, bool fixed);92929393-/* Translated target IO */9494-void wl1271_spi_read(struct wl1271 *wl, int addr, void *buf, size_t len,9595- bool fixed);9696-void wl1271_spi_write(struct wl1271 *wl, int addr, void *buf, size_t len,9797- bool fixed);9898-u32 wl1271_spi_read32(struct wl1271 *wl, int addr);9999-void wl1271_spi_write32(struct wl1271 *wl, int addr, u32 val);100100-101101-/* Top Register IO */102102-void wl1271_top_reg_write(struct wl1271 *wl, int addr, u16 val);103103-u16 wl1271_top_reg_read(struct wl1271 *wl, int addr);104104-10593/* INIT and RESET words */10694void wl1271_spi_reset(struct wl1271 *wl);10795void wl1271_spi_init(struct wl1271 *wl);108108-int wl1271_set_partition(struct wl1271 *wl,109109- struct wl1271_partition_set *p);110110-111111-static inline u32 wl1271_raw_read32(struct wl1271 *wl, int addr)112112-{113113- wl1271_spi_raw_read(wl, addr, &wl->buffer_32,114114- sizeof(wl->buffer_32), false);115115-116116- return wl->buffer_32;117117-}118118-119119-static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)120120-{121121- wl->buffer_32 = val;122122- wl1271_spi_raw_write(wl, addr, &wl->buffer_32,123123- sizeof(wl->buffer_32), false);124124-}125125-12696#endif /* __WL1271_SPI_H__ */
+283
drivers/net/wireless/wl12xx/wl1271_testmode.c
···11+/*22+ * This file is part of wl127133+ *44+ * Copyright (C) 2010 Nokia Corporation55+ *66+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License1010+ * version 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful, but1313+ * WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1515+ * General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA2020+ * 02110-1301 USA2121+ *2222+ */2323+#include "wl1271_testmode.h"2424+2525+#include <net/genetlink.h>2626+2727+#include "wl1271.h"2828+#include "wl1271_spi.h"2929+#include "wl1271_acx.h"3030+3131+#define WL1271_TM_MAX_DATA_LENGTH 10243232+3333+enum wl1271_tm_commands {3434+ WL1271_TM_CMD_UNSPEC,3535+ WL1271_TM_CMD_TEST,3636+ WL1271_TM_CMD_INTERROGATE,3737+ WL1271_TM_CMD_CONFIGURE,3838+ WL1271_TM_CMD_NVS_PUSH,3939+ WL1271_TM_CMD_SET_PLT_MODE,4040+4141+ __WL1271_TM_CMD_AFTER_LAST4242+};4343+#define WL1271_TM_CMD_MAX (__WL1271_TM_CMD_AFTER_LAST - 1)4444+4545+enum wl1271_tm_attrs {4646+ WL1271_TM_ATTR_UNSPEC,4747+ WL1271_TM_ATTR_CMD_ID,4848+ WL1271_TM_ATTR_ANSWER,4949+ WL1271_TM_ATTR_DATA,5050+ WL1271_TM_ATTR_IE_ID,5151+ WL1271_TM_ATTR_PLT_MODE,5252+5353+ __WL1271_TM_ATTR_AFTER_LAST5454+};5555+#define WL1271_TM_ATTR_MAX (__WL1271_TM_ATTR_AFTER_LAST - 1)5656+5757+static struct nla_policy wl1271_tm_policy[WL1271_TM_ATTR_MAX + 1] = {5858+ [WL1271_TM_ATTR_CMD_ID] = { .type = NLA_U32 },5959+ [WL1271_TM_ATTR_ANSWER] = { .type = NLA_U8 },6060+ [WL1271_TM_ATTR_DATA] = { .type = NLA_BINARY,6161+ .len = WL1271_TM_MAX_DATA_LENGTH },6262+ [WL1271_TM_ATTR_IE_ID] = { .type = NLA_U32 },6363+ [WL1271_TM_ATTR_PLT_MODE] = { .type = NLA_U32 },6464+};6565+6666+6767+static int wl1271_tm_cmd_test(struct wl1271 *wl, struct nlattr *tb[])6868+{6969+ int buf_len, ret, len;7070+ struct sk_buff *skb;7171+ void *buf;7272+ u8 answer = 0;7373+7474+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd test");7575+7676+ if (!tb[WL1271_TM_ATTR_DATA])7777+ return -EINVAL;7878+7979+ buf = nla_data(tb[WL1271_TM_ATTR_DATA]);8080+ buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);8181+8282+ if (tb[WL1271_TM_ATTR_ANSWER])8383+ answer = nla_get_u8(tb[WL1271_TM_ATTR_ANSWER]);8484+8585+ if (buf_len > sizeof(struct wl1271_command))8686+ return -EMSGSIZE;8787+8888+ mutex_lock(&wl->mutex);8989+ ret = wl1271_cmd_test(wl, buf, buf_len, answer);9090+ mutex_unlock(&wl->mutex);9191+9292+ if (ret < 0) {9393+ wl1271_warning("testmode cmd test failed: %d", ret);9494+ return ret;9595+ }9696+9797+ if (answer) {9898+ len = nla_total_size(buf_len);9999+ skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, len);100100+ if (!skb)101101+ return -ENOMEM;102102+103103+ NLA_PUT(skb, WL1271_TM_ATTR_DATA, buf_len, buf);104104+ ret = cfg80211_testmode_reply(skb);105105+ if (ret < 0)106106+ return ret;107107+ }108108+109109+ return 0;110110+111111+nla_put_failure:112112+ kfree_skb(skb);113113+ return -EMSGSIZE;114114+}115115+116116+static int wl1271_tm_cmd_interrogate(struct wl1271 *wl, struct nlattr *tb[])117117+{118118+ int ret;119119+ struct wl1271_command *cmd;120120+ struct sk_buff *skb;121121+ u8 ie_id;122122+123123+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd interrogate");124124+125125+ if (!tb[WL1271_TM_ATTR_IE_ID])126126+ return -EINVAL;127127+128128+ ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);129129+130130+ cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);131131+ if (!cmd)132132+ return -ENOMEM;133133+134134+ mutex_lock(&wl->mutex);135135+ ret = wl1271_cmd_interrogate(wl, ie_id, cmd, sizeof(*cmd));136136+ mutex_unlock(&wl->mutex);137137+138138+ if (ret < 0) {139139+ wl1271_warning("testmode cmd interrogate failed: %d", ret);140140+ return ret;141141+ }142142+143143+ skb = cfg80211_testmode_alloc_reply_skb(wl->hw->wiphy, sizeof(*cmd));144144+ if (!skb)145145+ return -ENOMEM;146146+147147+ NLA_PUT(skb, WL1271_TM_ATTR_DATA, sizeof(*cmd), cmd);148148+149149+ return 0;150150+151151+nla_put_failure:152152+ kfree_skb(skb);153153+ return -EMSGSIZE;154154+}155155+156156+static int wl1271_tm_cmd_configure(struct wl1271 *wl, struct nlattr *tb[])157157+{158158+ int buf_len, ret;159159+ void *buf;160160+ u8 ie_id;161161+162162+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd configure");163163+164164+ if (!tb[WL1271_TM_ATTR_DATA])165165+ return -EINVAL;166166+ if (!tb[WL1271_TM_ATTR_IE_ID])167167+ return -EINVAL;168168+169169+ ie_id = nla_get_u8(tb[WL1271_TM_ATTR_IE_ID]);170170+ buf = nla_data(tb[WL1271_TM_ATTR_DATA]);171171+ buf_len = nla_len(tb[WL1271_TM_ATTR_DATA]);172172+173173+ if (buf_len > sizeof(struct wl1271_command))174174+ return -EMSGSIZE;175175+176176+ mutex_lock(&wl->mutex);177177+ ret = wl1271_cmd_configure(wl, ie_id, buf, buf_len);178178+ mutex_unlock(&wl->mutex);179179+180180+ if (ret < 0) {181181+ wl1271_warning("testmode cmd configure failed: %d", ret);182182+ return ret;183183+ }184184+185185+ return 0;186186+}187187+188188+static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])189189+{190190+ int ret = 0;191191+ size_t len;192192+ void *buf;193193+194194+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd nvs push");195195+196196+ if (!tb[WL1271_TM_ATTR_DATA])197197+ return -EINVAL;198198+199199+ buf = nla_data(tb[WL1271_TM_ATTR_DATA]);200200+ len = nla_len(tb[WL1271_TM_ATTR_DATA]);201201+202202+ if (len != sizeof(struct wl1271_nvs_file)) {203203+ wl1271_error("nvs size is not as expected: %zu != %zu",204204+ len, sizeof(struct wl1271_nvs_file));205205+ return -EMSGSIZE;206206+ }207207+208208+ mutex_lock(&wl->mutex);209209+210210+ kfree(wl->nvs);211211+212212+ wl->nvs = kmalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);213213+ if (!wl->nvs) {214214+ wl1271_error("could not allocate memory for the nvs file");215215+ ret = -ENOMEM;216216+ goto out;217217+ }218218+219219+ memcpy(wl->nvs, buf, len);220220+221221+ wl1271_debug(DEBUG_TESTMODE, "testmode pushed nvs");222222+223223+out:224224+ mutex_unlock(&wl->mutex);225225+226226+ return ret;227227+}228228+229229+static int wl1271_tm_cmd_set_plt_mode(struct wl1271 *wl, struct nlattr *tb[])230230+{231231+ u32 val;232232+ int ret;233233+234234+ wl1271_debug(DEBUG_TESTMODE, "testmode cmd set plt mode");235235+236236+ if (!tb[WL1271_TM_ATTR_PLT_MODE])237237+ return -EINVAL;238238+239239+ val = nla_get_u32(tb[WL1271_TM_ATTR_PLT_MODE]);240240+241241+ switch (val) {242242+ case 0:243243+ ret = wl1271_plt_stop(wl);244244+ break;245245+ case 1:246246+ ret = wl1271_plt_start(wl);247247+ break;248248+ default:249249+ ret = -EINVAL;250250+ break;251251+ }252252+253253+ return ret;254254+}255255+256256+int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len)257257+{258258+ struct wl1271 *wl = hw->priv;259259+ struct nlattr *tb[WL1271_TM_ATTR_MAX + 1];260260+ int err;261261+262262+ err = nla_parse(tb, WL1271_TM_ATTR_MAX, data, len, wl1271_tm_policy);263263+ if (err)264264+ return err;265265+266266+ if (!tb[WL1271_TM_ATTR_CMD_ID])267267+ return -EINVAL;268268+269269+ switch (nla_get_u32(tb[WL1271_TM_ATTR_CMD_ID])) {270270+ case WL1271_TM_CMD_TEST:271271+ return wl1271_tm_cmd_test(wl, tb);272272+ case WL1271_TM_CMD_INTERROGATE:273273+ return wl1271_tm_cmd_interrogate(wl, tb);274274+ case WL1271_TM_CMD_CONFIGURE:275275+ return wl1271_tm_cmd_configure(wl, tb);276276+ case WL1271_TM_CMD_NVS_PUSH:277277+ return wl1271_tm_cmd_nvs_push(wl, tb);278278+ case WL1271_TM_CMD_SET_PLT_MODE:279279+ return wl1271_tm_cmd_set_plt_mode(wl, tb);280280+ default:281281+ return -EOPNOTSUPP;282282+ }283283+}
+31
drivers/net/wireless/wl12xx/wl1271_testmode.h
···11+/*22+ * This file is part of wl127133+ *44+ * Copyright (C) 2010 Nokia Corporation55+ *66+ * Contact: Luciano Coelho <luciano.coelho@nokia.com>77+ *88+ * This program is free software; you can redistribute it and/or99+ * modify it under the terms of the GNU General Public License1010+ * version 2 as published by the Free Software Foundation.1111+ *1212+ * This program is distributed in the hope that it will be useful, but1313+ * WITHOUT ANY WARRANTY; without even the implied warranty of1414+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1515+ * General Public License for more details.1616+ *1717+ * You should have received a copy of the GNU General Public License1818+ * along with this program; if not, write to the Free Software1919+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA2020+ * 02110-1301 USA2121+ *2222+ */2323+2424+#ifndef __WL1271_TESTMODE_H__2525+#define __WL1271_TESTMODE_H__2626+2727+#include <net/mac80211.h>2828+2929+int wl1271_tm_cmd(struct ieee80211_hw *hw, void *data, int len);3030+3131+#endif /* __WL1271_TESTMODE_H__ */
+16-12
drivers/net/wireless/wl12xx/wl1271_tx.c
···26262727#include "wl1271.h"2828#include "wl1271_spi.h"2929+#include "wl1271_io.h"2930#include "wl1271_reg.h"3031#include "wl1271_ps.h"3132#include "wl1271_tx.h"···8887 u32 extra, struct ieee80211_tx_info *control)8988{9089 struct wl1271_tx_hw_descr *desc;9191- int pad;9090+ int pad, ac;9291 u16 tx_attr;93929493 desc = (struct wl1271_tx_hw_descr *) skb->data;···108107109108 /* configure the tx attributes */110109 tx_attr = wl->session_counter << TX_HW_ATTR_OFST_SESSION_COUNTER;111111- /* FIXME: do we know the packet priority? can we identify mgmt112112- packets, and use max prio for them at least? */113113- desc->tid = 0;110110+111111+ /* queue */112112+ ac = wl1271_tx_get_queue(skb_get_queue_mapping(skb));113113+ desc->tid = wl1271_tx_ac_to_tid(ac);114114+114115 desc->aid = TX_HW_DEFAULT_AID;115116 desc->reserved = 0;116117···166163 len = WL1271_TX_ALIGN(skb->len);167164168165 /* perform a fixed address block write with the packet */169169- wl1271_spi_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);166166+ wl1271_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);170167171168 /* write packet new counter into the write access register */172169 wl->tx_packets_count++;173173- wl1271_spi_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);170170+ wl1271_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);174171175172 desc = (struct wl1271_tx_hw_descr *) skb->data;176173 wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",···204201 ret = wl1271_cmd_set_default_wep_key(wl, idx);205202 if (ret < 0)206203 return ret;204204+ wl->default_key = idx;207205 }208206 }209207···376372 wl1271_debug(DEBUG_TX, "tx_complete received, packets: %d", count);377373378374 /* read the tx results from the chipset */379379- wl1271_spi_read(wl, le32_to_cpu(memmap->tx_result),380380- wl->tx_res_if, sizeof(*wl->tx_res_if), false);375375+ wl1271_read(wl, le32_to_cpu(memmap->tx_result),376376+ wl->tx_res_if, sizeof(*wl->tx_res_if), false);381377382378 /* verify that the result buffer is not getting overrun */383379 if (count > TX_HW_RESULT_QUEUE_LEN) {···398394 }399395400396 /* write host counter to chipset (to ack) */401401- wl1271_spi_write32(wl, le32_to_cpu(memmap->tx_result) +402402- offsetof(struct wl1271_tx_hw_res_if,403403- tx_result_host_counter),404404- le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));397397+ wl1271_write32(wl, le32_to_cpu(memmap->tx_result) +398398+ offsetof(struct wl1271_tx_hw_res_if,399399+ tx_result_host_counter),400400+ le32_to_cpu(wl->tx_res_if->tx_result_fw_counter));405401}406402407403/* caller must hold wl->mutex */
+36
drivers/net/wireless/wl12xx/wl1271_tx.h
···123123 struct wl1271_tx_hw_res_descr tx_results_queue[TX_HW_RESULT_QUEUE_LEN];124124} __attribute__ ((packed));125125126126+static inline int wl1271_tx_get_queue(int queue)127127+{128128+ /* FIXME: use best effort until WMM is enabled */129129+ return CONF_TX_AC_BE;130130+131131+ switch (queue) {132132+ case 0:133133+ return CONF_TX_AC_VO;134134+ case 1:135135+ return CONF_TX_AC_VI;136136+ case 2:137137+ return CONF_TX_AC_BE;138138+ case 3:139139+ return CONF_TX_AC_BK;140140+ default:141141+ return CONF_TX_AC_BE;142142+ }143143+}144144+145145+/* wl1271 tx descriptor needs the tid and we need to convert it from ac */146146+static inline int wl1271_tx_ac_to_tid(int ac)147147+{148148+ switch (ac) {149149+ case 0:150150+ return 0;151151+ case 1:152152+ return 2;153153+ case 2:154154+ return 4;155155+ case 3:156156+ return 6;157157+ default:158158+ return 0;159159+ }160160+}161161+126162void wl1271_tx_work(struct work_struct *work);127163void wl1271_tx_complete(struct wl1271 *wl, u32 count);128164void wl1271_tx_flush(struct wl1271 *wl);
+7
drivers/ssb/driver_chipcommon_pmu.c
···332332 case 0x5354:333333 ssb_pmu0_pllinit_r0(cc, crystalfreq);334334 break;335335+ case 0x4322:336336+ if (cc->pmu.rev == 2) {337337+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_ADDR, 0x0000000A);338338+ chipco_write32(cc, SSB_CHIPCO_PLLCTL_DATA, 0x380005C0);339339+ }340340+ break;335341 default:336342 ssb_printk(KERN_ERR PFX337343 "ERROR: PLL init unknown for device %04X\n",···423417424418 switch (bus->chip_id) {425419 case 0x4312:420420+ case 0x4322:426421 /* We keep the default settings:427422 * min_msk = 0xCBB428423 * max_msk = 0x7FFFF
···61686168 u16 sc ;61696169 unsigned int frag,seq;61706170 hdr = (struct ieee80211_hdr_3addr *)buffer;61716171- sc = le16_to_cpu(hdr->seq_ctl);61716171+ sc = le16_to_cpu(hdr->seq_ctrl);61726172 frag = WLAN_GET_SEQ_FRAG(sc);61736173 seq = WLAN_GET_SEQ_SEQ(sc);61746174 //cosa add 04292008 to record the sequence number···68276827 tmp_buf = (u8*)skb->data;// + get_rxpacket_shiftbytes_819xusb(pstats);6828682868296829 hdr = (struct ieee80211_hdr_3addr *)tmp_buf;68306830- fc = le16_to_cpu(hdr->frame_ctl);68306830+ fc = le16_to_cpu(hdr->frame_control);68316831 type = WLAN_FC_GET_TYPE(fc);68326832 praddr = hdr->addr1;68336833
+50-1
include/linux/nl80211.h
···33/*44 * 802.11 netlink interface public header55 *66- * Copyright 2006, 2007, 2008 Johannes Berg <johannes@sipsolutions.net>66+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>77 * Copyright 2008 Michael Wu <flamingice@sourmilk.net>88 * Copyright 2008 Luis Carlos Cobo <luisca@cozybit.com>99 * Copyright 2008 Michael Buesch <mb@bu3sch.de>···299299 * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface300300 * and @NL80211_ATTR_TX_RATES the set of allowed rates.301301 *302302+ * @NL80211_CMD_REGISTER_ACTION: Register for receiving certain action frames303303+ * (via @NL80211_CMD_ACTION) for processing in userspace. This command304304+ * requires an interface index and a match attribute containing the first305305+ * few bytes of the frame that should match, e.g. a single byte for only306306+ * a category match or four bytes for vendor frames including the OUI.307307+ * The registration cannot be dropped, but is removed automatically308308+ * when the netlink socket is closed. Multiple registrations can be made.309309+ * @NL80211_CMD_ACTION: Action frame TX request and RX notification. This310310+ * command is used both as a request to transmit an Action frame and as an311311+ * event indicating reception of an Action frame that was not processed in312312+ * kernel code, but is for us (i.e., which may need to be processed in a313313+ * user space application). %NL80211_ATTR_FRAME is used to specify the314314+ * frame contents (including header). %NL80211_ATTR_WIPHY_FREQ (and315315+ * optionally %NL80211_ATTR_WIPHY_CHANNEL_TYPE) is used to indicate on316316+ * which channel the frame is to be transmitted or was received. This317317+ * channel has to be the current channel (remain-on-channel or the318318+ * operational channel). When called, this operation returns a cookie319319+ * (%NL80211_ATTR_COOKIE) that will be included with the TX status event320320+ * pertaining to the TX request.321321+ * @NL80211_CMD_ACTION_TX_STATUS: Report TX status of an Action frame322322+ * transmitted with %NL80211_CMD_ACTION. %NL80211_ATTR_COOKIE identifies323323+ * the TX command and %NL80211_ATTR_FRAME includes the contents of the324324+ * frame. %NL80211_ATTR_ACK flag is included if the recipient acknowledged325325+ * the frame.326326+ *302327 * @NL80211_CMD_MAX: highest used command number303328 * @__NL80211_CMD_AFTER_LAST: internal use304329 */···411386 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,412387413388 NL80211_CMD_SET_TX_BITRATE_MASK,389389+390390+ NL80211_CMD_REGISTER_ACTION,391391+ NL80211_CMD_ACTION,392392+ NL80211_CMD_ACTION_TX_STATUS,393393+394394+ NL80211_CMD_SET_POWER_SAVE,395395+ NL80211_CMD_GET_POWER_SAVE,414396415397 /* add new commands above here */416398···685653 * rates based on negotiated supported rates information. This attribute686654 * is used with %NL80211_CMD_SET_TX_BITRATE_MASK.687655 *656656+ * @NL80211_ATTR_FRAME_MATCH: A binary attribute which typically must contain657657+ * at least one byte, currently used with @NL80211_CMD_REGISTER_ACTION.658658+ *659659+ * @NL80211_ATTR_ACK: Flag attribute indicating that the frame was660660+ * acknowledged by the recipient.661661+ *688662 * @NL80211_ATTR_MAX: highest attribute number currently defined689663 * @__NL80211_ATTR_AFTER_LAST: internal use690664 */···835797 NL80211_ATTR_WIPHY_COVERAGE_CLASS,836798837799 NL80211_ATTR_TX_RATES,800800+801801+ NL80211_ATTR_FRAME_MATCH,802802+803803+ NL80211_ATTR_ACK,804804+805805+ NL80211_ATTR_PS_STATE,838806839807 /* add attributes here, update the policy in nl80211.c */840808···15761532enum nl80211_band {15771533 NL80211_BAND_2GHZ,15781534 NL80211_BAND_5GHZ,15351535+};15361536+15371537+enum nl80211_ps_state {15381538+ NL80211_PS_DISABLED,15391539+ NL80211_PS_ENABLED,15791540};1580154115811542#endif /* __LINUX_NL80211_H */
+50-4
include/net/cfg80211.h
···33/*44 * 802.11 device and configuration interface55 *66- * Copyright 2006-2009 Johannes Berg <johannes@sipsolutions.net>66+ * Copyright 2006-2010 Johannes Berg <johannes@sipsolutions.net>77 *88 * This program is free software; you can redistribute it and/or modify99 * it under the terms of the GNU General Public License version 2 as···998998 * @cancel_remain_on_channel: Cancel an on-going remain-on-channel operation.999999 * This allows the operation to be terminated prior to timeout based on10001000 * the duration value.10011001+ * @action: Transmit an action frame10011002 *10021003 * @testmode_cmd: run a test mode command10031004 *···11451144 struct net_device *dev,11461145 u64 cookie);1147114611481148- /* some temporary stuff to finish wext */11471147+ int (*action)(struct wiphy *wiphy, struct net_device *dev,11481148+ struct ieee80211_channel *chan,11491149+ enum nl80211_channel_type channel_type,11501150+ const u8 *buf, size_t len, u64 *cookie);11511151+11491152 int (*set_power_mgmt)(struct wiphy *wiphy, struct net_device *dev,11501153 bool enabled, int timeout);11511154};···14501445 * set by driver (if supported) on add_interface BEFORE registering the14511446 * netdev and may otherwise be used by driver read-only, will be update14521447 * by cfg80211 on change_interface14481448+ * @action_registrations: list of registrations for action frames14491449+ * @action_registrations_lock: lock for the list14531450 */14541451struct wireless_dev {14551452 struct wiphy *wiphy;···14601453 /* the remainder of this struct should be private to cfg80211 */14611454 struct list_head list;14621455 struct net_device *netdev;14561456+14571457+ struct list_head action_registrations;14581458+ spinlock_t action_registrations_lock;1463145914641460 struct mutex mtx;14651461···14881478 struct cfg80211_internal_bss *auth_bsses[MAX_AUTH_BSSES];14891479 struct cfg80211_internal_bss *current_bss; /* associated / joined */1490148014811481+ bool ps;14821482+ int ps_timeout;14831483+14911484#ifdef CONFIG_CFG80211_WEXT14921485 /* wext data */14931486 struct {···15021489 u8 bssid[ETH_ALEN], prev_bssid[ETH_ALEN];15031490 u8 ssid[IEEE80211_MAX_SSID_LEN];15041491 s8 default_key, default_mgmt_key;15051505- bool ps, prev_bssid_valid;15061506- int ps_timeout;14921492+ bool prev_bssid_valid;15071493 } wext;15081494#endif15091495};···23022290 */23032291void cfg80211_new_sta(struct net_device *dev, const u8 *mac_addr,23042292 struct station_info *sinfo, gfp_t gfp);22932293+22942294+/**22952295+ * cfg80211_rx_action - notification of received, unprocessed Action frame22962296+ * @dev: network device22972297+ * @freq: Frequency on which the frame was received in MHz22982298+ * @buf: Action frame (header + body)22992299+ * @len: length of the frame data23002300+ * @gfp: context flags23012301+ * Returns %true if a user space application is responsible for rejecting the23022302+ * unrecognized Action frame; %false if no such application is registered23032303+ * (i.e., the driver is responsible for rejecting the unrecognized Action23042304+ * frame)23052305+ *23062306+ * This function is called whenever an Action frame is received for a station23072307+ * mode interface, but is not processed in kernel.23082308+ */23092309+bool cfg80211_rx_action(struct net_device *dev, int freq, const u8 *buf,23102310+ size_t len, gfp_t gfp);23112311+23122312+/**23132313+ * cfg80211_action_tx_status - notification of TX status for Action frame23142314+ * @dev: network device23152315+ * @cookie: Cookie returned by cfg80211_ops::action()23162316+ * @buf: Action frame (header + body)23172317+ * @len: length of the frame data23182318+ * @ack: Whether frame was acknowledged23192319+ * @gfp: context flags23202320+ *23212321+ * This function is called whenever an Action frame was requested to be23222322+ * transmitted with cfg80211_ops::action() to report the TX status of the23232323+ * transmission attempt.23242324+ */23252325+void cfg80211_action_tx_status(struct net_device *dev, u64 cookie,23262326+ const u8 *buf, size_t len, bool ack, gfp_t gfp);2305232723062328#endif /* __NET_CFG80211_H */
+5-1
include/net/mac80211.h
···33 *44 * Copyright 2002-2005, Devicescape Software, Inc.55 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>66- * Copyright 2007-2008 Johannes Berg <johannes@sipsolutions.net>66+ * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>77 *88 * This program is free software; you can redistribute it and/or modify99 * it under the terms of the GNU General Public License version 2 as···264264 * be modified again (no seqno assignment, crypto, etc.)265265 * @IEEE80211_TX_INTFL_HAS_RADIOTAP: This frame was injected and still266266 * has a radiotap header at skb->data.267267+ * @IEEE80211_TX_INTFL_NL80211_FRAME_TX: Frame was requested through nl80211268268+ * MLME command (internal to mac80211 to figure out whether to send TX269269+ * status to user space)267270 */268271enum mac80211_tx_control_flags {269272 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),···289286 IEEE80211_TX_CTL_MORE_FRAMES = BIT(18),290287 IEEE80211_TX_INTFL_RETRANSMISSION = BIT(19),291288 IEEE80211_TX_INTFL_HAS_RADIOTAP = BIT(20),289289+ IEEE80211_TX_INTFL_NL80211_FRAME_TX = BIT(21),292290};293291294292/**
···22 * Copyright 2002-2005, Instant802 Networks, Inc.33 * Copyright 2005-2006, Devicescape Software, Inc.44 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>55- * Copyright 2007 Johannes Berg <johannes@sipsolutions.net>55+ * Copyright 2007-2010 Johannes Berg <johannes@sipsolutions.net>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 as···13971397 ieee80211_is_data(fc) &&13981398 (rx->key || rx->sdata->drop_unencrypted)))13991399 return -EACCES;14001400+14011401+ return 0;14021402+}14031403+14041404+static int14051405+ieee80211_drop_unencrypted_mgmt(struct ieee80211_rx_data *rx)14061406+{14071407+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)rx->skb->data;14081408+ __le16 fc = hdr->frame_control;14091409+ int res;14101410+14111411+ res = ieee80211_drop_unencrypted(rx, fc);14121412+ if (unlikely(res))14131413+ return res;14141414+14001415 if (rx->sta && test_sta_flags(rx->sta, WLAN_STA_MFP)) {14011416 if (unlikely(ieee80211_is_unicast_robust_mgmt_frame(rx->skb) &&14021417 rx->key))···18701855 struct ieee80211_local *local = rx->local;18711856 struct ieee80211_sub_if_data *sdata = rx->sdata;18721857 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;18581858+ struct sk_buff *nskb;18591859+ struct ieee80211_rx_status *status;18731860 int len = rx->skb->len;1874186118751862 if (!ieee80211_is_action(mgmt->frame_control))18761863 return RX_CONTINUE;1877186418781878- if (!rx->sta)18791879- return RX_DROP_MONITOR;18651865+ /* drop too small frames */18661866+ if (len < IEEE80211_MIN_ACTION_SIZE)18671867+ return RX_DROP_UNUSABLE;18681868+18691869+ if (!rx->sta && mgmt->u.action.category != WLAN_CATEGORY_PUBLIC)18701870+ return RX_DROP_UNUSABLE;1880187118811872 if (!(rx->flags & IEEE80211_RX_RA_MATCH))18821882- return RX_DROP_MONITOR;18731873+ return RX_DROP_UNUSABLE;1883187418841884- if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))18851885- return RX_DROP_MONITOR;18861886-18871887- /* all categories we currently handle have action_code */18881888- if (len < IEEE80211_MIN_ACTION_SIZE + 1)18891889- return RX_DROP_MONITOR;18751875+ if (ieee80211_drop_unencrypted_mgmt(rx))18761876+ return RX_DROP_UNUSABLE;1890187718911878 switch (mgmt->u.action.category) {18921879 case WLAN_CATEGORY_BACK:···19011884 if (sdata->vif.type != NL80211_IFTYPE_STATION &&19021885 sdata->vif.type != NL80211_IFTYPE_AP_VLAN &&19031886 sdata->vif.type != NL80211_IFTYPE_AP)19041904- return RX_DROP_MONITOR;18871887+ break;18881888+18891889+ /* verify action_code is present */18901890+ if (len < IEEE80211_MIN_ACTION_SIZE + 1)18911891+ break;1905189219061893 switch (mgmt->u.action.u.addba_req.action_code) {19071894 case WLAN_ACTION_ADDBA_REQ:···19131892 sizeof(mgmt->u.action.u.addba_req)))19141893 return RX_DROP_MONITOR;19151894 ieee80211_process_addba_request(local, rx->sta, mgmt, len);19161916- break;18951895+ goto handled;19171896 case WLAN_ACTION_ADDBA_RESP:19181897 if (len < (IEEE80211_MIN_ACTION_SIZE +19191898 sizeof(mgmt->u.action.u.addba_resp)))19201920- return RX_DROP_MONITOR;18991899+ break;19211900 ieee80211_process_addba_resp(local, rx->sta, mgmt, len);19221922- break;19011901+ goto handled;19231902 case WLAN_ACTION_DELBA:19241903 if (len < (IEEE80211_MIN_ACTION_SIZE +19251904 sizeof(mgmt->u.action.u.delba)))19261926- return RX_DROP_MONITOR;19051905+ break;19271906 ieee80211_process_delba(sdata, rx->sta, mgmt, len);19281928- break;19071907+ goto handled;19291908 }19301909 break;19311910 case WLAN_CATEGORY_SPECTRUM_MGMT:19321911 if (local->hw.conf.channel->band != IEEE80211_BAND_5GHZ)19331933- return RX_DROP_MONITOR;19121912+ break;1934191319351914 if (sdata->vif.type != NL80211_IFTYPE_STATION)19361936- return RX_DROP_MONITOR;19151915+ break;19161916+19171917+ /* verify action_code is present */19181918+ if (len < IEEE80211_MIN_ACTION_SIZE + 1)19191919+ break;1937192019381921 switch (mgmt->u.action.u.measurement.action_code) {19391922 case WLAN_ACTION_SPCT_MSR_REQ:19401923 if (len < (IEEE80211_MIN_ACTION_SIZE +19411924 sizeof(mgmt->u.action.u.measurement)))19421942- return RX_DROP_MONITOR;19251925+ break;19431926 ieee80211_process_measurement_req(sdata, mgmt, len);19441944- break;19271927+ goto handled;19451928 case WLAN_ACTION_SPCT_CHL_SWITCH:19461929 if (len < (IEEE80211_MIN_ACTION_SIZE +19471930 sizeof(mgmt->u.action.u.chan_switch)))19481948- return RX_DROP_MONITOR;19311931+ break;1949193219501933 if (sdata->vif.type != NL80211_IFTYPE_STATION)19511951- return RX_DROP_MONITOR;19341934+ break;1952193519531936 if (memcmp(mgmt->bssid, sdata->u.mgd.bssid, ETH_ALEN))19541954- return RX_DROP_MONITOR;19371937+ break;1955193819561939 return ieee80211_sta_rx_mgmt(sdata, rx->skb);19571940 }···19631938 case WLAN_CATEGORY_SA_QUERY:19641939 if (len < (IEEE80211_MIN_ACTION_SIZE +19651940 sizeof(mgmt->u.action.u.sa_query)))19661966- return RX_DROP_MONITOR;19411941+ break;19421942+19671943 switch (mgmt->u.action.u.sa_query.action) {19681944 case WLAN_ACTION_SA_QUERY_REQUEST:19691945 if (sdata->vif.type != NL80211_IFTYPE_STATION)19701970- return RX_DROP_MONITOR;19461946+ break;19711947 ieee80211_process_sa_query_req(sdata, mgmt, len);19721972- break;19731973- case WLAN_ACTION_SA_QUERY_RESPONSE:19741974- /*19751975- * SA Query response is currently only used in AP mode19761976- * and it is processed in user space.19771977- */19781978- return RX_CONTINUE;19481948+ goto handled;19791949 }19801950 break;19811981- default:19821982- /* do not process rejected action frames */19831983- if (mgmt->u.action.category & 0x80)19841984- return RX_DROP_MONITOR;19851985-19861986- return RX_CONTINUE;19871951 }1988195219891989- rx->sta->rx_packets++;19531953+ /*19541954+ * For AP mode, hostapd is responsible for handling any action19551955+ * frames that we didn't handle, including returning unknown19561956+ * ones. For all other modes we will return them to the sender,19571957+ * setting the 0x80 bit in the action category, as required by19581958+ * 802.11-2007 7.3.1.11.19591959+ */19601960+ if (sdata->vif.type == NL80211_IFTYPE_AP ||19611961+ sdata->vif.type == NL80211_IFTYPE_AP_VLAN)19621962+ return RX_DROP_MONITOR;19631963+19641964+ /*19651965+ * Getting here means the kernel doesn't know how to handle19661966+ * it, but maybe userspace does ... include returned frames19671967+ * so userspace can register for those to know whether ones19681968+ * it transmitted were processed or returned.19691969+ */19701970+ status = IEEE80211_SKB_RXCB(rx->skb);19711971+19721972+ if (sdata->vif.type == NL80211_IFTYPE_STATION &&19731973+ cfg80211_rx_action(rx->sdata->dev, status->freq,19741974+ rx->skb->data, rx->skb->len,19751975+ GFP_ATOMIC))19761976+ goto handled;19771977+19781978+ /* do not return rejected action frames */19791979+ if (mgmt->u.action.category & 0x80)19801980+ return RX_DROP_UNUSABLE;19811981+19821982+ nskb = skb_copy_expand(rx->skb, local->hw.extra_tx_headroom, 0,19831983+ GFP_ATOMIC);19841984+ if (nskb) {19851985+ struct ieee80211_mgmt *mgmt = (void *)nskb->data;19861986+19871987+ mgmt->u.action.category |= 0x80;19881988+ memcpy(mgmt->da, mgmt->sa, ETH_ALEN);19891989+ memcpy(mgmt->sa, rx->sdata->vif.addr, ETH_ALEN);19901990+19911991+ memset(nskb->cb, 0, sizeof(nskb->cb));19921992+19931993+ ieee80211_tx_skb(rx->sdata, nskb);19941994+ }19951995+19961996+ handled:19971997+ if (rx->sta)19981998+ rx->sta->rx_packets++;19901999 dev_kfree_skb(rx->skb);19912000 return RX_QUEUED;19922001}···20291970ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)20301971{20311972 struct ieee80211_sub_if_data *sdata = rx->sdata;20322032- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *) rx->skb->data;20331973 ieee80211_rx_result rxs;2034197420351975 if (!(rx->flags & IEEE80211_RX_RA_MATCH))20361976 return RX_DROP_MONITOR;2037197720382038- if (ieee80211_drop_unencrypted(rx, mgmt->frame_control))20392039- return RX_DROP_MONITOR;19781978+ if (ieee80211_drop_unencrypted_mgmt(rx))19791979+ return RX_DROP_UNUSABLE;2040198020411981 rxs = ieee80211_work_rx_mgmt(rx->sdata, rx->skb);20421982 if (rxs != RX_CONTINUE)
+6-1
net/mac80211/status.c
···22 * Copyright 2002-2005, Instant802 Networks, Inc.33 * Copyright 2005-2006, Devicescape Software, Inc.44 * Copyright 2006-2007 Jiri Benc <jbenc@suse.cz>55- * Copyright 2008-2009 Johannes Berg <johannes@sipsolutions.net>55+ * Copyright 2008-2010 Johannes Berg <johannes@sipsolutions.net>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 as···287287 mod_timer(&local->dynamic_ps_timer, jiffies +288288 msecs_to_jiffies(10));289289 }290290+291291+ if (info->flags & IEEE80211_TX_INTFL_NL80211_FRAME_TX)292292+ cfg80211_action_tx_status(293293+ skb->dev, (unsigned long) skb, skb->data, skb->len,294294+ !!(info->flags & IEEE80211_TX_STAT_ACK), GFP_ATOMIC);290295291296 /* this was a transmitted frame, but now we want to reuse it */292297 skb_orphan(skb);