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

Commit ed277c93 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Wey-Yi Guy
Browse files

iwlwifi: virtualize op_mode's free skb



This handler allows the transport layer to free an skb from the
op_mode. This can happen when the driver is stopped while Tx
packets are pending in the transport layer.

Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent cbe6ab4e
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -1170,6 +1170,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans)
	priv->shrd = trans->shrd;
	priv->shrd->priv = priv;

	iwl_trans_configure(trans(priv), op_mode);

	/* At this point both hw and priv are allocated. */

	SET_IEEE80211_DEV(priv->hw, trans(priv)->dev);
@@ -1383,6 +1385,7 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
const struct iwl_op_mode_ops iwl_dvm_ops = {
	.start = iwl_op_mode_dvm_start,
	.stop = iwl_op_mode_dvm_stop,
	.free_skb = iwl_free_skb,
};

/*****************************************************************************
+1 −0
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ static inline void iwl_set_calib_hdr(struct iwl_calib_hdr *hdr, u8 cmd)
void iwl_down(struct iwl_priv *priv);
void iwl_cancel_deferred_work(struct iwl_priv *priv);
void iwlagn_prepare_restart(struct iwl_priv *priv);
void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb);

/* MAC80211 */
struct ieee80211_hw *iwl_alloc_all(void);
+3 −1
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@
#include "iwl-shared.h"
#include "iwl-agn.h"
#include "iwl-trans.h"
#include "iwl-wifi.h"

const u8 iwl_bcast_addr[ETH_ALEN] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };

@@ -1464,8 +1465,9 @@ void iwl_nic_config(struct iwl_priv *priv)
	cfg(priv)->lib->nic_config(priv);
}

void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb)
void iwl_free_skb(struct iwl_op_mode *op_mode, struct sk_buff *skb)
{
	struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
	struct ieee80211_tx_info *info;

	info = IEEE80211_SKB_CB(skb);
+12 −0
Original line number Diff line number Diff line
@@ -65,6 +65,7 @@

struct iwl_op_mode;
struct iwl_trans;
struct sk_buff;

/**
 * struct iwl_op_mode_ops - op_mode specific operations
@@ -75,10 +76,15 @@ struct iwl_trans;
 *	May sleep
 * @stop: stop the op_mode
 *	May sleep
 * @free_skb: allows the transport layer to free skbs that haven't been
 *	reclaimed by the op_mode. This can happen when the driver is freed and
 *	there are Tx packets pending in the transport layer.
 *	Must be atomic
 */
struct iwl_op_mode_ops {
	struct iwl_op_mode *(*start)(struct iwl_trans *trans);
	void (*stop)(struct iwl_op_mode *op_mode);
	void (*free_skb)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
};

/**
@@ -100,6 +106,12 @@ static inline void iwl_op_mode_stop(struct iwl_op_mode *op_mode)
	op_mode->ops->stop(op_mode);
}

static inline void iwl_op_mode_free_skb(struct iwl_op_mode *op_mode,
					struct sk_buff *skb)
{
	op_mode->ops->free_skb(op_mode, skb);
}

/*****************************************************
* Op mode layers implementations
******************************************************/
+0 −1
Original line number Diff line number Diff line
@@ -540,7 +540,6 @@ int __must_check iwl_rx_dispatch(struct iwl_priv *priv,
int iwlagn_hw_valid_rtc_data_addr(u32 addr);
void iwl_set_hw_rfkill_state(struct iwl_priv *priv, bool state);
void iwl_nic_config(struct iwl_priv *priv);
void iwl_free_skb(struct iwl_priv *priv, struct sk_buff *skb);
void iwlagn_fw_error(struct iwl_priv *priv, bool ondemand);
const char *get_cmd_string(u8 cmd);
bool iwl_check_for_ct_kill(struct iwl_priv *priv);
Loading