make b43 work with minstrel
Subsystems (2)
cover make b43 work with minstrel
Hi,
here are some small patches to make b43 work properly with minstrel. The b43 patch might need more review/testing, but it matches my observations with a BCM4311 card. b43legacy could probably be adapted in a similar way, but I didn't test that.
- Felix
PATCH 1/2 mac80211: detect hardware rate fallback for non-MRR hardware
This fixes tx status processing for drivers that do not support mrr. If the retry count is bigger than the maximum retry count configured in the hardware, do not count the rate attempt as successful, the hardware has probably switched to a lower rate.
net/mac80211/rc80211_minstrel.c +8 -0
@@ -171,6 +171,7 @@ minstrel_tx_status(void *priv, struct iestruct ieee80211_tx_info *info =IEEE80211_SKB_CB (skb);struct ieee80211_tx_altrate *ar = info->status.retries;struct minstrel_priv *mp = priv; +struct ieee80211_local *local =hw_to_local (mp->hw);int i, ndx, tries;int success =0 ;
@@ -180,6 +181,13 @@ minstrel_tx_status(void *priv, struct ieif (!mp->has_mrr || (ar[0 ].rate_idx <0 )) { ndx =rix_to_ndx (mi, info->tx_rate_idx); tries = info->status.retry_count +1 ; + +/* If the driver does not support the MRR API, but uses +* a fallback rate, use the long retry limit as indication +* that a rate switch has happened */ +if (!mp->has_mrr && (tries >= local->long_retry_limit)) + success =0 ; + mi->r[ndx].success += success; mi->r[ndx].attempts += tries;return ;
PATCH 2/2 b43: fix tx status reporting on rate fallback
If the hardware uses RTS/CTS reporting and the actual RTS/CTS handshake failed, it will switch to the fallback rate, even though the main rate was never actually attempted. Make sure that this does not screw up rate control statistics.
drivers/net/wireless/b43/b43.h +3 -0
@@ -778,6 +778,9 @@ struct b43_wldev {#ifdef CONFIG_B43_DEBUG struct b43_dfsentry *dfsentry;#endif + +/* necessary for figuring out the correct tx status */ +int short_retry; };static inline struct b43_wl *hw_to_b43_wl (struct ieee80211_hw *hw)
drivers/net/wireless/b43/dma.c +1 -1
@@ -1393,7 +1393,7 @@ void b43_dma_handle_txstatus(struct b43_* Call back to inform the ieee80211 subsystem about * the status of the transmission. */ - frame_succeed =b43_fill_txstatus_report (info, status); + frame_succeed =b43_fill_txstatus_report (dev, info, status);#ifdef CONFIG_B43_DEBUG if (frame_succeed) ring->nr_succeed_tx_packets++;
drivers/net/wireless/b43/main.c +1 -0
@@ -3892,6 +3892,7 @@ static void b43_set_retry_limits(struct short_retry);b43_shm_write16 (dev,B43_SHM_SCRATCH ,B43_SHM_SC_LRLIMIT , long_retry); + dev->short_retry = short_retry; }static void b43_set_synth_pu_delay (struct b43_wldev *dev,bool idle)
drivers/net/wireless/b43/pio.c +1 -1
@@ -589,7 +589,7 @@ void b43_pio_handle_txstatus(struct b43_ info =IEEE80211_SKB_CB (pack->skb);memset (&info->status,0 ,sizeof (info->status)); -b43_fill_txstatus_report (info, status); +b43_fill_txstatus_report (dev, info, status); total_len = pack->skb->len +b43_txhdr_size (dev); total_len =roundup (total_len,4 );
drivers/net/wireless/b43/xmit.c +14 -2
@@ -687,7 +687,8 @@ void b43_handle_txstatus(struct b43_wlde/* Fill out the mac80211 TXstatus report based on the b43-specific * txstatus report data. This returns a boolean whether the frame was * successfully transmitted. */ -bool b43_fill_txstatus_report (struct ieee80211_tx_info *report, +bool b43_fill_txstatus_report (struct b43_wldev *dev, +struct ieee80211_tx_info *report,const struct b43_txstatus *status) {bool frame_success =1 ;
@@ -706,8 +707,19 @@ bool b43_fill_txstatus_report(struct ieeif (status->frame_count ==0 ) {/* The frame was not transmitted at all. */ report->status.retry_count =0 ; - }else + }else if (status->rts_count > dev->short_retry) { +/* +* If the short retries (RTS, not data frame) have exceeded +* the limit, the hw will not have tried the selected rate, +* but will have used the fallback rate instead. +* Don't let the rate control count attempts for the selected +* rate in this case, otherwise the statistics will be off. +*/ + report->tx_rate_idx =0 ; + report->status.retry_count =0 ; + }else { report->status.retry_count = status->frame_count -1 ; + }return frame_success; }
drivers/net/wireless/b43/xmit.h +2 -1
@@ -294,7 +294,8 @@ void b43_rx(struct b43_wldev *dev, strucvoid b43_handle_txstatus (struct b43_wldev *dev,const struct b43_txstatus *status); -bool b43_fill_txstatus_report (struct ieee80211_tx_info *report, +bool b43_fill_txstatus_report (struct b43_wldev *dev, +struct ieee80211_tx_info *report,const struct b43_txstatus *status);void b43_tx_suspend (struct b43_wldev *dev);