aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/p54/p54common.c
diff options
context:
space:
mode:
authorChristian Lamparter <chunkeey@web.de>2008-10-14 22:07:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-10-31 19:00:33 -0400
commitb92f30d65aeb0502e2ed8beb80c8465578b40002 (patch)
tree7d2669d864df5368377dcad11c1bbf4be266eff5 /drivers/net/wireless/p54/p54common.c
parent9de5776ff33a006b864341a6ec8d31f1a3c628cf (diff)
p54: fix memory management
We have to be careful if multiple "control frames" are passed in a very short intervals to the device's firmware. As p54_assign_address always put them into same memory location. To guarantee that this won't happen anymore, we have to treat control frames like normal data frames in the devices own memory management. 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.c288
1 files changed, 161 insertions, 127 deletions
diff --git a/drivers/net/wireless/p54/p54common.c b/drivers/net/wireless/p54/p54common.c
index 68ae8c06bbd7..13080b1ba5e7 100644
--- a/drivers/net/wireless/p54/p54common.c
+++ b/drivers/net/wireless/p54/p54common.c
@@ -528,11 +528,55 @@ static void inline p54_wake_free_queues(struct ieee80211_hw *dev)
528 struct p54_common *priv = dev->priv; 528 struct p54_common *priv = dev->priv;
529 int i; 529 int i;
530 530
531 if (priv->mode == NL80211_IFTYPE_UNSPECIFIED)
532 return ;
533
531 for (i = 0; i < dev->queues; i++) 534 for (i = 0; i < dev->queues; i++)
532 if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit) 535 if (priv->tx_stats[i + 4].len < priv->tx_stats[i + 4].limit)
533 ieee80211_wake_queue(dev, i); 536 ieee80211_wake_queue(dev, i);
534} 537}
535 538
539void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb)
540{
541 struct p54_common *priv = dev->priv;
542 struct ieee80211_tx_info *info;
543 struct memrecord *range;
544 unsigned long flags;
545 u32 freed = 0, last_addr = priv->rx_start;
546
547 if (!skb || !dev)
548 return;
549
550 spin_lock_irqsave(&priv->tx_queue.lock, flags);
551 info = IEEE80211_SKB_CB(skb);
552 range = (void *)info->rate_driver_data;
553 if (skb->prev != (struct sk_buff *)&priv->tx_queue) {
554 struct ieee80211_tx_info *ni;
555 struct memrecord *mr;
556
557 ni = IEEE80211_SKB_CB(skb->prev);
558 mr = (struct memrecord *)ni->rate_driver_data;
559 last_addr = mr->end_addr;
560 }
561 if (skb->next != (struct sk_buff *)&priv->tx_queue) {
562 struct ieee80211_tx_info *ni;
563 struct memrecord *mr;
564
565 ni = IEEE80211_SKB_CB(skb->next);
566 mr = (struct memrecord *)ni->rate_driver_data;
567 freed = mr->start_addr - last_addr;
568 } else
569 freed = priv->rx_end - last_addr;
570 __skb_unlink(skb, &priv->tx_queue);
571 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
572 kfree_skb(skb);
573
574 if (freed >= priv->headroom + sizeof(struct p54_control_hdr) + 48 +
575 IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
576 p54_wake_free_queues(dev);
577}
578EXPORT_SYMBOL_GPL(p54_free_skb);
579
536static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) 580static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
537{ 581{
538 struct p54_common *priv = dev->priv; 582 struct p54_common *priv = dev->priv;
@@ -705,12 +749,14 @@ EXPORT_SYMBOL_GPL(p54_rx);
705 * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees 749 * marks allocated areas as reserved if necessary. p54_rx_frame_sent frees
706 * allocated areas. 750 * allocated areas.
707 */ 751 */
708static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, 752static int p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
709 struct p54_control_hdr *data, u32 len) 753 struct p54_control_hdr *data, u32 len)
710{ 754{
711 struct p54_common *priv = dev->priv; 755 struct p54_common *priv = dev->priv;
712 struct sk_buff *entry = priv->tx_queue.next; 756 struct sk_buff *entry = priv->tx_queue.next;
713 struct sk_buff *target_skb = NULL; 757 struct sk_buff *target_skb = NULL;
758 struct ieee80211_tx_info *info;
759 struct memrecord *range;
714 u32 last_addr = priv->rx_start; 760 u32 last_addr = priv->rx_start;
715 u32 largest_hole = 0; 761 u32 largest_hole = 0;
716 u32 target_addr = priv->rx_start; 762 u32 target_addr = priv->rx_start;
@@ -718,12 +764,15 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
718 unsigned int left; 764 unsigned int left;
719 len = (len + priv->headroom + priv->tailroom + 3) & ~0x3; 765 len = (len + priv->headroom + priv->tailroom + 3) & ~0x3;
720 766
767 if (!skb)
768 return -EINVAL;
769
721 spin_lock_irqsave(&priv->tx_queue.lock, flags); 770 spin_lock_irqsave(&priv->tx_queue.lock, flags);
722 left = skb_queue_len(&priv->tx_queue); 771 left = skb_queue_len(&priv->tx_queue);
723 while (left--) { 772 while (left--) {
724 u32 hole_size; 773 u32 hole_size;
725 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(entry); 774 info = IEEE80211_SKB_CB(entry);
726 struct memrecord *range = (void *)info->rate_driver_data; 775 range = (void *)info->rate_driver_data;
727 hole_size = range->start_addr - last_addr; 776 hole_size = range->start_addr - last_addr;
728 if (!target_skb && hole_size >= len) { 777 if (!target_skb && hole_size >= len) {
729 target_skb = entry->prev; 778 target_skb = entry->prev;
@@ -738,27 +787,57 @@ static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb,
738 target_skb = priv->tx_queue.prev; 787 target_skb = priv->tx_queue.prev;
739 largest_hole = max(largest_hole, priv->rx_end - last_addr - len); 788 largest_hole = max(largest_hole, priv->rx_end - last_addr - len);
740 if (!skb_queue_empty(&priv->tx_queue)) { 789 if (!skb_queue_empty(&priv->tx_queue)) {
741 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(target_skb); 790 info = IEEE80211_SKB_CB(target_skb);
742 struct memrecord *range = (void *)info->rate_driver_data; 791 range = (void *)info->rate_driver_data;
743 target_addr = range->end_addr; 792 target_addr = range->end_addr;
744 } 793 }
745 } else 794 } else
746 largest_hole = max(largest_hole, priv->rx_end - last_addr); 795 largest_hole = max(largest_hole, priv->rx_end - last_addr);
747 796
748 if (skb) { 797 if (!target_skb) {
749 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 798 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
750 struct memrecord *range = (void *)info->rate_driver_data; 799 ieee80211_stop_queues(dev);
751 range->start_addr = target_addr; 800 return -ENOMEM;
752 range->end_addr = target_addr + len;
753 __skb_queue_after(&priv->tx_queue, target_skb, skb);
754 if (largest_hole < priv->rx_mtu + priv->headroom +
755 priv->tailroom +
756 sizeof(struct p54_control_hdr))
757 ieee80211_stop_queues(dev);
758 } 801 }
802
803 info = IEEE80211_SKB_CB(skb);
804 range = (void *)info->rate_driver_data;
805 range->start_addr = target_addr;
806 range->end_addr = target_addr + len;
807 __skb_queue_after(&priv->tx_queue, target_skb, skb);
759 spin_unlock_irqrestore(&priv->tx_queue.lock, flags); 808 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
760 809
810 if (largest_hole < priv->headroom + sizeof(struct p54_control_hdr) +
811 48 + IEEE80211_MAX_RTS_THRESHOLD + priv->tailroom)
812 ieee80211_stop_queues(dev);
813
761 data->req_id = cpu_to_le32(target_addr + priv->headroom); 814 data->req_id = cpu_to_le32(target_addr + priv->headroom);
815 return 0;
816}
817
818static struct sk_buff *p54_alloc_skb(struct ieee80211_hw *dev,
819 u16 hdr_flags, u16 len, u16 type, gfp_t memflags)
820{
821 struct p54_common *priv = dev->priv;
822 struct p54_control_hdr *hdr;
823 struct sk_buff *skb;
824
825 skb = __dev_alloc_skb(len + priv->tx_hdr_len, memflags);
826 if (!skb)
827 return NULL;
828 skb_reserve(skb, priv->tx_hdr_len);
829
830 hdr = (struct p54_control_hdr *) skb_put(skb, sizeof(*hdr));
831 hdr->magic1 = cpu_to_le16(hdr_flags);
832 hdr->len = cpu_to_le16(len - sizeof(*hdr));
833 hdr->type = cpu_to_le16(type);
834 hdr->retry1 = hdr->retry2 = 0;
835
836 if (unlikely(p54_assign_address(dev, skb, hdr, len))) {
837 kfree_skb(skb);
838 return NULL;
839 }
840 return skb;
762} 841}
763 842
764int p54_read_eeprom(struct ieee80211_hw *dev) 843int p54_read_eeprom(struct ieee80211_hw *dev)
@@ -766,36 +845,31 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
766 struct p54_common *priv = dev->priv; 845 struct p54_common *priv = dev->priv;
767 struct p54_control_hdr *hdr = NULL; 846 struct p54_control_hdr *hdr = NULL;
768 struct p54_eeprom_lm86 *eeprom_hdr; 847 struct p54_eeprom_lm86 *eeprom_hdr;
848 struct sk_buff *skb;
769 size_t eeprom_size = 0x2020, offset = 0, blocksize; 849 size_t eeprom_size = 0x2020, offset = 0, blocksize;
770 int ret = -ENOMEM; 850 int ret = -ENOMEM;
771 void *eeprom = NULL; 851 void *eeprom = NULL;
772 852
773 hdr = (struct p54_control_hdr *)kzalloc(sizeof(*hdr) + 853 skb = p54_alloc_skb(dev, 0x8000, sizeof(*hdr) + sizeof(*eeprom_hdr) +
774 sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN, GFP_KERNEL); 854 EEPROM_READBACK_LEN,
775 if (!hdr) 855 P54_CONTROL_TYPE_EEPROM_READBACK, GFP_KERNEL);
856 if (!skb)
776 goto free; 857 goto free;
777
778 priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL); 858 priv->eeprom = kzalloc(EEPROM_READBACK_LEN, GFP_KERNEL);
779 if (!priv->eeprom) 859 if (!priv->eeprom)
780 goto free; 860 goto free;
781
782 eeprom = kzalloc(eeprom_size, GFP_KERNEL); 861 eeprom = kzalloc(eeprom_size, GFP_KERNEL);
783 if (!eeprom) 862 if (!eeprom)
784 goto free; 863 goto free;
785 864
786 hdr->magic1 = cpu_to_le16(0x8000); 865 eeprom_hdr = (struct p54_eeprom_lm86 *) skb_put(skb,
787 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_EEPROM_READBACK); 866 sizeof(*eeprom_hdr) + EEPROM_READBACK_LEN);
788 hdr->retry1 = hdr->retry2 = 0;
789 eeprom_hdr = (struct p54_eeprom_lm86 *) hdr->data;
790 867
791 while (eeprom_size) { 868 while (eeprom_size) {
792 blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN); 869 blocksize = min(eeprom_size, (size_t)EEPROM_READBACK_LEN);
793 hdr->len = cpu_to_le16(blocksize + sizeof(*eeprom_hdr));
794 eeprom_hdr->offset = cpu_to_le16(offset); 870 eeprom_hdr->offset = cpu_to_le16(offset);
795 eeprom_hdr->len = cpu_to_le16(blocksize); 871 eeprom_hdr->len = cpu_to_le16(blocksize);
796 p54_assign_address(dev, NULL, hdr, le16_to_cpu(hdr->len) + 872 priv->tx(dev, skb, 0);
797 sizeof(*hdr));
798 priv->tx(dev, hdr, le16_to_cpu(hdr->len) + sizeof(*hdr), 0);
799 873
800 if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) { 874 if (!wait_for_completion_interruptible_timeout(&priv->eeprom_comp, HZ)) {
801 printk(KERN_ERR "%s: device does not respond!\n", 875 printk(KERN_ERR "%s: device does not respond!\n",
@@ -813,7 +887,7 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
813free: 887free:
814 kfree(priv->eeprom); 888 kfree(priv->eeprom);
815 priv->eeprom = NULL; 889 priv->eeprom = NULL;
816 kfree(hdr); 890 p54_free_skb(dev, skb);
817 kfree(eeprom); 891 kfree(eeprom);
818 892
819 return ret; 893 return ret;
@@ -936,9 +1010,11 @@ static int p54_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
936 txhdr->align[0] = padding; 1010 txhdr->align[0] = padding;
937 1011
938 /* modifies skb->cb and with it info, so must be last! */ 1012 /* modifies skb->cb and with it info, so must be last! */
939 p54_assign_address(dev, skb, hdr, skb->len); 1013 if (unlikely(p54_assign_address(dev, skb, hdr, skb->len))) {
940 1014 skb_pull(skb, sizeof(*hdr) + sizeof(*txhdr) + padding);
941 priv->tx(dev, hdr, skb->len, 0); 1015 return NETDEV_TX_BUSY;
1016 }
1017 priv->tx(dev, skb, 0);
942 return 0; 1018 return 0;
943} 1019}
944 1020
@@ -946,22 +1022,22 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
946 const u8 *bssid) 1022 const u8 *bssid)
947{ 1023{
948 struct p54_common *priv = dev->priv; 1024 struct p54_common *priv = dev->priv;
949 struct p54_control_hdr *hdr; 1025 struct sk_buff *skb;
950 struct p54_tx_control_filter *filter; 1026 struct p54_tx_control_filter *filter;
951 size_t data_len; 1027 u16 data_len = sizeof(struct p54_control_hdr) + sizeof(*filter);
952
953 hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
954 priv->tx_hdr_len, GFP_ATOMIC);
955 if (!hdr)
956 return -ENOMEM;
957 1028
958 hdr = (void *)hdr + priv->tx_hdr_len; 1029 if (priv->fw_var < 0x500)
1030 data_len += P54_TX_CONTROL_FILTER_V1_LEN;
1031 else
1032 data_len += P54_TX_CONTROL_FILTER_V2_LEN;
959 1033
960 filter = (struct p54_tx_control_filter *) hdr->data; 1034 skb = p54_alloc_skb(dev, 0x8001, data_len, P54_CONTROL_TYPE_FILTER_SET,
961 hdr->magic1 = cpu_to_le16(0x8001); 1035 GFP_ATOMIC);
962 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_FILTER_SET); 1036 if (!skb)
1037 return -ENOMEM;
963 1038
964 priv->filter_type = filter->filter_type = cpu_to_le16(filter_type); 1039 filter = (struct p54_tx_control_filter *) skb_put(skb, sizeof(*filter));
1040 filter->filter_type = priv->filter_type = cpu_to_le16(filter_type);
965 memcpy(filter->mac_addr, priv->mac_addr, ETH_ALEN); 1041 memcpy(filter->mac_addr, priv->mac_addr, ETH_ALEN);
966 if (!bssid) 1042 if (!bssid)
967 memset(filter->bssid, ~0, ETH_ALEN); 1043 memset(filter->bssid, ~0, ETH_ALEN);
@@ -969,47 +1045,37 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
969 memcpy(filter->bssid, bssid, ETH_ALEN); 1045 memcpy(filter->bssid, bssid, ETH_ALEN);
970 filter->rx_antenna = priv->rx_antenna; 1046 filter->rx_antenna = priv->rx_antenna;
971 if (priv->fw_var < 0x500) { 1047 if (priv->fw_var < 0x500) {
972 data_len = P54_TX_CONTROL_FILTER_V1_LEN;
973 filter->v1.basic_rate_mask = cpu_to_le32(0x15f); 1048 filter->v1.basic_rate_mask = cpu_to_le32(0x15f);
974 filter->v1.rx_addr = cpu_to_le32(priv->rx_end); 1049 filter->v1.rx_addr = cpu_to_le32(priv->rx_end);
975 filter->v1.max_rx = cpu_to_le16(priv->rx_mtu); 1050 filter->v1.max_rx = cpu_to_le16(priv->rx_mtu);
976 filter->v1.rxhw = cpu_to_le16(priv->rxhw); 1051 filter->v1.rxhw = cpu_to_le16(priv->rxhw);
977 filter->v1.wakeup_timer = cpu_to_le16(500); 1052 filter->v1.wakeup_timer = cpu_to_le16(500);
978 } else { 1053 } else {
979 data_len = P54_TX_CONTROL_FILTER_V2_LEN;
980 filter->v2.rx_addr = cpu_to_le32(priv->rx_end); 1054 filter->v2.rx_addr = cpu_to_le32(priv->rx_end);
981 filter->v2.max_rx = cpu_to_le16(priv->rx_mtu); 1055 filter->v2.max_rx = cpu_to_le16(priv->rx_mtu);
982 filter->v2.rxhw = cpu_to_le16(priv->rxhw); 1056 filter->v2.rxhw = cpu_to_le16(priv->rxhw);
983 filter->v2.timer = cpu_to_le16(1000); 1057 filter->v2.timer = cpu_to_le16(1000);
984 } 1058 }
985 hdr->len = cpu_to_le16(data_len); 1059 priv->tx(dev, skb, 1);
986 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
987 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
988 return 0; 1060 return 0;
989} 1061}
990 1062
991static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq) 1063static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
992{ 1064{
993 struct p54_common *priv = dev->priv; 1065 struct p54_common *priv = dev->priv;
994 struct p54_control_hdr *hdr; 1066 struct sk_buff *skb;
995 struct p54_tx_control_channel *chan; 1067 struct p54_tx_control_channel *chan;
996 unsigned int i; 1068 unsigned int i;
997 size_t data_len; 1069 size_t data_len = sizeof(struct p54_control_hdr) + sizeof(*chan);
998 void *entry; 1070 void *entry;
999 1071
1000 hdr = kzalloc(sizeof(*hdr) + sizeof(*chan) + 1072 skb = p54_alloc_skb(dev, 0x8001, data_len,
1001 priv->tx_hdr_len, GFP_KERNEL); 1073 P54_CONTROL_TYPE_CHANNEL_CHANGE, GFP_ATOMIC);
1002 if (!hdr) 1074 if (!skb)
1003 return -ENOMEM; 1075 return -ENOMEM;
1004 1076
1005 hdr = (void *)hdr + priv->tx_hdr_len; 1077 chan = (struct p54_tx_control_channel *) skb_put(skb, sizeof(*chan));
1006 1078 memset(chan->padding1, 0, sizeof(chan->padding1));
1007 chan = (struct p54_tx_control_channel *) hdr->data;
1008
1009 hdr->magic1 = cpu_to_le16(0x8001);
1010
1011 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_CHANNEL_CHANGE);
1012
1013 chan->flags = cpu_to_le16(0x1); 1079 chan->flags = cpu_to_le16(0x1);
1014 chan->dwell = cpu_to_le16(0x0); 1080 chan->dwell = cpu_to_le16(0x0);
1015 1081
@@ -1065,48 +1131,37 @@ static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq)
1065 chan->v1.rssical_mul = cpu_to_le16(130); 1131 chan->v1.rssical_mul = cpu_to_le16(130);
1066 chan->v1.rssical_add = cpu_to_le16(0xfe70); 1132 chan->v1.rssical_add = cpu_to_le16(0xfe70);
1067 } else { 1133 } else {
1068 data_len = P54_TX_CONTROL_CHANNEL_V2_LEN;
1069 chan->v2.rssical_mul = cpu_to_le16(130); 1134 chan->v2.rssical_mul = cpu_to_le16(130);
1070 chan->v2.rssical_add = cpu_to_le16(0xfe70); 1135 chan->v2.rssical_add = cpu_to_le16(0xfe70);
1071 chan->v2.basic_rate_mask = cpu_to_le32(0x15f); 1136 chan->v2.basic_rate_mask = cpu_to_le32(0x15f);
1072 } 1137 }
1073 1138 priv->tx(dev, skb, 1);
1074 hdr->len = cpu_to_le16(data_len);
1075 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + data_len);
1076 priv->tx(dev, hdr, sizeof(*hdr) + data_len, 1);
1077 return 0; 1139 return 0;
1078 1140
1079 err: 1141 err:
1080 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy)); 1142 printk(KERN_ERR "%s: frequency change failed\n", wiphy_name(dev->wiphy));
1081 kfree(hdr); 1143 kfree_skb(skb);
1082 return -EINVAL; 1144 return -EINVAL;
1083} 1145}
1084 1146
1085static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) 1147static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act)
1086{ 1148{
1087 struct p54_common *priv = dev->priv; 1149 struct p54_common *priv = dev->priv;
1088 struct p54_control_hdr *hdr; 1150 struct sk_buff *skb;
1089 struct p54_tx_control_led *led; 1151 struct p54_tx_control_led *led;
1090 1152
1091 hdr = kzalloc(sizeof(*hdr) + sizeof(*led) + 1153 skb = p54_alloc_skb(dev, 0x8001, sizeof(*led) +
1092 priv->tx_hdr_len, GFP_KERNEL); 1154 sizeof(struct p54_control_hdr),
1093 if (!hdr) 1155 P54_CONTROL_TYPE_LED, GFP_ATOMIC);
1156 if (!skb)
1094 return -ENOMEM; 1157 return -ENOMEM;
1095 1158
1096 hdr = (void *)hdr + priv->tx_hdr_len; 1159 led = (struct p54_tx_control_led *)skb_put(skb, sizeof(*led));
1097 hdr->magic1 = cpu_to_le16(0x8001);
1098 hdr->len = cpu_to_le16(sizeof(*led));
1099 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_LED);
1100 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*led));
1101
1102 led = (struct p54_tx_control_led *) hdr->data;
1103 led->mode = cpu_to_le16(mode); 1160 led->mode = cpu_to_le16(mode);
1104 led->led_permanent = cpu_to_le16(link); 1161 led->led_permanent = cpu_to_le16(link);
1105 led->led_temporary = cpu_to_le16(act); 1162 led->led_temporary = cpu_to_le16(act);
1106 led->duration = cpu_to_le16(1000); 1163 led->duration = cpu_to_le16(1000);
1107 1164 priv->tx(dev, skb, 1);
1108 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*led), 1);
1109
1110 return 0; 1165 return 0;
1111} 1166}
1112 1167
@@ -1121,20 +1176,15 @@ do { \
1121static int p54_set_edcf(struct ieee80211_hw *dev) 1176static int p54_set_edcf(struct ieee80211_hw *dev)
1122{ 1177{
1123 struct p54_common *priv = dev->priv; 1178 struct p54_common *priv = dev->priv;
1124 struct p54_control_hdr *hdr; 1179 struct sk_buff *skb;
1125 struct p54_edcf *edcf; 1180 struct p54_edcf *edcf;
1126 1181
1127 hdr = kzalloc(priv->tx_hdr_len + sizeof(*hdr) + sizeof(*edcf), 1182 skb = p54_alloc_skb(dev, 0x8001, sizeof(struct p54_control_hdr) +
1128 GFP_ATOMIC); 1183 sizeof(*edcf), P54_CONTROL_TYPE_DCFINIT, GFP_ATOMIC);
1129 if (!hdr) 1184 if (!skb)
1130 return -ENOMEM; 1185 return -ENOMEM;
1131 1186
1132 hdr = (void *)hdr + priv->tx_hdr_len; 1187 edcf = (struct p54_edcf *)skb_put(skb, sizeof(*edcf));
1133 hdr->magic1 = cpu_to_le16(0x8001);
1134 hdr->len = cpu_to_le16(sizeof(*edcf));
1135 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_DCFINIT);
1136 hdr->retry1 = hdr->retry2 = 0;
1137 edcf = (struct p54_edcf *)hdr->data;
1138 if (priv->use_short_slot) { 1188 if (priv->use_short_slot) {
1139 edcf->slottime = 9; 1189 edcf->slottime = 9;
1140 edcf->sifs = 0x10; 1190 edcf->sifs = 0x10;
@@ -1149,30 +1199,22 @@ static int p54_set_edcf(struct ieee80211_hw *dev)
1149 edcf->round_trip_delay = cpu_to_le16(0); 1199 edcf->round_trip_delay = cpu_to_le16(0);
1150 memset(edcf->mapping, 0, sizeof(edcf->mapping)); 1200 memset(edcf->mapping, 0, sizeof(edcf->mapping));
1151 memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue)); 1201 memcpy(edcf->queue, priv->qos_params, sizeof(edcf->queue));
1152 1202 priv->tx(dev, skb, 1);
1153 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*edcf));
1154 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*edcf), 1);
1155 return 0; 1203 return 0;
1156} 1204}
1157 1205
1158static int p54_init_stats(struct ieee80211_hw *dev) 1206static int p54_init_stats(struct ieee80211_hw *dev)
1159{ 1207{
1160 struct p54_common *priv = dev->priv; 1208 struct p54_common *priv = dev->priv;
1161 struct p54_control_hdr *hdr;
1162 struct p54_statistics *stats;
1163
1164 priv->cached_stats = kzalloc(priv->tx_hdr_len +
1165 sizeof(*hdr) + sizeof(*stats), GFP_KERNEL);
1166 1209
1210 priv->cached_stats = p54_alloc_skb(dev, 0x8000,
1211 sizeof(struct p54_control_hdr) +
1212 sizeof(struct p54_statistics),
1213 P54_CONTROL_TYPE_STAT_READBACK,
1214 GFP_KERNEL);
1167 if (!priv->cached_stats) 1215 if (!priv->cached_stats)
1168 return -ENOMEM; 1216 return -ENOMEM;
1169 1217
1170 hdr = (void *) priv->cached_stats + priv->tx_hdr_len;
1171 hdr->magic1 = cpu_to_le16(0x8000);
1172 hdr->len = cpu_to_le16(sizeof(*stats));
1173 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_STAT_READBACK);
1174 hdr->retry1 = hdr->retry2 = 0;
1175
1176 mod_timer(&priv->stats_timer, jiffies + HZ); 1218 mod_timer(&priv->stats_timer, jiffies + HZ);
1177 return 0; 1219 return 0;
1178} 1220}
@@ -1202,10 +1244,11 @@ static void p54_stop(struct ieee80211_hw *dev)
1202 struct sk_buff *skb; 1244 struct sk_buff *skb;
1203 1245
1204 del_timer(&priv->stats_timer); 1246 del_timer(&priv->stats_timer);
1205 kfree(priv->cached_stats); 1247 p54_free_skb(dev, priv->cached_stats);
1206 priv->cached_stats = NULL; 1248 priv->cached_stats = NULL;
1207 while ((skb = skb_dequeue(&priv->tx_queue))) 1249 while ((skb = skb_dequeue(&priv->tx_queue)))
1208 kfree_skb(skb); 1250 kfree_skb(skb);
1251
1209 priv->stop(dev); 1252 priv->stop(dev);
1210 priv->tsf_high32 = priv->tsf_low32 = 0; 1253 priv->tsf_high32 = priv->tsf_low32 = 0;
1211 priv->mode = NL80211_IFTYPE_UNSPECIFIED; 1254 priv->mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -1333,27 +1376,21 @@ static int p54_conf_tx(struct ieee80211_hw *dev, u16 queue,
1333static int p54_init_xbow_synth(struct ieee80211_hw *dev) 1376static int p54_init_xbow_synth(struct ieee80211_hw *dev)
1334{ 1377{
1335 struct p54_common *priv = dev->priv; 1378 struct p54_common *priv = dev->priv;
1336 struct p54_control_hdr *hdr; 1379 struct sk_buff *skb;
1337 struct p54_tx_control_xbow_synth *xbow; 1380 struct p54_tx_control_xbow_synth *xbow;
1338 1381
1339 hdr = kzalloc(sizeof(*hdr) + sizeof(*xbow) + 1382 skb = p54_alloc_skb(dev, 0x8001, sizeof(struct p54_control_hdr) +
1340 priv->tx_hdr_len, GFP_KERNEL); 1383 sizeof(*xbow), P54_CONTROL_TYPE_XBOW_SYNTH_CFG,
1341 if (!hdr) 1384 GFP_KERNEL);
1385 if (!skb)
1342 return -ENOMEM; 1386 return -ENOMEM;
1343 1387
1344 hdr = (void *)hdr + priv->tx_hdr_len; 1388 xbow = (struct p54_tx_control_xbow_synth *)skb_put(skb, sizeof(*xbow));
1345 hdr->magic1 = cpu_to_le16(0x8001);
1346 hdr->len = cpu_to_le16(sizeof(*xbow));
1347 hdr->type = cpu_to_le16(P54_CONTROL_TYPE_XBOW_SYNTH_CFG);
1348 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*xbow));
1349
1350 xbow = (struct p54_tx_control_xbow_synth *) hdr->data;
1351 xbow->magic1 = cpu_to_le16(0x1); 1389 xbow->magic1 = cpu_to_le16(0x1);
1352 xbow->magic2 = cpu_to_le16(0x2); 1390 xbow->magic2 = cpu_to_le16(0x2);
1353 xbow->freq = cpu_to_le16(5390); 1391 xbow->freq = cpu_to_le16(5390);
1354 1392 memset(xbow->padding, 0, sizeof(xbow->padding));
1355 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*xbow), 1); 1393 priv->tx(dev, skb, 1);
1356
1357 return 0; 1394 return 0;
1358} 1395}
1359 1396
@@ -1361,14 +1398,10 @@ static void p54_statistics_timer(unsigned long data)
1361{ 1398{
1362 struct ieee80211_hw *dev = (struct ieee80211_hw *) data; 1399 struct ieee80211_hw *dev = (struct ieee80211_hw *) data;
1363 struct p54_common *priv = dev->priv; 1400 struct p54_common *priv = dev->priv;
1364 struct p54_control_hdr *hdr;
1365 struct p54_statistics *stats;
1366 1401
1367 BUG_ON(!priv->cached_stats); 1402 BUG_ON(!priv->cached_stats);
1368 hdr = (void *) priv->cached_stats + priv->tx_hdr_len;
1369 p54_assign_address(dev, NULL, hdr, sizeof(*hdr) + sizeof(*stats));
1370 1403
1371 priv->tx(dev, hdr, sizeof(*hdr) + sizeof(*stats), 0); 1404 priv->tx(dev, priv->cached_stats, 0);
1372} 1405}
1373 1406
1374static int p54_get_stats(struct ieee80211_hw *dev, 1407static int p54_get_stats(struct ieee80211_hw *dev,
@@ -1486,7 +1519,8 @@ EXPORT_SYMBOL_GPL(p54_init_common);
1486void p54_free_common(struct ieee80211_hw *dev) 1519void p54_free_common(struct ieee80211_hw *dev)
1487{ 1520{
1488 struct p54_common *priv = dev->priv; 1521 struct p54_common *priv = dev->priv;
1489 kfree(priv->cached_stats); 1522 del_timer(&priv->stats_timer);
1523 kfree_skb(priv->cached_stats);
1490 kfree(priv->iq_autocal); 1524 kfree(priv->iq_autocal);
1491 kfree(priv->output_limit); 1525 kfree(priv->output_limit);
1492 kfree(priv->curve_data); 1526 kfree(priv->curve_data);