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

Commit c2acea8e authored by Johannes Berg's avatar Johannes Berg Committed by John W. Linville
Browse files

iwlwifi: fix up command sending



The current command sending in iwlwifi is a bit of a mess:
 1) there is a struct, iwl_cmd, that contains both driver
    and device data in a single packed structure -- this
    is very confusing
 2) the on-stack data and the command metadata share a
    structure by embedding the latter in the former, which
    is also rather confusing because it leads to weird
    unions and similarly odd constructs
 3) each txq always has enough space for 256 commands,
    even if only 32 end up being used

This patch fixes these things:
 1) rename iwl_cmd to iwl_device_cmd and keep track of
    command metadata and device command separately, in
    two arrays in each tx queue
 2) remove the 'meta' member from iwl_host_cmd and only
    put in the required members
 3) allocate the cmd/meta arrays separately instead of
    embedding them into the txq structure

Signed-off-by: default avatarJohannes Berg <johannes@sipsolutions.net>
Signed-off-by: default avatarReinette Chatre <reinette.chatre@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent fbf3a2af
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -80,7 +80,7 @@ static const struct {
#define IWL_SOLID_BLINK_IDX (ARRAY_SIZE(blink_tbl) - 1)

static int iwl3945_led_cmd_callback(struct iwl_priv *priv,
				    struct iwl_cmd *cmd,
				    struct iwl_device_cmd *cmd,
				    struct sk_buff *skb)
{
	return 1;
@@ -99,8 +99,8 @@ static int iwl_send_led_cmd(struct iwl_priv *priv,
		.id = REPLY_LEDS_CMD,
		.len = sizeof(struct iwl_led_cmd),
		.data = led_cmd,
		.meta.flags = CMD_ASYNC,
		.meta.u.callback = iwl3945_led_cmd_callback,
		.flags = CMD_ASYNC,
		.callback = iwl3945_led_cmd_callback,
	};

	return iwl_send_cmd(priv, &cmd);
+10 −8
Original line number Diff line number Diff line
@@ -749,8 +749,8 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
	/* Unmap tx_cmd */
	if (counter)
		pci_unmap_single(dev,
				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
				pci_unmap_len(&txq->cmd[index]->meta, len),
				pci_unmap_addr(&txq->meta[index], mapping),
				pci_unmap_len(&txq->meta[index], len),
				PCI_DMA_TODEVICE);

	/* unmap chunks if any */
@@ -774,9 +774,11 @@ void iwl3945_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
 * iwl3945_hw_build_tx_cmd_rate - Add rate portion to TX_CMD:
 *
*/
void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
				  struct iwl_device_cmd *cmd,
				  struct ieee80211_tx_info *info,
			      struct ieee80211_hdr *hdr, int sta_id, int tx_id)
				  struct ieee80211_hdr *hdr,
				  int sta_id, int tx_id)
{
	u16 hw_value = ieee80211_get_tx_rate(priv->hw, info)->hw_value;
	u16 rate_index = min(hw_value & 0xffff, IWL_RATE_COUNT - 1);
@@ -1858,7 +1860,7 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
	struct iwl_host_cmd cmd = {
		.id = REPLY_RXON_ASSOC,
		.len = sizeof(rxon_assoc),
		.meta.flags = CMD_WANT_SKB,
		.flags = CMD_WANT_SKB,
		.data = &rxon_assoc,
	};
	const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
@@ -1882,14 +1884,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
	if (rc)
		return rc;

	res = (struct iwl_rx_packet *)cmd.meta.u.skb->data;
	res = (struct iwl_rx_packet *)cmd.reply_skb->data;
	if (res->hdr.flags & IWL_CMD_FAILED_MSK) {
		IWL_ERR(priv, "Bad return from REPLY_RXON_ASSOC command\n");
		rc = -EIO;
	}

	priv->alloc_rxb_skb--;
	dev_kfree_skb_any(cmd.meta.u.skb);
	dev_kfree_skb_any(cmd.reply_skb);

	return rc;
}
+5 −4
Original line number Diff line number Diff line
@@ -254,7 +254,8 @@ extern int iwl3945_hw_tx_queue_init(struct iwl_priv *priv,
				struct iwl_tx_queue *txq);
extern unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
				 struct iwl3945_frame *frame, u8 rate);
void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv, struct iwl_cmd *cmd,
void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
				  struct iwl_device_cmd *cmd,
				  struct ieee80211_tx_info *info,
				  struct ieee80211_hdr *hdr,
				  int sta_id, int tx_id);
+2 −2
Original line number Diff line number Diff line
@@ -442,8 +442,8 @@ void iwl_hw_txq_free_tfd(struct iwl_priv *priv, struct iwl_tx_queue *txq)
	/* Unmap tx_cmd */
	if (num_tbs)
		pci_unmap_single(dev,
				pci_unmap_addr(&txq->cmd[index]->meta, mapping),
				pci_unmap_len(&txq->cmd[index]->meta, len),
				pci_unmap_addr(&txq->meta[index], mapping),
				pci_unmap_len(&txq->meta[index], len),
				PCI_DMA_BIDIRECTIONAL);

	/* Unmap chunks, if any. */
+2 −2
Original line number Diff line number Diff line
@@ -86,7 +86,7 @@ int iwl_send_calib_results(struct iwl_priv *priv)

	struct iwl_host_cmd hcmd = {
		.id = REPLY_PHY_CALIBRATION_CMD,
		.meta.flags = CMD_SIZE_HUGE,
		.flags = CMD_SIZE_HUGE,
	};

	for (i = 0; i < IWL_CALIB_MAX; i++) {
@@ -419,7 +419,7 @@ static int iwl_sensitivity_write(struct iwl_priv *priv)
	struct iwl_host_cmd cmd_out = {
		.id = SENSITIVITY_CMD,
		.len = sizeof(struct iwl_sensitivity_cmd),
		.meta.flags = CMD_ASYNC,
		.flags = CMD_ASYNC,
		.data = &cmd,
	};

Loading