Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd4abac5 authored by Tomas Winkler's avatar Tomas Winkler Committed by John W. Linville
Browse files

iwlwifi: move TX code into iwl-tx.c



This patch moves the sending part of the TX code into iwl-tx.c
including sending host commands.

Signed-off-by: default avatarTomas Winkler <tomas.winkler@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 54dbb525
Loading
Loading
Loading
Loading
+0 −105
Original line number Diff line number Diff line
@@ -1933,76 +1933,6 @@ int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel)
	return rc;
}

#define RTS_HCCA_RETRY_LIMIT		3
#define RTS_DFAULT_RETRY_LIMIT		60

void iwl4965_hw_build_tx_cmd_rate(struct iwl_priv *priv,
			      struct iwl_cmd *cmd,
			      struct ieee80211_tx_control *ctrl,
			      struct ieee80211_hdr *hdr, int sta_id,
			      int is_hcca)
{
	struct iwl_tx_cmd *tx = &cmd->cmd.tx;
	u8 rts_retry_limit = 0;
	u8 data_retry_limit = 0;
	u16 fc = le16_to_cpu(hdr->frame_control);
	u8 rate_plcp;
	u16 rate_flags = 0;
	int rate_idx = min(ctrl->tx_rate->hw_value & 0xffff, IWL_RATE_COUNT - 1);

	rate_plcp = iwl_rates[rate_idx].plcp;

	rts_retry_limit = (is_hcca) ?
	    RTS_HCCA_RETRY_LIMIT : RTS_DFAULT_RETRY_LIMIT;

	if ((rate_idx >= IWL_FIRST_CCK_RATE) && (rate_idx <= IWL_LAST_CCK_RATE))
		rate_flags |= RATE_MCS_CCK_MSK;


	if (ieee80211_is_probe_response(fc)) {
		data_retry_limit = 3;
		if (data_retry_limit < rts_retry_limit)
			rts_retry_limit = data_retry_limit;
	} else
		data_retry_limit = IWL_DEFAULT_TX_RETRY;

	if (priv->data_retry_limit != -1)
		data_retry_limit = priv->data_retry_limit;


	if (ieee80211_is_data(fc)) {
		tx->initial_rate_index = 0;
		tx->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
	} else {
		switch (fc & IEEE80211_FCTL_STYPE) {
		case IEEE80211_STYPE_AUTH:
		case IEEE80211_STYPE_DEAUTH:
		case IEEE80211_STYPE_ASSOC_REQ:
		case IEEE80211_STYPE_REASSOC_REQ:
			if (tx->tx_flags & TX_CMD_FLG_RTS_MSK) {
				tx->tx_flags &= ~TX_CMD_FLG_RTS_MSK;
				tx->tx_flags |= TX_CMD_FLG_CTS_MSK;
			}
			break;
		default:
			break;
		}

		/* Alternate between antenna A and B for successive frames */
		if (priv->use_ant_b_for_management_frame) {
			priv->use_ant_b_for_management_frame = 0;
			rate_flags |= RATE_MCS_ANT_B_MSK;
		} else {
			priv->use_ant_b_for_management_frame = 1;
			rate_flags |= RATE_MCS_ANT_A_MSK;
		}
	}

	tx->rts_retry_limit = rts_retry_limit;
	tx->data_retry_limit = data_retry_limit;
	tx->rate_n_flags = iwl4965_hw_set_rate_n_flags(rate_plcp, rate_flags);
}

static int iwl4965_shared_mem_rx_idx(struct iwl_priv *priv)
{
	struct iwl4965_shared *s = priv->shared_virt;
@@ -2046,40 +1976,6 @@ unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
	return (sizeof(*tx_beacon_cmd) + frame_size);
}

int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *ptr,
				 dma_addr_t addr, u16 len)
{
	int index, is_odd;
	struct iwl_tfd_frame *tfd = ptr;
	u32 num_tbs = IWL_GET_BITS(*tfd, num_tbs);

	/* Each TFD can point to a maximum 20 Tx buffers */
	if ((num_tbs >= MAX_NUM_OF_TBS) || (num_tbs < 0)) {
		IWL_ERROR("Error can not send more than %d chunks\n",
			  MAX_NUM_OF_TBS);
		return -EINVAL;
	}

	index = num_tbs / 2;
	is_odd = num_tbs & 0x1;

	if (!is_odd) {
		tfd->pa[index].tb1_addr = cpu_to_le32(addr);
		IWL_SET_BITS(tfd->pa[index], tb1_addr_hi,
			     iwl_get_dma_hi_address(addr));
		IWL_SET_BITS(tfd->pa[index], tb1_len, len);
	} else {
		IWL_SET_BITS(tfd->pa[index], tb2_addr_lo16,
			     (u32) (addr & 0xffff));
		IWL_SET_BITS(tfd->pa[index], tb2_addr_hi20, addr >> 16);
		IWL_SET_BITS(tfd->pa[index], tb2_len, len);
	}

	IWL_SET_BITS(*tfd, num_tbs, num_tbs + 1);

	return 0;
}

