developer | 20d6771 | 2022-03-02 14:09:32 +0800 | [diff] [blame] | 1 | From 323105f9f7d5057ffb445948318525f81b76506c Mon Sep 17 00:00:00 2001 |
| 2 | From: Shayne Chen <shayne.chen@mediatek.com> |
| 3 | Date: Tue, 11 May 2021 10:24:46 +0800 |
| 4 | Subject: [PATCH 1108/1112] mt76: testmode: rework the flow of init tx skb |
| 5 | |
| 6 | This is the preparation for supporting virtual stations in testmode. |
| 7 | |
| 8 | Signed-off-by: Shayne Chen <shayne.chen@mediatek.com> |
| 9 | --- |
| 10 | drivers/net/wireless/mediatek/mt76/mt76.h | 3 +- |
| 11 | .../wireless/mediatek/mt76/mt7915/testmode.c | 2 +- |
| 12 | drivers/net/wireless/mediatek/mt76/testmode.c | 73 +++++++++++++++---- |
| 13 | 3 files changed, 61 insertions(+), 17 deletions(-) |
| 14 | |
| 15 | diff --git a/mt76.h b/mt76.h |
| 16 | index ce4a098..b5f1367 100644 |
| 17 | --- a/mt76.h |
| 18 | +++ b/mt76.h |
| 19 | @@ -1289,7 +1289,7 @@ int mt76_testmode_cmd(struct ieee80211_hw *hw, struct ieee80211_vif *vif, |
| 20 | int mt76_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb, |
| 21 | struct netlink_callback *cb, void *data, int len); |
| 22 | int mt76_testmode_set_state(struct mt76_phy *phy, enum mt76_testmode_state state); |
| 23 | -int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len); |
| 24 | +int mt76_testmode_init_skb(struct mt76_phy *phy, u32 len, u8 aid, struct sk_buff **skb); |
| 25 | |
| 26 | static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) |
| 27 | { |
| 28 | @@ -1303,7 +1303,6 @@ static inline void mt76_testmode_reset(struct mt76_phy *phy, bool disable) |
| 29 | #endif |
| 30 | } |
| 31 | |
| 32 | - |
| 33 | /* internal */ |
| 34 | static inline struct ieee80211_hw * |
| 35 | mt76_tx_status_get_hw(struct mt76_dev *dev, struct sk_buff *skb) |
| 36 | diff --git a/mt7915/testmode.c b/mt7915/testmode.c |
| 37 | index 08bb700..054829e 100644 |
| 38 | --- a/mt7915/testmode.c |
| 39 | +++ b/mt7915/testmode.c |
| 40 | @@ -431,7 +431,7 @@ mt7915_tm_set_tx_len(struct mt7915_phy *phy, u32 tx_time) |
| 41 | bitrate = cfg80211_calculate_bitrate(&rate); |
| 42 | tx_len = bitrate * tx_time / 10 / 8; |
| 43 | |
| 44 | - ret = mt76_testmode_alloc_skb(phy->mt76, tx_len); |
| 45 | + ret = mt76_testmode_init_skb(phy->mt76, tx_len, 0, &td->tx_skb); |
| 46 | if (ret) |
| 47 | return ret; |
| 48 | |
| 49 | diff --git a/testmode.c b/testmode.c |
| 50 | index bb15388..0f93338 100644 |
| 51 | --- a/testmode.c |
| 52 | +++ b/testmode.c |
| 53 | @@ -87,15 +87,34 @@ mt76_testmode_max_mpdu_len(struct mt76_phy *phy, u8 tx_rate_mode) |
| 54 | } |
| 55 | |
| 56 | static void |
| 57 | -mt76_testmode_free_skb(struct mt76_phy *phy) |
| 58 | +mt76_testmode_free_skb(struct sk_buff **tx_skb) |
| 59 | +{ |
| 60 | + dev_kfree_skb(*tx_skb); |
| 61 | + *tx_skb = NULL; |
| 62 | +} |
| 63 | + |
| 64 | +static void |
| 65 | +mt76_testmode_free_skb_all(struct mt76_phy *phy) |
| 66 | { |
| 67 | struct mt76_testmode_data *td = &phy->test; |
| 68 | |
| 69 | - dev_kfree_skb(td->tx_skb); |
| 70 | - td->tx_skb = NULL; |
| 71 | + if (mt76_testmode_has_sta(phy)) { |
| 72 | + struct mt76_testmode_sta *tm_sta; |
| 73 | + int i; |
| 74 | + |
| 75 | + mt76_testmode_for_each_sta(phy, i, tm_sta) { |
| 76 | + mt76_testmode_free_skb(&tm_sta->tx_skb); |
| 77 | + } |
| 78 | + |
| 79 | + return; |
| 80 | + } |
| 81 | + |
| 82 | + mt76_testmode_free_skb(&td->tx_skb); |
| 83 | } |
| 84 | |
| 85 | -int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) |
| 86 | +static int |
| 87 | +mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len, |
| 88 | + struct sk_buff **tx_skb, u8 *da) |
| 89 | { |
| 90 | #define MT_TXP_MAX_LEN 4095 |
| 91 | u16 fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA | |
| 92 | @@ -128,7 +147,9 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) |
| 93 | hdr->frame_control = cpu_to_le16(fc); |
| 94 | memcpy(hdr->addr1, td->addr[0], ETH_ALEN); |
| 95 | memcpy(hdr->addr2, td->addr[1], ETH_ALEN); |
| 96 | - memcpy(hdr->addr3, td->addr[2], ETH_ALEN); |
| 97 | + /* memcpy(hdr->addr3, td->addr[2], ETH_ALEN); */ |
| 98 | + memcpy(hdr->addr3, da, ETH_ALEN); |
| 99 | + |
| 100 | skb_set_queue_mapping(head, IEEE80211_AC_BE); |
| 101 | |
| 102 | info = IEEE80211_SKB_CB(head); |
| 103 | @@ -152,7 +173,7 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) |
| 104 | |
| 105 | frag = alloc_skb(frag_len, GFP_KERNEL); |
| 106 | if (!frag) { |
| 107 | - mt76_testmode_free_skb(phy); |
| 108 | + mt76_testmode_free_skb(tx_skb); |
| 109 | dev_kfree_skb(head); |
| 110 | return -ENOMEM; |
| 111 | } |
| 112 | @@ -165,23 +186,25 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len) |
| 113 | frag_tail = &(*frag_tail)->next; |
| 114 | } |
| 115 | |
| 116 | - mt76_testmode_free_skb(phy); |
| 117 | - td->tx_skb = head; |
| 118 | + mt76_testmode_free_skb(tx_skb); |
| 119 | + *tx_skb = head; |
| 120 | |
| 121 | return 0; |
| 122 | } |
| 123 | -EXPORT_SYMBOL(mt76_testmode_alloc_skb); |
| 124 | |
| 125 | -static int |
| 126 | -mt76_testmode_tx_init(struct mt76_phy *phy) |
| 127 | +int mt76_testmode_init_skb(struct mt76_phy *phy, u32 len, u8 aid, |
| 128 | + struct sk_buff **tx_skb) |
| 129 | { |
| 130 | struct mt76_testmode_data *td = &phy->test; |
| 131 | struct ieee80211_tx_info *info; |
| 132 | struct ieee80211_tx_rate *rate; |
| 133 | u8 max_nss = hweight8(phy->antenna_mask); |
| 134 | + u8 da[ETH_ALEN]; |
| 135 | int ret; |
| 136 | |
| 137 | - ret = mt76_testmode_alloc_skb(phy, td->tx_mpdu_len); |
| 138 | + ether_addr_copy(da, phy->macaddr); |
| 139 | + da[0] += aid * 4; |
| 140 | + ret = mt76_testmode_alloc_skb(phy, len, tx_skb, da); |
| 141 | if (ret) |
| 142 | return ret; |
| 143 | |
| 144 | @@ -191,7 +214,7 @@ mt76_testmode_tx_init(struct mt76_phy *phy) |
| 145 | if (td->tx_antenna_mask) |
| 146 | max_nss = min_t(u8, max_nss, hweight8(td->tx_antenna_mask)); |
| 147 | |
| 148 | - info = IEEE80211_SKB_CB(td->tx_skb); |
| 149 | + info = IEEE80211_SKB_CB(*tx_skb); |
| 150 | rate = &info->control.rates[0]; |
| 151 | rate->count = 1; |
| 152 | rate->idx = td->tx_rate_idx; |
| 153 | @@ -263,6 +286,28 @@ mt76_testmode_tx_init(struct mt76_phy *phy) |
| 154 | out: |
| 155 | return 0; |
| 156 | } |
| 157 | +EXPORT_SYMBOL(mt76_testmode_init_skb); |
| 158 | + |
| 159 | +static int |
| 160 | +mt76_testmode_tx_init(struct mt76_phy *phy) |
| 161 | +{ |
| 162 | + struct mt76_testmode_data *td = &phy->test; |
| 163 | + struct mt76_testmode_sta *tm_sta; |
| 164 | + int ret, i; |
| 165 | + |
| 166 | + if (!mt76_testmode_has_sta(phy)) |
| 167 | + return mt76_testmode_init_skb(phy, td->tx_mpdu_len, |
| 168 | + 0, &td->tx_skb); |
| 169 | + |
| 170 | + mt76_testmode_for_each_sta(phy, i, tm_sta) { |
| 171 | + ret = mt76_testmode_init_skb(phy, tm_sta->sd.tx_mpdu_len, |
| 172 | + tm_sta->sd.aid, &tm_sta->tx_skb); |
| 173 | + if (ret) |
| 174 | + return ret; |
| 175 | + } |
| 176 | + |
| 177 | + return 0; |
| 178 | +} |
| 179 | |
| 180 | static void |
| 181 | mt76_testmode_tx_start(struct mt76_phy *phy) |
| 182 | @@ -291,7 +336,7 @@ mt76_testmode_tx_stop(struct mt76_phy *phy) |
| 183 | wait_event_timeout(dev->tx_wait, td->tx_done == td->tx_queued, |
| 184 | MT76_TM_TIMEOUT * HZ); |
| 185 | |
| 186 | - mt76_testmode_free_skb(phy); |
| 187 | + mt76_testmode_free_skb_all(phy); |
| 188 | } |
| 189 | |
| 190 | static inline void |
| 191 | -- |
| 192 | 2.25.1 |
| 193 | |