mt76x2_tx_common.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name>
  3. * Copyright (C) 2018 Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
  4. *
  5. * Permission to use, copy, modify, and/or distribute this software for any
  6. * purpose with or without fee is hereby granted, provided that the above
  7. * copyright notice and this permission notice appear in all copies.
  8. *
  9. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  10. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  11. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  12. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  13. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  14. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  15. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  16. */
  17. #include "mt76x2.h"
  18. #include "mt76x2_dma.h"
  19. void mt76x2_tx(struct ieee80211_hw *hw, struct ieee80211_tx_control *control,
  20. struct sk_buff *skb)
  21. {
  22. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  23. struct mt76x2_dev *dev = hw->priv;
  24. struct ieee80211_vif *vif = info->control.vif;
  25. struct mt76_wcid *wcid = &dev->global_wcid;
  26. if (control->sta) {
  27. struct mt76x2_sta *msta;
  28. msta = (struct mt76x2_sta *)control->sta->drv_priv;
  29. wcid = &msta->wcid;
  30. /* sw encrypted frames */
  31. if (!info->control.hw_key && wcid->hw_key_idx != 0xff)
  32. control->sta = NULL;
  33. }
  34. if (vif && !control->sta) {
  35. struct mt76x2_vif *mvif;
  36. mvif = (struct mt76x2_vif *)vif->drv_priv;
  37. wcid = &mvif->group_wcid;
  38. }
  39. mt76_tx(&dev->mt76, control->sta, wcid, skb);
  40. }
  41. EXPORT_SYMBOL_GPL(mt76x2_tx);
  42. int mt76x2_insert_hdr_pad(struct sk_buff *skb)
  43. {
  44. int len = ieee80211_get_hdrlen_from_skb(skb);
  45. if (len % 4 == 0)
  46. return 0;
  47. skb_push(skb, 2);
  48. memmove(skb->data, skb->data + 2, len);
  49. skb->data[len] = 0;
  50. skb->data[len + 1] = 0;
  51. return 2;
  52. }
  53. EXPORT_SYMBOL_GPL(mt76x2_insert_hdr_pad);
  54. s8 mt76x2_tx_get_max_txpwr_adj(struct mt76x2_dev *dev,
  55. const struct ieee80211_tx_rate *rate)
  56. {
  57. s8 max_txpwr;
  58. if (rate->flags & IEEE80211_TX_RC_VHT_MCS) {
  59. u8 mcs = ieee80211_rate_get_vht_mcs(rate);
  60. if (mcs == 8 || mcs == 9) {
  61. max_txpwr = dev->rate_power.vht[8];
  62. } else {
  63. u8 nss, idx;
  64. nss = ieee80211_rate_get_vht_nss(rate);
  65. idx = ((nss - 1) << 3) + mcs;
  66. max_txpwr = dev->rate_power.ht[idx & 0xf];
  67. }
  68. } else if (rate->flags & IEEE80211_TX_RC_MCS) {
  69. max_txpwr = dev->rate_power.ht[rate->idx & 0xf];
  70. } else {
  71. enum nl80211_band band = dev->mt76.chandef.chan->band;
  72. if (band == NL80211_BAND_2GHZ) {
  73. const struct ieee80211_rate *r;
  74. struct wiphy *wiphy = mt76_hw(dev)->wiphy;
  75. struct mt76_rate_power *rp = &dev->rate_power;
  76. r = &wiphy->bands[band]->bitrates[rate->idx];
  77. if (r->flags & IEEE80211_RATE_SHORT_PREAMBLE)
  78. max_txpwr = rp->cck[r->hw_value & 0x3];
  79. else
  80. max_txpwr = rp->ofdm[r->hw_value & 0x7];
  81. } else {
  82. max_txpwr = dev->rate_power.ofdm[rate->idx & 0x7];
  83. }
  84. }
  85. return max_txpwr;
  86. }
  87. EXPORT_SYMBOL_GPL(mt76x2_tx_get_max_txpwr_adj);
  88. s8 mt76x2_tx_get_txpwr_adj(struct mt76x2_dev *dev, s8 txpwr, s8 max_txpwr_adj)
  89. {
  90. txpwr = min_t(s8, txpwr, dev->txpower_conf);
  91. txpwr -= (dev->target_power + dev->target_power_delta[0]);
  92. txpwr = min_t(s8, txpwr, max_txpwr_adj);
  93. if (!dev->enable_tpc)
  94. return 0;
  95. else if (txpwr >= 0)
  96. return min_t(s8, txpwr, 7);
  97. else
  98. return (txpwr < -16) ? 8 : (txpwr + 32) / 2;
  99. }
  100. EXPORT_SYMBOL_GPL(mt76x2_tx_get_txpwr_adj);
  101. void mt76x2_tx_set_txpwr_auto(struct mt76x2_dev *dev, s8 txpwr)
  102. {
  103. s8 txpwr_adj;
  104. txpwr_adj = mt76x2_tx_get_txpwr_adj(dev, txpwr,
  105. dev->rate_power.ofdm[4]);
  106. mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
  107. MT_PROT_AUTO_TX_CFG_PROT_PADJ, txpwr_adj);
  108. mt76_rmw_field(dev, MT_PROT_AUTO_TX_CFG,
  109. MT_PROT_AUTO_TX_CFG_AUTO_PADJ, txpwr_adj);
  110. }
  111. EXPORT_SYMBOL_GPL(mt76x2_tx_set_txpwr_auto);
  112. void mt76x2_tx_complete(struct mt76x2_dev *dev, struct sk_buff *skb)
  113. {
  114. struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
  115. if (info->flags & IEEE80211_TX_CTL_AMPDU) {
  116. ieee80211_free_txskb(mt76_hw(dev), skb);
  117. } else {
  118. ieee80211_tx_info_clear_status(info);
  119. info->status.rates[0].idx = -1;
  120. info->flags |= IEEE80211_TX_STAT_ACK;
  121. ieee80211_tx_status(mt76_hw(dev), skb);
  122. }
  123. }
  124. EXPORT_SYMBOL_GPL(mt76x2_tx_complete);