/* * Initialize a Copy Engine based on caller-supplied attributes. * This may be called once to initialize both source and destination * rings or it may be called twice for separate source and destination * initialization. It may be that only one side or the other is * initialized by software/firmware. */ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { int ret; if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, attr); if (ret) { ath10k_err(ar, "Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); return ret; } } if (attr->dest_nentries) { ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); if (ret) { ath10k_err(ar, "Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); return ret; } } return 0; }
/* * Initialize a Copy Engine based on caller-supplied attributes. * This may be called once to initialize both source and destination * rings or it may be called twice for separate source and destination * initialization. It may be that only one side or the other is * initialized by software/firmware. */ int ath10k_ce_init_pipe(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_pci *ar_pci = ath10k_pci_priv(ar); struct ath10k_ce_pipe *ce_state = &ar_pci->ce_states[ce_id]; int ret; /* * Make sure there's enough CE ringbuffer entries for HTT TX to avoid * additional TX locking checks. * * For the lack of a better place do the check here. */ BUILD_BUG_ON(2*TARGET_NUM_MSDU_DESC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); BUILD_BUG_ON(2*TARGET_10X_NUM_MSDU_DESC > (CE_HTT_H2T_MSG_SRC_NENTRIES - 1)); ret = ath10k_pci_wake(ar); if (ret) return ret; spin_lock_bh(&ar_pci->ce_lock); ce_state->ar = ar; ce_state->id = ce_id; ce_state->ctrl_addr = ath10k_ce_base_address(ce_id); ce_state->attr_flags = attr->flags; ce_state->src_sz_max = attr->src_sz_max; spin_unlock_bh(&ar_pci->ce_lock); if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); goto out; } } if (attr->dest_nentries) { ret = ath10k_ce_init_dest_ring(ar, ce_id, attr); if (ret) { ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); goto out; } } out: ath10k_pci_sleep(ar); return ret; }
/* * Initialize a Copy Engine based on caller-supplied attributes. * This may be called once to initialize both source and destination * rings or it may be called twice for separate source and destination * initialization. It may be that only one side or the other is * initialized by software/firmware. */ struct ath10k_ce_pipe *ath10k_ce_init(struct ath10k *ar, unsigned int ce_id, const struct ce_attr *attr) { struct ath10k_ce_pipe *ce_state; u32 ctrl_addr = ath10k_ce_base_address(ce_id); int ret; ret = ath10k_pci_wake(ar); if (ret) return NULL; ce_state = ath10k_ce_init_state(ar, ce_id, attr); if (!ce_state) { ath10k_err("Failed to initialize CE state for ID: %d\n", ce_id); return NULL; } if (attr->src_nentries) { ret = ath10k_ce_init_src_ring(ar, ce_id, ce_state, attr); if (ret) { ath10k_err("Failed to initialize CE src ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); return NULL; } } if (attr->dest_nentries) { ret = ath10k_ce_init_dest_ring(ar, ce_id, ce_state, attr); if (ret) { ath10k_err("Failed to initialize CE dest ring for ID: %d (%d)\n", ce_id, ret); ath10k_ce_deinit(ce_state); return NULL; } } /* Enable CE error interrupts */ ath10k_ce_error_intr_enable(ar, ctrl_addr); ath10k_pci_sleep(ar); return ce_state; }