Commit 1169310f authored by Golan Ben Ami's avatar Golan Ben Ami Committed by Luca Coelho

iwlwifi: refactor txq_alloc for supporting more command type

Support more txq_alloc command types by moving the command declaration
to the gen specific area.  While at it, move some of the code segments
to a common place for re-use.
Signed-off-by: default avatarGolan Ben Ami <golan.ben.ami@intel.com>
Signed-off-by: default avatarLuca Coelho <luciano.coelho@intel.com>
parent 764f9de5
...@@ -562,7 +562,7 @@ struct iwl_trans_ops { ...@@ -562,7 +562,7 @@ struct iwl_trans_ops {
bool configure_scd); bool configure_scd);
/* 22000 functions */ /* 22000 functions */
int (*txq_alloc)(struct iwl_trans *trans, int (*txq_alloc)(struct iwl_trans *trans,
struct iwl_tx_queue_cfg_cmd *cmd, __le16 flags, u8 sta_id, u8 tid,
int cmd_id, int size, int cmd_id, int size,
unsigned int queue_wdg_timeout); unsigned int queue_wdg_timeout);
void (*txq_free)(struct iwl_trans *trans, int queue); void (*txq_free)(struct iwl_trans *trans, int queue);
...@@ -970,7 +970,7 @@ iwl_trans_txq_free(struct iwl_trans *trans, int queue) ...@@ -970,7 +970,7 @@ iwl_trans_txq_free(struct iwl_trans *trans, int queue)
static inline int static inline int
iwl_trans_txq_alloc(struct iwl_trans *trans, iwl_trans_txq_alloc(struct iwl_trans *trans,
struct iwl_tx_queue_cfg_cmd *cmd, __le16 flags, u8 sta_id, u8 tid,
int cmd_id, int size, int cmd_id, int size,
unsigned int wdg_timeout) unsigned int wdg_timeout)
{ {
...@@ -984,7 +984,8 @@ iwl_trans_txq_alloc(struct iwl_trans *trans, ...@@ -984,7 +984,8 @@ iwl_trans_txq_alloc(struct iwl_trans *trans,
return -EIO; return -EIO;
} }
return trans->ops->txq_alloc(trans, cmd, cmd_id, size, wdg_timeout); return trans->ops->txq_alloc(trans, flags, sta_id, tid,
cmd_id, size, wdg_timeout);
} }
static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans, static inline void iwl_trans_txq_set_shared_mode(struct iwl_trans *trans,
......
...@@ -720,19 +720,15 @@ static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue, ...@@ -720,19 +720,15 @@ static bool iwl_mvm_update_txq_mapping(struct iwl_mvm *mvm, int queue,
int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue, int iwl_mvm_tvqm_enable_txq(struct iwl_mvm *mvm, int mac80211_queue,
u8 sta_id, u8 tid, unsigned int timeout) u8 sta_id, u8 tid, unsigned int timeout)
{ {
struct iwl_tx_queue_cfg_cmd cmd = {
.flags = cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE),
.sta_id = sta_id,
.tid = tid,
};
int queue, size = IWL_DEFAULT_QUEUE_SIZE; int queue, size = IWL_DEFAULT_QUEUE_SIZE;
if (cmd.tid == IWL_MAX_TID_COUNT) { if (tid == IWL_MAX_TID_COUNT) {
cmd.tid = IWL_MGMT_TID; tid = IWL_MGMT_TID;
size = IWL_MGMT_QUEUE_SIZE; size = IWL_MGMT_QUEUE_SIZE;
} }
queue = iwl_trans_txq_alloc(mvm->trans, (void *)&cmd, queue = iwl_trans_txq_alloc(mvm->trans,
SCD_QUEUE_CFG, size, timeout); cpu_to_le16(TX_QUEUE_CFG_ENABLE_QUEUE),
sta_id, tid, SCD_QUEUE_CFG, size, timeout);
if (queue < 0) { if (queue < 0) {
IWL_DEBUG_TX_QUEUES(mvm, IWL_DEBUG_TX_QUEUES(mvm,
......
...@@ -1036,8 +1036,16 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power); ...@@ -1036,8 +1036,16 @@ void iwl_pcie_alloc_fw_monitor(struct iwl_trans *trans, u8 max_power);
int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans, int iwl_trans_pcie_gen2_start_fw(struct iwl_trans *trans,
const struct fw_img *fw, bool run_in_rfkill); const struct fw_img *fw, bool run_in_rfkill);
void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr); void iwl_trans_pcie_gen2_fw_alive(struct iwl_trans *trans, u32 scd_addr);
void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans,
struct iwl_txq *txq);
int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans,
struct iwl_txq **intxq, int size,
unsigned int timeout);
int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans,
struct iwl_txq *txq,
struct iwl_host_cmd *hcmd);
int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
struct iwl_tx_queue_cfg_cmd *cmd, __le16 flags, u8 sta_id, u8 tid,
int cmd_id, int size, int cmd_id, int size,
unsigned int timeout); unsigned int timeout);
void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue); void iwl_trans_pcie_dyn_txq_free(struct iwl_trans *trans, int queue);
......
...@@ -1065,7 +1065,7 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id) ...@@ -1065,7 +1065,7 @@ void iwl_pcie_gen2_txq_unmap(struct iwl_trans *trans, int txq_id)
iwl_wake_queue(trans, txq); iwl_wake_queue(trans, txq);
} }
static void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans, void iwl_pcie_gen2_txq_free_memory(struct iwl_trans *trans,
struct iwl_txq *txq) struct iwl_txq *txq)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
...@@ -1120,23 +1120,13 @@ static void iwl_pcie_gen2_txq_free(struct iwl_trans *trans, int txq_id) ...@@ -1120,23 +1120,13 @@ static void iwl_pcie_gen2_txq_free(struct iwl_trans *trans, int txq_id)
clear_bit(txq_id, trans_pcie->queue_used); clear_bit(txq_id, trans_pcie->queue_used);
} }
int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, int iwl_trans_pcie_dyn_txq_alloc_dma(struct iwl_trans *trans,
struct iwl_tx_queue_cfg_cmd *cmd, struct iwl_txq **intxq, int size,
int cmd_id, int size,
unsigned int timeout) unsigned int timeout)
{ {
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); int ret;
struct iwl_tx_queue_cfg_rsp *rsp;
struct iwl_txq *txq;
struct iwl_host_cmd hcmd = {
.id = cmd_id,
.len = { sizeof(*cmd) },
.data = { cmd, },
.flags = CMD_WANT_SKB,
};
int ret, qid;
u32 wr_ptr;
struct iwl_txq *txq;
txq = kzalloc(sizeof(*txq), GFP_KERNEL); txq = kzalloc(sizeof(*txq), GFP_KERNEL);
if (!txq) if (!txq)
return -ENOMEM; return -ENOMEM;
...@@ -1164,20 +1154,30 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1164,20 +1154,30 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
txq->wd_timeout = msecs_to_jiffies(timeout); txq->wd_timeout = msecs_to_jiffies(timeout);
cmd->tfdq_addr = cpu_to_le64(txq->dma_addr); *intxq = txq;
cmd->byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma); return 0;
cmd->cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size));
ret = iwl_trans_send_cmd(trans, &hcmd); error:
if (ret) iwl_pcie_gen2_txq_free_memory(trans, txq);
goto error; return ret;
}
int iwl_trans_pcie_txq_alloc_response(struct iwl_trans *trans,
struct iwl_txq *txq,
struct iwl_host_cmd *hcmd)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
struct iwl_tx_queue_cfg_rsp *rsp;
int ret, qid;
u32 wr_ptr;
if (WARN_ON(iwl_rx_packet_payload_len(hcmd.resp_pkt) != sizeof(*rsp))) { if (WARN_ON(iwl_rx_packet_payload_len(hcmd->resp_pkt) !=
sizeof(*rsp))) {
ret = -EINVAL; ret = -EINVAL;
goto error_free_resp; goto error_free_resp;
} }
rsp = (void *)hcmd.resp_pkt->data; rsp = (void *)hcmd->resp_pkt->data;
qid = le16_to_cpu(rsp->queue_number); qid = le16_to_cpu(rsp->queue_number);
wr_ptr = le16_to_cpu(rsp->write_pointer); wr_ptr = le16_to_cpu(rsp->write_pointer);
...@@ -1204,11 +1204,48 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans, ...@@ -1204,11 +1204,48 @@ int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
(txq->write_ptr) | (qid << 16)); (txq->write_ptr) | (qid << 16));
IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid); IWL_DEBUG_TX_QUEUES(trans, "Activate queue %d\n", qid);
iwl_free_resp(&hcmd); iwl_free_resp(hcmd);
return qid; return qid;
error_free_resp: error_free_resp:
iwl_free_resp(&hcmd); iwl_free_resp(hcmd);
iwl_pcie_gen2_txq_free_memory(trans, txq);
return ret;
}
int iwl_trans_pcie_dyn_txq_alloc(struct iwl_trans *trans,
__le16 flags, u8 sta_id, u8 tid,
int cmd_id, int size,
unsigned int timeout)
{
struct iwl_txq *txq = NULL;
struct iwl_tx_queue_cfg_cmd cmd = {
.flags = flags,
.sta_id = sta_id,
.tid = tid,
};
struct iwl_host_cmd hcmd = {
.id = cmd_id,
.len = { sizeof(cmd) },
.data = { &cmd, },
.flags = CMD_WANT_SKB,
};
int ret;
ret = iwl_trans_pcie_dyn_txq_alloc_dma(trans, &txq, size, timeout);
if (ret)
return ret;
cmd.tfdq_addr = cpu_to_le64(txq->dma_addr);
cmd.byte_cnt_addr = cpu_to_le64(txq->bc_tbl.dma);
cmd.cb_size = cpu_to_le32(TFD_QUEUE_CB_SIZE(size));
ret = iwl_trans_send_cmd(trans, &hcmd);
if (ret)
goto error;
return iwl_trans_pcie_txq_alloc_response(trans, txq, &hcmd);
error: error:
iwl_pcie_gen2_txq_free_memory(trans, txq); iwl_pcie_gen2_txq_free_memory(trans, txq);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment