aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rt2x00/rt2x00dev.c
diff options
context:
space:
mode:
authorIvo van Doorn <ivdoorn@gmail.com>2009-04-26 10:09:32 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-05-06 15:14:50 -0400
commit35f00cfcc06bb85e0659f9847400518008d78145 (patch)
treedccebd4dd7cde975d857d1fb3f28dd1e467fa72f /drivers/net/wireless/rt2x00/rt2x00dev.c
parent9f1661718c7fcf82e25c6aed20b729ee372d9d65 (diff)
rt2x00: Implement support for 802.11n
Extend rt2x00lib capabilities to support 802.11n, it still lacks aggregation support, but that can be added in the future. Signed-off-by: Ivo van Doorn <IvDoorn@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rt2x00/rt2x00dev.c')
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c92
1 files changed, 67 insertions, 25 deletions
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index e15086af7278..f2270845072a 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -323,19 +323,54 @@ void rt2x00lib_txdone(struct queue_entry *entry,
323} 323}
324EXPORT_SYMBOL_GPL(rt2x00lib_txdone); 324EXPORT_SYMBOL_GPL(rt2x00lib_txdone);
325 325
326static int rt2x00lib_rxdone_read_signal(struct rt2x00_dev *rt2x00dev,
327 struct rxdone_entry_desc *rxdesc)
328{
329 struct ieee80211_supported_band *sband;
330 const struct rt2x00_rate *rate;
331 unsigned int i;
332 int signal;
333 int type;
334
335 /*
336 * For non-HT rates the MCS value needs to contain the
337 * actually used rate modulation (CCK or OFDM).
338 */
339 if (rxdesc->dev_flags & RXDONE_SIGNAL_MCS)
340 signal = RATE_MCS(rxdesc->rate_mode, rxdesc->signal);
341 else
342 signal = rxdesc->signal;
343
344 type = (rxdesc->dev_flags & RXDONE_SIGNAL_MASK);
345
346 sband = &rt2x00dev->bands[rt2x00dev->curr_band];
347 for (i = 0; i < sband->n_bitrates; i++) {
348 rate = rt2x00_get_rate(sband->bitrates[i].hw_value);
349
350 if (((type == RXDONE_SIGNAL_PLCP) &&
351 (rate->plcp == signal)) ||
352 ((type == RXDONE_SIGNAL_BITRATE) &&
353 (rate->bitrate == signal)) ||
354 ((type == RXDONE_SIGNAL_MCS) &&
355 (rate->mcs == signal))) {
356 return i;
357 }
358 }
359
360 WARNING(rt2x00dev, "Frame received with unrecognized signal, "
361 "signal=0x%.4x, type=%d.\n", signal, type);
362 return 0;
363}
364
326void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, 365void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
327 struct queue_entry *entry) 366 struct queue_entry *entry)
328{ 367{
329 struct rxdone_entry_desc rxdesc; 368 struct rxdone_entry_desc rxdesc;
330 struct sk_buff *skb; 369 struct sk_buff *skb;
331 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; 370 struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status;
332 struct ieee80211_supported_band *sband;
333 const struct rt2x00_rate *rate;
334 unsigned int header_length; 371 unsigned int header_length;
335 bool l2pad; 372 bool l2pad;
336 unsigned int i; 373 int rate_idx;
337 int idx = -1;
338
339 /* 374 /*
340 * Allocate a new sk_buffer. If no new buffer available, drop the 375 * Allocate a new sk_buffer. If no new buffer available, drop the
341 * received frame and reuse the existing buffer. 376 * received frame and reuse the existing buffer.
@@ -379,26 +414,17 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
379 rt2x00queue_payload_align(entry->skb, l2pad, header_length); 414 rt2x00queue_payload_align(entry->skb, l2pad, header_length);
380 415
381 /* 416 /*
382 * Update RX statistics. 417 * Check if the frame was received using HT. In that case,
418 * the rate is the MCS index and should be passed to mac80211
419 * directly. Otherwise we need to translate the signal to
420 * the correct bitrate index.
383 */ 421 */
384 sband = &rt2x00dev->bands[rt2x00dev->curr_band]; 422 if (rxdesc.rate_mode == RATE_MODE_CCK ||
385 for (i = 0; i < sband->n_bitrates; i++) { 423 rxdesc.rate_mode == RATE_MODE_OFDM) {
386 rate = rt2x00_get_rate(sband->bitrates[i].hw_value); 424 rate_idx = rt2x00lib_rxdone_read_signal(rt2x00dev, &rxdesc);
387 425 } else {
388 if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && 426 rxdesc.flags |= RX_FLAG_HT;
389 (rate->plcp == rxdesc.signal)) || 427 rate_idx = rxdesc.signal;
390 ((rxdesc.dev_flags & RXDONE_SIGNAL_BITRATE) &&
391 (rate->bitrate == rxdesc.signal))) {
392 idx = i;
393 break;
394 }
395 }
396
397 if (idx < 0) {
398 WARNING(rt2x00dev, "Frame received with unrecognized signal,"
399 "signal=0x%.2x, type=%d.\n", rxdesc.signal,
400 (rxdesc.dev_flags & RXDONE_SIGNAL_MASK));
401 idx = 0;
402 } 428 }
403 429
404 /* 430 /*
@@ -408,7 +434,7 @@ void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev,
408 rt2x00debug_update_crypto(rt2x00dev, &rxdesc); 434 rt2x00debug_update_crypto(rt2x00dev, &rxdesc);
409 435
410 rx_status->mactime = rxdesc.timestamp; 436 rx_status->mactime = rxdesc.timestamp;
411 rx_status->rate_idx = idx; 437 rx_status->rate_idx = rate_idx;
412 rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi); 438 rx_status->qual = rt2x00link_calculate_signal(rt2x00dev, rxdesc.rssi);
413 rx_status->signal = rxdesc.rssi; 439 rx_status->signal = rxdesc.rssi;
414 rx_status->noise = rxdesc.noise; 440 rx_status->noise = rxdesc.noise;
@@ -443,72 +469,84 @@ const struct rt2x00_rate rt2x00_supported_rates[12] = {
443 .bitrate = 10, 469 .bitrate = 10,
444 .ratemask = BIT(0), 470 .ratemask = BIT(0),
445 .plcp = 0x00, 471 .plcp = 0x00,
472 .mcs = RATE_MCS(RATE_MODE_CCK, 0),
446 }, 473 },
447 { 474 {
448 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 475 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
449 .bitrate = 20, 476 .bitrate = 20,
450 .ratemask = BIT(1), 477 .ratemask = BIT(1),
451 .plcp = 0x01, 478 .plcp = 0x01,
479 .mcs = RATE_MCS(RATE_MODE_CCK, 1),
452 }, 480 },
453 { 481 {
454 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 482 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
455 .bitrate = 55, 483 .bitrate = 55,
456 .ratemask = BIT(2), 484 .ratemask = BIT(2),
457 .plcp = 0x02, 485 .plcp = 0x02,
486 .mcs = RATE_MCS(RATE_MODE_CCK, 2),
458 }, 487 },
459 { 488 {
460 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE, 489 .flags = DEV_RATE_CCK | DEV_RATE_SHORT_PREAMBLE,
461 .bitrate = 110, 490 .bitrate = 110,
462 .ratemask = BIT(3), 491 .ratemask = BIT(3),
463 .plcp = 0x03, 492 .plcp = 0x03,
493 .mcs = RATE_MCS(RATE_MODE_CCK, 3),
464 }, 494 },
465 { 495 {
466 .flags = DEV_RATE_OFDM, 496 .flags = DEV_RATE_OFDM,
467 .bitrate = 60, 497 .bitrate = 60,
468 .ratemask = BIT(4), 498 .ratemask = BIT(4),
469 .plcp = 0x0b, 499 .plcp = 0x0b,
500 .mcs = RATE_MCS(RATE_MODE_OFDM, 0),
470 }, 501 },
471 { 502 {
472 .flags = DEV_RATE_OFDM, 503 .flags = DEV_RATE_OFDM,
473 .bitrate = 90, 504 .bitrate = 90,
474 .ratemask = BIT(5), 505 .ratemask = BIT(5),
475 .plcp = 0x0f, 506 .plcp = 0x0f,
507 .mcs = RATE_MCS(RATE_MODE_OFDM, 1),
476 }, 508 },
477 { 509 {
478 .flags = DEV_RATE_OFDM, 510 .flags = DEV_RATE_OFDM,
479 .bitrate = 120, 511 .bitrate = 120,
480 .ratemask = BIT(6), 512 .ratemask = BIT(6),
481 .plcp = 0x0a, 513 .plcp = 0x0a,
514 .mcs = RATE_MCS(RATE_MODE_OFDM, 2),
482 }, 515 },
483 { 516 {
484 .flags = DEV_RATE_OFDM, 517 .flags = DEV_RATE_OFDM,
485 .bitrate = 180, 518 .bitrate = 180,
486 .ratemask = BIT(7), 519 .ratemask = BIT(7),
487 .plcp = 0x0e, 520 .plcp = 0x0e,
521 .mcs = RATE_MCS(RATE_MODE_OFDM, 3),
488 }, 522 },
489 { 523 {
490 .flags = DEV_RATE_OFDM, 524 .flags = DEV_RATE_OFDM,
491 .bitrate = 240, 525 .bitrate = 240,
492 .ratemask = BIT(8), 526 .ratemask = BIT(8),
493 .plcp = 0x09, 527 .plcp = 0x09,
528 .mcs = RATE_MCS(RATE_MODE_OFDM, 4),
494 }, 529 },
495 { 530 {
496 .flags = DEV_RATE_OFDM, 531 .flags = DEV_RATE_OFDM,
497 .bitrate = 360, 532 .bitrate = 360,
498 .ratemask = BIT(9), 533 .ratemask = BIT(9),
499 .plcp = 0x0d, 534 .plcp = 0x0d,
535 .mcs = RATE_MCS(RATE_MODE_OFDM, 5),
500 }, 536 },
501 { 537 {
502 .flags = DEV_RATE_OFDM, 538 .flags = DEV_RATE_OFDM,
503 .bitrate = 480, 539 .bitrate = 480,
504 .ratemask = BIT(10), 540 .ratemask = BIT(10),
505 .plcp = 0x08, 541 .plcp = 0x08,
542 .mcs = RATE_MCS(RATE_MODE_OFDM, 6),
506 }, 543 },
507 { 544 {
508 .flags = DEV_RATE_OFDM, 545 .flags = DEV_RATE_OFDM,
509 .bitrate = 540, 546 .bitrate = 540,
510 .ratemask = BIT(11), 547 .ratemask = BIT(11),
511 .plcp = 0x0c, 548 .plcp = 0x0c,
549 .mcs = RATE_MCS(RATE_MODE_OFDM, 7),
512 }, 550 },
513}; 551};
514 552
@@ -584,6 +622,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
584 rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates; 622 rt2x00dev->bands[IEEE80211_BAND_2GHZ].bitrates = rates;
585 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = 623 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
586 &rt2x00dev->bands[IEEE80211_BAND_2GHZ]; 624 &rt2x00dev->bands[IEEE80211_BAND_2GHZ];
625 memcpy(&rt2x00dev->bands[IEEE80211_BAND_2GHZ].ht_cap,
626 &spec->ht, sizeof(spec->ht));
587 } 627 }
588 628
589 /* 629 /*
@@ -600,6 +640,8 @@ static int rt2x00lib_probe_hw_modes(struct rt2x00_dev *rt2x00dev,
600 rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4]; 640 rt2x00dev->bands[IEEE80211_BAND_5GHZ].bitrates = &rates[4];
601 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = 641 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
602 &rt2x00dev->bands[IEEE80211_BAND_5GHZ]; 642 &rt2x00dev->bands[IEEE80211_BAND_5GHZ];
643 memcpy(&rt2x00dev->bands[IEEE80211_BAND_5GHZ].ht_cap,
644 &spec->ht, sizeof(spec->ht));
603 } 645 }
604 646
605 return 0; 647 return 0;