···11* STMicroelectronics SAS. ST21NFCA NFC Controller2233Required properties:44-- compatible: Should be "st,st21nfca-i2c".44+- compatible: Should be "st,st21nfca_i2c".55- clock-frequency: I²C work frequency.66- reg: address on the bus77- interrupt-parent: phandle for the interrupt gpio controller
···329329 return ret;330330}331331332332+void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe)333333+{334334+ struct ath10k *ar = pipe->ar;335335+ struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);336336+ struct ath10k_ce_ring *src_ring = pipe->src_ring;337337+ u32 ctrl_addr = pipe->ctrl_addr;338338+339339+ lockdep_assert_held(&ar_pci->ce_lock);340340+341341+ /*342342+ * This function must be called only if there is an incomplete343343+ * scatter-gather transfer (before index register is updated)344344+ * that needs to be cleaned up.345345+ */346346+ if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index))347347+ return;348348+349349+ if (WARN_ON_ONCE(src_ring->write_index ==350350+ ath10k_ce_src_ring_write_index_get(ar, ctrl_addr)))351351+ return;352352+353353+ src_ring->write_index--;354354+ src_ring->write_index &= src_ring->nentries_mask;355355+356356+ src_ring->per_transfer_context[src_ring->write_index] = NULL;357357+}358358+332359int ath10k_ce_send(struct ath10k_ce_pipe *ce_state,333360 void *per_transfer_context,334361 u32 buffer,
+2
drivers/net/wireless/ath/ath10k/ce.h
···160160 unsigned int transfer_id,161161 unsigned int flags);162162163163+void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe);164164+163165void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state,164166 void (*send_cb)(struct ath10k_ce_pipe *),165167 int disable_interrupts);
+154-123
drivers/net/wireless/ath/ath10k/core.c
···5858 complete(&ar->target_suspend);5959}60606161-static int ath10k_init_connect_htc(struct ath10k *ar)6262-{6363- int status;6464-6565- status = ath10k_wmi_connect_htc_service(ar);6666- if (status)6767- goto conn_fail;6868-6969- /* Start HTC */7070- status = ath10k_htc_start(&ar->htc);7171- if (status)7272- goto conn_fail;7373-7474- /* Wait for WMI event to be ready */7575- status = ath10k_wmi_wait_for_service_ready(ar);7676- if (status <= 0) {7777- ath10k_warn("wmi service ready event not received");7878- status = -ETIMEDOUT;7979- goto timeout;8080- }8181-8282- ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n");8383- return 0;8484-8585-timeout:8686- ath10k_htc_stop(&ar->htc);8787-conn_fail:8888- return status;8989-}9090-9161static int ath10k_init_configure_target(struct ath10k *ar)9262{9363 u32 param_host;···651681 switch (ar->state) {652682 case ATH10K_STATE_ON:653683 ar->state = ATH10K_STATE_RESTARTING;654654- ath10k_halt(ar);684684+ del_timer_sync(&ar->scan.timeout);685685+ ath10k_reset_scan((unsigned long)ar);655686 ieee80211_restart_hw(ar->hw);656687 break;657688 case ATH10K_STATE_OFF:···661690 ath10k_warn("cannot restart a device that hasn't been started\n");662691 break;663692 case ATH10K_STATE_RESTARTING:693693+ /* hw restart might be requested from multiple places */694694+ break;664695 case ATH10K_STATE_RESTARTED:665696 ar->state = ATH10K_STATE_WEDGED;666697 /* fall through */···673700674701 mutex_unlock(&ar->conf_mutex);675702}676676-677677-struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,678678- const struct ath10k_hif_ops *hif_ops)679679-{680680- struct ath10k *ar;681681-682682- ar = ath10k_mac_create();683683- if (!ar)684684- return NULL;685685-686686- ar->ath_common.priv = ar;687687- ar->ath_common.hw = ar->hw;688688-689689- ar->p2p = !!ath10k_p2p;690690- ar->dev = dev;691691-692692- ar->hif.priv = hif_priv;693693- ar->hif.ops = hif_ops;694694-695695- init_completion(&ar->scan.started);696696- init_completion(&ar->scan.completed);697697- init_completion(&ar->scan.on_channel);698698- init_completion(&ar->target_suspend);699699-700700- init_completion(&ar->install_key_done);701701- init_completion(&ar->vdev_setup_done);702702-703703- setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar);704704-705705- ar->workqueue = create_singlethread_workqueue("ath10k_wq");706706- if (!ar->workqueue)707707- goto err_wq;708708-709709- mutex_init(&ar->conf_mutex);710710- spin_lock_init(&ar->data_lock);711711-712712- INIT_LIST_HEAD(&ar->peers);713713- init_waitqueue_head(&ar->peer_mapping_wq);714714-715715- init_completion(&ar->offchan_tx_completed);716716- INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);717717- skb_queue_head_init(&ar->offchan_tx_queue);718718-719719- INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);720720- skb_queue_head_init(&ar->wmi_mgmt_tx_queue);721721-722722- INIT_WORK(&ar->restart_work, ath10k_core_restart);723723-724724- return ar;725725-726726-err_wq:727727- ath10k_mac_destroy(ar);728728- return NULL;729729-}730730-EXPORT_SYMBOL(ath10k_core_create);731731-732732-void ath10k_core_destroy(struct ath10k *ar)733733-{734734- flush_workqueue(ar->workqueue);735735- destroy_workqueue(ar->workqueue);736736-737737- ath10k_mac_destroy(ar);738738-}739739-EXPORT_SYMBOL(ath10k_core_destroy);740703741704int ath10k_core_start(struct ath10k *ar)742705{···714805 goto err;715806 }716807808808+ status = ath10k_htt_init(ar);809809+ if (status) {810810+ ath10k_err("failed to init htt: %d\n", status);811811+ goto err_wmi_detach;812812+ }813813+814814+ status = ath10k_htt_tx_alloc(&ar->htt);815815+ if (status) {816816+ ath10k_err("failed to alloc htt tx: %d\n", status);817817+ goto err_wmi_detach;818818+ }819819+820820+ status = ath10k_htt_rx_alloc(&ar->htt);821821+ if (status) {822822+ ath10k_err("failed to alloc htt rx: %d\n", status);823823+ goto err_htt_tx_detach;824824+ }825825+717826 status = ath10k_hif_start(ar);718827 if (status) {719828 ath10k_err("could not start HIF: %d\n", status);720720- goto err_wmi_detach;829829+ goto err_htt_rx_detach;721830 }722831723832 status = ath10k_htc_wait_target(&ar->htc);···744817 goto err_hif_stop;745818 }746819747747- status = ath10k_htt_attach(ar);820820+ status = ath10k_htt_connect(&ar->htt);748821 if (status) {749749- ath10k_err("could not attach htt (%d)\n", status);822822+ ath10k_err("failed to connect htt (%d)\n", status);750823 goto err_hif_stop;751824 }752825753753- status = ath10k_init_connect_htc(ar);754754- if (status)755755- goto err_htt_detach;826826+ status = ath10k_wmi_connect(ar);827827+ if (status) {828828+ ath10k_err("could not connect wmi: %d\n", status);829829+ goto err_hif_stop;830830+ }831831+832832+ status = ath10k_htc_start(&ar->htc);833833+ if (status) {834834+ ath10k_err("failed to start htc: %d\n", status);835835+ goto err_hif_stop;836836+ }837837+838838+ status = ath10k_wmi_wait_for_service_ready(ar);839839+ if (status <= 0) {840840+ ath10k_warn("wmi service ready event not received");841841+ status = -ETIMEDOUT;842842+ goto err_htc_stop;843843+ }756844757845 ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n",758846 ar->hw->wiphy->fw_version);···775833 status = ath10k_wmi_cmd_init(ar);776834 if (status) {777835 ath10k_err("could not send WMI init command (%d)\n", status);778778- goto err_disconnect_htc;836836+ goto err_htc_stop;779837 }780838781839 status = ath10k_wmi_wait_for_unified_ready(ar);782840 if (status <= 0) {783841 ath10k_err("wmi unified ready event not received\n");784842 status = -ETIMEDOUT;785785- goto err_disconnect_htc;843843+ goto err_htc_stop;786844 }787845788788- status = ath10k_htt_attach_target(&ar->htt);789789- if (status)790790- goto err_disconnect_htc;846846+ status = ath10k_htt_setup(&ar->htt);847847+ if (status) {848848+ ath10k_err("failed to setup htt: %d\n", status);849849+ goto err_htc_stop;850850+ }791851792852 status = ath10k_debug_start(ar);793853 if (status)794794- goto err_disconnect_htc;854854+ goto err_htc_stop;795855796856 ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1;797857 INIT_LIST_HEAD(&ar->arvifs);···812868813869 return 0;814870815815-err_disconnect_htc:871871+err_htc_stop:816872 ath10k_htc_stop(&ar->htc);817817-err_htt_detach:818818- ath10k_htt_detach(&ar->htt);819873err_hif_stop:820874 ath10k_hif_stop(ar);875875+err_htt_rx_detach:876876+ ath10k_htt_rx_free(&ar->htt);877877+err_htt_tx_detach:878878+ ath10k_htt_tx_free(&ar->htt);821879err_wmi_detach:822880 ath10k_wmi_detach(ar);823881err:···859913860914 ath10k_debug_stop(ar);861915 ath10k_htc_stop(&ar->htc);862862- ath10k_htt_detach(&ar->htt);916916+ ath10k_hif_stop(ar);917917+ ath10k_htt_tx_free(&ar->htt);918918+ ath10k_htt_rx_free(&ar->htt);863919 ath10k_wmi_detach(ar);864920}865921EXPORT_SYMBOL(ath10k_core_stop);···9531005 return 0;9541006}9551007956956-int ath10k_core_register(struct ath10k *ar, u32 chip_id)10081008+static void ath10k_core_register_work(struct work_struct *work)9571009{10101010+ struct ath10k *ar = container_of(work, struct ath10k, register_work);9581011 int status;959959-960960- ar->chip_id = chip_id;961961-962962- status = ath10k_core_check_chip_id(ar);963963- if (status) {964964- ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id);965965- return status;966966- }96710129681013 status = ath10k_core_probe_fw(ar);9691014 if (status) {9701015 ath10k_err("could not probe fw (%d)\n", status);971971- return status;10161016+ goto err;9721017 }97310189741019 status = ath10k_mac_register(ar);···9761035 goto err_unregister_mac;9771036 }9781037979979- return 0;10381038+ set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);10391039+ return;98010409811041err_unregister_mac:9821042 ath10k_mac_unregister(ar);9831043err_release_fw:9841044 ath10k_core_free_firmware_files(ar);985985- return status;10451045+err:10461046+ device_release_driver(ar->dev);10471047+ return;10481048+}10491049+10501050+int ath10k_core_register(struct ath10k *ar, u32 chip_id)10511051+{10521052+ int status;10531053+10541054+ ar->chip_id = chip_id;10551055+10561056+ status = ath10k_core_check_chip_id(ar);10571057+ if (status) {10581058+ ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id);10591059+ return status;10601060+ }10611061+10621062+ queue_work(ar->workqueue, &ar->register_work);10631063+10641064+ return 0;9861065}9871066EXPORT_SYMBOL(ath10k_core_register);98810679891068void ath10k_core_unregister(struct ath10k *ar)9901069{10701070+ cancel_work_sync(&ar->register_work);10711071+10721072+ if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))10731073+ return;10741074+9911075 /* We must unregister from mac80211 before we stop HTC and HIF.9921076 * Otherwise we will fail to submit commands to FW and mac80211 will be9931077 * unhappy about callback failures. */···10231057 ath10k_debug_destroy(ar);10241058}10251059EXPORT_SYMBOL(ath10k_core_unregister);10601060+10611061+struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev,10621062+ const struct ath10k_hif_ops *hif_ops)10631063+{10641064+ struct ath10k *ar;10651065+10661066+ ar = ath10k_mac_create();10671067+ if (!ar)10681068+ return NULL;10691069+10701070+ ar->ath_common.priv = ar;10711071+ ar->ath_common.hw = ar->hw;10721072+10731073+ ar->p2p = !!ath10k_p2p;10741074+ ar->dev = dev;10751075+10761076+ ar->hif.priv = hif_priv;10771077+ ar->hif.ops = hif_ops;10781078+10791079+ init_completion(&ar->scan.started);10801080+ init_completion(&ar->scan.completed);10811081+ init_completion(&ar->scan.on_channel);10821082+ init_completion(&ar->target_suspend);10831083+10841084+ init_completion(&ar->install_key_done);10851085+ init_completion(&ar->vdev_setup_done);10861086+10871087+ setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar);10881088+10891089+ ar->workqueue = create_singlethread_workqueue("ath10k_wq");10901090+ if (!ar->workqueue)10911091+ goto err_wq;10921092+10931093+ mutex_init(&ar->conf_mutex);10941094+ spin_lock_init(&ar->data_lock);10951095+10961096+ INIT_LIST_HEAD(&ar->peers);10971097+ init_waitqueue_head(&ar->peer_mapping_wq);10981098+10991099+ init_completion(&ar->offchan_tx_completed);11001100+ INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work);11011101+ skb_queue_head_init(&ar->offchan_tx_queue);11021102+11031103+ INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work);11041104+ skb_queue_head_init(&ar->wmi_mgmt_tx_queue);11051105+11061106+ INIT_WORK(&ar->register_work, ath10k_core_register_work);11071107+ INIT_WORK(&ar->restart_work, ath10k_core_restart);11081108+11091109+ return ar;11101110+11111111+err_wq:11121112+ ath10k_mac_destroy(ar);11131113+ return NULL;11141114+}11151115+EXPORT_SYMBOL(ath10k_core_create);11161116+11171117+void ath10k_core_destroy(struct ath10k *ar)11181118+{11191119+ flush_workqueue(ar->workqueue);11201120+ destroy_workqueue(ar->workqueue);11211121+11221122+ ath10k_mac_destroy(ar);11231123+}11241124+EXPORT_SYMBOL(ath10k_core_destroy);1026112510271126MODULE_AUTHOR("Qualcomm Atheros");10281127MODULE_DESCRIPTION("Core module for QCA988X PCIe devices.");
+8
drivers/net/wireless/ath/ath10k/core.h
···335335 /* Indicates that ath10k device is during CAC phase of DFS */336336 ATH10K_CAC_RUNNING,337337 ATH10K_FLAG_FIRST_BOOT_DONE,338338+ ATH10K_FLAG_CORE_REGISTERED,338339};339340340341struct ath10k {···441440 bool radar_enabled;442441 int num_started_vdevs;443442443443+ /* Protected by conf-mutex */444444+ u8 supp_tx_chainmask;445445+ u8 supp_rx_chainmask;446446+ u8 cfg_tx_chainmask;447447+ u8 cfg_rx_chainmask;448448+444449 struct wmi_pdev_set_wmm_params_arg wmm_params;445450 struct completion install_key_done;446451···477470478471 enum ath10k_state state;479472473473+ struct work_struct register_work;480474 struct work_struct restart_work;481475482476 /* cycle count is reported twice for each visited channel during scan.
-6
drivers/net/wireless/ath/ath10k/htc.c
···830830 return 0;831831}832832833833-/*834834- * stop HTC communications, i.e. stop interrupt reception, and flush all835835- * queued buffers836836- */837833void ath10k_htc_stop(struct ath10k_htc *htc)838834{839835 spin_lock_bh(&htc->tx_lock);840836 htc->stopped = true;841837 spin_unlock_bh(&htc->tx_lock);842842-843843- ath10k_hif_stop(htc->ar);844838}845839846840/* registered target arrival callback from the HIF layer */
+3-39
drivers/net/wireless/ath/ath10k/htt.c
···2222#include "core.h"2323#include "debug.h"24242525-static int ath10k_htt_htc_attach(struct ath10k_htt *htt)2525+int ath10k_htt_connect(struct ath10k_htt *htt)2626{2727 struct ath10k_htc_svc_conn_req conn_req;2828 struct ath10k_htc_svc_conn_resp conn_resp;···4848 return 0;4949}50505151-int ath10k_htt_attach(struct ath10k *ar)5151+int ath10k_htt_init(struct ath10k *ar)5252{5353 struct ath10k_htt *htt = &ar->htt;5454- int ret;55545655 htt->ar = ar;5756 htt->max_throughput_mbps = 800;5858-5959- /*6060- * Connect to HTC service.6161- * This has to be done before calling ath10k_htt_rx_attach,6262- * since ath10k_htt_rx_attach involves sending a rx ring configure6363- * message to the target.6464- */6565- ret = ath10k_htt_htc_attach(htt);6666- if (ret) {6767- ath10k_err("could not attach htt htc (%d)\n", ret);6868- goto err_htc_attach;6969- }7070-7171- ret = ath10k_htt_tx_attach(htt);7272- if (ret) {7373- ath10k_err("could not attach htt tx (%d)\n", ret);7474- goto err_htc_attach;7575- }7676-7777- ret = ath10k_htt_rx_attach(htt);7878- if (ret) {7979- ath10k_err("could not attach htt rx (%d)\n", ret);8080- goto err_rx_attach;8181- }82578358 /*8459 * Prefetch enough data to satisfy target···6893 2; /* ip4 dscp or ip6 priority */69947095 return 0;7171-7272-err_rx_attach:7373- ath10k_htt_tx_detach(htt);7474-err_htc_attach:7575- return ret;7696}77977898#define HTT_TARGET_VERSION_TIMEOUT_HZ (3*HZ)···87117 return 0;88118}891199090-int ath10k_htt_attach_target(struct ath10k_htt *htt)120120+int ath10k_htt_setup(struct ath10k_htt *htt)91121{92122 int status;93123···109139 return status;110140111141 return ath10k_htt_send_rx_ring_cfg_ll(htt);112112-}113113-114114-void ath10k_htt_detach(struct ath10k_htt *htt)115115-{116116- ath10k_htt_rx_detach(htt);117117- ath10k_htt_tx_detach(htt);118142}
···5454 switch (key->cipher) {5555 case WLAN_CIPHER_SUITE_CCMP:5656 arg.key_cipher = WMI_CIPHER_AES_CCM;5757- key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;5757+ if (arvif->vdev_type == WMI_VDEV_TYPE_AP)5858+ key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV_MGMT;5959+ else6060+ key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;5861 break;5962 case WLAN_CIPHER_SUITE_TKIP:6063 arg.key_cipher = WMI_CIPHER_TKIP;···18911888 wep_key_work);18921889 int ret, keyidx = arvif->def_wep_key_newidx;1893189018911891+ mutex_lock(&arvif->ar->conf_mutex);18921892+18931893+ if (arvif->ar->state != ATH10K_STATE_ON)18941894+ goto unlock;18951895+18941896 if (arvif->def_wep_key_idx == keyidx)18951895- return;18971897+ goto unlock;1896189818971899 ath10k_dbg(ATH10K_DBG_MAC, "mac vdev %d set keyidx %d\n",18981900 arvif->vdev_id, keyidx);···19101902 ath10k_warn("failed to update wep key index for vdev %d: %d\n",19111903 arvif->vdev_id,19121904 ret);19131913- return;19051905+ goto unlock;19141906 }1915190719161908 arvif->def_wep_key_idx = keyidx;19091909+19101910+unlock:19111911+ mutex_unlock(&arvif->ar->conf_mutex);19171912}1918191319191914static void ath10k_tx_h_update_wep_key(struct sk_buff *skb)···22972286 ath10k_tx_htt(ar, skb);22982287}2299228823002300-/*23012301- * Initialize various parameters with default vaules.23022302- */22892289+/* Must not be called with conf_mutex held as workers can use that also. */22902290+static void ath10k_drain_tx(struct ath10k *ar)22912291+{22922292+ /* make sure rcu-protected mac80211 tx path itself is drained */22932293+ synchronize_net();22942294+22952295+ ath10k_offchan_tx_purge(ar);22962296+ ath10k_mgmt_over_wmi_tx_purge(ar);22972297+22982298+ cancel_work_sync(&ar->offchan_tx_work);22992299+ cancel_work_sync(&ar->wmi_mgmt_tx_work);23002300+}23012301+23032302void ath10k_halt(struct ath10k *ar)23042303{23052304 struct ath10k_vif *arvif;···23242303 }2325230423262305 del_timer_sync(&ar->scan.timeout);23272327- ath10k_offchan_tx_purge(ar);23282328- ath10k_mgmt_over_wmi_tx_purge(ar);23062306+ ath10k_reset_scan((unsigned long)ar);23292307 ath10k_peer_cleanup_all(ar);23302308 ath10k_core_stop(ar);23312309 ath10k_hif_power_down(ar);2332231023332311 spin_lock_bh(&ar->data_lock);23342334- if (ar->scan.in_progress) {23352335- del_timer(&ar->scan.timeout);23362336- ar->scan.in_progress = false;23372337- ieee80211_scan_completed(ar->hw, true);23382338- }23392339-23402312 list_for_each_entry(arvif, &ar->arvifs, list) {23412313 if (!arvif->beacon)23422314 continue;···23432329 spin_unlock_bh(&ar->data_lock);23442330}2345233123322332+static int ath10k_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)23332333+{23342334+ struct ath10k *ar = hw->priv;23352335+23362336+ mutex_lock(&ar->conf_mutex);23372337+23382338+ if (ar->cfg_tx_chainmask) {23392339+ *tx_ant = ar->cfg_tx_chainmask;23402340+ *rx_ant = ar->cfg_rx_chainmask;23412341+ } else {23422342+ *tx_ant = ar->supp_tx_chainmask;23432343+ *rx_ant = ar->supp_rx_chainmask;23442344+ }23452345+23462346+ mutex_unlock(&ar->conf_mutex);23472347+23482348+ return 0;23492349+}23502350+23512351+static int __ath10k_set_antenna(struct ath10k *ar, u32 tx_ant, u32 rx_ant)23522352+{23532353+ int ret;23542354+23552355+ lockdep_assert_held(&ar->conf_mutex);23562356+23572357+ ar->cfg_tx_chainmask = tx_ant;23582358+ ar->cfg_rx_chainmask = rx_ant;23592359+23602360+ if ((ar->state != ATH10K_STATE_ON) &&23612361+ (ar->state != ATH10K_STATE_RESTARTED))23622362+ return 0;23632363+23642364+ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->tx_chain_mask,23652365+ tx_ant);23662366+ if (ret) {23672367+ ath10k_warn("failed to set tx-chainmask: %d, req 0x%x\n",23682368+ ret, tx_ant);23692369+ return ret;23702370+ }23712371+23722372+ ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->rx_chain_mask,23732373+ rx_ant);23742374+ if (ret) {23752375+ ath10k_warn("failed to set rx-chainmask: %d, req 0x%x\n",23762376+ ret, rx_ant);23772377+ return ret;23782378+ }23792379+23802380+ return 0;23812381+}23822382+23832383+static int ath10k_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)23842384+{23852385+ struct ath10k *ar = hw->priv;23862386+ int ret;23872387+23882388+ mutex_lock(&ar->conf_mutex);23892389+ ret = __ath10k_set_antenna(ar, tx_ant, rx_ant);23902390+ mutex_unlock(&ar->conf_mutex);23912391+ return ret;23922392+}23932393+23462394static int ath10k_start(struct ieee80211_hw *hw)23472395{23482396 struct ath10k *ar = hw->priv;23492397 int ret = 0;2350239823992399+ /*24002400+ * This makes sense only when restarting hw. It is harmless to call24012401+ * uncoditionally. This is necessary to make sure no HTT/WMI tx24022402+ * commands will be submitted while restarting.24032403+ */24042404+ ath10k_drain_tx(ar);24052405+23512406 mutex_lock(&ar->conf_mutex);2352240723532353- if (ar->state != ATH10K_STATE_OFF &&23542354- ar->state != ATH10K_STATE_RESTARTING) {24082408+ switch (ar->state) {24092409+ case ATH10K_STATE_OFF:24102410+ ar->state = ATH10K_STATE_ON;24112411+ break;24122412+ case ATH10K_STATE_RESTARTING:24132413+ ath10k_halt(ar);24142414+ ar->state = ATH10K_STATE_RESTARTED;24152415+ break;24162416+ case ATH10K_STATE_ON:24172417+ case ATH10K_STATE_RESTARTED:24182418+ case ATH10K_STATE_WEDGED:24192419+ WARN_ON(1);23552420 ret = -EINVAL;23562356- goto exit;24212421+ goto err;23572422 }2358242323592424 ret = ath10k_hif_power_up(ar);23602425 if (ret) {23612426 ath10k_err("Could not init hif: %d\n", ret);23622362- ar->state = ATH10K_STATE_OFF;23632363- goto exit;24272427+ goto err_off;23642428 }2365242923662430 ret = ath10k_core_start(ar);23672431 if (ret) {23682432 ath10k_err("Could not init core: %d\n", ret);23692369- ath10k_hif_power_down(ar);23702370- ar->state = ATH10K_STATE_OFF;23712371- goto exit;24332433+ goto err_power_down;23722434 }2373243523742374- if (ar->state == ATH10K_STATE_OFF)23752375- ar->state = ATH10K_STATE_ON;23762376- else if (ar->state == ATH10K_STATE_RESTARTING)23772377- ar->state = ATH10K_STATE_RESTARTED;23782378-23792436 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->pmf_qos, 1);23802380- if (ret)24372437+ if (ret) {23812438 ath10k_warn("failed to enable PMF QOS: %d\n", ret);24392439+ goto err_core_stop;24402440+ }2382244123832442 ret = ath10k_wmi_pdev_set_param(ar, ar->wmi.pdev_param->dynamic_bw, 1);23842384- if (ret)24432443+ if (ret) {23852444 ath10k_warn("failed to enable dynamic BW: %d\n", ret);24452445+ goto err_core_stop;24462446+ }24472447+24482448+ if (ar->cfg_tx_chainmask)24492449+ __ath10k_set_antenna(ar, ar->cfg_tx_chainmask,24502450+ ar->cfg_rx_chainmask);2386245123872452 /*23882453 * By default FW set ARP frames ac to voice (6). In that case ARP···24772384 if (ret) {24782385 ath10k_warn("failed to set arp ac override parameter: %d\n",24792386 ret);24802480- goto exit;23872387+ goto err_core_stop;24812388 }2482238924832390 ar->num_started_vdevs = 0;24842391 ath10k_regd_update(ar);24852485- ret = 0;2486239224872487-exit:23932393+ mutex_unlock(&ar->conf_mutex);23942394+ return 0;23952395+23962396+err_core_stop:23972397+ ath10k_core_stop(ar);23982398+23992399+err_power_down:24002400+ ath10k_hif_power_down(ar);24012401+24022402+err_off:24032403+ ar->state = ATH10K_STATE_OFF;24042404+24052405+err:24882406 mutex_unlock(&ar->conf_mutex);24892407 return ret;24902408}···25042400{25052401 struct ath10k *ar = hw->priv;2506240225072507- mutex_lock(&ar->conf_mutex);25082508- if (ar->state == ATH10K_STATE_ON ||25092509- ar->state == ATH10K_STATE_RESTARTED ||25102510- ar->state == ATH10K_STATE_WEDGED)25112511- ath10k_halt(ar);24032403+ ath10k_drain_tx(ar);2512240425132513- ar->state = ATH10K_STATE_OFF;24052405+ mutex_lock(&ar->conf_mutex);24062406+ if (ar->state != ATH10K_STATE_OFF) {24072407+ ath10k_halt(ar);24082408+ ar->state = ATH10K_STATE_OFF;24092409+ }25142410 mutex_unlock(&ar->conf_mutex);2515241125162516- ath10k_mgmt_over_wmi_tx_purge(ar);25172517-25182518- cancel_work_sync(&ar->offchan_tx_work);25192519- cancel_work_sync(&ar->wmi_mgmt_tx_work);25202412 cancel_work_sync(&ar->restart_work);25212413}25222414···30252925 arvif->u.ap.hidden_ssid = info->hidden_ssid;30262926 }3027292730283028- if (changed & BSS_CHANGED_BSSID) {29282928+ /*29292929+ * Firmware manages AP self-peer internally so make sure to not create29302930+ * it in driver. Otherwise AP self-peer deletion may timeout later.29312931+ */29322932+ if (changed & BSS_CHANGED_BSSID &&29332933+ vif->type != NL80211_IFTYPE_AP) {30292934 if (!is_zero_ether_addr(info->bssid)) {30302935 ath10k_dbg(ATH10K_DBG_MAC,30312936 "mac vdev %d create peer %pM\n",···42474142 fixed_nss, force_sgi);42484143}4249414442504250-static void ath10k_channel_switch_beacon(struct ieee80211_hw *hw,42514251- struct ieee80211_vif *vif,42524252- struct cfg80211_chan_def *chandef)42534253-{42544254- /* there's no need to do anything here. vif->csa_active is enough */42554255- return;42564256-}42574257-42584145static void ath10k_sta_rc_update(struct ieee80211_hw *hw,42594146 struct ieee80211_vif *vif,42604147 struct ieee80211_sta *sta,···43504253 .set_frag_threshold = ath10k_set_frag_threshold,43514254 .flush = ath10k_flush,43524255 .tx_last_beacon = ath10k_tx_last_beacon,42564256+ .set_antenna = ath10k_set_antenna,42574257+ .get_antenna = ath10k_get_antenna,43534258 .restart_complete = ath10k_restart_complete,43544259 .get_survey = ath10k_get_survey,43554260 .set_bitrate_mask = ath10k_set_bitrate_mask,43564356- .channel_switch_beacon = ath10k_channel_switch_beacon,43574261 .sta_rc_update = ath10k_sta_rc_update,43584262 .get_tsf = ath10k_get_tsf,43594263#ifdef CONFIG_PM···46994601 BIT(NL80211_IFTYPE_STATION) |47004602 BIT(NL80211_IFTYPE_ADHOC) |47014603 BIT(NL80211_IFTYPE_AP);46044604+46054605+ if (test_bit(ATH10K_FW_FEATURE_WMI_10X, ar->fw_features)) {46064606+ /* TODO: Have to deal with 2x2 chips if/when the come out. */46074607+ ar->supp_tx_chainmask = TARGET_10X_TX_CHAIN_MASK;46084608+ ar->supp_rx_chainmask = TARGET_10X_RX_CHAIN_MASK;46094609+ } else {46104610+ ar->supp_tx_chainmask = TARGET_TX_CHAIN_MASK;46114611+ ar->supp_rx_chainmask = TARGET_RX_CHAIN_MASK;46124612+ }46134613+46144614+ ar->hw->wiphy->available_antennas_rx = ar->supp_rx_chainmask;46154615+ ar->hw->wiphy->available_antennas_tx = ar->supp_tx_chainmask;4702461647034617 if (!test_bit(ATH10K_FW_FEATURE_NO_P2P, ar->fw_features))47044618 ar->hw->wiphy->interface_modes |=
+73-30
drivers/net/wireless/ath/ath10k/pci.c
···59596060/* how long wait to wait for target to initialise, in ms */6161#define ATH10K_PCI_TARGET_WAIT 30006262+#define ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS 362636364#define QCA988X_2_0_DEVICE_ID (0x003c)6465···762761 struct ath10k_pci_pipe *pci_pipe = &ar_pci->pipe_info[pipe_id];763762 struct ath10k_ce_pipe *ce_pipe = pci_pipe->ce_hdl;764763 struct ath10k_ce_ring *src_ring = ce_pipe->src_ring;765765- unsigned int nentries_mask = src_ring->nentries_mask;766766- unsigned int sw_index = src_ring->sw_index;767767- unsigned int write_index = src_ring->write_index;768768- int err, i;764764+ unsigned int nentries_mask;765765+ unsigned int sw_index;766766+ unsigned int write_index;767767+ int err, i = 0;769768770769 spin_lock_bh(&ar_pci->ce_lock);770770+771771+ nentries_mask = src_ring->nentries_mask;772772+ sw_index = src_ring->sw_index;773773+ write_index = src_ring->write_index;771774772775 if (unlikely(CE_RING_DELTA(nentries_mask,773776 write_index, sw_index - 1) < n_items)) {774777 err = -ENOBUFS;775775- goto unlock;778778+ goto err;776779 }777780778781 for (i = 0; i < n_items - 1; i++) {···793788 items[i].transfer_id,794789 CE_SEND_FLAG_GATHER);795790 if (err)796796- goto unlock;791791+ goto err;797792 }798793799794 /* `i` is equal to `n_items -1` after for() */···811806 items[i].transfer_id,812807 0);813808 if (err)814814- goto unlock;809809+ goto err;815810816816- err = 0;817817-unlock:811811+ spin_unlock_bh(&ar_pci->ce_lock);812812+ return 0;813813+814814+err:815815+ for (; i > 0; i--)816816+ __ath10k_ce_send_revert(ce_pipe);817817+818818 spin_unlock_bh(&ar_pci->ce_lock);819819 return err;820820}···12801270 int ret;1281127112821272 ath10k_dbg(ATH10K_DBG_BOOT, "boot hif stop\n");12731273+12741274+ if (WARN_ON(!ar_pci->started))12751275+ return;1283127612841277 ret = ath10k_ce_disable_interrupts(ar);12851278 if (ret)···18151802 ath10k_pci_sleep(ar);18161803}1817180418051805+/* this function effectively clears target memory controller assert line */18061806+static void ath10k_pci_warm_reset_si0(struct ath10k *ar)18071807+{18081808+ u32 val;18091809+18101810+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);18111811+ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,18121812+ val | SOC_RESET_CONTROL_SI0_RST_MASK);18131813+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);18141814+18151815+ msleep(10);18161816+18171817+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);18181818+ ath10k_pci_soc_write32(ar, SOC_RESET_CONTROL_ADDRESS,18191819+ val & ~SOC_RESET_CONTROL_SI0_RST_MASK);18201820+ val = ath10k_pci_soc_read32(ar, SOC_RESET_CONTROL_ADDRESS);18211821+18221822+ msleep(10);18231823+}18241824+18181825static int ath10k_pci_warm_reset(struct ath10k *ar)18191826{18201827 int ret = 0;···18921859 val = ath10k_pci_read32(ar, RTC_SOC_BASE_ADDRESS +18931860 SOC_RESET_CONTROL_ADDRESS);18941861 msleep(10);18621862+18631863+ ath10k_pci_warm_reset_si0(ar);1895186418961865 /* debug */18971866 val = ath10k_pci_read32(ar, SOC_CORE_BASE_ADDRESS +···20231988 return ret;20241989}2025199019911991+static int ath10k_pci_hif_power_up_warm(struct ath10k *ar)19921992+{19931993+ int i, ret;19941994+19951995+ /*19961996+ * Sometime warm reset succeeds after retries.19971997+ *19981998+ * FIXME: It might be possible to tune ath10k_pci_warm_reset() to work19991999+ * at first try.20002000+ */20012001+ for (i = 0; i < ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS; i++) {20022002+ ret = __ath10k_pci_hif_power_up(ar, false);20032003+ if (ret == 0)20042004+ break;20052005+20062006+ ath10k_warn("failed to warm reset (attempt %d out of %d): %d\n",20072007+ i + 1, ATH10K_PCI_NUM_WARM_RESET_ATTEMPTS, ret);20082008+ }20092009+20102010+ return ret;20112011+}20122012+20262013static int ath10k_pci_hif_power_up(struct ath10k *ar)20272014{20282015 int ret;···20561999 * preferred (and safer) way to perform a device reset is through a20572000 * warm reset.20582001 *20592059- * Warm reset doesn't always work though (notably after a firmware20602060- * crash) so fall back to cold reset if necessary.20022002+ * Warm reset doesn't always work though so fall back to cold reset may20032003+ * be necessary.20612004 */20622062- ret = __ath10k_pci_hif_power_up(ar, false);20052005+ ret = ath10k_pci_hif_power_up_warm(ar);20632006 if (ret) {20642007 ath10k_warn("failed to power up target using warm reset: %d\n",20652008 ret);···22532196 if (fw_ind & FW_IND_EVENT_PENDING) {22542197 ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,22552198 fw_ind & ~FW_IND_EVENT_PENDING);22562256-22572257- /* Some structures are unavailable during early boot or at22582258- * driver teardown so just print that the device has crashed. */22592259- ath10k_warn("device crashed - no diagnostics available\n");21992199+ ath10k_pci_hif_dump_area(ar);22602200 }2261220122622202 ath10k_pci_sleep(ar);···2530247625312477 if (val & FW_IND_EVENT_PENDING) {25322478 ath10k_warn("device has crashed during init\n");24792479+ ath10k_pci_write32(ar, FW_INDICATOR_ADDRESS,24802480+ val & ~FW_IND_EVENT_PENDING);24812481+ ath10k_pci_hif_dump_area(ar);25332482 ret = -ECOMM;25342483 goto out;25352484 }···2659260226602603 pci_set_drvdata(pdev, ar);2661260426622662- /*26632663- * Without any knowledge of the Host, the Target may have been reset or26642664- * power cycled and its Config Space may no longer reflect the PCI26652665- * address space that was assigned earlier by the PCI infrastructure.26662666- * Refresh it now.26672667- */26682668- ret = pci_assign_resource(pdev, BAR_NUM);26692669- if (ret) {26702670- ath10k_err("failed to assign PCI space: %d\n", ret);26712671- goto err_ar;26722672- }26732673-26742605 ret = pci_enable_device(pdev);26752606 if (ret) {26762607 ath10k_err("failed to enable PCI device: %d\n", ret);···2769272427702725 if (!ar_pci)27712726 return;27722772-27732773- tasklet_kill(&ar_pci->msi_fw_err);2774272727752728 ath10k_core_unregister(ar);27762729 ath10k_pci_free_ce(ar);
···138138 goto err_release_reg;139139 }140140 /* rollback to err_iounmap */141141- dev_info(&pdev->dev, "CSR at %pR -> %p\n", &pdev->resource[0], csr);141141+ dev_info(&pdev->dev, "CSR at %pR -> 0x%p\n", &pdev->resource[0], csr);142142143143 wil = wil_if_alloc(dev, csr);144144 if (IS_ERR(wil)) {
+8-1
drivers/net/wireless/ath/wil6210/rx_reorder.c
···4949{5050 int index;51515252- while (seq_less(r->head_seq_num, hseq)) {5252+ /* note: this function is never called with5353+ * hseq preceding r->head_seq_num, i.e it is always true5454+ * !seq_less(hseq, r->head_seq_num)5555+ * and thus on loop exit it should be5656+ * r->head_seq_num == hseq5757+ */5858+ while (seq_less(r->head_seq_num, hseq) && r->stored_mpdu_num) {5359 index = reorder_index(r, r->head_seq_num);5460 wil_release_reorder_frame(wil, r, index);5561 }6262+ r->head_seq_num = hseq;5663}57645865static void wil_reorder_release(struct wil6210_priv *wil,
+22-6
drivers/net/wireless/ath/wil6210/txrx.c
···6464 return vring->size - used - 1;6565}66666767+/**6868+ * wil_vring_wmark_low - low watermark for available descriptor space6969+ */7070+static inline int wil_vring_wmark_low(struct vring *vring)7171+{7272+ return vring->size/8;7373+}7474+7575+/**7676+ * wil_vring_wmark_high - high watermark for available descriptor space7777+ */7878+static inline int wil_vring_wmark_high(struct vring *vring)7979+{8080+ return vring->size/4;8181+}8282+6783static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)6884{6985 struct device *dev = wil_to_dev(wil);···11498 _d->dma.status = TX_DMA_STATUS_DU;11599 }116100117117- wil_dbg_misc(wil, "vring[%d] 0x%p:0x%016llx 0x%p\n", vring->size,118118- vring->va, (unsigned long long)vring->pa, vring->ctx);101101+ wil_dbg_misc(wil, "vring[%d] 0x%p:%pad 0x%p\n", vring->size,102102+ vring->va, &vring->pa, vring->ctx);119103120104 return 0;121105}···896880 pa = dma_map_single(dev, skb->data,897881 skb_headlen(skb), DMA_TO_DEVICE);898882899899- wil_dbg_txrx(wil, "Tx skb %d bytes %p -> %#08llx\n", skb_headlen(skb),900900- skb->data, (unsigned long long)pa);883883+ wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb),884884+ skb->data, &pa);901885 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_OFFSET, 16, 1,902886 skb->data, skb_headlen(skb), false);903887···10231007 rc = wil_tx_vring(wil, vring, skb);1024100810251009 /* do we still have enough room in the vring? */10261026- if (wil_vring_avail_tx(vring) < vring->size/8)10101010+ if (wil_vring_avail_tx(vring) < wil_vring_wmark_low(vring))10271011 netif_tx_stop_all_queues(wil_to_ndev(wil));1028101210291013 switch (rc) {···11321116 done++;11331117 }11341118 }11351135- if (wil_vring_avail_tx(vring) > vring->size/4)11191119+ if (wil_vring_avail_tx(vring) > wil_vring_wmark_high(vring))11361120 netif_tx_wake_all_queues(wil_to_ndev(wil));1137112111381122 return done;
+6
drivers/net/wireless/ath/wil6210/wil6210.h
···4040#define WIL6210_MAX_CID (8) /* HW limit */4141#define WIL6210_NAPI_BUDGET (16) /* arbitrary */4242#define WIL6210_ITR_TRSH (10000) /* arbitrary - about 15 IRQs/msec */4343+#define WIL6210_FW_RECOVERY_RETRIES (5) /* try to recover this many times */4444+#define WIL6210_FW_RECOVERY_TO msecs_to_jiffies(5000)4545+#define WIL6210_SCAN_TO msecs_to_jiffies(10000)43464447/* Hardware definitions begin */4548···364361 u32 fw_version;365362 u32 hw_version;366363 u8 n_mids; /* number of additional MIDs as reported by FW */364364+ int recovery_count; /* num of FW recovery attempts in a short time */365365+ unsigned long last_fw_recovery; /* jiffies of last fw recovery */367366 /* profile */368367 u32 monitor_flags;369368 u32 secure_pcp; /* create secure PCP? */···387382 struct work_struct disconnect_worker;388383 struct work_struct fw_error_worker; /* for FW error recovery */389384 struct timer_list connect_timer;385385+ struct timer_list scan_timer; /* detect scan timeout */390386 int pending_connect_cid;391387 struct list_head pending_wmi_ev;392388 /*
···37423742 b43dbg(dev->wl, "Switching to %s GHz band\n",37433743 band_to_string(chan->band));3744374437453745- b43_software_rfkill(dev, true);37453745+ /* Some new devices don't need disabling radio for band switching */37463746+ if (!(phy->type == B43_PHYTYPE_N && phy->rev >= 3))37473747+ b43_software_rfkill(dev, true);3746374837473749 phy->gmode = gmode;37483750 b43_phy_put_into_reset(dev);···51665164static int b43_wireless_core_attach(struct b43_wldev *dev)51675165{51685166 struct b43_wl *wl = dev->wl;51675167+ struct b43_phy *phy = &dev->phy;51695168 int err;51705169 u32 tmp;51715170 bool have_2ghz_phy = false, have_5ghz_phy = false;···51835180 b43err(wl, "Bus powerup failed\n");51845181 goto out;51855182 }51835183+51845184+ phy->do_full_init = true;5186518551875186 /* Try to guess supported bands for the first init needs */51885187 switch (dev->dev->bus_type) {
+5
drivers/net/wireless/b43/phy_common.c
···98989999 phy->ops->switch_analog(dev, true);100100 b43_software_rfkill(dev, false);101101+101102 err = ops->init(dev);102103 if (err) {103104 b43err(dev->wl, "PHY init failed\n");104105 goto err_block_rf;105106 }107107+ phy->do_full_init = false;108108+106109 /* Make sure to switch hardware and firmware (SHM) to107110 * the default channel. */108111 err = b43_switch_channel(dev, ops->get_default_chan(dev));···117114 return 0;118115119116err_phy_exit:117117+ phy->do_full_init = true;120118 if (ops->exit)121119 ops->exit(dev);122120err_block_rf:···131127 const struct b43_phy_operations *ops = dev->phy.ops;132128133129 b43_software_rfkill(dev, true);130130+ dev->phy.do_full_init = true;134131 if (ops->exit)135132 ops->exit(dev);136133}
+3
drivers/net/wireless/b43/phy_common.h
···234234 /* Is GMODE (2 GHz mode) bit enabled? */235235 bool gmode;236236237237+ /* After power reset full init has to be performed */238238+ bool do_full_init;239239+237240 /* Analog Type */238241 u8 analog;239242 /* B43_PHYTYPE_ */
+6-11
drivers/net/wireless/b43/phy_n.c
···700700 b43_radio_mask(dev, R2057_RFPLL_MISC_CAL_RESETN, ~0x78);701701 b43_radio_mask(dev, R2057_XTAL_CONFIG2, ~0x80);702702703703- if (dev->phy.n->init_por) {703703+ if (dev->phy.do_full_init) {704704 b43_radio_2057_rcal(dev);705705 b43_radio_2057_rccal(dev);706706 }707707 b43_radio_mask(dev, R2057_RFPLL_MASTER, ~0x8);708708-709709- dev->phy.n->init_por = false;710708}711709712710/* http://bcm-v4.sipsolutions.net/802.11/Radio/2057/Init */···10261028 b43_radio_mask(dev, B2056_SYN_COM_RESET, ~0x2);10271029 b43_radio_mask(dev, B2056_SYN_PLL_MAST2, ~0xFC);10281030 b43_radio_mask(dev, B2056_SYN_RCCAL_CTRL0, ~0x1);10291029- if (dev->phy.n->init_por)10311031+ if (dev->phy.do_full_init)10301032 b43_radio_2056_rcal(dev);10311033}10321034···10391041 b43_radio_init2056_pre(dev);10401042 b2056_upload_inittabs(dev, 0, 0);10411043 b43_radio_init2056_post(dev);10421042-10431043- dev->phy.n->init_por = false;10441044}1045104510461046/**************************************************···55575561 nphy->hang_avoid = (phy->rev == 3 || phy->rev == 4);55585562 nphy->spur_avoid = (phy->rev >= 3) ?55595563 B43_SPUR_AVOID_AUTO : B43_SPUR_AVOID_DISABLE;55605560- nphy->init_por = true;55615564 nphy->gain_boost = true; /* this way we follow wl, assume it is true */55625565 nphy->txrx_chain = 2; /* sth different than 0 and 1 for now */55635566 nphy->phyrxchain = 3; /* to avoid b43_nphy_set_rx_core_state like wl */···55975602 nphy->ipa2g_on = sprom->fem.ghz2.extpa_gain == 2;55985603 nphy->ipa5g_on = sprom->fem.ghz5.extpa_gain == 2;55995604 }56005600-56015601- nphy->init_por = true;56025605}5603560656045607static void b43_nphy_op_free(struct b43_wldev *dev)···57075714 }57085715 } else {57095716 if (dev->phy.rev >= 7) {57105710- b43_radio_2057_init(dev);57175717+ if (!dev->phy.radio_on)57185718+ b43_radio_2057_init(dev);57115719 b43_switch_channel(dev, dev->phy.channel);57125720 } else if (dev->phy.rev >= 3) {57135713- b43_radio_init2056(dev);57215721+ if (!dev->phy.radio_on)57225722+ b43_radio_init2056(dev);57145723 b43_switch_channel(dev, dev->phy.channel);57155724 } else {57165725 b43_radio_init2055(dev);
···1313 * 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_H1616+#ifndef BRCMFMAC_FIRMWARE_H1717+#define BRCMFMAC_FIRMWARE_H18181919+#define BRCMF_FW_REQUEST 0x000F2020+#define BRCMF_FW_REQUEST_NVRAM 0x00012121+#define BRCMF_FW_REQ_FLAGS 0x00F02222+#define BRCMF_FW_REQ_NV_OPTIONAL 0x001019232020-void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length);2121-void brcmf_nvram_free(void *nvram);2424+void brcmf_fw_nvram_free(void *nvram);2525+/*2626+ * Request firmware(s) asynchronously. When the asynchronous request2727+ * fails it will not use the callback, but call device_release_driver()2828+ * instead which will call the driver .remove() callback.2929+ */3030+int brcmf_fw_get_firmwares(struct device *dev, u16 flags,3131+ const char *code, const char *nvram,3232+ void (*fw_cb)(struct device *dev,3333+ const struct firmware *fw,3434+ void *nvram_image, u32 nvram_len));22352323-2424-#endif /* BRCMFMAC_NVRAM_H */3636+#endif /* BRCMFMAC_FIRMWARE_H */
+85-184
drivers/net/wireless/brcm80211/brcmfmac/usb.c
···2525#include <dhd_bus.h>2626#include <dhd_dbg.h>27272828+#include "firmware.h"2829#include "usb_rdl.h"2930#include "usb.h"3031···6261 u8 *image;6362 int image_len;6463};6565-static struct list_head fw_image_list;6666-6767-struct intr_transfer_buf {6868- u32 notification;6969- u32 reserved;7070-};71647265struct brcmf_usbdev_info {7366 struct brcmf_usbdev bus_pub; /* MUST BE FIRST */···7075 struct list_head rx_postq;7176 struct list_head tx_freeq;7277 struct list_head tx_postq;7373- uint rx_pipe, tx_pipe, intr_pipe, rx_pipe2;7878+ uint rx_pipe, tx_pipe, rx_pipe2;74797580 int rx_low_watermark;7681 int tx_low_watermark;···8287 struct brcmf_usbreq *tx_reqs;8388 struct brcmf_usbreq *rx_reqs;84898585- u8 *image; /* buffer for combine fw and nvram */9090+ const u8 *image; /* buffer for combine fw and nvram */8691 int image_len;87928893 struct usb_device *usbdev;···99104 ulong ctl_op;100105101106 struct urb *bulk_urb; /* used for FW download */102102- struct urb *intr_urb; /* URB for interrupt endpoint */103103- int intr_size; /* Size of interrupt message */104104- int interval; /* Interrupt polling interval */105105- struct intr_transfer_buf intr; /* Data buffer for interrupt endpoint */106107};107108108109static void brcmf_usb_rx_refill(struct brcmf_usbdev_info *devinfo,···522531 }523532}524533525525-static void526526-brcmf_usb_intr_complete(struct urb *urb)527527-{528528- struct brcmf_usbdev_info *devinfo =529529- (struct brcmf_usbdev_info *)urb->context;530530- int err;531531-532532- brcmf_dbg(USB, "Enter, urb->status=%d\n", urb->status);533533-534534- if (devinfo == NULL)535535- return;536536-537537- if (unlikely(urb->status)) {538538- if (urb->status == -ENOENT ||539539- urb->status == -ESHUTDOWN ||540540- urb->status == -ENODEV) {541541- brcmf_usb_state_change(devinfo,542542- BRCMFMAC_USB_STATE_DOWN);543543- }544544- }545545-546546- if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_DOWN) {547547- brcmf_err("intr cb when DBUS down, ignoring\n");548548- return;549549- }550550-551551- if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP) {552552- err = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);553553- if (err)554554- brcmf_err("usb_submit_urb, err=%d\n", err);555555- }556556-}557557-558534static int brcmf_usb_tx(struct device *dev, struct sk_buff *skb)559535{560536 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);···577619{578620 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(dev);579621 u16 ifnum;580580- int ret;581622582623 brcmf_dbg(USB, "Enter\n");583624 if (devinfo->bus_pub.state == BRCMFMAC_USB_STATE_UP)···584627585628 /* Success, indicate devinfo is fully up */586629 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_UP);587587-588588- if (devinfo->intr_urb) {589589- usb_fill_int_urb(devinfo->intr_urb, devinfo->usbdev,590590- devinfo->intr_pipe,591591- &devinfo->intr,592592- devinfo->intr_size,593593- (usb_complete_t)brcmf_usb_intr_complete,594594- devinfo,595595- devinfo->interval);596596-597597- ret = usb_submit_urb(devinfo->intr_urb, GFP_ATOMIC);598598- if (ret) {599599- brcmf_err("USB_SUBMIT_URB failed with status %d\n",600600- ret);601601- return -EINVAL;602602- }603603- }604630605631 if (devinfo->ctl_urb) {606632 devinfo->ctl_in_pipe = usb_rcvctrlpipe(devinfo->usbdev, 0);···621681 return;622682623683 brcmf_usb_state_change(devinfo, BRCMFMAC_USB_STATE_DOWN);624624- if (devinfo->intr_urb)625625- usb_kill_urb(devinfo->intr_urb);626684627685 if (devinfo->ctl_urb)628686 usb_kill_urb(devinfo->ctl_urb);···9591021 }96010229611023 err = brcmf_usb_dlstart(devinfo,962962- devinfo->image, devinfo->image_len);10241024+ (u8 *)devinfo->image, devinfo->image_len);9631025 if (err == 0)9641026 err = brcmf_usb_dlrun(devinfo);9651027 return err;···9741036 brcmf_usb_free_q(&devinfo->rx_freeq, false);9751037 brcmf_usb_free_q(&devinfo->tx_freeq, false);9761038977977- usb_free_urb(devinfo->intr_urb);9781039 usb_free_urb(devinfo->ctl_urb);9791040 usb_free_urb(devinfo->bulk_urb);9801041···10171080 return -1;10181081}1019108210201020-static int brcmf_usb_get_fw(struct brcmf_usbdev_info *devinfo)10831083+static const char *brcmf_usb_get_fwname(struct brcmf_usbdev_info *devinfo)10211084{10221022- s8 *fwname;10231023- const struct firmware *fw;10241024- struct brcmf_usb_image *fw_image;10251025- int err;10261026-10271027- brcmf_dbg(USB, "Enter\n");10281085 switch (devinfo->bus_pub.devid) {10291086 case 43143:10301030- fwname = BRCMF_USB_43143_FW_NAME;10311031- break;10871087+ return BRCMF_USB_43143_FW_NAME;10321088 case 43235:10331089 case 43236:10341090 case 43238:10351035- fwname = BRCMF_USB_43236_FW_NAME;10361036- break;10911091+ return BRCMF_USB_43236_FW_NAME;10371092 case 43242:10381038- fwname = BRCMF_USB_43242_FW_NAME;10391039- break;10931093+ return BRCMF_USB_43242_FW_NAME;10401094 default:10411041- return -EINVAL;10421042- break;10951095+ return NULL;10431096 }10441044- brcmf_dbg(USB, "Loading FW %s\n", fwname);10451045- list_for_each_entry(fw_image, &fw_image_list, list) {10461046- if (fw_image->fwname == fwname) {10471047- devinfo->image = fw_image->image;10481048- devinfo->image_len = fw_image->image_len;10491049- return 0;10501050- }10511051- }10521052- /* fw image not yet loaded. Load it now and add to list */10531053- err = request_firmware(&fw, fwname, devinfo->dev);10541054- if (!fw) {10551055- brcmf_err("fail to request firmware %s\n", fwname);10561056- return err;10571057- }10581058- if (check_file(fw->data) < 0) {10591059- brcmf_err("invalid firmware %s\n", fwname);10601060- return -EINVAL;10611061- }10621062-10631063- fw_image = kzalloc(sizeof(*fw_image), GFP_ATOMIC);10641064- if (!fw_image)10651065- return -ENOMEM;10661066- INIT_LIST_HEAD(&fw_image->list);10671067- list_add_tail(&fw_image->list, &fw_image_list);10681068- fw_image->fwname = fwname;10691069- fw_image->image = vmalloc(fw->size);10701070- if (!fw_image->image)10711071- return -ENOMEM;10721072-10731073- memcpy(fw_image->image, fw->data, fw->size);10741074- fw_image->image_len = fw->size;10751075-10761076- release_firmware(fw);10771077-10781078- devinfo->image = fw_image->image;10791079- devinfo->image_len = fw_image->image_len;10801080-10811081- return 0;10821097}1083109810841099···10751186 goto error;10761187 devinfo->tx_freecount = ntxq;1077118810781078- devinfo->intr_urb = usb_alloc_urb(0, GFP_ATOMIC);10791079- if (!devinfo->intr_urb) {10801080- brcmf_err("usb_alloc_urb (intr) failed\n");10811081- goto error;10821082- }10831189 devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);10841190 if (!devinfo->ctl_urb) {10851191 brcmf_err("usb_alloc_urb (ctl) failed\n");···10861202 goto error;10871203 }1088120410891089- if (!brcmf_usb_dlneeded(devinfo))10901090- return &devinfo->bus_pub;10911091-10921092- brcmf_dbg(USB, "Start fw downloading\n");10931093- if (brcmf_usb_get_fw(devinfo))10941094- goto error;10951095-10961096- if (brcmf_usb_fw_download(devinfo))10971097- goto error;10981098-10991205 return &devinfo->bus_pub;1100120611011207error:···1096122210971223static struct brcmf_bus_ops brcmf_usb_bus_ops = {10981224 .txdata = brcmf_usb_tx,10991099- .init = brcmf_usb_up,11001225 .stop = brcmf_usb_down,11011226 .txctl = brcmf_usb_tx_ctlpkt,11021227 .rxctl = brcmf_usb_rx_ctlpkt,11031228};1104122912301230+static int brcmf_usb_bus_setup(struct brcmf_usbdev_info *devinfo)12311231+{12321232+ int ret;12331233+12341234+ /* Attach to the common driver interface */12351235+ ret = brcmf_attach(devinfo->dev);12361236+ if (ret) {12371237+ brcmf_err("brcmf_attach failed\n");12381238+ return ret;12391239+ }12401240+12411241+ ret = brcmf_usb_up(devinfo->dev);12421242+ if (ret)12431243+ goto fail;12441244+12451245+ ret = brcmf_bus_start(devinfo->dev);12461246+ if (ret)12471247+ goto fail;12481248+12491249+ return 0;12501250+fail:12511251+ brcmf_detach(devinfo->dev);12521252+ return ret;12531253+}12541254+12551255+static void brcmf_usb_probe_phase2(struct device *dev,12561256+ const struct firmware *fw,12571257+ void *nvram, u32 nvlen)12581258+{12591259+ struct brcmf_bus *bus = dev_get_drvdata(dev);12601260+ struct brcmf_usbdev_info *devinfo;12611261+ int ret;12621262+12631263+ brcmf_dbg(USB, "Start fw downloading\n");12641264+ ret = check_file(fw->data);12651265+ if (ret < 0) {12661266+ brcmf_err("invalid firmware\n");12671267+ release_firmware(fw);12681268+ goto error;12691269+ }12701270+12711271+ devinfo = bus->bus_priv.usb->devinfo;12721272+ devinfo->image = fw->data;12731273+ devinfo->image_len = fw->size;12741274+12751275+ ret = brcmf_usb_fw_download(devinfo);12761276+ release_firmware(fw);12771277+ if (ret)12781278+ goto error;12791279+12801280+ ret = brcmf_usb_bus_setup(devinfo);12811281+ if (ret)12821282+ goto error;12831283+12841284+ return;12851285+error:12861286+ brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);12871287+ device_release_driver(dev);12881288+}12891289+11051290static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)11061291{11071292 struct brcmf_bus *bus = NULL;11081293 struct brcmf_usbdev *bus_pub = NULL;11091109- int ret;11101294 struct device *dev = devinfo->dev;12951295+ int ret;1111129611121297 brcmf_dbg(USB, "Enter\n");11131298 bus_pub = brcmf_usb_attach(devinfo, BRCMF_USB_NRXQ, BRCMF_USB_NTXQ);···11891256 bus->proto_type = BRCMF_PROTO_BCDC;11901257 bus->always_use_fws_queue = true;1191125811921192- /* Attach to the common driver interface */11931193- ret = brcmf_attach(dev);11941194- if (ret) {11951195- brcmf_err("brcmf_attach failed\n");11961196- goto fail;12591259+ if (!brcmf_usb_dlneeded(devinfo)) {12601260+ ret = brcmf_usb_bus_setup(devinfo);12611261+ if (ret)12621262+ goto fail;11971263 }11981198-11991199- ret = brcmf_bus_start(dev);12001200- if (ret) {12011201- brcmf_err("dongle is not responding\n");12021202- brcmf_detach(dev);12031203- goto fail;12041204- }12051205-12641264+ /* request firmware here */12651265+ brcmf_fw_get_firmwares(dev, 0, brcmf_usb_get_fwname(devinfo), NULL,12661266+ brcmf_usb_probe_phase2);12061267 return 0;12681268+12071269fail:12081270 /* Release resources in reverse order */12091271 kfree(bus);···12861358 goto fail;12871359 }1288136012891289- endpoint_num = endpoint->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;12901290- devinfo->intr_pipe = usb_rcvintpipe(usb, endpoint_num);12911291-12921361 devinfo->rx_pipe = 0;12931362 devinfo->rx_pipe2 = 0;12941363 devinfo->tx_pipe = 0;···13171392 }13181393 }1319139413201320- /* Allocate interrupt URB and data buffer */13211321- /* RNDIS says 8-byte intr, our old drivers used 4-byte */13221322- if (IFEPDESC(usb, CONTROL_IF, 0).wMaxPacketSize == cpu_to_le16(16))13231323- devinfo->intr_size = 8;13241324- else13251325- devinfo->intr_size = 4;13261326-13271327- devinfo->interval = IFEPDESC(usb, CONTROL_IF, 0).bInterval;13281328-13291329- if (usb->speed == USB_SPEED_HIGH)13951395+ if (usb->speed == USB_SPEED_SUPER)13961396+ brcmf_dbg(USB, "Broadcom super speed USB wireless device detected\n");13971397+ else if (usb->speed == USB_SPEED_HIGH)13301398 brcmf_dbg(USB, "Broadcom high speed USB wireless device detected\n");13311399 else13321400 brcmf_dbg(USB, "Broadcom full speed USB wireless device detected\n");···13741456 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);1375145713761458 brcmf_dbg(USB, "Enter\n");13771377- if (!brcmf_attach(devinfo->dev))13781378- return brcmf_bus_start(&usb->dev);13791379-13801380- return 0;14591459+ return brcmf_usb_bus_setup(devinfo);13811460}1382146113831462static int brcmf_usb_reset_resume(struct usb_interface *intf)13841463{13851464 struct usb_device *usb = interface_to_usbdev(intf);13861465 struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev);13871387-13881466 brcmf_dbg(USB, "Enter\n");1389146713901390- if (!brcmf_usb_fw_download(devinfo))13911391- return brcmf_usb_resume(intf);13921392-13931393- return -EIO;14681468+ return brcmf_fw_get_firmwares(&usb->dev, 0,14691469+ brcmf_usb_get_fwname(devinfo), NULL,14701470+ brcmf_usb_probe_phase2);13941471}1395147213961473#define BRCMF_USB_VENDOR_ID_BROADCOM 0x0a5c···14201507 .disable_hub_initiated_lpm = 1,14211508};1422150914231423-static void brcmf_release_fw(struct list_head *q)14241424-{14251425- struct brcmf_usb_image *fw_image, *next;14261426-14271427- list_for_each_entry_safe(fw_image, next, q, list) {14281428- vfree(fw_image->image);14291429- list_del_init(&fw_image->list);14301430- }14311431-}14321432-14331510static int brcmf_usb_reset_device(struct device *dev, void *notused)14341511{14351512 /* device past is the usb interface so we···14381535 ret = driver_for_each_device(drv, NULL, NULL,14391536 brcmf_usb_reset_device);14401537 usb_deregister(&brcmf_usbdrvr);14411441- brcmf_release_fw(&fw_image_list);14421538}1443153914441540void brcmf_usb_register(void)14451541{14461542 brcmf_dbg(USB, "Enter\n");14471447- INIT_LIST_HEAD(&fw_image_list);14481543 usb_register(&brcmf_usbdrvr);14491544}
···189189};190190191191/**192192+ * enum ieee80211_chanctx_switch_mode - channel context switch mode193193+ * @CHANCTX_SWMODE_REASSIGN_VIF: Both old and new contexts already194194+ * exist (and will continue to exist), but the virtual interface195195+ * needs to be switched from one to the other.196196+ * @CHANCTX_SWMODE_SWAP_CONTEXTS: The old context exists but will stop197197+ * to exist with this call, the new context doesn't exist but198198+ * will be active after this call, the virtual interface switches199199+ * from the old to the new (note that the driver may of course200200+ * implement this as an on-the-fly chandef switch of the existing201201+ * hardware context, but the mac80211 pointer for the old context202202+ * will cease to exist and only the new one will later be used203203+ * for changes/removal.)204204+ */205205+enum ieee80211_chanctx_switch_mode {206206+ CHANCTX_SWMODE_REASSIGN_VIF,207207+ CHANCTX_SWMODE_SWAP_CONTEXTS,208208+};209209+210210+/**211211+ * struct ieee80211_vif_chanctx_switch - vif chanctx switch information212212+ *213213+ * This is structure is used to pass information about a vif that214214+ * needs to switch from one chanctx to another. The215215+ * &ieee80211_chanctx_switch_mode defines how the switch should be216216+ * done.217217+ *218218+ * @vif: the vif that should be switched from old_ctx to new_ctx219219+ * @old_ctx: the old context to which the vif was assigned220220+ * @new_ctx: the new context to which the vif must be assigned221221+ */222222+struct ieee80211_vif_chanctx_switch {223223+ struct ieee80211_vif *vif;224224+ struct ieee80211_chanctx_conf *old_ctx;225225+ struct ieee80211_chanctx_conf *new_ctx;226226+};227227+228228+/**192229 * enum ieee80211_bss_change - BSS change notification flags193230 *194231 * These flags are used with the bss_info_changed() callback···27732736 * to vif. Possible use is for hw queue remapping.27742737 * @unassign_vif_chanctx: Notifies device driver about channel context being27752738 * unbound from vif.27392739+ * @switch_vif_chanctx: switch a number of vifs from one chanctx to27402740+ * another, as specified in the list of27412741+ * @ieee80211_vif_chanctx_switch passed to the driver, according27422742+ * to the mode defined in &ieee80211_chanctx_switch_mode.27432743+ *27762744 * @start_ap: Start operation on the AP interface, this is called after all the27772745 * information in bss_conf is set and beacon can be retrieved. A channel27782746 * context is bound before this is called. Note that if the driver uses···29942952 void (*unassign_vif_chanctx)(struct ieee80211_hw *hw,29952953 struct ieee80211_vif *vif,29962954 struct ieee80211_chanctx_conf *ctx);29552955+ int (*switch_vif_chanctx)(struct ieee80211_hw *hw,29562956+ struct ieee80211_vif_chanctx_switch *vifs,29572957+ int n_vifs,29582958+ enum ieee80211_chanctx_switch_mode mode);2997295929982960 void (*restart_complete)(struct ieee80211_hw *hw);29992961