aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-12-21 16:52:10 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-01-29 15:58:44 -0500
commit29701e5abf155d76fc8ab785a172c4ccf6cf47ee (patch)
treebdf9e9d5582a7754b124439b7674d56302918a6e /drivers/net/wireless/p54
parenta15bd00543a859a72546e4b09342b70e79e9ef1e (diff)
p54: enable proper frame injection
This patch enables frame injection in monitor mode for all p54 devices. As a result, any user can finally use the aircrack-ng suite out of the box. e.g: aireplay-ng --test wlan0 Trying broadcast probe requests... Injection is working! Found 1 AP Trying directed probe requests... XX:XX:XX:XX:XX:XX - channel: i - 'SSID' Ping (min/avg/max): 1.536ms/3.193ms/4.377ms Power: 193.00 30/30: 100% Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r--drivers/net/wireless/p54/p54common.c95
1 files changed, 69 insertions, 26 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 3298cb464f7..28d98338957 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -775,9 +775,16 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
775 priv->tx_stats[entry_data->hw_queue].len--; 775 priv->tx_stats[entry_data->hw_queue].len--;
776 priv->stats.dot11ACKFailureCount += payload->tries - 1; 776 priv->stats.dot11ACKFailureCount += payload->tries - 1;
777 777
778 if (unlikely(entry == priv->cached_beacon)) { 778 /*
779 * Frames in P54_QUEUE_FWSCAN and P54_QUEUE_BEACON are
780 * generated by the driver. Therefore tx_status is bogus
781 * and we don't want to confuse the mac80211 stack.
782 */
783 if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
784 if (entry_data->hw_queue == P54_QUEUE_BEACON)
785 priv->cached_beacon = NULL;
786
779 kfree_skb(entry); 787 kfree_skb(entry);
780 priv->cached_beacon = NULL;
781 goto out; 788 goto out;
782 } 789 }
783 790
@@ -1240,33 +1247,26 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
1240{ 1247{
1241 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 1248 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1242 struct p54_common *priv = dev->priv; 1249 struct p54_common *priv = dev->priv;
1243 int ret = 0; 1250 int ret = 1;
1244
1245 if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
1246 if (ieee80211_is_beacon(hdr->frame_control)) {
1247 *aid = 0;
1248 *queue = P54_QUEUE_BEACON;
1249 *extra_len = IEEE80211_MAX_TIM_LEN;
1250 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
1251 return 0;
1252 } else if (ieee80211_is_probe_resp(hdr->frame_control)) {
1253 *aid = 0;
1254 *queue = P54_QUEUE_MGMT;
1255 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
1256 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
1257 return 0;
1258 } else {
1259 *queue = P54_QUEUE_MGMT;
1260 ret = 0;
1261 }
1262 } else {
1263 *queue += P54_QUEUE_DATA;
1264 ret = 1;
1265 }
1266 1251
1267 switch (priv->mode) { 1252 switch (priv->mode) {
1253 case NL80211_IFTYPE_MONITOR:
1254 /*
1255 * We have to set P54_HDR_FLAG_DATA_OUT_PROMISC for
1256 * every frame in promiscuous/monitor mode.
1257 * see STSW45x0C LMAC API - page 12.
1258 */
1259 *aid = 0;
1260 *flags = P54_HDR_FLAG_DATA_OUT_PROMISC;
1261 *queue += P54_QUEUE_DATA;
1262 break;
1268 case NL80211_IFTYPE_STATION: 1263 case NL80211_IFTYPE_STATION:
1269 *aid = 1; 1264 *aid = 1;
1265 if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
1266 *queue = P54_QUEUE_MGMT;
1267 ret = 0;
1268 } else
1269 *queue += P54_QUEUE_DATA;
1270 break; 1270 break;
1271 case NL80211_IFTYPE_AP: 1271 case NL80211_IFTYPE_AP:
1272 case NL80211_IFTYPE_ADHOC: 1272 case NL80211_IFTYPE_ADHOC:
@@ -1276,10 +1276,44 @@ static int p54_tx_fill(struct ieee80211_hw *dev, struct sk_buff *skb,
1276 *queue = P54_QUEUE_CAB; 1276 *queue = P54_QUEUE_CAB;
1277 return 0; 1277 return 0;
1278 } 1278 }
1279
1280 if (unlikely(ieee80211_is_mgmt(hdr->frame_control))) {
1281 if (ieee80211_is_probe_resp(hdr->frame_control)) {
1282 *aid = 0;
1283 *queue = P54_QUEUE_MGMT;
1284 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP |
1285 P54_HDR_FLAG_DATA_OUT_NOCANCEL;
1286 return 0;
1287 } else if (ieee80211_is_beacon(hdr->frame_control)) {
1288 *aid = 0;
1289
1290 if (info->flags & IEEE80211_TX_CTL_INJECTED) {
1291 /*
1292 * Injecting beacons on top of a AP is
1293 * not a good idea... nevertheless,
1294 * it should be doable.
1295 */
1296
1297 *queue += P54_QUEUE_DATA;
1298 return 1;
1299 }
1300
1301 *flags = P54_HDR_FLAG_DATA_OUT_TIMESTAMP;
1302 *queue = P54_QUEUE_BEACON;
1303 *extra_len = IEEE80211_MAX_TIM_LEN;
1304 return 0;
1305 } else {
1306 *queue = P54_QUEUE_MGMT;
1307 ret = 0;
1308 }
1309 } else
1310 *queue += P54_QUEUE_DATA;
1311
1279 if (info->control.sta) 1312 if (info->control.sta)
1280 *aid = info->control.sta->aid; 1313 *aid = info->control.sta->aid;
1281 else 1314 else
1282 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL; 1315 *flags |= P54_HDR_FLAG_DATA_OUT_NOCANCEL;
1316 break;
1283 } 1317 }
1284 return ret; 1318 return ret;
1285} 1319}
@@ -1497,11 +1531,20 @@ static int p54_setup_mac(struct ieee80211_hw *dev)
1497 case NL80211_IFTYPE_MESH_POINT: 1531 case NL80211_IFTYPE_MESH_POINT:
1498 mode = P54_FILTER_TYPE_IBSS; 1532 mode = P54_FILTER_TYPE_IBSS;
1499 break; 1533 break;
1534 case NL80211_IFTYPE_MONITOR:
1535 mode = P54_FILTER_TYPE_PROMISCUOUS;
1536 break;
1500 default: 1537 default:
1501 mode = P54_FILTER_TYPE_NONE; 1538 mode = P54_FILTER_TYPE_NONE;
1502 break; 1539 break;
1503 } 1540 }
1504 if (priv->filter_flags & FIF_PROMISC_IN_BSS) 1541
1542 /*
1543 * "TRANSPARENT and PROMISCUOUS are mutually exclusive"
1544 * STSW45X0C LMAC API - page 12
1545 */
1546 if ((priv->filter_flags & FIF_PROMISC_IN_BSS) &&
1547 (mode != P54_FILTER_TYPE_PROMISCUOUS))
1505 mode |= P54_FILTER_TYPE_TRANSPARENT; 1548 mode |= P54_FILTER_TYPE_TRANSPARENT;
1506 } else 1549 } else
1507 mode = P54_FILTER_TYPE_RX_DISABLED; 1550 mode = P54_FILTER_TYPE_RX_DISABLED;