aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/p54')
-rw-r--r--drivers/net/wireless/p54/Kconfig29
-rw-r--r--drivers/net/wireless/p54/eeprom.c236
-rw-r--r--drivers/net/wireless/p54/eeprom.h7
-rw-r--r--drivers/net/wireless/p54/fwio.c58
-rw-r--r--drivers/net/wireless/p54/lmac.h4
-rw-r--r--drivers/net/wireless/p54/main.c103
-rw-r--r--drivers/net/wireless/p54/p54.h9
-rw-r--r--drivers/net/wireless/p54/p54pci.c17
-rw-r--r--drivers/net/wireless/p54/p54spi.c14
-rw-r--r--drivers/net/wireless/p54/p54spi_eeprom.h9
-rw-r--r--drivers/net/wireless/p54/p54usb.c27
-rw-r--r--drivers/net/wireless/p54/txrx.c48
12 files changed, 448 insertions, 113 deletions
diff --git a/drivers/net/wireless/p54/Kconfig b/drivers/net/wireless/p54/Kconfig
index b0342a520bf1..0ec55b50798e 100644
--- a/drivers/net/wireless/p54/Kconfig
+++ b/drivers/net/wireless/p54/Kconfig
@@ -2,13 +2,14 @@ config P54_COMMON
2 tristate "Softmac Prism54 support" 2 tristate "Softmac Prism54 support"
3 depends on MAC80211 && EXPERIMENTAL 3 depends on MAC80211 && EXPERIMENTAL
4 select FW_LOADER 4 select FW_LOADER
5 select CRC_CCITT
5 ---help--- 6 ---help---
6 This is common code for isl38xx/stlc45xx based modules. 7 This is common code for isl38xx/stlc45xx based modules.
7 This module does nothing by itself - the USB/PCI/SPI front-ends 8 This module does nothing by itself - the USB/PCI/SPI front-ends
8 also need to be enabled in order to support any devices. 9 also need to be enabled in order to support any devices.
9 10
10 These devices require softmac firmware which can be found at 11 These devices require softmac firmware which can be found at
11 http://prism54.org/ 12 <http://wireless.kernel.org/en/users/Drivers/p54>
12 13
13 If you choose to build a module, it'll be called p54common. 14 If you choose to build a module, it'll be called p54common.
14 15
@@ -20,7 +21,7 @@ config P54_USB
20 This driver is for USB isl38xx based wireless cards. 21 This driver is for USB isl38xx based wireless cards.
21 22
22 These devices require softmac firmware which can be found at 23 These devices require softmac firmware which can be found at
23 http://prism54.org/ 24 <http://wireless.kernel.org/en/users/Drivers/p54>
24 25
25 If you choose to build a module, it'll be called p54usb. 26 If you choose to build a module, it'll be called p54usb.
26 27
@@ -34,7 +35,7 @@ config P54_PCI
34 supported by the fullmac driver/firmware. 35 supported by the fullmac driver/firmware.
35 36
36 This driver requires softmac firmware which can be found at 37 This driver requires softmac firmware which can be found at
37 http://prism54.org/ 38 <http://wireless.kernel.org/en/users/Drivers/p54>
38 39
39 If you choose to build a module, it'll be called p54pci. 40 If you choose to build a module, it'll be called p54pci.
40 41
@@ -42,12 +43,28 @@ config P54_SPI
42 tristate "Prism54 SPI (stlc45xx) support" 43 tristate "Prism54 SPI (stlc45xx) support"
43 depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS 44 depends on P54_COMMON && SPI_MASTER && GENERIC_HARDIRQS
44 ---help--- 45 ---help---
45 This driver is for stlc4550 or stlc4560 based wireless chips. 46 This driver is for stlc4550 or stlc4560 based wireless chips
46 This driver is experimental, untested and will probably only work on 47 such as Nokia's N800/N810 Portable Internet Tablet.
47 Nokia's N800/N810 Portable Internet Tablet.
48 48
49 If you choose to build a module, it'll be called p54spi. 49 If you choose to build a module, it'll be called p54spi.
50 50
51config P54_SPI_DEFAULT_EEPROM
52 bool "Include fallback EEPROM blob"
53 depends on P54_SPI
54 default n
55 ---help---
56 Unlike the PCI or USB devices, the SPI variants don't have
57 a dedicated EEPROM chip to store all device specific values
58 for calibration, country and interface settings.
59
60 The driver will try to load the image "3826.eeprom", if the
61 file is put at the right place. (usually /lib/firmware.)
62
63 Only if this request fails, this option will provide a
64 backup set of generic values to get the device working.
65
66 Enabling this option adds about 4k to p54spi.
67
51config P54_LEDS 68config P54_LEDS
52 bool 69 bool
53 depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON) 70 depends on P54_COMMON && MAC80211_LEDS && (LEDS_CLASS = y || LEDS_CLASS = P54_COMMON)
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index 78347041ec40..54cc0bba66b9 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -23,6 +23,7 @@
23#include <linux/slab.h> 23#include <linux/slab.h>
24 24
25#include <net/mac80211.h> 25#include <net/mac80211.h>
26#include <linux/crc-ccitt.h>
26 27
27#include "p54.h" 28#include "p54.h"
28#include "eeprom.h" 29#include "eeprom.h"
@@ -54,6 +55,17 @@ static struct ieee80211_rate p54_arates[] = {
54 { .bitrate = 540, .hw_value = 11, }, 55 { .bitrate = 540, .hw_value = 11, },
55}; 56};
56 57
58static struct p54_rssi_db_entry p54_rssi_default = {
59 /*
60 * The defaults are taken from usb-logs of the
61 * vendor driver. So, they should be safe to
62 * use in case we can't get a match from the
63 * rssi <-> dBm conversion database.
64 */
65 .mul = 130,
66 .add = -398,
67};
68
57#define CHAN_HAS_CAL BIT(0) 69#define CHAN_HAS_CAL BIT(0)
58#define CHAN_HAS_LIMIT BIT(1) 70#define CHAN_HAS_LIMIT BIT(1)
59#define CHAN_HAS_CURVE BIT(2) 71#define CHAN_HAS_CURVE BIT(2)
@@ -86,13 +98,27 @@ static int p54_get_band_from_freq(u16 freq)
86 return -1; 98 return -1;
87} 99}
88 100
101static int same_band(u16 freq, u16 freq2)
102{
103 return p54_get_band_from_freq(freq) == p54_get_band_from_freq(freq2);
104}
105
89static int p54_compare_channels(const void *_a, 106static int p54_compare_channels(const void *_a,
90 const void *_b) 107 const void *_b)
91{ 108{
92 const struct p54_channel_entry *a = _a; 109 const struct p54_channel_entry *a = _a;
93 const struct p54_channel_entry *b = _b; 110 const struct p54_channel_entry *b = _b;
94 111
95 return a->index - b->index; 112 return a->freq - b->freq;
113}
114
115static int p54_compare_rssichan(const void *_a,
116 const void *_b)
117{
118 const struct p54_rssi_db_entry *a = _a;
119 const struct p54_rssi_db_entry *b = _b;
120
121 return a->freq - b->freq;
96} 122}
97 123
98static int p54_fill_band_bitrates(struct ieee80211_hw *dev, 124static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
@@ -144,25 +170,26 @@ static int p54_generate_band(struct ieee80211_hw *dev,
144 170
145 for (i = 0, j = 0; (j < list->band_channel_num[band]) && 171 for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
146 (i < list->entries); i++) { 172 (i < list->entries); i++) {
173 struct p54_channel_entry *chan = &list->channels[i];
147 174
148 if (list->channels[i].band != band) 175 if (chan->band != band)
149 continue; 176 continue;
150 177
151 if (list->channels[i].data != CHAN_HAS_ALL) { 178 if (chan->data != CHAN_HAS_ALL) {
152 wiphy_err(dev->wiphy, 179 wiphy_err(dev->wiphy, "%s%s%s is/are missing for "
153 "%s%s%s is/are missing for channel:%d [%d MHz].\n", 180 "channel:%d [%d MHz].\n",
154 (list->channels[i].data & CHAN_HAS_CAL ? "" : 181 (chan->data & CHAN_HAS_CAL ? "" :
155 " [iqauto calibration data]"), 182 " [iqauto calibration data]"),
156 (list->channels[i].data & CHAN_HAS_LIMIT ? "" : 183 (chan->data & CHAN_HAS_LIMIT ? "" :
157 " [output power limits]"), 184 " [output power limits]"),
158 (list->channels[i].data & CHAN_HAS_CURVE ? "" : 185 (chan->data & CHAN_HAS_CURVE ? "" :
159 " [curve data]"), 186 " [curve data]"),
160 list->channels[i].index, list->channels[i].freq); 187 chan->index, chan->freq);
161 continue; 188 continue;
162 } 189 }
163 190
164 tmp->channels[j].band = list->channels[i].band; 191 tmp->channels[j].band = chan->band;
165 tmp->channels[j].center_freq = list->channels[i].freq; 192 tmp->channels[j].center_freq = chan->freq;
166 j++; 193 j++;
167 } 194 }
168 195
@@ -260,8 +287,10 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
260 list->max_entries = max_channel_num; 287 list->max_entries = max_channel_num;
261 list->channels = kzalloc(sizeof(struct p54_channel_entry) * 288 list->channels = kzalloc(sizeof(struct p54_channel_entry) *
262 max_channel_num, GFP_KERNEL); 289 max_channel_num, GFP_KERNEL);
263 if (!list->channels) 290 if (!list->channels) {
291 ret = -ENOMEM;
264 goto free; 292 goto free;
293 }
265 294
266 for (i = 0; i < max_channel_num; i++) { 295 for (i = 0; i < max_channel_num; i++) {
267 if (i < priv->iq_autocal_len) { 296 if (i < priv->iq_autocal_len) {
@@ -288,7 +317,7 @@ static int p54_generate_channel_lists(struct ieee80211_hw *dev)
288 } 317 }
289 } 318 }
290 319
291 /* sort the list by the channel index */ 320 /* sort the channel list by frequency */
292 sort(list->channels, list->entries, sizeof(struct p54_channel_entry), 321 sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
293 p54_compare_channels, NULL); 322 p54_compare_channels, NULL);
294 323
@@ -407,33 +436,121 @@ static int p54_convert_rev1(struct ieee80211_hw *dev,
407static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2", 436static const char *p54_rf_chips[] = { "INVALID-0", "Duette3", "Duette2",
408 "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" }; 437 "Frisbee", "Xbow", "Longbow", "INVALID-6", "INVALID-7" };
409 438
410static void p54_parse_rssical(struct ieee80211_hw *dev, void *data, int len, 439static int p54_parse_rssical(struct ieee80211_hw *dev,
411 u16 type) 440 u8 *data, int len, u16 type)
412{ 441{
413 struct p54_common *priv = dev->priv; 442 struct p54_common *priv = dev->priv;
414 int offset = (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) ? 2 : 0; 443 struct p54_rssi_db_entry *entry;
415 int entry_size = sizeof(struct pda_rssi_cal_entry) + offset; 444 size_t db_len, entries;
416 int num_entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2; 445 int offset = 0, i;
417 int i; 446
447 if (type != PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
448 entries = (type == PDR_RSSI_LINEAR_APPROXIMATION) ? 1 : 2;
449 if (len != sizeof(struct pda_rssi_cal_entry) * entries) {
450 wiphy_err(dev->wiphy, "rssical size mismatch.\n");
451 goto err_data;
452 }
453 } else {
454 /*
455 * Some devices (Dell 1450 USB, Xbow 5GHz card, etc...)
456 * have an empty two byte header.
457 */
458 if (*((__le16 *)&data[offset]) == cpu_to_le16(0))
459 offset += 2;
418 460
419 if (len != (entry_size * num_entries)) { 461 entries = (len - offset) /
420 wiphy_err(dev->wiphy, 462 sizeof(struct pda_rssi_cal_ext_entry);
421 "unknown rssi calibration data packing type:(%x) len:%d.\n",
422 type, len);
423 463
424 print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, 464 if ((len - offset) % sizeof(struct pda_rssi_cal_ext_entry) ||
425 data, len); 465 entries <= 0) {
466 wiphy_err(dev->wiphy, "invalid rssi database.\n");
467 goto err_data;
468 }
469 }
426 470
427 wiphy_err(dev->wiphy, "please report this issue.\n"); 471 db_len = sizeof(*entry) * entries;
428 return; 472 priv->rssi_db = kzalloc(db_len + sizeof(*priv->rssi_db), GFP_KERNEL);
473 if (!priv->rssi_db)
474 return -ENOMEM;
475
476 priv->rssi_db->offset = 0;
477 priv->rssi_db->entries = entries;
478 priv->rssi_db->entry_size = sizeof(*entry);
479 priv->rssi_db->len = db_len;
480
481 entry = (void *)((unsigned long)priv->rssi_db->data + priv->rssi_db->offset);
482 if (type == PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED) {
483 struct pda_rssi_cal_ext_entry *cal = (void *) &data[offset];
484
485 for (i = 0; i < entries; i++) {
486 entry[i].freq = le16_to_cpu(cal[i].freq);
487 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
488 entry[i].add = (s16) le16_to_cpu(cal[i].add);
489 }
490 } else {
491 struct pda_rssi_cal_entry *cal = (void *) &data[offset];
492
493 for (i = 0; i < entries; i++) {
494 u16 freq = 0;
495 switch (i) {
496 case IEEE80211_BAND_2GHZ:
497 freq = 2437;
498 break;
499 case IEEE80211_BAND_5GHZ:
500 freq = 5240;
501 break;
502 }
503
504 entry[i].freq = freq;
505 entry[i].mul = (s16) le16_to_cpu(cal[i].mul);
506 entry[i].add = (s16) le16_to_cpu(cal[i].add);
507 }
429 } 508 }
430 509
431 for (i = 0; i < num_entries; i++) { 510 /* sort the list by channel frequency */
432 struct pda_rssi_cal_entry *cal = data + 511 sort(entry, entries, sizeof(*entry), p54_compare_rssichan, NULL);
433 (offset + i * entry_size); 512 return 0;
434 priv->rssical_db[i].mul = (s16) le16_to_cpu(cal->mul); 513
435 priv->rssical_db[i].add = (s16) le16_to_cpu(cal->add); 514err_data:
515 wiphy_err(dev->wiphy,
516 "rssi calibration data packing type:(%x) len:%d.\n",
517 type, len);
518
519 print_hex_dump_bytes("rssical:", DUMP_PREFIX_NONE, data, len);
520
521 wiphy_err(dev->wiphy, "please report this issue.\n");
522 return -EINVAL;
523}
524
525struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *priv, const u16 freq)
526{
527 struct p54_rssi_db_entry *entry;
528 int i, found = -1;
529
530 if (!priv->rssi_db)
531 return &p54_rssi_default;
532
533 entry = (void *)(priv->rssi_db->data + priv->rssi_db->offset);
534 for (i = 0; i < priv->rssi_db->entries; i++) {
535 if (!same_band(freq, entry[i].freq))
536 continue;
537
538 if (found == -1) {
539 found = i;
540 continue;
541 }
542
543 /* nearest match */
544 if (abs(freq - entry[i].freq) <
545 abs(freq - entry[found].freq)) {
546 found = i;
547 continue;
548 } else {
549 break;
550 }
436 } 551 }
552
553 return found < 0 ? &p54_rssi_default : &entry[found];
437} 554}
438 555
439static void p54_parse_default_country(struct ieee80211_hw *dev, 556static void p54_parse_default_country(struct ieee80211_hw *dev,
@@ -540,6 +657,7 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
540 int err; 657 int err;
541 u8 *end = (u8 *)eeprom + len; 658 u8 *end = (u8 *)eeprom + len;
542 u16 synth = 0; 659 u16 synth = 0;
660 u16 crc16 = ~0;
543 661
544 wrap = (struct eeprom_pda_wrap *) eeprom; 662 wrap = (struct eeprom_pda_wrap *) eeprom;
545 entry = (void *)wrap->data + le16_to_cpu(wrap->len); 663 entry = (void *)wrap->data + le16_to_cpu(wrap->len);
@@ -623,21 +741,30 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
623 case PDR_RSSI_LINEAR_APPROXIMATION: 741 case PDR_RSSI_LINEAR_APPROXIMATION:
624 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND: 742 case PDR_RSSI_LINEAR_APPROXIMATION_DUAL_BAND:
625 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED: 743 case PDR_RSSI_LINEAR_APPROXIMATION_EXTENDED:
626 p54_parse_rssical(dev, entry->data, data_len, 744 err = p54_parse_rssical(dev, entry->data, data_len,
627 le16_to_cpu(entry->code)); 745 le16_to_cpu(entry->code));
746 if (err)
747 goto err;
628 break; 748 break;
629 case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM: { 749 case PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2: {
630 __le16 *src = (void *) entry->data; 750 struct pda_custom_wrapper *pda = (void *) entry->data;
631 s16 *dst = (void *) &priv->rssical_db; 751 __le16 *src;
752 u16 *dst;
632 int i; 753 int i;
633 754
634 if (data_len != sizeof(priv->rssical_db)) { 755 if (priv->rssi_db || data_len < sizeof(*pda))
635 err = -EINVAL; 756 break;
636 goto err; 757
637 } 758 priv->rssi_db = p54_convert_db(pda, data_len);
638 for (i = 0; i < sizeof(priv->rssical_db) / 759 if (!priv->rssi_db)
639 sizeof(*src); i++) 760 break;
761
762 src = (void *) priv->rssi_db->data;
763 dst = (void *) priv->rssi_db->data;
764
765 for (i = 0; i < priv->rssi_db->entries; i++)
640 *(dst++) = (s16) le16_to_cpu(*(src++)); 766 *(dst++) = (s16) le16_to_cpu(*(src++));
767
641 } 768 }
642 break; 769 break;
643 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: { 770 case PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM: {
@@ -655,16 +782,29 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
655 } 782 }
656 break; 783 break;
657 case PDR_END: 784 case PDR_END:
658 /* make it overrun */ 785 crc16 = ~crc_ccitt(crc16, (u8 *) entry, sizeof(*entry));
659 entry_len = len; 786 if (crc16 != le16_to_cpup((__le16 *)entry->data)) {
787 wiphy_err(dev->wiphy, "eeprom failed checksum "
788 "test!\n");
789 err = -ENOMSG;
790 goto err;
791 } else {
792 goto good_eeprom;
793 }
660 break; 794 break;
661 default: 795 default:
662 break; 796 break;
663 } 797 }
664 798
665 entry = (void *)entry + (entry_len + 1)*2; 799 crc16 = crc_ccitt(crc16, (u8 *)entry, (entry_len + 1) * 2);
800 entry = (void *)entry + (entry_len + 1) * 2;
666 } 801 }
667 802
803 wiphy_err(dev->wiphy, "unexpected end of eeprom data.\n");
804 err = -ENODATA;
805 goto err;
806
807good_eeprom:
668 if (!synth || !priv->iq_autocal || !priv->output_limit || 808 if (!synth || !priv->iq_autocal || !priv->output_limit ||
669 !priv->curve_data) { 809 !priv->curve_data) {
670 wiphy_err(dev->wiphy, 810 wiphy_err(dev->wiphy,
@@ -700,6 +840,8 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
700 SET_IEEE80211_PERM_ADDR(dev, perm_addr); 840 SET_IEEE80211_PERM_ADDR(dev, perm_addr);
701 } 841 }
702 842
843 priv->cur_rssi = &p54_rssi_default;
844
703 wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n", 845 wiphy_info(dev->wiphy, "hwaddr %pM, MAC:isl38%02x RF:%s\n",
704 dev->wiphy->perm_addr, priv->version, 846 dev->wiphy->perm_addr, priv->version,
705 p54_rf_chips[priv->rxhw]); 847 p54_rf_chips[priv->rxhw]);
@@ -710,9 +852,11 @@ err:
710 kfree(priv->iq_autocal); 852 kfree(priv->iq_autocal);
711 kfree(priv->output_limit); 853 kfree(priv->output_limit);
712 kfree(priv->curve_data); 854 kfree(priv->curve_data);
855 kfree(priv->rssi_db);
713 priv->iq_autocal = NULL; 856 priv->iq_autocal = NULL;
714 priv->output_limit = NULL; 857 priv->output_limit = NULL;
715 priv->curve_data = NULL; 858 priv->curve_data = NULL;
859 priv->rssi_db = NULL;
716 860
717 wiphy_err(dev->wiphy, "eeprom parse failed!\n"); 861 wiphy_err(dev->wiphy, "eeprom parse failed!\n");
718 return err; 862 return err;
diff --git a/drivers/net/wireless/p54/eeprom.h b/drivers/net/wireless/p54/eeprom.h
index 9051aef11249..afde72b84606 100644
--- a/drivers/net/wireless/p54/eeprom.h
+++ b/drivers/net/wireless/p54/eeprom.h
@@ -81,6 +81,12 @@ struct pda_pa_curve_data {
81 u8 data[0]; 81 u8 data[0];
82} __packed; 82} __packed;
83 83
84struct pda_rssi_cal_ext_entry {
85 __le16 freq;
86 __le16 mul;
87 __le16 add;
88} __packed;
89
84struct pda_rssi_cal_entry { 90struct pda_rssi_cal_entry {
85 __le16 mul; 91 __le16 mul;
86 __le16 add; 92 __le16 add;
@@ -179,6 +185,7 @@ struct pda_custom_wrapper {
179 185
180/* used by our modificated eeprom image */ 186/* used by our modificated eeprom image */
181#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD 187#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM 0xDEAD
188#define PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 0xCAFF
182#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF 189#define PDR_PRISM_PA_CAL_OUTPUT_POWER_LIMITS_CUSTOM 0xBEEF
183#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D 190#define PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM 0xB05D
184 191
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index 15b20c29a604..b6a061cbbdec 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -123,10 +123,14 @@ int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
123 bootrec = (struct bootrec *)&bootrec->data[len]; 123 bootrec = (struct bootrec *)&bootrec->data[len];
124 } 124 }
125 125
126 if (fw_version) 126 if (fw_version) {
127 wiphy_info(priv->hw->wiphy, 127 wiphy_info(priv->hw->wiphy,
128 "FW rev %s - Softmac protocol %x.%x\n", 128 "FW rev %s - Softmac protocol %x.%x\n",
129 fw_version, priv->fw_var >> 8, priv->fw_var & 0xff); 129 fw_version, priv->fw_var >> 8, priv->fw_var & 0xff);
130 snprintf(dev->wiphy->fw_version, sizeof(dev->wiphy->fw_version),
131 "%s - %x.%x", fw_version,
132 priv->fw_var >> 8, priv->fw_var & 0xff);
133 }
130 134
131 if (priv->fw_var < 0x500) 135 if (priv->fw_var < 0x500)
132 wiphy_info(priv->hw->wiphy, 136 wiphy_info(priv->hw->wiphy,
@@ -393,9 +397,9 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
393 union p54_scan_body_union *body; 397 union p54_scan_body_union *body;
394 struct p54_scan_tail_rate *rate; 398 struct p54_scan_tail_rate *rate;
395 struct pda_rssi_cal_entry *rssi; 399 struct pda_rssi_cal_entry *rssi;
400 struct p54_rssi_db_entry *rssi_data;
396 unsigned int i; 401 unsigned int i;
397 void *entry; 402 void *entry;
398 int band = priv->hw->conf.channel->band;
399 __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq); 403 __le16 freq = cpu_to_le16(priv->hw->conf.channel->center_freq);
400 404
401 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) + 405 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*head) +
@@ -499,13 +503,14 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
499 } 503 }
500 504
501 rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi)); 505 rssi = (struct pda_rssi_cal_entry *) skb_put(skb, sizeof(*rssi));
502 rssi->mul = cpu_to_le16(priv->rssical_db[band].mul); 506 rssi_data = p54_rssi_find(priv, le16_to_cpu(freq));
503 rssi->add = cpu_to_le16(priv->rssical_db[band].add); 507 rssi->mul = cpu_to_le16(rssi_data->mul);
508 rssi->add = cpu_to_le16(rssi_data->add);
504 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) { 509 if (priv->rxhw == PDR_SYNTH_FRONTEND_LONGBOW) {
505 /* Longbow frontend needs ever more */ 510 /* Longbow frontend needs ever more */
506 rssi = (void *) skb_put(skb, sizeof(*rssi)); 511 rssi = (void *) skb_put(skb, sizeof(*rssi));
507 rssi->mul = cpu_to_le16(priv->rssical_db[band].longbow_unkn); 512 rssi->mul = cpu_to_le16(rssi_data->longbow_unkn);
508 rssi->add = cpu_to_le16(priv->rssical_db[band].longbow_unk2); 513 rssi->add = cpu_to_le16(rssi_data->longbow_unk2);
509 } 514 }
510 515
511 if (priv->fw_var >= 0x509) { 516 if (priv->fw_var >= 0x509) {
@@ -519,6 +524,7 @@ int p54_scan(struct p54_common *priv, u16 mode, u16 dwell)
519 hdr->len = cpu_to_le16(skb->len - sizeof(*hdr)); 524 hdr->len = cpu_to_le16(skb->len - sizeof(*hdr));
520 525
521 p54_tx(priv, skb); 526 p54_tx(priv, skb);
527 priv->cur_rssi = rssi_data;
522 return 0; 528 return 0;
523 529
524err: 530err:
@@ -553,6 +559,7 @@ int p54_set_edcf(struct p54_common *priv)
553{ 559{
554 struct sk_buff *skb; 560 struct sk_buff *skb;
555 struct p54_edcf *edcf; 561 struct p54_edcf *edcf;
562 u8 rtd;
556 563
557 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf), 564 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*edcf),
558 P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC); 565 P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
@@ -569,9 +576,15 @@ int p54_set_edcf(struct p54_common *priv)
569 edcf->sifs = 0x0a; 576 edcf->sifs = 0x0a;
570 edcf->eofpad = 0x06; 577 edcf->eofpad = 0x06;
571 } 578 }
579 /*
580 * calculate the extra round trip delay according to the
581 * formula from 802.11-2007 17.3.8.6.
582 */
583 rtd = 3 * priv->coverage_class;
584 edcf->slottime += rtd;
585 edcf->round_trip_delay = cpu_to_le16(rtd);
572 /* (see prism54/isl_oid.h for further details) */ 586 /* (see prism54/isl_oid.h for further details) */
573 edcf->frameburst = cpu_to_le16(0); 587 edcf->frameburst = cpu_to_le16(0);
574 edcf->round_trip_delay = cpu_to_le16(0);
575 edcf->flags = 0; 588 edcf->flags = 0;
576 memset(edcf->mapping, 0, sizeof(edcf->mapping)); 589 memset(edcf->mapping, 0, sizeof(edcf->mapping));
577 memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue)); 590 memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
@@ -714,3 +727,34 @@ int p54_fetch_statistics(struct p54_common *priv)
714 p54_tx(priv, skb); 727 p54_tx(priv, skb);
715 return 0; 728 return 0;
716} 729}
730
731int p54_set_groupfilter(struct p54_common *priv)
732{
733 struct p54_group_address_table *grp;
734 struct sk_buff *skb;
735 bool on = false;
736
737 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL_OPSET, sizeof(*grp),
738 P54_CONTROL_TYPE_GROUP_ADDRESS_TABLE, GFP_KERNEL);
739 if (!skb)
740 return -ENOMEM;
741
742 grp = (struct p54_group_address_table *)skb_put(skb, sizeof(*grp));
743
744 on = !(priv->filter_flags & FIF_ALLMULTI) &&
745 (priv->mc_maclist_num > 0 &&
746 priv->mc_maclist_num <= MC_FILTER_ADDRESS_NUM);
747
748 if (on) {
749 grp->filter_enable = cpu_to_le16(1);
750 grp->num_address = cpu_to_le16(priv->mc_maclist_num);
751 memcpy(grp->mac_list, priv->mc_maclist, sizeof(grp->mac_list));
752 } else {
753 grp->filter_enable = cpu_to_le16(0);
754 grp->num_address = cpu_to_le16(0);
755 memset(grp->mac_list, 0, sizeof(grp->mac_list));
756 }
757
758 p54_tx(priv, skb);
759 return 0;
760}
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h
index 04b63ec80fa4..3d8d622bec55 100644
--- a/drivers/net/wireless/p54/lmac.h
+++ b/drivers/net/wireless/p54/lmac.h
@@ -526,7 +526,7 @@ int p54_init_leds(struct p54_common *priv);
526void p54_unregister_leds(struct p54_common *priv); 526void p54_unregister_leds(struct p54_common *priv);
527 527
528/* xmit functions */ 528/* xmit functions */
529int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb); 529void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb);
530int p54_tx_cancel(struct p54_common *priv, __le32 req_id); 530int p54_tx_cancel(struct p54_common *priv, __le32 req_id);
531void p54_tx(struct p54_common *priv, struct sk_buff *skb); 531void p54_tx(struct p54_common *priv, struct sk_buff *skb);
532 532
@@ -540,6 +540,7 @@ int p54_update_beacon_tim(struct p54_common *priv, u16 aid, bool set);
540int p54_setup_mac(struct p54_common *priv); 540int p54_setup_mac(struct p54_common *priv);
541int p54_set_ps(struct p54_common *priv); 541int p54_set_ps(struct p54_common *priv);
542int p54_fetch_statistics(struct p54_common *priv); 542int p54_fetch_statistics(struct p54_common *priv);
543int p54_set_groupfilter(struct p54_common *priv);
543 544
544/* e/v DCF setup */ 545/* e/v DCF setup */
545int p54_set_edcf(struct p54_common *priv); 546int p54_set_edcf(struct p54_common *priv);
@@ -551,6 +552,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot,
551/* eeprom */ 552/* eeprom */
552int p54_download_eeprom(struct p54_common *priv, void *buf, 553int p54_download_eeprom(struct p54_common *priv, void *buf,
553 u16 offset, u16 len); 554 u16 offset, u16 len);
555struct p54_rssi_db_entry *p54_rssi_find(struct p54_common *p, const u16 freq);
554 556
555/* utility */ 557/* utility */
556u8 *p54_find_ie(struct sk_buff *skb, u8 ie); 558u8 *p54_find_ie(struct sk_buff *skb, u8 ie);
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 47db439b63bf..a5a6d9e647bb 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -157,7 +157,7 @@ static int p54_beacon_update(struct p54_common *priv,
157 * to cancel the old beacon template by hand, instead the firmware 157 * to cancel the old beacon template by hand, instead the firmware
158 * will release the previous one through the feedback mechanism. 158 * will release the previous one through the feedback mechanism.
159 */ 159 */
160 WARN_ON(p54_tx_80211(priv->hw, beacon)); 160 p54_tx_80211(priv->hw, beacon);
161 priv->tsf_high32 = 0; 161 priv->tsf_high32 = 0;
162 priv->tsf_low32 = 0; 162 priv->tsf_low32 = 0;
163 163
@@ -308,6 +308,31 @@ out:
308 return ret; 308 return ret;
309} 309}
310 310
311static u64 p54_prepare_multicast(struct ieee80211_hw *dev,
312 struct netdev_hw_addr_list *mc_list)
313{
314 struct p54_common *priv = dev->priv;
315 struct netdev_hw_addr *ha;
316 int i;
317
318 BUILD_BUG_ON(ARRAY_SIZE(priv->mc_maclist) !=
319 ARRAY_SIZE(((struct p54_group_address_table *)NULL)->mac_list));
320 /*
321 * The first entry is reserved for the global broadcast MAC.
322 * Otherwise the firmware will drop it and ARP will no longer work.
323 */
324 i = 1;
325 priv->mc_maclist_num = netdev_hw_addr_list_count(mc_list) + i;
326 netdev_hw_addr_list_for_each(ha, mc_list) {
327 memcpy(&priv->mc_maclist[i], ha->addr, ETH_ALEN);
328 i++;
329 if (i >= ARRAY_SIZE(priv->mc_maclist))
330 break;
331 }
332
333 return 1; /* update */
334}
335
311static void p54_configure_filter(struct ieee80211_hw *dev, 336static void p54_configure_filter(struct ieee80211_hw *dev,
312 unsigned int changed_flags, 337 unsigned int changed_flags,
313 unsigned int *total_flags, 338 unsigned int *total_flags,
@@ -316,12 +341,16 @@ static void p54_configure_filter(struct ieee80211_hw *dev,
316 struct p54_common *priv = dev->priv; 341 struct p54_common *priv = dev->priv;
317 342
318 *total_flags &= FIF_PROMISC_IN_BSS | 343 *total_flags &= FIF_PROMISC_IN_BSS |
344 FIF_ALLMULTI |
319 FIF_OTHER_BSS; 345 FIF_OTHER_BSS;
320 346
321 priv->filter_flags = *total_flags; 347 priv->filter_flags = *total_flags;
322 348
323 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) 349 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS))
324 p54_setup_mac(priv); 350 p54_setup_mac(priv);
351
352 if (changed_flags & FIF_ALLMULTI || multicast)
353 p54_set_groupfilter(priv);
325} 354}
326 355
327static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue, 356static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
@@ -429,8 +458,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
429 458
430 mutex_lock(&priv->conf_mutex); 459 mutex_lock(&priv->conf_mutex);
431 if (cmd == SET_KEY) { 460 if (cmd == SET_KEY) {
432 switch (key->alg) { 461 switch (key->cipher) {
433 case ALG_TKIP: 462 case WLAN_CIPHER_SUITE_TKIP:
434 if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL | 463 if (!(priv->privacy_caps & (BR_DESC_PRIV_CAP_MICHAEL |
435 BR_DESC_PRIV_CAP_TKIP))) { 464 BR_DESC_PRIV_CAP_TKIP))) {
436 ret = -EOPNOTSUPP; 465 ret = -EOPNOTSUPP;
@@ -439,7 +468,8 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
439 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 468 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
440 algo = P54_CRYPTO_TKIPMICHAEL; 469 algo = P54_CRYPTO_TKIPMICHAEL;
441 break; 470 break;
442 case ALG_WEP: 471 case WLAN_CIPHER_SUITE_WEP40:
472 case WLAN_CIPHER_SUITE_WEP104:
443 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) { 473 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_WEP)) {
444 ret = -EOPNOTSUPP; 474 ret = -EOPNOTSUPP;
445 goto out_unlock; 475 goto out_unlock;
@@ -447,7 +477,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
447 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 477 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
448 algo = P54_CRYPTO_WEP; 478 algo = P54_CRYPTO_WEP;
449 break; 479 break;
450 case ALG_CCMP: 480 case WLAN_CIPHER_SUITE_CCMP:
451 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) { 481 if (!(priv->privacy_caps & BR_DESC_PRIV_CAP_AESCCMP)) {
452 ret = -EOPNOTSUPP; 482 ret = -EOPNOTSUPP;
453 goto out_unlock; 483 goto out_unlock;
@@ -464,7 +494,7 @@ static int p54_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
464 494
465 if (slot < 0) { 495 if (slot < 0) {
466 /* 496 /*
467 * The device supports the choosen algorithm, but the 497 * The device supports the chosen algorithm, but the
468 * firmware does not provide enough key slots to store 498 * firmware does not provide enough key slots to store
469 * all of them. 499 * all of them.
470 * But encryption offload for outgoing frames is always 500 * But encryption offload for outgoing frames is always
@@ -523,6 +553,59 @@ static int p54_get_survey(struct ieee80211_hw *dev, int idx,
523 return 0; 553 return 0;
524} 554}
525 555
556static unsigned int p54_flush_count(struct p54_common *priv)
557{
558 unsigned int total = 0, i;
559
560 BUILD_BUG_ON(P54_QUEUE_NUM > ARRAY_SIZE(priv->tx_stats));
561
562 /*
563 * Because the firmware has the sole control over any frames
564 * in the P54_QUEUE_BEACON or P54_QUEUE_SCAN queues, they
565 * don't really count as pending or active.
566 */
567 for (i = P54_QUEUE_MGMT; i < P54_QUEUE_NUM; i++)
568 total += priv->tx_stats[i].len;
569 return total;
570}
571
572static void p54_flush(struct ieee80211_hw *dev, bool drop)
573{
574 struct p54_common *priv = dev->priv;
575 unsigned int total, i;
576
577 /*
578 * Currently, it wouldn't really matter if we wait for one second
579 * or 15 minutes. But once someone gets around and completes the
580 * TODOs [ancel stuck frames / reset device] in p54_work, it will
581 * suddenly make sense to wait that long.
582 */
583 i = P54_STATISTICS_UPDATE * 2 / 20;
584
585 /*
586 * In this case no locking is required because as we speak the
587 * queues have already been stopped and no new frames can sneak
588 * up from behind.
589 */
590 while ((total = p54_flush_count(priv) && i--)) {
591 /* waste time */
592 msleep(20);
593 }
594
595 WARN(total, "tx flush timeout, unresponsive firmware");
596}
597
598static void p54_set_coverage_class(struct ieee80211_hw *dev, u8 coverage_class)
599{
600 struct p54_common *priv = dev->priv;
601
602 mutex_lock(&priv->conf_mutex);
603 /* support all coverage class values as in 802.11-2007 Table 7-27 */
604 priv->coverage_class = clamp_t(u8, coverage_class, 0, 31);
605 p54_set_edcf(priv);
606 mutex_unlock(&priv->conf_mutex);
607}
608
526static const struct ieee80211_ops p54_ops = { 609static const struct ieee80211_ops p54_ops = {
527 .tx = p54_tx_80211, 610 .tx = p54_tx_80211,
528 .start = p54_start, 611 .start = p54_start,
@@ -535,11 +618,14 @@ static const struct ieee80211_ops p54_ops = {
535 .sta_remove = p54_sta_add_remove, 618 .sta_remove = p54_sta_add_remove,
536 .set_key = p54_set_key, 619 .set_key = p54_set_key,
537 .config = p54_config, 620 .config = p54_config,
621 .flush = p54_flush,
538 .bss_info_changed = p54_bss_info_changed, 622 .bss_info_changed = p54_bss_info_changed,
623 .prepare_multicast = p54_prepare_multicast,
539 .configure_filter = p54_configure_filter, 624 .configure_filter = p54_configure_filter,
540 .conf_tx = p54_conf_tx, 625 .conf_tx = p54_conf_tx,
541 .get_stats = p54_get_stats, 626 .get_stats = p54_get_stats,
542 .get_survey = p54_get_survey, 627 .get_survey = p54_get_survey,
628 .set_coverage_class = p54_set_coverage_class,
543}; 629};
544 630
545struct ieee80211_hw *p54_init_common(size_t priv_data_len) 631struct ieee80211_hw *p54_init_common(size_t priv_data_len)
@@ -604,13 +690,14 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
604 init_completion(&priv->beacon_comp); 690 init_completion(&priv->beacon_comp);
605 INIT_DELAYED_WORK(&priv->work, p54_work); 691 INIT_DELAYED_WORK(&priv->work, p54_work);
606 692
693 memset(&priv->mc_maclist[0], ~0, ETH_ALEN);
607 return dev; 694 return dev;
608} 695}
609EXPORT_SYMBOL_GPL(p54_init_common); 696EXPORT_SYMBOL_GPL(p54_init_common);
610 697
611int p54_register_common(struct ieee80211_hw *dev, struct device *pdev) 698int p54_register_common(struct ieee80211_hw *dev, struct device *pdev)
612{ 699{
613 struct p54_common *priv = dev->priv; 700 struct p54_common __maybe_unused *priv = dev->priv;
614 int err; 701 int err;
615 702
616 err = ieee80211_register_hw(dev); 703 err = ieee80211_register_hw(dev);
@@ -641,10 +728,12 @@ void p54_free_common(struct ieee80211_hw *dev)
641 kfree(priv->iq_autocal); 728 kfree(priv->iq_autocal);
642 kfree(priv->output_limit); 729 kfree(priv->output_limit);
643 kfree(priv->curve_data); 730 kfree(priv->curve_data);
731 kfree(priv->rssi_db);
644 kfree(priv->used_rxkeys); 732 kfree(priv->used_rxkeys);
645 priv->iq_autocal = NULL; 733 priv->iq_autocal = NULL;
646 priv->output_limit = NULL; 734 priv->output_limit = NULL;
647 priv->curve_data = NULL; 735 priv->curve_data = NULL;
736 priv->rssi_db = NULL;
648 priv->used_rxkeys = NULL; 737 priv->used_rxkeys = NULL;
649 ieee80211_free_hw(dev); 738 ieee80211_free_hw(dev);
650} 739}
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 43a3b2ead81a..799d05e12595 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -116,7 +116,8 @@ struct p54_edcf_queue_param {
116 __le16 txop; 116 __le16 txop;
117} __packed; 117} __packed;
118 118
119struct p54_rssi_linear_approximation { 119struct p54_rssi_db_entry {
120 u16 freq;
120 s16 mul; 121 s16 mul;
121 s16 add; 122 s16 add;
122 s16 longbow_unkn; 123 s16 longbow_unkn;
@@ -197,24 +198,28 @@ struct p54_common {
197 u8 rx_diversity_mask; 198 u8 rx_diversity_mask;
198 u8 tx_diversity_mask; 199 u8 tx_diversity_mask;
199 unsigned int output_power; 200 unsigned int output_power;
201 struct p54_rssi_db_entry *cur_rssi;
200 int noise; 202 int noise;
201 /* calibration, output power limit and rssi<->dBm conversation data */ 203 /* calibration, output power limit and rssi<->dBm conversation data */
202 struct pda_iq_autocal_entry *iq_autocal; 204 struct pda_iq_autocal_entry *iq_autocal;
203 unsigned int iq_autocal_len; 205 unsigned int iq_autocal_len;
204 struct p54_cal_database *curve_data; 206 struct p54_cal_database *curve_data;
205 struct p54_cal_database *output_limit; 207 struct p54_cal_database *output_limit;
206 struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; 208 struct p54_cal_database *rssi_db;
207 struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS]; 209 struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
208 210
209 /* BBP/MAC state */ 211 /* BBP/MAC state */
210 u8 mac_addr[ETH_ALEN]; 212 u8 mac_addr[ETH_ALEN];
211 u8 bssid[ETH_ALEN]; 213 u8 bssid[ETH_ALEN];
214 u8 mc_maclist[4][ETH_ALEN];
212 u16 wakeup_timer; 215 u16 wakeup_timer;
213 unsigned int filter_flags; 216 unsigned int filter_flags;
217 int mc_maclist_num;
214 int mode; 218 int mode;
215 u32 tsf_low32, tsf_high32; 219 u32 tsf_low32, tsf_high32;
216 u32 basic_rate_mask; 220 u32 basic_rate_mask;
217 u16 aid; 221 u16 aid;
222 u8 coverage_class;
218 bool powersave_override; 223 bool powersave_override;
219 __le32 beacon_req_id; 224 __le32 beacon_req_id;
220 struct completion beacon_comp; 225 struct completion beacon_comp;
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c
index 1eacba4daa5b..1b753173680f 100644
--- a/drivers/net/wireless/p54/p54pci.c
+++ b/drivers/net/wireless/p54/p54pci.c
@@ -199,6 +199,7 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
199 while (i != idx) { 199 while (i != idx) {
200 u16 len; 200 u16 len;
201 struct sk_buff *skb; 201 struct sk_buff *skb;
202 dma_addr_t dma_addr;
202 desc = &ring[i]; 203 desc = &ring[i];
203 len = le16_to_cpu(desc->len); 204 len = le16_to_cpu(desc->len);
204 skb = rx_buf[i]; 205 skb = rx_buf[i];
@@ -216,17 +217,20 @@ static void p54p_check_rx_ring(struct ieee80211_hw *dev, u32 *index,
216 217
217 len = priv->common.rx_mtu; 218 len = priv->common.rx_mtu;
218 } 219 }
220 dma_addr = le32_to_cpu(desc->host_addr);
221 pci_dma_sync_single_for_cpu(priv->pdev, dma_addr,
222 priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
219 skb_put(skb, len); 223 skb_put(skb, len);
220 224
221 if (p54_rx(dev, skb)) { 225 if (p54_rx(dev, skb)) {
222 pci_unmap_single(priv->pdev, 226 pci_unmap_single(priv->pdev, dma_addr,
223 le32_to_cpu(desc->host_addr), 227 priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
224 priv->common.rx_mtu + 32,
225 PCI_DMA_FROMDEVICE);
226 rx_buf[i] = NULL; 228 rx_buf[i] = NULL;
227 desc->host_addr = 0; 229 desc->host_addr = cpu_to_le32(0);
228 } else { 230 } else {
229 skb_trim(skb, 0); 231 skb_trim(skb, 0);
232 pci_dma_sync_single_for_device(priv->pdev, dma_addr,
233 priv->common.rx_mtu + 32, PCI_DMA_FROMDEVICE);
230 desc->len = cpu_to_le16(priv->common.rx_mtu + 32); 234 desc->len = cpu_to_le16(priv->common.rx_mtu + 32);
231 } 235 }
232 236
@@ -327,10 +331,9 @@ static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
327 struct p54p_ring_control *ring_control = priv->ring_control; 331 struct p54p_ring_control *ring_control = priv->ring_control;
328 struct p54p_desc *desc; 332 struct p54p_desc *desc;
329 dma_addr_t mapping; 333 dma_addr_t mapping;
330 u32 device_idx, idx, i; 334 u32 idx, i;
331 335
332 spin_lock_irqsave(&priv->lock, flags); 336 spin_lock_irqsave(&priv->lock, flags);
333 device_idx = le32_to_cpu(ring_control->device_idx[1]);
334 idx = le32_to_cpu(ring_control->host_idx[1]); 337 idx = le32_to_cpu(ring_control->host_idx[1]);
335 i = idx % ARRAY_SIZE(ring_control->tx_data); 338 i = idx % ARRAY_SIZE(ring_control->tx_data);
336 339
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index 087bf0698a5a..6d9204fef90b 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -32,11 +32,14 @@
32#include <linux/slab.h> 32#include <linux/slab.h>
33 33
34#include "p54spi.h" 34#include "p54spi.h"
35#include "p54spi_eeprom.h"
36#include "p54.h" 35#include "p54.h"
37 36
38#include "lmac.h" 37#include "lmac.h"
39 38
39#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
40#include "p54spi_eeprom.h"
41#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
42
40MODULE_FIRMWARE("3826.arm"); 43MODULE_FIRMWARE("3826.arm");
41MODULE_ALIAS("stlc45xx"); 44MODULE_ALIAS("stlc45xx");
42 45
@@ -195,9 +198,13 @@ static int p54spi_request_eeprom(struct ieee80211_hw *dev)
195 198
196 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev); 199 ret = request_firmware(&eeprom, "3826.eeprom", &priv->spi->dev);
197 if (ret < 0) { 200 if (ret < 0) {
201#ifdef CONFIG_P54_SPI_DEFAULT_EEPROM
198 dev_info(&priv->spi->dev, "loading default eeprom...\n"); 202 dev_info(&priv->spi->dev, "loading default eeprom...\n");
199 ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom, 203 ret = p54_parse_eeprom(dev, (void *) p54spi_eeprom,
200 sizeof(p54spi_eeprom)); 204 sizeof(p54spi_eeprom));
205#else
206 dev_err(&priv->spi->dev, "Failed to request user eeprom\n");
207#endif /* CONFIG_P54_SPI_DEFAULT_EEPROM */
201 } else { 208 } else {
202 dev_info(&priv->spi->dev, "loading user eeprom...\n"); 209 dev_info(&priv->spi->dev, "loading user eeprom...\n");
203 ret = p54_parse_eeprom(dev, (void *) eeprom->data, 210 ret = p54_parse_eeprom(dev, (void *) eeprom->data,
@@ -280,7 +287,7 @@ static void p54spi_power_on(struct p54s_priv *priv)
280 enable_irq(gpio_to_irq(p54spi_gpio_irq)); 287 enable_irq(gpio_to_irq(p54spi_gpio_irq));
281 288
282 /* 289 /*
283 * need to wait a while before device can be accessed, the lenght 290 * need to wait a while before device can be accessed, the length
284 * is just a guess 291 * is just a guess
285 */ 292 */
286 msleep(10); 293 msleep(10);
@@ -642,8 +649,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
642 goto err_free_common; 649 goto err_free_common;
643 } 650 }
644 651
645 set_irq_type(gpio_to_irq(p54spi_gpio_irq), 652 irq_set_irq_type(gpio_to_irq(p54spi_gpio_irq), IRQ_TYPE_EDGE_RISING);
646 IRQ_TYPE_EDGE_RISING);
647 653
648 disable_irq(gpio_to_irq(p54spi_gpio_irq)); 654 disable_irq(gpio_to_irq(p54spi_gpio_irq));
649 655
diff --git a/drivers/net/wireless/p54/p54spi_eeprom.h b/drivers/net/wireless/p54/p54spi_eeprom.h
index 1ea1050911d9..0b7bfb0adcf2 100644
--- a/drivers/net/wireless/p54/p54spi_eeprom.h
+++ b/drivers/net/wireless/p54/p54spi_eeprom.h
@@ -65,9 +65,10 @@ static unsigned char p54spi_eeprom[] = {
650x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */ 650x03, 0x00, 0x00, 0x11, /* PDR_ANTENNA_GAIN */
66 0x08, 0x08, 0x08, 0x08, 66 0x08, 0x08, 0x08, 0x08,
67 67
680x09, 0x00, 0xad, 0xde, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOM */ 680x0a, 0x00, 0xff, 0xca, /* PDR_RSSI_LINEAR_APPROXIMATION_CUSTOMV2 */
69 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00, 69 0x01, 0x00, 0x0a, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 70 0x00, 0x00, 0x0a, 0x00,
71 0x85, 0x09, 0x0a, 0x01, 0x72, 0xfe, 0x1a, 0x00, 0x00, 0x00,
71 72
72/* struct pda_custom_wrapper */ 73/* struct pda_custom_wrapper */
730x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */ 740x10, 0x06, 0x5d, 0xb0, /* PDR_PRISM_PA_CAL_CURVE_DATA_CUSTOM */
@@ -671,7 +672,7 @@ static unsigned char p54spi_eeprom[] = {
671 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01, 672 0xa8, 0x09, 0x25, 0x00, 0xf5, 0xff, 0xf9, 0xff, 0x00, 0x01,
672 673
6730x02, 0x00, 0x00, 0x00, /* PDR_END */ 6740x02, 0x00, 0x00, 0x00, /* PDR_END */
674 0xa8, 0xf5 /* bogus data */ 675 0xb6, 0x04,
675}; 676};
676 677
677#endif /* P54SPI_EEPROM_H */ 678#endif /* P54SPI_EEPROM_H */
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c
index ad595958b7df..a8f3bc740dfa 100644
--- a/drivers/net/wireless/p54/p54usb.c
+++ b/drivers/net/wireless/p54/p54usb.c
@@ -33,8 +33,18 @@ MODULE_ALIAS("prism54usb");
33MODULE_FIRMWARE("isl3886usb"); 33MODULE_FIRMWARE("isl3886usb");
34MODULE_FIRMWARE("isl3887usb"); 34MODULE_FIRMWARE("isl3887usb");
35 35
36/*
37 * Note:
38 *
39 * Always update our wiki's device list (located at:
40 * http://wireless.kernel.org/en/users/Drivers/p54/devices ),
41 * whenever you add a new device.
42 */
43
36static struct usb_device_id p54u_table[] __devinitdata = { 44static struct usb_device_id p54u_table[] __devinitdata = {
37 /* Version 1 devices (pci chip + net2280) */ 45 /* Version 1 devices (pci chip + net2280) */
46 {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */
47 {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */
38 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */ 48 {USB_DEVICE(0x0506, 0x0a11)}, /* 3COM 3CRWE254G72 */
39 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */ 49 {USB_DEVICE(0x06b9, 0x0120)}, /* Thomson SpeedTouch 120g */
40 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ 50 {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */
@@ -46,12 +56,20 @@ static struct usb_device_id p54u_table[] __devinitdata = {
46 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ 56 {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */
47 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ 57 {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */
48 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ 58 {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */
59 {USB_DEVICE(0x0bf8, 0x1007)}, /* Fujitsu E-5400 USB */
49 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */ 60 {USB_DEVICE(0x0cde, 0x0006)}, /* Medion 40900, Roper Europe */
61 {USB_DEVICE(0x0db0, 0x6826)}, /* MSI UB54G (MS-6826) */
62 {USB_DEVICE(0x107b, 0x55f2)}, /* Gateway WGU-210 (Gemtek) */
50 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */ 63 {USB_DEVICE(0x124a, 0x4023)}, /* Shuttle PN15, Airvast WM168g, IOGear GWU513 */
64 {USB_DEVICE(0x1435, 0x0210)}, /* Inventel UR054G */
65 {USB_DEVICE(0x15a9, 0x0002)}, /* Gemtek WUBI-100GW 802.11g */
66 {USB_DEVICE(0x1630, 0x0005)}, /* 2Wire 802.11g USB (v1) / Z-Com */
67 {USB_DEVICE(0x182d, 0x096b)}, /* Sitecom WL-107 */
51 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */ 68 {USB_DEVICE(0x1915, 0x2234)}, /* Linksys WUSB54G OEM */
52 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */ 69 {USB_DEVICE(0x1915, 0x2235)}, /* Linksys WUSB54G Portable OEM */
53 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */ 70 {USB_DEVICE(0x2001, 0x3701)}, /* DLink DWL-G120 Spinnaker */
54 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */ 71 {USB_DEVICE(0x2001, 0x3703)}, /* DLink DWL-G122 */
72 {USB_DEVICE(0x2001, 0x3762)}, /* Conceptronic C54U */
55 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */ 73 {USB_DEVICE(0x5041, 0x2234)}, /* Linksys WUSB54G */
56 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */ 74 {USB_DEVICE(0x5041, 0x2235)}, /* Linksys WUSB54G Portable */
57 75
@@ -60,9 +78,11 @@ static struct usb_device_id p54u_table[] __devinitdata = {
60 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */ 78 {USB_DEVICE(0x050d, 0x7050)}, /* Belkin F5D7050 ver 1000 */
61 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */ 79 {USB_DEVICE(0x0572, 0x2000)}, /* Cohiba Proto board */
62 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */ 80 {USB_DEVICE(0x0572, 0x2002)}, /* Cohiba Proto board */
81 {USB_DEVICE(0x06a9, 0x000e)}, /* Westell 802.11g USB (A90-211WG-01) */
63 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */ 82 {USB_DEVICE(0x06b9, 0x0121)}, /* Thomson SpeedTouch 121g */
64 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */ 83 {USB_DEVICE(0x0707, 0xee13)}, /* SMC 2862W-G version 2 */
65 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */ 84 {USB_DEVICE(0x083a, 0x4521)}, /* Siemens Gigaset USB Adapter 54 version 2 */
85 {USB_DEVICE(0x083a, 0xc501)}, /* Zoom Wireless-G 4410 */
66 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */ 86 {USB_DEVICE(0x083a, 0xf503)}, /* Accton FD7050E ver 1010ec */
67 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */ 87 {USB_DEVICE(0x0846, 0x4240)}, /* Netgear WG111 (v2) */
68 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */ 88 {USB_DEVICE(0x0915, 0x2000)}, /* Cohiba Proto board */
@@ -80,7 +100,10 @@ static struct usb_device_id p54u_table[] __devinitdata = {
80 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ 100 {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */
81 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */ 101 {USB_DEVICE(0x1413, 0x5400)}, /* Telsey 802.11g USB2.0 Adapter */
82 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ 102 {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */
103 {USB_DEVICE(0x1668, 0x1050)}, /* Actiontec 802UIG-1 */
104 {USB_DEVICE(0x1740, 0x1000)}, /* Senao NUB-350 */
83 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ 105 {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */
106 {USB_DEVICE(0x2001, 0x3705)}, /* D-Link DWL-G120 rev C1 */
84 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */ 107 {USB_DEVICE(0x413c, 0x5513)}, /* Dell WLA3310 USB Wireless Adapter */
85 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */ 108 {USB_DEVICE(0x413c, 0x8102)}, /* Spinnaker DUT */
86 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */ 109 {USB_DEVICE(0x413c, 0x8104)}, /* Cohiba Proto board */
@@ -170,7 +193,7 @@ static void p54u_rx_cb(struct urb *urb)
170static void p54u_tx_cb(struct urb *urb) 193static void p54u_tx_cb(struct urb *urb)
171{ 194{
172 struct sk_buff *skb = urb->context; 195 struct sk_buff *skb = urb->context;
173 struct ieee80211_hw *dev = (struct ieee80211_hw *) 196 struct ieee80211_hw *dev =
174 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); 197 usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0));
175 198
176 p54_free_skb(dev, skb); 199 p54_free_skb(dev, skb);
@@ -930,8 +953,8 @@ static int __devinit p54u_probe(struct usb_interface *intf,
930#ifdef CONFIG_PM 953#ifdef CONFIG_PM
931 /* ISL3887 needs a full reset on resume */ 954 /* ISL3887 needs a full reset on resume */
932 udev->reset_resume = 1; 955 udev->reset_resume = 1;
956#endif /* CONFIG_PM */
933 err = p54u_device_reset(dev); 957 err = p54u_device_reset(dev);
934#endif
935 958
936 priv->hw_type = P54U_3887; 959 priv->hw_type = P54U_3887;
937 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr); 960 dev->extra_tx_headroom += sizeof(struct lm87_tx_hdr);
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 0e937dc0c9c4..042842e704de 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -273,17 +273,15 @@ void p54_tx(struct p54_common *priv, struct sk_buff *skb)
273 273
274static int p54_rssi_to_dbm(struct p54_common *priv, int rssi) 274static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
275{ 275{
276 int band = priv->hw->conf.channel->band; 276 if (priv->rxhw != 5) {
277 277 return ((rssi * priv->cur_rssi->mul) / 64 +
278 if (priv->rxhw != 5) 278 priv->cur_rssi->add) / 4;
279 return ((rssi * priv->rssical_db[band].mul) / 64 + 279 } else {
280 priv->rssical_db[band].add) / 4;
281 else
282 /* 280 /*
283 * TODO: find the correct formula 281 * TODO: find the correct formula
284 */ 282 */
285 return ((rssi * priv->rssical_db[band].mul) / 64 + 283 return rssi / 2 - 110;
286 priv->rssical_db[band].add) / 4; 284 }
287} 285}
288 286
289/* 287/*
@@ -369,7 +367,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
369 rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32; 367 rx_status->mactime = ((u64)priv->tsf_high32) << 32 | tsf32;
370 priv->tsf_low32 = tsf32; 368 priv->tsf_low32 = tsf32;
371 369
372 rx_status->flag |= RX_FLAG_TSFT; 370 rx_status->flag |= RX_FLAG_MACTIME_MPDU;
373 371
374 if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN)) 372 if (hdr->flags & cpu_to_le16(P54_HDR_FLAG_DATA_ALIGN))
375 header_len += hdr->align[0]; 373 header_len += hdr->align[0];
@@ -618,7 +616,7 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
618 else 616 else
619 *burst_possible = false; 617 *burst_possible = false;
620 618
621 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) 619 if (!(info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
622 *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR; 620 *flags |= P54_HDR_FLAG_DATA_OUT_SEQNR;
623 621
624 if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE) 622 if (info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)
@@ -683,28 +681,29 @@ static void p54_tx_80211_header(struct p54_common *priv, struct sk_buff *skb,
683 } 681 }
684} 682}
685 683
686static u8 p54_convert_algo(enum ieee80211_key_alg alg) 684static u8 p54_convert_algo(u32 cipher)
687{ 685{
688 switch (alg) { 686 switch (cipher) {
689 case ALG_WEP: 687 case WLAN_CIPHER_SUITE_WEP40:
688 case WLAN_CIPHER_SUITE_WEP104:
690 return P54_CRYPTO_WEP; 689 return P54_CRYPTO_WEP;
691 case ALG_TKIP: 690 case WLAN_CIPHER_SUITE_TKIP:
692 return P54_CRYPTO_TKIPMICHAEL; 691 return P54_CRYPTO_TKIPMICHAEL;
693 case ALG_CCMP: 692 case WLAN_CIPHER_SUITE_CCMP:
694 return P54_CRYPTO_AESCCMP; 693 return P54_CRYPTO_AESCCMP;
695 default: 694 default:
696 return 0; 695 return 0;
697 } 696 }
698} 697}
699 698
700int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb) 699void p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
701{ 700{
702 struct p54_common *priv = dev->priv; 701 struct p54_common *priv = dev->priv;
703 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 702 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
704 struct p54_tx_info *p54info; 703 struct p54_tx_info *p54info;
705 struct p54_hdr *hdr; 704 struct p54_hdr *hdr;
706 struct p54_tx_data *txhdr; 705 struct p54_tx_data *txhdr;
707 unsigned int padding, len, extra_len; 706 unsigned int padding, len, extra_len = 0;
708 int i, j, ridx; 707 int i, j, ridx;
709 u16 hdr_flags = 0, aid = 0; 708 u16 hdr_flags = 0, aid = 0;
710 u8 rate, queue = 0, crypt_offset = 0; 709 u8 rate, queue = 0, crypt_offset = 0;
@@ -718,12 +717,8 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
718 &hdr_flags, &aid, &burst_allowed); 717 &hdr_flags, &aid, &burst_allowed);
719 718
720 if (p54_tx_qos_accounting_alloc(priv, skb, queue)) { 719 if (p54_tx_qos_accounting_alloc(priv, skb, queue)) {
721 if (!IS_QOS_QUEUE(queue)) { 720 dev_kfree_skb_any(skb);
722 dev_kfree_skb_any(skb); 721 return;
723 return NETDEV_TX_OK;
724 } else {
725 return NETDEV_TX_BUSY;
726 }
727 } 722 }
728 723
729 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3; 724 padding = (unsigned long)(skb->data - (sizeof(*hdr) + sizeof(*txhdr))) & 3;
@@ -731,7 +726,7 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
731 726
732 if (info->control.hw_key) { 727 if (info->control.hw_key) {
733 crypt_offset = ieee80211_get_hdrlen_from_skb(skb); 728 crypt_offset = ieee80211_get_hdrlen_from_skb(skb);
734 if (info->control.hw_key->alg == ALG_TKIP) { 729 if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
735 u8 *iv = (u8 *)(skb->data + crypt_offset); 730 u8 *iv = (u8 *)(skb->data + crypt_offset);
736 /* 731 /*
737 * The firmware excepts that the IV has to have 732 * The firmware excepts that the IV has to have
@@ -827,10 +822,10 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
827 hdr->tries = ridx; 822 hdr->tries = ridx;
828 txhdr->rts_rate_idx = 0; 823 txhdr->rts_rate_idx = 0;
829 if (info->control.hw_key) { 824 if (info->control.hw_key) {
830 txhdr->key_type = p54_convert_algo(info->control.hw_key->alg); 825 txhdr->key_type = p54_convert_algo(info->control.hw_key->cipher);
831 txhdr->key_len = min((u8)16, info->control.hw_key->keylen); 826 txhdr->key_len = min((u8)16, info->control.hw_key->keylen);
832 memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len); 827 memcpy(txhdr->key, info->control.hw_key->key, txhdr->key_len);
833 if (info->control.hw_key->alg == ALG_TKIP) { 828 if (info->control.hw_key->cipher == WLAN_CIPHER_SUITE_TKIP) {
834 /* reserve space for the MIC key */ 829 /* reserve space for the MIC key */
835 len += 8; 830 len += 8;
836 memcpy(skb_put(skb, 8), &(info->control.hw_key->key 831 memcpy(skb_put(skb, 8), &(info->control.hw_key->key
@@ -866,5 +861,4 @@ int p54_tx_80211(struct ieee80211_hw *dev, struct sk_buff *skb)
866 p54info->extra_len = extra_len; 861 p54info->extra_len = extra_len;
867 862
868 p54_tx(priv, skb); 863 p54_tx(priv, skb);
869 return NETDEV_TX_OK;
870} 864}