aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54common.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-09-03 16:25:25 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-08 14:00:18 -0400
commit19c19d54b6bfa57746f3ec805d1d7951eefa353b (patch)
tree1a48522cd59e6ef492d99ebe212beb819c2526a8 /drivers/net/wireless/p54/p54common.c
parente0a58eacf540c65763288c81caa74013f62d7234 (diff)
p54: better firmware support
This patch hopefully contains all necessary changes to support firmwares for all devices up to atleast 2.13.3.0. (or: LowerMAC Protocol Rev: 5.5 ) And this is a big win, since: * newer firmwares are more stable and reliable than the old ones. * no problems anymore with packages > 1399 octets (without lowering the MTU). * monitor mode finally works on USB for more than just a few seconds. Signed-off-by: Christian Lamparter <chunkeey@web.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/p54/p54common.c')
-rw-r--r--drivers/net/wireless/p54/p54common.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index f742abab7594..f96f7c7e6af5 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -424,11 +424,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
424} 424}
425EXPORT_SYMBOL_GPL(p54_parse_eeprom); 425EXPORT_SYMBOL_GPL(p54_parse_eeprom);
426 426
427static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb) 427static int p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
428{ 428{
429 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data; 429 struct p54_rx_hdr *hdr = (struct p54_rx_hdr *) skb->data;
430 struct ieee80211_rx_status rx_status = {0}; 430 struct ieee80211_rx_status rx_status = {0};
431 u16 freq = le16_to_cpu(hdr->freq); 431 u16 freq = le16_to_cpu(hdr->freq);
432 size_t header_len = sizeof(*hdr);
432 433
433 rx_status.signal = hdr->rssi; 434 rx_status.signal = hdr->rssi;
434 /* XX correct? */ 435 /* XX correct? */
@@ -440,10 +441,15 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
440 rx_status.mactime = le64_to_cpu(hdr->timestamp); 441 rx_status.mactime = le64_to_cpu(hdr->timestamp);
441 rx_status.flag |= RX_FLAG_TSFT; 442 rx_status.flag |= RX_FLAG_TSFT;
442 443
443 skb_pull(skb, sizeof(*hdr)); 444 if (hdr->magic & cpu_to_le16(0x4000))
445 header_len += hdr->align[0];
446
447 skb_pull(skb, header_len);
444 skb_trim(skb, le16_to_cpu(hdr->len)); 448 skb_trim(skb, le16_to_cpu(hdr->len));
445 449
446 ieee80211_rx_irqsafe(dev, skb, &rx_status); 450 ieee80211_rx_irqsafe(dev, skb, &rx_status);
451
452 return -1;
447} 453}
448 454
449static void inline p54_wake_free_queues(struct ieee80211_hw *dev) 455static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
@@ -536,7 +542,7 @@ static void p54_rx_eeprom_readback(struct ieee80211_hw *dev,
536 complete(&priv->eeprom_comp); 542 complete(&priv->eeprom_comp);
537} 543}
538 544
539static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb) 545static int p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
540{ 546{
541 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data; 547 struct p54_control_hdr *hdr = (struct p54_control_hdr *) skb->data;
542 548
@@ -554,31 +560,19 @@ static void p54_rx_control(struct ieee80211_hw *dev, struct sk_buff *skb)
554 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type)); 560 wiphy_name(dev->wiphy), le16_to_cpu(hdr->type));
555 break; 561 break;
556 } 562 }
563
564 return 0;
557} 565}
558 566
559/* returns zero if skb can be reused */ 567/* returns zero if skb can be reused */
560int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb) 568int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb)
561{ 569{
562 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8; 570 u8 type = le16_to_cpu(*((__le16 *)skb->data)) >> 8;
563 switch (type) { 571
564 case 0x00: 572 if (type == 0x80)
565 case 0x01: 573 return p54_rx_control(dev, skb);
566 p54_rx_data(dev, skb); 574 else
567 return -1; 575 return p54_rx_data(dev, skb);
568 case 0x4d:
569 /* TODO: do something better... but then again, I've never seen this happen */
570 printk(KERN_ERR "%s: Received fault. Probably need to restart hardware now..\n",
571 wiphy_name(dev->wiphy));
572 break;
573 case 0x80:
574 p54_rx_control(dev, skb);
575 break;
576 default:
577 printk(KERN_ERR "%s: unknown frame RXed (0x%02x)\n",
578 wiphy_name(dev->wiphy), type);
579 break;
580 }
581 return 0;
582} 576}
583EXPORT_SYMBOL_GPL(p54_rx); 577EXPORT_SYMBOL_GPL(p54_rx);
584 578
@@ -791,6 +785,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
791 struct p54_common *priv = dev->priv; 785 struct p54_common *priv = dev->priv;
792 struct p54_control_hdr *hdr; 786 struct p54_control_hdr *hdr;
793 struct p54_tx_control_filter *filter; 787 struct p54_tx_control_filter *filter;
788 size_t data_len;
794 789
795 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) + 790 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
796 priv->tx_hdr_len, GFP_ATOMIC); 791 priv->tx_hdr_len, GFP_ATOMIC);
@@ -801,8 +796,6 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
801 796
802 filter = (struct p54_tx_control_filter *) hdr->data; 797 filter = (struct p54_tx_control_filter *) hdr->data;
803 hdr->magic1 = cpu_to_le16(0x8001); 798 hdr->magic1 = cpu_to_le16(0x8001);
804 hdr->len = cpu_to_le16(sizeof(*filter));
805 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*filter));
806 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET); 799 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET);
807 800
808 priv->filter_type = filter->filter_type = cpu_to_le16(filter_type); 801 priv->filter_type = filter->filter_type = cpu_to_le16(filter_type);
@@ -813,13 +806,25 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
813 memcpy(filter->bssid, bssid, ETH_ALEN); 806 memcpy(filter->bssid, bssid, ETH_ALEN);
814 807
815 filter->rx_antenna = priv->rx_antenna; 808 filter->rx_antenna = priv->rx_antenna;
816 filter->basic_rate_mask = cpu_to_le32(0x15F);
817 filter->rx_addr = cpu_to_le32(priv->rx_end);
818 filter->max_rx = cpu_to_le16(priv->rx_mtu);
819 filter->rxhw = cpu_to_le16(priv->rxhw);
820 filter->wakeup_timer = cpu_to_le16(500);
821 809
822 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*filter), 1); 810 if (priv->fw_var < 0x500) {
811 data_len = P54_TX_CONTROL_FILTER_V1_LEN;
812 filter->v1.basic_rate_mask = cpu_to_le32(0x15F);
813 filter->v1.rx_addr = cpu_to_le32(priv->rx_end);
814 filter->v1.max_rx = cpu_to_le16(priv->rx_mtu);
815 filter->v1.rxhw = cpu_to_le16(priv->rxhw);
816 filter->v1.wakeup_timer = cpu_to_le16(500);
817 } else {
818 data_len = P54_TX_CONTROL_FILTER_V2_LEN;
819 filter->v2.rx_addr = cpu_to_le32(priv->rx_end);
820 filter->v2.max_rx = cpu_to_le16(priv->rx_mtu);
821 filter->v2.rxhw = cpu_to_le16(priv->rxhw);
822 filter->v2.timer = cpu_to_le16(1000);
823 }
824
825 hdr->len = cpu_to_le16(data_len);
826 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
827 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
823 return 0; 828 return 0;
824} 829}
825 830
@@ -829,6 +834,7 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
829 struct p54_control_hdr *hdr; 834 struct p54_control_hdr *hdr;
830 struct p54_tx_control_channel *chan; 835 struct p54_tx_control_channel *chan;
831 unsigned int i; 836 unsigned int i;
837 size_t data_len;
832 void *entry; 838 void *entry;
833 839
834 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) + 840 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) +
@@ -841,9 +847,8 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
841 chan = (struct p54_tx_control_channel *) hdr->data; 847 chan = (struct p54_tx_control_channel *) hdr->data;
842 848
843 hdr->magic1 = cpu_to_le16(0x8001); 849 hdr->magic1 = cpu_to_le16(0x8001);
844 hdr->len = cpu_to_le16(sizeof(*chan)); 850
845 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE); 851 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
846 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*chan));
847 852
848 chan->flags = cpu_to_le16(0x1); 853 chan->flags = cpu_to_le16(0x1);
849 chan->dwell = cpu_to_le16(0x0); 854 chan->dwell = cpu_to_le16(0x0);
@@ -895,10 +900,20 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
895 break; 900 break;
896 } 901 }
897 902
898 chan->rssical_mul = cpu_to_le16(130); 903 if (priv->fw_var < 0x500) {
899 chan->rssical_add = cpu_to_le16(0xfe70); /* -400 */ 904 data_len = P54_TX_CONTROL_CHANNEL_V1_LEN;
905 chan->v1.rssical_mul = cpu_to_le16(130);
906 chan->v1.rssical_add = cpu_to_le16(0xfe70);
907 } else {
908 data_len = P54_TX_CONTROL_CHANNEL_V2_LEN;
909 chan->v2.rssical_mul = cpu_to_le16(130);
910 chan->v2.rssical_add = cpu_to_le16(0xfe70);
911 chan->v2.basic_rate_mask = cpu_to_le32(0x15f);
912 }
900 913
901 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*chan), 1); 914 hdr->len = cpu_to_le16(data_len);
915 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
916 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
902 return 0; 917 return 0;
903 918
904 err: 919 err: