Skip to content

Commit

Permalink
mac80211: make tx() operation return void
Browse files Browse the repository at this point in the history
The return value of the tx operation is commonly
misused by drivers, leading to errors. All drivers
will drop frames if they fail to TX the frame, and
they must also properly manage the queues (if they
didn't, mac80211 would already warn).

Removing the ability for drivers to return a BUSY
value also allows significant cleanups of the TX
TX handling code in mac80211.

Note that this also fixes a bug in ath9k_htc, the
old "return -1" there was wrong.

Signed-off-by: Johannes Berg <[email protected]>
Tested-by: Sedat Dilek <[email protected]> [ath5k]
Acked-by: Gertjan van Wingerde <[email protected]> [rt2x00]
Acked-by: Larry Finger <[email protected]> [b43, rtl8187, rtlwifi]
Acked-by: Luciano Coelho <[email protected]> [wl12xx]
Signed-off-by: John W. Linville <[email protected]>
  • Loading branch information
jmberg-intel authored and linvjw committed Feb 25, 2011
1 parent 43f12d4 commit 7bb4568
Show file tree
Hide file tree
Showing 37 changed files with 122 additions and 237 deletions.
4 changes: 1 addition & 3 deletions drivers/net/wireless/adm8211.c
Original file line number Diff line number Diff line change
Expand Up @@ -1658,7 +1658,7 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb,
}

/* Put adm8211_tx_hdr on skb and transmit */
static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
static void adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
{
struct adm8211_tx_hdr *txhdr;
size_t payload_len, hdrlen;
Expand Down Expand Up @@ -1707,8 +1707,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
txhdr->retry_limit = info->control.rates[0].count;

adm8211_tx_raw(dev, skb, plcp_signal, hdrlen);

return NETDEV_TX_OK;
}

static int adm8211_alloc_rings(struct ieee80211_hw *dev)
Expand Down
7 changes: 3 additions & 4 deletions drivers/net/wireless/at76c50x-usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1728,7 +1728,7 @@ static void at76_mac80211_tx_callback(struct urb *urb)
ieee80211_wake_queues(priv->hw);
}

static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static void at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct at76_priv *priv = hw->priv;
struct at76_tx_buffer *tx_buffer = priv->bulk_out_buffer;
Expand All @@ -1741,7 +1741,8 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (priv->tx_urb->status == -EINPROGRESS) {
wiphy_err(priv->hw->wiphy,
"%s called while tx urb is pending\n", __func__);
return NETDEV_TX_BUSY;
dev_kfree_skb_any(skb);
return;
}

/* The following code lines are important when the device is going to
Expand Down Expand Up @@ -1795,8 +1796,6 @@ static int at76_mac80211_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
priv->tx_urb,
priv->tx_urb->hcpriv, priv->tx_urb->complete);
}

return 0;
}

static int at76_mac80211_start(struct ieee80211_hw *hw)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/ar9170/ar9170.h
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);
int ar9170_nag_limiter(struct ar9170 *ar);

/* MAC */
int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
int ar9170_init_mac(struct ar9170 *ar);
int ar9170_set_qos(struct ar9170 *ar);
int ar9170_update_multicast(struct ar9170 *ar, const u64 mc_hast);
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/ath/ar9170/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1475,7 +1475,7 @@ static void ar9170_tx(struct ar9170 *ar)
msecs_to_jiffies(AR9170_JANITOR_DELAY));
}

int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ar9170 *ar = hw->priv;
struct ieee80211_tx_info *info;
Expand All @@ -1493,11 +1493,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
skb_queue_tail(&ar->tx_pending[queue], skb);

ar9170_tx(ar);
return NETDEV_TX_OK;
return;

err_free:
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}

static int ar9170_op_add_interface(struct ieee80211_hw *hw,
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/wireless/ath/ath5k/ath5k.h
Original file line number Diff line number Diff line change
Expand Up @@ -1164,8 +1164,8 @@ struct ath5k_txq;

void set_beacon_filter(struct ieee80211_hw *hw, bool enable);
bool ath_any_vif_assoc(struct ath5k_softc *sc);
int ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq);
void ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq);
int ath5k_init_hw(struct ath5k_softc *sc);
int ath5k_stop_hw(struct ath5k_softc *sc);
void ath5k_mode_setup(struct ath5k_softc *sc, struct ieee80211_vif *vif);
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/ath/ath5k/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1518,7 +1518,7 @@ ath5k_tasklet_rx(unsigned long data)
* TX Handling *
\*************/

