···3737 ---help---3838 Select this to ath10k use tracing infrastructure.39394040+config ATH10K_DFS_CERTIFIED4141+ bool "Atheros DFS support for certified platforms"4242+ depends on ATH10K && CFG80211_CERTIFICATION_ONUS4343+ default n4444+ ---help---4545+ This option enables DFS support for initiating radiation on4646+ ath10k.
+11
drivers/net/wireless/ath/ath10k/core.h
···253253 u8 bssid[ETH_ALEN];254254 } ibss;255255 } u;256256+257257+ u8 fixed_rate;258258+ u8 fixed_nss;256259};257260258261struct ath10k_vif_iter {···275272 struct delayed_work htt_stats_dwork;276273 struct ath10k_dfs_stats dfs_stats;277274 struct ath_dfs_pool_stats dfs_pool_stats;275275+276276+ u32 fw_dbglog_mask;278277};279278280279enum ath10k_state {···310305311306 /* firmware support tx frame management over WMI, otherwise it's HTT */312307 ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX = 2,308308+309309+ /* Firmware does not support P2P */310310+ ATH10K_FW_FEATURE_NO_P2P = 3,313311314312 /* keep last */315313 ATH10K_FW_FEATURE_COUNT,···436428 struct list_head arvifs;437429 struct list_head peers;438430 wait_queue_head_t peer_mapping_wq;431431+432432+ /* number of created peers; protected by data_lock */433433+ int num_peers;439434440435 struct work_struct offchan_tx_work;441436 struct sk_buff_head offchan_tx_queue;
+66
drivers/net/wireless/ath/ath10k/debug.c
···614614 .llseek = default_llseek,615615};616616617617+static ssize_t ath10k_read_fw_dbglog(struct file *file,618618+ char __user *user_buf,619619+ size_t count, loff_t *ppos)620620+{621621+ struct ath10k *ar = file->private_data;622622+ unsigned int len;623623+ char buf[32];624624+625625+ len = scnprintf(buf, sizeof(buf), "0x%08x\n",626626+ ar->debug.fw_dbglog_mask);627627+628628+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);629629+}630630+631631+static ssize_t ath10k_write_fw_dbglog(struct file *file,632632+ const char __user *user_buf,633633+ size_t count, loff_t *ppos)634634+{635635+ struct ath10k *ar = file->private_data;636636+ unsigned long mask;637637+ int ret;638638+639639+ ret = kstrtoul_from_user(user_buf, count, 0, &mask);640640+ if (ret)641641+ return ret;642642+643643+ mutex_lock(&ar->conf_mutex);644644+645645+ ar->debug.fw_dbglog_mask = mask;646646+647647+ if (ar->state == ATH10K_STATE_ON) {648648+ ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);649649+ if (ret) {650650+ ath10k_warn("dbglog cfg failed from debugfs: %d\n",651651+ ret);652652+ goto exit;653653+ }654654+ }655655+656656+ ret = count;657657+658658+exit:659659+ mutex_unlock(&ar->conf_mutex);660660+661661+ return ret;662662+}663663+664664+static const struct file_operations fops_fw_dbglog = {665665+ .read = ath10k_read_fw_dbglog,666666+ .write = ath10k_write_fw_dbglog,667667+ .open = simple_open,668668+ .owner = THIS_MODULE,669669+ .llseek = default_llseek,670670+};671671+617672int ath10k_debug_start(struct ath10k *ar)618673{619674 int ret;···679624 if (ret)680625 /* continue normally anyway, this isn't serious */681626 ath10k_warn("failed to start htt stats workqueue: %d\n", ret);627627+628628+ if (ar->debug.fw_dbglog_mask) {629629+ ret = ath10k_wmi_dbglog_cfg(ar, ar->debug.fw_dbglog_mask);630630+ if (ret)631631+ /* not serious */632632+ ath10k_warn("failed to enable dbglog during start: %d",633633+ ret);634634+ }682635683636 return 0;684637}···809746810747 debugfs_create_file("htt_stats_mask", S_IRUSR, ar->debug.debugfs_phy,811748 ar, &fops_htt_stats_mask);749749+750750+ debugfs_create_file("fw_dbglog", S_IRUSR, ar->debug.debugfs_phy,751751+ ar, &fops_fw_dbglog);812752813753 if (config_enabled(CONFIG_ATH10K_DFS_CERTIFIED)) {814754 debugfs_create_file("dfs_simulate_radar", S_IWUSR,
···231231 ~IEEE80211_FCTL_PROTECTED);232232 }233233234234- if (info->status == HTT_RX_IND_MPDU_STATUS_TKIP_MIC_ERR)234234+ if (info->mic_err)235235 status->flag |= RX_FLAG_MMIC_ERROR;236236237237 if (info->fcs_err)
+100-6
drivers/net/wireless/ath/ath10k/wmi.c
···1616 */17171818#include <linux/skbuff.h>1919+#include <linux/ctype.h>19202021#include "core.h"2122#include "htc.h"···876875 struct wmi_mgmt_rx_event_v2 *ev_v2;877876 struct wmi_mgmt_rx_hdr_v1 *ev_hdr;878877 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);878878+ struct ieee80211_channel *ch;879879 struct ieee80211_hdr *hdr;880880 u32 rx_status;881881 u32 channel;···929927 if (rx_status & WMI_RX_STATUS_ERR_MIC)930928 status->flag |= RX_FLAG_MMIC_ERROR;931929932932- status->band = phy_mode_to_band(phy_mode);930930+ /* HW can Rx CCK rates on 5GHz. In that case phy_mode is set to931931+ * MODE_11B. This means phy_mode is not a reliable source for the band932932+ * of mgmt rx. */933933+934934+ ch = ar->scan_channel;935935+ if (!ch)936936+ ch = ar->rx_channel;937937+938938+ if (ch) {939939+ status->band = ch->band;940940+941941+ if (phy_mode == MODE_11B &&942942+ status->band == IEEE80211_BAND_5GHZ)943943+ ath10k_dbg(ATH10K_DBG_MGMT, "wmi mgmt rx 11b (CCK) on 5GHz\n");944944+ } else {945945+ ath10k_warn("using (unreliable) phy_mode to extract band for mgmt rx\n");946946+ status->band = phy_mode_to_band(phy_mode);947947+ }948948+933949 status->freq = ieee80211_channel_to_frequency(channel, status->band);934950 status->signal = snr + ATH10K_DEFAULT_NOISE_FLOOR;935951 status->rate_idx = get_rate_idx(rate, status->band);···957937 hdr = (struct ieee80211_hdr *)skb->data;958938 fc = le16_to_cpu(hdr->frame_control);959939960960- if (fc & IEEE80211_FCTL_PROTECTED) {940940+ /* FW delivers WEP Shared Auth frame with Protected Bit set and941941+ * encrypted payload. However in case of PMF it delivers decrypted942942+ * frames with Protected Bit set. */943943+ if (ieee80211_has_protected(hdr->frame_control) &&944944+ !ieee80211_is_auth(hdr->frame_control)) {961945 status->flag |= RX_FLAG_DECRYPTED | RX_FLAG_IV_STRIPPED |962946 RX_FLAG_MMIC_STRIPPED;963947 hdr->frame_control = __cpu_to_le16(fc &···10711047 ath10k_dbg(ATH10K_DBG_WMI, "WMI_ECHO_EVENTID\n");10721048}1073104910741074-static void ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)10501050+static int ath10k_wmi_event_debug_mesg(struct ath10k *ar, struct sk_buff *skb)10751051{10761076- ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_MESG_EVENTID\n");10521052+ ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug mesg len %d\n",10531053+ skb->len);10541054+10551055+ trace_ath10k_wmi_dbglog(skb->data, skb->len);10561056+10571057+ return 0;10771058}1078105910791060static void ath10k_wmi_event_update_stats(struct ath10k *ar,···16821653}1683165416841655static void ath10k_wmi_event_debug_print(struct ath10k *ar,16851685- struct sk_buff *skb)16561656+ struct sk_buff *skb)16861657{16871687- ath10k_dbg(ATH10K_DBG_WMI, "WMI_DEBUG_PRINT_EVENTID\n");16581658+ char buf[101], c;16591659+ int i;16601660+16611661+ for (i = 0; i < sizeof(buf) - 1; i++) {16621662+ if (i >= skb->len)16631663+ break;16641664+16651665+ c = skb->data[i];16661666+16671667+ if (c == '\0')16681668+ break;16691669+16701670+ if (isascii(c) && isprint(c))16711671+ buf[i] = c;16721672+ else16731673+ buf[i] = '.';16741674+ }16751675+16761676+ if (i == sizeof(buf) - 1)16771677+ ath10k_warn("wmi debug print truncated: %d\n", skb->len);16781678+16791679+ /* for some reason the debug prints end with \n, remove that */16801680+ if (skb->data[i - 1] == '\n')16811681+ i--;16821682+16831683+ /* the last byte is always reserved for the null character */16841684+ buf[i] = '\0';16851685+16861686+ ath10k_dbg(ATH10K_DBG_WMI, "wmi event debug print '%s'\n", buf);16881687}1689168816901689static void ath10k_wmi_event_pdev_qvit(struct ath10k *ar, struct sk_buff *skb)···35013444 ath10k_dbg(ATH10K_DBG_WMI, "wmi force fw hang %d delay %d\n",35023445 type, delay_ms);35033446 return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);34473447+}34483448+34493449+int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable)34503450+{34513451+ struct wmi_dbglog_cfg_cmd *cmd;34523452+ struct sk_buff *skb;34533453+ u32 cfg;34543454+34553455+ skb = ath10k_wmi_alloc_skb(sizeof(*cmd));34563456+ if (!skb)34573457+ return -ENOMEM;34583458+34593459+ cmd = (struct wmi_dbglog_cfg_cmd *)skb->data;34603460+34613461+ if (module_enable) {34623462+ cfg = SM(ATH10K_DBGLOG_LEVEL_VERBOSE,34633463+ ATH10K_DBGLOG_CFG_LOG_LVL);34643464+ } else {34653465+ /* set back defaults, all modules with WARN level */34663466+ cfg = SM(ATH10K_DBGLOG_LEVEL_WARN,34673467+ ATH10K_DBGLOG_CFG_LOG_LVL);34683468+ module_enable = ~0;34693469+ }34703470+34713471+ cmd->module_enable = __cpu_to_le32(module_enable);34723472+ cmd->module_valid = __cpu_to_le32(~0);34733473+ cmd->config_enable = __cpu_to_le32(cfg);34743474+ cmd->config_valid = __cpu_to_le32(ATH10K_DBGLOG_CFG_LOG_LVL_MASK);34753475+34763476+ ath10k_dbg(ATH10K_DBG_WMI,34773477+ "wmi dbglog cfg modules %08x %08x config %08x %08x\n",34783478+ __le32_to_cpu(cmd->module_enable),34793479+ __le32_to_cpu(cmd->module_valid),34803480+ __le32_to_cpu(cmd->config_enable),34813481+ __le32_to_cpu(cmd->config_valid));34823482+34833483+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->dbglog_cfg_cmdid);35043484}
+61
drivers/net/wireless/ath/ath10k/wmi.h
···30033003 const void *key_data;30043004};3005300530063006+/*30073007+ * vdev fixed rate format:30083008+ * - preamble - b7:b6 - see WMI_RATE_PREMABLE_30093009+ * - nss - b5:b4 - ss number (0 mean 1ss)30103010+ * - rate_mcs - b3:b0 - as below30113011+ * CCK: 0 - 11Mbps, 1 - 5,5Mbps, 2 - 2Mbps, 3 - 1Mbps,30123012+ * 4 - 11Mbps (s), 5 - 5,5Mbps (s), 6 - 2Mbps (s)30133013+ * OFDM: 0 - 48Mbps, 1 - 24Mbps, 2 - 12Mbps, 3 - 6Mbps,30143014+ * 4 - 54Mbps, 5 - 36Mbps, 6 - 18Mbps, 7 - 9Mbps30153015+ * HT/VHT: MCS index30163016+ */30173017+30063018/* Preamble types to be used with VDEV fixed rate configuration */30073019enum wmi_rate_preamble {30083020 WMI_RATE_PREAMBLE_OFDM,···41024090 __le32 delay_ms;41034091} __packed;4104409240934093+enum ath10k_dbglog_level {40944094+ ATH10K_DBGLOG_LEVEL_VERBOSE = 0,40954095+ ATH10K_DBGLOG_LEVEL_INFO = 1,40964096+ ATH10K_DBGLOG_LEVEL_WARN = 2,40974097+ ATH10K_DBGLOG_LEVEL_ERR = 3,40984098+};40994099+41004100+/* VAP ids to enable dbglog */41014101+#define ATH10K_DBGLOG_CFG_VAP_LOG_LSB 041024102+#define ATH10K_DBGLOG_CFG_VAP_LOG_MASK 0x0000ffff41034103+41044104+/* to enable dbglog in the firmware */41054105+#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_LSB 1641064106+#define ATH10K_DBGLOG_CFG_REPORTING_ENABLE_MASK 0x0001000041074107+41084108+/* timestamp resolution */41094109+#define ATH10K_DBGLOG_CFG_RESOLUTION_LSB 1741104110+#define ATH10K_DBGLOG_CFG_RESOLUTION_MASK 0x000E000041114111+41124112+/* number of queued messages before sending them to the host */41134113+#define ATH10K_DBGLOG_CFG_REPORT_SIZE_LSB 2041144114+#define ATH10K_DBGLOG_CFG_REPORT_SIZE_MASK 0x0ff0000041154115+41164116+/*41174117+ * Log levels to enable. This defines the minimum level to enable, this is41184118+ * not a bitmask. See enum ath10k_dbglog_level for the values.41194119+ */41204120+#define ATH10K_DBGLOG_CFG_LOG_LVL_LSB 2841214121+#define ATH10K_DBGLOG_CFG_LOG_LVL_MASK 0x7000000041224122+41234123+/*41244124+ * Note: this is a cleaned up version of a struct firmware uses. For41254125+ * example, config_valid was hidden inside an array.41264126+ */41274127+struct wmi_dbglog_cfg_cmd {41284128+ /* bitmask to hold mod id config*/41294129+ __le32 module_enable;41304130+41314131+ /* see ATH10K_DBGLOG_CFG_ */41324132+ __le32 config_enable;41334133+41344134+ /* mask of module id bits to be changed */41354135+ __le32 module_valid;41364136+41374137+ /* mask of config bits to be changed, see ATH10K_DBGLOG_CFG_ */41384138+ __le32 config_valid;41394139+} __packed;41404140+41054141#define ATH10K_RTS_MAX 234741064142#define ATH10K_FRAGMT_THRESHOLD_MIN 54041074143#define ATH10K_FRAGMT_THRESHOLD_MAX 2346···42274167int ath10k_wmi_force_fw_hang(struct ath10k *ar,42284168 enum wmi_force_fw_hang_type type, u32 delay_ms);42294169int ath10k_wmi_mgmt_tx(struct ath10k *ar, struct sk_buff *skb);41704170+int ath10k_wmi_dbglog_cfg(struct ath10k *ar, u32 module_enable);4230417142314172#endif /* _WMI_H_ */
+8-26
drivers/net/wireless/ath/ath5k/base.c
···12381238ath5k_check_ibss_tsf(struct ath5k_hw *ah, struct sk_buff *skb,12391239 struct ieee80211_rx_status *rxs)12401240{12411241- struct ath_common *common = ath5k_hw_common(ah);12421241 u64 tsf, bc_tstamp;12431242 u32 hw_tu;12441243 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;1245124412461246- if (ieee80211_is_beacon(mgmt->frame_control) &&12471247- le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS &&12481248- ether_addr_equal_64bits(mgmt->bssid, common->curbssid)) {12451245+ if (le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS) {12491246 /*12501247 * Received an IBSS beacon with the same BSSID. Hardware *must*12511248 * have updated the local TSF. We have to work around various···12961299 "fixed beacon timers after beacon receive\n");12971300 }12981301 }12991299-}13001300-13011301-static void13021302-ath5k_update_beacon_rssi(struct ath5k_hw *ah, struct sk_buff *skb, int rssi)13031303-{13041304- struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data;13051305- struct ath_common *common = ath5k_hw_common(ah);13061306-13071307- /* only beacons from our BSSID */13081308- if (!ieee80211_is_beacon(mgmt->frame_control) ||13091309- !ether_addr_equal_64bits(mgmt->bssid, common->curbssid))13101310- return;13111311-13121312- ewma_add(&ah->ah_beacon_rssi_avg, rssi);13131313-13141314- /* in IBSS mode we should keep RSSI statistics per neighbour */13151315- /* le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS */13161302}1317130313181304/*···13701390 struct ath5k_rx_status *rs)13711391{13721392 struct ieee80211_rx_status *rxs;13931393+ struct ath_common *common = ath5k_hw_common(ah);1373139413741395 ath5k_remove_padding(skb);13751396···1423144214241443 trace_ath5k_rx(ah, skb);1425144414261426- ath5k_update_beacon_rssi(ah, skb, rs->rs_rssi);14451445+ if (ath_is_mybeacon(common, (struct ieee80211_hdr *)skb->data)) {14461446+ ewma_add(&ah->ah_beacon_rssi_avg, rs->rs_rssi);1427144714281428- /* check beacons in IBSS mode */14291429- if (ah->opmode == NL80211_IFTYPE_ADHOC)14301430- ath5k_check_ibss_tsf(ah, skb, rxs);14481448+ /* check beacons in IBSS mode */14491449+ if (ah->opmode == NL80211_IFTYPE_ADHOC)14501450+ ath5k_check_ibss_tsf(ah, skb, rxs);14511451+ }1431145214321453 ieee80211_rx(ah->hw, skb);14331454}···25322549 hw->wiphy->available_antennas_rx = 0x3;2533255025342551 hw->extra_tx_headroom = 2;25352535- hw->channel_change_time = 5000;2536255225372553 /*25382554 * Mark the device as detached to avoid processing
+8
drivers/net/wireless/ath/ath9k/Kconfig
···65656666 Also required for changing debug message flags at run time.67676868+config ATH9K_STATION_STATISTICS6969+ bool "Detailed station statistics"7070+ depends on ATH9K && ATH9K_DEBUGFS && DEBUG_FS7171+ select MAC80211_DEBUGFS7272+ default n7373+ ---help---7474+ This option enables detailed statistics for association stations.7575+6876config ATH9K_DFS_CERTIFIED6977 bool "Atheros DFS support for certified platforms"7078 depends on ATH9K && CFG80211_CERTIFICATION_ONUS
···258258 }259259 }260260261261+ sc->gtt_cnt = 0;261262 ieee80211_wake_queues(sc->hw);262263263264 return true;···477476 }478477 }479478479479+ if (status & ATH9K_INT_GTT) {480480+ sc->gtt_cnt++;481481+482482+ if ((sc->gtt_cnt >= MAX_GTT_CNT) && !ath9k_hw_check_alive(ah)) {483483+ type = RESET_TYPE_TX_GTT;484484+ ath9k_queue_reset(sc, type);485485+ atomic_inc(&ah->intr_ref_cnt);486486+ ath_dbg(common, ANY,487487+ "GTT: Skipping interrupts\n");488488+ goto out;489489+ }490490+ }491491+480492 spin_lock_irqsave(&sc->sc_pm_lock, flags);481493 if ((status & ATH9K_INT_TSFOOR) && sc->ps_enabled) {482494 /*···517503 }518504519505 if (status & ATH9K_INT_TX) {520520- if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA)506506+ if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {507507+ /*508508+ * For EDMA chips, TX completion is enabled for the509509+ * beacon queue, so if a beacon has been transmitted510510+ * successfully after a GTT interrupt, the GTT counter511511+ * gets reset to zero here.512512+ */513513+ /* sc->gtt_cnt = 0; */514514+521515 ath_tx_edma_tasklet(sc);522522- else516516+ } else {523517 ath_tx_tasklet(sc);518518+ }524519525520 wake_up(&sc->tx_wait);526521 }···559536 ATH9K_INT_TX | \560537 ATH9K_INT_BMISS | \561538 ATH9K_INT_CST | \539539+ ATH9K_INT_GTT | \562540 ATH9K_INT_TSFOOR | \563541 ATH9K_INT_GENTIMER | \564542 ATH9K_INT_MCI)565543566544 struct ath_softc *sc = dev;567545 struct ath_hw *ah = sc->sc_ah;568568- struct ath_common *common = ath9k_hw_common(ah);569546 enum ath9k_int status;570547 u32 sync_cause = 0;571548 bool sched = false;···626603#ifdef CONFIG_ATH9K_WOW627604 if (status & ATH9K_INT_BMISS) {628605 if (atomic_read(&sc->wow_sleep_proc_intr) == 0) {629629- ath_dbg(common, ANY, "during WoW we got a BMISS\n");630606 atomic_inc(&sc->wow_got_bmiss_intr);631607 atomic_dec(&sc->wow_sleep_proc_intr);632608 }633609 }634610#endif635635-636611637612 if (status & ATH9K_INT_SWBA)638613 tasklet_schedule(&sc->bcon_tasklet);···756735 if (ah->config.hw_hang_checks & HW_BB_WATCHDOG)757736 ah->imask |= ATH9K_INT_BB_WATCHDOG;758737759759- ah->imask |= ATH9K_INT_GTT;738738+ /*739739+ * Enable GTT interrupts only for AR9003/AR9004 chips740740+ * for now.741741+ */742742+ if (AR_SREV_9300_20_OR_LATER(ah))743743+ ah->imask |= ATH9K_INT_GTT;760744761745 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT)762746 ah->imask |= ATH9K_INT_CST;···21372111 .get_et_strings = ath9k_get_et_strings,21382112#endif2139211321402140-#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_DEBUGFS)21142114+#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_ATH9K_STATION_STATISTICS)21412115 .sta_add_debugfs = ath9k_sta_add_debugfs,21422116#endif21432117 .sw_scan_start = ath9k_sw_scan_start,
+5-17
drivers/net/wireless/ath/ath9k/recv.c
···969969 rxs->mactime += 0x100000000ULL;970970}971971972972-static bool ath9k_is_mybeacon(struct ath_softc *sc, struct ieee80211_hdr *hdr)973973-{974974- struct ath_hw *ah = sc->sc_ah;975975- struct ath_common *common = ath9k_hw_common(ah);976976-977977- if (ieee80211_is_beacon(hdr->frame_control)) {978978- RX_STAT_INC(rx_beacons);979979- if (!is_zero_ether_addr(common->curbssid) &&980980- ether_addr_equal_64bits(hdr->addr3, common->curbssid))981981- return true;982982- }983983-984984- return false;985985-}986986-987972/*988973 * For Decrypt or Demic errors, we only mark packet status here and always push989974 * up the frame up to let mac80211 handle the actual error case, be it no···10561071 goto exit;10571072 }1058107310591059- rx_stats->is_mybeacon = ath9k_is_mybeacon(sc, hdr);10741074+ if (ath_is_mybeacon(common, hdr)) {10751075+ RX_STAT_INC(rx_beacons);10761076+ rx_stats->is_mybeacon = true;10771077+ }1060107810611079 /*10621080 * This shouldn't happen, but have a safety check anyway.···13421354 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);1343135513441356 ath9k_antenna_check(sc, &rs);13451345-13461357 ath9k_apply_ampdu_details(sc, &rs, rxs);13581358+ ath_debug_rate_stats(sc, &rs, skb);1347135913481360 ieee80211_rx(hw, skb);13491361
···19671967 return -ENOMEM;19681968 ar->num_channels = chans;1969196919701970- /*19711971- * I measured this, a bandswitch takes roughly19721972- * 135 ms and a frequency switch about 80.19731973- *19741974- * FIXME: measure these values again once EEPROM settings19751975- * are used, that will influence them!19761976- */19771977- if (bands == 2)19781978- ar->hw->channel_change_time = 135 * 1000;19791979- else19801980- ar->hw->channel_change_time = 80 * 1000;19811981-19821970 regulatory->current_rd = le16_to_cpu(ar->eeprom.reg_domain[0]);1983197119841972 /* second part of wiphy init */
+3-6
drivers/net/wireless/ath/carl9170/rx.c
···519519{520520 struct ieee80211_hdr *hdr = data;521521 struct ieee80211_tim_ie *tim_ie;522522+ struct ath_common *common = &ar->common;522523 u8 *tim;523524 u8 tim_len;524525 bool cam;···527526 if (likely(!(ar->hw->conf.flags & IEEE80211_CONF_PS)))528527 return;529528530530- /* check if this really is a beacon */531531- if (!ieee80211_is_beacon(hdr->frame_control))532532- return;533533-534529 /* min. beacon length + FCS_LEN */535530 if (len <= 40 + FCS_LEN)536531 return;537532533533+ /* check if this really is a beacon */538534 /* and only beacons from the associated BSSID, please */539539- if (!ether_addr_equal_64bits(hdr->addr3, ar->common.curbssid) ||540540- !ar->common.curaid)535535+ if (!ath_is_mybeacon(common, hdr) || !common->curaid)541536 return;542537543538 ar->ps.last_beacon = jiffies;
···731731struct b43_request_fw_context {732732 /* The device we are requesting the fw for. */733733 struct b43_wldev *dev;734734- /* a completion event structure needed if this call is asynchronous */735735- struct completion fw_load_complete;736734 /* a pointer to the firmware object */737735 const struct firmware *blob;738736 /* The type of firmware to request. */···807809struct b43_wldev {808810 struct b43_bus_dev *dev;809811 struct b43_wl *wl;812812+ /* a completion event structure needed if this call is asynchronous */813813+ struct completion fw_load_complete;810814811815 /* The device initialization status.812816 * Use b43_status() to query. */
+16-11
drivers/net/wireless/b43/main.c
···2070207020712071static void b43_release_firmware(struct b43_wldev *dev)20722072{20732073+ complete(&dev->fw_load_complete);20732074 b43_do_release_fw(&dev->fw.ucode);20742075 b43_do_release_fw(&dev->fw.pcm);20752076 b43_do_release_fw(&dev->fw.initvals);···20962095 struct b43_request_fw_context *ctx = context;2097209620982097 ctx->blob = firmware;20992099- complete(&ctx->fw_load_complete);20982098+ complete(&ctx->dev->fw_load_complete);21002099}2101210021022101int b43_do_request_fw(struct b43_request_fw_context *ctx,···21432142 }21442143 if (async) {21452144 /* do this part asynchronously */21462146- init_completion(&ctx->fw_load_complete);21452145+ init_completion(&ctx->dev->fw_load_complete);21472146 err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,21482147 ctx->dev->dev->dev, GFP_KERNEL,21492148 ctx, b43_fw_cb);···21512150 pr_err("Unable to load firmware\n");21522151 return err;21532152 }21542154- /* stall here until fw ready */21552155- wait_for_completion(&ctx->fw_load_complete);21532153+ wait_for_completion(&ctx->dev->fw_load_complete);21562154 if (ctx->blob)21572155 goto fw_ready;21582156 /* On some ARM systems, the async request will fail, but the next sync21592159- * request works. For this reason, we dall through here21572157+ * request works. For this reason, we fall through here21602158 */21612159 }21622160 err = request_firmware(&ctx->blob, ctx->fwname,···2424242424252425static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);24262426static void b43_one_core_detach(struct b43_bus_dev *dev);24272427+static int b43_rng_init(struct b43_wl *wl);2427242824282429static void b43_request_firmware(struct work_struct *work)24292430{···24762475 goto err_one_core_detach;24772476 wl->hw_registred = true;24782477 b43_leds_register(wl->current_dev);24782478+24792479+ /* Register HW RNG driver */24802480+ b43_rng_init(wl);24812481+24792482 goto out;2480248324812484err_one_core_detach:···46414636 if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)46424637 return;4643463846444644- /* Unregister HW RNG driver */46454645- b43_rng_exit(dev->wl);46464646-46474639 b43_set_status(dev, B43_STAT_UNINIT);4648464046494641 /* Stop the microcode PSM. */···47964794 ieee80211_wake_queues(dev->wl->hw);4797479547984796 b43_set_status(dev, B43_STAT_INITIALIZED);47994799-48004800- /* Register HW RNG driver */48014801- b43_rng_init(dev->wl);4802479748034798out:48044799 return err;···5463546454645465 b43_one_core_detach(wldev->dev);5465546654675467+ /* Unregister HW RNG driver */54685468+ b43_rng_exit(wl);54695469+54665470 b43_leds_unregister(wl);5467547154685472 ieee80211_free_hw(wl->hw);···55425540 }5543554155445542 b43_one_core_detach(dev);55435543+55445544+ /* Unregister HW RNG driver */55455545+ b43_rng_exit(wl);5545554655465547 if (list_empty(&wl->devlist)) {55475548 b43_leds_unregister(wl);
+1
drivers/net/wireless/b43legacy/main.c
···39193919 * as the ieee80211 unreg will destroy the workqueue. */39203920 cancel_work_sync(&wldev->restart_work);39213921 cancel_work_sync(&wl->firmware_load);39223922+ complete(&wldev->fw_load_complete);3922392339233924 B43legacy_WARN_ON(!wl);39243925 if (!wldev->fw.ucode)
···934934 p2p_ifp = NULL;935935936936 /* signal bus ready */937937- bus_if->state = BRCMF_BUS_DATA;937937+ brcmf_bus_change_state(bus_if, BRCMF_BUS_DATA);938938939939 /* Bus is ready, do any initialization */940940 ret = brcmf_c_preinit_dcmds(ifp);···1028102810291029 /* stop firmware event handling */10301030 brcmf_fweh_detach(drvr);10311031+10321032+ brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);1031103310321034 /* make sure primary interface removed last */10331035 for (i = BRCMF_MAX_IFS-1; i > -1; i--)
···4141#include <soc.h>4242#include "sdio_host.h"4343#include "sdio_chip.h"4444+#include "nvram.h"44454546#define DCMD_RESP_TIMEOUT 2000 /* In milli second */4647···369368/* Private data for SDIO bus interaction */370369struct brcmf_sdio {371370 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */372372- struct chip_info *ci; /* Chip info struct */373373- char *vars; /* Variables (from CIS and/or other) */374374- uint varsz; /* Size of variables buffer */371371+ struct brcmf_chip *ci; /* Chip info struct */375372376373 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */377374···1082108310831084 /* Clear partial in any case */10841085 bus->cur_read.len = 0;10851085-10861086- /* If we can't reach the device, signal failure */10871087- if (err)10881088- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;10891086}1090108710911088/* return total length of buffer chain */···16781683 bus->rxpending = true;1679168416801685 for (rd->seq_num = bus->rx_seq, rxleft = maxframes;16811681- !bus->rxskip && rxleft &&16821682- bus->sdiodev->bus_if->state != BRCMF_BUS_DOWN;16861686+ !bus->rxskip && rxleft && brcmf_bus_ready(bus->sdiodev->bus_if);16831687 rd->seq_num++, rxleft--) {1684168816851689 /* Handle glomming separately */···22272233 bus->watchdog_tsk = NULL;22282234 }2229223522302230- sdio_claim_host(bus->sdiodev->func[1]);22362236+ if (bus_if->state == BRCMF_BUS_DOWN) {22372237+ sdio_claim_host(sdiodev->func[1]);2231223822322232- /* Enable clock for device interrupts */22332233- brcmf_sdio_bus_sleep(bus, false, false);22392239+ /* Enable clock for device interrupts */22402240+ brcmf_sdio_bus_sleep(bus, false, false);2234224122352235- /* Disable and clear interrupts at the chip level also */22362236- w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));22372237- local_hostintmask = bus->hostintmask;22382238- bus->hostintmask = 0;22422242+ /* Disable and clear interrupts at the chip level also */22432243+ w_sdreg32(bus, 0, offsetof(struct sdpcmd_regs, hostintmask));22442244+ local_hostintmask = bus->hostintmask;22452245+ bus->hostintmask = 0;2239224622402240- /* Change our idea of bus state */22412241- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;22472247+ /* Force backplane clocks to assure F2 interrupt propagates */22482248+ saveclk = brcmf_sdiod_regrb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,22492249+ &err);22502250+ if (!err)22512251+ brcmf_sdiod_regwb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,22522252+ (saveclk | SBSDIO_FORCE_HT), &err);22532253+ if (err)22542254+ brcmf_err("Failed to force clock for F2: err %d\n",22552255+ err);2242225622432243- /* Force clocks on backplane to be sure F2 interrupt propagates */22442244- saveclk = brcmf_sdiod_regrb(bus->sdiodev,22452245- SBSDIO_FUNC1_CHIPCLKCSR, &err);22462246- if (!err) {22472247- brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,22482248- (saveclk | SBSDIO_FORCE_HT), &err);22572257+ /* Turn off the bus (F2), free any pending packets */22582258+ brcmf_dbg(INTR, "disable SDIO interrupts\n");22592259+ sdio_disable_func(sdiodev->func[SDIO_FUNC_2]);22602260+22612261+ /* Clear any pending interrupts now that F2 is disabled */22622262+ w_sdreg32(bus, local_hostintmask,22632263+ offsetof(struct sdpcmd_regs, intstatus));22642264+22652265+ sdio_release_host(sdiodev->func[1]);22492266 }22502250- if (err)22512251- brcmf_err("Failed to force clock for F2: err %d\n", err);22522252-22532253- /* Turn off the bus (F2), free any pending packets */22542254- brcmf_dbg(INTR, "disable SDIO interrupts\n");22552255- sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);22562256-22572257- /* Clear any pending interrupts now that F2 is disabled */22582258- w_sdreg32(bus, local_hostintmask,22592259- offsetof(struct sdpcmd_regs, intstatus));22602260-22612261- /* Turn off the backplane clock (only) */22622262- brcmf_sdio_clkctl(bus, CLK_SDONLY, false);22632263- sdio_release_host(bus->sdiodev->func[1]);22642264-22652267 /* Clear the data packet queues */22662268 brcmu_pktq_flush(&bus->txq, true, NULL, NULL);22672269···23472357 /* Check for inconsistent device control */23482358 devctl = brcmf_sdiod_regrb(bus->sdiodev,23492359 SBSDIO_DEVICE_CTL, &err);23502350- if (err) {23512351- brcmf_err("error reading DEVCTL: %d\n", err);23522352- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;23532353- }23542360#endif /* DEBUG */2355236123562362 /* Read CSR, if clock on switch to AVAIL, else ignore */23572363 clkctl = brcmf_sdiod_regrb(bus->sdiodev,23582364 SBSDIO_FUNC1_CHIPCLKCSR, &err);23592359- if (err) {23602360- brcmf_err("error reading CSR: %d\n",23612361- err);23622362- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;23632363- }2364236523652366 brcmf_dbg(SDIO, "DPC: PENDING, devctl 0x%02x clkctl 0x%02x\n",23662367 devctl, clkctl);···23592378 if (SBSDIO_HTAV(clkctl)) {23602379 devctl = brcmf_sdiod_regrb(bus->sdiodev,23612380 SBSDIO_DEVICE_CTL, &err);23622362- if (err) {23632363- brcmf_err("error reading DEVCTL: %d\n",23642364- err);23652365- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;23662366- }23672381 devctl &= ~SBSDIO_DEVCTL_CA_INT_ONLY;23682382 brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_DEVICE_CTL,23692383 devctl, &err);23702370- if (err) {23712371- brcmf_err("error writing DEVCTL: %d\n",23722372- err);23732373- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;23742374- }23752384 bus->clkstate = CLK_AVAIL;23762385 }23772386 }···24962525 txlimit -= framecnt;24972526 }2498252724992499- if ((bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) || (err != 0)) {25282528+ if (!brcmf_bus_ready(bus->sdiodev->bus_if) || (err != 0)) {25002529 brcmf_err("failed backplane access over SDIO, halting operation\n");25012501- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;25022530 atomic_set(&bus->intstatus, 0);25032531 } else if (atomic_read(&bus->intstatus) ||25042532 atomic_read(&bus->ipend) > 0 ||···31653195 return rxlen ? (int)rxlen : -ETIMEDOUT;31663196}3167319731683168-static bool brcmf_sdio_download_state(struct brcmf_sdio *bus, bool enter)31983198+#ifdef DEBUG31993199+static bool32003200+brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,32013201+ u8 *ram_data, uint ram_sz)31693202{31703170- struct chip_info *ci = bus->ci;32033203+ char *ram_cmp;32043204+ int err;32053205+ bool ret = true;32063206+ int address;32073207+ int offset;32083208+ int len;3171320931723172- /* To enter download state, disable ARM and reset SOCRAM.31733173- * To exit download state, simply reset ARM (default is RAM boot).31743174- */31753175- if (enter) {31763176- bus->alp_only = true;32103210+ /* read back and verify */32113211+ brcmf_dbg(INFO, "Compare RAM dl & ul at 0x%08x; size=%d\n", ram_addr,32123212+ ram_sz);32133213+ ram_cmp = kmalloc(MEMBLOCK, GFP_KERNEL);32143214+ /* do not proceed while no memory but */32153215+ if (!ram_cmp)32163216+ return true;3177321731783178- brcmf_sdio_chip_enter_download(bus->sdiodev, ci);31793179- } else {31803180- if (!brcmf_sdio_chip_exit_download(bus->sdiodev, ci, bus->vars,31813181- bus->varsz))31823182- return false;31833183-31843184- /* Allow HT Clock now that the ARM is running. */31853185- bus->alp_only = false;31863186-31873187- bus->sdiodev->bus_if->state = BRCMF_BUS_LOAD;32183218+ address = ram_addr;32193219+ offset = 0;32203220+ while (offset < ram_sz) {32213221+ len = ((offset + MEMBLOCK) < ram_sz) ? MEMBLOCK :32223222+ ram_sz - offset;32233223+ err = brcmf_sdiod_ramrw(sdiodev, false, address, ram_cmp, len);32243224+ if (err) {32253225+ brcmf_err("error %d on reading %d membytes at 0x%08x\n",32263226+ err, len, address);32273227+ ret = false;32283228+ break;32293229+ } else if (memcmp(ram_cmp, &ram_data[offset], len)) {32303230+ brcmf_err("Downloaded RAM image is corrupted, block offset is %d, len is %d\n",32313231+ offset, len);32323232+ ret = false;32333233+ break;32343234+ }32353235+ offset += len;32363236+ address += len;31883237 }3189323832393239+ kfree(ram_cmp);32403240+32413241+ return ret;32423242+}32433243+#else /* DEBUG */32443244+static bool32453245+brcmf_sdio_verifymemory(struct brcmf_sdio_dev *sdiodev, u32 ram_addr,32463246+ u8 *ram_data, uint ram_sz)32473247+{31903248 return true;31913249}32503250+#endif /* DEBUG */3192325131933193-static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus)32523252+static int brcmf_sdio_download_code_file(struct brcmf_sdio *bus,32533253+ const struct firmware *fw)31943254{31953195- const struct firmware *fw;31963255 int err;31973256 int offset;31983257 int address;31993258 int len;3200325932013201- fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);32023202- if (fw == NULL)32033203- return -ENOENT;32043204-32053205- if (brcmf_sdio_chip_getinfidx(bus->ci, BCMA_CORE_ARM_CR4) !=32063206- BRCMF_MAX_CORENUM)32073207- memcpy(&bus->ci->rst_vec, fw->data, sizeof(bus->ci->rst_vec));32603260+ brcmf_dbg(TRACE, "Enter\n");3208326132093262 err = 0;32103263 offset = 0;···32403247 if (err) {32413248 brcmf_err("error %d on writing %d membytes at 0x%08x\n",32423249 err, len, address);32433243- goto failure;32503250+ return err;32443251 }32453252 offset += len;32463253 address += len;32473254 }32483248-32493249-failure:32503250- release_firmware(fw);32553255+ if (!err)32563256+ if (!brcmf_sdio_verifymemory(bus->sdiodev, bus->ci->rambase,32573257+ (u8 *)fw->data, fw->size))32583258+ err = -EIO;3251325932523260 return err;32533261}3254326232553255-/*32563256- * ProcessVars:Takes a buffer of "<var>=<value>\n" lines read from a file32573257- * and ending in a NUL.32583258- * Removes carriage returns, empty lines, comment lines, and converts32593259- * newlines to NULs.32603260- * Shortens buffer as needed and pads with NULs. End of buffer is marked32613261- * by two NULs.32623262-*/32633263-32643264-static int brcmf_sdio_strip_nvram(struct brcmf_sdio *bus,32653265- const struct firmware *nv)32633263+static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus,32643264+ const struct firmware *nv)32663265{32673267- char *varbuf;32683268- char *dp;32693269- bool findNewline;32703270- int column;32713271- int ret = 0;32723272- uint buf_len, n, len;32663266+ void *vars;32673267+ u32 varsz;32683268+ int address;32693269+ int err;3273327032743274- len = nv->size;32753275- varbuf = vmalloc(len);32763276- if (!varbuf)32773277- return -ENOMEM;32713271+ brcmf_dbg(TRACE, "Enter\n");3278327232793279- memcpy(varbuf, nv->data, len);32803280- dp = varbuf;32733273+ vars = brcmf_nvram_strip(nv, &varsz);3281327432823282- findNewline = false;32833283- column = 0;32753275+ if (vars == NULL)32763276+ return -EINVAL;3284327732853285- for (n = 0; n < len; n++) {32863286- if (varbuf[n] == 0)32873287- break;32883288- if (varbuf[n] == '\r')32893289- continue;32903290- if (findNewline && varbuf[n] != '\n')32913291- continue;32923292- findNewline = false;32933293- if (varbuf[n] == '#') {32943294- findNewline = true;32953295- continue;32963296- }32973297- if (varbuf[n] == '\n') {32983298- if (column == 0)32993299- continue;33003300- *dp++ = 0;33013301- column = 0;33023302- continue;33033303- }33043304- *dp++ = varbuf[n];33053305- column++;33063306- }33073307- buf_len = dp - varbuf;33083308- while (dp < varbuf + n)33093309- *dp++ = 0;32783278+ address = bus->ci->ramsize - varsz + bus->ci->rambase;32793279+ err = brcmf_sdiod_ramrw(bus->sdiodev, true, address, vars, varsz);32803280+ if (err)32813281+ brcmf_err("error %d on writing %d nvram bytes at 0x%08x\n",32823282+ err, varsz, address);32833283+ else if (!brcmf_sdio_verifymemory(bus->sdiodev, address, vars, varsz))32843284+ err = -EIO;3310328533113311- kfree(bus->vars);33123312- /* roundup needed for download to device */33133313- bus->varsz = roundup(buf_len + 1, 4);33143314- bus->vars = kmalloc(bus->varsz, GFP_KERNEL);33153315- if (bus->vars == NULL) {33163316- bus->varsz = 0;33173317- ret = -ENOMEM;33183318- goto err;33193319- }32863286+ brcmf_nvram_free(vars);3320328733213321- /* copy the processed variables and add null termination */33223322- memcpy(bus->vars, varbuf, buf_len);33233323- bus->vars[buf_len] = 0;33243324-err:33253325- vfree(varbuf);33263326- return ret;33273327-}33283328-33293329-static int brcmf_sdio_download_nvram(struct brcmf_sdio *bus)33303330-{33313331- const struct firmware *nv;33323332- int ret;33333333-33343334- nv = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);33353335- if (nv == NULL)33363336- return -ENOENT;33373337-33383338- ret = brcmf_sdio_strip_nvram(bus, nv);33393339-33403340- release_firmware(nv);33413341-33423342- return ret;32883288+ return err;33433289}3344329033453291static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus)33463292{33473293 int bcmerror = -EFAULT;33483348-32943294+ const struct firmware *fw;32953295+ u32 rstvec;3349329633503297 sdio_claim_host(bus->sdiodev->func[1]);33513298 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);3352329933533300 /* Keep arm in reset */33543354- if (!brcmf_sdio_download_state(bus, true)) {33553355- brcmf_err("error placing ARM core in reset\n");33013301+ brcmf_sdio_chip_enter_download(bus->sdiodev, bus->ci);33023302+33033303+ fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_BIN);33043304+ if (fw == NULL) {33053305+ bcmerror = -ENOENT;33563306 goto err;33573307 }3358330833593359- if (brcmf_sdio_download_code_file(bus)) {33093309+ rstvec = get_unaligned_le32(fw->data);33103310+ brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);33113311+33123312+ bcmerror = brcmf_sdio_download_code_file(bus, fw);33133313+ release_firmware(fw);33143314+ if (bcmerror) {33603315 brcmf_err("dongle image file download failed\n");33613316 goto err;33623317 }3363331833643364- if (brcmf_sdio_download_nvram(bus)) {33193319+ fw = brcmf_sdio_get_fw(bus, BRCMF_FIRMWARE_NVRAM);33203320+ if (fw == NULL) {33213321+ bcmerror = -ENOENT;33223322+ goto err;33233323+ }33243324+33253325+ bcmerror = brcmf_sdio_download_nvram(bus, fw);33263326+ release_firmware(fw);33273327+ if (bcmerror) {33653328 brcmf_err("dongle nvram file download failed\n");33663329 goto err;33673330 }3368333133693332 /* Take arm out of reset */33703370- if (!brcmf_sdio_download_state(bus, false)) {33333333+ if (!brcmf_sdio_chip_exit_download(bus->sdiodev, bus->ci, rstvec)) {33713334 brcmf_err("error getting out of ARM core reset\n");33723335 goto err;33733336 }3374333733383338+ /* Allow HT Clock now that the ARM is running. */33393339+ brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_LOAD);33753340 bcmerror = 0;3376334133773342err:···3518356735193568 /* try to download image and nvram to the dongle */35203569 if (bus_if->state == BRCMF_BUS_DOWN) {35703570+ bus->alp_only = true;35213571 err = brcmf_sdio_download_firmware(bus);35223572 if (err)35233573 return err;35743574+ bus->alp_only = false;35243575 }3525357635263577 if (!bus->sdiodev->bus_if->drvr)···36063653 return;36073654 }3608365536093609- if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {36563656+ if (!brcmf_bus_ready(bus->sdiodev->bus_if)) {36103657 brcmf_err("bus is down. we have nothing to do\n");36113658 return;36123659 }···36173664 else36183665 if (brcmf_sdio_intr_rstatus(bus)) {36193666 brcmf_err("failed backplane access\n");36203620- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;36213667 }3622366836233669 /* Disable additional interrupts (is this needed now)? */···37313779 u32 reg_val;37323780 u32 drivestrength;3733378137343734- bus->alp_only = true;37353735-37363782 sdio_claim_host(bus->sdiodev->func[1]);3737378337383784 pr_debug("F1 signature read @0x18000000=0x%4x\n",···37523802 err, BRCMF_INIT_CLKCTL1, clkctl);37533803 goto fail;37543804 }38053805+38063806+ /* SDIO register access works so moving38073807+ * state from UNKNOWN to DOWN.38083808+ */38093809+ brcmf_bus_change_state(bus->sdiodev->bus_if, BRCMF_BUS_DOWN);3755381037563811 if (brcmf_sdio_chip_attach(bus->sdiodev, &bus->ci)) {37573812 brcmf_err("brcmf_sdio_chip_attach failed!\n");···39814026 /* Disable F2 to clear any intermediate frame state on the dongle */39824027 sdio_disable_func(bus->sdiodev->func[SDIO_FUNC_2]);3983402839843984- bus->sdiodev->bus_if->state = BRCMF_BUS_DOWN;39854029 bus->rxflow = false;3986403039874031 /* Done with backplane-dependent accesses, can drop clock... */···40364082 }4037408340384084 if (bus->ci) {40394039- sdio_claim_host(bus->sdiodev->func[1]);40404040- brcmf_sdio_clkctl(bus, CLK_AVAIL, false);40414041- brcmf_sdio_clkctl(bus, CLK_NONE, false);40424042- sdio_release_host(bus->sdiodev->func[1]);40854085+ if (bus->sdiodev->bus_if->state == BRCMF_BUS_DOWN) {40864086+ sdio_claim_host(bus->sdiodev->func[1]);40874087+ brcmf_sdio_clkctl(bus, CLK_AVAIL, false);40884088+ /* Leave the device in state where it is40894089+ * 'quiet'. This is done by putting it in40904090+ * download_state which essentially resets40914091+ * all necessary cores.40924092+ */40934093+ msleep(20);40944094+ brcmf_sdio_chip_enter_download(bus->sdiodev,40954095+ bus->ci);40964096+ brcmf_sdio_clkctl(bus, CLK_NONE, false);40974097+ sdio_release_host(bus->sdiodev->func[1]);40984098+ }40434099 brcmf_sdio_chip_detach(&bus->ci);40444100 }4045410140464102 brcmu_pkt_buf_free_skb(bus->txglom_sgpad);40474103 kfree(bus->rxbuf);40484104 kfree(bus->hdrbuf);40494049- kfree(bus->vars);40504105 kfree(bus);40514106 }40524107
+94
drivers/net/wireless/brcm80211/brcmfmac/nvram.c
···11+/*22+ * Copyright (c) 2013 Broadcom Corporation33+ *44+ * Permission to use, copy, modify, and/or distribute this software for any55+ * purpose with or without fee is hereby granted, provided that the above66+ * copyright notice and this permission notice appear in all copies.77+ *88+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES99+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1010+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY1111+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1212+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION1313+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN1414+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1515+ */1616+1717+#include <linux/kernel.h>1818+#include <linux/slab.h>1919+#include <linux/firmware.h>2020+2121+#include "nvram.h"2222+2323+/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file2424+ * and ending in a NUL. Removes carriage returns, empty lines, comment lines,2525+ * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.2626+ * End of buffer is completed with token identifying length of buffer.2727+ */2828+void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)2929+{3030+ u8 *nvram;3131+ u32 i;3232+ u32 len;3333+ u32 column;3434+ u8 val;3535+ bool comment;3636+ u32 token;3737+ __le32 token_le;3838+3939+ /* Alloc for extra 0 byte + roundup by 4 + length field */4040+ nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);4141+ if (!nvram)4242+ return NULL;4343+4444+ len = 0;4545+ column = 0;4646+ comment = false;4747+ for (i = 0; i < nv->size; i++) {4848+ val = nv->data[i];4949+ if (val == 0)5050+ break;5151+ if (val == '\r')5252+ continue;5353+ if (comment && (val != '\n'))5454+ continue;5555+ comment = false;5656+ if (val == '#') {5757+ comment = true;5858+ continue;5959+ }6060+ if (val == '\n') {6161+ if (column == 0)6262+ continue;6363+ nvram[len] = 0;6464+ len++;6565+ column = 0;6666+ continue;6767+ }6868+ nvram[len] = val;6969+ len++;7070+ column++;7171+ }7272+ column = len;7373+ *new_length = roundup(len + 1, 4);7474+ while (column != *new_length) {7575+ nvram[column] = 0;7676+ column++;7777+ }7878+7979+ token = *new_length / 4;8080+ token = (~token << 16) | (token & 0x0000FFFF);8181+ token_le = cpu_to_le32(token);8282+8383+ memcpy(&nvram[*new_length], &token_le, sizeof(token_le));8484+ *new_length += sizeof(token_le);8585+8686+ return nvram;8787+}8888+8989+void brcmf_nvram_free(void *nvram)9090+{9191+ kfree(nvram);9292+}9393+9494+
+24
drivers/net/wireless/brcm80211/brcmfmac/nvram.h
···11+/*22+ * Copyright (c) 2013 Broadcom Corporation33+ *44+ * Permission to use, copy, modify, and/or distribute this software for any55+ * purpose with or without fee is hereby granted, provided that the above66+ * copyright notice and this permission notice appear in all copies.77+ *88+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES99+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF1010+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY1111+ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES1212+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION1313+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN1414+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.1515+ */1616+#ifndef BRCMFMAC_NVRAM_H1717+#define BRCMFMAC_NVRAM_H1818+1919+2020+void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);2121+void brcmf_nvram_free(void *nvram);2222+2323+2424+#endif /* BRCMFMAC_NVRAM_H */
···205205 struct iwl_device_cmd *cmd)206206{207207 struct iwl_rx_packet *pkt = rxb_addr(rxb);208208- u32 __maybe_unused len =209209- le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;208208+ u32 __maybe_unused len = iwl_rx_packet_len(pkt);210209 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "211210 "notification for PM_DEBUG_STATISTIC_NOTIFIC:\n", len);212211 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->data, len);···456457 const int reg_recalib_period = 60;457458 int change;458459 struct iwl_rx_packet *pkt = rxb_addr(rxb);459459- u32 len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;460460+ u32 len = iwl_rx_packet_payload_len(pkt);460461 __le32 *flag;461462 struct statistics_general_common *common;462463 struct statistics_rx_non_phy *rx_non_phy;···465466 struct statistics_rx_phy *rx_cck;466467 struct statistics_tx *tx;467468 struct statistics_bt_activity *bt_activity;468468-469469- len -= sizeof(struct iwl_cmd_header); /* skip header */470469471470 IWL_DEBUG_RX(priv, "Statistics notification received (%d bytes).\n",472471 len);
+1-6
drivers/net/wireless/iwlwifi/dvm/ucode.c
···388388{389389 struct iwl_priv *priv = data;390390 struct iwl_calib_hdr *hdr;391391- int len;392391393392 if (pkt->hdr.cmd != CALIBRATION_RES_NOTIFICATION) {394393 WARN_ON(pkt->hdr.cmd != CALIBRATION_COMPLETE_NOTIFICATION);···395396 }396397397398 hdr = (struct iwl_calib_hdr *)pkt->data;398398- len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;399399400400- /* reduce the size by the length field itself */401401- len -= sizeof(__le32);402402-403403- if (iwl_calib_set(priv, hdr, len))400400+ if (iwl_calib_set(priv, hdr, iwl_rx_packet_payload_len(pkt)))404401 IWL_ERR(priv, "Failed to record calibration data %d\n",405402 hdr->op_code);406403
+1-8
drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
···264264 struct ieee80211_sta_vht_cap *vht_cap)265265{266266 int num_ants = num_of_ant(data->valid_rx_ant);267267- int bf_sts_cap = num_ants - 1;268267269268 vht_cap->vht_supported = true;270269271270 vht_cap->cap = IEEE80211_VHT_CAP_SHORT_GI_80 |272271 IEEE80211_VHT_CAP_RXSTBC_1 |273272 IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE |274274- bf_sts_cap << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |273273+ 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |275274 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;276275277276 if (num_ants > 1)···289290 IEEE80211_VHT_MCS_NOT_SUPPORTED << 12 |290291 IEEE80211_VHT_MCS_NOT_SUPPORTED << 14);291292292292- /* Max rate for Long GI NSS=2 80Mhz is 780Mbps */293293- vht_cap->vht_mcs.rx_highest = cpu_to_le16(780);294294-295293 if (num_ants == 1 ||296294 cfg->rx_with_siso_diversity) {297295 vht_cap->cap |= IEEE80211_VHT_CAP_RX_ANTENNA_PATTERN |···296300 /* this works because NOT_SUPPORTED == 3 */297301 vht_cap->vht_mcs.rx_mcs_map |=298302 cpu_to_le16(IEEE80211_VHT_MCS_NOT_SUPPORTED << 2);299299- /* Max rate for Long GI NSS=1 80Mhz is 390Mbps */300300- vht_cap->vht_mcs.rx_highest = cpu_to_le16(390);301303 }302304303305 vht_cap->vht_mcs.tx_mcs_map = vht_cap->vht_mcs.rx_mcs_map;304304- vht_cap->vht_mcs.tx_highest = vht_cap->vht_mcs.rx_highest;305306}306307307308static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
···262262 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;263263264264 /* currently FW API supports only one optional cipher scheme */265265- if (mvm->fw->cs->cipher) {265265+ if (mvm->fw->cs[0].cipher) {266266 mvm->hw->n_cipher_schemes = 1;267267- mvm->hw->cipher_schemes = mvm->fw->cs;267267+ mvm->hw->cipher_schemes = &mvm->fw->cs[0];268268 }269269270270#ifdef CONFIG_PM_SLEEP···944944 IWL_ERR(mvm, "failed to update power mode\n");945945 }946946 iwl_mvm_bt_coex_vif_change(mvm);947947+ iwl_mvm_update_smps(mvm, vif, IWL_MVM_SMPS_REQ_TT,948948+ IEEE80211_SMPS_AUTOMATIC);947949 } else if (changes & BSS_CHANGED_BEACON_INFO) {948950 /*949951 * We received a beacon _after_ association so···10141012 if (ret)10151013 goto out_unbind;1016101410151015+ /* must be set before quota calculations */10161016+ mvmvif->ap_ibss_active = true;10171017+10181018+ /* power updated needs to be done before quotas */10191019+ mvm->bound_vif_cnt++;10201020+ iwl_mvm_power_update_binding(mvm, vif, true);10211021+10171022 ret = iwl_mvm_update_quotas(mvm, vif);10181023 if (ret)10191019- goto out_rm_bcast;10241024+ goto out_quota_failed;1020102510211026 /* Need to update the P2P Device MAC (only GO, IBSS is single vif) */10221027 if (vif->p2p && mvm->p2p_device_vif)···10341025 mutex_unlock(&mvm->mutex);10351026 return 0;1036102710371037-out_rm_bcast:10281028+out_quota_failed:10291029+ mvm->bound_vif_cnt--;10301030+ iwl_mvm_power_update_binding(mvm, vif, false);10311031+ mvmvif->ap_ibss_active = false;10381032 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);10391033out_unbind:10401034 iwl_mvm_binding_remove_vif(mvm, vif);···10691057 iwl_mvm_update_quotas(mvm, NULL);10701058 iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta);10711059 iwl_mvm_binding_remove_vif(mvm, vif);10601060+10611061+ mvm->bound_vif_cnt--;10621062+ iwl_mvm_power_update_binding(mvm, vif, false);10631063+10721064 iwl_mvm_mac_ctxt_remove(mvm, vif);1073106510741066 mutex_unlock(&mvm->mutex);···18061790 }1807179118081792 iwl_mvm_binding_remove_vif(mvm, vif);18091809-out_unlock:18101810- mvmvif->phy_ctxt = NULL;18111793 mvm->bound_vif_cnt--;18121794 iwl_mvm_power_update_binding(mvm, vif, false);1813179517961796+out_unlock:17971797+ mvmvif->phy_ctxt = NULL;18141798 mutex_unlock(&mvm->mutex);18151799}18161800
+6-7
drivers/net/wireless/iwlwifi/mvm/nvm.c
···392392/* Loads the NVM data stored in mvm->nvm_sections into the NIC */393393int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)394394{395395- int i, ret;396396- u16 section_id;395395+ int i, ret = 0;397396 struct iwl_nvm_section *sections = mvm->nvm_sections;398397399398 IWL_DEBUG_EEPROM(mvm->trans->dev, "'Write to NVM\n");400399401401- for (i = 0; i < ARRAY_SIZE(nvm_to_read); i++) {402402- section_id = nvm_to_read[i];403403- ret = iwl_nvm_write_section(mvm, section_id,404404- sections[section_id].data,405405- sections[section_id].length);400400+ for (i = 0; i < ARRAY_SIZE(mvm->nvm_sections); i++) {401401+ if (!mvm->nvm_sections[i].data || !mvm->nvm_sections[i].length)402402+ continue;403403+ ret = iwl_nvm_write_section(mvm, i, sections[i].data,404404+ sections[i].length);406405 if (ret < 0) {407406 IWL_ERR(mvm, "iwl_mvm_send_cmd failed: %d\n", ret);408407 break;
···356356 return idx;357357 }358358359359- return -1;359359+ return IWL_RATE_INVALID;360360}361361362362static void rs_rate_scale_perform(struct iwl_mvm *mvm,···702702 memset(rate, 0, sizeof(*rate));703703 rate->index = iwl_hwrate_to_plcp_idx(ucode_rate);704704705705- if (rate->index == IWL_RATE_INVALID) {706706- rate->index = -1;705705+ if (rate->index == IWL_RATE_INVALID)707706 return -EINVAL;708708- }709707710708 rate->ant = (ant_msk >> RATE_MCS_ANT_POS);711709···15881590 search_tbl->column = col_id;15891591 rs_set_expected_tpt_table(lq_sta, search_tbl);1590159215931593+ lq_sta->visited_columns |= BIT(col_id);15941594+15911595 /* Get the best matching rate if we're changing modes. e.g.15921596 * SISO->MIMO, LEGACY->SISO, MIMO->SISO15931597 */···16131613 IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",16141614 col_id, rate->index);1615161516161616- lq_sta->visited_columns |= BIT(col_id);16171616 return 0;1618161716191618err:···25592560 int index = iwl_hwrate_to_plcp_idx(rate);2560256125612562 return sprintf(buf, "Legacy | ANT: %s Rate: %s Mbps\n",25622562- rs_pretty_ant(ant), iwl_rate_mcs[index].mbps);25632563+ rs_pretty_ant(ant),25642564+ index == IWL_RATE_INVALID ? "BAD" :25652565+ iwl_rate_mcs[index].mbps);25632566 }2564256725652568 if (rate & RATE_MCS_VHT_MSK) {
+2-2
drivers/net/wireless/iwlwifi/mvm/time-event.c
···249249 container_of(notif_wait, struct iwl_mvm, notif_wait);250250 struct iwl_mvm_time_event_data *te_data = data;251251 struct iwl_time_event_resp *resp;252252- int resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;252252+ int resp_len = iwl_rx_packet_payload_len(pkt);253253254254 if (WARN_ON(pkt->hdr.cmd != TIME_EVENT_CMD))255255 return true;256256257257- if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {257257+ if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {258258 IWL_ERR(mvm, "Invalid TIME_EVENT_CMD response\n");259259 return true;260260 }
+4-5
drivers/net/wireless/iwlwifi/mvm/tx.c
···390390 seq_number &= IEEE80211_SCTL_SEQ;391391 hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);392392 hdr->seq_ctrl |= cpu_to_le16(seq_number);393393- seq_number += 0x10;394393 is_data_qos = true;395394 is_ampdu = info->flags & IEEE80211_TX_CTL_AMPDU;396395 }···406407 }407408408409 IWL_DEBUG_TX(mvm, "TX to [%d|%d] Q:%d - seq: 0x%x\n", mvmsta->sta_id,409409- tid, txq_id, seq_number);410410+ tid, txq_id, IEEE80211_SEQ_TO_SN(seq_number));410411411412 if (iwl_trans_tx(mvm->trans, skb, dev_cmd, txq_id))412413 goto drop_unlock_sta;413414414415 if (is_data_qos && !ieee80211_has_morefrags(fc))415415- mvmsta->tid_data[tid].seq_number = seq_number;416416+ mvmsta->tid_data[tid].seq_number = seq_number + 0x10;416417417418 spin_unlock(&mvmsta->lock);418419···703704 */704705 spin_lock_bh(&mvmsta->lock);705706 sta = rcu_dereference(mvm->fw_id_to_mac_id[sta_id]);706706- if (IS_ERR_OR_NULL(sta)) {707707+ if (!sta || PTR_ERR(sta) == -EBUSY) {707708 /*708709 * Station disappeared in the meantime:709710 * so we are draining.···712713 schedule_work(&mvm->sta_drained_wk);713714 }714715 spin_unlock_bh(&mvmsta->lock);715715- } else if (!mvmsta) {716716+ } else if (!mvmsta && PTR_ERR(sta) == -EBUSY) {716717 /* Tx response without STA, so we are draining */717718 set_bit(sta_id, mvm->sta_drained);718719 schedule_work(&mvm->sta_drained_wk);
+2-2
drivers/net/wireless/iwlwifi/mvm/utils.c
···168168 goto out_free_resp;169169 }170170171171- resp_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;172172- if (WARN_ON_ONCE(resp_len != sizeof(pkt->hdr) + sizeof(*resp))) {171171+ resp_len = iwl_rx_packet_payload_len(pkt);172172+ if (WARN_ON_ONCE(resp_len != sizeof(*resp))) {173173 ret = -EIO;174174 goto out_free_resp;175175 }
+1-1
drivers/net/wireless/iwlwifi/pcie/rx.c
···615615 rxcb._offset, get_cmd_string(trans_pcie, pkt->hdr.cmd),616616 pkt->hdr.cmd);617617618618- len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;618618+ len = iwl_rx_packet_len(pkt);619619 len += sizeof(u32); /* account for status word */620620 trace_iwlwifi_dev_rx(trans->dev, trans, pkt, len);621621 trace_iwlwifi_dev_rx_data(trans->dev, trans, pkt, len);
+22
drivers/net/wireless/iwlwifi/pcie/trans.c
···178178 goto out;179179 }180180181181+ if (trans->cfg->host_interrupt_operation_mode) {182182+ /*183183+ * This is a bit of an abuse - This is needed for 7260 / 3160184184+ * only check host_interrupt_operation_mode even if this is185185+ * not related to host_interrupt_operation_mode.186186+ *187187+ * Enable the oscillator to count wake up time for L1 exit. This188188+ * consumes slightly more power (100uA) - but allows to be sure189189+ * that we wake up from L1 on time.190190+ *191191+ * This looks weird: read twice the same register, discard the192192+ * value, set a bit, and yet again, read that same register193193+ * just to discard the value. But that's the way the hardware194194+ * seems to like it.195195+ */196196+ iwl_read_prph(trans, OSC_CLK);197197+ iwl_read_prph(trans, OSC_CLK);198198+ iwl_set_bits_prph(trans, OSC_CLK, OSC_CLK_FORCE_CONTROL);199199+ iwl_read_prph(trans, OSC_CLK);200200+ iwl_read_prph(trans, OSC_CLK);201201+ }202202+181203 /*182204 * Enable DMA clock and wait for it to stabilize.183205 *
+1-6
drivers/net/wireless/libertas/cfg.c
···12681268_new_connect_scan_req(struct wiphy *wiphy, struct cfg80211_connect_params *sme)12691269{12701270 struct cfg80211_scan_request *creq = NULL;12711271- int i, n_channels = 0;12711271+ int i, n_channels = ieee80211_get_num_supported_channels(wiphy);12721272 enum ieee80211_band band;12731273-12741274- for (band = 0; band < IEEE80211_NUM_BANDS; band++) {12751275- if (wiphy->bands[band])12761276- n_channels += wiphy->bands[band]->n_channels;12771277- }1278127312791274 creq = kzalloc(sizeof(*creq) + sizeof(struct cfg80211_ssid) +12801275 n_channels * sizeof(void *),
···6565 * kernel, uses:6666 * %HWSIM_ATTR_ADDR_TRANSMITTER, %HWSIM_ATTR_FLAGS,6767 * %HWSIM_ATTR_TX_INFO, %HWSIM_ATTR_SIGNAL, %HWSIM_ATTR_COOKIE6868+ * @HWSIM_CMD_CREATE_RADIO: create a new radio with the given parameters,6969+ * returns the radio ID (>= 0) or negative on errors7070+ * @HWSIM_CMD_DESTROY_RADIO: destroy a radio6871 * @__HWSIM_CMD_MAX: enum limit6972 */7073enum {···7572 HWSIM_CMD_REGISTER,7673 HWSIM_CMD_FRAME,7774 HWSIM_CMD_TX_INFO_FRAME,7575+ HWSIM_CMD_CREATE_RADIO,7676+ HWSIM_CMD_DESTROY_RADIO,7877 __HWSIM_CMD_MAX,7978};8079#define HWSIM_CMD_MAX (_HWSIM_CMD_MAX - 1)···9994 space10095 * @HWSIM_ATTR_TX_INFO: ieee80211_tx_rate array10196 * @HWSIM_ATTR_COOKIE: sk_buff cookie to identify the frame9797+ * @HWSIM_ATTR_CHANNELS: u32 attribute used with the %HWSIM_CMD_CREATE_RADIO9898+ * command giving the number of channels supported by the new radio9999+ * @HWSIM_ATTR_RADIO_ID: u32 attribute used with %HWSIM_CMD_DESTROY_RADIO100100+ * only to destroy a radio101101+ * @HWSIM_ATTR_REG_HINT_ALPHA2: alpha2 for regulatoro driver hint102102+ * (nla string, length 2)103103+ * @HWSIM_ATTR_REG_CUSTOM_REG: custom regulatory domain index (u32 attribute)104104+ * @HWSIM_ATTR_REG_STRICT_REG: request REGULATORY_STRICT_REG (flag attribute)102105 * @__HWSIM_ATTR_MAX: enum limit103106 */104107···121108 HWSIM_ATTR_SIGNAL,122109 HWSIM_ATTR_TX_INFO,123110 HWSIM_ATTR_COOKIE,111111+ HWSIM_ATTR_CHANNELS,112112+ HWSIM_ATTR_RADIO_ID,113113+ HWSIM_ATTR_REG_HINT_ALPHA2,114114+ HWSIM_ATTR_REG_CUSTOM_REG,115115+ HWSIM_ATTR_REG_STRICT_REG,124116 __HWSIM_ATTR_MAX,125117};126118#define HWSIM_ATTR_MAX (__HWSIM_ATTR_MAX - 1)
+2-2
drivers/net/wireless/mwifiex/Kconfig
···3131 mwifiex_pcie.32323333config MWIFIEX_USB3434- tristate "Marvell WiFi-Ex Driver for USB8797"3434+ tristate "Marvell WiFi-Ex Driver for USB8797/8897"3535 depends on MWIFIEX && USB3636 select FW_LOADER3737 ---help---3838 This adds support for wireless adapters based on Marvell3939- Avastar 88W8797 chipset with USB interface.3939+ 8797/8897 chipset with USB interface.40404141 If you choose to build it as a module, it will be called4242 mwifiex_usb.
···11+config NFC_MRVL22+ tristate "Marvell NFC driver support"33+ depends on NFC_NCI44+ help55+ The core driver to support Marvell NFC devices.66+77+ This driver is required if you want to support88+ Marvell NFC device 8897.99+1010+ Say Y here to compile Marvell NFC driver into the kernel or1111+ say M to compile it as module.1212+1313+config NFC_MRVL_USB1414+ tristate "Marvell NFC-over-USB driver"1515+ depends on NFC_MRVL && USB1616+ help1717+ Marvell NFC-over-USB driver.1818+1919+ This driver provides support for Marvell NFC-over-USB devices:2020+ 8897.2121+2222+ Say Y here to compile support for Marvell NFC-over-USB driver2323+ into the kernel or say M to compile it as module.
+9
drivers/nfc/nfcmrvl/Makefile
···11+#22+# Makefile for NFCMRVL NCI based NFC driver33+#44+55+nfcmrvl-y += main.o66+obj-$(CONFIG_NFC_MRVL) += nfcmrvl.o77+88+nfcmrvl_usb-y += usb.o99+obj-$(CONFIG_NFC_MRVL_USB) += nfcmrvl_usb.o
+165
drivers/nfc/nfcmrvl/main.c
···11+/*22+ * Marvell NFC driver: major functions33+ *44+ * Copyright (C) 2014, Marvell International Ltd.55+ *66+ * This software file (the "File") is distributed by Marvell International77+ * Ltd. under the terms of the GNU General Public License Version 2, June 199188+ * (the "License"). You may use, redistribute and/or modify this File in99+ * accordance with the terms and conditions of the License, a copy of which1010+ * is available on the worldwide web at1111+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.1212+ *1313+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE1414+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE1515+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about1616+ * this warranty disclaimer.1717+ */1818+1919+#include <linux/module.h>2020+#include <linux/nfc.h>2121+#include <net/nfc/nci.h>2222+#include <net/nfc/nci_core.h>2323+#include "nfcmrvl.h"2424+2525+#define VERSION "1.0"2626+2727+static int nfcmrvl_nci_open(struct nci_dev *ndev)2828+{2929+ struct nfcmrvl_private *priv = nci_get_drvdata(ndev);3030+ int err;3131+3232+ if (test_and_set_bit(NFCMRVL_NCI_RUNNING, &priv->flags))3333+ return 0;3434+3535+ err = priv->if_ops->nci_open(priv);3636+3737+ if (err)3838+ clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags);3939+4040+ return err;4141+}4242+4343+static int nfcmrvl_nci_close(struct nci_dev *ndev)4444+{4545+ struct nfcmrvl_private *priv = nci_get_drvdata(ndev);4646+4747+ if (!test_and_clear_bit(NFCMRVL_NCI_RUNNING, &priv->flags))4848+ return 0;4949+5050+ priv->if_ops->nci_close(priv);5151+5252+ return 0;5353+}5454+5555+static int nfcmrvl_nci_send(struct nci_dev *ndev, struct sk_buff *skb)5656+{5757+ struct nfcmrvl_private *priv = nci_get_drvdata(ndev);5858+5959+ nfc_info(priv->dev, "send entry, len %d\n", skb->len);6060+6161+ skb->dev = (void *)ndev;6262+6363+ if (!test_bit(NFCMRVL_NCI_RUNNING, &priv->flags))6464+ return -EBUSY;6565+6666+ return priv->if_ops->nci_send(priv, skb);6767+}6868+6969+static int nfcmrvl_nci_setup(struct nci_dev *ndev)7070+{7171+ __u8 val;7272+7373+ val = NFCMRVL_GPIO_PIN_NFC_NOT_ALLOWED;7474+ nci_set_config(ndev, NFCMRVL_NOT_ALLOWED_ID, 1, &val);7575+ val = NFCMRVL_GPIO_PIN_NFC_ACTIVE;7676+ nci_set_config(ndev, NFCMRVL_ACTIVE_ID, 1, &val);7777+ val = NFCMRVL_EXT_COEX_ENABLE;7878+ nci_set_config(ndev, NFCMRVL_EXT_COEX_ID, 1, &val);7979+8080+ return 0;8181+}8282+8383+static struct nci_ops nfcmrvl_nci_ops = {8484+ .open = nfcmrvl_nci_open,8585+ .close = nfcmrvl_nci_close,8686+ .send = nfcmrvl_nci_send,8787+ .setup = nfcmrvl_nci_setup,8888+};8989+9090+struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,9191+ struct nfcmrvl_if_ops *ops,9292+ struct device *dev)9393+{9494+ struct nfcmrvl_private *priv;9595+ int rc;9696+ u32 protocols;9797+9898+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);9999+ if (!priv)100100+ return ERR_PTR(-ENOMEM);101101+102102+ priv->drv_data = drv_data;103103+ priv->if_ops = ops;104104+ priv->dev = dev;105105+106106+ protocols = NFC_PROTO_JEWEL_MASK107107+ | NFC_PROTO_MIFARE_MASK | NFC_PROTO_FELICA_MASK108108+ | NFC_PROTO_ISO14443_MASK109109+ | NFC_PROTO_ISO14443_B_MASK110110+ | NFC_PROTO_NFC_DEP_MASK;111111+112112+ priv->ndev = nci_allocate_device(&nfcmrvl_nci_ops, protocols, 0, 0);113113+ if (!priv->ndev) {114114+ nfc_err(dev, "nci_allocate_device failed");115115+ rc = -ENOMEM;116116+ goto error;117117+ }118118+119119+ nci_set_drvdata(priv->ndev, priv);120120+121121+ rc = nci_register_device(priv->ndev);122122+ if (rc) {123123+ nfc_err(dev, "nci_register_device failed %d", rc);124124+ nci_free_device(priv->ndev);125125+ goto error;126126+ }127127+128128+ nfc_info(dev, "registered with nci successfully\n");129129+ return priv;130130+131131+error:132132+ kfree(priv);133133+ return ERR_PTR(rc);134134+}135135+EXPORT_SYMBOL_GPL(nfcmrvl_nci_register_dev);136136+137137+void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv)138138+{139139+ struct nci_dev *ndev = priv->ndev;140140+141141+ nci_unregister_device(ndev);142142+ nci_free_device(ndev);143143+ kfree(priv);144144+}145145+EXPORT_SYMBOL_GPL(nfcmrvl_nci_unregister_dev);146146+147147+int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count)148148+{149149+ struct sk_buff *skb;150150+151151+ skb = nci_skb_alloc(priv->ndev, count, GFP_ATOMIC);152152+ if (!skb)153153+ return -ENOMEM;154154+155155+ memcpy(skb_put(skb, count), data, count);156156+ nci_recv_frame(priv->ndev, skb);157157+158158+ return count;159159+}160160+EXPORT_SYMBOL_GPL(nfcmrvl_nci_recv_frame);161161+162162+MODULE_AUTHOR("Marvell International Ltd.");163163+MODULE_DESCRIPTION("Marvell NFC driver ver " VERSION);164164+MODULE_VERSION(VERSION);165165+MODULE_LICENSE("GPL v2");
+48
drivers/nfc/nfcmrvl/nfcmrvl.h
···11+/**22+ * Marvell NFC driver33+ *44+ * Copyright (C) 2014, Marvell International Ltd.55+ *66+ * This software file (the "File") is distributed by Marvell International77+ * Ltd. under the terms of the GNU General Public License Version 2, June 199188+ * (the "License"). You may use, redistribute and/or modify this File in99+ * accordance with the terms and conditions of the License, a copy of which1010+ * is available on the worldwide web at1111+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.1212+ *1313+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE1414+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE1515+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about1616+ * this warranty disclaimer.1717+ **/1818+1919+/* Define private flags: */2020+#define NFCMRVL_NCI_RUNNING 12121+2222+#define NFCMRVL_EXT_COEX_ID 0xE02323+#define NFCMRVL_NOT_ALLOWED_ID 0xE12424+#define NFCMRVL_ACTIVE_ID 0xE22525+#define NFCMRVL_EXT_COEX_ENABLE 12626+#define NFCMRVL_GPIO_PIN_NFC_NOT_ALLOWED 0xA2727+#define NFCMRVL_GPIO_PIN_NFC_ACTIVE 0xB2828+#define NFCMRVL_NCI_MAX_EVENT_SIZE 2602929+3030+struct nfcmrvl_private {3131+ struct nci_dev *ndev;3232+ unsigned long flags;3333+ void *drv_data;3434+ struct device *dev;3535+ struct nfcmrvl_if_ops *if_ops;3636+};3737+3838+struct nfcmrvl_if_ops {3939+ int (*nci_open) (struct nfcmrvl_private *priv);4040+ int (*nci_close) (struct nfcmrvl_private *priv);4141+ int (*nci_send) (struct nfcmrvl_private *priv, struct sk_buff *skb);4242+};4343+4444+void nfcmrvl_nci_unregister_dev(struct nfcmrvl_private *priv);4545+int nfcmrvl_nci_recv_frame(struct nfcmrvl_private *priv, void *data, int count);4646+struct nfcmrvl_private *nfcmrvl_nci_register_dev(void *drv_data,4747+ struct nfcmrvl_if_ops *ops,4848+ struct device *dev);
+459
drivers/nfc/nfcmrvl/usb.c
···11+/**22+ * Marvell NFC-over-USB driver: USB interface related functions33+ *44+ * Copyright (C) 2014, Marvell International Ltd.55+ *66+ * This software file (the "File") is distributed by Marvell International77+ * Ltd. under the terms of the GNU General Public License Version 2, June 199188+ * (the "License"). You may use, redistribute and/or modify this File in99+ * accordance with the terms and conditions of the License, a copy of which1010+ * is available on the worldwide web at1111+ * http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt.1212+ *1313+ * THE FILE IS DISTRIBUTED AS-IS, WITHOUT WARRANTY OF ANY KIND, AND THE1414+ * IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE1515+ * ARE EXPRESSLY DISCLAIMED. The License provides additional details about1616+ * this warranty disclaimer.1717+ **/1818+1919+#include <linux/module.h>2020+#include <linux/usb.h>2121+#include <linux/nfc.h>2222+#include <net/nfc/nci.h>2323+#include <net/nfc/nci_core.h>2424+#include "nfcmrvl.h"2525+2626+#define VERSION "1.0"2727+2828+static struct usb_device_id nfcmrvl_table[] = {2929+ { USB_DEVICE_INTERFACE_CLASS(0x1286, 0x2046, 0xff) },3030+ { } /* Terminating entry */3131+};3232+3333+MODULE_DEVICE_TABLE(usb, nfcmrvl_table);3434+3535+#define NFCMRVL_USB_BULK_RUNNING 13636+#define NFCMRVL_USB_SUSPENDING 23737+3838+struct nfcmrvl_usb_drv_data {3939+ struct usb_device *udev;4040+ struct usb_interface *intf;4141+ unsigned long flags;4242+ struct work_struct waker;4343+ struct usb_anchor tx_anchor;4444+ struct usb_anchor bulk_anchor;4545+ struct usb_anchor deferred;4646+ int tx_in_flight;4747+ /* protects tx_in_flight */4848+ spinlock_t txlock;4949+ struct usb_endpoint_descriptor *bulk_tx_ep;5050+ struct usb_endpoint_descriptor *bulk_rx_ep;5151+ int suspend_count;5252+ struct nfcmrvl_private *priv;5353+};5454+5555+static int nfcmrvl_inc_tx(struct nfcmrvl_usb_drv_data *drv_data)5656+{5757+ unsigned long flags;5858+ int rv;5959+6060+ spin_lock_irqsave(&drv_data->txlock, flags);6161+ rv = test_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);6262+ if (!rv)6363+ drv_data->tx_in_flight++;6464+ spin_unlock_irqrestore(&drv_data->txlock, flags);6565+6666+ return rv;6767+}6868+6969+static void nfcmrvl_bulk_complete(struct urb *urb)7070+{7171+ struct nfcmrvl_usb_drv_data *drv_data = urb->context;7272+ int err;7373+7474+ dev_dbg(&drv_data->udev->dev, "urb %p status %d count %d",7575+ urb, urb->status, urb->actual_length);7676+7777+ if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))7878+ return;7979+8080+ if (!urb->status) {8181+ if (nfcmrvl_nci_recv_frame(drv_data->priv, urb->transfer_buffer,8282+ urb->actual_length) < 0)8383+ nfc_err(&drv_data->udev->dev, "corrupted Rx packet");8484+ }8585+8686+ if (!test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags))8787+ return;8888+8989+ usb_anchor_urb(urb, &drv_data->bulk_anchor);9090+ usb_mark_last_busy(drv_data->udev);9191+9292+ err = usb_submit_urb(urb, GFP_ATOMIC);9393+ if (err) {9494+ /* -EPERM: urb is being killed;9595+ * -ENODEV: device got disconnected9696+ */9797+ if (err != -EPERM && err != -ENODEV)9898+ nfc_err(&drv_data->udev->dev,9999+ "urb %p failed to resubmit (%d)", urb, -err);100100+ usb_unanchor_urb(urb);101101+ }102102+}103103+104104+static int105105+nfcmrvl_submit_bulk_urb(struct nfcmrvl_usb_drv_data *drv_data, gfp_t mem_flags)106106+{107107+ struct urb *urb;108108+ unsigned char *buf;109109+ unsigned int pipe;110110+ int err, size = NFCMRVL_NCI_MAX_EVENT_SIZE;111111+112112+ if (!drv_data->bulk_rx_ep)113113+ return -ENODEV;114114+115115+ urb = usb_alloc_urb(0, mem_flags);116116+ if (!urb)117117+ return -ENOMEM;118118+119119+ buf = kmalloc(size, mem_flags);120120+ if (!buf) {121121+ usb_free_urb(urb);122122+ return -ENOMEM;123123+ }124124+125125+ pipe = usb_rcvbulkpipe(drv_data->udev,126126+ drv_data->bulk_rx_ep->bEndpointAddress);127127+128128+ usb_fill_bulk_urb(urb, drv_data->udev, pipe, buf, size,129129+ nfcmrvl_bulk_complete, drv_data);130130+131131+ urb->transfer_flags |= URB_FREE_BUFFER;132132+133133+ usb_mark_last_busy(drv_data->udev);134134+ usb_anchor_urb(urb, &drv_data->bulk_anchor);135135+136136+ err = usb_submit_urb(urb, mem_flags);137137+ if (err) {138138+ if (err != -EPERM && err != -ENODEV)139139+ nfc_err(&drv_data->udev->dev,140140+ "urb %p submission failed (%d)", urb, -err);141141+ usb_unanchor_urb(urb);142142+ }143143+144144+ usb_free_urb(urb);145145+146146+ return err;147147+}148148+149149+static void nfcmrvl_tx_complete(struct urb *urb)150150+{151151+ struct sk_buff *skb = urb->context;152152+ struct nci_dev *ndev = (struct nci_dev *)skb->dev;153153+ struct nfcmrvl_private *priv = nci_get_drvdata(ndev);154154+ struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;155155+156156+ nfc_info(priv->dev, "urb %p status %d count %d",157157+ urb, urb->status, urb->actual_length);158158+159159+ spin_lock(&drv_data->txlock);160160+ drv_data->tx_in_flight--;161161+ spin_unlock(&drv_data->txlock);162162+163163+ kfree(urb->setup_packet);164164+ kfree_skb(skb);165165+}166166+167167+static int nfcmrvl_usb_nci_open(struct nfcmrvl_private *priv)168168+{169169+ struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;170170+ int err;171171+172172+ err = usb_autopm_get_interface(drv_data->intf);173173+ if (err)174174+ return err;175175+176176+ drv_data->intf->needs_remote_wakeup = 1;177177+178178+ err = nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);179179+ if (err)180180+ goto failed;181181+182182+ set_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);183183+ nfcmrvl_submit_bulk_urb(drv_data, GFP_KERNEL);184184+185185+ usb_autopm_put_interface(drv_data->intf);186186+ return 0;187187+188188+failed:189189+ usb_autopm_put_interface(drv_data->intf);190190+ return err;191191+}192192+193193+static void nfcmrvl_usb_stop_traffic(struct nfcmrvl_usb_drv_data *drv_data)194194+{195195+ usb_kill_anchored_urbs(&drv_data->bulk_anchor);196196+}197197+198198+static int nfcmrvl_usb_nci_close(struct nfcmrvl_private *priv)199199+{200200+ struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;201201+ int err;202202+203203+ cancel_work_sync(&drv_data->waker);204204+205205+ clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);206206+207207+ nfcmrvl_usb_stop_traffic(drv_data);208208+ usb_kill_anchored_urbs(&drv_data->tx_anchor);209209+ err = usb_autopm_get_interface(drv_data->intf);210210+ if (err)211211+ goto failed;212212+213213+ drv_data->intf->needs_remote_wakeup = 0;214214+ usb_autopm_put_interface(drv_data->intf);215215+216216+failed:217217+ usb_scuttle_anchored_urbs(&drv_data->deferred);218218+ return 0;219219+}220220+221221+static int nfcmrvl_usb_nci_send(struct nfcmrvl_private *priv,222222+ struct sk_buff *skb)223223+{224224+ struct nfcmrvl_usb_drv_data *drv_data = priv->drv_data;225225+ struct urb *urb;226226+ unsigned int pipe;227227+ int err;228228+229229+ if (!drv_data->bulk_tx_ep)230230+ return -ENODEV;231231+232232+ urb = usb_alloc_urb(0, GFP_ATOMIC);233233+ if (!urb)234234+ return -ENOMEM;235235+236236+ pipe = usb_sndbulkpipe(drv_data->udev,237237+ drv_data->bulk_tx_ep->bEndpointAddress);238238+239239+ usb_fill_bulk_urb(urb, drv_data->udev, pipe, skb->data, skb->len,240240+ nfcmrvl_tx_complete, skb);241241+242242+ err = nfcmrvl_inc_tx(drv_data);243243+ if (err) {244244+ usb_anchor_urb(urb, &drv_data->deferred);245245+ schedule_work(&drv_data->waker);246246+ err = 0;247247+ goto done;248248+ }249249+250250+ usb_anchor_urb(urb, &drv_data->tx_anchor);251251+252252+ err = usb_submit_urb(urb, GFP_ATOMIC);253253+ if (err) {254254+ if (err != -EPERM && err != -ENODEV)255255+ nfc_err(&drv_data->udev->dev,256256+ "urb %p submission failed (%d)", urb, -err);257257+ kfree(urb->setup_packet);258258+ usb_unanchor_urb(urb);259259+ } else {260260+ usb_mark_last_busy(drv_data->udev);261261+ }262262+263263+done:264264+ usb_free_urb(urb);265265+ return err;266266+}267267+268268+static struct nfcmrvl_if_ops usb_ops = {269269+ .nci_open = nfcmrvl_usb_nci_open,270270+ .nci_close = nfcmrvl_usb_nci_close,271271+ .nci_send = nfcmrvl_usb_nci_send,272272+};273273+274274+static void nfcmrvl_waker(struct work_struct *work)275275+{276276+ struct nfcmrvl_usb_drv_data *drv_data =277277+ container_of(work, struct nfcmrvl_usb_drv_data, waker);278278+ int err;279279+280280+ err = usb_autopm_get_interface(drv_data->intf);281281+ if (err)282282+ return;283283+284284+ usb_autopm_put_interface(drv_data->intf);285285+}286286+287287+static int nfcmrvl_probe(struct usb_interface *intf,288288+ const struct usb_device_id *id)289289+{290290+ struct usb_endpoint_descriptor *ep_desc;291291+ struct nfcmrvl_usb_drv_data *drv_data;292292+ struct nfcmrvl_private *priv;293293+ int i;294294+ struct usb_device *udev = interface_to_usbdev(intf);295295+296296+ nfc_info(&udev->dev, "intf %p id %p", intf, id);297297+298298+ drv_data = devm_kzalloc(&intf->dev, sizeof(*drv_data), GFP_KERNEL);299299+ if (!drv_data)300300+ return -ENOMEM;301301+302302+ for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) {303303+ ep_desc = &intf->cur_altsetting->endpoint[i].desc;304304+305305+ if (!drv_data->bulk_tx_ep &&306306+ usb_endpoint_is_bulk_out(ep_desc)) {307307+ drv_data->bulk_tx_ep = ep_desc;308308+ continue;309309+ }310310+311311+ if (!drv_data->bulk_rx_ep &&312312+ usb_endpoint_is_bulk_in(ep_desc)) {313313+ drv_data->bulk_rx_ep = ep_desc;314314+ continue;315315+ }316316+ }317317+318318+ if (!drv_data->bulk_tx_ep || !drv_data->bulk_rx_ep)319319+ return -ENODEV;320320+321321+ drv_data->udev = udev;322322+ drv_data->intf = intf;323323+324324+ INIT_WORK(&drv_data->waker, nfcmrvl_waker);325325+ spin_lock_init(&drv_data->txlock);326326+327327+ init_usb_anchor(&drv_data->tx_anchor);328328+ init_usb_anchor(&drv_data->bulk_anchor);329329+ init_usb_anchor(&drv_data->deferred);330330+331331+ priv = nfcmrvl_nci_register_dev(drv_data, &usb_ops,332332+ &drv_data->udev->dev);333333+ if (IS_ERR(priv))334334+ return PTR_ERR(priv);335335+336336+ drv_data->priv = priv;337337+ priv->dev = &drv_data->udev->dev;338338+339339+ usb_set_intfdata(intf, drv_data);340340+341341+ return 0;342342+}343343+344344+static void nfcmrvl_disconnect(struct usb_interface *intf)345345+{346346+ struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);347347+348348+ if (!drv_data)349349+ return;350350+351351+ nfc_info(&drv_data->udev->dev, "intf %p", intf);352352+353353+ nfcmrvl_nci_unregister_dev(drv_data->priv);354354+355355+ usb_set_intfdata(drv_data->intf, NULL);356356+}357357+358358+#ifdef CONFIG_PM359359+static int nfcmrvl_suspend(struct usb_interface *intf, pm_message_t message)360360+{361361+ struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);362362+363363+ nfc_info(&drv_data->udev->dev, "intf %p", intf);364364+365365+ if (drv_data->suspend_count++)366366+ return 0;367367+368368+ spin_lock_irq(&drv_data->txlock);369369+ if (!(PMSG_IS_AUTO(message) && drv_data->tx_in_flight)) {370370+ set_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);371371+ spin_unlock_irq(&drv_data->txlock);372372+ } else {373373+ spin_unlock_irq(&drv_data->txlock);374374+ drv_data->suspend_count--;375375+ return -EBUSY;376376+ }377377+378378+ nfcmrvl_usb_stop_traffic(drv_data);379379+ usb_kill_anchored_urbs(&drv_data->tx_anchor);380380+381381+ return 0;382382+}383383+384384+static void nfcmrvl_play_deferred(struct nfcmrvl_usb_drv_data *drv_data)385385+{386386+ struct urb *urb;387387+ int err;388388+389389+ while ((urb = usb_get_from_anchor(&drv_data->deferred))) {390390+ err = usb_submit_urb(urb, GFP_ATOMIC);391391+ if (err)392392+ break;393393+394394+ drv_data->tx_in_flight++;395395+ }396396+ usb_scuttle_anchored_urbs(&drv_data->deferred);397397+}398398+399399+static int nfcmrvl_resume(struct usb_interface *intf)400400+{401401+ struct nfcmrvl_usb_drv_data *drv_data = usb_get_intfdata(intf);402402+ int err = 0;403403+404404+ nfc_info(&drv_data->udev->dev, "intf %p", intf);405405+406406+ if (--drv_data->suspend_count)407407+ return 0;408408+409409+ if (!test_bit(NFCMRVL_NCI_RUNNING, &drv_data->flags))410410+ goto done;411411+412412+ if (test_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags)) {413413+ err = nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);414414+ if (err) {415415+ clear_bit(NFCMRVL_USB_BULK_RUNNING, &drv_data->flags);416416+ goto failed;417417+ }418418+419419+ nfcmrvl_submit_bulk_urb(drv_data, GFP_NOIO);420420+ }421421+422422+ spin_lock_irq(&drv_data->txlock);423423+ nfcmrvl_play_deferred(drv_data);424424+ clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);425425+ spin_unlock_irq(&drv_data->txlock);426426+427427+ return 0;428428+429429+failed:430430+ usb_scuttle_anchored_urbs(&drv_data->deferred);431431+done:432432+ spin_lock_irq(&drv_data->txlock);433433+ clear_bit(NFCMRVL_USB_SUSPENDING, &drv_data->flags);434434+ spin_unlock_irq(&drv_data->txlock);435435+436436+ return err;437437+}438438+#endif439439+440440+static struct usb_driver nfcmrvl_usb_driver = {441441+ .name = "nfcmrvl",442442+ .probe = nfcmrvl_probe,443443+ .disconnect = nfcmrvl_disconnect,444444+#ifdef CONFIG_PM445445+ .suspend = nfcmrvl_suspend,446446+ .resume = nfcmrvl_resume,447447+ .reset_resume = nfcmrvl_resume,448448+#endif449449+ .id_table = nfcmrvl_table,450450+ .supports_autosuspend = 1,451451+ .disable_hub_initiated_lpm = 1,452452+ .soft_unbind = 1,453453+};454454+module_usb_driver(nfcmrvl_usb_driver);455455+456456+MODULE_AUTHOR("Marvell International Ltd.");457457+MODULE_DESCRIPTION("Marvell NFC-over-USB driver ver " VERSION);458458+MODULE_VERSION(VERSION);459459+MODULE_LICENSE("GPL v2");
+3
drivers/nfc/pn533.c
···521521 if (frame->ccid.type != 0x83)522522 return false;523523524524+ if (!frame->ccid.datalen)525525+ return false;526526+524527 if (frame->data[frame->ccid.datalen - 2] == 0x63)525528 return false;526529
···18571857 WLAN_KEY_LEN_CCMP = 16,18581858 WLAN_KEY_LEN_TKIP = 32,18591859 WLAN_KEY_LEN_AES_CMAC = 16,18601860+ WLAN_KEY_LEN_SMS4 = 32,18601861};1861186218621863#define IEEE80211_WEP_IV_LEN 4···19031902#define WLAN_EXT_CAPA5_TDLS_PROHIBITED BIT(6)1904190319051904#define WLAN_EXT_CAPA8_OPMODE_NOTIF BIT(6)19051905+#define WLAN_EXT_CAPA8_TDLS_WIDE_BW_ENABLED BIT(7)1906190619071907/* TDLS specific payload type in the LLC/SNAP header */19081908#define WLAN_TDLS_SNAP_RFTYPE 0x2
+8
include/net/cfg80211.h
···46404640 */46414641void cfg80211_crit_proto_stopped(struct wireless_dev *wdev, gfp_t gfp);4642464246434643+/**46444644+ * ieee80211_get_num_supported_channels - get number of channels device has46454645+ * @wiphy: the wiphy46464646+ *46474647+ * Return: the number of channels supported by the device.46484648+ */46494649+unsigned int ieee80211_get_num_supported_channels(struct wiphy *wiphy);46504650+46434651/* Logging, debugging and troubleshooting/diagnostic helpers. */4644465246454653/* wiphy_printk helpers, similar to dev_printk */
+5-3
include/net/mac80211.h
···16161616 * @extra_beacon_tailroom: tailroom to reserve in each beacon tx skb.16171617 * Can be used by drivers to add extra IEs.16181618 *16191619- * @channel_change_time: time (in microseconds) it takes to change channels.16201620- *16211619 * @max_signal: Maximum value for signal (rssi) in RX information, used16221620 * only when @IEEE80211_HW_SIGNAL_UNSPEC or @IEEE80211_HW_SIGNAL_DB16231621 *···16971699 u32 flags;16981700 unsigned int extra_tx_headroom;16991701 unsigned int extra_beacon_tailroom;17001700- int channel_change_time;17011702 int vif_data_size;17021703 int sta_data_size;17031704 int chanctx_data_size;···21192122 * appropriately (only the last frame may have %IEEE80211_TX_STATUS_EOSP)21202123 * and also take care of the EOSP and MORE_DATA bits in the frame.21212124 * The driver may also use ieee80211_sta_eosp() in this case.21252125+ *21262126+ * Note that if the driver ever buffers frames other than QoS-data21272127+ * frames, it must take care to never send a non-QoS-data frame as21282128+ * the last frame in a service period, adding a QoS-nulldata frame21292129+ * after a non-QoS-data frame if needed.21222130 */2123213121242132/**
+10
include/net/nfc/digital.h
···122122 * switch_rf to turn the radio on. A call to in|tg_configure_hw must turn123123 * the device radio on.124124 * @abort_cmd: Discard the last sent command.125125+ *126126+ * Notes: Asynchronous functions have a timeout parameter. It is the driver127127+ * responsibility to call the digital stack back through the128128+ * nfc_digital_cmd_complete_t callback when no RF respsonse has been129129+ * received within the specified time (in milliseconds). In that case the130130+ * driver must set the resp sk_buff to ERR_PTR(-ETIMEDOUT).131131+ * Since the digital stack serializes commands to be sent, it's mandatory132132+ * for the driver to handle the timeout correctly. Otherwise the stack133133+ * would not be able to send new commands, waiting for the reply of the134134+ * current one.125135 */126136struct nfc_digital_ops {127137 int (*in_configure_hw)(struct nfc_digital_dev *ddev, int type,
···9696 * initiator is %REGDOM_SET_BY_CORE). Drivers that use9797 * wiphy_apply_custom_regulatory() should have this flag set9898 * or the regulatory core will set it for the wiphy.9999+ * If you use regulatory_hint() *after* using100100+ * wiphy_apply_custom_regulatory() the wireless core will101101+ * clear the REGULATORY_CUSTOM_REG for your wiphy as it would be102102+ * implied that the device somehow gained knowledge of its region.99103 * @REGULATORY_STRICT_REG: tells us that the wiphy for this device100104 * has regulatory domain that it wishes to be considered as the101105 * superset for regulatory rules. After this device gets its regulatory
···3076307630773077/* main receive path */3078307830793079-static int prepare_for_handlers(struct ieee80211_rx_data *rx,30803080- struct ieee80211_hdr *hdr)30793079+static bool prepare_for_handlers(struct ieee80211_rx_data *rx,30803080+ struct ieee80211_hdr *hdr)30813081{30823082 struct ieee80211_sub_if_data *sdata = rx->sdata;30833083 struct sk_buff *skb = rx->skb;···30883088 switch (sdata->vif.type) {30893089 case NL80211_IFTYPE_STATION:30903090 if (!bssid && !sdata->u.mgd.use_4addr)30913091- return 0;30913091+ return false;30923092 if (!multicast &&30933093 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {30943094 if (!(sdata->dev->flags & IFF_PROMISC) ||30953095 sdata->u.mgd.use_4addr)30963096- return 0;30963096+ return false;30973097 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;30983098 }30993099 break;31003100 case NL80211_IFTYPE_ADHOC:31013101 if (!bssid)31023102- return 0;31023102+ return false;31033103 if (ether_addr_equal(sdata->vif.addr, hdr->addr2) ||31043104 ether_addr_equal(sdata->u.ibss.bssid, hdr->addr2))31053105- return 0;31053105+ return false;31063106 if (ieee80211_is_beacon(hdr->frame_control)) {31073107- return 1;31073107+ return true;31083108 } else if (!ieee80211_bssid_match(bssid, sdata->u.ibss.bssid)) {31093109- return 0;31093109+ return false;31103110 } else if (!multicast &&31113111 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {31123112 if (!(sdata->dev->flags & IFF_PROMISC))31133113- return 0;31133113+ return false;31143114 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;31153115 } else if (!rx->sta) {31163116 int rate_idx;···31263126 if (!multicast &&31273127 !ether_addr_equal(sdata->vif.addr, hdr->addr1)) {31283128 if (!(sdata->dev->flags & IFF_PROMISC))31293129- return 0;31293129+ return false;3130313031313131 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;31323132 }···31353135 case NL80211_IFTYPE_AP:31363136 if (!bssid) {31373137 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1))31383138- return 0;31383138+ return false;31393139 } else if (!ieee80211_bssid_match(bssid, sdata->vif.addr)) {31403140 /*31413141 * Accept public action frames even when the···31453145 */31463146 if (!multicast &&31473147 !ether_addr_equal(sdata->vif.addr, hdr->addr1))31483148- return 0;31483148+ return false;31493149 if (ieee80211_is_public_action(hdr, skb->len))31503150- return 1;31503150+ return true;31513151 if (!ieee80211_is_beacon(hdr->frame_control))31523152- return 0;31523152+ return false;31533153 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;31543154 }31553155 break;31563156 case NL80211_IFTYPE_WDS:31573157 if (bssid || !ieee80211_is_data(hdr->frame_control))31583158- return 0;31583158+ return false;31593159 if (!ether_addr_equal(sdata->u.wds.remote_addr, hdr->addr2))31603160- return 0;31603160+ return false;31613161 break;31623162 case NL80211_IFTYPE_P2P_DEVICE:31633163 if (!ieee80211_is_public_action(hdr, skb->len) &&31643164 !ieee80211_is_probe_req(hdr->frame_control) &&31653165 !ieee80211_is_probe_resp(hdr->frame_control) &&31663166 !ieee80211_is_beacon(hdr->frame_control))31673167- return 0;31673167+ return false;31683168 if (!ether_addr_equal(sdata->vif.addr, hdr->addr1) &&31693169 !multicast)31703170 status->rx_flags &= ~IEEE80211_RX_RA_MATCH;···31753175 break;31763176 }3177317731783178- return 1;31783178+ return true;31793179}3180318031813181/*···31913191 struct ieee80211_sub_if_data *sdata = rx->sdata;31923192 struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb);31933193 struct ieee80211_hdr *hdr = (void *)skb->data;31943194- int prepares;3195319431963195 rx->skb = skb;31973196 status->rx_flags |= IEEE80211_RX_RA_MATCH;31983198- prepares = prepare_for_handlers(rx, hdr);3199319732003200- if (!prepares)31983198+ if (!prepare_for_handlers(rx, hdr))32013199 return false;3202320032033201 if (!consume) {
+154-88
net/mac80211/sta_info.c
···300300 if (!sta)301301 return NULL;302302303303+ rcu_read_lock();304304+ tx_latency = rcu_dereference(local->tx_latency);305305+ /* init stations Tx latency statistics && TID bins */306306+ if (tx_latency) {307307+ sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *308308+ sizeof(struct ieee80211_tx_latency_stat),309309+ GFP_ATOMIC);310310+ if (!sta->tx_lat) {311311+ rcu_read_unlock();312312+ goto free;313313+ }314314+315315+ if (tx_latency->n_ranges) {316316+ for (i = 0; i < IEEE80211_NUM_TIDS; i++) {317317+ /* size of bins is size of the ranges +1 */318318+ sta->tx_lat[i].bin_count =319319+ tx_latency->n_ranges + 1;320320+ sta->tx_lat[i].bins =321321+ kcalloc(sta->tx_lat[i].bin_count,322322+ sizeof(u32), GFP_ATOMIC);323323+ if (!sta->tx_lat[i].bins) {324324+ rcu_read_unlock();325325+ goto free;326326+ }327327+ }328328+ }329329+ }330330+ rcu_read_unlock();331331+303332 spin_lock_init(&sta->lock);304333 INIT_WORK(&sta->drv_unblock_wk, sta_unblock);305334 INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);···353324 for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)354325 ewma_init(&sta->chain_signal_avg[i], 1024, 8);355326356356- if (sta_prepare_rate_control(local, sta, gfp)) {357357- kfree(sta);358358- return NULL;359359- }327327+ if (sta_prepare_rate_control(local, sta, gfp))328328+ goto free;360329361330 for (i = 0; i < IEEE80211_NUM_TIDS; i++) {362331 /*···398371 }399372 }400373401401- rcu_read_lock();402402-403403- tx_latency = rcu_dereference(local->tx_latency);404404- /* init stations Tx latency statistics && TID bins */405405- if (tx_latency)406406- sta->tx_lat = kzalloc(IEEE80211_NUM_TIDS *407407- sizeof(struct ieee80211_tx_latency_stat),408408- GFP_ATOMIC);409409-410410- /*411411- * if Tx latency and bins are enabled and the previous allocation412412- * succeeded413413- */414414- if (tx_latency && tx_latency->n_ranges && sta->tx_lat)415415- for (i = 0; i < IEEE80211_NUM_TIDS; i++) {416416- /* size of bins is size of the ranges +1 */417417- sta->tx_lat[i].bin_count =418418- tx_latency->n_ranges + 1;419419- sta->tx_lat[i].bins = kcalloc(sta->tx_lat[i].bin_count,420420- sizeof(u32),421421- GFP_ATOMIC);422422- }423423-424424- rcu_read_unlock();425425-426374 sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);427427-428375 return sta;376376+377377+free:378378+ if (sta->tx_lat) {379379+ for (i = 0; i < IEEE80211_NUM_TIDS; i++)380380+ kfree(sta->tx_lat[i].bins);381381+ kfree(sta->tx_lat);382382+ }383383+ kfree(sta);384384+ return NULL;429385}430386431387static int sta_info_insert_check(struct sta_info *sta)···1153114311541144static void ieee80211_send_null_response(struct ieee80211_sub_if_data *sdata,11551145 struct sta_info *sta, int tid,11561156- enum ieee80211_frame_release_type reason)11461146+ enum ieee80211_frame_release_type reason,11471147+ bool call_driver)11571148{11581149 struct ieee80211_local *local = sdata->local;11591150 struct ieee80211_qos_hdr *nullfunc;···12121201 IEEE80211_TX_STATUS_EOSP |12131202 IEEE80211_TX_CTL_REQ_TX_STATUS;1214120312151215- drv_allow_buffered_frames(local, sta, BIT(tid), 1, reason, false);12041204+ if (call_driver)12051205+ drv_allow_buffered_frames(local, sta, BIT(tid), 1,12061206+ reason, false);1216120712171208 skb->dev = sdata->dev;12181209···12301217 rcu_read_unlock();12311218}1232121912201220+static int find_highest_prio_tid(unsigned long tids)12211221+{12221222+ /* lower 3 TIDs aren't ordered perfectly */12231223+ if (tids & 0xF8)12241224+ return fls(tids) - 1;12251225+ /* TID 0 is BE just like TID 3 */12261226+ if (tids & BIT(0))12271227+ return 0;12281228+ return fls(tids) - 1;12291229+}12301230+12331231static void12341232ieee80211_sta_ps_deliver_response(struct sta_info *sta,12351233 int n_frames, u8 ignored_acs,···12481224{12491225 struct ieee80211_sub_if_data *sdata = sta->sdata;12501226 struct ieee80211_local *local = sdata->local;12511251- bool found = false;12521227 bool more_data = false;12531228 int ac;12541229 unsigned long driver_release_tids = 0;···1258123512591236 __skb_queue_head_init(&frames);1260123712611261- /*12621262- * Get response frame(s) and more data bit for it.12631263- */12381238+ /* Get response frame(s) and more data bit for the last one. */12641239 for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {12651240 unsigned long tids;12661241···1267124612681247 tids = ieee80211_tids_for_ac(ac);1269124812701270- if (!found) {12711271- driver_release_tids = sta->driver_buffered_tids & tids;12721272- if (driver_release_tids) {12731273- found = true;12741274- } else {12751275- struct sk_buff *skb;12491249+ /* if we already have frames from software, then we can't also12501250+ * release from hardware queues12511251+ */12521252+ if (skb_queue_empty(&frames))12531253+ driver_release_tids |= sta->driver_buffered_tids & tids;1276125412771277- while (n_frames > 0) {12781278- skb = skb_dequeue(&sta->tx_filtered[ac]);12791279- if (!skb) {12801280- skb = skb_dequeue(12811281- &sta->ps_tx_buf[ac]);12821282- if (skb)12831283- local->total_ps_buffered--;12841284- }12851285- if (!skb)12861286- break;12871287- n_frames--;12881288- found = true;12891289- __skb_queue_tail(&frames, skb);12901290- }12911291- }12921292-12931293- /*12941294- * If the driver has data on more than one TID then12551255+ if (driver_release_tids) {12561256+ /* If the driver has data on more than one TID then12951257 * certainly there's more data if we release just a12961296- * single frame now (from a single TID).12581258+ * single frame now (from a single TID). This will12591259+ * only happen for PS-Poll.12971260 */12981261 if (reason == IEEE80211_FRAME_RELEASE_PSPOLL &&12991262 hweight16(driver_release_tids) > 1) {13001263 more_data = true;13011264 driver_release_tids =13021302- BIT(ffs(driver_release_tids) - 1);12651265+ BIT(find_highest_prio_tid(12661266+ driver_release_tids));13031267 break;12681268+ }12691269+ } else {12701270+ struct sk_buff *skb;12711271+12721272+ while (n_frames > 0) {12731273+ skb = skb_dequeue(&sta->tx_filtered[ac]);12741274+ if (!skb) {12751275+ skb = skb_dequeue(12761276+ &sta->ps_tx_buf[ac]);12771277+ if (skb)12781278+ local->total_ps_buffered--;12791279+ }12801280+ if (!skb)12811281+ break;12821282+ n_frames--;12831283+ __skb_queue_tail(&frames, skb);13041284 }13051285 }1306128612871287+ /* If we have more frames buffered on this AC, then set the12881288+ * more-data bit and abort the loop since we can't send more12891289+ * data from other ACs before the buffered frames from this.12901290+ */13071291 if (!skb_queue_empty(&sta->tx_filtered[ac]) ||13081292 !skb_queue_empty(&sta->ps_tx_buf[ac])) {13091293 more_data = true;···13161290 }13171291 }1318129213191319- if (!found) {12931293+ if (skb_queue_empty(&frames) && !driver_release_tids) {13201294 int tid;1321129513221296 /*···13371311 /* This will evaluate to 1, 3, 5 or 7. */13381312 tid = 7 - ((ffs(~ignored_acs) - 1) << 1);1339131313401340- ieee80211_send_null_response(sdata, sta, tid, reason);13411341- return;13421342- }13431343-13441344- if (!driver_release_tids) {13141314+ ieee80211_send_null_response(sdata, sta, tid, reason, true);13151315+ } else if (!driver_release_tids) {13451316 struct sk_buff_head pending;13461317 struct sk_buff *skb;13471318 int num = 0;13481319 u16 tids = 0;13201320+ bool need_null = false;1349132113501322 skb_queue_head_init(&pending);13511323···13771353 ieee80211_is_qos_nullfunc(hdr->frame_control))13781354 qoshdr = ieee80211_get_qos_ctl(hdr);1379135513801380- /* end service period after last frame */13811381- if (skb_queue_empty(&frames)) {13821382- if (reason == IEEE80211_FRAME_RELEASE_UAPSD &&13831383- qoshdr)13841384- *qoshdr |= IEEE80211_QOS_CTL_EOSP;13561356+ tids |= BIT(skb->priority);13571357+13581358+ __skb_queue_tail(&pending, skb);13591359+13601360+ /* end service period after last frame or add one */13611361+ if (!skb_queue_empty(&frames))13621362+ continue;13631363+13641364+ if (reason != IEEE80211_FRAME_RELEASE_UAPSD) {13651365+ /* for PS-Poll, there's only one frame */13661366+ info->flags |= IEEE80211_TX_STATUS_EOSP |13671367+ IEEE80211_TX_CTL_REQ_TX_STATUS;13681368+ break;13691369+ }13701370+13711371+ /* For uAPSD, things are a bit more complicated. If the13721372+ * last frame has a QoS header (i.e. is a QoS-data or13731373+ * QoS-nulldata frame) then just set the EOSP bit there13741374+ * and be done.13751375+ * If the frame doesn't have a QoS header (which means13761376+ * it should be a bufferable MMPDU) then we can't set13771377+ * the EOSP bit in the QoS header; add a QoS-nulldata13781378+ * frame to the list to send it after the MMPDU.13791379+ *13801380+ * Note that this code is only in the mac80211-release13811381+ * code path, we assume that the driver will not buffer13821382+ * anything but QoS-data frames, or if it does, will13831383+ * create the QoS-nulldata frame by itself if needed.13841384+ *13851385+ * Cf. 802.11-2012 10.2.1.10 (c).13861386+ */13871387+ if (qoshdr) {13881388+ *qoshdr |= IEEE80211_QOS_CTL_EOSP;1385138913861390 info->flags |= IEEE80211_TX_STATUS_EOSP |13871391 IEEE80211_TX_CTL_REQ_TX_STATUS;13921392+ } else {13931393+ /* The standard isn't completely clear on this13941394+ * as it says the more-data bit should be set13951395+ * if there are more BUs. The QoS-Null frame13961396+ * we're about to send isn't buffered yet, we13971397+ * only create it below, but let's pretend it13981398+ * was buffered just in case some clients only13991399+ * expect more-data=0 when eosp=1.14001400+ */14011401+ hdr->frame_control |=14021402+ cpu_to_le16(IEEE80211_FCTL_MOREDATA);14031403+ need_null = true;14041404+ num++;13881405 }13891389-13901390- if (qoshdr)13911391- tids |= BIT(*qoshdr & IEEE80211_QOS_CTL_TID_MASK);13921392- else13931393- tids |= BIT(0);13941394-13951395- __skb_queue_tail(&pending, skb);14061406+ break;13961407 }1397140813981409 drv_allow_buffered_frames(local, sta, tids, num,···1435137614361377 ieee80211_add_pending_skbs(local, &pending);1437137813791379+ if (need_null)13801380+ ieee80211_send_null_response(13811381+ sdata, sta, find_highest_prio_tid(tids),13821382+ reason, false);13831383+14381384 sta_info_recalc_tim(sta);14391385 } else {14401386 /*14411387 * We need to release a frame that is buffered somewhere in the14421388 * driver ... it'll have to handle that.14431443- * Note that, as per the comment above, it'll also have to see14441444- * if there is more than just one frame on the specific TID that14451445- * we're releasing from, and it needs to set the more-data bit14461446- * accordingly if we tell it that there's no more data. If we do14471447- * tell it there's more data, then of course the more-data bit14481448- * needs to be set anyway.13891389+ * Note that the driver also has to check the number of frames13901390+ * on the TIDs we're releasing from - if there are more than13911391+ * n_frames it has to set the more-data bit (if we didn't ask13921392+ * it to set it anyway due to other buffered frames); if there13931393+ * are fewer than n_frames it has to make sure to adjust that13941394+ * to allow the service period to end properly.14491395 */14501396 drv_release_buffered_frames(local, sta, driver_release_tids,14511397 n_frames, reason, more_data);···14581394 /*14591395 * Note that we don't recalculate the TIM bit here as it would14601396 * most likely have no effect at all unless the driver told us14611461- * that the TID became empty before returning here from the13971397+ * that the TID(s) became empty before returning here from the14621398 * release function.14631463- * Either way, however, when the driver tells us that the TID13991399+ * Either way, however, when the driver tells us that the TID(s)14641400 * became empty we'll do the TIM recalculation.14651401 */14661402 }···1548148415491485 if (WARN_ON(tid >= IEEE80211_NUM_TIDS))15501486 return;14871487+14881488+ trace_api_sta_set_buffered(sta->local, pubsta, tid, buffered);1551148915521490 if (buffered)15531491 set_bit(tid, &sta->driver_buffered_tids);
+27
net/mac80211/trace.h
···18351835 )18361836);1837183718381838+TRACE_EVENT(api_sta_set_buffered,18391839+ TP_PROTO(struct ieee80211_local *local,18401840+ struct ieee80211_sta *sta,18411841+ u8 tid, bool buffered),18421842+18431843+ TP_ARGS(local, sta, tid, buffered),18441844+18451845+ TP_STRUCT__entry(18461846+ LOCAL_ENTRY18471847+ STA_ENTRY18481848+ __field(u8, tid)18491849+ __field(bool, buffered)18501850+ ),18511851+18521852+ TP_fast_assign(18531853+ LOCAL_ASSIGN;18541854+ STA_ASSIGN;18551855+ __entry->tid = tid;18561856+ __entry->buffered = buffered;18571857+ ),18581858+18591859+ TP_printk(18601860+ LOCAL_PR_FMT STA_PR_FMT " tid:%d buffered:%d",18611861+ LOCAL_PR_ARG, STA_PR_ARG, __entry->tid, __entry->buffered18621862+ )18631863+);18641864+18381865/*18391866 * Tracing for internal functions18401867 * (which may also be called in response to driver calls)
···127127 * APs with pairwise keys should never receive Michael MIC128128 * errors for non-zero keyidx because these are reserved for129129 * group keys and only the AP is sending real multicast130130- * frames in the BSS. (130130+ * frames in the BSS.131131 */132132 return RX_DROP_UNUSABLE;133133 }
+2-5
net/nfc/core.c
···133133 dev->dev_up = true;134134135135 /* We have to enable the device before discovering SEs */136136- if (dev->ops->discover_se) {137137- rc = dev->ops->discover_se(dev);138138- if (rc)139139- pr_warn("SE discovery failed\n");140140- }136136+ if (dev->ops->discover_se && dev->ops->discover_se(dev))137137+ pr_err("SE discovery failed\n");141138142139error:143140 device_unlock(&dev->dev);
+26-2
net/nfc/digital_core.c
···339339 pr_debug("rf_tech=%d, protocol=%d\n", rf_tech, protocol);340340341341 ddev->curr_rf_tech = rf_tech;342342- ddev->curr_protocol = protocol;343342344343 if (DIGITAL_DRV_CAPS_IN_CRC(ddev)) {345344 ddev->skb_add_crc = digital_skb_add_crc_none;···540541 __u8 comm_mode, __u8 *gb, size_t gb_len)541542{542543 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);544544+ int rc;543545544544- return digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len);546546+ rc = digital_in_send_atr_req(ddev, target, comm_mode, gb, gb_len);547547+548548+ if (!rc)549549+ ddev->curr_protocol = NFC_PROTO_NFC_DEP;550550+551551+ return rc;545552}546553547554static int digital_dep_link_down(struct nfc_dev *nfc_dev)···562557static int digital_activate_target(struct nfc_dev *nfc_dev,563558 struct nfc_target *target, __u32 protocol)564559{560560+ struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);561561+562562+ if (ddev->poll_tech_count) {563563+ pr_err("Can't activate a target while polling\n");564564+ return -EBUSY;565565+ }566566+567567+ if (ddev->curr_protocol) {568568+ pr_err("A target is already active\n");569569+ return -EBUSY;570570+ }571571+572572+ ddev->curr_protocol = protocol;573573+565574 return 0;566575}567576···583564 struct nfc_target *target)584565{585566 struct nfc_digital_dev *ddev = nfc_get_drvdata(nfc_dev);567567+568568+ if (!ddev->curr_protocol) {569569+ pr_err("No active target\n");570570+ return;571571+ }586572587573 ddev->curr_protocol = 0;588574}
···335335 kfree_skb(skb);336336337337exit_noskb:338338- if (r) {339339- /* TODO: There was an error dispatching the event,340340- * how to propagate up to nfc core?341341- */342342- }338338+ if (r)339339+ nfc_hci_driver_failure(hdev, r);343340}344341345342static void nfc_hci_cmd_timeout(unsigned long data)