struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
- const struct iwl_mac_cfg *mac_cfg,
- unsigned int txcmd_size,
- unsigned int txcmd_align)
+ const struct iwl_mac_cfg *mac_cfg)
{
struct iwl_trans *trans;
#ifdef CONFIG_LOCKDEP
INIT_DELAYED_WORK(&trans->restart.wk, iwl_trans_restart_wk);
- snprintf(trans->dev_cmd_pool_name, sizeof(trans->dev_cmd_pool_name),
- "iwl_cmd_pool:%s", dev_name(trans->dev));
- trans->dev_cmd_pool =
- kmem_cache_create(trans->dev_cmd_pool_name,
- txcmd_size, txcmd_align,
- SLAB_HWCACHE_ALIGN, NULL);
- if (!trans->dev_cmd_pool)
- return NULL;
-
return trans;
}
void iwl_trans_free(struct iwl_trans *trans)
{
cancel_delayed_work_sync(&trans->restart.wk);
- kmem_cache_destroy(trans->dev_cmd_pool);
}
int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd)
}
IWL_EXPORT_SYMBOL(iwl_trans_send_cmd);
+struct iwl_device_tx_cmd *iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
+{
+ return iwl_pcie_gen1_2_alloc_tx_cmd(trans);
+}
+IWL_EXPORT_SYMBOL(iwl_trans_alloc_tx_cmd);
+
+void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
+ struct iwl_device_tx_cmd *dev_cmd)
+{
+ iwl_pcie_gen1_2_free_tx_cmd(trans, dev_cmd);
+}
+IWL_EXPORT_SYMBOL(iwl_trans_free_tx_cmd);
+
/* Comparator for struct iwl_hcmd_names.
* Used in the binary search over a list of host commands.
*
* @fail_to_parse_pnvm_image: set to true if pnvm parsing failed
* @reduce_power_loaded: indicates reduced power section was loaded
* @failed_to_load_reduce_power_image: set to true if pnvm loading failed
- * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
- * The user should use iwl_trans_{alloc,free}_tx_cmd.
- * @dev_cmd_pool_name: name for the TX command allocation pool
* @dbgfs_dir: iwlwifi debugfs base dir for this device
* @sync_cmd_lockdep_map: lockdep map for checking sync commands
* @dbg: additional debug data, see &struct iwl_trans_debug
u8 reduce_power_loaded:1;
u8 failed_to_load_reduce_power_image:1;
- /* The following fields are internal only */
- struct kmem_cache *dev_cmd_pool;
- char dev_cmd_pool_name[50];
-
struct dentry *dbgfs_dir;
#ifdef CONFIG_LOCKDEP
const struct iwl_dump_sanitize_ops *sanitize_ops,
void *sanitize_ctx);
-static inline struct iwl_device_tx_cmd *
-iwl_trans_alloc_tx_cmd(struct iwl_trans *trans)
-{
- return kmem_cache_zalloc(trans->dev_cmd_pool, GFP_ATOMIC);
-}
+struct iwl_device_tx_cmd *iwl_trans_alloc_tx_cmd(struct iwl_trans *trans);
int iwl_trans_send_cmd(struct iwl_trans *trans, struct iwl_host_cmd *cmd);
-static inline void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
- struct iwl_device_tx_cmd *dev_cmd)
-{
- kmem_cache_free(trans->dev_cmd_pool, dev_cmd);
-}
+void iwl_trans_free_tx_cmd(struct iwl_trans *trans,
+ struct iwl_device_tx_cmd *dev_cmd);
int iwl_trans_tx(struct iwl_trans *trans, struct sk_buff *skb,
struct iwl_device_tx_cmd *dev_cmd, int queue);
*****************************************************/
struct iwl_trans *iwl_trans_alloc(unsigned int priv_size,
struct device *dev,
- const struct iwl_mac_cfg *mac_cfg,
- unsigned int txcmd_size,
- unsigned int txcmd_align);
+ const struct iwl_mac_cfg *mac_cfg);
void iwl_trans_free(struct iwl_trans *trans);
static inline bool iwl_trans_is_hw_error_value(u32 val)
* @me_recheck_wk: worker to recheck WiAMT/CSME presence
* @invalid_tx_cmd: invalid TX command buffer
* @wait_command_queue: wait queue for sync commands
+ * @dev_cmd_pool: pool for Tx cmd allocation - for internal use only.
+ * The user should use iwl_trans_{alloc,free}_tx_cmd.
+ * @dev_cmd_pool_name: name for the TX command allocation pool
*/
struct iwl_trans_pcie {
struct iwl_rxq *rxq;
struct iwl_dma_ptr invalid_tx_cmd;
wait_queue_head_t wait_command_queue;
+
+ struct kmem_cache *dev_cmd_pool;
+ char dev_cmd_pool_name[50];
};
static inline struct iwl_trans_pcie *
return le16_to_cpu(tb->hi_n_len) >> 4;
}
+static inline struct iwl_device_tx_cmd *
+iwl_pcie_gen1_2_alloc_tx_cmd(struct iwl_trans *trans)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ return kmem_cache_zalloc(trans_pcie->dev_cmd_pool, GFP_ATOMIC);
+}
+
+static inline void
+iwl_pcie_gen1_2_free_tx_cmd(struct iwl_trans *trans,
+ struct iwl_device_tx_cmd *dev_cmd)
+{
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+
+ kmem_cache_free(trans_pcie->dev_cmd_pool, dev_cmd);
+}
+
void iwl_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
struct sk_buff_head *skbs, bool is_flush);
void iwl_pcie_set_q_ptrs(struct iwl_trans *trans, int txq_id, int ptr);
free_percpu(trans_pcie->txqs.tso_hdr_page);
}
+ kmem_cache_destroy(trans_pcie->dev_cmd_pool);
iwl_trans_free(trans);
}
iwl_trans_sync_nmi_with_addr(trans, inta_addr, sw_err_bit);
}
-static int iwl_trans_pcie_set_txcmd_info(const struct iwl_mac_cfg *mac_cfg,
- unsigned int *txcmd_size,
- unsigned int *txcmd_align)
+static int iwl_trans_pcie_alloc_txcmd_pool(struct iwl_trans *trans)
{
- if (!mac_cfg->gen2) {
- *txcmd_size = sizeof(struct iwl_tx_cmd_v6);
- *txcmd_align = sizeof(void *);
- } else if (mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
- *txcmd_size = sizeof(struct iwl_tx_cmd_v9);
- *txcmd_align = 64;
+ struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
+ unsigned int txcmd_size, txcmd_align;
+
+ if (!trans->mac_cfg->gen2) {
+ txcmd_size = sizeof(struct iwl_tx_cmd_v6);
+ txcmd_align = sizeof(void *);
+ } else if (trans->mac_cfg->device_family < IWL_DEVICE_FAMILY_AX210) {
+ txcmd_size = sizeof(struct iwl_tx_cmd_v9);
+ txcmd_align = 64;
} else {
- *txcmd_size = sizeof(struct iwl_tx_cmd);
- *txcmd_align = 128;
+ txcmd_size = sizeof(struct iwl_tx_cmd);
+ txcmd_align = 128;
}
- *txcmd_size += sizeof(struct iwl_cmd_header);
- *txcmd_size += 36; /* biggest possible 802.11 header */
+ txcmd_size += sizeof(struct iwl_cmd_header);
+ txcmd_size += 36; /* biggest possible 802.11 header */
/* Ensure device TX cmd cannot reach/cross a page boundary in gen2 */
- if (WARN_ON((mac_cfg->gen2 && *txcmd_size >= *txcmd_align)))
+ if (WARN_ON((trans->mac_cfg->gen2 && txcmd_size >= txcmd_align)))
return -EINVAL;
+ snprintf(trans_pcie->dev_cmd_pool_name,
+ sizeof(trans_pcie->dev_cmd_pool_name),
+ "iwl_cmd_pool:%s", dev_name(trans->dev));
+
+ trans_pcie->dev_cmd_pool =
+ kmem_cache_create(trans_pcie->dev_cmd_pool_name,
+ txcmd_size, txcmd_align,
+ SLAB_HWCACHE_ALIGN, NULL);
+ if (!trans_pcie->dev_cmd_pool)
+ return -ENOMEM;
+
return 0;
}
struct iwl_trans_info *info, u8 __iomem *hw_base)
{
struct iwl_trans_pcie *trans_pcie, **priv;
- unsigned int txcmd_size, txcmd_align;
struct iwl_trans *trans;
unsigned int bc_tbl_n_entries;
int ret, addr_size;
- ret = iwl_trans_pcie_set_txcmd_info(mac_cfg, &txcmd_size,
- &txcmd_align);
- if (ret)
- return ERR_PTR(ret);
-
trans = iwl_trans_alloc(sizeof(struct iwl_trans_pcie), &pdev->dev,
- mac_cfg, txcmd_size, txcmd_align);
+ mac_cfg);
if (!trans)
return ERR_PTR(-ENOMEM);
/* Initialize the wait queue for commands */
init_waitqueue_head(&trans_pcie->wait_command_queue);
+ ret = iwl_trans_pcie_alloc_txcmd_pool(trans);
+ if (ret)
+ goto out_free_trans;
+
if (trans->mac_cfg->gen2) {
trans_pcie->txqs.tfd.addr_size = 64;
trans_pcie->txqs.tfd.max_tbs = IWL_TFH_NUM_TBS;
trans_pcie->txqs.tso_hdr_page = alloc_percpu(struct iwl_tso_hdr_page);
if (!trans_pcie->txqs.tso_hdr_page) {
ret = -ENOMEM;
- goto out_free_trans;
+ goto out_free_txcmd_pool;
}
if (trans->mac_cfg->device_family >= IWL_DEVICE_FAMILY_BZ)
free_netdev(trans_pcie->napi_dev);
out_free_tso:
free_percpu(trans_pcie->txqs.tso_hdr_page);
+out_free_txcmd_pool:
+ kmem_cache_destroy(trans_pcie->dev_cmd_pool);
out_free_trans:
iwl_trans_free(trans);
return ERR_PTR(ret);