int
void
ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
struct ath5k_txq *txq)
{
Expand Down Expand Up @@ -1567,11 +1567,10 @@ ath5k_tx_queue(struct ieee80211_hw *hw, struct sk_buff *skb,
spin_unlock_irqrestore(&sc->txbuflock, flags);
goto drop_packet;
}
return NETDEV_TX_OK;
return;

drop_packet:
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}

static void
Expand Down
6 changes: 3 additions & 3 deletions drivers/net/wireless/ath/ath5k/mac80211-ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,18 +52,18 @@ extern int ath5k_modparam_nohwcrypt;
* Mac80211 functions *
\********************/

static int
static void
ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath5k_softc *sc = hw->priv;
u16 qnum = skb_get_queue_mapping(skb);

if (WARN_ON(qnum >= sc->ah->ah_capabilities.cap_queues.q_tx_num)) {
dev_kfree_skb_any(skb);
return 0;
return;
}

return ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
ath5k_tx_queue(hw, skb, &sc->txqs[qnum]);
}


Expand Down
7 changes: 3 additions & 4 deletions drivers/net/wireless/ath/ath9k/htc_drv_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1036,7 +1036,7 @@ void ath9k_htc_ani_work(struct work_struct *work)
/* mac80211 Callbacks */
/**********************/

static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static void ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ieee80211_hdr *hdr;
struct ath9k_htc_priv *priv = hw->priv;
Expand All @@ -1049,7 +1049,7 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
padsize = padpos & 3;
if (padsize && skb->len > padpos) {
if (skb_headroom(skb) < padsize)
return -1;
goto fail_tx;
skb_push(skb, padsize);
memmove(skb->data, skb->data + padsize, padpos);
}
Expand All @@ -1070,11 +1070,10 @@ static int ath9k_htc_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
goto fail_tx;
}

return 0;
return;

fail_tx:
dev_kfree_skb_any(skb);
return 0;
}

static int ath9k_htc_start(struct ieee80211_hw *hw)
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/ath/ath9k/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1142,8 +1142,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
return r;
}

static int ath9k_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
static void ath9k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ath_softc *sc = hw->priv;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
Expand Down Expand Up @@ -1200,10 +1199,9 @@ static int ath9k_tx(struct ieee80211_hw *hw,
goto exit;
}

return 0;
return;
exit:
dev_kfree_skb_any(skb);
return 0;
}

static void ath9k_stop(struct ieee80211_hw *hw)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/ath/carl9170/carl9170.h
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,7 @@ void carl9170_rx(struct ar9170 *ar, void *buf, unsigned int len);
void carl9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len);

/* TX */
int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void carl9170_tx_janitor(struct work_struct *work);
void carl9170_tx_process_status(struct ar9170 *ar,
const struct carl9170_rsp *cmd);
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/ath/carl9170/tx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1339,7 +1339,7 @@ static bool carl9170_tx_ampdu_queue(struct ar9170 *ar,
return false;
}

int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct ar9170 *ar = hw->priv;
struct ieee80211_tx_info *info;
Expand Down Expand Up @@ -1373,12 +1373,11 @@ int carl9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
}

carl9170_tx(ar);
return NETDEV_TX_OK;
return;

err_free:
ar->tx_dropped++;
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
}

void carl9170_tx_scheduler(struct ar9170 *ar)
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3203,22 +3203,20 @@ static void b43_tx_work(struct work_struct *work)
mutex_unlock(&wl->mutex);
}

static int b43_op_tx(struct ieee80211_hw *hw,
static void b43_op_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct b43_wl *wl = hw_to_b43_wl(hw);

if (unlikely(skb->len < 2 + 2 + 6)) {
/* Too short, this can't be a valid frame. */
dev_kfree_skb_any(skb);
return NETDEV_TX_OK;
return;
}
B43_WARN_ON(skb_shinfo(skb)->nr_frags);

skb_queue_tail(&wl->tx_queue, skb);
ieee80211_queue_work(wl->hw, &wl->tx_work);

return NETDEV_TX_OK;
}

static void b43_qos_params_upload(struct b43_wldev *dev,
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/b43legacy/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -2442,8 +2442,8 @@ static int b43legacy_rng_init(struct b43legacy_wl *wl)
return err;
}

