Loading drivers/net/wireless/ath/ath10k/bmi.c +27 −15 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ void ath10k_bmi_start(struct ath10k *ar) { ath10k_dbg(ATH10K_DBG_CORE, "BMI started\n"); ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n"); ar->bmi.done_sent = false; } Loading @@ -32,8 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n"); if (ar->bmi.done_sent) { ath10k_dbg(ATH10K_DBG_CORE, "%s skipped\n", __func__); ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n"); return 0; } Loading @@ -46,7 +49,6 @@ int ath10k_bmi_done(struct ath10k *ar) return ret; } ath10k_dbg(ATH10K_DBG_CORE, "BMI done\n"); return 0; } Loading @@ -59,6 +61,8 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, u32 resplen = sizeof(resp.get_target_info); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n"); if (ar->bmi.done_sent) { ath10k_warn("BMI Get Target Info Command disallowed\n"); return -EBUSY; Loading @@ -80,6 +84,7 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, target_info->version = __le32_to_cpu(resp.get_target_info.version); target_info->type = __le32_to_cpu(resp.get_target_info.type); return 0; } Loading @@ -92,15 +97,14 @@ int ath10k_bmi_read_memory(struct ath10k *ar, u32 rxlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", address, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, length: %d)\n", __func__, ar, address, length); while (length) { rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE); Loading Loading @@ -133,15 +137,14 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 txlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", address, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, length: %d)\n", __func__, ar, address, length); while (length) { txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen); Loading Loading @@ -180,15 +183,14 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) u32 resplen = sizeof(resp.execute); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", address, *param); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, param: %d)\n", __func__, ar, address, *param); cmd.id = __cpu_to_le32(BMI_EXECUTE); cmd.execute.addr = __cpu_to_le32(address); cmd.execute.param = __cpu_to_le32(*param); Loading Loading @@ -216,6 +218,9 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) u32 txlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", buffer, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; Loading Loading @@ -250,6 +255,9 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", address); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; Loading @@ -275,6 +283,10 @@ int ath10k_bmi_fast_download(struct ath10k *ar, u32 trailer_len = length - head_len; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi fast download address 0x%x buffer 0x%p length %d\n", address, buffer, length); ret = ath10k_bmi_lz_stream_start(ar, address); if (ret) return ret; Loading drivers/net/wireless/ath/ath10k/ce.c +26 −87 Original line number Diff line number Diff line Loading @@ -338,33 +338,19 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, return ret; } void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer, unsigned int nbytes, u32 flags) { unsigned int num_items = sendlist->num_items; struct ce_sendlist_item *item; item = &sendlist->item[num_items]; item->data = buffer; item->u.nbytes = nbytes; item->flags = flags; sendlist->num_items++; } int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_context, struct ce_sendlist *sendlist, unsigned int transfer_id) unsigned int transfer_id, u32 paddr, unsigned int nbytes, u32 flags) { struct ath10k_ce_ring *src_ring = ce_state->src_ring; struct ce_sendlist_item *item; struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); unsigned int nentries_mask = src_ring->nentries_mask; unsigned int num_items = sendlist->num_items; unsigned int sw_index; unsigned int write_index; int i, delta, ret = -ENOMEM; int delta, ret = -ENOMEM; spin_lock_bh(&ar_pci->ce_lock); Loading @@ -373,30 +359,12 @@ int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, delta = CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); if (delta >= num_items) { /* * Handle all but the last item uniformly. */ for (i = 0; i < num_items - 1; i++) { item = &sendlist->item[i]; ret = ath10k_ce_send_nolock(ce_state, CE_SENDLIST_ITEM_CTXT, (u32) item->data, item->u.nbytes, transfer_id, item->flags | CE_SEND_FLAG_GATHER); if (ret) ath10k_warn("CE send failed for item: %d\n", i); } /* * Provide valid context pointer for final item. */ item = &sendlist->item[i]; if (delta >= 1) { ret = ath10k_ce_send_nolock(ce_state, per_transfer_context, (u32) item->data, item->u.nbytes, transfer_id, item->flags); paddr, nbytes, transfer_id, flags); if (ret) ath10k_warn("CE send failed for last item: %d\n", i); ath10k_warn("CE send failed: %d\n", ret); } spin_unlock_bh(&ar_pci->ce_lock); Loading Loading @@ -742,11 +710,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; u32 ctrl_addr = ce_state->ctrl_addr; void *transfer_context; u32 buf; unsigned int nbytes; unsigned int id; unsigned int flags; int ret; ret = ath10k_pci_wake(ar); Loading @@ -759,38 +722,15 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) ath10k_ce_engine_int_status_clear(ar, ctrl_addr, HOST_IS_COPY_COMPLETE_MASK); if (ce_state->recv_cb) { /* * Pop completed recv buffers and call the registered * recv callback for each */ while (ath10k_ce_completed_recv_next_nolock(ce_state, &transfer_context, &buf, &nbytes, &id, &flags) == 0) { spin_unlock_bh(&ar_pci->ce_lock); ce_state->recv_cb(ce_state, transfer_context, buf, nbytes, id, flags); spin_lock_bh(&ar_pci->ce_lock); } } if (ce_state->send_cb) { /* * Pop completed send buffers and call the registered * send callback for each */ while (ath10k_ce_completed_send_next_nolock(ce_state, &transfer_context, &buf, &nbytes, &id) == 0) { spin_unlock_bh(&ar_pci->ce_lock); ce_state->send_cb(ce_state, transfer_context, buf, nbytes, id); if (ce_state->recv_cb) ce_state->recv_cb(ce_state); if (ce_state->send_cb) ce_state->send_cb(ce_state); spin_lock_bh(&ar_pci->ce_lock); } } /* * Misc CE interrupts are not being handled, but still need Loading Loading @@ -881,11 +821,7 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar) } void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id), void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts) { struct ath10k *ar = ce_state->ar; Loading @@ -898,12 +834,7 @@ void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, } void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, void (*recv_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags)) void (*recv_cb)(struct ath10k_ce_pipe *)) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); Loading Loading @@ -1010,6 +941,10 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; } Loading Loading @@ -1091,6 +1026,10 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } Loading drivers/net/wireless/ath/ath10k/ce.h +8 −62 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ /* Descriptor rings must be aligned to this boundary */ #define CE_DESC_RING_ALIGN 8 #define CE_SENDLIST_ITEMS_MAX 12 #define CE_SEND_FLAG_GATHER 0x00010000 /* Loading Loading @@ -116,41 +115,14 @@ struct ath10k_ce_pipe { u32 ctrl_addr; void (*send_cb) (struct ath10k_ce_pipe *ce_state, void *per_transfer_send_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id); void (*recv_cb) (struct ath10k_ce_pipe *ce_state, void *per_transfer_recv_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags); void (*send_cb)(struct ath10k_ce_pipe *); void (*recv_cb)(struct ath10k_ce_pipe *); unsigned int src_sz_max; struct ath10k_ce_ring *src_ring; struct ath10k_ce_ring *dest_ring; }; struct ce_sendlist_item { /* e.g. buffer or desc list */ dma_addr_t data; union { /* simple buffer */ unsigned int nbytes; /* Rx descriptor list */ unsigned int ndesc; } u; /* externally-specified flags; OR-ed with internal flags */ u32 flags; }; struct ce_sendlist { unsigned int num_items; struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX]; }; /* Copy Engine settable attributes */ struct ce_attr; Loading Loading @@ -181,20 +153,9 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int flags); void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id), void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts); /* Append a simple buffer (address/length) to a sendlist. */ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer, unsigned int nbytes, /* OR-ed with internal flags */ u32 flags); /* * Queue a "sendlist" of buffers to be sent using gather to a single * anonymous destination buffer Loading @@ -206,10 +167,10 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, * Implemenation note: Pushes multiple buffers with Gather to Source ring. */ int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_send_context, struct ce_sendlist *sendlist, /* 14 bits */ unsigned int transfer_id); void *per_transfer_context, unsigned int transfer_id, u32 paddr, unsigned int nbytes, u32 flags); /*==================Recv=======================*/ Loading @@ -228,12 +189,7 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, u32 buffer); void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, void (*recv_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags)); void (*recv_cb)(struct ath10k_ce_pipe *)); /* recv flags */ /* Data is byte-swapped */ Loading Loading @@ -325,16 +281,6 @@ struct ce_attr { unsigned int dest_nentries; }; /* * When using sendlist_send to transfer multiple buffer fragments, the * transfer context of each fragment, except last one, will be filled * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for * each fragment done with send and the transfer context would be * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the * status of a send completion. */ #define CE_SENDLIST_ITEM_CTXT ((void *)0xcecebeef) #define SR_BA_ADDRESS 0x0000 #define SR_SIZE_ADDRESS 0x0004 #define DR_BA_ADDRESS 0x0008 Loading drivers/net/wireless/ath/ath10k/core.c +20 −4 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { static void ath10k_send_suspend_complete(struct ath10k *ar) { ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__); ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); ar->is_target_paused = true; wake_up(&ar->event_queue); Loading Loading @@ -101,7 +101,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar) goto timeout; } ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n"); ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); return 0; timeout: Loading Loading @@ -203,8 +203,8 @@ static int ath10k_push_board_ext_data(struct ath10k *ar, return ret; } ath10k_dbg(ATH10K_DBG_CORE, "ath10k: Board extended Data download addr: 0x%x\n", ath10k_dbg(ATH10K_DBG_BOOT, "boot push board extended data addr 0x%x\n", board_ext_data_addr); if (board_ext_data_addr == 0) Loading Loading @@ -435,6 +435,13 @@ static int ath10k_init_uart(struct ath10k *ar) return ret; } /* Set the UART baud rate to 19200. */ ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); if (ret) { ath10k_warn("could not set the baud rate (%d)\n", ret); return ret; } ath10k_info("UART prints enabled\n"); return 0; } Loading Loading @@ -630,6 +637,10 @@ int ath10k_core_start(struct ath10k *ar) if (status) goto err_disconnect_htc; status = ath10k_debug_start(ar); if (status) goto err_disconnect_htc; ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; return 0; Loading @@ -647,6 +658,7 @@ EXPORT_SYMBOL(ath10k_core_start); void ath10k_core_stop(struct ath10k *ar) { ath10k_debug_stop(ar); ath10k_htc_stop(&ar->htc); ath10k_htt_detach(&ar->htt); ath10k_wmi_detach(ar); Loading Loading @@ -710,6 +722,9 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) { u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", ar->chip_id, hw_revision); /* Check that we are not using hw1.0 (some of them have same pci id * as hw2.0) before doing anything else as ath10k crashes horribly * due to missing hw1.0 workarounds. */ Loading Loading @@ -777,6 +792,7 @@ void ath10k_core_unregister(struct ath10k *ar) * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ ath10k_mac_unregister(ar); ath10k_core_free_firmware_files(ar); } EXPORT_SYMBOL(ath10k_core_unregister); Loading drivers/net/wireless/ath/ath10k/core.h +8 −14 Original line number Diff line number Diff line Loading @@ -52,18 +52,12 @@ struct ath10k_skb_cb { struct { u8 vdev_id; u16 msdu_id; u8 tid; bool is_offchan; bool is_conf; bool discard; bool no_ack; u8 refcount; struct sk_buff *txfrag; struct sk_buff *msdu; } __packed htt; /* 4 bytes left on 64bit arch */ u8 frag_len; u8 pad_len; } __packed htt; } __packed; static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) Loading Loading @@ -112,11 +106,7 @@ struct ath10k_wmi { enum ath10k_htc_ep_id eid; struct completion service_ready; struct completion unified_ready; atomic_t pending_tx_count; wait_queue_head_t wq; struct sk_buff_head wmi_event_list; struct work_struct wmi_event_work; wait_queue_head_t tx_credits_wq; }; struct ath10k_peer_stat { Loading Loading @@ -203,6 +193,7 @@ struct ath10k_vif { enum wmi_vdev_subtype vdev_subtype; u32 beacon_interval; u32 dtim_period; struct sk_buff *beacon; struct ath10k *ar; struct ieee80211_vif *vif; Loading Loading @@ -246,6 +237,9 @@ struct ath10k_debug { u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; struct completion event_stats_compl; unsigned long htt_stats_mask; struct delayed_work htt_stats_dwork; }; enum ath10k_state { Loading Loading
drivers/net/wireless/ath/ath10k/bmi.c +27 −15 Original line number Diff line number Diff line Loading @@ -22,7 +22,8 @@ void ath10k_bmi_start(struct ath10k *ar) { ath10k_dbg(ATH10K_DBG_CORE, "BMI started\n"); ath10k_dbg(ATH10K_DBG_BMI, "bmi start\n"); ar->bmi.done_sent = false; } Loading @@ -32,8 +33,10 @@ int ath10k_bmi_done(struct ath10k *ar) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.done); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi done\n"); if (ar->bmi.done_sent) { ath10k_dbg(ATH10K_DBG_CORE, "%s skipped\n", __func__); ath10k_dbg(ATH10K_DBG_BMI, "bmi skipped\n"); return 0; } Loading @@ -46,7 +49,6 @@ int ath10k_bmi_done(struct ath10k *ar) return ret; } ath10k_dbg(ATH10K_DBG_CORE, "BMI done\n"); return 0; } Loading @@ -59,6 +61,8 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, u32 resplen = sizeof(resp.get_target_info); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi get target info\n"); if (ar->bmi.done_sent) { ath10k_warn("BMI Get Target Info Command disallowed\n"); return -EBUSY; Loading @@ -80,6 +84,7 @@ int ath10k_bmi_get_target_info(struct ath10k *ar, target_info->version = __le32_to_cpu(resp.get_target_info.version); target_info->type = __le32_to_cpu(resp.get_target_info.type); return 0; } Loading @@ -92,15 +97,14 @@ int ath10k_bmi_read_memory(struct ath10k *ar, u32 rxlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi read address 0x%x length %d\n", address, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, length: %d)\n", __func__, ar, address, length); while (length) { rxlen = min_t(u32, length, BMI_MAX_DATA_SIZE); Loading Loading @@ -133,15 +137,14 @@ int ath10k_bmi_write_memory(struct ath10k *ar, u32 txlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi write address 0x%x length %d\n", address, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, length: %d)\n", __func__, ar, address, length); while (length) { txlen = min(length, BMI_MAX_DATA_SIZE - hdrlen); Loading Loading @@ -180,15 +183,14 @@ int ath10k_bmi_execute(struct ath10k *ar, u32 address, u32 *param) u32 resplen = sizeof(resp.execute); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi execute address 0x%x param 0x%x\n", address, *param); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; } ath10k_dbg(ATH10K_DBG_CORE, "%s: (device: 0x%p, address: 0x%x, param: %d)\n", __func__, ar, address, *param); cmd.id = __cpu_to_le32(BMI_EXECUTE); cmd.execute.addr = __cpu_to_le32(address); cmd.execute.param = __cpu_to_le32(*param); Loading Loading @@ -216,6 +218,9 @@ int ath10k_bmi_lz_data(struct ath10k *ar, const void *buffer, u32 length) u32 txlen; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi lz data buffer 0x%p length %d\n", buffer, length); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; Loading Loading @@ -250,6 +255,9 @@ int ath10k_bmi_lz_stream_start(struct ath10k *ar, u32 address) u32 cmdlen = sizeof(cmd.id) + sizeof(cmd.lz_start); int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi lz stream start address 0x%x\n", address); if (ar->bmi.done_sent) { ath10k_warn("command disallowed\n"); return -EBUSY; Loading @@ -275,6 +283,10 @@ int ath10k_bmi_fast_download(struct ath10k *ar, u32 trailer_len = length - head_len; int ret; ath10k_dbg(ATH10K_DBG_BMI, "bmi fast download address 0x%x buffer 0x%p length %d\n", address, buffer, length); ret = ath10k_bmi_lz_stream_start(ar, address); if (ret) return ret; Loading
drivers/net/wireless/ath/ath10k/ce.c +26 −87 Original line number Diff line number Diff line Loading @@ -338,33 +338,19 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, return ret; } void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer, unsigned int nbytes, u32 flags) { unsigned int num_items = sendlist->num_items; struct ce_sendlist_item *item; item = &sendlist->item[num_items]; item->data = buffer; item->u.nbytes = nbytes; item->flags = flags; sendlist->num_items++; } int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_context, struct ce_sendlist *sendlist, unsigned int transfer_id) unsigned int transfer_id, u32 paddr, unsigned int nbytes, u32 flags) { struct ath10k_ce_ring *src_ring = ce_state->src_ring; struct ce_sendlist_item *item; struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); unsigned int nentries_mask = src_ring->nentries_mask; unsigned int num_items = sendlist->num_items; unsigned int sw_index; unsigned int write_index; int i, delta, ret = -ENOMEM; int delta, ret = -ENOMEM; spin_lock_bh(&ar_pci->ce_lock); Loading @@ -373,30 +359,12 @@ int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, delta = CE_RING_DELTA(nentries_mask, write_index, sw_index - 1); if (delta >= num_items) { /* * Handle all but the last item uniformly. */ for (i = 0; i < num_items - 1; i++) { item = &sendlist->item[i]; ret = ath10k_ce_send_nolock(ce_state, CE_SENDLIST_ITEM_CTXT, (u32) item->data, item->u.nbytes, transfer_id, item->flags | CE_SEND_FLAG_GATHER); if (ret) ath10k_warn("CE send failed for item: %d\n", i); } /* * Provide valid context pointer for final item. */ item = &sendlist->item[i]; if (delta >= 1) { ret = ath10k_ce_send_nolock(ce_state, per_transfer_context, (u32) item->data, item->u.nbytes, transfer_id, item->flags); paddr, nbytes, transfer_id, flags); if (ret) ath10k_warn("CE send failed for last item: %d\n", i); ath10k_warn("CE send failed: %d\n", ret); } spin_unlock_bh(&ar_pci->ce_lock); Loading Loading @@ -742,11 +710,6 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; u32 ctrl_addr = ce_state->ctrl_addr; void *transfer_context; u32 buf; unsigned int nbytes; unsigned int id; unsigned int flags; int ret; ret = ath10k_pci_wake(ar); Loading @@ -759,38 +722,15 @@ void ath10k_ce_per_engine_service(struct ath10k *ar, unsigned int ce_id) ath10k_ce_engine_int_status_clear(ar, ctrl_addr, HOST_IS_COPY_COMPLETE_MASK); if (ce_state->recv_cb) { /* * Pop completed recv buffers and call the registered * recv callback for each */ while (ath10k_ce_completed_recv_next_nolock(ce_state, &transfer_context, &buf, &nbytes, &id, &flags) == 0) { spin_unlock_bh(&ar_pci->ce_lock); ce_state->recv_cb(ce_state, transfer_context, buf, nbytes, id, flags); spin_lock_bh(&ar_pci->ce_lock); } } if (ce_state->send_cb) { /* * Pop completed send buffers and call the registered * send callback for each */ while (ath10k_ce_completed_send_next_nolock(ce_state, &transfer_context, &buf, &nbytes, &id) == 0) { spin_unlock_bh(&ar_pci->ce_lock); ce_state->send_cb(ce_state, transfer_context, buf, nbytes, id); if (ce_state->recv_cb) ce_state->recv_cb(ce_state); if (ce_state->send_cb) ce_state->send_cb(ce_state); spin_lock_bh(&ar_pci->ce_lock); } } /* * Misc CE interrupts are not being handled, but still need Loading Loading @@ -881,11 +821,7 @@ void ath10k_ce_disable_interrupts(struct ath10k *ar) } void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id), void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts) { struct ath10k *ar = ce_state->ar; Loading @@ -898,12 +834,7 @@ void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, } void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, void (*recv_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags)) void (*recv_cb)(struct ath10k_ce_pipe *)) { struct ath10k *ar = ce_state->ar; struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); Loading Loading @@ -1010,6 +941,10 @@ static int ath10k_ce_init_src_ring(struct ath10k *ar, ath10k_ce_src_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_src_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce src ring id %d entries %d base_addr %p\n", ce_id, nentries, src_ring->base_addr_owner_space); return 0; } Loading Loading @@ -1091,6 +1026,10 @@ static int ath10k_ce_init_dest_ring(struct ath10k *ar, ath10k_ce_dest_ring_lowmark_set(ar, ctrl_addr, 0); ath10k_ce_dest_ring_highmark_set(ar, ctrl_addr, nentries); ath10k_dbg(ATH10K_DBG_BOOT, "boot ce dest ring id %d entries %d base_addr %p\n", ce_id, nentries, dest_ring->base_addr_owner_space); return 0; } Loading
drivers/net/wireless/ath/ath10k/ce.h +8 −62 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ /* Descriptor rings must be aligned to this boundary */ #define CE_DESC_RING_ALIGN 8 #define CE_SENDLIST_ITEMS_MAX 12 #define CE_SEND_FLAG_GATHER 0x00010000 /* Loading Loading @@ -116,41 +115,14 @@ struct ath10k_ce_pipe { u32 ctrl_addr; void (*send_cb) (struct ath10k_ce_pipe *ce_state, void *per_transfer_send_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id); void (*recv_cb) (struct ath10k_ce_pipe *ce_state, void *per_transfer_recv_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags); void (*send_cb)(struct ath10k_ce_pipe *); void (*recv_cb)(struct ath10k_ce_pipe *); unsigned int src_sz_max; struct ath10k_ce_ring *src_ring; struct ath10k_ce_ring *dest_ring; }; struct ce_sendlist_item { /* e.g. buffer or desc list */ dma_addr_t data; union { /* simple buffer */ unsigned int nbytes; /* Rx descriptor list */ unsigned int ndesc; } u; /* externally-specified flags; OR-ed with internal flags */ u32 flags; }; struct ce_sendlist { unsigned int num_items; struct ce_sendlist_item item[CE_SENDLIST_ITEMS_MAX]; }; /* Copy Engine settable attributes */ struct ce_attr; Loading Loading @@ -181,20 +153,9 @@ int ath10k_ce_send(struct ath10k_ce_pipe *ce_state, unsigned int flags); void ath10k_ce_send_cb_register(struct ath10k_ce_pipe *ce_state, void (*send_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id), void (*send_cb)(struct ath10k_ce_pipe *), int disable_interrupts); /* Append a simple buffer (address/length) to a sendlist. */ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, u32 buffer, unsigned int nbytes, /* OR-ed with internal flags */ u32 flags); /* * Queue a "sendlist" of buffers to be sent using gather to a single * anonymous destination buffer Loading @@ -206,10 +167,10 @@ void ath10k_ce_sendlist_buf_add(struct ce_sendlist *sendlist, * Implemenation note: Pushes multiple buffers with Gather to Source ring. */ int ath10k_ce_sendlist_send(struct ath10k_ce_pipe *ce_state, void *per_transfer_send_context, struct ce_sendlist *sendlist, /* 14 bits */ unsigned int transfer_id); void *per_transfer_context, unsigned int transfer_id, u32 paddr, unsigned int nbytes, u32 flags); /*==================Recv=======================*/ Loading @@ -228,12 +189,7 @@ int ath10k_ce_recv_buf_enqueue(struct ath10k_ce_pipe *ce_state, u32 buffer); void ath10k_ce_recv_cb_register(struct ath10k_ce_pipe *ce_state, void (*recv_cb)(struct ath10k_ce_pipe *ce_state, void *transfer_context, u32 buffer, unsigned int nbytes, unsigned int transfer_id, unsigned int flags)); void (*recv_cb)(struct ath10k_ce_pipe *)); /* recv flags */ /* Data is byte-swapped */ Loading Loading @@ -325,16 +281,6 @@ struct ce_attr { unsigned int dest_nentries; }; /* * When using sendlist_send to transfer multiple buffer fragments, the * transfer context of each fragment, except last one, will be filled * with CE_SENDLIST_ITEM_CTXT. ce_completed_send will return success for * each fragment done with send and the transfer context would be * CE_SENDLIST_ITEM_CTXT. Upper layer could use this to identify the * status of a send completion. */ #define CE_SENDLIST_ITEM_CTXT ((void *)0xcecebeef) #define SR_BA_ADDRESS 0x0000 #define SR_SIZE_ADDRESS 0x0004 #define DR_BA_ADDRESS 0x0008 Loading
drivers/net/wireless/ath/ath10k/core.c +20 −4 Original line number Diff line number Diff line Loading @@ -53,7 +53,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { static void ath10k_send_suspend_complete(struct ath10k *ar) { ath10k_dbg(ATH10K_DBG_CORE, "%s\n", __func__); ath10k_dbg(ATH10K_DBG_BOOT, "boot suspend complete\n"); ar->is_target_paused = true; wake_up(&ar->event_queue); Loading Loading @@ -101,7 +101,7 @@ static int ath10k_init_connect_htc(struct ath10k *ar) goto timeout; } ath10k_dbg(ATH10K_DBG_CORE, "core wmi ready\n"); ath10k_dbg(ATH10K_DBG_BOOT, "boot wmi ready\n"); return 0; timeout: Loading Loading @@ -203,8 +203,8 @@ static int ath10k_push_board_ext_data(struct ath10k *ar, return ret; } ath10k_dbg(ATH10K_DBG_CORE, "ath10k: Board extended Data download addr: 0x%x\n", ath10k_dbg(ATH10K_DBG_BOOT, "boot push board extended data addr 0x%x\n", board_ext_data_addr); if (board_ext_data_addr == 0) Loading Loading @@ -435,6 +435,13 @@ static int ath10k_init_uart(struct ath10k *ar) return ret; } /* Set the UART baud rate to 19200. */ ret = ath10k_bmi_write32(ar, hi_desired_baud_rate, 19200); if (ret) { ath10k_warn("could not set the baud rate (%d)\n", ret); return ret; } ath10k_info("UART prints enabled\n"); return 0; } Loading Loading @@ -630,6 +637,10 @@ int ath10k_core_start(struct ath10k *ar) if (status) goto err_disconnect_htc; status = ath10k_debug_start(ar); if (status) goto err_disconnect_htc; ar->free_vdev_map = (1 << TARGET_NUM_VDEVS) - 1; return 0; Loading @@ -647,6 +658,7 @@ EXPORT_SYMBOL(ath10k_core_start); void ath10k_core_stop(struct ath10k *ar) { ath10k_debug_stop(ar); ath10k_htc_stop(&ar->htc); ath10k_htt_detach(&ar->htt); ath10k_wmi_detach(ar); Loading Loading @@ -710,6 +722,9 @@ static int ath10k_core_check_chip_id(struct ath10k *ar) { u32 hw_revision = MS(ar->chip_id, SOC_CHIP_ID_REV); ath10k_dbg(ATH10K_DBG_BOOT, "boot chip_id 0x%08x hw_revision 0x%x\n", ar->chip_id, hw_revision); /* Check that we are not using hw1.0 (some of them have same pci id * as hw2.0) before doing anything else as ath10k crashes horribly * due to missing hw1.0 workarounds. */ Loading Loading @@ -777,6 +792,7 @@ void ath10k_core_unregister(struct ath10k *ar) * Otherwise we will fail to submit commands to FW and mac80211 will be * unhappy about callback failures. */ ath10k_mac_unregister(ar); ath10k_core_free_firmware_files(ar); } EXPORT_SYMBOL(ath10k_core_unregister); Loading
drivers/net/wireless/ath/ath10k/core.h +8 −14 Original line number Diff line number Diff line Loading @@ -52,18 +52,12 @@ struct ath10k_skb_cb { struct { u8 vdev_id; u16 msdu_id; u8 tid; bool is_offchan; bool is_conf; bool discard; bool no_ack; u8 refcount; struct sk_buff *txfrag; struct sk_buff *msdu; } __packed htt; /* 4 bytes left on 64bit arch */ u8 frag_len; u8 pad_len; } __packed htt; } __packed; static inline struct ath10k_skb_cb *ATH10K_SKB_CB(struct sk_buff *skb) Loading Loading @@ -112,11 +106,7 @@ struct ath10k_wmi { enum ath10k_htc_ep_id eid; struct completion service_ready; struct completion unified_ready; atomic_t pending_tx_count; wait_queue_head_t wq; struct sk_buff_head wmi_event_list; struct work_struct wmi_event_work; wait_queue_head_t tx_credits_wq; }; struct ath10k_peer_stat { Loading Loading @@ -203,6 +193,7 @@ struct ath10k_vif { enum wmi_vdev_subtype vdev_subtype; u32 beacon_interval; u32 dtim_period; struct sk_buff *beacon; struct ath10k *ar; struct ieee80211_vif *vif; Loading Loading @@ -246,6 +237,9 @@ struct ath10k_debug { u32 wmi_service_bitmap[WMI_SERVICE_BM_SIZE]; struct completion event_stats_compl; unsigned long htt_stats_mask; struct delayed_work htt_stats_dwork; }; enum ath10k_state { Loading