diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/p54/p54.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54common.c | 288 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54pci.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/p54/p54usb.c | 74 |
4 files changed, 229 insertions, 163 deletions
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h index 1dace10feb7e..e9988e78a0c2 100644 --- a/drivers/net/wireless/p54/p54.h +++ b/drivers/net/wireless/p54/p54.h | |||
@@ -69,8 +69,8 @@ struct p54_common { | |||
69 | u32 rx_start; | 69 | u32 rx_start; |
70 | u32 rx_end; | 70 | u32 rx_end; |
71 | struct sk_buff_head tx_queue; | 71 | struct sk_buff_head tx_queue; |
72 | void (*tx)(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 72 | void (*tx)(struct ieee80211_hw *dev, struct sk_buff *skb, |
73 | size_t len, int free_on_tx); | 73 | int free_on_tx); |
74 | int (*open)(struct ieee80211_hw *dev); | 74 | int (*open)(struct ieee80211_hw *dev); |
75 | void (*stop)(struct ieee80211_hw *dev); | 75 | void (*stop)(struct ieee80211_hw *dev); |
76 | int mode; | 76 | int mode; |
@@ -102,13 +102,14 @@ struct p54_common { | |||
102 | struct ieee80211_low_level_stats stats; | 102 | struct ieee80211_low_level_stats stats; |
103 | struct timer_list stats_timer; | 103 | struct timer_list stats_timer; |
104 | struct completion stats_comp; | 104 | struct completion stats_comp; |
105 | void *cached_stats; | 105 | struct sk_buff *cached_stats; |
106 | int noise; | 106 | int noise; |
107 | void *eeprom; | 107 | void *eeprom; |
108 | struct completion eeprom_comp; | 108 | struct completion eeprom_comp; |
109 | }; | 109 | }; |
110 | 110 | ||
111 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); | 111 | int p54_rx(struct ieee80211_hw *dev, struct sk_buff *skb); |
112 | void p54_free_skb(struct ieee80211_hw *dev, struct sk_buff *skb); | ||
112 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); | 113 | int p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw); |
113 | int p54_read_eeprom(struct ieee80211_hw *dev); | 114 | int p54_read_eeprom(struct ieee80211_hw *dev); |
114 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); | 115 | struct ieee80211_hw *p54_init_common(size_t priv_data_len); |
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 | ||
539 | void 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 | } | ||
578 | EXPORT_SYMBOL_GPL(p54_free_skb); | ||
579 | |||
536 | static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb) | 580 | static 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 | */ |
708 | static void p54_assign_address(struct ieee80211_hw *dev, struct sk_buff *skb, | 752 | static 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 | |||
818 | static 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 | ||
764 | int p54_read_eeprom(struct ieee80211_hw *dev) | 843 | int 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) | |||
813 | free: | 887 | free: |
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 | ||
991 | static int p54_set_freq(struct ieee80211_hw *dev, __le16 freq) | 1063 | static 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 | ||
1085 | static int p54_set_leds(struct ieee80211_hw *dev, int mode, int link, int act) | 1147 | static 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 { \ | |||
1121 | static int p54_set_edcf(struct ieee80211_hw *dev) | 1176 | static 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 | ||
1158 | static int p54_init_stats(struct ieee80211_hw *dev) | 1206 | static 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, | |||
1333 | static int p54_init_xbow_synth(struct ieee80211_hw *dev) | 1376 | static 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 | ||
1374 | static int p54_get_stats(struct ieee80211_hw *dev, | 1407 | static int p54_get_stats(struct ieee80211_hw *dev, |
@@ -1486,7 +1519,8 @@ EXPORT_SYMBOL_GPL(p54_init_common); | |||
1486 | void p54_free_common(struct ieee80211_hw *dev) | 1519 | void 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); |
diff --git a/drivers/net/wireless/p54/p54pci.c b/drivers/net/wireless/p54/p54pci.c index bba2c90e533f..1bb9584f0355 100644 --- a/drivers/net/wireless/p54/p54pci.c +++ b/drivers/net/wireless/p54/p54pci.c | |||
@@ -235,7 +235,7 @@ static void p54p_check_tx_ring(struct ieee80211_hw *dev, u32 *index, | |||
235 | 235 | ||
236 | while (i != idx) { | 236 | while (i != idx) { |
237 | desc = &ring[i]; | 237 | desc = &ring[i]; |
238 | kfree(tx_buf[i]); | 238 | p54_free_skb(dev, tx_buf[i]); |
239 | tx_buf[i] = NULL; | 239 | tx_buf[i] = NULL; |
240 | 240 | ||
241 | pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), | 241 | pci_unmap_single(priv->pdev, le32_to_cpu(desc->host_addr), |
@@ -306,8 +306,8 @@ static irqreturn_t p54p_interrupt(int irq, void *dev_id) | |||
306 | return reg ? IRQ_HANDLED : IRQ_NONE; | 306 | return reg ? IRQ_HANDLED : IRQ_NONE; |
307 | } | 307 | } |
308 | 308 | ||
309 | static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 309 | static void p54p_tx(struct ieee80211_hw *dev, struct sk_buff *skb, |
310 | size_t len, int free_on_tx) | 310 | int free_on_tx) |
311 | { | 311 | { |
312 | struct p54p_priv *priv = dev->priv; | 312 | struct p54p_priv *priv = dev->priv; |
313 | struct p54p_ring_control *ring_control = priv->ring_control; | 313 | struct p54p_ring_control *ring_control = priv->ring_control; |
@@ -322,18 +322,19 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, | |||
322 | idx = le32_to_cpu(ring_control->host_idx[1]); | 322 | idx = le32_to_cpu(ring_control->host_idx[1]); |
323 | i = idx % ARRAY_SIZE(ring_control->tx_data); | 323 | i = idx % ARRAY_SIZE(ring_control->tx_data); |
324 | 324 | ||
325 | mapping = pci_map_single(priv->pdev, data, len, PCI_DMA_TODEVICE); | 325 | mapping = pci_map_single(priv->pdev, skb->data, skb->len, |
326 | PCI_DMA_TODEVICE); | ||
326 | desc = &ring_control->tx_data[i]; | 327 | desc = &ring_control->tx_data[i]; |
327 | desc->host_addr = cpu_to_le32(mapping); | 328 | desc->host_addr = cpu_to_le32(mapping); |
328 | desc->device_addr = data->req_id; | 329 | desc->device_addr = ((struct p54_control_hdr *)skb->data)->req_id; |
329 | desc->len = cpu_to_le16(len); | 330 | desc->len = cpu_to_le16(skb->len); |
330 | desc->flags = 0; | 331 | desc->flags = 0; |
331 | 332 | ||
332 | wmb(); | 333 | wmb(); |
333 | ring_control->host_idx[1] = cpu_to_le32(idx + 1); | 334 | ring_control->host_idx[1] = cpu_to_le32(idx + 1); |
334 | 335 | ||
335 | if (free_on_tx) | 336 | if (free_on_tx) |
336 | priv->tx_buf_data[i] = data; | 337 | priv->tx_buf_data[i] = skb; |
337 | 338 | ||
338 | spin_unlock_irqrestore(&priv->lock, flags); | 339 | spin_unlock_irqrestore(&priv->lock, flags); |
339 | 340 | ||
@@ -342,8 +343,10 @@ static void p54p_tx(struct ieee80211_hw *dev, struct p54_control_hdr *data, | |||
342 | 343 | ||
343 | /* FIXME: unlikely to happen because the device usually runs out of | 344 | /* FIXME: unlikely to happen because the device usually runs out of |
344 | memory before we fill the ring up, but we can make it impossible */ | 345 | memory before we fill the ring up, but we can make it impossible */ |
345 | if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) | 346 | if (idx - device_idx > ARRAY_SIZE(ring_control->tx_data) - 2) { |
347 | p54_free_skb(dev, skb); | ||
346 | printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy)); | 348 | printk(KERN_INFO "%s: tx overflow.\n", wiphy_name(dev->wiphy)); |
349 | } | ||
347 | } | 350 | } |
348 | 351 | ||
349 | static void p54p_stop(struct ieee80211_hw *dev) | 352 | static void p54p_stop(struct ieee80211_hw *dev) |
@@ -393,7 +396,7 @@ static void p54p_stop(struct ieee80211_hw *dev) | |||
393 | le16_to_cpu(desc->len), | 396 | le16_to_cpu(desc->len), |
394 | PCI_DMA_TODEVICE); | 397 | PCI_DMA_TODEVICE); |
395 | 398 | ||
396 | kfree(priv->tx_buf_data[i]); | 399 | p54_free_skb(dev, priv->tx_buf_data[i]); |
397 | priv->tx_buf_data[i] = NULL; | 400 | priv->tx_buf_data[i] = NULL; |
398 | } | 401 | } |
399 | 402 | ||
@@ -405,7 +408,7 @@ static void p54p_stop(struct ieee80211_hw *dev) | |||
405 | le16_to_cpu(desc->len), | 408 | le16_to_cpu(desc->len), |
406 | PCI_DMA_TODEVICE); | 409 | PCI_DMA_TODEVICE); |
407 | 410 | ||
408 | kfree(priv->tx_buf_mgmt[i]); | 411 | p54_free_skb(dev, priv->tx_buf_mgmt[i]); |
409 | priv->tx_buf_mgmt[i] = NULL; | 412 | priv->tx_buf_mgmt[i] = NULL; |
410 | } | 413 | } |
411 | 414 | ||
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 68f1b80f04d9..88fb65046c71 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -135,6 +135,16 @@ static void p54u_rx_cb(struct urb *urb) | |||
135 | usb_submit_urb(urb, GFP_ATOMIC); | 135 | usb_submit_urb(urb, GFP_ATOMIC); |
136 | } | 136 | } |
137 | 137 | ||
138 | static void p54u_tx_reuse_skb_cb(struct urb *urb) | ||
139 | { | ||
140 | struct sk_buff *skb = urb->context; | ||
141 | struct p54u_priv *priv = (struct p54u_priv *)((struct ieee80211_hw *) | ||
142 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)))->priv; | ||
143 | |||
144 | skb_pull(skb, priv->common.tx_hdr_len); | ||
145 | usb_free_urb(urb); | ||
146 | } | ||
147 | |||
138 | static void p54u_tx_cb(struct urb *urb) | 148 | static void p54u_tx_cb(struct urb *urb) |
139 | { | 149 | { |
140 | usb_free_urb(urb); | 150 | usb_free_urb(urb); |
@@ -146,6 +156,16 @@ static void p54u_tx_free_cb(struct urb *urb) | |||
146 | usb_free_urb(urb); | 156 | usb_free_urb(urb); |
147 | } | 157 | } |
148 | 158 | ||
159 | static void p54u_tx_free_skb_cb(struct urb *urb) | ||
160 | { | ||
161 | struct sk_buff *skb = urb->context; | ||
162 | struct ieee80211_hw *dev = (struct ieee80211_hw *) | ||
163 | usb_get_intfdata(usb_ifnum_to_if(urb->dev, 0)); | ||
164 | |||
165 | p54_free_skb(dev, skb); | ||
166 | usb_free_urb(urb); | ||
167 | } | ||
168 | |||
149 | static int p54u_init_urbs(struct ieee80211_hw *dev) | 169 | static int p54u_init_urbs(struct ieee80211_hw *dev) |
150 | { | 170 | { |
151 | struct p54u_priv *priv = dev->priv; | 171 | struct p54u_priv *priv = dev->priv; |
@@ -192,8 +212,8 @@ static void p54u_free_urbs(struct ieee80211_hw *dev) | |||
192 | } | 212 | } |
193 | } | 213 | } |
194 | 214 | ||
195 | static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 215 | static void p54u_tx_3887(struct ieee80211_hw *dev, struct sk_buff *skb, |
196 | size_t len, int free_on_tx) | 216 | int free_on_tx) |
197 | { | 217 | { |
198 | struct p54u_priv *priv = dev->priv; | 218 | struct p54u_priv *priv = dev->priv; |
199 | struct urb *addr_urb, *data_urb; | 219 | struct urb *addr_urb, *data_urb; |
@@ -209,11 +229,14 @@ static void p54u_tx_3887(struct ieee80211_hw *dev, struct p54_control_hdr *data, | |||
209 | } | 229 | } |
210 | 230 | ||
211 | usb_fill_bulk_urb(addr_urb, priv->udev, | 231 | usb_fill_bulk_urb(addr_urb, priv->udev, |
212 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), &data->req_id, | 232 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
213 | sizeof(data->req_id), p54u_tx_cb, dev); | 233 | &((struct p54_control_hdr *)skb->data)->req_id, 4, |
234 | p54u_tx_cb, dev); | ||
214 | usb_fill_bulk_urb(data_urb, priv->udev, | 235 | usb_fill_bulk_urb(data_urb, priv->udev, |
215 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), data, len, | 236 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
216 | free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); | 237 | skb->data, skb->len, |
238 | free_on_tx ? p54u_tx_free_skb_cb : | ||
239 | p54u_tx_reuse_skb_cb, skb); | ||
217 | 240 | ||
218 | usb_submit_urb(addr_urb, GFP_ATOMIC); | 241 | usb_submit_urb(addr_urb, GFP_ATOMIC); |
219 | usb_submit_urb(data_urb, GFP_ATOMIC); | 242 | usb_submit_urb(data_urb, GFP_ATOMIC); |
@@ -232,31 +255,35 @@ static __le32 p54u_lm87_chksum(const u32 *data, size_t length) | |||
232 | return cpu_to_le32(chk); | 255 | return cpu_to_le32(chk); |
233 | } | 256 | } |
234 | 257 | ||
235 | static void p54u_tx_lm87(struct ieee80211_hw *dev, | 258 | static void p54u_tx_lm87(struct ieee80211_hw *dev, struct sk_buff *skb, |
236 | struct p54_control_hdr *data, | 259 | int free_on_tx) |
237 | size_t len, int free_on_tx) | ||
238 | { | 260 | { |
239 | struct p54u_priv *priv = dev->priv; | 261 | struct p54u_priv *priv = dev->priv; |
240 | struct urb *data_urb; | 262 | struct urb *data_urb; |
241 | struct lm87_tx_hdr *hdr = (void *)data - sizeof(*hdr); | 263 | struct lm87_tx_hdr *hdr; |
264 | __le32 checksum; | ||
265 | __le32 addr = ((struct p54_control_hdr *)skb->data)->req_id; | ||
242 | 266 | ||
243 | data_urb = usb_alloc_urb(0, GFP_ATOMIC); | 267 | data_urb = usb_alloc_urb(0, GFP_ATOMIC); |
244 | if (!data_urb) | 268 | if (!data_urb) |
245 | return; | 269 | return; |
246 | 270 | ||
247 | hdr->chksum = p54u_lm87_chksum((u32 *)data, len); | 271 | checksum = p54u_lm87_chksum((u32 *)skb->data, skb->len); |
248 | hdr->device_addr = data->req_id; | 272 | hdr = (struct lm87_tx_hdr *)skb_push(skb, sizeof(*hdr)); |
273 | hdr->chksum = checksum; | ||
274 | hdr->device_addr = addr; | ||
249 | 275 | ||
250 | usb_fill_bulk_urb(data_urb, priv->udev, | 276 | usb_fill_bulk_urb(data_urb, priv->udev, |
251 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, | 277 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
252 | len + sizeof(*hdr), free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, | 278 | skb->data, skb->len, |
253 | dev); | 279 | free_on_tx ? p54u_tx_free_skb_cb : |
280 | p54u_tx_reuse_skb_cb, skb); | ||
254 | 281 | ||
255 | usb_submit_urb(data_urb, GFP_ATOMIC); | 282 | usb_submit_urb(data_urb, GFP_ATOMIC); |
256 | } | 283 | } |
257 | 284 | ||
258 | static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *data, | 285 | static void p54u_tx_net2280(struct ieee80211_hw *dev, struct sk_buff *skb, |
259 | size_t len, int free_on_tx) | 286 | int free_on_tx) |
260 | { | 287 | { |
261 | struct p54u_priv *priv = dev->priv; | 288 | struct p54u_priv *priv = dev->priv; |
262 | struct urb *int_urb, *data_urb; | 289 | struct urb *int_urb, *data_urb; |
@@ -284,11 +311,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da | |||
284 | reg->addr = cpu_to_le32(P54U_DEV_BASE); | 311 | reg->addr = cpu_to_le32(P54U_DEV_BASE); |
285 | reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); | 312 | reg->val = cpu_to_le32(ISL38XX_DEV_INT_DATA); |
286 | 313 | ||
287 | len += sizeof(*data); | 314 | hdr = (void *)skb_push(skb, sizeof(*hdr)); |
288 | hdr = (void *)data - sizeof(*hdr); | ||
289 | memset(hdr, 0, sizeof(*hdr)); | 315 | memset(hdr, 0, sizeof(*hdr)); |
290 | hdr->device_addr = data->req_id; | 316 | hdr->device_addr = ((struct p54_control_hdr *)skb->data)->req_id; |
291 | hdr->len = cpu_to_le16(len); | 317 | hdr->len = cpu_to_le16(skb->len + sizeof(struct p54_control_hdr)); |
292 | 318 | ||
293 | usb_fill_bulk_urb(int_urb, priv->udev, | 319 | usb_fill_bulk_urb(int_urb, priv->udev, |
294 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), | 320 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DEV), reg, sizeof(*reg), |
@@ -296,8 +322,10 @@ static void p54u_tx_net2280(struct ieee80211_hw *dev, struct p54_control_hdr *da | |||
296 | usb_submit_urb(int_urb, GFP_ATOMIC); | 322 | usb_submit_urb(int_urb, GFP_ATOMIC); |
297 | 323 | ||
298 | usb_fill_bulk_urb(data_urb, priv->udev, | 324 | usb_fill_bulk_urb(data_urb, priv->udev, |
299 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), hdr, len + sizeof(*hdr), | 325 | usb_sndbulkpipe(priv->udev, P54U_PIPE_DATA), |
300 | free_on_tx ? p54u_tx_free_cb : p54u_tx_cb, dev); | 326 | skb->data, skb->len, |
327 | free_on_tx ? p54u_tx_free_skb_cb : | ||
328 | p54u_tx_reuse_skb_cb, skb); | ||
301 | usb_submit_urb(data_urb, GFP_ATOMIC); | 329 | usb_submit_urb(data_urb, GFP_ATOMIC); |
302 | } | 330 | } |
303 | 331 | ||