static int b43legacy_op_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
static void b43legacy_op_tx(struct ieee80211_hw *hw,
struct sk_buff *skb)
{
struct b43legacy_wl *wl = hw_to_b43legacy_wl(hw);
struct b43legacy_wldev *dev = wl->current_dev;
Expand All @@ -2466,7 +2466,6 @@ static int b43legacy_op_tx(struct ieee80211_hw *hw,
/* Drop the packet. */
dev_kfree_skb_any(skb);
}
return NETDEV_TX_OK;
}

static int b43legacy_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlegacy/iwl-4965.h
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ void iwl4965_eeprom_release_semaphore(struct iwl_priv *priv);
int iwl4965_eeprom_check_version(struct iwl_priv *priv);

/* mac80211 handlers (for 4965) */
int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
int iwl4965_mac_start(struct ieee80211_hw *hw);
void iwl4965_mac_stop(struct ieee80211_hw *hw);
void iwl4965_configure_filter(struct ieee80211_hw *hw,
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlegacy/iwl3945-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -3170,7 +3170,7 @@ static void iwl3945_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}

static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static void iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;

Expand All @@ -3183,7 +3183,6 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);

IWL_DEBUG_MAC80211(priv, "leave\n");
return NETDEV_TX_OK;
}

void iwl3945_config_ap(struct iwl_priv *priv)
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlegacy/iwl4965-base.c
Original file line number Diff line number Diff line change
Expand Up @@ -2631,7 +2631,7 @@ void iwl4965_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}

int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;

Expand All @@ -2644,7 +2644,6 @@ int iwl4965_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);

IWL_DEBUG_MACDUMP(priv, "leave\n");
return NETDEV_TX_OK;
}

void iwl4965_mac_update_tkip_key(struct ieee80211_hw *hw,
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/iwlwifi/iwl-agn.c
Original file line number Diff line number Diff line change
Expand Up @@ -3330,7 +3330,7 @@ void iwlagn_mac_stop(struct ieee80211_hw *hw)
IWL_DEBUG_MAC80211(priv, "leave\n");
}

int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct iwl_priv *priv = hw->priv;

Expand All @@ -3343,7 +3343,6 @@ int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
dev_kfree_skb_any(skb);

IWL_DEBUG_MACDUMP(priv, "leave\n");
return NETDEV_TX_OK;
}

void iwlagn_mac_update_tkip_key(struct ieee80211_hw *hw,
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/wireless/iwlwifi/iwl-agn.h
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ iwlagn_remove_notification(struct iwl_priv *priv,
struct iwl_notification_wait *wait_entry);

/* mac80211 handlers (for 4965) */
int iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
void iwlagn_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb);
int iwlagn_mac_start(struct ieee80211_hw *hw);
void iwlagn_mac_stop(struct ieee80211_hw *hw);
void iwlagn_configure_filter(struct ieee80211_hw *hw,
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/wireless/libertas_tf/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ static void lbtf_free_adapter(struct lbtf_private *priv)
lbtf_deb_leave(LBTF_DEB_MAIN);
}

static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static void lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
struct lbtf_private *priv = hw->priv;

Expand All @@ -236,7 +236,6 @@ static int lbtf_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
* there are no buffered multicast frames to send
*/
ieee80211_stop_queues(priv->hw);
return NETDEV_TX_OK;
}

static void lbtf_tx_work(struct work_struct *work)
Expand Down
5 changes: 2 additions & 3 deletions drivers/net/wireless/mac80211_hwsim.c
Original file line number Diff line number Diff line change
Expand Up @@ -541,7 +541,7 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
}


static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
static void mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
{
bool ack;
struct ieee80211_tx_info *txi;
Expand All @@ -551,7 +551,7 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (skb->len < 10) {
/* Should not happen; just a sanity check for addr1 use */
dev_kfree_skb(skb);
return NETDEV_TX_OK;
return;
}

ack = mac80211_hwsim_tx_frame(hw, skb);
Expand All @@ -571,7 +571,6 @@ static int mac80211_hwsim_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
if (!(txi->flags & IEEE80211_TX_CTL_NO_ACK) && ack)
txi->flags |= IEEE80211_TX_STAT_ACK;
ieee80211_tx_status_irqsafe(hw, skb);
return NETDEV_TX_OK;
}


Expand Down
Loading

0 comments on commit 7bb4568

Please sign in to comment.