318-mac80211-add-ieee80211_tx_status_noskb.patch 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. From: Felix Fietkau <nbd@openwrt.org>
  2. Date: Sat, 15 Nov 2014 23:50:27 +0100
  3. Subject: [PATCH] mac80211: add ieee80211_tx_status_noskb
  4. This can be used by drivers that cannot reliably map tx status
  5. information onto specific skbs.
  6. Signed-off-by: Felix Fietkau <nbd@openwrt.org>
  7. ---
  8. --- a/include/net/mac80211.h
  9. +++ b/include/net/mac80211.h
  10. @@ -3517,6 +3517,28 @@ void ieee80211_tx_status(struct ieee8021
  11. struct sk_buff *skb);
  12. /**
  13. + * ieee80211_tx_status_noskb - transmit status callback without skb
  14. + *
  15. + * This function can be used as a replacement for ieee80211_tx_status
  16. + * in drivers that cannot reliably map tx status information back to
  17. + * specific skbs.
  18. + *
  19. + * This function may not be called in IRQ context. Calls to this function
  20. + * for a single hardware must be synchronized against each other. Calls
  21. + * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
  22. + * may not be mixed for a single hardware. Must not run concurrently with
  23. + * ieee80211_rx() or ieee80211_rx_ni().
  24. + *
  25. + * @hw: the hardware the frame was transmitted by
  26. + * @sta: the receiver station to which this packet is sent
  27. + * (NULL for multicast packets)
  28. + * @info: tx status information
  29. + */
  30. +void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
  31. + struct ieee80211_sta *sta,
  32. + struct ieee80211_tx_info *info);
  33. +
  34. +/**
  35. * ieee80211_tx_status_ni - transmit status callback (in process context)
  36. *
  37. * Like ieee80211_tx_status() but can be called in process context.
  38. --- a/net/mac80211/rate.h
  39. +++ b/net/mac80211/rate.h
  40. @@ -49,6 +49,23 @@ static inline void rate_control_tx_statu
  41. }
  42. +static inline void
  43. +rate_control_tx_status_noskb(struct ieee80211_local *local,
  44. + struct ieee80211_supported_band *sband,
  45. + struct sta_info *sta,
  46. + struct ieee80211_tx_info *info)
  47. +{
  48. + struct rate_control_ref *ref = local->rate_ctrl;
  49. + struct ieee80211_sta *ista = &sta->sta;
  50. + void *priv_sta = sta->rate_ctrl_priv;
  51. +
  52. + if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
  53. + return;
  54. +
  55. + ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
  56. +}
  57. +
  58. +
  59. static inline void rate_control_rate_init(struct sta_info *sta)
  60. {
  61. struct ieee80211_local *local = sta->sdata->local;
  62. --- a/net/mac80211/status.c
  63. +++ b/net/mac80211/status.c
  64. @@ -541,10 +541,9 @@ static void ieee80211_tx_latency_end_msr
  65. #define STA_LOST_TDLS_PKT_THRESHOLD 10
  66. #define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */
  67. -static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
  68. +static void ieee80211_lost_packet(struct sta_info *sta,
  69. + struct ieee80211_tx_info *info)
  70. {
  71. - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  72. -
  73. /* This packet was aggregated but doesn't carry status info */
  74. if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
  75. !(info->flags & IEEE80211_TX_STAT_AMPDU))
  76. @@ -571,24 +570,13 @@ static void ieee80211_lost_packet(struct
  77. sta->lost_packets = 0;
  78. }
  79. -void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
  80. +static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
  81. + struct ieee80211_tx_info *info,
  82. + int *retry_count)
  83. {
  84. - struct sk_buff *skb2;
  85. - struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
  86. - struct ieee80211_local *local = hw_to_local(hw);
  87. - struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  88. - __le16 fc;
  89. - struct ieee80211_supported_band *sband;
  90. - struct ieee80211_sub_if_data *sdata;
  91. - struct net_device *prev_dev = NULL;
  92. - struct sta_info *sta, *tmp;
  93. - int retry_count = -1, i;
  94. int rates_idx = -1;
  95. - bool send_to_cooked;
  96. - bool acked;
  97. - struct ieee80211_bar *bar;
  98. - int rtap_len;
  99. - int shift = 0;
  100. + int count = -1;
  101. + int i;
  102. for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
  103. if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
  104. @@ -606,12 +594,94 @@ void ieee80211_tx_status(struct ieee8021
  105. break;
  106. }
  107. - retry_count += info->status.rates[i].count;
  108. + count += info->status.rates[i].count;
  109. }
  110. rates_idx = i - 1;
  111. - if (retry_count < 0)
  112. - retry_count = 0;
  113. + if (count < 0)
  114. + count = 0;
  115. +
  116. + *retry_count = count;
  117. + return rates_idx;
  118. +}
  119. +
  120. +void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
  121. + struct ieee80211_sta *pubsta,
  122. + struct ieee80211_tx_info *info)
  123. +{
  124. + struct ieee80211_local *local = hw_to_local(hw);
  125. + struct ieee80211_supported_band *sband;
  126. + int retry_count;
  127. + int rates_idx;
  128. + bool acked;
  129. +
  130. + rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
  131. +
  132. + sband = hw->wiphy->bands[info->band];
  133. +
  134. + acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
  135. + if (pubsta) {
  136. + struct sta_info *sta;
  137. +
  138. + sta = container_of(pubsta, struct sta_info, sta);
  139. +
  140. + if (info->flags & IEEE80211_TX_STATUS_EOSP)
  141. + clear_sta_flag(sta, WLAN_STA_SP);
  142. +
  143. + if (!acked)
  144. + sta->tx_retry_failed++;
  145. + sta->tx_retry_count += retry_count;
  146. +
  147. + if (acked) {
  148. + sta->last_rx = jiffies;
  149. +
  150. + if (sta->lost_packets)
  151. + sta->lost_packets = 0;
  152. +
  153. + /* Track when last TDLS packet was ACKed */
  154. + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
  155. + sta->last_tdls_pkt_time = jiffies;
  156. + } else {
  157. + ieee80211_lost_packet(sta, info);
  158. + }
  159. +
  160. + rate_control_tx_status_noskb(local, sband, sta, info);
  161. + }
  162. +
  163. + if (acked) {
  164. + local->dot11TransmittedFrameCount++;
  165. + if (!pubsta)
  166. + local->dot11MulticastTransmittedFrameCount++;
  167. + if (retry_count > 0)
  168. + local->dot11RetryCount++;
  169. + if (retry_count > 1)
  170. + local->dot11MultipleRetryCount++;
  171. + } else {
  172. + local->dot11FailedCount++;
  173. + }
  174. +}
  175. +EXPORT_SYMBOL(ieee80211_tx_status_noskb);
  176. +
  177. +void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
  178. +{
  179. + struct sk_buff *skb2;
  180. + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
  181. + struct ieee80211_local *local = hw_to_local(hw);
  182. + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  183. + __le16 fc;
  184. + struct ieee80211_supported_band *sband;
  185. + struct ieee80211_sub_if_data *sdata;
  186. + struct net_device *prev_dev = NULL;
  187. + struct sta_info *sta, *tmp;
  188. + int retry_count;
  189. + int rates_idx;
  190. + bool send_to_cooked;
  191. + bool acked;
  192. + struct ieee80211_bar *bar;
  193. + int rtap_len;
  194. + int shift = 0;
  195. +
  196. + rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
  197. rcu_read_lock();
  198. @@ -716,7 +786,7 @@ void ieee80211_tx_status(struct ieee8021
  199. if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
  200. sta->last_tdls_pkt_time = jiffies;
  201. } else {
  202. - ieee80211_lost_packet(sta, skb);
  203. + ieee80211_lost_packet(sta, info);
  204. }
  205. }