static int iwl4965_alloc_shared_mem(struct iwl_priv *priv)
{
	priv->shared_virt = pci_alloc_consistent(priv->pci_dev,
@@ -3711,7 +3607,6 @@ static struct iwl_hcmd_ops iwl4965_hcmd = {

static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
	.get_hcmd_size = iwl4965_get_hcmd_size,
	.enqueue_hcmd = iwl4965_enqueue_hcmd,
	.build_addsta_hcmd = iwl4965_build_addsta_hcmd,
#ifdef CONFIG_IWL4965_RUN_TIME_CALIB
	.chain_noise_reset = iwl4965_chain_noise_reset,
+7 −2
Original line number Diff line number Diff line
@@ -87,7 +87,6 @@ struct iwl_hcmd_ops {
};
struct iwl_hcmd_utils_ops {
	u16 (*get_hcmd_size)(u8 cmd_id, u16 len);
	int (*enqueue_hcmd)(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
	u16 (*build_addsta_hcmd)(const struct iwl_addsta_cmd *cmd, u8 *data);
#ifdef CONFIG_IWLWIFI_RUN_TIME_CALIB
	void (*gain_computation)(struct iwl_priv *priv,
@@ -208,10 +207,14 @@ void iwl_rx_allocate(struct iwl_priv *priv);
* TX
******************************************************/
int iwl_txq_ctx_reset(struct iwl_priv *priv);
int iwl_tx_skb(struct iwl_priv *priv,
		struct sk_buff *skb, struct ieee80211_tx_control *ctl);
/* FIXME: remove when free Tx is fully merged into iwlcore */
int iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq);
void iwl_hw_txq_ctx_free(struct iwl_priv *priv);

int iwl_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
					dma_addr_t addr, u16 len);
int iwl_txq_update_write_ptr(struct iwl_priv *priv, struct iwl_tx_queue *txq);
/*****************************************************
 *   S e n d i n g     H o s t     C o m m a n d s   *
 *****************************************************/
@@ -227,6 +230,8 @@ int iwl_send_cmd_pdu_async(struct iwl_priv *priv, u8 id, u16 len,
			   int (*callback)(struct iwl_priv *priv,
					   struct iwl_cmd *cmd,
					   struct sk_buff *skb));

int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd);
/*************** DRIVER STATUS FUNCTIONS   *****/

#define STATUS_HCMD_ACTIVE	0	/* host command in progress */
+19 −2
Original line number Diff line number Diff line
@@ -689,8 +689,6 @@ extern int iwl4965_hw_set_hw_params(struct iwl_priv *priv);
extern int iwl4965_hw_nic_stop_master(struct iwl_priv *priv);
extern void iwl4965_hw_txq_ctx_stop(struct iwl_priv *priv);
extern int iwl4965_hw_nic_reset(struct iwl_priv *priv);
extern int iwl4965_hw_txq_attach_buf_to_tfd(struct iwl_priv *priv, void *tfd,
					dma_addr_t addr, u16 len);
extern int iwl4965_hw_get_temperature(struct iwl_priv *priv);
extern unsigned int iwl4965_hw_get_beacon_cmd(struct iwl_priv *priv,
				 struct iwl_frame *frame, u8 rate);
@@ -719,6 +717,25 @@ extern u8 iwl_find_station(struct iwl_priv *priv, const u8 *bssid);
extern int iwl4965_hw_channel_switch(struct iwl_priv *priv, u16 channel);
extern int iwl4965_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index);
extern int iwl_queue_space(const struct iwl_queue *q);
static inline int iwl_queue_used(const struct iwl_queue *q, int i)
{
	return q->write_ptr > q->read_ptr ?
		(i >= q->read_ptr && i < q->write_ptr) :
		!(i < q->read_ptr && i >= q->write_ptr);
}


static inline u8 get_cmd_index(struct iwl_queue *q, u32 index, int is_huge)
{
	/* This is for scan command, the big buffer at end of command array */
	if (is_huge)
		return q->n_window;	/* must be power of 2 */

	/* Otherwise, use normal size buffers */
	return index & (q->n_window - 1);
}


struct iwl_priv;

extern void iwl4965_radio_kill_sw(struct iwl_priv *priv, int disable_radio);
+2 −2
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ static int iwl_send_cmd_async(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
	if (test_bit(STATUS_EXIT_PENDING, &priv->status))
		return -EBUSY;

	ret = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
	ret = iwl_enqueue_hcmd(priv, cmd);
	if (ret < 0) {
		IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
			  get_cmd_string(cmd->id), ret);
@@ -170,7 +170,7 @@ int iwl_send_cmd_sync(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
	if (cmd->meta.flags & CMD_WANT_SKB)
		cmd->meta.source = &cmd->meta;

	cmd_idx = priv->cfg->ops->utils->enqueue_hcmd(priv, cmd);
	cmd_idx = iwl_enqueue_hcmd(priv, cmd);
	if (cmd_idx < 0) {
		ret = cmd_idx;
		IWL_ERROR("Error sending %s: enqueue_hcmd failed: %d\n",
+662 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading