Loading drivers/net/wireless/ath/ath10k/bmi.h +2 −1 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, \ addr = host_interest_item_address(HI_ITEM(item)); \ ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ if (!ret) \ *val = __le32_to_cpu(tmp); \ ret; \ }) Loading drivers/net/wireless/ath/ath10k/ce.c +27 −0 Original line number Diff line number Diff line Loading @@ -329,6 +329,33 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, return ret; } void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *src_ring = pipe->src_ring; u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); /* * This function must be called only if there is an incomplete * scatter-gather transfer (before index register is updated) * that needs to be cleaned up. */ if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index)) return; if (WARN_ON_ONCE(src_ring->write_index == ath10k_ce_src_ring_write_index_get(ar, ctrl_addr))) return; src_ring->write_index--; src_ring->write_index &= src_ring->nentries_mask; src_ring->per_transfer_context[src_ring->write_index] = NULL; } int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_context, u32 buffer, Loading drivers/net/wireless/ath/ath10k/ce.h +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, unsigned int transfer_id, unsigned int flags); void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts); Loading drivers/net/wireless/ath/ath10k/core.c +154 −123 Original line number Diff line number Diff line Loading @@ -58,36 +58,6 @@ static void ath10k_send_suspend_complete(struct ath10k *ar) complete(&ar->target_suspend); } static int ath10k_init_connect_htc(struct ath10k *ar) { int status; status = ath10k_wmi_connect_htc_service(ar); if (status) goto conn_fail; /* Start HTC */ status = ath10k_htc_start(&ar->htc); if (status) goto conn_fail; /* Wait for WMI event to be ready */ status = ath10k_wmi_wait_for_service_ready(ar); if (status <= 0) { ath10k_warn("wmi service ready event not received"); status = -ETIMEDOUT; goto timeout; } ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); return 0; timeout: ath10k_htc_stop(&ar->htc); conn_fail: return status; } static int ath10k_init_configure_target(struct ath10k *ar) { u32 param_host; Loading Loading @@ -681,7 +651,8 @@ static void ath10k_core_restart(struct work_struct *work) switch (ar->state) { case ATH10K_STATE_ON: ar->state = ATH10K_STATE_RESTARTING; ath10k_halt(ar); del_timer_sync(&ar->scan.timeout); ath10k_reset_scan((unsigned long)ar); ieee80211_restart_hw(ar->hw); break; case ATH10K_STATE_OFF: Loading @@ -690,6 +661,8 @@ static void ath10k_core_restart(struct work_struct *work) ath10k_warn("cannot restart a device that hasn't been started\n"); break; case ATH10K_STATE_RESTARTING: /* hw restart might be requested from multiple places */ break; case ATH10K_STATE_RESTARTED: ar->state = ATH10K_STATE_WEDGED; /* fall through */ Loading @@ -701,70 +674,6 @@ static void ath10k_core_restart(struct work_struct *work) mutex_unlock(&ar->conf_mutex); } struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; ar = ath10k_mac_create(); if (!ar) return NULL; ar->ath_common.priv = ar; ar->ath_common.hw = ar->hw; ar->p2p = !!ath10k_p2p; ar->dev = dev; ar->hif.priv = hif_priv; ar->hif.ops = hif_ops; init_completion(&ar->scan.started); init_completion(&ar->scan.completed); init_completion(&ar->scan.on_channel); init_completion(&ar->target_suspend); init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); ar->workqueue = create_singlethread_workqueue("ath10k_wq"); if (!ar->workqueue) goto err_wq; mutex_init(&ar->conf_mutex); spin_lock_init(&ar->data_lock); INIT_LIST_HEAD(&ar->peers); init_waitqueue_head(&ar->peer_mapping_wq); init_completion(&ar->offchan_tx_completed); INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); skb_queue_head_init(&ar->offchan_tx_queue); INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); INIT_WORK(&ar->restart_work, ath10k_core_restart); return ar; err_wq: ath10k_mac_destroy(ar); return NULL; } EXPORT_SYMBOL(ath10k_core_create); void ath10k_core_destroy(struct ath10k *ar) { flush_workqueue(ar->workqueue); destroy_workqueue(ar->workqueue); ath10k_mac_destroy(ar); } EXPORT_SYMBOL(ath10k_core_destroy); int ath10k_core_start(struct ath10k *ar) { int status; Loading Loading @@ -805,10 +714,28 @@ int ath10k_core_start(struct ath10k *ar) goto err; } status = ath10k_htt_init(ar); if (status) { ath10k_err("failed to init htt: %d\n", status); goto err_wmi_detach; } status = ath10k_htt_tx_alloc(&ar->htt); if (status) { ath10k_err("failed to alloc htt tx: %d\n", status); goto err_wmi_detach; } status = ath10k_htt_rx_alloc(&ar->htt); if (status) { ath10k_err("failed to alloc htt rx: %d\n", status); goto err_htt_tx_detach; } status = ath10k_hif_start(ar); if (status) { ath10k_err("could not start HIF: %d\n", status); goto err_wmi_detach; goto err_htt_rx_detach; } status = ath10k_htc_wait_target(&ar->htc); Loading @@ -817,15 +744,30 @@ int ath10k_core_start(struct ath10k *ar) goto err_hif_stop; } status = ath10k_htt_attach(ar); status = ath10k_htt_connect(&ar->htt); if (status) { ath10k_err("could not attach htt (%d)\n", status); ath10k_err("failed to connect htt (%d)\n", status); goto err_hif_stop; } status = ath10k_init_connect_htc(ar); if (status) goto err_htt_detach; status = ath10k_wmi_connect(ar); if (status) { ath10k_err("could not connect wmi: %d\n", status); goto err_hif_stop; } status = ath10k_htc_start(&ar->htc); if (status) { ath10k_err("failed to start htc: %d\n", status); goto err_hif_stop; } status = ath10k_wmi_wait_for_service_ready(ar); if (status <= 0) { ath10k_warn("wmi service ready event not received"); status = -ETIMEDOUT; goto err_htc_stop; } ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", ar->hw->wiphy->fw_version); Loading @@ -833,23 +775,25 @@ int ath10k_core_start(struct ath10k *ar) status = ath10k_wmi_cmd_init(ar); if (status) { ath10k_err("could not send WMI init command (%d)\n", status); goto err_disconnect_htc; goto err_htc_stop; } status = ath10k_wmi_wait_for_unified_ready(ar); if (status <= 0) { ath10k_err("wmi unified ready event not received\n"); status = -ETIMEDOUT; goto err_disconnect_htc; goto err_htc_stop; } status = ath10k_htt_attach_target(&ar->htt); if (status) goto err_disconnect_htc; status = ath10k_htt_setup(&ar->htt); if (status) { ath10k_err("failed to setup htt: %d\n", status); goto err_htc_stop; } status = ath10k_debug_start(ar); if (status) goto err_disconnect_htc; goto err_htc_stop; ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; INIT_LIST_HEAD(&ar->arvifs); Loading @@ -868,12 +812,14 @@ int ath10k_core_start(struct ath10k *ar) return 0; err_disconnect_htc: err_htc_stop: ath10k_htc_stop(&ar->htc); err_htt_detach: ath10k_htt_detach(&ar->htt); err_hif_stop: ath10k_hif_stop(ar); err_htt_rx_detach: ath10k_htt_rx_free(&ar->htt); err_htt_tx_detach: ath10k_htt_tx_free(&ar->htt); err_wmi_detach: ath10k_wmi_detach(ar); err: Loading Loading @@ -913,7 +859,9 @@ void ath10k_core_stop(struct ath10k *ar) ath10k_debug_stop(ar); ath10k_htc_stop(&ar->htc); ath10k_htt_detach(&ar->htt); ath10k_hif_stop(ar); ath10k_htt_tx_free(&ar->htt); ath10k_htt_rx_free(&ar->htt); ath10k_wmi_detach(ar); } EXPORT_SYMBOL(ath10k_core_stop); Loading Loading @@ -1005,22 +953,15 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) return 0; } int ath10k_core_register(struct ath10k *ar, u32 chip_id) static void ath10k_core_register_work(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, register_work); int status; ar->chip_id = chip_id; status = ath10k_core_check_chip_id(ar); if (status) { ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); return status; } status = ath10k_core_probe_fw(ar); if (status) { ath10k_err("could not probe fw (%d)\n", status); return status; goto err; } status = ath10k_mac_register(ar); Loading @@ -1035,18 +976,43 @@ int ath10k_core_register(struct ath10k *ar, u32 chip_id) goto err_unregister_mac; } return 0; set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); return; err_unregister_mac: ath10k_mac_unregister(ar); err_release_fw: ath10k_core_free_firmware_files(ar); err: device_release_driver(ar->dev); return; } int ath10k_core_register(struct ath10k *ar, u32 chip_id) { int status; ar->chip_id = chip_id; status = ath10k_core_check_chip_id(ar); if (status) { ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); return status; } queue_work(ar->workqueue, &ar->register_work); return 0; } EXPORT_SYMBOL(ath10k_core_register); void ath10k_core_unregister(struct ath10k *ar) { cancel_work_sync(&ar->register_work); if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; /* We must unregister from mac80211 before we stop HTC and HIF. * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ Loading @@ -1058,6 +1024,71 @@ void ath10k_core_unregister(struct ath10k *ar) } EXPORT_SYMBOL(ath10k_core_unregister); struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; ar = ath10k_mac_create(); if (!ar) return NULL; ar->ath_common.priv = ar; ar->ath_common.hw = ar->hw; ar->p2p = !!ath10k_p2p; ar->dev = dev; ar->hif.priv = hif_priv; ar->hif.ops = hif_ops; init_completion(&ar->scan.started); init_completion(&ar->scan.completed); init_completion(&ar->scan.on_channel); init_completion(&ar->target_suspend); init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); ar->workqueue = create_singlethread_workqueue("ath10k_wq"); if (!ar->workqueue) goto err_wq; mutex_init(&ar->conf_mutex); spin_lock_init(&ar->data_lock); INIT_LIST_HEAD(&ar->peers); init_waitqueue_head(&ar->peer_mapping_wq); init_completion(&ar->offchan_tx_completed); INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); skb_queue_head_init(&ar->offchan_tx_queue); INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); INIT_WORK(&ar->register_work, ath10k_core_register_work); INIT_WORK(&ar->restart_work, ath10k_core_restart); return ar; err_wq: ath10k_mac_destroy(ar); return NULL; } EXPORT_SYMBOL(ath10k_core_create); void ath10k_core_destroy(struct ath10k *ar) { flush_workqueue(ar->workqueue); destroy_workqueue(ar->workqueue); ath10k_mac_destroy(ar); } EXPORT_SYMBOL(ath10k_core_destroy); MODULE_AUTHOR("Qualcomm Atheros"); MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); MODULE_LICENSE("Dual BSD/GPL"); drivers/net/wireless/ath/ath10k/core.h +8 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,7 @@ enum ath10k_dev_flags { /* Indicates that ath10k device is during CAC phase of DFS */ ATH10K_CAC_RUNNING, ATH10K_FLAG_FIRST_BOOT_DONE, ATH10K_FLAG_CORE_REGISTERED, }; struct ath10k { Loading Loading @@ -440,6 +441,12 @@ struct ath10k { bool radar_enabled; int num_started_vdevs; /* Protected by conf-mutex */ u8 supp_tx_chainmask; u8 supp_rx_chainmask; u8 cfg_tx_chainmask; u8 cfg_rx_chainmask; struct wmi_pdev_set_wmm_params_arg wmm_params; struct completion install_key_done; Loading Loading @@ -470,6 +477,7 @@ struct ath10k { enum ath10k_state state; struct work_struct register_work; struct work_struct restart_work; /* cycle count is reported twice for each visited channel during scan. Loading Loading
drivers/net/wireless/ath/ath10k/bmi.h +2 −1 Original line number Diff line number Diff line Loading @@ -201,6 +201,7 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 address, \ addr = host_interest_item_address(HI_ITEM(item)); \ ret = ath10k_bmi_read_memory(ar, addr, (u8 *)&tmp, 4); \ if (!ret) \ *val = __le32_to_cpu(tmp); \ ret; \ }) Loading
drivers/net/wireless/ath/ath10k/ce.c +27 −0 Original line number Diff line number Diff line Loading @@ -329,6 +329,33 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, return ret; } void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe) { struct ath10k *ar = pipe->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_ring *src_ring = pipe->src_ring; u32 ctrl_addr = pipe->ctrl_addr; lockdep_assert_held(&ar_pci->ce_lock); /* * This function must be called only if there is an incomplete * scatter-gather transfer (before index register is updated) * that needs to be cleaned up. */ if (WARN_ON_ONCE(src_ring->write_index == src_ring->sw_index)) return; if (WARN_ON_ONCE(src_ring->write_index == ath10k_ce_src_ring_write_index_get(ar, ctrl_addr))) return; src_ring->write_index--; src_ring->write_index &= src_ring->nentries_mask; src_ring->per_transfer_context[src_ring->write_index] = NULL; } int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_context, u32 buffer, Loading
drivers/net/wireless/ath/ath10k/ce.h +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,8 @@ int ath10k_ce_send_nolock(struct ath10k_ce_pipe *ce_state, unsigned int transfer_id, unsigned int flags); void __ath10k_ce_send_revert(struct ath10k_ce_pipe *pipe); void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts); Loading
drivers/net/wireless/ath/ath10k/core.c +154 −123 Original line number Diff line number Diff line Loading @@ -58,36 +58,6 @@ static void ath10k_send_suspend_complete(struct ath10k *ar) complete(&ar->target_suspend); } static int ath10k_init_connect_htc(struct ath10k *ar) { int status; status = ath10k_wmi_connect_htc_service(ar); if (status) goto conn_fail; /* Start HTC */ status = ath10k_htc_start(&ar->htc); if (status) goto conn_fail; /* Wait for WMI event to be ready */ status = ath10k_wmi_wait_for_service_ready(ar); if (status <= 0) { ath10k_warn("wmi service ready event not received"); status = -ETIMEDOUT; goto timeout; } ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); return 0; timeout: ath10k_htc_stop(&ar->htc); conn_fail: return status; } static int ath10k_init_configure_target(struct ath10k *ar) { u32 param_host; Loading Loading @@ -681,7 +651,8 @@ static void ath10k_core_restart(struct work_struct *work) switch (ar->state) { case ATH10K_STATE_ON: ar->state = ATH10K_STATE_RESTARTING; ath10k_halt(ar); del_timer_sync(&ar->scan.timeout); ath10k_reset_scan((unsigned long)ar); ieee80211_restart_hw(ar->hw); break; case ATH10K_STATE_OFF: Loading @@ -690,6 +661,8 @@ static void ath10k_core_restart(struct work_struct *work) ath10k_warn("cannot restart a device that hasn't been started\n"); break; case ATH10K_STATE_RESTARTING: /* hw restart might be requested from multiple places */ break; case ATH10K_STATE_RESTARTED: ar->state = ATH10K_STATE_WEDGED; /* fall through */ Loading @@ -701,70 +674,6 @@ static void ath10k_core_restart(struct work_struct *work) mutex_unlock(&ar->conf_mutex); } struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; ar = ath10k_mac_create(); if (!ar) return NULL; ar->ath_common.priv = ar; ar->ath_common.hw = ar->hw; ar->p2p = !!ath10k_p2p; ar->dev = dev; ar->hif.priv = hif_priv; ar->hif.ops = hif_ops; init_completion(&ar->scan.started); init_completion(&ar->scan.completed); init_completion(&ar->scan.on_channel); init_completion(&ar->target_suspend); init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); ar->workqueue = create_singlethread_workqueue("ath10k_wq"); if (!ar->workqueue) goto err_wq; mutex_init(&ar->conf_mutex); spin_lock_init(&ar->data_lock); INIT_LIST_HEAD(&ar->peers); init_waitqueue_head(&ar->peer_mapping_wq); init_completion(&ar->offchan_tx_completed); INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); skb_queue_head_init(&ar->offchan_tx_queue); INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); INIT_WORK(&ar->restart_work, ath10k_core_restart); return ar; err_wq: ath10k_mac_destroy(ar); return NULL; } EXPORT_SYMBOL(ath10k_core_create); void ath10k_core_destroy(struct ath10k *ar) { flush_workqueue(ar->workqueue); destroy_workqueue(ar->workqueue); ath10k_mac_destroy(ar); } EXPORT_SYMBOL(ath10k_core_destroy); int ath10k_core_start(struct ath10k *ar) { int status; Loading Loading @@ -805,10 +714,28 @@ int ath10k_core_start(struct ath10k *ar) goto err; } status = ath10k_htt_init(ar); if (status) { ath10k_err("failed to init htt: %d\n", status); goto err_wmi_detach; } status = ath10k_htt_tx_alloc(&ar->htt); if (status) { ath10k_err("failed to alloc htt tx: %d\n", status); goto err_wmi_detach; } status = ath10k_htt_rx_alloc(&ar->htt); if (status) { ath10k_err("failed to alloc htt rx: %d\n", status); goto err_htt_tx_detach; } status = ath10k_hif_start(ar); if (status) { ath10k_err("could not start HIF: %d\n", status); goto err_wmi_detach; goto err_htt_rx_detach; } status = ath10k_htc_wait_target(&ar->htc); Loading @@ -817,15 +744,30 @@ int ath10k_core_start(struct ath10k *ar) goto err_hif_stop; } status = ath10k_htt_attach(ar); status = ath10k_htt_connect(&ar->htt); if (status) { ath10k_err("could not attach htt (%d)\n", status); ath10k_err("failed to connect htt (%d)\n", status); goto err_hif_stop; } status = ath10k_init_connect_htc(ar); if (status) goto err_htt_detach; status = ath10k_wmi_connect(ar); if (status) { ath10k_err("could not connect wmi: %d\n", status); goto err_hif_stop; } status = ath10k_htc_start(&ar->htc); if (status) { ath10k_err("failed to start htc: %d\n", status); goto err_hif_stop; } status = ath10k_wmi_wait_for_service_ready(ar); if (status <= 0) { ath10k_warn("wmi service ready event not received"); status = -ETIMEDOUT; goto err_htc_stop; } ath10k_dbg(ATH10K_DBG_BOOT, "firmware %s booted\n", ar->hw->wiphy->fw_version); Loading @@ -833,23 +775,25 @@ int ath10k_core_start(struct ath10k *ar) status = ath10k_wmi_cmd_init(ar); if (status) { ath10k_err("could not send WMI init command (%d)\n", status); goto err_disconnect_htc; goto err_htc_stop; } status = ath10k_wmi_wait_for_unified_ready(ar); if (status <= 0) { ath10k_err("wmi unified ready event not received\n"); status = -ETIMEDOUT; goto err_disconnect_htc; goto err_htc_stop; } status = ath10k_htt_attach_target(&ar->htt); if (status) goto err_disconnect_htc; status = ath10k_htt_setup(&ar->htt); if (status) { ath10k_err("failed to setup htt: %d\n", status); goto err_htc_stop; } status = ath10k_debug_start(ar); if (status) goto err_disconnect_htc; goto err_htc_stop; ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; INIT_LIST_HEAD(&ar->arvifs); Loading @@ -868,12 +812,14 @@ int ath10k_core_start(struct ath10k *ar) return 0; err_disconnect_htc: err_htc_stop: ath10k_htc_stop(&ar->htc); err_htt_detach: ath10k_htt_detach(&ar->htt); err_hif_stop: ath10k_hif_stop(ar); err_htt_rx_detach: ath10k_htt_rx_free(&ar->htt); err_htt_tx_detach: ath10k_htt_tx_free(&ar->htt); err_wmi_detach: ath10k_wmi_detach(ar); err: Loading Loading @@ -913,7 +859,9 @@ void ath10k_core_stop(struct ath10k *ar) ath10k_debug_stop(ar); ath10k_htc_stop(&ar->htc); ath10k_htt_detach(&ar->htt); ath10k_hif_stop(ar); ath10k_htt_tx_free(&ar->htt); ath10k_htt_rx_free(&ar->htt); ath10k_wmi_detach(ar); } EXPORT_SYMBOL(ath10k_core_stop); Loading Loading @@ -1005,22 +953,15 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) return 0; } int ath10k_core_register(struct ath10k *ar, u32 chip_id) static void ath10k_core_register_work(struct work_struct *work) { struct ath10k *ar = container_of(work, struct ath10k, register_work); int status; ar->chip_id = chip_id; status = ath10k_core_check_chip_id(ar); if (status) { ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); return status; } status = ath10k_core_probe_fw(ar); if (status) { ath10k_err("could not probe fw (%d)\n", status); return status; goto err; } status = ath10k_mac_register(ar); Loading @@ -1035,18 +976,43 @@ int ath10k_core_register(struct ath10k *ar, u32 chip_id) goto err_unregister_mac; } return 0; set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags); return; err_unregister_mac: ath10k_mac_unregister(ar); err_release_fw: ath10k_core_free_firmware_files(ar); err: device_release_driver(ar->dev); return; } int ath10k_core_register(struct ath10k *ar, u32 chip_id) { int status; ar->chip_id = chip_id; status = ath10k_core_check_chip_id(ar); if (status) { ath10k_err("Unsupported chip id 0x%08x\n", ar->chip_id); return status; } queue_work(ar->workqueue, &ar->register_work); return 0; } EXPORT_SYMBOL(ath10k_core_register); void ath10k_core_unregister(struct ath10k *ar) { cancel_work_sync(&ar->register_work); if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; /* We must unregister from mac80211 before we stop HTC and HIF. * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ Loading @@ -1058,6 +1024,71 @@ void ath10k_core_unregister(struct ath10k *ar) } EXPORT_SYMBOL(ath10k_core_unregister); struct ath10k *ath10k_core_create(void *hif_priv, struct device *dev, const struct ath10k_hif_ops *hif_ops) { struct ath10k *ar; ar = ath10k_mac_create(); if (!ar) return NULL; ar->ath_common.priv = ar; ar->ath_common.hw = ar->hw; ar->p2p = !!ath10k_p2p; ar->dev = dev; ar->hif.priv = hif_priv; ar->hif.ops = hif_ops; init_completion(&ar->scan.started); init_completion(&ar->scan.completed); init_completion(&ar->scan.on_channel); init_completion(&ar->target_suspend); init_completion(&ar->install_key_done); init_completion(&ar->vdev_setup_done); setup_timer(&ar->scan.timeout, ath10k_reset_scan, (unsigned long)ar); ar->workqueue = create_singlethread_workqueue("ath10k_wq"); if (!ar->workqueue) goto err_wq; mutex_init(&ar->conf_mutex); spin_lock_init(&ar->data_lock); INIT_LIST_HEAD(&ar->peers); init_waitqueue_head(&ar->peer_mapping_wq); init_completion(&ar->offchan_tx_completed); INIT_WORK(&ar->offchan_tx_work, ath10k_offchan_tx_work); skb_queue_head_init(&ar->offchan_tx_queue); INIT_WORK(&ar->wmi_mgmt_tx_work, ath10k_mgmt_over_wmi_tx_work); skb_queue_head_init(&ar->wmi_mgmt_tx_queue); INIT_WORK(&ar->register_work, ath10k_core_register_work); INIT_WORK(&ar->restart_work, ath10k_core_restart); return ar; err_wq: ath10k_mac_destroy(ar); return NULL; } EXPORT_SYMBOL(ath10k_core_create); void ath10k_core_destroy(struct ath10k *ar) { flush_workqueue(ar->workqueue); destroy_workqueue(ar->workqueue); ath10k_mac_destroy(ar); } EXPORT_SYMBOL(ath10k_core_destroy); MODULE_AUTHOR("Qualcomm Atheros"); MODULE_DESCRIPTION("Core module for QCA988X PCIe devices."); MODULE_LICENSE("Dual BSD/GPL");
drivers/net/wireless/ath/ath10k/core.h +8 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,7 @@ enum ath10k_dev_flags { /* Indicates that ath10k device is during CAC phase of DFS */ ATH10K_CAC_RUNNING, ATH10K_FLAG_FIRST_BOOT_DONE, ATH10K_FLAG_CORE_REGISTERED, }; struct ath10k { Loading Loading @@ -440,6 +441,12 @@ struct ath10k { bool radar_enabled; int num_started_vdevs; /* Protected by conf-mutex */ u8 supp_tx_chainmask; u8 supp_rx_chainmask; u8 cfg_tx_chainmask; u8 cfg_rx_chainmask; struct wmi_pdev_set_wmm_params_arg wmm_params; struct completion install_key_done; Loading Loading @@ -470,6 +477,7 @@ struct ath10k { enum ath10k_state state; struct work_struct register_work; struct work_struct restart_work; /* cycle count is reported twice for each visited channel during scan. Loading