diff options
author | David S. Miller <davem@davemloft.net> | 2008-06-29 01:57:58 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-06-29 01:57:58 -0400 |
commit | 28f49d8fec19833672a6a813bfde0068fee50bc9 (patch) | |
tree | 6905c5cabc063e44b891ae0af5b5d7cce69e6e71 /drivers/net | |
parent | 332e4af80d1214fbf0e263e1408fc7c5b64ecdd6 (diff) | |
parent | ff28bd94e307c67abb1bccda5d3a9018bd798e08 (diff) |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Diffstat (limited to 'drivers/net')
52 files changed, 1337 insertions, 3759 deletions
diff --git a/drivers/net/b44.c b/drivers/net/b44.c index 59dce6aa0865..c3bda5ce67c4 100644 --- a/drivers/net/b44.c +++ b/drivers/net/b44.c | |||
@@ -148,9 +148,9 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev, | |||
148 | unsigned long offset, | 148 | unsigned long offset, |
149 | enum dma_data_direction dir) | 149 | enum dma_data_direction dir) |
150 | { | 150 | { |
151 | dma_sync_single_range_for_device(sdev->dma_dev, dma_base, | 151 | ssb_dma_sync_single_range_for_device(sdev, dma_base, |
152 | offset & dma_desc_align_mask, | 152 | offset & dma_desc_align_mask, |
153 | dma_desc_sync_size, dir); | 153 | dma_desc_sync_size, dir); |
154 | } | 154 | } |
155 | 155 | ||
156 | static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, | 156 | static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, |
@@ -158,9 +158,9 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev, | |||
158 | unsigned long offset, | 158 | unsigned long offset, |
159 | enum dma_data_direction dir) | 159 | enum dma_data_direction dir) |
160 | { | 160 | { |
161 | dma_sync_single_range_for_cpu(sdev->dma_dev, dma_base, | 161 | ssb_dma_sync_single_range_for_cpu(sdev, dma_base, |
162 | offset & dma_desc_align_mask, | 162 | offset & dma_desc_align_mask, |
163 | dma_desc_sync_size, dir); | 163 | dma_desc_sync_size, dir); |
164 | } | 164 | } |
165 | 165 | ||
166 | static inline unsigned long br32(const struct b44 *bp, unsigned long reg) | 166 | static inline unsigned long br32(const struct b44 *bp, unsigned long reg) |
@@ -613,10 +613,10 @@ static void b44_tx(struct b44 *bp) | |||
613 | 613 | ||
614 | BUG_ON(skb == NULL); | 614 | BUG_ON(skb == NULL); |
615 | 615 | ||
616 | dma_unmap_single(bp->sdev->dma_dev, | 616 | ssb_dma_unmap_single(bp->sdev, |
617 | rp->mapping, | 617 | rp->mapping, |
618 | skb->len, | 618 | skb->len, |
619 | DMA_TO_DEVICE); | 619 | DMA_TO_DEVICE); |
620 | rp->skb = NULL; | 620 | rp->skb = NULL; |
621 | dev_kfree_skb_irq(skb); | 621 | dev_kfree_skb_irq(skb); |
622 | } | 622 | } |
@@ -653,29 +653,29 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
653 | if (skb == NULL) | 653 | if (skb == NULL) |
654 | return -ENOMEM; | 654 | return -ENOMEM; |
655 | 655 | ||
656 | mapping = dma_map_single(bp->sdev->dma_dev, skb->data, | 656 | mapping = ssb_dma_map_single(bp->sdev, skb->data, |
657 | RX_PKT_BUF_SZ, | 657 | RX_PKT_BUF_SZ, |
658 | DMA_FROM_DEVICE); | 658 | DMA_FROM_DEVICE); |
659 | 659 | ||
660 | /* Hardware bug work-around, the chip is unable to do PCI DMA | 660 | /* Hardware bug work-around, the chip is unable to do PCI DMA |
661 | to/from anything above 1GB :-( */ | 661 | to/from anything above 1GB :-( */ |
662 | if (dma_mapping_error(mapping) || | 662 | if (ssb_dma_mapping_error(bp->sdev, mapping) || |
663 | mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { | 663 | mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { |
664 | /* Sigh... */ | 664 | /* Sigh... */ |
665 | if (!dma_mapping_error(mapping)) | 665 | if (!ssb_dma_mapping_error(bp->sdev, mapping)) |
666 | dma_unmap_single(bp->sdev->dma_dev, mapping, | 666 | ssb_dma_unmap_single(bp->sdev, mapping, |
667 | RX_PKT_BUF_SZ, DMA_FROM_DEVICE); | 667 | RX_PKT_BUF_SZ, DMA_FROM_DEVICE); |
668 | dev_kfree_skb_any(skb); | 668 | dev_kfree_skb_any(skb); |
669 | skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); | 669 | skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA); |
670 | if (skb == NULL) | 670 | if (skb == NULL) |
671 | return -ENOMEM; | 671 | return -ENOMEM; |
672 | mapping = dma_map_single(bp->sdev->dma_dev, skb->data, | 672 | mapping = ssb_dma_map_single(bp->sdev, skb->data, |
673 | RX_PKT_BUF_SZ, | 673 | RX_PKT_BUF_SZ, |
674 | DMA_FROM_DEVICE); | 674 | DMA_FROM_DEVICE); |
675 | if (dma_mapping_error(mapping) || | 675 | if (ssb_dma_mapping_error(bp->sdev, mapping) || |
676 | mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { | 676 | mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) { |
677 | if (!dma_mapping_error(mapping)) | 677 | if (!ssb_dma_mapping_error(bp->sdev, mapping)) |
678 | dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE); | 678 | ssb_dma_unmap_single(bp->sdev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE); |
679 | dev_kfree_skb_any(skb); | 679 | dev_kfree_skb_any(skb); |
680 | return -ENOMEM; | 680 | return -ENOMEM; |
681 | } | 681 | } |
@@ -750,9 +750,9 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked) | |||
750 | dest_idx * sizeof(dest_desc), | 750 | dest_idx * sizeof(dest_desc), |
751 | DMA_BIDIRECTIONAL); | 751 | DMA_BIDIRECTIONAL); |
752 | 752 | ||
753 | dma_sync_single_for_device(bp->sdev->dma_dev, le32_to_cpu(src_desc->addr), | 753 | ssb_dma_sync_single_for_device(bp->sdev, le32_to_cpu(src_desc->addr), |
754 | RX_PKT_BUF_SZ, | 754 | RX_PKT_BUF_SZ, |
755 | DMA_FROM_DEVICE); | 755 | DMA_FROM_DEVICE); |
756 | } | 756 | } |
757 | 757 | ||
758 | static int b44_rx(struct b44 *bp, int budget) | 758 | static int b44_rx(struct b44 *bp, int budget) |
@@ -772,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget) | |||
772 | struct rx_header *rh; | 772 | struct rx_header *rh; |
773 | u16 len; | 773 | u16 len; |
774 | 774 | ||
775 | dma_sync_single_for_cpu(bp->sdev->dma_dev, map, | 775 | ssb_dma_sync_single_for_cpu(bp->sdev, map, |
776 | RX_PKT_BUF_SZ, | 776 | RX_PKT_BUF_SZ, |
777 | DMA_FROM_DEVICE); | 777 | DMA_FROM_DEVICE); |
778 | rh = (struct rx_header *) skb->data; | 778 | rh = (struct rx_header *) skb->data; |
@@ -806,8 +806,8 @@ static int b44_rx(struct b44 *bp, int budget) | |||
806 | skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); | 806 | skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod); |
807 | if (skb_size < 0) | 807 | if (skb_size < 0) |
808 | goto drop_it; | 808 | goto drop_it; |
809 | dma_unmap_single(bp->sdev->dma_dev, map, | 809 | ssb_dma_unmap_single(bp->sdev, map, |
810 | skb_size, DMA_FROM_DEVICE); | 810 | skb_size, DMA_FROM_DEVICE); |
811 | /* Leave out rx_header */ | 811 | /* Leave out rx_header */ |
812 | skb_put(skb, len + RX_PKT_OFFSET); | 812 | skb_put(skb, len + RX_PKT_OFFSET); |
813 | skb_pull(skb, RX_PKT_OFFSET); | 813 | skb_pull(skb, RX_PKT_OFFSET); |
@@ -966,25 +966,25 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
966 | goto err_out; | 966 | goto err_out; |
967 | } | 967 | } |
968 | 968 | ||
969 | mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE); | 969 | mapping = ssb_dma_map_single(bp->sdev, skb->data, len, DMA_TO_DEVICE); |
970 | if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { | 970 | if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) { |
971 | struct sk_buff *bounce_skb; | 971 | struct sk_buff *bounce_skb; |
972 | 972 | ||
973 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ | 973 | /* Chip can't handle DMA to/from >1GB, use bounce buffer */ |
974 | if (!dma_mapping_error(mapping)) | 974 | if (!ssb_dma_mapping_error(bp->sdev, mapping)) |
975 | dma_unmap_single(bp->sdev->dma_dev, mapping, len, | 975 | ssb_dma_unmap_single(bp->sdev, mapping, len, |
976 | DMA_TO_DEVICE); | 976 | DMA_TO_DEVICE); |
977 | 977 | ||
978 | bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA); | 978 | bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA); |
979 | if (!bounce_skb) | 979 | if (!bounce_skb) |
980 | goto err_out; | 980 | goto err_out; |
981 | 981 | ||
982 | mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data, | 982 | mapping = ssb_dma_map_single(bp->sdev, bounce_skb->data, |
983 | len, DMA_TO_DEVICE); | 983 | len, DMA_TO_DEVICE); |
984 | if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) { | 984 | if (ssb_dma_mapping_error(bp->sdev, mapping) || mapping + len > DMA_30BIT_MASK) { |
985 | if (!dma_mapping_error(mapping)) | 985 | if (!ssb_dma_mapping_error(bp->sdev, mapping)) |
986 | dma_unmap_single(bp->sdev->dma_dev, mapping, | 986 | ssb_dma_unmap_single(bp->sdev, mapping, |
987 | len, DMA_TO_DEVICE); | 987 | len, DMA_TO_DEVICE); |
988 | dev_kfree_skb_any(bounce_skb); | 988 | dev_kfree_skb_any(bounce_skb); |
989 | goto err_out; | 989 | goto err_out; |
990 | } | 990 | } |
@@ -1082,8 +1082,8 @@ static void b44_free_rings(struct b44 *bp) | |||
1082 | 1082 | ||
1083 | if (rp->skb == NULL) | 1083 | if (rp->skb == NULL) |
1084 | continue; | 1084 | continue; |
1085 | dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ, | 1085 | ssb_dma_unmap_single(bp->sdev, rp->mapping, RX_PKT_BUF_SZ, |
1086 | DMA_FROM_DEVICE); | 1086 | DMA_FROM_DEVICE); |
1087 | dev_kfree_skb_any(rp->skb); | 1087 | dev_kfree_skb_any(rp->skb); |
1088 | rp->skb = NULL; | 1088 | rp->skb = NULL; |
1089 | } | 1089 | } |
@@ -1094,8 +1094,8 @@ static void b44_free_rings(struct b44 *bp) | |||
1094 | 1094 | ||
1095 | if (rp->skb == NULL) | 1095 | if (rp->skb == NULL) |
1096 | continue; | 1096 | continue; |
1097 | dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len, | 1097 | ssb_dma_unmap_single(bp->sdev, rp->mapping, rp->skb->len, |
1098 | DMA_TO_DEVICE); | 1098 | DMA_TO_DEVICE); |
1099 | dev_kfree_skb_any(rp->skb); | 1099 | dev_kfree_skb_any(rp->skb); |
1100 | rp->skb = NULL; | 1100 | rp->skb = NULL; |
1101 | } | 1101 | } |
@@ -1117,14 +1117,14 @@ static void b44_init_rings(struct b44 *bp) | |||
1117 | memset(bp->tx_ring, 0, B44_TX_RING_BYTES); | 1117 | memset(bp->tx_ring, 0, B44_TX_RING_BYTES); |
1118 | 1118 | ||
1119 | if (bp->flags & B44_FLAG_RX_RING_HACK) | 1119 | if (bp->flags & B44_FLAG_RX_RING_HACK) |
1120 | dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma, | 1120 | ssb_dma_sync_single_for_device(bp->sdev, bp->rx_ring_dma, |
1121 | DMA_TABLE_BYTES, | 1121 | DMA_TABLE_BYTES, |
1122 | DMA_BIDIRECTIONAL); | 1122 | DMA_BIDIRECTIONAL); |
1123 | 1123 | ||
1124 | if (bp->flags & B44_FLAG_TX_RING_HACK) | 1124 | if (bp->flags & B44_FLAG_TX_RING_HACK) |
1125 | dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma, | 1125 | ssb_dma_sync_single_for_device(bp->sdev, bp->tx_ring_dma, |
1126 | DMA_TABLE_BYTES, | 1126 | DMA_TABLE_BYTES, |
1127 | DMA_TO_DEVICE); | 1127 | DMA_TO_DEVICE); |
1128 | 1128 | ||
1129 | for (i = 0; i < bp->rx_pending; i++) { | 1129 | for (i = 0; i < bp->rx_pending; i++) { |
1130 | if (b44_alloc_rx_skb(bp, -1, i) < 0) | 1130 | if (b44_alloc_rx_skb(bp, -1, i) < 0) |
@@ -1144,25 +1144,27 @@ static void b44_free_consistent(struct b44 *bp) | |||
1144 | bp->tx_buffers = NULL; | 1144 | bp->tx_buffers = NULL; |
1145 | if (bp->rx_ring) { | 1145 | if (bp->rx_ring) { |
1146 | if (bp->flags & B44_FLAG_RX_RING_HACK) { | 1146 | if (bp->flags & B44_FLAG_RX_RING_HACK) { |
1147 | dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma, | 1147 | ssb_dma_unmap_single(bp->sdev, bp->rx_ring_dma, |
1148 | DMA_TABLE_BYTES, | 1148 | DMA_TABLE_BYTES, |
1149 | DMA_BIDIRECTIONAL); | 1149 | DMA_BIDIRECTIONAL); |
1150 | kfree(bp->rx_ring); | 1150 | kfree(bp->rx_ring); |
1151 | } else | 1151 | } else |
1152 | dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES, | 1152 | ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, |
1153 | bp->rx_ring, bp->rx_ring_dma); | 1153 | bp->rx_ring, bp->rx_ring_dma, |
1154 | GFP_KERNEL); | ||
1154 | bp->rx_ring = NULL; | 1155 | bp->rx_ring = NULL; |
1155 | bp->flags &= ~B44_FLAG_RX_RING_HACK; | 1156 | bp->flags &= ~B44_FLAG_RX_RING_HACK; |
1156 | } | 1157 | } |
1157 | if (bp->tx_ring) { | 1158 | if (bp->tx_ring) { |
1158 | if (bp->flags & B44_FLAG_TX_RING_HACK) { | 1159 | if (bp->flags & B44_FLAG_TX_RING_HACK) { |
1159 | dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma, | 1160 | ssb_dma_unmap_single(bp->sdev, bp->tx_ring_dma, |
1160 | DMA_TABLE_BYTES, | 1161 | DMA_TABLE_BYTES, |
1161 | DMA_TO_DEVICE); | 1162 | DMA_TO_DEVICE); |
1162 | kfree(bp->tx_ring); | 1163 | kfree(bp->tx_ring); |
1163 | } else | 1164 | } else |
1164 | dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES, | 1165 | ssb_dma_free_consistent(bp->sdev, DMA_TABLE_BYTES, |
1165 | bp->tx_ring, bp->tx_ring_dma); | 1166 | bp->tx_ring, bp->tx_ring_dma, |
1167 | GFP_KERNEL); | ||
1166 | bp->tx_ring = NULL; | 1168 | bp->tx_ring = NULL; |
1167 | bp->flags &= ~B44_FLAG_TX_RING_HACK; | 1169 | bp->flags &= ~B44_FLAG_TX_RING_HACK; |
1168 | } | 1170 | } |
@@ -1187,7 +1189,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) | |||
1187 | goto out_err; | 1189 | goto out_err; |
1188 | 1190 | ||
1189 | size = DMA_TABLE_BYTES; | 1191 | size = DMA_TABLE_BYTES; |
1190 | bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->rx_ring_dma, gfp); | 1192 | bp->rx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->rx_ring_dma, gfp); |
1191 | if (!bp->rx_ring) { | 1193 | if (!bp->rx_ring) { |
1192 | /* Allocation may have failed due to pci_alloc_consistent | 1194 | /* Allocation may have failed due to pci_alloc_consistent |
1193 | insisting on use of GFP_DMA, which is more restrictive | 1195 | insisting on use of GFP_DMA, which is more restrictive |
@@ -1199,11 +1201,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) | |||
1199 | if (!rx_ring) | 1201 | if (!rx_ring) |
1200 | goto out_err; | 1202 | goto out_err; |
1201 | 1203 | ||
1202 | rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring, | 1204 | rx_ring_dma = ssb_dma_map_single(bp->sdev, rx_ring, |
1203 | DMA_TABLE_BYTES, | 1205 | DMA_TABLE_BYTES, |
1204 | DMA_BIDIRECTIONAL); | 1206 | DMA_BIDIRECTIONAL); |
1205 | 1207 | ||
1206 | if (dma_mapping_error(rx_ring_dma) || | 1208 | if (ssb_dma_mapping_error(bp->sdev, rx_ring_dma) || |
1207 | rx_ring_dma + size > DMA_30BIT_MASK) { | 1209 | rx_ring_dma + size > DMA_30BIT_MASK) { |
1208 | kfree(rx_ring); | 1210 | kfree(rx_ring); |
1209 | goto out_err; | 1211 | goto out_err; |
@@ -1214,9 +1216,9 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) | |||
1214 | bp->flags |= B44_FLAG_RX_RING_HACK; | 1216 | bp->flags |= B44_FLAG_RX_RING_HACK; |
1215 | } | 1217 | } |
1216 | 1218 | ||
1217 | bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->tx_ring_dma, gfp); | 1219 | bp->tx_ring = ssb_dma_alloc_consistent(bp->sdev, size, &bp->tx_ring_dma, gfp); |
1218 | if (!bp->tx_ring) { | 1220 | if (!bp->tx_ring) { |
1219 | /* Allocation may have failed due to dma_alloc_coherent | 1221 | /* Allocation may have failed due to ssb_dma_alloc_consistent |
1220 | insisting on use of GFP_DMA, which is more restrictive | 1222 | insisting on use of GFP_DMA, which is more restrictive |
1221 | than necessary... */ | 1223 | than necessary... */ |
1222 | struct dma_desc *tx_ring; | 1224 | struct dma_desc *tx_ring; |
@@ -1226,11 +1228,11 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp) | |||
1226 | if (!tx_ring) | 1228 | if (!tx_ring) |
1227 | goto out_err; | 1229 | goto out_err; |
1228 | 1230 | ||
1229 | tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring, | 1231 | tx_ring_dma = ssb_dma_map_single(bp->sdev, tx_ring, |
1230 | DMA_TABLE_BYTES, | 1232 | DMA_TABLE_BYTES, |
1231 | DMA_TO_DEVICE); | 1233 | DMA_TO_DEVICE); |
1232 | 1234 | ||
1233 | if (dma_mapping_error(tx_ring_dma) || | 1235 | if (ssb_dma_mapping_error(bp->sdev, tx_ring_dma) || |
1234 | tx_ring_dma + size > DMA_30BIT_MASK) { | 1236 | tx_ring_dma + size > DMA_30BIT_MASK) { |
1235 | kfree(tx_ring); | 1237 | kfree(tx_ring); |
1236 | goto out_err; | 1238 | goto out_err; |
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c index aa963ac1e37b..6b2dee0cf3a9 100644 --- a/drivers/net/ps3_gelic_wireless.c +++ b/drivers/net/ps3_gelic_wireless.c | |||
@@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len, | |||
571 | * independent format | 571 | * independent format |
572 | */ | 572 | */ |
573 | static char *gelic_wl_translate_scan(struct net_device *netdev, | 573 | static char *gelic_wl_translate_scan(struct net_device *netdev, |
574 | struct iw_request_info *info, | ||
574 | char *ev, | 575 | char *ev, |
575 | char *stop, | 576 | char *stop, |
576 | struct gelic_wl_scan_info *network) | 577 | struct gelic_wl_scan_info *network) |
@@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
588 | iwe.cmd = SIOCGIWAP; | 589 | iwe.cmd = SIOCGIWAP; |
589 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 590 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
590 | memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN); | 591 | memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN); |
591 | ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN); | 592 | ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_ADDR_LEN); |
592 | 593 | ||
593 | /* ESSID */ | 594 | /* ESSID */ |
594 | iwe.cmd = SIOCGIWESSID; | 595 | iwe.cmd = SIOCGIWESSID; |
595 | iwe.u.data.flags = 1; | 596 | iwe.u.data.flags = 1; |
596 | iwe.u.data.length = strnlen(scan->essid, 32); | 597 | iwe.u.data.length = strnlen(scan->essid, 32); |
597 | ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); | 598 | ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid); |
598 | 599 | ||
599 | /* FREQUENCY */ | 600 | /* FREQUENCY */ |
600 | iwe.cmd = SIOCGIWFREQ; | 601 | iwe.cmd = SIOCGIWFREQ; |
601 | iwe.u.freq.m = be16_to_cpu(scan->channel); | 602 | iwe.u.freq.m = be16_to_cpu(scan->channel); |
602 | iwe.u.freq.e = 0; /* table value in MHz */ | 603 | iwe.u.freq.e = 0; /* table value in MHz */ |
603 | iwe.u.freq.i = 0; | 604 | iwe.u.freq.i = 0; |
604 | ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN); | 605 | ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_FREQ_LEN); |
605 | 606 | ||
606 | /* RATES */ | 607 | /* RATES */ |
607 | iwe.cmd = SIOCGIWRATE; | 608 | iwe.cmd = SIOCGIWRATE; |
608 | iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; | 609 | iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; |
609 | /* to stuff multiple values in one event */ | 610 | /* to stuff multiple values in one event */ |
610 | tmp = ev + IW_EV_LCP_LEN; | 611 | tmp = ev + iwe_stream_lcp_len(info); |
611 | /* put them in ascendant order (older is first) */ | 612 | /* put them in ascendant order (older is first) */ |
612 | i = 0; | 613 | i = 0; |
613 | j = 0; | 614 | j = 0; |
@@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
620 | else | 621 | else |
621 | rate = scan->rate[i++] & 0x7f; | 622 | rate = scan->rate[i++] & 0x7f; |
622 | iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */ | 623 | iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */ |
623 | tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, | 624 | tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe, |
624 | IW_EV_PARAM_LEN); | 625 | IW_EV_PARAM_LEN); |
625 | } | 626 | } |
626 | while (j < network->rate_ext_len) { | 627 | while (j < network->rate_ext_len) { |
627 | iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000; | 628 | iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000; |
628 | tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, | 629 | tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe, |
629 | IW_EV_PARAM_LEN); | 630 | IW_EV_PARAM_LEN); |
630 | } | 631 | } |
631 | /* Check if we added any rate */ | 632 | /* Check if we added any rate */ |
632 | if (IW_EV_LCP_LEN < (tmp - ev)) | 633 | if (iwe_stream_lcp_len(info) < (tmp - ev)) |
633 | ev = tmp; | 634 | ev = tmp; |
634 | 635 | ||
635 | /* ENCODE */ | 636 | /* ENCODE */ |
@@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
639 | else | 640 | else |
640 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 641 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
641 | iwe.u.data.length = 0; | 642 | iwe.u.data.length = 0; |
642 | ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); | 643 | ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid); |
643 | 644 | ||
644 | /* MODE */ | 645 | /* MODE */ |
645 | iwe.cmd = SIOCGIWMODE; | 646 | iwe.cmd = SIOCGIWMODE; |
@@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
649 | iwe.u.mode = IW_MODE_MASTER; | 650 | iwe.u.mode = IW_MODE_MASTER; |
650 | else | 651 | else |
651 | iwe.u.mode = IW_MODE_ADHOC; | 652 | iwe.u.mode = IW_MODE_ADHOC; |
652 | ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN); | 653 | ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_UINT_LEN); |
653 | } | 654 | } |
654 | 655 | ||
655 | /* QUAL */ | 656 | /* QUAL */ |
@@ -659,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
659 | iwe.u.qual.level = be16_to_cpu(scan->rssi); | 660 | iwe.u.qual.level = be16_to_cpu(scan->rssi); |
660 | iwe.u.qual.qual = be16_to_cpu(scan->rssi); | 661 | iwe.u.qual.qual = be16_to_cpu(scan->rssi); |
661 | iwe.u.qual.noise = 0; | 662 | iwe.u.qual.noise = 0; |
662 | ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN); | 663 | ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_QUAL_LEN); |
663 | 664 | ||
664 | /* RSN */ | 665 | /* RSN */ |
665 | memset(&iwe, 0, sizeof(iwe)); | 666 | memset(&iwe, 0, sizeof(iwe)); |
@@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
669 | if (len) { | 670 | if (len) { |
670 | iwe.cmd = IWEVGENIE; | 671 | iwe.cmd = IWEVGENIE; |
671 | iwe.u.data.length = len; | 672 | iwe.u.data.length = len; |
672 | ev = iwe_stream_add_point(ev, stop, &iwe, buf); | 673 | ev = iwe_stream_add_point(info, ev, stop, &iwe, buf); |
673 | } | 674 | } |
674 | } else { | 675 | } else { |
675 | /* this scan info has IE data */ | 676 | /* this scan info has IE data */ |
@@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
684 | memcpy(buf, ie_info.wpa.data, ie_info.wpa.len); | 685 | memcpy(buf, ie_info.wpa.data, ie_info.wpa.len); |
685 | iwe.cmd = IWEVGENIE; | 686 | iwe.cmd = IWEVGENIE; |
686 | iwe.u.data.length = ie_info.wpa.len; | 687 | iwe.u.data.length = ie_info.wpa.len; |
687 | ev = iwe_stream_add_point(ev, stop, &iwe, buf); | 688 | ev = iwe_stream_add_point(info, ev, stop, &iwe, buf); |
688 | } | 689 | } |
689 | 690 | ||
690 | if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) { | 691 | if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) { |
@@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev, | |||
692 | memcpy(buf, ie_info.rsn.data, ie_info.rsn.len); | 693 | memcpy(buf, ie_info.rsn.data, ie_info.rsn.len); |
693 | iwe.cmd = IWEVGENIE; | 694 | iwe.cmd = IWEVGENIE; |
694 | iwe.u.data.length = ie_info.rsn.len; | 695 | iwe.u.data.length = ie_info.rsn.len; |
695 | ev = iwe_stream_add_point(ev, stop, &iwe, buf); | 696 | ev = iwe_stream_add_point(info, ev, stop, &iwe, buf); |
696 | } | 697 | } |
697 | } | 698 | } |
698 | 699 | ||
@@ -737,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev, | |||
737 | if (wl->scan_age == 0 || | 738 | if (wl->scan_age == 0 || |
738 | time_after(scan_info->last_scanned + wl->scan_age, | 739 | time_after(scan_info->last_scanned + wl->scan_age, |
739 | this_time)) | 740 | this_time)) |
740 | ev = gelic_wl_translate_scan(netdev, ev, stop, | 741 | ev = gelic_wl_translate_scan(netdev, info, |
742 | ev, stop, | ||
741 | scan_info); | 743 | scan_info); |
742 | else | 744 | else |
743 | pr_debug("%s:entry too old\n", __func__); | 745 | pr_debug("%s:entry too old\n", __func__); |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 22e1e9a1fb73..865f2980c273 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -14,30 +14,6 @@ config WLAN_PRE80211 | |||
14 | This option does not affect the kernel build, it only | 14 | This option does not affect the kernel build, it only |
15 | lets you choose drivers. | 15 | lets you choose drivers. |
16 | 16 | ||
17 | config STRIP | ||
18 | tristate "STRIP (Metricom starmode radio IP)" | ||
19 | depends on INET && WLAN_PRE80211 | ||
20 | select WIRELESS_EXT | ||
21 | ---help--- | ||
22 | Say Y if you have a Metricom radio and intend to use Starmode Radio | ||
23 | IP. STRIP is a radio protocol developed for the MosquitoNet project | ||
24 | (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet | ||
25 | traffic using Metricom radios. Metricom radios are small, battery | ||
26 | powered, 100kbit/sec packet radio transceivers, about the size and | ||
27 | weight of a cellular telephone. (You may also have heard them called | ||
28 | "Metricom modems" but we avoid the term "modem" because it misleads | ||
29 | many people into thinking that you can plug a Metricom modem into a | ||
30 | phone line and use it as a modem.) | ||
31 | |||
32 | You can use STRIP on any Linux machine with a serial port, although | ||
33 | it is obviously most useful for people with laptop computers. If you | ||
34 | think you might get a Metricom radio in the future, there is no harm | ||
35 | in saying Y to STRIP now, except that it makes the kernel a bit | ||
36 | bigger. | ||
37 | |||
38 | To compile this as a module, choose M here: the module will be | ||
39 | called strip. | ||
40 | |||
41 | config ARLAN | 17 | config ARLAN |
42 | tristate "Aironet Arlan 655 & IC2200 DS support" | 18 | tristate "Aironet Arlan 655 & IC2200 DS support" |
43 | depends on ISA && !64BIT && WLAN_PRE80211 | 19 | depends on ISA && !64BIT && WLAN_PRE80211 |
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile index 54a4f6f1db67..2668934abbff 100644 --- a/drivers/net/wireless/Makefile +++ b/drivers/net/wireless/Makefile | |||
@@ -6,7 +6,6 @@ obj-$(CONFIG_IPW2100) += ipw2100.o | |||
6 | 6 | ||
7 | obj-$(CONFIG_IPW2200) += ipw2200.o | 7 | obj-$(CONFIG_IPW2200) += ipw2200.o |
8 | 8 | ||
9 | obj-$(CONFIG_STRIP) += strip.o | ||
10 | obj-$(CONFIG_ARLAN) += arlan.o | 9 | obj-$(CONFIG_ARLAN) += arlan.o |
11 | 10 | ||
12 | arlan-objs := arlan-main.o arlan-proc.o | 11 | arlan-objs := arlan-main.o arlan-proc.o |
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c index 0ba55ba93958..3333d4596b8d 100644 --- a/drivers/net/wireless/adm8211.c +++ b/drivers/net/wireless/adm8211.c | |||
@@ -1685,7 +1685,6 @@ static void adm8211_tx_raw(struct ieee80211_hw *dev, struct sk_buff *skb, | |||
1685 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | 1685 | static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) |
1686 | { | 1686 | { |
1687 | struct adm8211_tx_hdr *txhdr; | 1687 | struct adm8211_tx_hdr *txhdr; |
1688 | u16 fc; | ||
1689 | size_t payload_len, hdrlen; | 1688 | size_t payload_len, hdrlen; |
1690 | int plcp, dur, len, plcp_signal, short_preamble; | 1689 | int plcp, dur, len, plcp_signal, short_preamble; |
1691 | struct ieee80211_hdr *hdr; | 1690 | struct ieee80211_hdr *hdr; |
@@ -1696,8 +1695,7 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1696 | plcp_signal = txrate->bitrate; | 1695 | plcp_signal = txrate->bitrate; |
1697 | 1696 | ||
1698 | hdr = (struct ieee80211_hdr *)skb->data; | 1697 | hdr = (struct ieee80211_hdr *)skb->data; |
1699 | fc = le16_to_cpu(hdr->frame_control) & ~IEEE80211_FCTL_PROTECTED; | 1698 | hdrlen = ieee80211_hdrlen(hdr->frame_control); |
1700 | hdrlen = ieee80211_get_hdrlen(fc); | ||
1701 | memcpy(skb->cb, skb->data, hdrlen); | 1699 | memcpy(skb->cb, skb->data, hdrlen); |
1702 | hdr = (struct ieee80211_hdr *)skb->cb; | 1700 | hdr = (struct ieee80211_hdr *)skb->cb; |
1703 | skb_pull(skb, hdrlen); | 1701 | skb_pull(skb, hdrlen); |
@@ -1711,8 +1709,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1711 | txhdr->frame_control = hdr->frame_control; | 1709 | txhdr->frame_control = hdr->frame_control; |
1712 | 1710 | ||
1713 | len = hdrlen + payload_len + FCS_LEN; | 1711 | len = hdrlen + payload_len + FCS_LEN; |
1714 | if (fc & IEEE80211_FCTL_PROTECTED) | ||
1715 | len += 8; | ||
1716 | 1712 | ||
1717 | txhdr->frag = cpu_to_le16(0x0FFF); | 1713 | txhdr->frag = cpu_to_le16(0x0FFF); |
1718 | adm8211_calc_durations(&dur, &plcp, payload_len, | 1714 | adm8211_calc_durations(&dur, &plcp, payload_len, |
@@ -1730,9 +1726,6 @@ static int adm8211_tx(struct ieee80211_hw *dev, struct sk_buff *skb) | |||
1730 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 1726 | if (info->flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
1731 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); | 1727 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_RTS); |
1732 | 1728 | ||
1733 | if (fc & IEEE80211_FCTL_PROTECTED) | ||
1734 | txhdr->header_control |= cpu_to_le16(ADM8211_TXHDRCTL_ENABLE_WEP_ENGINE); | ||
1735 | |||
1736 | txhdr->retry_limit = info->control.retry_limit; | 1729 | txhdr->retry_limit = info->control.retry_limit; |
1737 | 1730 | ||
1738 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); | 1731 | adm8211_tx_raw(dev, skb, plcp_signal, hdrlen); |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index e30f8b79ea89..b5cd850a4a59 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -85,10 +85,10 @@ static struct pci_driver airo_driver = { | |||
85 | 85 | ||
86 | /* Include Wireless Extension definition and check version - Jean II */ | 86 | /* Include Wireless Extension definition and check version - Jean II */ |
87 | #include <linux/wireless.h> | 87 | #include <linux/wireless.h> |
88 | #define WIRELESS_SPY // enable iwspy support | 88 | #define WIRELESS_SPY /* enable iwspy support */ |
89 | #include <net/iw_handler.h> // New driver API | 89 | #include <net/iw_handler.h> /* New driver API */ |
90 | 90 | ||
91 | #define CISCO_EXT // enable Cisco extensions | 91 | #define CISCO_EXT /* enable Cisco extensions */ |
92 | #ifdef CISCO_EXT | 92 | #ifdef CISCO_EXT |
93 | #include <linux/delay.h> | 93 | #include <linux/delay.h> |
94 | #endif | 94 | #endif |
@@ -281,7 +281,7 @@ MODULE_PARM_DESC(proc_perm, "The permission bits of the files in /proc"); | |||
281 | /* This is a kind of sloppy hack to get this information to OUT4500 and | 281 | /* This is a kind of sloppy hack to get this information to OUT4500 and |
282 | IN4500. I would be extremely interested in the situation where this | 282 | IN4500. I would be extremely interested in the situation where this |
283 | doesn't work though!!! */ | 283 | doesn't work though!!! */ |
284 | static int do8bitIO = 0; | 284 | static int do8bitIO /* = 0 */; |
285 | 285 | ||
286 | /* Return codes */ | 286 | /* Return codes */ |
287 | #define SUCCESS 0 | 287 | #define SUCCESS 0 |
@@ -398,8 +398,8 @@ static int do8bitIO = 0; | |||
398 | #define MAXTXQ 64 | 398 | #define MAXTXQ 64 |
399 | 399 | ||
400 | /* BAP selectors */ | 400 | /* BAP selectors */ |
401 | #define BAP0 0 // Used for receiving packets | 401 | #define BAP0 0 /* Used for receiving packets */ |
402 | #define BAP1 2 // Used for xmiting packets and working with RIDS | 402 | #define BAP1 2 /* Used for xmiting packets and working with RIDS */ |
403 | 403 | ||
404 | /* Flags */ | 404 | /* Flags */ |
405 | #define COMMAND_BUSY 0x8000 | 405 | #define COMMAND_BUSY 0x8000 |
@@ -5522,11 +5522,13 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5522 | Cmd cmd; | 5522 | Cmd cmd; |
5523 | Resp rsp; | 5523 | Resp rsp; |
5524 | 5524 | ||
5525 | if ((ai->APList == NULL) && | 5525 | if (!ai->APList) |
5526 | (ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL)) == NULL) | 5526 | ai->APList = kmalloc(sizeof(APListRid), GFP_KERNEL); |
5527 | if (!ai->APList) | ||
5527 | return -ENOMEM; | 5528 | return -ENOMEM; |
5528 | if ((ai->SSID == NULL) && | 5529 | if (!ai->SSID) |
5529 | (ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL)) == NULL) | 5530 | ai->SSID = kmalloc(sizeof(SsidRid), GFP_KERNEL); |
5531 | if (!ai->SSID) | ||
5530 | return -ENOMEM; | 5532 | return -ENOMEM; |
5531 | readAPListRid(ai, ai->APList); | 5533 | readAPListRid(ai, ai->APList); |
5532 | readSsidRid(ai, ai->SSID); | 5534 | readSsidRid(ai, ai->SSID); |
@@ -5537,7 +5539,7 @@ static int airo_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
5537 | disable_MAC(ai, 0); | 5539 | disable_MAC(ai, 0); |
5538 | netif_device_detach(dev); | 5540 | netif_device_detach(dev); |
5539 | ai->power = state; | 5541 | ai->power = state; |
5540 | cmd.cmd=HOSTSLEEP; | 5542 | cmd.cmd = HOSTSLEEP; |
5541 | issuecommand(ai, &cmd, &rsp); | 5543 | issuecommand(ai, &cmd, &rsp); |
5542 | 5544 | ||
5543 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); | 5545 | pci_enable_wake(pdev, pci_choose_state(pdev, state), 1); |
@@ -5567,7 +5569,7 @@ static int airo_pci_resume(struct pci_dev *pdev) | |||
5567 | msleep(100); | 5569 | msleep(100); |
5568 | } | 5570 | } |
5569 | 5571 | ||
5570 | set_bit (FLAG_COMMIT, &ai->flags); | 5572 | set_bit(FLAG_COMMIT, &ai->flags); |
5571 | disable_MAC(ai, 0); | 5573 | disable_MAC(ai, 0); |
5572 | msleep(200); | 5574 | msleep(200); |
5573 | if (ai->SSID) { | 5575 | if (ai->SSID) { |
@@ -5594,9 +5596,6 @@ static int airo_pci_resume(struct pci_dev *pdev) | |||
5594 | static int __init airo_init_module( void ) | 5596 | static int __init airo_init_module( void ) |
5595 | { | 5597 | { |
5596 | int i; | 5598 | int i; |
5597 | #if 0 | ||
5598 | int have_isa_dev = 0; | ||
5599 | #endif | ||
5600 | 5599 | ||
5601 | airo_entry = create_proc_entry("driver/aironet", | 5600 | airo_entry = create_proc_entry("driver/aironet", |
5602 | S_IFDIR | airo_perm, | 5601 | S_IFDIR | airo_perm, |
@@ -5607,15 +5606,11 @@ static int __init airo_init_module( void ) | |||
5607 | airo_entry->gid = proc_gid; | 5606 | airo_entry->gid = proc_gid; |
5608 | } | 5607 | } |
5609 | 5608 | ||
5610 | for( i = 0; i < 4 && io[i] && irq[i]; i++ ) { | 5609 | for (i = 0; i < 4 && io[i] && irq[i]; i++) { |
5611 | airo_print_info("", "Trying to configure ISA adapter at irq=%d " | 5610 | airo_print_info("", "Trying to configure ISA adapter at irq=%d " |
5612 | "io=0x%x", irq[i], io[i] ); | 5611 | "io=0x%x", irq[i], io[i] ); |
5613 | if (init_airo_card( irq[i], io[i], 0, NULL )) | 5612 | if (init_airo_card( irq[i], io[i], 0, NULL )) |
5614 | #if 0 | ||
5615 | have_isa_dev = 1; | ||
5616 | #else | ||
5617 | /* do nothing */ ; | 5613 | /* do nothing */ ; |
5618 | #endif | ||
5619 | } | 5614 | } |
5620 | 5615 | ||
5621 | #ifdef CONFIG_PCI | 5616 | #ifdef CONFIG_PCI |
@@ -5661,7 +5656,7 @@ static void __exit airo_cleanup_module( void ) | |||
5661 | 5656 | ||
5662 | static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi) | 5657 | static u8 airo_rssi_to_dbm (tdsRssiEntry *rssi_rid, u8 rssi) |
5663 | { | 5658 | { |
5664 | if( !rssi_rid ) | 5659 | if (!rssi_rid) |
5665 | return 0; | 5660 | return 0; |
5666 | 5661 | ||
5667 | return (0x100 - rssi_rid[rssi].rssidBm); | 5662 | return (0x100 - rssi_rid[rssi].rssidBm); |
@@ -5671,10 +5666,10 @@ static u8 airo_dbm_to_pct (tdsRssiEntry *rssi_rid, u8 dbm) | |||
5671 | { | 5666 | { |
5672 | int i; | 5667 | int i; |
5673 | 5668 | ||
5674 | if( !rssi_rid ) | 5669 | if (!rssi_rid) |
5675 | return 0; | 5670 | return 0; |
5676 | 5671 | ||
5677 | for( i = 0; i < 256; i++ ) | 5672 | for (i = 0; i < 256; i++) |
5678 | if (rssi_rid[i].rssidBm == dbm) | 5673 | if (rssi_rid[i].rssidBm == dbm) |
5679 | return rssi_rid[i].rssipct; | 5674 | return rssi_rid[i].rssipct; |
5680 | 5675 | ||
@@ -7156,6 +7151,7 @@ out: | |||
7156 | * format that the Wireless Tools will understand - Jean II | 7151 | * format that the Wireless Tools will understand - Jean II |
7157 | */ | 7152 | */ |
7158 | static inline char *airo_translate_scan(struct net_device *dev, | 7153 | static inline char *airo_translate_scan(struct net_device *dev, |
7154 | struct iw_request_info *info, | ||
7159 | char *current_ev, | 7155 | char *current_ev, |
7160 | char *end_buf, | 7156 | char *end_buf, |
7161 | BSSListRid *bss) | 7157 | BSSListRid *bss) |
@@ -7172,7 +7168,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7172 | iwe.cmd = SIOCGIWAP; | 7168 | iwe.cmd = SIOCGIWAP; |
7173 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 7169 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
7174 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); | 7170 | memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); |
7175 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); | 7171 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
7172 | &iwe, IW_EV_ADDR_LEN); | ||
7176 | 7173 | ||
7177 | /* Other entries will be displayed in the order we give them */ | 7174 | /* Other entries will be displayed in the order we give them */ |
7178 | 7175 | ||
@@ -7182,7 +7179,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7182 | iwe.u.data.length = 32; | 7179 | iwe.u.data.length = 32; |
7183 | iwe.cmd = SIOCGIWESSID; | 7180 | iwe.cmd = SIOCGIWESSID; |
7184 | iwe.u.data.flags = 1; | 7181 | iwe.u.data.flags = 1; |
7185 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); | 7182 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
7183 | &iwe, bss->ssid); | ||
7186 | 7184 | ||
7187 | /* Add mode */ | 7185 | /* Add mode */ |
7188 | iwe.cmd = SIOCGIWMODE; | 7186 | iwe.cmd = SIOCGIWMODE; |
@@ -7192,7 +7190,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7192 | iwe.u.mode = IW_MODE_MASTER; | 7190 | iwe.u.mode = IW_MODE_MASTER; |
7193 | else | 7191 | else |
7194 | iwe.u.mode = IW_MODE_ADHOC; | 7192 | iwe.u.mode = IW_MODE_ADHOC; |
7195 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); | 7193 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
7194 | &iwe, IW_EV_UINT_LEN); | ||
7196 | } | 7195 | } |
7197 | 7196 | ||
7198 | /* Add frequency */ | 7197 | /* Add frequency */ |
@@ -7203,7 +7202,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7203 | */ | 7202 | */ |
7204 | iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000; | 7203 | iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000; |
7205 | iwe.u.freq.e = 1; | 7204 | iwe.u.freq.e = 1; |
7206 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); | 7205 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
7206 | &iwe, IW_EV_FREQ_LEN); | ||
7207 | 7207 | ||
7208 | dBm = le16_to_cpu(bss->dBm); | 7208 | dBm = le16_to_cpu(bss->dBm); |
7209 | 7209 | ||
@@ -7223,7 +7223,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7223 | | IW_QUAL_DBM; | 7223 | | IW_QUAL_DBM; |
7224 | } | 7224 | } |
7225 | iwe.u.qual.noise = ai->wstats.qual.noise; | 7225 | iwe.u.qual.noise = ai->wstats.qual.noise; |
7226 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); | 7226 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
7227 | &iwe, IW_EV_QUAL_LEN); | ||
7227 | 7228 | ||
7228 | /* Add encryption capability */ | 7229 | /* Add encryption capability */ |
7229 | iwe.cmd = SIOCGIWENCODE; | 7230 | iwe.cmd = SIOCGIWENCODE; |
@@ -7232,11 +7233,12 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7232 | else | 7233 | else |
7233 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 7234 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
7234 | iwe.u.data.length = 0; | 7235 | iwe.u.data.length = 0; |
7235 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); | 7236 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
7237 | &iwe, bss->ssid); | ||
7236 | 7238 | ||
7237 | /* Rate : stuffing multiple values in a single event require a bit | 7239 | /* Rate : stuffing multiple values in a single event require a bit |
7238 | * more of magic - Jean II */ | 7240 | * more of magic - Jean II */ |
7239 | current_val = current_ev + IW_EV_LCP_LEN; | 7241 | current_val = current_ev + iwe_stream_lcp_len(info); |
7240 | 7242 | ||
7241 | iwe.cmd = SIOCGIWRATE; | 7243 | iwe.cmd = SIOCGIWRATE; |
7242 | /* Those two flags are ignored... */ | 7244 | /* Those two flags are ignored... */ |
@@ -7249,10 +7251,12 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7249 | /* Bit rate given in 500 kb/s units (+ 0x80) */ | 7251 | /* Bit rate given in 500 kb/s units (+ 0x80) */ |
7250 | iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000); | 7252 | iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000); |
7251 | /* Add new value to event */ | 7253 | /* Add new value to event */ |
7252 | current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); | 7254 | current_val = iwe_stream_add_value(info, current_ev, |
7255 | current_val, end_buf, | ||
7256 | &iwe, IW_EV_PARAM_LEN); | ||
7253 | } | 7257 | } |
7254 | /* Check if we added any event */ | 7258 | /* Check if we added any event */ |
7255 | if((current_val - current_ev) > IW_EV_LCP_LEN) | 7259 | if ((current_val - current_ev) > iwe_stream_lcp_len(info)) |
7256 | current_ev = current_val; | 7260 | current_ev = current_val; |
7257 | 7261 | ||
7258 | /* Beacon interval */ | 7262 | /* Beacon interval */ |
@@ -7261,7 +7265,8 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7261 | iwe.cmd = IWEVCUSTOM; | 7265 | iwe.cmd = IWEVCUSTOM; |
7262 | sprintf(buf, "bcn_int=%d", bss->beaconInterval); | 7266 | sprintf(buf, "bcn_int=%d", bss->beaconInterval); |
7263 | iwe.u.data.length = strlen(buf); | 7267 | iwe.u.data.length = strlen(buf); |
7264 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); | 7268 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
7269 | &iwe, buf); | ||
7265 | kfree(buf); | 7270 | kfree(buf); |
7266 | } | 7271 | } |
7267 | 7272 | ||
@@ -7295,8 +7300,10 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7295 | iwe.cmd = IWEVGENIE; | 7300 | iwe.cmd = IWEVGENIE; |
7296 | iwe.u.data.length = min(info_element->len + 2, | 7301 | iwe.u.data.length = min(info_element->len + 2, |
7297 | MAX_WPA_IE_LEN); | 7302 | MAX_WPA_IE_LEN); |
7298 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 7303 | current_ev = iwe_stream_add_point( |
7299 | &iwe, (char *) info_element); | 7304 | info, current_ev, |
7305 | end_buf, &iwe, | ||
7306 | (char *) info_element); | ||
7300 | } | 7307 | } |
7301 | break; | 7308 | break; |
7302 | 7309 | ||
@@ -7304,8 +7311,9 @@ static inline char *airo_translate_scan(struct net_device *dev, | |||
7304 | iwe.cmd = IWEVGENIE; | 7311 | iwe.cmd = IWEVGENIE; |
7305 | iwe.u.data.length = min(info_element->len + 2, | 7312 | iwe.u.data.length = min(info_element->len + 2, |
7306 | MAX_WPA_IE_LEN); | 7313 | MAX_WPA_IE_LEN); |
7307 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 7314 | current_ev = iwe_stream_add_point( |
7308 | &iwe, (char *) info_element); | 7315 | info, current_ev, end_buf, |
7316 | &iwe, (char *) info_element); | ||
7309 | break; | 7317 | break; |
7310 | 7318 | ||
7311 | default: | 7319 | default: |
@@ -7344,7 +7352,7 @@ static int airo_get_scan(struct net_device *dev, | |||
7344 | 7352 | ||
7345 | list_for_each_entry (net, &ai->network_list, list) { | 7353 | list_for_each_entry (net, &ai->network_list, list) { |
7346 | /* Translate to WE format this entry */ | 7354 | /* Translate to WE format this entry */ |
7347 | current_ev = airo_translate_scan(dev, current_ev, | 7355 | current_ev = airo_translate_scan(dev, info, current_ev, |
7348 | extra + dwrq->length, | 7356 | extra + dwrq->length, |
7349 | &net->bss); | 7357 | &net->bss); |
7350 | 7358 | ||
diff --git a/drivers/net/wireless/ath5k/Kconfig b/drivers/net/wireless/ath5k/Kconfig index f1f2aea2eab4..75383a5df992 100644 --- a/drivers/net/wireless/ath5k/Kconfig +++ b/drivers/net/wireless/ath5k/Kconfig | |||
@@ -1,6 +1,9 @@ | |||
1 | config ATH5K | 1 | config ATH5K |
2 | tristate "Atheros 5xxx wireless cards support" | 2 | tristate "Atheros 5xxx wireless cards support" |
3 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL | 3 | depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL |
4 | select MAC80211_LEDS | ||
5 | select LEDS_CLASS | ||
6 | select NEW_LEDS | ||
4 | ---help--- | 7 | ---help--- |
5 | This module adds support for wireless adapters based on | 8 | This module adds support for wireless adapters based on |
6 | Atheros 5xxx chipset. | 9 | Atheros 5xxx chipset. |
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 85045afc1ba7..a43e9b25169b 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -58,11 +58,6 @@ | |||
58 | #include "reg.h" | 58 | #include "reg.h" |
59 | #include "debug.h" | 59 | #include "debug.h" |
60 | 60 | ||
61 | enum { | ||
62 | ATH_LED_TX, | ||
63 | ATH_LED_RX, | ||
64 | }; | ||
65 | |||
66 | static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ | 61 | static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */ |
67 | 62 | ||
68 | 63 | ||
@@ -309,13 +304,10 @@ static void ath5k_tasklet_reset(unsigned long data); | |||
309 | 304 | ||
310 | static void ath5k_calibrate(unsigned long data); | 305 | static void ath5k_calibrate(unsigned long data); |
311 | /* LED functions */ | 306 | /* LED functions */ |
312 | static void ath5k_led_off(unsigned long data); | 307 | static int ath5k_init_leds(struct ath5k_softc *sc); |
313 | static void ath5k_led_blink(struct ath5k_softc *sc, | 308 | static void ath5k_led_enable(struct ath5k_softc *sc); |
314 | unsigned int on, | 309 | static void ath5k_led_off(struct ath5k_softc *sc); |
315 | unsigned int off); | 310 | static void ath5k_unregister_leds(struct ath5k_softc *sc); |
316 | static void ath5k_led_event(struct ath5k_softc *sc, | ||
317 | int event); | ||
318 | |||
319 | 311 | ||
320 | /* | 312 | /* |
321 | * Module init/exit functions | 313 | * Module init/exit functions |
@@ -596,8 +588,7 @@ ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state) | |||
596 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); | 588 | struct ieee80211_hw *hw = pci_get_drvdata(pdev); |
597 | struct ath5k_softc *sc = hw->priv; | 589 | struct ath5k_softc *sc = hw->priv; |
598 | 590 | ||
599 | if (test_bit(ATH_STAT_LEDSOFT, sc->status)) | 591 | ath5k_led_off(sc); |
600 | ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1); | ||
601 | 592 | ||
602 | ath5k_stop_hw(sc); | 593 | ath5k_stop_hw(sc); |
603 | pci_save_state(pdev); | 594 | pci_save_state(pdev); |
@@ -632,10 +623,7 @@ ath5k_pci_resume(struct pci_dev *pdev) | |||
632 | pci_write_config_byte(pdev, 0x41, 0); | 623 | pci_write_config_byte(pdev, 0x41, 0); |
633 | 624 | ||
634 | ath5k_init(sc); | 625 | ath5k_init(sc); |
635 | if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { | 626 | ath5k_led_enable(sc); |
636 | ath5k_hw_set_gpio_output(ah, sc->led_pin); | ||
637 | ath5k_hw_set_gpio(ah, sc->led_pin, 0); | ||
638 | } | ||
639 | 627 | ||
640 | /* | 628 | /* |
641 | * Reset the key cache since some parts do not | 629 | * Reset the key cache since some parts do not |
@@ -742,27 +730,6 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
742 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); | 730 | tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc); |
743 | tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); | 731 | tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc); |
744 | setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc); | 732 | setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc); |
745 | setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc); | ||
746 | |||
747 | sc->led_on = 0; /* low true */ | ||
748 | /* | ||
749 | * Auto-enable soft led processing for IBM cards and for | ||
750 | * 5211 minipci cards. | ||
751 | */ | ||
752 | if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM || | ||
753 | pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) { | ||
754 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | ||
755 | sc->led_pin = 0; | ||
756 | } | ||
757 | /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */ | ||
758 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) { | ||
759 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | ||
760 | sc->led_pin = 0; | ||
761 | } | ||
762 | if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { | ||
763 | ath5k_hw_set_gpio_output(ah, sc->led_pin); | ||
764 | ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on); | ||
765 | } | ||
766 | 733 | ||
767 | ath5k_hw_get_lladdr(ah, mac); | 734 | ath5k_hw_get_lladdr(ah, mac); |
768 | SET_IEEE80211_PERM_ADDR(hw, mac); | 735 | SET_IEEE80211_PERM_ADDR(hw, mac); |
@@ -776,6 +743,8 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
776 | goto err_queues; | 743 | goto err_queues; |
777 | } | 744 | } |
778 | 745 | ||
746 | ath5k_init_leds(sc); | ||
747 | |||
779 | return 0; | 748 | return 0; |
780 | err_queues: | 749 | err_queues: |
781 | ath5k_txq_release(sc); | 750 | ath5k_txq_release(sc); |
@@ -809,6 +778,7 @@ ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
809 | ath5k_desc_free(sc, pdev); | 778 | ath5k_desc_free(sc, pdev); |
810 | ath5k_txq_release(sc); | 779 | ath5k_txq_release(sc); |
811 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); | 780 | ath5k_hw_release_tx_queue(sc->ah, sc->bhalq); |
781 | ath5k_unregister_leds(sc); | ||
812 | 782 | ||
813 | /* | 783 | /* |
814 | * NB: can't reclaim these until after ieee80211_ifdetach | 784 | * NB: can't reclaim these until after ieee80211_ifdetach |
@@ -1060,65 +1030,9 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
1060 | return 0; | 1030 | return 0; |
1061 | } | 1031 | } |
1062 | 1032 | ||
1063 | /* | ||
1064 | * TODO: CLEAN THIS !!! | ||
1065 | */ | ||
1066 | static void | 1033 | static void |
1067 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) | 1034 | ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode) |
1068 | { | 1035 | { |
1069 | if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) { | ||
1070 | /* from Atheros NDIS driver, w/ permission */ | ||
1071 | static const struct { | ||
1072 | u16 rate; /* tx/rx 802.11 rate */ | ||
1073 | u16 timeOn; /* LED on time (ms) */ | ||
1074 | u16 timeOff; /* LED off time (ms) */ | ||
1075 | } blinkrates[] = { | ||
1076 | { 108, 40, 10 }, | ||
1077 | { 96, 44, 11 }, | ||
1078 | { 72, 50, 13 }, | ||
1079 | { 48, 57, 14 }, | ||
1080 | { 36, 67, 16 }, | ||
1081 | { 24, 80, 20 }, | ||
1082 | { 22, 100, 25 }, | ||
1083 | { 18, 133, 34 }, | ||
1084 | { 12, 160, 40 }, | ||
1085 | { 10, 200, 50 }, | ||
1086 | { 6, 240, 58 }, | ||
1087 | { 4, 267, 66 }, | ||
1088 | { 2, 400, 100 }, | ||
1089 | { 0, 500, 130 } | ||
1090 | }; | ||
1091 | const struct ath5k_rate_table *rt = | ||
1092 | ath5k_hw_get_rate_table(sc->ah, mode); | ||
1093 | unsigned int i, j; | ||
1094 | |||
1095 | BUG_ON(rt == NULL); | ||
1096 | |||
1097 | memset(sc->hwmap, 0, sizeof(sc->hwmap)); | ||
1098 | for (i = 0; i < 32; i++) { | ||
1099 | u8 ix = rt->rate_code_to_index[i]; | ||
1100 | if (ix == 0xff) { | ||
1101 | sc->hwmap[i].ledon = msecs_to_jiffies(500); | ||
1102 | sc->hwmap[i].ledoff = msecs_to_jiffies(130); | ||
1103 | continue; | ||
1104 | } | ||
1105 | sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD; | ||
1106 | /* receive frames include FCS */ | ||
1107 | sc->hwmap[i].rxflags = sc->hwmap[i].txflags | | ||
1108 | IEEE80211_RADIOTAP_F_FCS; | ||
1109 | /* setup blink rate table to avoid per-packet lookup */ | ||
1110 | for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++) | ||
1111 | if (blinkrates[j].rate == /* XXX why 7f? */ | ||
1112 | (rt->rates[ix].dot11_rate&0x7f)) | ||
1113 | break; | ||
1114 | |||
1115 | sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j]. | ||
1116 | timeOn); | ||
1117 | sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j]. | ||
1118 | timeOff); | ||
1119 | } | ||
1120 | } | ||
1121 | |||
1122 | sc->curmode = mode; | 1036 | sc->curmode = mode; |
1123 | 1037 | ||
1124 | if (mode == AR5K_MODE_11A) { | 1038 | if (mode == AR5K_MODE_11A) { |
@@ -1691,9 +1605,9 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1691 | /* Apparently when a default key is used to decrypt the packet | 1605 | /* Apparently when a default key is used to decrypt the packet |
1692 | the hw does not set the index used to decrypt. In such cases | 1606 | the hw does not set the index used to decrypt. In such cases |
1693 | get the index from the packet. */ | 1607 | get the index from the packet. */ |
1694 | if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) && | 1608 | if (ieee80211_has_protected(hdr->frame_control) && |
1695 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && | 1609 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1696 | skb->len >= hlen + 4) { | 1610 | skb->len >= hlen + 4) { |
1697 | keyix = skb->data[hlen + 3] >> 6; | 1611 | keyix = skb->data[hlen + 3] >> 6; |
1698 | 1612 | ||
1699 | if (test_bit(keyix, sc->keymap)) | 1613 | if (test_bit(keyix, sc->keymap)) |
@@ -1712,10 +1626,7 @@ ath5k_check_ibss_tsf(struct ath5k_softc *sc, struct sk_buff *skb, | |||
1712 | u32 hw_tu; | 1626 | u32 hw_tu; |
1713 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; | 1627 | struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)skb->data; |
1714 | 1628 | ||
1715 | if ((le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_FTYPE) == | 1629 | if (ieee80211_is_beacon(mgmt->frame_control) && |
1716 | IEEE80211_FTYPE_MGMT && | ||
1717 | (le16_to_cpu(mgmt->frame_control) & IEEE80211_FCTL_STYPE) == | ||
1718 | IEEE80211_STYPE_BEACON && | ||
1719 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && | 1630 | le16_to_cpu(mgmt->u.beacon.capab_info) & WLAN_CAPABILITY_IBSS && |
1720 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { | 1631 | memcmp(mgmt->bssid, sc->ah->ah_bssid, ETH_ALEN) == 0) { |
1721 | /* | 1632 | /* |
@@ -1903,8 +1814,6 @@ accept: | |||
1903 | ath5k_check_ibss_tsf(sc, skb, &rxs); | 1814 | ath5k_check_ibss_tsf(sc, skb, &rxs); |
1904 | 1815 | ||
1905 | __ieee80211_rx(sc->hw, skb, &rxs); | 1816 | __ieee80211_rx(sc->hw, skb, &rxs); |
1906 | sc->led_rxrate = rs.rs_rate; | ||
1907 | ath5k_led_event(sc, ATH_LED_RX); | ||
1908 | next: | 1817 | next: |
1909 | list_move_tail(&bf->list, &sc->rxbuf); | 1818 | list_move_tail(&bf->list, &sc->rxbuf); |
1910 | } while (ath5k_rxbuf_setup(sc, bf) == 0); | 1819 | } while (ath5k_rxbuf_setup(sc, bf) == 0); |
@@ -1985,13 +1894,9 @@ ath5k_tasklet_tx(unsigned long data) | |||
1985 | struct ath5k_softc *sc = (void *)data; | 1894 | struct ath5k_softc *sc = (void *)data; |
1986 | 1895 | ||
1987 | ath5k_tx_processq(sc, sc->txq); | 1896 | ath5k_tx_processq(sc, sc->txq); |
1988 | |||
1989 | ath5k_led_event(sc, ATH_LED_TX); | ||
1990 | } | 1897 | } |
1991 | 1898 | ||
1992 | 1899 | ||
1993 | |||
1994 | |||
1995 | /*****************\ | 1900 | /*****************\ |
1996 | * Beacon handling * | 1901 | * Beacon handling * |
1997 | \*****************/ | 1902 | \*****************/ |
@@ -2366,11 +2271,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2366 | ieee80211_stop_queues(sc->hw); | 2271 | ieee80211_stop_queues(sc->hw); |
2367 | 2272 | ||
2368 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | 2273 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
2369 | if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { | 2274 | ath5k_led_off(sc); |
2370 | del_timer_sync(&sc->led_tim); | ||
2371 | ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on); | ||
2372 | __clear_bit(ATH_STAT_LEDBLINKING, sc->status); | ||
2373 | } | ||
2374 | ath5k_hw_set_intr(ah, 0); | 2275 | ath5k_hw_set_intr(ah, 0); |
2375 | } | 2276 | } |
2376 | ath5k_txq_cleanup(sc); | 2277 | ath5k_txq_cleanup(sc); |
@@ -2566,55 +2467,124 @@ ath5k_calibrate(unsigned long data) | |||
2566 | \***************/ | 2467 | \***************/ |
2567 | 2468 | ||
2568 | static void | 2469 | static void |
2569 | ath5k_led_off(unsigned long data) | 2470 | ath5k_led_enable(struct ath5k_softc *sc) |
2570 | { | 2471 | { |
2571 | struct ath5k_softc *sc = (void *)data; | 2472 | if (test_bit(ATH_STAT_LEDSOFT, sc->status)) { |
2572 | 2473 | ath5k_hw_set_gpio_output(sc->ah, sc->led_pin); | |
2573 | if (test_bit(ATH_STAT_LEDENDBLINK, sc->status)) | 2474 | ath5k_led_off(sc); |
2574 | __clear_bit(ATH_STAT_LEDBLINKING, sc->status); | ||
2575 | else { | ||
2576 | __set_bit(ATH_STAT_LEDENDBLINK, sc->status); | ||
2577 | ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on); | ||
2578 | mod_timer(&sc->led_tim, jiffies + sc->led_off); | ||
2579 | } | 2475 | } |
2580 | } | 2476 | } |
2581 | 2477 | ||
2582 | /* | ||
2583 | * Blink the LED according to the specified on/off times. | ||
2584 | */ | ||
2585 | static void | 2478 | static void |
2586 | ath5k_led_blink(struct ath5k_softc *sc, unsigned int on, | 2479 | ath5k_led_on(struct ath5k_softc *sc) |
2587 | unsigned int off) | ||
2588 | { | 2480 | { |
2589 | ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off); | 2481 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) |
2482 | return; | ||
2590 | ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on); | 2483 | ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on); |
2591 | __set_bit(ATH_STAT_LEDBLINKING, sc->status); | ||
2592 | __clear_bit(ATH_STAT_LEDENDBLINK, sc->status); | ||
2593 | sc->led_off = off; | ||
2594 | mod_timer(&sc->led_tim, jiffies + on); | ||
2595 | } | 2484 | } |
2596 | 2485 | ||
2597 | static void | 2486 | static void |
2598 | ath5k_led_event(struct ath5k_softc *sc, int event) | 2487 | ath5k_led_off(struct ath5k_softc *sc) |
2599 | { | 2488 | { |
2600 | if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status))) | 2489 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) |
2601 | return; | 2490 | return; |
2602 | if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status))) | 2491 | ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on); |
2603 | return; /* don't interrupt active blink */ | 2492 | } |
2604 | switch (event) { | 2493 | |
2605 | case ATH_LED_TX: | 2494 | static void |
2606 | ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon, | 2495 | ath5k_led_brightness_set(struct led_classdev *led_dev, |
2607 | sc->hwmap[sc->led_txrate].ledoff); | 2496 | enum led_brightness brightness) |
2608 | break; | 2497 | { |
2609 | case ATH_LED_RX: | 2498 | struct ath5k_led *led = container_of(led_dev, struct ath5k_led, |
2610 | ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon, | 2499 | led_dev); |
2611 | sc->hwmap[sc->led_rxrate].ledoff); | 2500 | |
2612 | break; | 2501 | if (brightness == LED_OFF) |
2502 | ath5k_led_off(led->sc); | ||
2503 | else | ||
2504 | ath5k_led_on(led->sc); | ||
2505 | } | ||
2506 | |||
2507 | static int | ||
2508 | ath5k_register_led(struct ath5k_softc *sc, struct ath5k_led *led, | ||
2509 | const char *name, char *trigger) | ||
2510 | { | ||
2511 | int err; | ||
2512 | |||
2513 | led->sc = sc; | ||
2514 | strncpy(led->name, name, sizeof(led->name)); | ||
2515 | led->led_dev.name = led->name; | ||
2516 | led->led_dev.default_trigger = trigger; | ||
2517 | led->led_dev.brightness_set = ath5k_led_brightness_set; | ||
2518 | |||
2519 | err = led_classdev_register(&sc->pdev->dev, &led->led_dev); | ||
2520 | if (err) | ||
2521 | { | ||
2522 | ATH5K_WARN(sc, "could not register LED %s\n", name); | ||
2523 | led->sc = NULL; | ||
2613 | } | 2524 | } |
2525 | return err; | ||
2526 | } | ||
2527 | |||
2528 | static void | ||
2529 | ath5k_unregister_led(struct ath5k_led *led) | ||
2530 | { | ||
2531 | if (!led->sc) | ||
2532 | return; | ||
2533 | led_classdev_unregister(&led->led_dev); | ||
2534 | ath5k_led_off(led->sc); | ||
2535 | led->sc = NULL; | ||
2614 | } | 2536 | } |
2615 | 2537 | ||
2538 | static void | ||
2539 | ath5k_unregister_leds(struct ath5k_softc *sc) | ||
2540 | { | ||
2541 | ath5k_unregister_led(&sc->rx_led); | ||
2542 | ath5k_unregister_led(&sc->tx_led); | ||
2543 | } | ||
2616 | 2544 | ||
2617 | 2545 | ||
2546 | static int | ||
2547 | ath5k_init_leds(struct ath5k_softc *sc) | ||
2548 | { | ||
2549 | int ret = 0; | ||
2550 | struct ieee80211_hw *hw = sc->hw; | ||
2551 | struct pci_dev *pdev = sc->pdev; | ||
2552 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; | ||
2553 | |||
2554 | sc->led_on = 0; /* active low */ | ||
2555 | |||
2556 | /* | ||
2557 | * Auto-enable soft led processing for IBM cards and for | ||
2558 | * 5211 minipci cards. | ||
2559 | */ | ||
2560 | if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM || | ||
2561 | pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) { | ||
2562 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | ||
2563 | sc->led_pin = 0; | ||
2564 | } | ||
2565 | /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */ | ||
2566 | if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) { | ||
2567 | __set_bit(ATH_STAT_LEDSOFT, sc->status); | ||
2568 | sc->led_pin = 1; | ||
2569 | } | ||
2570 | if (!test_bit(ATH_STAT_LEDSOFT, sc->status)) | ||
2571 | goto out; | ||
2572 | |||
2573 | ath5k_led_enable(sc); | ||
2574 | |||
2575 | snprintf(name, sizeof(name), "ath5k-%s::rx", wiphy_name(hw->wiphy)); | ||
2576 | ret = ath5k_register_led(sc, &sc->rx_led, name, | ||
2577 | ieee80211_get_rx_led_name(hw)); | ||
2578 | if (ret) | ||
2579 | goto out; | ||
2580 | |||
2581 | snprintf(name, sizeof(name), "ath5k-%s::tx", wiphy_name(hw->wiphy)); | ||
2582 | ret = ath5k_register_led(sc, &sc->tx_led, name, | ||
2583 | ieee80211_get_tx_led_name(hw)); | ||
2584 | out: | ||
2585 | return ret; | ||
2586 | } | ||
2587 | |||
2618 | 2588 | ||
2619 | /********************\ | 2589 | /********************\ |
2620 | * Mac80211 functions * | 2590 | * Mac80211 functions * |
@@ -2625,7 +2595,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2625 | { | 2595 | { |
2626 | struct ath5k_softc *sc = hw->priv; | 2596 | struct ath5k_softc *sc = hw->priv; |
2627 | struct ath5k_buf *bf; | 2597 | struct ath5k_buf *bf; |
2628 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | ||
2629 | unsigned long flags; | 2598 | unsigned long flags; |
2630 | int hdrlen; | 2599 | int hdrlen; |
2631 | int pad; | 2600 | int pad; |
@@ -2651,8 +2620,6 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2651 | memmove(skb->data, skb->data+pad, hdrlen); | 2620 | memmove(skb->data, skb->data+pad, hdrlen); |
2652 | } | 2621 | } |
2653 | 2622 | ||
2654 | sc->led_txrate = ieee80211_get_tx_rate(hw, info)->hw_value; | ||
2655 | |||
2656 | spin_lock_irqsave(&sc->txbuflock, flags); | 2623 | spin_lock_irqsave(&sc->txbuflock, flags); |
2657 | if (list_empty(&sc->txbuf)) { | 2624 | if (list_empty(&sc->txbuf)) { |
2658 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); | 2625 | ATH5K_ERR(sc, "no further txbuf available, dropping packet\n"); |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index bb4b26d523ab..47f414b09e67 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/list.h> | 45 | #include <linux/list.h> |
46 | #include <linux/wireless.h> | 46 | #include <linux/wireless.h> |
47 | #include <linux/if_ether.h> | 47 | #include <linux/if_ether.h> |
48 | #include <linux/leds.h> | ||
48 | 49 | ||
49 | #include "ath5k.h" | 50 | #include "ath5k.h" |
50 | #include "debug.h" | 51 | #include "debug.h" |
@@ -79,6 +80,19 @@ struct ath5k_txq { | |||
79 | bool setup; | 80 | bool setup; |
80 | }; | 81 | }; |
81 | 82 | ||
83 | #define ATH5K_LED_MAX_NAME_LEN 31 | ||
84 | |||
85 | /* | ||
86 | * State for LED triggers | ||
87 | */ | ||
88 | struct ath5k_led | ||
89 | { | ||
90 | char name[ATH5K_LED_MAX_NAME_LEN + 1]; /* name of the LED in sysfs */ | ||
91 | struct ath5k_softc *sc; /* driver state */ | ||
92 | struct led_classdev led_dev; /* led classdev */ | ||
93 | }; | ||
94 | |||
95 | |||
82 | #if CHAN_DEBUG | 96 | #if CHAN_DEBUG |
83 | #define ATH_CHAN_MAX (26+26+26+200+200) | 97 | #define ATH_CHAN_MAX (26+26+26+200+200) |
84 | #else | 98 | #else |
@@ -118,13 +132,11 @@ struct ath5k_softc { | |||
118 | size_t desc_len; /* size of TX/RX descriptors */ | 132 | size_t desc_len; /* size of TX/RX descriptors */ |
119 | u16 cachelsz; /* cache line size */ | 133 | u16 cachelsz; /* cache line size */ |
120 | 134 | ||
121 | DECLARE_BITMAP(status, 6); | 135 | DECLARE_BITMAP(status, 4); |
122 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ | 136 | #define ATH_STAT_INVALID 0 /* disable hardware accesses */ |
123 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ | 137 | #define ATH_STAT_MRRETRY 1 /* multi-rate retry support */ |
124 | #define ATH_STAT_PROMISC 2 | 138 | #define ATH_STAT_PROMISC 2 |
125 | #define ATH_STAT_LEDBLINKING 3 /* LED blink operation active */ | 139 | #define ATH_STAT_LEDSOFT 3 /* enable LED gpio status */ |
126 | #define ATH_STAT_LEDENDBLINK 4 /* finish LED blink operation */ | ||
127 | #define ATH_STAT_LEDSOFT 5 /* enable LED gpio status */ | ||
128 | 140 | ||
129 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ | 141 | unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ |
130 | unsigned int curmode; /* current phy mode */ | 142 | unsigned int curmode; /* current phy mode */ |
@@ -132,13 +144,6 @@ struct ath5k_softc { | |||
132 | 144 | ||
133 | struct ieee80211_vif *vif; | 145 | struct ieee80211_vif *vif; |
134 | 146 | ||
135 | struct { | ||
136 | u8 rxflags; /* radiotap rx flags */ | ||
137 | u8 txflags; /* radiotap tx flags */ | ||
138 | u16 ledon; /* softled on time */ | ||
139 | u16 ledoff; /* softled off time */ | ||
140 | } hwmap[32]; /* h/w rate ix mappings */ | ||
141 | |||
142 | enum ath5k_int imask; /* interrupt mask copy */ | 147 | enum ath5k_int imask; /* interrupt mask copy */ |
143 | 148 | ||
144 | DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */ | 149 | DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */ |
@@ -148,9 +153,6 @@ struct ath5k_softc { | |||
148 | unsigned int led_pin, /* GPIO pin for driving LED */ | 153 | unsigned int led_pin, /* GPIO pin for driving LED */ |
149 | led_on, /* pin setting for LED on */ | 154 | led_on, /* pin setting for LED on */ |
150 | led_off; /* off time for current blink */ | 155 | led_off; /* off time for current blink */ |
151 | struct timer_list led_tim; /* led off timer */ | ||
152 | u8 led_rxrate; /* current rx rate for LED */ | ||
153 | u8 led_txrate; /* current tx rate for LED */ | ||
154 | 156 | ||
155 | struct tasklet_struct restq; /* reset tasklet */ | 157 | struct tasklet_struct restq; /* reset tasklet */ |
156 | 158 | ||
@@ -159,6 +161,7 @@ struct ath5k_softc { | |||
159 | spinlock_t rxbuflock; | 161 | spinlock_t rxbuflock; |
160 | u32 *rxlink; /* link ptr in last RX desc */ | 162 | u32 *rxlink; /* link ptr in last RX desc */ |
161 | struct tasklet_struct rxtq; /* rx intr tasklet */ | 163 | struct tasklet_struct rxtq; /* rx intr tasklet */ |
164 | struct ath5k_led rx_led; /* rx led */ | ||
162 | 165 | ||
163 | struct list_head txbuf; /* transmit buffer */ | 166 | struct list_head txbuf; /* transmit buffer */ |
164 | spinlock_t txbuflock; | 167 | spinlock_t txbuflock; |
@@ -167,6 +170,7 @@ struct ath5k_softc { | |||
167 | 170 | ||
168 | struct ath5k_txq *txq; /* beacon and tx*/ | 171 | struct ath5k_txq *txq; /* beacon and tx*/ |
169 | struct tasklet_struct txtq; /* tx intr tasklet */ | 172 | struct tasklet_struct txtq; /* tx intr tasklet */ |
173 | struct ath5k_led tx_led; /* tx led */ | ||
170 | 174 | ||
171 | struct ath5k_buf *bbuf; /* beacon buffer */ | 175 | struct ath5k_buf *bbuf; /* beacon buffer */ |
172 | unsigned int bhalq, /* SW q for outgoing beacons */ | 176 | unsigned int bhalq, /* SW q for outgoing beacons */ |
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 77990b56860b..c6d12c53bda4 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c | |||
@@ -31,14 +31,14 @@ | |||
31 | #include "base.h" | 31 | #include "base.h" |
32 | #include "debug.h" | 32 | #include "debug.h" |
33 | 33 | ||
34 | /*Rate tables*/ | 34 | /* Rate tables */ |
35 | static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A; | 35 | static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A; |
36 | static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B; | 36 | static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B; |
37 | static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G; | 37 | static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G; |
38 | static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO; | 38 | static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO; |
39 | static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR; | 39 | static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR; |
40 | 40 | ||
41 | /*Prototypes*/ | 41 | /* Prototypes */ |
42 | static int ath5k_hw_nic_reset(struct ath5k_hw *, u32); | 42 | static int ath5k_hw_nic_reset(struct ath5k_hw *, u32); |
43 | static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool); | 43 | static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool); |
44 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, | 44 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 7bb2646ae0ef..28b6ff3eaa37 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev, | |||
2310 | iwe.cmd = SIOCGIWAP; | 2310 | iwe.cmd = SIOCGIWAP; |
2311 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 2311 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
2312 | memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); | 2312 | memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); |
2313 | current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); | 2313 | current_ev = iwe_stream_add_event(info, current_ev, |
2314 | extra + IW_SCAN_MAX_DATA, | ||
2315 | &iwe, IW_EV_ADDR_LEN); | ||
2314 | 2316 | ||
2315 | iwe.u.data.length = priv->BSSinfo[i].SSIDsize; | 2317 | iwe.u.data.length = priv->BSSinfo[i].SSIDsize; |
2316 | if (iwe.u.data.length > 32) | 2318 | if (iwe.u.data.length > 32) |
2317 | iwe.u.data.length = 32; | 2319 | iwe.u.data.length = 32; |
2318 | iwe.cmd = SIOCGIWESSID; | 2320 | iwe.cmd = SIOCGIWESSID; |
2319 | iwe.u.data.flags = 1; | 2321 | iwe.u.data.flags = 1; |
2320 | current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID); | 2322 | current_ev = iwe_stream_add_point(info, current_ev, |
2323 | extra + IW_SCAN_MAX_DATA, | ||
2324 | &iwe, priv->BSSinfo[i].SSID); | ||
2321 | 2325 | ||
2322 | iwe.cmd = SIOCGIWMODE; | 2326 | iwe.cmd = SIOCGIWMODE; |
2323 | iwe.u.mode = priv->BSSinfo[i].BSStype; | 2327 | iwe.u.mode = priv->BSSinfo[i].BSStype; |
2324 | current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN); | 2328 | current_ev = iwe_stream_add_event(info, current_ev, |
2329 | extra + IW_SCAN_MAX_DATA, | ||
2330 | &iwe, IW_EV_UINT_LEN); | ||
2325 | 2331 | ||
2326 | iwe.cmd = SIOCGIWFREQ; | 2332 | iwe.cmd = SIOCGIWFREQ; |
2327 | iwe.u.freq.m = priv->BSSinfo[i].channel; | 2333 | iwe.u.freq.m = priv->BSSinfo[i].channel; |
2328 | iwe.u.freq.e = 0; | 2334 | iwe.u.freq.e = 0; |
2329 | current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN); | 2335 | current_ev = iwe_stream_add_event(info, current_ev, |
2336 | extra + IW_SCAN_MAX_DATA, | ||
2337 | &iwe, IW_EV_FREQ_LEN); | ||
2330 | 2338 | ||
2331 | /* Add quality statistics */ | 2339 | /* Add quality statistics */ |
2332 | iwe.cmd = IWEVQUAL; | 2340 | iwe.cmd = IWEVQUAL; |
2333 | iwe.u.qual.level = priv->BSSinfo[i].RSSI; | 2341 | iwe.u.qual.level = priv->BSSinfo[i].RSSI; |
2334 | iwe.u.qual.qual = iwe.u.qual.level; | 2342 | iwe.u.qual.qual = iwe.u.qual.level; |
2335 | /* iwe.u.qual.noise = SOMETHING */ | 2343 | /* iwe.u.qual.noise = SOMETHING */ |
2336 | current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN); | 2344 | current_ev = iwe_stream_add_event(info, current_ev, |
2345 | extra + IW_SCAN_MAX_DATA, | ||
2346 | &iwe, IW_EV_QUAL_LEN); | ||
2337 | 2347 | ||
2338 | 2348 | ||
2339 | iwe.cmd = SIOCGIWENCODE; | 2349 | iwe.cmd = SIOCGIWENCODE; |
@@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev, | |||
2342 | else | 2352 | else |
2343 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 2353 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
2344 | iwe.u.data.length = 0; | 2354 | iwe.u.data.length = 0; |
2345 | current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL); | 2355 | current_ev = iwe_stream_add_point(info, current_ev, |
2356 | extra + IW_SCAN_MAX_DATA, | ||
2357 | &iwe, NULL); | ||
2346 | } | 2358 | } |
2347 | 2359 | ||
2348 | /* Length of data */ | 2360 | /* Length of data */ |
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h index 532365f5ecef..edcdfa366452 100644 --- a/drivers/net/wireless/b43/b43.h +++ b/drivers/net/wireless/b43/b43.h | |||
@@ -441,6 +441,8 @@ enum { | |||
441 | #define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */ | 441 | #define B43_FWPANIC_DIE 0 /* Firmware died. Don't auto-restart it. */ |
442 | #define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */ | 442 | #define B43_FWPANIC_RESTART 1 /* Firmware died. Schedule a controller reset. */ |
443 | 443 | ||
444 | /* The firmware register that contains the watchdog counter. */ | ||
445 | #define B43_WATCHDOG_REG 1 | ||
444 | 446 | ||
445 | /* Device specific rate values. | 447 | /* Device specific rate values. |
446 | * The actual values defined here are (rate_in_mbps * 2). | 448 | * The actual values defined here are (rate_in_mbps * 2). |
diff --git a/drivers/net/wireless/b43/debugfs.c b/drivers/net/wireless/b43/debugfs.c index 210e2789c1c3..29851bc1101f 100644 --- a/drivers/net/wireless/b43/debugfs.c +++ b/drivers/net/wireless/b43/debugfs.c | |||
@@ -74,70 +74,327 @@ struct b43_dfs_file * fops_to_dfs_file(struct b43_wldev *dev, | |||
74 | } while (0) | 74 | } while (0) |
75 | 75 | ||
76 | 76 | ||
77 | /* wl->irq_lock is locked */ | 77 | /* The biggest address values for SHM access from the debugfs files. */ |
78 | static ssize_t tsf_read_file(struct b43_wldev *dev, | 78 | #define B43_MAX_SHM_ROUTING 4 |
79 | char *buf, size_t bufsize) | 79 | #define B43_MAX_SHM_ADDR 0xFFFF |
80 | |||
81 | static ssize_t shm16read__read_file(struct b43_wldev *dev, | ||
82 | char *buf, size_t bufsize) | ||
80 | { | 83 | { |
81 | ssize_t count = 0; | 84 | ssize_t count = 0; |
82 | u64 tsf; | 85 | unsigned int routing, addr; |
86 | u16 val; | ||
83 | 87 | ||
84 | b43_tsf_read(dev, &tsf); | 88 | routing = dev->dfsentry->shm16read_routing_next; |
85 | fappend("0x%08x%08x\n", | 89 | addr = dev->dfsentry->shm16read_addr_next; |
86 | (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), | 90 | if ((routing > B43_MAX_SHM_ROUTING) || |
87 | (unsigned int)(tsf & 0xFFFFFFFFULL)); | 91 | (addr > B43_MAX_SHM_ADDR)) |
92 | return -EDESTADDRREQ; | ||
93 | |||
94 | val = b43_shm_read16(dev, routing, addr); | ||
95 | fappend("0x%04X\n", val); | ||
88 | 96 | ||
89 | return count; | 97 | return count; |
90 | } | 98 | } |
91 | 99 | ||
92 | /* wl->irq_lock is locked */ | 100 | static int shm16read__write_file(struct b43_wldev *dev, |
93 | static int tsf_write_file(struct b43_wldev *dev, | 101 | const char *buf, size_t count) |
94 | const char *buf, size_t count) | ||
95 | { | 102 | { |
96 | u64 tsf; | 103 | unsigned int routing, addr; |
104 | int res; | ||
97 | 105 | ||
98 | if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) | 106 | res = sscanf(buf, "0x%X 0x%X", &routing, &addr); |
107 | if (res != 2) | ||
99 | return -EINVAL; | 108 | return -EINVAL; |
100 | b43_tsf_write(dev, tsf); | 109 | if (routing > B43_MAX_SHM_ROUTING) |
110 | return -EADDRNOTAVAIL; | ||
111 | if (addr > B43_MAX_SHM_ADDR) | ||
112 | return -EADDRNOTAVAIL; | ||
113 | if (routing == B43_SHM_SHARED) { | ||
114 | if ((addr % 2) != 0) | ||
115 | return -EADDRNOTAVAIL; | ||
116 | } | ||
117 | |||
118 | dev->dfsentry->shm16read_routing_next = routing; | ||
119 | dev->dfsentry->shm16read_addr_next = addr; | ||
101 | 120 | ||
102 | return 0; | 121 | return 0; |
103 | } | 122 | } |
104 | 123 | ||
105 | /* wl->irq_lock is locked */ | 124 | static int shm16write__write_file(struct b43_wldev *dev, |
106 | static ssize_t ucode_regs_read_file(struct b43_wldev *dev, | 125 | const char *buf, size_t count) |
126 | { | ||
127 | unsigned int routing, addr, mask, set; | ||
128 | u16 val; | ||
129 | int res; | ||
130 | unsigned long flags; | ||
131 | |||
132 | res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X", | ||
133 | &routing, &addr, &mask, &set); | ||
134 | if (res != 4) | ||
135 | return -EINVAL; | ||
136 | if (routing > B43_MAX_SHM_ROUTING) | ||
137 | return -EADDRNOTAVAIL; | ||
138 | if (addr > B43_MAX_SHM_ADDR) | ||
139 | return -EADDRNOTAVAIL; | ||
140 | if (routing == B43_SHM_SHARED) { | ||
141 | if ((addr % 2) != 0) | ||
142 | return -EADDRNOTAVAIL; | ||
143 | } | ||
144 | if ((mask > 0xFFFF) || (set > 0xFFFF)) | ||
145 | return -E2BIG; | ||
146 | |||
147 | spin_lock_irqsave(&dev->wl->shm_lock, flags); | ||
148 | if (mask == 0) | ||
149 | val = 0; | ||
150 | else | ||
151 | val = __b43_shm_read16(dev, routing, addr); | ||
152 | val &= mask; | ||
153 | val |= set; | ||
154 | __b43_shm_write16(dev, routing, addr, val); | ||
155 | spin_unlock_irqrestore(&dev->wl->shm_lock, flags); | ||
156 | |||
157 | return 0; | ||
158 | } | ||
159 | |||
160 | static ssize_t shm32read__read_file(struct b43_wldev *dev, | ||
107 | char *buf, size_t bufsize) | 161 | char *buf, size_t bufsize) |
108 | { | 162 | { |
109 | ssize_t count = 0; | 163 | ssize_t count = 0; |
110 | int i; | 164 | unsigned int routing, addr; |
165 | u32 val; | ||
166 | |||
167 | routing = dev->dfsentry->shm32read_routing_next; | ||
168 | addr = dev->dfsentry->shm32read_addr_next; | ||
169 | if ((routing > B43_MAX_SHM_ROUTING) || | ||
170 | (addr > B43_MAX_SHM_ADDR)) | ||
171 | return -EDESTADDRREQ; | ||
111 | 172 | ||
112 | for (i = 0; i < 64; i++) { | 173 | val = b43_shm_read32(dev, routing, addr); |
113 | fappend("r%d = 0x%04x\n", i, | 174 | fappend("0x%08X\n", val); |
114 | b43_shm_read16(dev, B43_SHM_SCRATCH, i)); | 175 | |
176 | return count; | ||
177 | } | ||
178 | |||
179 | static int shm32read__write_file(struct b43_wldev *dev, | ||
180 | const char *buf, size_t count) | ||
181 | { | ||
182 | unsigned int routing, addr; | ||
183 | int res; | ||
184 | |||
185 | res = sscanf(buf, "0x%X 0x%X", &routing, &addr); | ||
186 | if (res != 2) | ||
187 | return -EINVAL; | ||
188 | if (routing > B43_MAX_SHM_ROUTING) | ||
189 | return -EADDRNOTAVAIL; | ||
190 | if (addr > B43_MAX_SHM_ADDR) | ||
191 | return -EADDRNOTAVAIL; | ||
192 | if (routing == B43_SHM_SHARED) { | ||
193 | if ((addr % 2) != 0) | ||
194 | return -EADDRNOTAVAIL; | ||
195 | } | ||
196 | |||
197 | dev->dfsentry->shm32read_routing_next = routing; | ||
198 | dev->dfsentry->shm32read_addr_next = addr; | ||
199 | |||
200 | return 0; | ||
201 | } | ||
202 | |||
203 | static int shm32write__write_file(struct b43_wldev *dev, | ||
204 | const char *buf, size_t count) | ||
205 | { | ||
206 | unsigned int routing, addr, mask, set; | ||
207 | u32 val; | ||
208 | int res; | ||
209 | unsigned long flags; | ||
210 | |||
211 | res = sscanf(buf, "0x%X 0x%X 0x%X 0x%X", | ||
212 | &routing, &addr, &mask, &set); | ||
213 | if (res != 4) | ||
214 | return -EINVAL; | ||
215 | if (routing > B43_MAX_SHM_ROUTING) | ||
216 | return -EADDRNOTAVAIL; | ||
217 | if (addr > B43_MAX_SHM_ADDR) | ||
218 | return -EADDRNOTAVAIL; | ||
219 | if (routing == B43_SHM_SHARED) { | ||
220 | if ((addr % 2) != 0) | ||
221 | return -EADDRNOTAVAIL; | ||
115 | } | 222 | } |
223 | if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF)) | ||
224 | return -E2BIG; | ||
225 | |||
226 | spin_lock_irqsave(&dev->wl->shm_lock, flags); | ||
227 | if (mask == 0) | ||
228 | val = 0; | ||
229 | else | ||
230 | val = __b43_shm_read32(dev, routing, addr); | ||
231 | val &= mask; | ||
232 | val |= set; | ||
233 | __b43_shm_write32(dev, routing, addr, val); | ||
234 | spin_unlock_irqrestore(&dev->wl->shm_lock, flags); | ||
235 | |||
236 | return 0; | ||
237 | } | ||
238 | |||
239 | /* The biggest MMIO address that we allow access to from the debugfs files. */ | ||
240 | #define B43_MAX_MMIO_ACCESS (0xF00 - 1) | ||
241 | |||
242 | static ssize_t mmio16read__read_file(struct b43_wldev *dev, | ||
243 | char *buf, size_t bufsize) | ||
244 | { | ||
245 | ssize_t count = 0; | ||
246 | unsigned int addr; | ||
247 | u16 val; | ||
248 | |||
249 | addr = dev->dfsentry->mmio16read_next; | ||
250 | if (addr > B43_MAX_MMIO_ACCESS) | ||
251 | return -EDESTADDRREQ; | ||
252 | |||
253 | val = b43_read16(dev, addr); | ||
254 | fappend("0x%04X\n", val); | ||
255 | |||
256 | return count; | ||
257 | } | ||
258 | |||
259 | static int mmio16read__write_file(struct b43_wldev *dev, | ||
260 | const char *buf, size_t count) | ||
261 | { | ||
262 | unsigned int addr; | ||
263 | int res; | ||
264 | |||
265 | res = sscanf(buf, "0x%X", &addr); | ||
266 | if (res != 1) | ||
267 | return -EINVAL; | ||
268 | if (addr > B43_MAX_MMIO_ACCESS) | ||
269 | return -EADDRNOTAVAIL; | ||
270 | if ((addr % 2) != 0) | ||
271 | return -EINVAL; | ||
272 | |||
273 | dev->dfsentry->mmio16read_next = addr; | ||
274 | |||
275 | return 0; | ||
276 | } | ||
277 | |||
278 | static int mmio16write__write_file(struct b43_wldev *dev, | ||
279 | const char *buf, size_t count) | ||
280 | { | ||
281 | unsigned int addr, mask, set; | ||
282 | int res; | ||
283 | u16 val; | ||
284 | |||
285 | res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set); | ||
286 | if (res != 3) | ||
287 | return -EINVAL; | ||
288 | if (addr > B43_MAX_MMIO_ACCESS) | ||
289 | return -EADDRNOTAVAIL; | ||
290 | if ((mask > 0xFFFF) || (set > 0xFFFF)) | ||
291 | return -E2BIG; | ||
292 | if ((addr % 2) != 0) | ||
293 | return -EINVAL; | ||
294 | |||
295 | if (mask == 0) | ||
296 | val = 0; | ||
297 | else | ||
298 | val = b43_read16(dev, addr); | ||
299 | val &= mask; | ||
300 | val |= set; | ||
301 | b43_write16(dev, addr, val); | ||
302 | |||
303 | return 0; | ||
304 | } | ||
305 | |||
306 | static ssize_t mmio32read__read_file(struct b43_wldev *dev, | ||
307 | char *buf, size_t bufsize) | ||
308 | { | ||
309 | ssize_t count = 0; | ||
310 | unsigned int addr; | ||
311 | u32 val; | ||
312 | |||
313 | addr = dev->dfsentry->mmio32read_next; | ||
314 | if (addr > B43_MAX_MMIO_ACCESS) | ||
315 | return -EDESTADDRREQ; | ||
316 | |||
317 | val = b43_read32(dev, addr); | ||
318 | fappend("0x%08X\n", val); | ||
116 | 319 | ||
117 | return count; | 320 | return count; |
118 | } | 321 | } |
119 | 322 | ||
323 | static int mmio32read__write_file(struct b43_wldev *dev, | ||
324 | const char *buf, size_t count) | ||
325 | { | ||
326 | unsigned int addr; | ||
327 | int res; | ||
328 | |||
329 | res = sscanf(buf, "0x%X", &addr); | ||
330 | if (res != 1) | ||
331 | return -EINVAL; | ||
332 | if (addr > B43_MAX_MMIO_ACCESS) | ||
333 | return -EADDRNOTAVAIL; | ||
334 | if ((addr % 4) != 0) | ||
335 | return -EINVAL; | ||
336 | |||
337 | dev->dfsentry->mmio32read_next = addr; | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | |||
342 | static int mmio32write__write_file(struct b43_wldev *dev, | ||
343 | const char *buf, size_t count) | ||
344 | { | ||
345 | unsigned int addr, mask, set; | ||
346 | int res; | ||
347 | u32 val; | ||
348 | |||
349 | res = sscanf(buf, "0x%X 0x%X 0x%X", &addr, &mask, &set); | ||
350 | if (res != 3) | ||
351 | return -EINVAL; | ||
352 | if (addr > B43_MAX_MMIO_ACCESS) | ||
353 | return -EADDRNOTAVAIL; | ||
354 | if ((mask > 0xFFFFFFFF) || (set > 0xFFFFFFFF)) | ||
355 | return -E2BIG; | ||
356 | if ((addr % 4) != 0) | ||
357 | return -EINVAL; | ||
358 | |||
359 | if (mask == 0) | ||
360 | val = 0; | ||
361 | else | ||
362 | val = b43_read32(dev, addr); | ||
363 | val &= mask; | ||
364 | val |= set; | ||
365 | b43_write32(dev, addr, val); | ||
366 | |||
367 | return 0; | ||
368 | } | ||
369 | |||
120 | /* wl->irq_lock is locked */ | 370 | /* wl->irq_lock is locked */ |
121 | static ssize_t shm_read_file(struct b43_wldev *dev, | 371 | static ssize_t tsf_read_file(struct b43_wldev *dev, |
122 | char *buf, size_t bufsize) | 372 | char *buf, size_t bufsize) |
123 | { | 373 | { |
124 | ssize_t count = 0; | 374 | ssize_t count = 0; |
125 | int i; | 375 | u64 tsf; |
126 | u16 tmp; | ||
127 | __le16 *le16buf = (__le16 *)buf; | ||
128 | 376 | ||
129 | for (i = 0; i < 0x1000; i++) { | 377 | b43_tsf_read(dev, &tsf); |
130 | if (bufsize < sizeof(tmp)) | 378 | fappend("0x%08x%08x\n", |
131 | break; | 379 | (unsigned int)((tsf & 0xFFFFFFFF00000000ULL) >> 32), |
132 | tmp = b43_shm_read16(dev, B43_SHM_SHARED, 2 * i); | 380 | (unsigned int)(tsf & 0xFFFFFFFFULL)); |
133 | le16buf[i] = cpu_to_le16(tmp); | ||
134 | count += sizeof(tmp); | ||
135 | bufsize -= sizeof(tmp); | ||
136 | } | ||
137 | 381 | ||
138 | return count; | 382 | return count; |
139 | } | 383 | } |
140 | 384 | ||
385 | /* wl->irq_lock is locked */ | ||
386 | static int tsf_write_file(struct b43_wldev *dev, | ||
387 | const char *buf, size_t count) | ||
388 | { | ||
389 | u64 tsf; | ||
390 | |||
391 | if (sscanf(buf, "%llu", (unsigned long long *)(&tsf)) != 1) | ||
392 | return -EINVAL; | ||
393 | b43_tsf_write(dev, tsf); | ||
394 | |||
395 | return 0; | ||
396 | } | ||
397 | |||
141 | static ssize_t txstat_read_file(struct b43_wldev *dev, | 398 | static ssize_t txstat_read_file(struct b43_wldev *dev, |
142 | char *buf, size_t bufsize) | 399 | char *buf, size_t bufsize) |
143 | { | 400 | { |
@@ -496,9 +753,15 @@ out_unlock: | |||
496 | .take_irqlock = _take_irqlock, \ | 753 | .take_irqlock = _take_irqlock, \ |
497 | } | 754 | } |
498 | 755 | ||
756 | B43_DEBUGFS_FOPS(shm16read, shm16read__read_file, shm16read__write_file, 1); | ||
757 | B43_DEBUGFS_FOPS(shm16write, NULL, shm16write__write_file, 1); | ||
758 | B43_DEBUGFS_FOPS(shm32read, shm32read__read_file, shm32read__write_file, 1); | ||
759 | B43_DEBUGFS_FOPS(shm32write, NULL, shm32write__write_file, 1); | ||
760 | B43_DEBUGFS_FOPS(mmio16read, mmio16read__read_file, mmio16read__write_file, 1); | ||
761 | B43_DEBUGFS_FOPS(mmio16write, NULL, mmio16write__write_file, 1); | ||
762 | B43_DEBUGFS_FOPS(mmio32read, mmio32read__read_file, mmio32read__write_file, 1); | ||
763 | B43_DEBUGFS_FOPS(mmio32write, NULL, mmio32write__write_file, 1); | ||
499 | B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); | 764 | B43_DEBUGFS_FOPS(tsf, tsf_read_file, tsf_write_file, 1); |
500 | B43_DEBUGFS_FOPS(ucode_regs, ucode_regs_read_file, NULL, 1); | ||
501 | B43_DEBUGFS_FOPS(shm, shm_read_file, NULL, 1); | ||
502 | B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); | 765 | B43_DEBUGFS_FOPS(txstat, txstat_read_file, NULL, 0); |
503 | B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0); | 766 | B43_DEBUGFS_FOPS(txpower_g, txpower_g_read_file, txpower_g_write_file, 0); |
504 | B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); | 767 | B43_DEBUGFS_FOPS(restart, NULL, restart_write_file, 1); |
@@ -538,6 +801,7 @@ static void b43_add_dynamic_debug(struct b43_wldev *dev) | |||
538 | add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0); | 801 | add_dyn_dbg("debug_pwork_fast", B43_DBG_PWORK_FAST, 0); |
539 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); | 802 | add_dyn_dbg("debug_pwork_stop", B43_DBG_PWORK_STOP, 0); |
540 | add_dyn_dbg("debug_lo", B43_DBG_LO, 0); | 803 | add_dyn_dbg("debug_lo", B43_DBG_LO, 0); |
804 | add_dyn_dbg("debug_firmware", B43_DBG_FIRMWARE, 0); | ||
541 | 805 | ||
542 | #undef add_dyn_dbg | 806 | #undef add_dyn_dbg |
543 | } | 807 | } |
@@ -584,6 +848,13 @@ void b43_debugfs_add_device(struct b43_wldev *dev) | |||
584 | return; | 848 | return; |
585 | } | 849 | } |
586 | 850 | ||
851 | e->mmio16read_next = 0xFFFF; /* invalid address */ | ||
852 | e->mmio32read_next = 0xFFFF; /* invalid address */ | ||
853 | e->shm16read_routing_next = 0xFFFFFFFF; /* invalid routing */ | ||
854 | e->shm16read_addr_next = 0xFFFFFFFF; /* invalid address */ | ||
855 | e->shm32read_routing_next = 0xFFFFFFFF; /* invalid routing */ | ||
856 | e->shm32read_addr_next = 0xFFFFFFFF; /* invalid address */ | ||
857 | |||
587 | #define ADD_FILE(name, mode) \ | 858 | #define ADD_FILE(name, mode) \ |
588 | do { \ | 859 | do { \ |
589 | struct dentry *d; \ | 860 | struct dentry *d; \ |
@@ -596,9 +867,15 @@ void b43_debugfs_add_device(struct b43_wldev *dev) | |||
596 | } while (0) | 867 | } while (0) |
597 | 868 | ||
598 | 869 | ||
870 | ADD_FILE(shm16read, 0600); | ||
871 | ADD_FILE(shm16write, 0200); | ||
872 | ADD_FILE(shm32read, 0600); | ||
873 | ADD_FILE(shm32write, 0200); | ||
874 | ADD_FILE(mmio16read, 0600); | ||
875 | ADD_FILE(mmio16write, 0200); | ||
876 | ADD_FILE(mmio32read, 0600); | ||
877 | ADD_FILE(mmio32write, 0200); | ||
599 | ADD_FILE(tsf, 0600); | 878 | ADD_FILE(tsf, 0600); |
600 | ADD_FILE(ucode_regs, 0400); | ||
601 | ADD_FILE(shm, 0400); | ||
602 | ADD_FILE(txstat, 0400); | 879 | ADD_FILE(txstat, 0400); |
603 | ADD_FILE(txpower_g, 0600); | 880 | ADD_FILE(txpower_g, 0600); |
604 | ADD_FILE(restart, 0200); | 881 | ADD_FILE(restart, 0200); |
@@ -620,9 +897,15 @@ void b43_debugfs_remove_device(struct b43_wldev *dev) | |||
620 | return; | 897 | return; |
621 | b43_remove_dynamic_debug(dev); | 898 | b43_remove_dynamic_debug(dev); |
622 | 899 | ||
900 | debugfs_remove(e->file_shm16read.dentry); | ||
901 | debugfs_remove(e->file_shm16write.dentry); | ||
902 | debugfs_remove(e->file_shm32read.dentry); | ||
903 | debugfs_remove(e->file_shm32write.dentry); | ||
904 | debugfs_remove(e->file_mmio16read.dentry); | ||
905 | debugfs_remove(e->file_mmio16write.dentry); | ||
906 | debugfs_remove(e->file_mmio32read.dentry); | ||
907 | debugfs_remove(e->file_mmio32write.dentry); | ||
623 | debugfs_remove(e->file_tsf.dentry); | 908 | debugfs_remove(e->file_tsf.dentry); |
624 | debugfs_remove(e->file_ucode_regs.dentry); | ||
625 | debugfs_remove(e->file_shm.dentry); | ||
626 | debugfs_remove(e->file_txstat.dentry); | 909 | debugfs_remove(e->file_txstat.dentry); |
627 | debugfs_remove(e->file_txpower_g.dentry); | 910 | debugfs_remove(e->file_txpower_g.dentry); |
628 | debugfs_remove(e->file_restart.dentry); | 911 | debugfs_remove(e->file_restart.dentry); |
diff --git a/drivers/net/wireless/b43/debugfs.h b/drivers/net/wireless/b43/debugfs.h index c75cff4151d9..22ffd02ba554 100644 --- a/drivers/net/wireless/b43/debugfs.h +++ b/drivers/net/wireless/b43/debugfs.h | |||
@@ -11,6 +11,7 @@ enum b43_dyndbg { /* Dynamic debugging features */ | |||
11 | B43_DBG_PWORK_FAST, | 11 | B43_DBG_PWORK_FAST, |
12 | B43_DBG_PWORK_STOP, | 12 | B43_DBG_PWORK_STOP, |
13 | B43_DBG_LO, | 13 | B43_DBG_LO, |
14 | B43_DBG_FIRMWARE, | ||
14 | __B43_NR_DYNDBG, | 15 | __B43_NR_DYNDBG, |
15 | }; | 16 | }; |
16 | 17 | ||
@@ -36,9 +37,15 @@ struct b43_dfsentry { | |||
36 | struct b43_wldev *dev; | 37 | struct b43_wldev *dev; |
37 | struct dentry *subdir; | 38 | struct dentry *subdir; |
38 | 39 | ||
40 | struct b43_dfs_file file_shm16read; | ||
41 | struct b43_dfs_file file_shm16write; | ||
42 | struct b43_dfs_file file_shm32read; | ||
43 | struct b43_dfs_file file_shm32write; | ||
44 | struct b43_dfs_file file_mmio16read; | ||
45 | struct b43_dfs_file file_mmio16write; | ||
46 | struct b43_dfs_file file_mmio32read; | ||
47 | struct b43_dfs_file file_mmio32write; | ||
39 | struct b43_dfs_file file_tsf; | 48 | struct b43_dfs_file file_tsf; |
40 | struct b43_dfs_file file_ucode_regs; | ||
41 | struct b43_dfs_file file_shm; | ||
42 | struct b43_dfs_file file_txstat; | 49 | struct b43_dfs_file file_txstat; |
43 | struct b43_dfs_file file_txpower_g; | 50 | struct b43_dfs_file file_txpower_g; |
44 | struct b43_dfs_file file_restart; | 51 | struct b43_dfs_file file_restart; |
@@ -46,6 +53,18 @@ struct b43_dfsentry { | |||
46 | 53 | ||
47 | struct b43_txstatus_log txstatlog; | 54 | struct b43_txstatus_log txstatlog; |
48 | 55 | ||
56 | /* The cached address for the next mmio16read file read */ | ||
57 | u16 mmio16read_next; | ||
58 | /* The cached address for the next mmio32read file read */ | ||
59 | u16 mmio32read_next; | ||
60 | |||
61 | /* The cached address for the next shm16read file read */ | ||
62 | u32 shm16read_routing_next; | ||
63 | u32 shm16read_addr_next; | ||
64 | /* The cached address for the next shm32read file read */ | ||
65 | u32 shm32read_routing_next; | ||
66 | u32 shm32read_addr_next; | ||
67 | |||
49 | /* Enabled/Disabled list for the dynamic debugging features. */ | 68 | /* Enabled/Disabled list for the dynamic debugging features. */ |
50 | u32 dyn_debug[__B43_NR_DYNDBG]; | 69 | u32 dyn_debug[__B43_NR_DYNDBG]; |
51 | /* Dentries for the dynamic debugging entries. */ | 70 | /* Dentries for the dynamic debugging entries. */ |
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c index 8a09a1db08db..098f886976f6 100644 --- a/drivers/net/wireless/b43/dma.c +++ b/drivers/net/wireless/b43/dma.c | |||
@@ -328,11 +328,11 @@ static inline | |||
328 | dma_addr_t dmaaddr; | 328 | dma_addr_t dmaaddr; |
329 | 329 | ||
330 | if (tx) { | 330 | if (tx) { |
331 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 331 | dmaaddr = ssb_dma_map_single(ring->dev->dev, |
332 | buf, len, DMA_TO_DEVICE); | 332 | buf, len, DMA_TO_DEVICE); |
333 | } else { | 333 | } else { |
334 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 334 | dmaaddr = ssb_dma_map_single(ring->dev->dev, |
335 | buf, len, DMA_FROM_DEVICE); | 335 | buf, len, DMA_FROM_DEVICE); |
336 | } | 336 | } |
337 | 337 | ||
338 | return dmaaddr; | 338 | return dmaaddr; |
@@ -343,11 +343,11 @@ static inline | |||
343 | dma_addr_t addr, size_t len, int tx) | 343 | dma_addr_t addr, size_t len, int tx) |
344 | { | 344 | { |
345 | if (tx) { | 345 | if (tx) { |
346 | dma_unmap_single(ring->dev->dev->dma_dev, | 346 | ssb_dma_unmap_single(ring->dev->dev, |
347 | addr, len, DMA_TO_DEVICE); | 347 | addr, len, DMA_TO_DEVICE); |
348 | } else { | 348 | } else { |
349 | dma_unmap_single(ring->dev->dev->dma_dev, | 349 | ssb_dma_unmap_single(ring->dev->dev, |
350 | addr, len, DMA_FROM_DEVICE); | 350 | addr, len, DMA_FROM_DEVICE); |
351 | } | 351 | } |
352 | } | 352 | } |
353 | 353 | ||
@@ -356,8 +356,8 @@ static inline | |||
356 | dma_addr_t addr, size_t len) | 356 | dma_addr_t addr, size_t len) |
357 | { | 357 | { |
358 | B43_WARN_ON(ring->tx); | 358 | B43_WARN_ON(ring->tx); |
359 | dma_sync_single_for_cpu(ring->dev->dev->dma_dev, | 359 | ssb_dma_sync_single_for_cpu(ring->dev->dev, |
360 | addr, len, DMA_FROM_DEVICE); | 360 | addr, len, DMA_FROM_DEVICE); |
361 | } | 361 | } |
362 | 362 | ||
363 | static inline | 363 | static inline |
@@ -365,8 +365,8 @@ static inline | |||
365 | dma_addr_t addr, size_t len) | 365 | dma_addr_t addr, size_t len) |
366 | { | 366 | { |
367 | B43_WARN_ON(ring->tx); | 367 | B43_WARN_ON(ring->tx); |
368 | dma_sync_single_for_device(ring->dev->dev->dma_dev, | 368 | ssb_dma_sync_single_for_device(ring->dev->dev, |
369 | addr, len, DMA_FROM_DEVICE); | 369 | addr, len, DMA_FROM_DEVICE); |
370 | } | 370 | } |
371 | 371 | ||
372 | static inline | 372 | static inline |
@@ -381,7 +381,6 @@ static inline | |||
381 | 381 | ||
382 | static int alloc_ringmemory(struct b43_dmaring *ring) | 382 | static int alloc_ringmemory(struct b43_dmaring *ring) |
383 | { | 383 | { |
384 | struct device *dma_dev = ring->dev->dev->dma_dev; | ||
385 | gfp_t flags = GFP_KERNEL; | 384 | gfp_t flags = GFP_KERNEL; |
386 | 385 | ||
387 | /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K | 386 | /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K |
@@ -392,11 +391,14 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
392 | * For unknown reasons - possibly a hardware error - the BCM4311 rev | 391 | * For unknown reasons - possibly a hardware error - the BCM4311 rev |
393 | * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, | 392 | * 02, which uses 64-bit DMA, needs the ring buffer in very low memory, |
394 | * which accounts for the GFP_DMA flag below. | 393 | * which accounts for the GFP_DMA flag below. |
394 | * | ||
395 | * The flags here must match the flags in free_ringmemory below! | ||
395 | */ | 396 | */ |
396 | if (ring->type == B43_DMA_64BIT) | 397 | if (ring->type == B43_DMA_64BIT) |
397 | flags |= GFP_DMA; | 398 | flags |= GFP_DMA; |
398 | ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE, | 399 | ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, |
399 | &(ring->dmabase), flags); | 400 | B43_DMA_RINGMEMSIZE, |
401 | &(ring->dmabase), flags); | ||
400 | if (!ring->descbase) { | 402 | if (!ring->descbase) { |
401 | b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); | 403 | b43err(ring->dev->wl, "DMA ringmemory allocation failed\n"); |
402 | return -ENOMEM; | 404 | return -ENOMEM; |
@@ -408,10 +410,13 @@ static int alloc_ringmemory(struct b43_dmaring *ring) | |||
408 | 410 | ||
409 | static void free_ringmemory(struct b43_dmaring *ring) | 411 | static void free_ringmemory(struct b43_dmaring *ring) |
410 | { | 412 | { |
411 | struct device *dma_dev = ring->dev->dev->dma_dev; | 413 | gfp_t flags = GFP_KERNEL; |
414 | |||
415 | if (ring->type == B43_DMA_64BIT) | ||
416 | flags |= GFP_DMA; | ||
412 | 417 | ||
413 | dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE, | 418 | ssb_dma_free_consistent(ring->dev->dev, B43_DMA_RINGMEMSIZE, |
414 | ring->descbase, ring->dmabase); | 419 | ring->descbase, ring->dmabase, flags); |
415 | } | 420 | } |
416 | 421 | ||
417 | /* Reset the RX DMA channel */ | 422 | /* Reset the RX DMA channel */ |
@@ -518,7 +523,7 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring, | |||
518 | dma_addr_t addr, | 523 | dma_addr_t addr, |
519 | size_t buffersize, bool dma_to_device) | 524 | size_t buffersize, bool dma_to_device) |
520 | { | 525 | { |
521 | if (unlikely(dma_mapping_error(addr))) | 526 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) |
522 | return 1; | 527 | return 1; |
523 | 528 | ||
524 | switch (ring->type) { | 529 | switch (ring->type) { |
@@ -844,10 +849,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
844 | goto err_kfree_meta; | 849 | goto err_kfree_meta; |
845 | 850 | ||
846 | /* test for ability to dma to txhdr_cache */ | 851 | /* test for ability to dma to txhdr_cache */ |
847 | dma_test = dma_map_single(dev->dev->dma_dev, | 852 | dma_test = ssb_dma_map_single(dev->dev, |
848 | ring->txhdr_cache, | 853 | ring->txhdr_cache, |
849 | b43_txhdr_size(dev), | 854 | b43_txhdr_size(dev), |
850 | DMA_TO_DEVICE); | 855 | DMA_TO_DEVICE); |
851 | 856 | ||
852 | if (b43_dma_mapping_error(ring, dma_test, | 857 | if (b43_dma_mapping_error(ring, dma_test, |
853 | b43_txhdr_size(dev), 1)) { | 858 | b43_txhdr_size(dev), 1)) { |
@@ -859,10 +864,10 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
859 | if (!ring->txhdr_cache) | 864 | if (!ring->txhdr_cache) |
860 | goto err_kfree_meta; | 865 | goto err_kfree_meta; |
861 | 866 | ||
862 | dma_test = dma_map_single(dev->dev->dma_dev, | 867 | dma_test = ssb_dma_map_single(dev->dev, |
863 | ring->txhdr_cache, | 868 | ring->txhdr_cache, |
864 | b43_txhdr_size(dev), | 869 | b43_txhdr_size(dev), |
865 | DMA_TO_DEVICE); | 870 | DMA_TO_DEVICE); |
866 | 871 | ||
867 | if (b43_dma_mapping_error(ring, dma_test, | 872 | if (b43_dma_mapping_error(ring, dma_test, |
868 | b43_txhdr_size(dev), 1)) { | 873 | b43_txhdr_size(dev), 1)) { |
@@ -873,9 +878,9 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev, | |||
873 | } | 878 | } |
874 | } | 879 | } |
875 | 880 | ||
876 | dma_unmap_single(dev->dev->dma_dev, | 881 | ssb_dma_unmap_single(dev->dev, |
877 | dma_test, b43_txhdr_size(dev), | 882 | dma_test, b43_txhdr_size(dev), |
878 | DMA_TO_DEVICE); | 883 | DMA_TO_DEVICE); |
879 | } | 884 | } |
880 | 885 | ||
881 | err = alloc_ringmemory(ring); | 886 | err = alloc_ringmemory(ring); |
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 704dd3551fff..9d2eb273b726 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c | |||
@@ -373,13 +373,10 @@ static inline void b43_shm_control_word(struct b43_wldev *dev, | |||
373 | b43_write32(dev, B43_MMIO_SHM_CONTROL, control); | 373 | b43_write32(dev, B43_MMIO_SHM_CONTROL, control); |
374 | } | 374 | } |
375 | 375 | ||
376 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | 376 | u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) |
377 | { | 377 | { |
378 | struct b43_wl *wl = dev->wl; | ||
379 | unsigned long flags; | ||
380 | u32 ret; | 378 | u32 ret; |
381 | 379 | ||
382 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
383 | if (routing == B43_SHM_SHARED) { | 380 | if (routing == B43_SHM_SHARED) { |
384 | B43_WARN_ON(offset & 0x0001); | 381 | B43_WARN_ON(offset & 0x0001); |
385 | if (offset & 0x0003) { | 382 | if (offset & 0x0003) { |
@@ -397,18 +394,26 @@ u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) | |||
397 | b43_shm_control_word(dev, routing, offset); | 394 | b43_shm_control_word(dev, routing, offset); |
398 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); | 395 | ret = b43_read32(dev, B43_MMIO_SHM_DATA); |
399 | out: | 396 | out: |
400 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
401 | |||
402 | return ret; | 397 | return ret; |
403 | } | 398 | } |
404 | 399 | ||
405 | u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | 400 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) |
406 | { | 401 | { |
407 | struct b43_wl *wl = dev->wl; | 402 | struct b43_wl *wl = dev->wl; |
408 | unsigned long flags; | 403 | unsigned long flags; |
409 | u16 ret; | 404 | u32 ret; |
410 | 405 | ||
411 | spin_lock_irqsave(&wl->shm_lock, flags); | 406 | spin_lock_irqsave(&wl->shm_lock, flags); |
407 | ret = __b43_shm_read32(dev, routing, offset); | ||
408 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) | ||
414 | { | ||
415 | u16 ret; | ||
416 | |||
412 | if (routing == B43_SHM_SHARED) { | 417 | if (routing == B43_SHM_SHARED) { |
413 | B43_WARN_ON(offset & 0x0001); | 418 | B43_WARN_ON(offset & 0x0001); |
414 | if (offset & 0x0003) { | 419 | if (offset & 0x0003) { |
@@ -423,17 +428,24 @@ u16 b43_shm_read16(struct b43_wldev * dev, u16 routing, u16 offset) | |||
423 | b43_shm_control_word(dev, routing, offset); | 428 | b43_shm_control_word(dev, routing, offset); |
424 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); | 429 | ret = b43_read16(dev, B43_MMIO_SHM_DATA); |
425 | out: | 430 | out: |
426 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
427 | |||
428 | return ret; | 431 | return ret; |
429 | } | 432 | } |
430 | 433 | ||
431 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | 434 | u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) |
432 | { | 435 | { |
433 | struct b43_wl *wl = dev->wl; | 436 | struct b43_wl *wl = dev->wl; |
434 | unsigned long flags; | 437 | unsigned long flags; |
438 | u16 ret; | ||
435 | 439 | ||
436 | spin_lock_irqsave(&wl->shm_lock, flags); | 440 | spin_lock_irqsave(&wl->shm_lock, flags); |
441 | ret = __b43_shm_read16(dev, routing, offset); | ||
442 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
443 | |||
444 | return ret; | ||
445 | } | ||
446 | |||
447 | void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | ||
448 | { | ||
437 | if (routing == B43_SHM_SHARED) { | 449 | if (routing == B43_SHM_SHARED) { |
438 | B43_WARN_ON(offset & 0x0001); | 450 | B43_WARN_ON(offset & 0x0001); |
439 | if (offset & 0x0003) { | 451 | if (offset & 0x0003) { |
@@ -443,35 +455,47 @@ void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) | |||
443 | (value >> 16) & 0xffff); | 455 | (value >> 16) & 0xffff); |
444 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); | 456 | b43_shm_control_word(dev, routing, (offset >> 2) + 1); |
445 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); | 457 | b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); |
446 | goto out; | 458 | return; |
447 | } | 459 | } |
448 | offset >>= 2; | 460 | offset >>= 2; |
449 | } | 461 | } |
450 | b43_shm_control_word(dev, routing, offset); | 462 | b43_shm_control_word(dev, routing, offset); |
451 | b43_write32(dev, B43_MMIO_SHM_DATA, value); | 463 | b43_write32(dev, B43_MMIO_SHM_DATA, value); |
452 | out: | ||
453 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
454 | } | 464 | } |
455 | 465 | ||
456 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | 466 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) |
457 | { | 467 | { |
458 | struct b43_wl *wl = dev->wl; | 468 | struct b43_wl *wl = dev->wl; |
459 | unsigned long flags; | 469 | unsigned long flags; |
460 | 470 | ||
461 | spin_lock_irqsave(&wl->shm_lock, flags); | 471 | spin_lock_irqsave(&wl->shm_lock, flags); |
472 | __b43_shm_write32(dev, routing, offset, value); | ||
473 | spin_unlock_irqrestore(&wl->shm_lock, flags); | ||
474 | } | ||
475 | |||
476 | void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | ||
477 | { | ||
462 | if (routing == B43_SHM_SHARED) { | 478 | if (routing == B43_SHM_SHARED) { |
463 | B43_WARN_ON(offset & 0x0001); | 479 | B43_WARN_ON(offset & 0x0001); |
464 | if (offset & 0x0003) { | 480 | if (offset & 0x0003) { |
465 | /* Unaligned access */ | 481 | /* Unaligned access */ |
466 | b43_shm_control_word(dev, routing, offset >> 2); | 482 | b43_shm_control_word(dev, routing, offset >> 2); |
467 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); | 483 | b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, value); |
468 | goto out; | 484 | return; |
469 | } | 485 | } |
470 | offset >>= 2; | 486 | offset >>= 2; |
471 | } | 487 | } |
472 | b43_shm_control_word(dev, routing, offset); | 488 | b43_shm_control_word(dev, routing, offset); |
473 | b43_write16(dev, B43_MMIO_SHM_DATA, value); | 489 | b43_write16(dev, B43_MMIO_SHM_DATA, value); |
474 | out: | 490 | } |
491 | |||
492 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value) | ||
493 | { | ||
494 | struct b43_wl *wl = dev->wl; | ||
495 | unsigned long flags; | ||
496 | |||
497 | spin_lock_irqsave(&wl->shm_lock, flags); | ||
498 | __b43_shm_write16(dev, routing, offset, value); | ||
475 | spin_unlock_irqrestore(&wl->shm_lock, flags); | 499 | spin_unlock_irqrestore(&wl->shm_lock, flags); |
476 | } | 500 | } |
477 | 501 | ||
@@ -2463,6 +2487,19 @@ static void b43_gpio_cleanup(struct b43_wldev *dev) | |||
2463 | /* http://bcm-specs.sipsolutions.net/EnableMac */ | 2487 | /* http://bcm-specs.sipsolutions.net/EnableMac */ |
2464 | void b43_mac_enable(struct b43_wldev *dev) | 2488 | void b43_mac_enable(struct b43_wldev *dev) |
2465 | { | 2489 | { |
2490 | if (b43_debug(dev, B43_DBG_FIRMWARE)) { | ||
2491 | u16 fwstate; | ||
2492 | |||
2493 | fwstate = b43_shm_read16(dev, B43_SHM_SHARED, | ||
2494 | B43_SHM_SH_UCODESTAT); | ||
2495 | if ((fwstate != B43_SHM_SH_UCODESTAT_SUSP) && | ||
2496 | (fwstate != B43_SHM_SH_UCODESTAT_SLEEP)) { | ||
2497 | b43err(dev->wl, "b43_mac_enable(): The firmware " | ||
2498 | "should be suspended, but current state is %u\n", | ||
2499 | fwstate); | ||
2500 | } | ||
2501 | } | ||
2502 | |||
2466 | dev->mac_suspended--; | 2503 | dev->mac_suspended--; |
2467 | B43_WARN_ON(dev->mac_suspended < 0); | 2504 | B43_WARN_ON(dev->mac_suspended < 0); |
2468 | if (dev->mac_suspended == 0) { | 2505 | if (dev->mac_suspended == 0) { |
@@ -2783,6 +2820,21 @@ static void b43_periodic_every30sec(struct b43_wldev *dev) | |||
2783 | static void b43_periodic_every15sec(struct b43_wldev *dev) | 2820 | static void b43_periodic_every15sec(struct b43_wldev *dev) |
2784 | { | 2821 | { |
2785 | struct b43_phy *phy = &dev->phy; | 2822 | struct b43_phy *phy = &dev->phy; |
2823 | u16 wdr; | ||
2824 | |||
2825 | if (dev->fw.opensource) { | ||
2826 | /* Check if the firmware is still alive. | ||
2827 | * It will reset the watchdog counter to 0 in its idle loop. */ | ||
2828 | wdr = b43_shm_read16(dev, B43_SHM_SCRATCH, B43_WATCHDOG_REG); | ||
2829 | if (unlikely(wdr)) { | ||
2830 | b43err(dev->wl, "Firmware watchdog: The firmware died!\n"); | ||
2831 | b43_controller_restart(dev, "Firmware watchdog"); | ||
2832 | return; | ||
2833 | } else { | ||
2834 | b43_shm_write16(dev, B43_SHM_SCRATCH, | ||
2835 | B43_WATCHDOG_REG, 1); | ||
2836 | } | ||
2837 | } | ||
2786 | 2838 | ||
2787 | if (phy->type == B43_PHYTYPE_G) { | 2839 | if (phy->type == B43_PHYTYPE_G) { |
2788 | //TODO: update_aci_moving_average | 2840 | //TODO: update_aci_moving_average |
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h index dad23c42b422..f871a252cb55 100644 --- a/drivers/net/wireless/b43/main.h +++ b/drivers/net/wireless/b43/main.h | |||
@@ -95,9 +95,13 @@ void b43_tsf_read(struct b43_wldev *dev, u64 * tsf); | |||
95 | void b43_tsf_write(struct b43_wldev *dev, u64 tsf); | 95 | void b43_tsf_write(struct b43_wldev *dev, u64 tsf); |
96 | 96 | ||
97 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); | 97 | u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); |
98 | u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset); | ||
98 | u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); | 99 | u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); |
100 | u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset); | ||
99 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); | 101 | void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); |
102 | void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value); | ||
100 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); | 103 | void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); |
104 | void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value); | ||
101 | 105 | ||
102 | u64 b43_hf_read(struct b43_wldev *dev); | 106 | u64 b43_hf_read(struct b43_wldev *dev); |
103 | void b43_hf_write(struct b43_wldev *dev, u64 value); | 107 | void b43_hf_write(struct b43_wldev *dev, u64 value); |
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c index 8b1555d95f1c..401591267592 100644 --- a/drivers/net/wireless/b43/pio.c +++ b/drivers/net/wireless/b43/pio.c | |||
@@ -586,7 +586,7 @@ void b43_pio_handle_txstatus(struct b43_wldev *dev, | |||
586 | 586 | ||
587 | spin_lock(&q->lock); /* IRQs are already disabled. */ | 587 | spin_lock(&q->lock); /* IRQs are already disabled. */ |
588 | 588 | ||
589 | info = (void *)pack->skb; | 589 | info = IEEE80211_SKB_CB(pack->skb); |
590 | memset(&info->status, 0, sizeof(info->status)); | 590 | memset(&info->status, 0, sizeof(info->status)); |
591 | 591 | ||
592 | b43_fill_txstatus_report(info, status); | 592 | b43_fill_txstatus_report(info, status); |
diff --git a/drivers/net/wireless/b43/rfkill.c b/drivers/net/wireless/b43/rfkill.c index 11f53cb1139e..4cca203992e8 100644 --- a/drivers/net/wireless/b43/rfkill.c +++ b/drivers/net/wireless/b43/rfkill.c | |||
@@ -88,7 +88,7 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
88 | goto out_unlock; | 88 | goto out_unlock; |
89 | err = 0; | 89 | err = 0; |
90 | switch (state) { | 90 | switch (state) { |
91 | case RFKILL_STATE_ON: | 91 | case RFKILL_STATE_UNBLOCKED: |
92 | if (!dev->radio_hw_enable) { | 92 | if (!dev->radio_hw_enable) { |
93 | /* No luck. We can't toggle the hardware RF-kill | 93 | /* No luck. We can't toggle the hardware RF-kill |
94 | * button from software. */ | 94 | * button from software. */ |
@@ -98,10 +98,13 @@ static int b43_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
98 | if (!dev->phy.radio_on) | 98 | if (!dev->phy.radio_on) |
99 | b43_radio_turn_on(dev); | 99 | b43_radio_turn_on(dev); |
100 | break; | 100 | break; |
101 | case RFKILL_STATE_OFF: | 101 | case RFKILL_STATE_SOFT_BLOCKED: |
102 | if (dev->phy.radio_on) | 102 | if (dev->phy.radio_on) |
103 | b43_radio_turn_off(dev, 0); | 103 | b43_radio_turn_off(dev, 0); |
104 | break; | 104 | break; |
105 | default: | ||
106 | b43warn(wl, "Received unexpected rfkill state %d.\n", state); | ||
107 | break; | ||
105 | } | 108 | } |
106 | out_unlock: | 109 | out_unlock: |
107 | mutex_unlock(&wl->mutex); | 110 | mutex_unlock(&wl->mutex); |
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c index f9e1cff2aecb..bf6f6c1ed4cf 100644 --- a/drivers/net/wireless/b43/xmit.c +++ b/drivers/net/wireless/b43/xmit.c | |||
@@ -193,7 +193,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
193 | const struct ieee80211_hdr *wlhdr = | 193 | const struct ieee80211_hdr *wlhdr = |
194 | (const struct ieee80211_hdr *)fragment_data; | 194 | (const struct ieee80211_hdr *)fragment_data; |
195 | int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); | 195 | int use_encryption = (!(info->flags & IEEE80211_TX_CTL_DO_NOT_ENCRYPT)); |
196 | u16 fctl = le16_to_cpu(wlhdr->frame_control); | 196 | __le16 fctl = wlhdr->frame_control; |
197 | struct ieee80211_rate *fbrate; | 197 | struct ieee80211_rate *fbrate; |
198 | u8 rate, rate_fb; | 198 | u8 rate, rate_fb; |
199 | int rate_ofdm, rate_fb_ofdm; | 199 | int rate_ofdm, rate_fb_ofdm; |
@@ -259,7 +259,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
259 | B43_TXH_MAC_KEYIDX; | 259 | B43_TXH_MAC_KEYIDX; |
260 | mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & | 260 | mac_ctl |= (key->algorithm << B43_TXH_MAC_KEYALG_SHIFT) & |
261 | B43_TXH_MAC_KEYALG; | 261 | B43_TXH_MAC_KEYALG; |
262 | wlhdr_len = ieee80211_get_hdrlen(fctl); | 262 | wlhdr_len = ieee80211_hdrlen(fctl); |
263 | iv_len = min((size_t) info->control.iv_len, | 263 | iv_len = min((size_t) info->control.iv_len, |
264 | ARRAY_SIZE(txhdr->iv)); | 264 | ARRAY_SIZE(txhdr->iv)); |
265 | memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); | 265 | memcpy(txhdr->iv, ((u8 *) wlhdr) + wlhdr_len, iv_len); |
@@ -317,8 +317,7 @@ int b43_generate_txhdr(struct b43_wldev *dev, | |||
317 | /* MAC control */ | 317 | /* MAC control */ |
318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) | 318 | if (!(info->flags & IEEE80211_TX_CTL_NO_ACK)) |
319 | mac_ctl |= B43_TXH_MAC_ACK; | 319 | mac_ctl |= B43_TXH_MAC_ACK; |
320 | if (!(((fctl & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | 320 | if (!ieee80211_is_pspoll(fctl)) |
321 | ((fctl & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PSPOLL))) | ||
322 | mac_ctl |= B43_TXH_MAC_HWSEQ; | 321 | mac_ctl |= B43_TXH_MAC_HWSEQ; |
323 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) | 322 | if (info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) |
324 | mac_ctl |= B43_TXH_MAC_STMSDU; | 323 | mac_ctl |= B43_TXH_MAC_STMSDU; |
@@ -509,7 +508,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
509 | struct b43_plcp_hdr6 *plcp; | 508 | struct b43_plcp_hdr6 *plcp; |
510 | struct ieee80211_hdr *wlhdr; | 509 | struct ieee80211_hdr *wlhdr; |
511 | const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; | 510 | const struct b43_rxhdr_fw4 *rxhdr = _rxhdr; |
512 | u16 fctl; | 511 | __le16 fctl; |
513 | u16 phystat0, phystat3, chanstat, mactime; | 512 | u16 phystat0, phystat3, chanstat, mactime; |
514 | u32 macstat; | 513 | u32 macstat; |
515 | u16 chanid; | 514 | u16 chanid; |
@@ -549,7 +548,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
549 | goto drop; | 548 | goto drop; |
550 | } | 549 | } |
551 | wlhdr = (struct ieee80211_hdr *)(skb->data); | 550 | wlhdr = (struct ieee80211_hdr *)(skb->data); |
552 | fctl = le16_to_cpu(wlhdr->frame_control); | 551 | fctl = wlhdr->frame_control; |
553 | 552 | ||
554 | if (macstat & B43_RX_MAC_DEC) { | 553 | if (macstat & B43_RX_MAC_DEC) { |
555 | unsigned int keyidx; | 554 | unsigned int keyidx; |
@@ -564,7 +563,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
564 | B43_WARN_ON(keyidx >= dev->max_nr_keys); | 563 | B43_WARN_ON(keyidx >= dev->max_nr_keys); |
565 | 564 | ||
566 | if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) { | 565 | if (dev->key[keyidx].algorithm != B43_SEC_ALGO_NONE) { |
567 | wlhdr_len = ieee80211_get_hdrlen(fctl); | 566 | wlhdr_len = ieee80211_hdrlen(fctl); |
568 | if (unlikely(skb->len < (wlhdr_len + 3))) { | 567 | if (unlikely(skb->len < (wlhdr_len + 3))) { |
569 | b43dbg(dev->wl, | 568 | b43dbg(dev->wl, |
570 | "RX: Packet size underrun (3)\n"); | 569 | "RX: Packet size underrun (3)\n"); |
@@ -604,9 +603,7 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr) | |||
604 | * of timestamp, i.e. about 65 milliseconds after the PHY received | 603 | * of timestamp, i.e. about 65 milliseconds after the PHY received |
605 | * the first symbol. | 604 | * the first symbol. |
606 | */ | 605 | */ |
607 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) | 606 | if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) { |
608 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
609 | dev->wl->radiotap_enabled) { | ||
610 | u16 low_mactime_now; | 607 | u16 low_mactime_now; |
611 | 608 | ||
612 | b43_tsf_read(dev, &status.mactime); | 609 | b43_tsf_read(dev, &status.mactime); |
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c index 203b0f42ac58..eb0243a22691 100644 --- a/drivers/net/wireless/b43legacy/dma.c +++ b/drivers/net/wireless/b43legacy/dma.c | |||
@@ -393,13 +393,13 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring, | |||
393 | dma_addr_t dmaaddr; | 393 | dma_addr_t dmaaddr; |
394 | 394 | ||
395 | if (tx) | 395 | if (tx) |
396 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 396 | dmaaddr = ssb_dma_map_single(ring->dev->dev, |
397 | buf, len, | 397 | buf, len, |
398 | DMA_TO_DEVICE); | 398 | DMA_TO_DEVICE); |
399 | else | 399 | else |
400 | dmaaddr = dma_map_single(ring->dev->dev->dma_dev, | 400 | dmaaddr = ssb_dma_map_single(ring->dev->dev, |
401 | buf, len, | 401 | buf, len, |
402 | DMA_FROM_DEVICE); | 402 | DMA_FROM_DEVICE); |
403 | 403 | ||
404 | return dmaaddr; | 404 | return dmaaddr; |
405 | } | 405 | } |
@@ -411,13 +411,13 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring, | |||
411 | int tx) | 411 | int tx) |
412 | { | 412 | { |
413 | if (tx) | 413 | if (tx) |
414 | dma_unmap_single(ring->dev->dev->dma_dev, | 414 | ssb_dma_unmap_single(ring->dev->dev, |
415 | addr, len, | 415 | addr, len, |
416 | DMA_TO_DEVICE); | 416 | DMA_TO_DEVICE); |
417 | else | 417 | else |
418 | dma_unmap_single(ring->dev->dev->dma_dev, | 418 | ssb_dma_unmap_single(ring->dev->dev, |
419 | addr, len, | 419 | addr, len, |
420 | DMA_FROM_DEVICE); | 420 | DMA_FROM_DEVICE); |
421 | } | 421 | } |
422 | 422 | ||
423 | static inline | 423 | static inline |
@@ -427,8 +427,8 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring, | |||
427 | { | 427 | { |
428 | B43legacy_WARN_ON(ring->tx); | 428 | B43legacy_WARN_ON(ring->tx); |
429 | 429 | ||
430 | dma_sync_single_for_cpu(ring->dev->dev->dma_dev, | 430 | ssb_dma_sync_single_for_cpu(ring->dev->dev, |
431 | addr, len, DMA_FROM_DEVICE); | 431 | addr, len, DMA_FROM_DEVICE); |
432 | } | 432 | } |
433 | 433 | ||
434 | static inline | 434 | static inline |
@@ -438,8 +438,8 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring, | |||
438 | { | 438 | { |
439 | B43legacy_WARN_ON(ring->tx); | 439 | B43legacy_WARN_ON(ring->tx); |
440 | 440 | ||
441 | dma_sync_single_for_device(ring->dev->dev->dma_dev, | 441 | ssb_dma_sync_single_for_device(ring->dev->dev, |
442 | addr, len, DMA_FROM_DEVICE); | 442 | addr, len, DMA_FROM_DEVICE); |
443 | } | 443 | } |
444 | 444 | ||
445 | static inline | 445 | static inline |
@@ -458,10 +458,11 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring, | |||
458 | 458 | ||
459 | static int alloc_ringmemory(struct b43legacy_dmaring *ring) | 459 | static int alloc_ringmemory(struct b43legacy_dmaring *ring) |
460 | { | 460 | { |
461 | struct device *dma_dev = ring->dev->dev->dma_dev; | 461 | /* GFP flags must match the flags in free_ringmemory()! */ |
462 | 462 | ring->descbase = ssb_dma_alloc_consistent(ring->dev->dev, | |
463 | ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, | 463 | B43legacy_DMA_RINGMEMSIZE, |
464 | &(ring->dmabase), GFP_KERNEL); | 464 | &(ring->dmabase), |
465 | GFP_KERNEL); | ||
465 | if (!ring->descbase) { | 466 | if (!ring->descbase) { |
466 | b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" | 467 | b43legacyerr(ring->dev->wl, "DMA ringmemory allocation" |
467 | " failed\n"); | 468 | " failed\n"); |
@@ -474,10 +475,8 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring) | |||
474 | 475 | ||
475 | static void free_ringmemory(struct b43legacy_dmaring *ring) | 476 | static void free_ringmemory(struct b43legacy_dmaring *ring) |
476 | { | 477 | { |
477 | struct device *dma_dev = ring->dev->dev->dma_dev; | 478 | ssb_dma_free_consistent(ring->dev->dev, B43legacy_DMA_RINGMEMSIZE, |
478 | 479 | ring->descbase, ring->dmabase, GFP_KERNEL); | |
479 | dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE, | ||
480 | ring->descbase, ring->dmabase); | ||
481 | } | 480 | } |
482 | 481 | ||
483 | /* Reset the RX DMA channel */ | 482 | /* Reset the RX DMA channel */ |
@@ -589,7 +588,7 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring, | |||
589 | size_t buffersize, | 588 | size_t buffersize, |
590 | bool dma_to_device) | 589 | bool dma_to_device) |
591 | { | 590 | { |
592 | if (unlikely(dma_mapping_error(addr))) | 591 | if (unlikely(ssb_dma_mapping_error(ring->dev->dev, addr))) |
593 | return 1; | 592 | return 1; |
594 | 593 | ||
595 | switch (ring->type) { | 594 | switch (ring->type) { |
@@ -894,9 +893,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
894 | goto err_kfree_meta; | 893 | goto err_kfree_meta; |
895 | 894 | ||
896 | /* test for ability to dma to txhdr_cache */ | 895 | /* test for ability to dma to txhdr_cache */ |
897 | dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache, | 896 | dma_test = ssb_dma_map_single(dev->dev, ring->txhdr_cache, |
898 | sizeof(struct b43legacy_txhdr_fw3), | 897 | sizeof(struct b43legacy_txhdr_fw3), |
899 | DMA_TO_DEVICE); | 898 | DMA_TO_DEVICE); |
900 | 899 | ||
901 | if (b43legacy_dma_mapping_error(ring, dma_test, | 900 | if (b43legacy_dma_mapping_error(ring, dma_test, |
902 | sizeof(struct b43legacy_txhdr_fw3), 1)) { | 901 | sizeof(struct b43legacy_txhdr_fw3), 1)) { |
@@ -908,7 +907,7 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
908 | if (!ring->txhdr_cache) | 907 | if (!ring->txhdr_cache) |
909 | goto err_kfree_meta; | 908 | goto err_kfree_meta; |
910 | 909 | ||
911 | dma_test = dma_map_single(dev->dev->dma_dev, | 910 | dma_test = ssb_dma_map_single(dev->dev, |
912 | ring->txhdr_cache, | 911 | ring->txhdr_cache, |
913 | sizeof(struct b43legacy_txhdr_fw3), | 912 | sizeof(struct b43legacy_txhdr_fw3), |
914 | DMA_TO_DEVICE); | 913 | DMA_TO_DEVICE); |
@@ -918,9 +917,9 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev, | |||
918 | goto err_kfree_txhdr_cache; | 917 | goto err_kfree_txhdr_cache; |
919 | } | 918 | } |
920 | 919 | ||
921 | dma_unmap_single(dev->dev->dma_dev, | 920 | ssb_dma_unmap_single(dev->dev, dma_test, |
922 | dma_test, sizeof(struct b43legacy_txhdr_fw3), | 921 | sizeof(struct b43legacy_txhdr_fw3), |
923 | DMA_TO_DEVICE); | 922 | DMA_TO_DEVICE); |
924 | } | 923 | } |
925 | 924 | ||
926 | ring->nr_slots = nr_slots; | 925 | ring->nr_slots = nr_slots; |
diff --git a/drivers/net/wireless/b43legacy/rfkill.c b/drivers/net/wireless/b43legacy/rfkill.c index d178dfbb1c9f..8935a302b220 100644 --- a/drivers/net/wireless/b43legacy/rfkill.c +++ b/drivers/net/wireless/b43legacy/rfkill.c | |||
@@ -90,7 +90,7 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
90 | goto out_unlock; | 90 | goto out_unlock; |
91 | err = 0; | 91 | err = 0; |
92 | switch (state) { | 92 | switch (state) { |
93 | case RFKILL_STATE_ON: | 93 | case RFKILL_STATE_UNBLOCKED: |
94 | if (!dev->radio_hw_enable) { | 94 | if (!dev->radio_hw_enable) { |
95 | /* No luck. We can't toggle the hardware RF-kill | 95 | /* No luck. We can't toggle the hardware RF-kill |
96 | * button from software. */ | 96 | * button from software. */ |
@@ -100,10 +100,14 @@ static int b43legacy_rfkill_soft_toggle(void *data, enum rfkill_state state) | |||
100 | if (!dev->phy.radio_on) | 100 | if (!dev->phy.radio_on) |
101 | b43legacy_radio_turn_on(dev); | 101 | b43legacy_radio_turn_on(dev); |
102 | break; | 102 | break; |
103 | case RFKILL_STATE_OFF: | 103 | case RFKILL_STATE_SOFT_BLOCKED: |
104 | if (dev->phy.radio_on) | 104 | if (dev->phy.radio_on) |
105 | b43legacy_radio_turn_off(dev, 0); | 105 | b43legacy_radio_turn_off(dev, 0); |
106 | break; | 106 | break; |
107 | default: | ||
108 | b43legacywarn(wl, "Received unexpected rfkill state %d.\n", | ||
109 | state); | ||
110 | break; | ||
107 | } | 111 | } |
108 | 112 | ||
109 | out_unlock: | 113 | out_unlock: |
diff --git a/drivers/net/wireless/b43legacy/xmit.c b/drivers/net/wireless/b43legacy/xmit.c index 82dc04d59446..a3540787eb50 100644 --- a/drivers/net/wireless/b43legacy/xmit.c +++ b/drivers/net/wireless/b43legacy/xmit.c | |||
@@ -442,7 +442,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
442 | struct b43legacy_plcp_hdr6 *plcp; | 442 | struct b43legacy_plcp_hdr6 *plcp; |
443 | struct ieee80211_hdr *wlhdr; | 443 | struct ieee80211_hdr *wlhdr; |
444 | const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr; | 444 | const struct b43legacy_rxhdr_fw3 *rxhdr = _rxhdr; |
445 | u16 fctl; | 445 | __le16 fctl; |
446 | u16 phystat0; | 446 | u16 phystat0; |
447 | u16 phystat3; | 447 | u16 phystat3; |
448 | u16 chanstat; | 448 | u16 chanstat; |
@@ -480,7 +480,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
480 | goto drop; | 480 | goto drop; |
481 | } | 481 | } |
482 | wlhdr = (struct ieee80211_hdr *)(skb->data); | 482 | wlhdr = (struct ieee80211_hdr *)(skb->data); |
483 | fctl = le16_to_cpu(wlhdr->frame_control); | 483 | fctl = wlhdr->frame_control; |
484 | 484 | ||
485 | if ((macstat & B43legacy_RX_MAC_DEC) && | 485 | if ((macstat & B43legacy_RX_MAC_DEC) && |
486 | !(macstat & B43legacy_RX_MAC_DECERR)) { | 486 | !(macstat & B43legacy_RX_MAC_DECERR)) { |
@@ -499,11 +499,11 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
499 | 499 | ||
500 | if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) { | 500 | if (dev->key[keyidx].algorithm != B43legacy_SEC_ALGO_NONE) { |
501 | /* Remove PROTECTED flag to mark it as decrypted. */ | 501 | /* Remove PROTECTED flag to mark it as decrypted. */ |
502 | B43legacy_WARN_ON(!(fctl & IEEE80211_FCTL_PROTECTED)); | 502 | B43legacy_WARN_ON(!ieee80211_has_protected(fctl)); |
503 | fctl &= ~IEEE80211_FCTL_PROTECTED; | 503 | fctl &= ~cpu_to_le16(IEEE80211_FCTL_PROTECTED); |
504 | wlhdr->frame_control = cpu_to_le16(fctl); | 504 | wlhdr->frame_control = fctl; |
505 | 505 | ||
506 | wlhdr_len = ieee80211_get_hdrlen(fctl); | 506 | wlhdr_len = ieee80211_hdrlen(fctl); |
507 | if (unlikely(skb->len < (wlhdr_len + 3))) { | 507 | if (unlikely(skb->len < (wlhdr_len + 3))) { |
508 | b43legacydbg(dev->wl, "RX: Packet size" | 508 | b43legacydbg(dev->wl, "RX: Packet size" |
509 | " underrun3\n"); | 509 | " underrun3\n"); |
@@ -556,9 +556,7 @@ void b43legacy_rx(struct b43legacy_wldev *dev, | |||
556 | * of timestamp, i.e. about 65 milliseconds after the PHY received | 556 | * of timestamp, i.e. about 65 milliseconds after the PHY received |
557 | * the first symbol. | 557 | * the first symbol. |
558 | */ | 558 | */ |
559 | if (((fctl & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) | 559 | if (ieee80211_is_beacon(fctl) || dev->wl->radiotap_enabled) { |
560 | == (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON)) || | ||
561 | dev->wl->radiotap_enabled) { | ||
562 | u16 low_mactime_now; | 560 | u16 low_mactime_now; |
563 | 561 | ||
564 | b43legacy_tsf_read(dev, &status.mactime); | 562 | b43legacy_tsf_read(dev, &status.mactime); |
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h index 547ba84dc797..3a386a636cca 100644 --- a/drivers/net/wireless/hostap/hostap.h +++ b/drivers/net/wireless/hostap/hostap.h | |||
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, | |||
67 | int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], | 67 | int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], |
68 | struct iw_quality qual[], int buf_size, | 68 | struct iw_quality qual[], int buf_size, |
69 | int aplist); | 69 | int aplist); |
70 | int prism2_ap_translate_scan(struct net_device *dev, char *buffer); | 70 | int prism2_ap_translate_scan(struct net_device *dev, |
71 | struct iw_request_info *info, char *buffer); | ||
71 | int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); | 72 | int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); |
72 | 73 | ||
73 | 74 | ||
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c index 0acd9589c48c..06b23df8f69b 100644 --- a/drivers/net/wireless/hostap/hostap_ap.c +++ b/drivers/net/wireless/hostap/hostap_ap.c | |||
@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], | |||
2420 | 2420 | ||
2421 | /* Translate our list of Access Points & Stations to a card independant | 2421 | /* Translate our list of Access Points & Stations to a card independant |
2422 | * format that the Wireless Tools will understand - Jean II */ | 2422 | * format that the Wireless Tools will understand - Jean II */ |
2423 | int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | 2423 | int prism2_ap_translate_scan(struct net_device *dev, |
2424 | struct iw_request_info *info, char *buffer) | ||
2424 | { | 2425 | { |
2425 | struct hostap_interface *iface; | 2426 | struct hostap_interface *iface; |
2426 | local_info_t *local; | 2427 | local_info_t *local; |
@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2449 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 2450 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
2450 | memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); | 2451 | memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); |
2451 | iwe.len = IW_EV_ADDR_LEN; | 2452 | iwe.len = IW_EV_ADDR_LEN; |
2452 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 2453 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
2453 | IW_EV_ADDR_LEN); | 2454 | &iwe, IW_EV_ADDR_LEN); |
2454 | 2455 | ||
2455 | /* Use the mode to indicate if it's a station or | 2456 | /* Use the mode to indicate if it's a station or |
2456 | * an Access Point */ | 2457 | * an Access Point */ |
@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2461 | else | 2462 | else |
2462 | iwe.u.mode = IW_MODE_INFRA; | 2463 | iwe.u.mode = IW_MODE_INFRA; |
2463 | iwe.len = IW_EV_UINT_LEN; | 2464 | iwe.len = IW_EV_UINT_LEN; |
2464 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 2465 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
2465 | IW_EV_UINT_LEN); | 2466 | &iwe, IW_EV_UINT_LEN); |
2466 | 2467 | ||
2467 | /* Some quality */ | 2468 | /* Some quality */ |
2468 | memset(&iwe, 0, sizeof(iwe)); | 2469 | memset(&iwe, 0, sizeof(iwe)); |
@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2477 | iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); | 2478 | iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); |
2478 | iwe.u.qual.updated = sta->last_rx_updated; | 2479 | iwe.u.qual.updated = sta->last_rx_updated; |
2479 | iwe.len = IW_EV_QUAL_LEN; | 2480 | iwe.len = IW_EV_QUAL_LEN; |
2480 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 2481 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
2481 | IW_EV_QUAL_LEN); | 2482 | &iwe, IW_EV_QUAL_LEN); |
2482 | 2483 | ||
2483 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT | 2484 | #ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT |
2484 | if (sta->ap) { | 2485 | if (sta->ap) { |
@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2486 | iwe.cmd = SIOCGIWESSID; | 2487 | iwe.cmd = SIOCGIWESSID; |
2487 | iwe.u.data.length = sta->u.ap.ssid_len; | 2488 | iwe.u.data.length = sta->u.ap.ssid_len; |
2488 | iwe.u.data.flags = 1; | 2489 | iwe.u.data.flags = 1; |
2489 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 2490 | current_ev = iwe_stream_add_point(info, current_ev, |
2490 | &iwe, | 2491 | end_buf, &iwe, |
2491 | sta->u.ap.ssid); | 2492 | sta->u.ap.ssid); |
2492 | 2493 | ||
2493 | memset(&iwe, 0, sizeof(iwe)); | 2494 | memset(&iwe, 0, sizeof(iwe)); |
@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2497 | IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; | 2498 | IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; |
2498 | else | 2499 | else |
2499 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 2500 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
2500 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 2501 | current_ev = iwe_stream_add_point(info, current_ev, |
2501 | &iwe, | 2502 | end_buf, &iwe, |
2502 | sta->u.ap.ssid | 2503 | sta->u.ap.ssid); |
2503 | /* 0 byte memcpy */); | ||
2504 | 2504 | ||
2505 | if (sta->u.ap.channel > 0 && | 2505 | if (sta->u.ap.channel > 0 && |
2506 | sta->u.ap.channel <= FREQ_COUNT) { | 2506 | sta->u.ap.channel <= FREQ_COUNT) { |
@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2510 | * 100000; | 2510 | * 100000; |
2511 | iwe.u.freq.e = 1; | 2511 | iwe.u.freq.e = 1; |
2512 | current_ev = iwe_stream_add_event( | 2512 | current_ev = iwe_stream_add_event( |
2513 | current_ev, end_buf, &iwe, | 2513 | info, current_ev, end_buf, &iwe, |
2514 | IW_EV_FREQ_LEN); | 2514 | IW_EV_FREQ_LEN); |
2515 | } | 2515 | } |
2516 | 2516 | ||
@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer) | |||
2519 | sprintf(buf, "beacon_interval=%d", | 2519 | sprintf(buf, "beacon_interval=%d", |
2520 | sta->listen_interval); | 2520 | sta->listen_interval); |
2521 | iwe.u.data.length = strlen(buf); | 2521 | iwe.u.data.length = strlen(buf); |
2522 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 2522 | current_ev = iwe_stream_add_point(info, current_ev, |
2523 | &iwe, buf); | 2523 | end_buf, &iwe, buf); |
2524 | } | 2524 | } |
2525 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ | 2525 | #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ |
2526 | 2526 | ||
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 0ca0bfeb0ada..ed52d98317cd 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev, | |||
1793 | 1793 | ||
1794 | #ifndef PRISM2_NO_STATION_MODES | 1794 | #ifndef PRISM2_NO_STATION_MODES |
1795 | static char * __prism2_translate_scan(local_info_t *local, | 1795 | static char * __prism2_translate_scan(local_info_t *local, |
1796 | struct iw_request_info *info, | ||
1796 | struct hfa384x_hostscan_result *scan, | 1797 | struct hfa384x_hostscan_result *scan, |
1797 | struct hostap_bss_info *bss, | 1798 | struct hostap_bss_info *bss, |
1798 | char *current_ev, char *end_buf) | 1799 | char *current_ev, char *end_buf) |
@@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1823 | iwe.cmd = SIOCGIWAP; | 1824 | iwe.cmd = SIOCGIWAP; |
1824 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 1825 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1825 | memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); | 1826 | memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); |
1826 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1827 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe, |
1827 | IW_EV_ADDR_LEN); | 1828 | IW_EV_ADDR_LEN); |
1828 | 1829 | ||
1829 | /* Other entries will be displayed in the order we give them */ | 1830 | /* Other entries will be displayed in the order we give them */ |
@@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1832 | iwe.cmd = SIOCGIWESSID; | 1833 | iwe.cmd = SIOCGIWESSID; |
1833 | iwe.u.data.length = ssid_len; | 1834 | iwe.u.data.length = ssid_len; |
1834 | iwe.u.data.flags = 1; | 1835 | iwe.u.data.flags = 1; |
1835 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid); | 1836 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
1837 | &iwe, ssid); | ||
1836 | 1838 | ||
1837 | memset(&iwe, 0, sizeof(iwe)); | 1839 | memset(&iwe, 0, sizeof(iwe)); |
1838 | iwe.cmd = SIOCGIWMODE; | 1840 | iwe.cmd = SIOCGIWMODE; |
@@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1847 | iwe.u.mode = IW_MODE_MASTER; | 1849 | iwe.u.mode = IW_MODE_MASTER; |
1848 | else | 1850 | else |
1849 | iwe.u.mode = IW_MODE_ADHOC; | 1851 | iwe.u.mode = IW_MODE_ADHOC; |
1850 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1852 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
1851 | IW_EV_UINT_LEN); | 1853 | &iwe, IW_EV_UINT_LEN); |
1852 | } | 1854 | } |
1853 | 1855 | ||
1854 | memset(&iwe, 0, sizeof(iwe)); | 1856 | memset(&iwe, 0, sizeof(iwe)); |
@@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1864 | if (chan > 0) { | 1866 | if (chan > 0) { |
1865 | iwe.u.freq.m = freq_list[chan - 1] * 100000; | 1867 | iwe.u.freq.m = freq_list[chan - 1] * 100000; |
1866 | iwe.u.freq.e = 1; | 1868 | iwe.u.freq.e = 1; |
1867 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1869 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
1868 | IW_EV_FREQ_LEN); | 1870 | &iwe, IW_EV_FREQ_LEN); |
1869 | } | 1871 | } |
1870 | 1872 | ||
1871 | if (scan) { | 1873 | if (scan) { |
@@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1884 | | IW_QUAL_NOISE_UPDATED | 1886 | | IW_QUAL_NOISE_UPDATED |
1885 | | IW_QUAL_QUAL_INVALID | 1887 | | IW_QUAL_QUAL_INVALID |
1886 | | IW_QUAL_DBM; | 1888 | | IW_QUAL_DBM; |
1887 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1889 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
1888 | IW_EV_QUAL_LEN); | 1890 | &iwe, IW_EV_QUAL_LEN); |
1889 | } | 1891 | } |
1890 | 1892 | ||
1891 | memset(&iwe, 0, sizeof(iwe)); | 1893 | memset(&iwe, 0, sizeof(iwe)); |
@@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1895 | else | 1897 | else |
1896 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 1898 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
1897 | iwe.u.data.length = 0; | 1899 | iwe.u.data.length = 0; |
1898 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); | 1900 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, ""); |
1899 | 1901 | ||
1900 | /* TODO: add SuppRates into BSS table */ | 1902 | /* TODO: add SuppRates into BSS table */ |
1901 | if (scan) { | 1903 | if (scan) { |
1902 | memset(&iwe, 0, sizeof(iwe)); | 1904 | memset(&iwe, 0, sizeof(iwe)); |
1903 | iwe.cmd = SIOCGIWRATE; | 1905 | iwe.cmd = SIOCGIWRATE; |
1904 | current_val = current_ev + IW_EV_LCP_LEN; | 1906 | current_val = current_ev + iwe_stream_lcp_len(info); |
1905 | pos = scan->sup_rates; | 1907 | pos = scan->sup_rates; |
1906 | for (i = 0; i < sizeof(scan->sup_rates); i++) { | 1908 | for (i = 0; i < sizeof(scan->sup_rates); i++) { |
1907 | if (pos[i] == 0) | 1909 | if (pos[i] == 0) |
@@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1909 | /* Bit rate given in 500 kb/s units (+ 0x80) */ | 1911 | /* Bit rate given in 500 kb/s units (+ 0x80) */ |
1910 | iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); | 1912 | iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); |
1911 | current_val = iwe_stream_add_value( | 1913 | current_val = iwe_stream_add_value( |
1912 | current_ev, current_val, end_buf, &iwe, | 1914 | info, current_ev, current_val, end_buf, &iwe, |
1913 | IW_EV_PARAM_LEN); | 1915 | IW_EV_PARAM_LEN); |
1914 | } | 1916 | } |
1915 | /* Check if we added any event */ | 1917 | /* Check if we added any event */ |
1916 | if ((current_val - current_ev) > IW_EV_LCP_LEN) | 1918 | if ((current_val - current_ev) > iwe_stream_lcp_len(info)) |
1917 | current_ev = current_val; | 1919 | current_ev = current_val; |
1918 | } | 1920 | } |
1919 | 1921 | ||
@@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1924 | iwe.cmd = IWEVCUSTOM; | 1926 | iwe.cmd = IWEVCUSTOM; |
1925 | sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); | 1927 | sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); |
1926 | iwe.u.data.length = strlen(buf); | 1928 | iwe.u.data.length = strlen(buf); |
1927 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 1929 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
1928 | buf); | 1930 | &iwe, buf); |
1929 | 1931 | ||
1930 | memset(&iwe, 0, sizeof(iwe)); | 1932 | memset(&iwe, 0, sizeof(iwe)); |
1931 | iwe.cmd = IWEVCUSTOM; | 1933 | iwe.cmd = IWEVCUSTOM; |
1932 | sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); | 1934 | sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); |
1933 | iwe.u.data.length = strlen(buf); | 1935 | iwe.u.data.length = strlen(buf); |
1934 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, | 1936 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
1935 | buf); | 1937 | &iwe, buf); |
1936 | 1938 | ||
1937 | if (local->last_scan_type == PRISM2_HOSTSCAN && | 1939 | if (local->last_scan_type == PRISM2_HOSTSCAN && |
1938 | (capabilities & WLAN_CAPABILITY_IBSS)) { | 1940 | (capabilities & WLAN_CAPABILITY_IBSS)) { |
@@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1940 | iwe.cmd = IWEVCUSTOM; | 1942 | iwe.cmd = IWEVCUSTOM; |
1941 | sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); | 1943 | sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); |
1942 | iwe.u.data.length = strlen(buf); | 1944 | iwe.u.data.length = strlen(buf); |
1943 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 1945 | current_ev = iwe_stream_add_point(info, current_ev, |
1944 | &iwe, buf); | 1946 | end_buf, &iwe, buf); |
1945 | } | 1947 | } |
1946 | } | 1948 | } |
1947 | kfree(buf); | 1949 | kfree(buf); |
@@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1950 | memset(&iwe, 0, sizeof(iwe)); | 1952 | memset(&iwe, 0, sizeof(iwe)); |
1951 | iwe.cmd = IWEVGENIE; | 1953 | iwe.cmd = IWEVGENIE; |
1952 | iwe.u.data.length = bss->wpa_ie_len; | 1954 | iwe.u.data.length = bss->wpa_ie_len; |
1953 | current_ev = iwe_stream_add_point( | 1955 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
1954 | current_ev, end_buf, &iwe, bss->wpa_ie); | 1956 | &iwe, bss->wpa_ie); |
1955 | } | 1957 | } |
1956 | 1958 | ||
1957 | if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { | 1959 | if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { |
1958 | memset(&iwe, 0, sizeof(iwe)); | 1960 | memset(&iwe, 0, sizeof(iwe)); |
1959 | iwe.cmd = IWEVGENIE; | 1961 | iwe.cmd = IWEVGENIE; |
1960 | iwe.u.data.length = bss->rsn_ie_len; | 1962 | iwe.u.data.length = bss->rsn_ie_len; |
1961 | current_ev = iwe_stream_add_point( | 1963 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
1962 | current_ev, end_buf, &iwe, bss->rsn_ie); | 1964 | &iwe, bss->rsn_ie); |
1963 | } | 1965 | } |
1964 | 1966 | ||
1965 | return current_ev; | 1967 | return current_ev; |
@@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1969 | /* Translate scan data returned from the card to a card independant | 1971 | /* Translate scan data returned from the card to a card independant |
1970 | * format that the Wireless Tools will understand - Jean II */ | 1972 | * format that the Wireless Tools will understand - Jean II */ |
1971 | static inline int prism2_translate_scan(local_info_t *local, | 1973 | static inline int prism2_translate_scan(local_info_t *local, |
1974 | struct iw_request_info *info, | ||
1972 | char *buffer, int buflen) | 1975 | char *buffer, int buflen) |
1973 | { | 1976 | { |
1974 | struct hfa384x_hostscan_result *scan; | 1977 | struct hfa384x_hostscan_result *scan; |
@@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local, | |||
1999 | if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { | 2002 | if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { |
2000 | bss->included = 1; | 2003 | bss->included = 1; |
2001 | current_ev = __prism2_translate_scan( | 2004 | current_ev = __prism2_translate_scan( |
2002 | local, scan, bss, current_ev, end_buf); | 2005 | local, info, scan, bss, current_ev, |
2006 | end_buf); | ||
2003 | found++; | 2007 | found++; |
2004 | } | 2008 | } |
2005 | } | 2009 | } |
2006 | if (!found) { | 2010 | if (!found) { |
2007 | current_ev = __prism2_translate_scan( | 2011 | current_ev = __prism2_translate_scan( |
2008 | local, scan, NULL, current_ev, end_buf); | 2012 | local, info, scan, NULL, current_ev, end_buf); |
2009 | } | 2013 | } |
2010 | /* Check if there is space for one more entry */ | 2014 | /* Check if there is space for one more entry */ |
2011 | if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { | 2015 | if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { |
@@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local, | |||
2023 | bss = list_entry(ptr, struct hostap_bss_info, list); | 2027 | bss = list_entry(ptr, struct hostap_bss_info, list); |
2024 | if (bss->included) | 2028 | if (bss->included) |
2025 | continue; | 2029 | continue; |
2026 | current_ev = __prism2_translate_scan(local, NULL, bss, | 2030 | current_ev = __prism2_translate_scan(local, info, NULL, bss, |
2027 | current_ev, end_buf); | 2031 | current_ev, end_buf); |
2028 | /* Check if there is space for one more entry */ | 2032 | /* Check if there is space for one more entry */ |
2029 | if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { | 2033 | if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { |
@@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev, | |||
2070 | } | 2074 | } |
2071 | local->scan_timestamp = 0; | 2075 | local->scan_timestamp = 0; |
2072 | 2076 | ||
2073 | res = prism2_translate_scan(local, extra, data->length); | 2077 | res = prism2_translate_scan(local, info, extra, data->length); |
2074 | 2078 | ||
2075 | if (res >= 0) { | 2079 | if (res >= 0) { |
2076 | data->length = res; | 2080 | data->length = res; |
@@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev, | |||
2103 | * Jean II */ | 2107 | * Jean II */ |
2104 | 2108 | ||
2105 | /* Translate to WE format */ | 2109 | /* Translate to WE format */ |
2106 | res = prism2_ap_translate_scan(dev, extra); | 2110 | res = prism2_ap_translate_scan(dev, info, extra); |
2107 | if (res >= 0) { | 2111 | if (res >= 0) { |
2108 | printk(KERN_DEBUG "Scan result translation succeeded " | 2112 | printk(KERN_DEBUG "Scan result translation succeeded " |
2109 | "(length=%d)\n", res); | 2113 | "(length=%d)\n", res); |
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig index a382c0078923..d7ea32f39694 100644 --- a/drivers/net/wireless/iwlwifi/Kconfig +++ b/drivers/net/wireless/iwlwifi/Kconfig | |||
@@ -8,7 +8,7 @@ config IWLCORE | |||
8 | select MAC80211_LEDS if IWLWIFI_LEDS | 8 | select MAC80211_LEDS if IWLWIFI_LEDS |
9 | select LEDS_CLASS if IWLWIFI_LEDS | 9 | select LEDS_CLASS if IWLWIFI_LEDS |
10 | select RFKILL if IWLWIFI_RFKILL | 10 | select RFKILL if IWLWIFI_RFKILL |
11 | select RFKILL_INPUT if IWLWIFI_RFKILL | 11 | select RFKILL_INPUT if (IWLWIFI_RFKILL && INPUT) |
12 | 12 | ||
13 | config IWLWIFI_LEDS | 13 | config IWLWIFI_LEDS |
14 | bool | 14 | bool |
diff --git a/drivers/net/wireless/iwlwifi/iwl-rfkill.c b/drivers/net/wireless/iwlwifi/iwl-rfkill.c index 5f098747cf95..ffefbb487e12 100644 --- a/drivers/net/wireless/iwlwifi/iwl-rfkill.c +++ b/drivers/net/wireless/iwlwifi/iwl-rfkill.c | |||
@@ -54,17 +54,20 @@ static int iwl_rfkill_soft_rf_kill(void *data, enum rfkill_state state) | |||
54 | mutex_lock(&priv->mutex); | 54 | mutex_lock(&priv->mutex); |
55 | 55 | ||
56 | switch (state) { | 56 | switch (state) { |
57 | case RFKILL_STATE_ON: | 57 | case RFKILL_STATE_UNBLOCKED: |
58 | iwl_radio_kill_sw_enable_radio(priv); | 58 | iwl_radio_kill_sw_enable_radio(priv); |
59 | /* if HW rf-kill is set dont allow ON state */ | 59 | /* if HW rf-kill is set dont allow ON state */ |
60 | if (iwl_is_rfkill(priv)) | 60 | if (iwl_is_rfkill(priv)) |
61 | err = -EBUSY; | 61 | err = -EBUSY; |
62 | break; | 62 | break; |
63 | case RFKILL_STATE_OFF: | 63 | case RFKILL_STATE_SOFT_BLOCKED: |
64 | iwl_radio_kill_sw_disable_radio(priv); | 64 | iwl_radio_kill_sw_disable_radio(priv); |
65 | if (!iwl_is_rfkill(priv)) | 65 | if (!iwl_is_rfkill(priv)) |
66 | err = -EBUSY; | 66 | err = -EBUSY; |
67 | break; | 67 | break; |
68 | default: | ||
69 | IWL_WARNING("we recieved unexpected RFKILL state %d\n", state); | ||
70 | break; | ||
68 | } | 71 | } |
69 | mutex_unlock(&priv->mutex); | 72 | mutex_unlock(&priv->mutex); |
70 | 73 | ||
@@ -95,6 +98,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
95 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; | 98 | priv->rfkill_mngr.rfkill->dev.class->suspend = NULL; |
96 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; | 99 | priv->rfkill_mngr.rfkill->dev.class->resume = NULL; |
97 | 100 | ||
101 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
98 | priv->rfkill_mngr.input_dev = input_allocate_device(); | 102 | priv->rfkill_mngr.input_dev = input_allocate_device(); |
99 | if (!priv->rfkill_mngr.input_dev) { | 103 | if (!priv->rfkill_mngr.input_dev) { |
100 | IWL_ERROR("Unable to allocate rfkill input device.\n"); | 104 | IWL_ERROR("Unable to allocate rfkill input device.\n"); |
@@ -109,6 +113,7 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
109 | priv->rfkill_mngr.input_dev->dev.parent = device; | 113 | priv->rfkill_mngr.input_dev->dev.parent = device; |
110 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); | 114 | priv->rfkill_mngr.input_dev->evbit[0] = BIT(EV_KEY); |
111 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); | 115 | set_bit(KEY_WLAN, priv->rfkill_mngr.input_dev->keybit); |
116 | #endif | ||
112 | 117 | ||
113 | ret = rfkill_register(priv->rfkill_mngr.rfkill); | 118 | ret = rfkill_register(priv->rfkill_mngr.rfkill); |
114 | if (ret) { | 119 | if (ret) { |
@@ -116,11 +121,13 @@ int iwl_rfkill_init(struct iwl_priv *priv) | |||
116 | goto free_input_dev; | 121 | goto free_input_dev; |
117 | } | 122 | } |
118 | 123 | ||
124 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
119 | ret = input_register_device(priv->rfkill_mngr.input_dev); | 125 | ret = input_register_device(priv->rfkill_mngr.input_dev); |
120 | if (ret) { | 126 | if (ret) { |
121 | IWL_ERROR("Unable to register rfkill input device: %d\n", ret); | 127 | IWL_ERROR("Unable to register rfkill input device: %d\n", ret); |
122 | goto unregister_rfkill; | 128 | goto unregister_rfkill; |
123 | } | 129 | } |
130 | #endif | ||
124 | 131 | ||
125 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); | 132 | IWL_DEBUG_RF_KILL("RFKILL initialization complete.\n"); |
126 | return ret; | 133 | return ret; |
@@ -130,8 +137,10 @@ unregister_rfkill: | |||
130 | priv->rfkill_mngr.rfkill = NULL; | 137 | priv->rfkill_mngr.rfkill = NULL; |
131 | 138 | ||
132 | free_input_dev: | 139 | free_input_dev: |
140 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
133 | input_free_device(priv->rfkill_mngr.input_dev); | 141 | input_free_device(priv->rfkill_mngr.input_dev); |
134 | priv->rfkill_mngr.input_dev = NULL; | 142 | priv->rfkill_mngr.input_dev = NULL; |
143 | #endif | ||
135 | 144 | ||
136 | freed_rfkill: | 145 | freed_rfkill: |
137 | if (priv->rfkill_mngr.rfkill != NULL) | 146 | if (priv->rfkill_mngr.rfkill != NULL) |
@@ -147,13 +156,16 @@ EXPORT_SYMBOL(iwl_rfkill_init); | |||
147 | void iwl_rfkill_unregister(struct iwl_priv *priv) | 156 | void iwl_rfkill_unregister(struct iwl_priv *priv) |
148 | { | 157 | { |
149 | 158 | ||
159 | #if defined(CONFIG_RFKILL_INPUT) || defined(CONFIG_RFKILL_INPUT_MODULE) | ||
150 | if (priv->rfkill_mngr.input_dev) | 160 | if (priv->rfkill_mngr.input_dev) |
151 | input_unregister_device(priv->rfkill_mngr.input_dev); | 161 | input_unregister_device(priv->rfkill_mngr.input_dev); |
162 | input_free_device(priv->rfkill_mngr.input_dev); | ||
163 | priv->rfkill_mngr.input_dev = NULL; | ||
164 | #endif | ||
152 | 165 | ||
153 | if (priv->rfkill_mngr.rfkill) | 166 | if (priv->rfkill_mngr.rfkill) |
154 | rfkill_unregister(priv->rfkill_mngr.rfkill); | 167 | rfkill_unregister(priv->rfkill_mngr.rfkill); |
155 | 168 | ||
156 | priv->rfkill_mngr.input_dev = NULL; | ||
157 | priv->rfkill_mngr.rfkill = NULL; | 169 | priv->rfkill_mngr.rfkill = NULL; |
158 | } | 170 | } |
159 | EXPORT_SYMBOL(iwl_rfkill_unregister); | 171 | EXPORT_SYMBOL(iwl_rfkill_unregister); |
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c index d448c9702a0f..343ed38f772d 100644 --- a/drivers/net/wireless/libertas/scan.c +++ b/drivers/net/wireless/libertas/scan.c | |||
@@ -776,8 +776,9 @@ out: | |||
776 | #define MAX_CUSTOM_LEN 64 | 776 | #define MAX_CUSTOM_LEN 64 |
777 | 777 | ||
778 | static inline char *lbs_translate_scan(struct lbs_private *priv, | 778 | static inline char *lbs_translate_scan(struct lbs_private *priv, |
779 | char *start, char *stop, | 779 | struct iw_request_info *info, |
780 | struct bss_descriptor *bss) | 780 | char *start, char *stop, |
781 | struct bss_descriptor *bss) | ||
781 | { | 782 | { |
782 | struct chan_freq_power *cfp; | 783 | struct chan_freq_power *cfp; |
783 | char *current_val; /* For rates */ | 784 | char *current_val; /* For rates */ |
@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
801 | iwe.cmd = SIOCGIWAP; | 802 | iwe.cmd = SIOCGIWAP; |
802 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 803 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
803 | memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); | 804 | memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); |
804 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); | 805 | start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN); |
805 | 806 | ||
806 | /* SSID */ | 807 | /* SSID */ |
807 | iwe.cmd = SIOCGIWESSID; | 808 | iwe.cmd = SIOCGIWESSID; |
808 | iwe.u.data.flags = 1; | 809 | iwe.u.data.flags = 1; |
809 | iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE); | 810 | iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE); |
810 | start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); | 811 | start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); |
811 | 812 | ||
812 | /* Mode */ | 813 | /* Mode */ |
813 | iwe.cmd = SIOCGIWMODE; | 814 | iwe.cmd = SIOCGIWMODE; |
814 | iwe.u.mode = bss->mode; | 815 | iwe.u.mode = bss->mode; |
815 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); | 816 | start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN); |
816 | 817 | ||
817 | /* Frequency */ | 818 | /* Frequency */ |
818 | iwe.cmd = SIOCGIWFREQ; | 819 | iwe.cmd = SIOCGIWFREQ; |
819 | iwe.u.freq.m = (long)cfp->freq * 100000; | 820 | iwe.u.freq.m = (long)cfp->freq * 100000; |
820 | iwe.u.freq.e = 1; | 821 | iwe.u.freq.e = 1; |
821 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); | 822 | start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN); |
822 | 823 | ||
823 | /* Add quality statistics */ | 824 | /* Add quality statistics */ |
824 | iwe.cmd = IWEVQUAL; | 825 | iwe.cmd = IWEVQUAL; |
@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
852 | nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; | 853 | nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; |
853 | iwe.u.qual.level = CAL_RSSI(snr, nf); | 854 | iwe.u.qual.level = CAL_RSSI(snr, nf); |
854 | } | 855 | } |
855 | start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); | 856 | start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN); |
856 | 857 | ||
857 | /* Add encryption capability */ | 858 | /* Add encryption capability */ |
858 | iwe.cmd = SIOCGIWENCODE; | 859 | iwe.cmd = SIOCGIWENCODE; |
@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
862 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 863 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
863 | } | 864 | } |
864 | iwe.u.data.length = 0; | 865 | iwe.u.data.length = 0; |
865 | start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); | 866 | start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid); |
866 | 867 | ||
867 | current_val = start + IW_EV_LCP_LEN; | 868 | current_val = start + iwe_stream_lcp_len(info); |
868 | 869 | ||
869 | iwe.cmd = SIOCGIWRATE; | 870 | iwe.cmd = SIOCGIWRATE; |
870 | iwe.u.bitrate.fixed = 0; | 871 | iwe.u.bitrate.fixed = 0; |
@@ -874,19 +875,19 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
874 | for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { | 875 | for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { |
875 | /* Bit rate given in 500 kb/s units */ | 876 | /* Bit rate given in 500 kb/s units */ |
876 | iwe.u.bitrate.value = bss->rates[j] * 500000; | 877 | iwe.u.bitrate.value = bss->rates[j] * 500000; |
877 | current_val = iwe_stream_add_value(start, current_val, | 878 | current_val = iwe_stream_add_value(info, start, current_val, |
878 | stop, &iwe, IW_EV_PARAM_LEN); | 879 | stop, &iwe, IW_EV_PARAM_LEN); |
879 | } | 880 | } |
880 | if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate | 881 | if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate |
881 | && !lbs_ssid_cmp(priv->curbssparams.ssid, | 882 | && !lbs_ssid_cmp(priv->curbssparams.ssid, |
882 | priv->curbssparams.ssid_len, | 883 | priv->curbssparams.ssid_len, |
883 | bss->ssid, bss->ssid_len)) { | 884 | bss->ssid, bss->ssid_len)) { |
884 | iwe.u.bitrate.value = 22 * 500000; | 885 | iwe.u.bitrate.value = 22 * 500000; |
885 | current_val = iwe_stream_add_value(start, current_val, | 886 | current_val = iwe_stream_add_value(info, start, current_val, |
886 | stop, &iwe, IW_EV_PARAM_LEN); | 887 | stop, &iwe, IW_EV_PARAM_LEN); |
887 | } | 888 | } |
888 | /* Check if we added any event */ | 889 | /* Check if we added any event */ |
889 | if((current_val - start) > IW_EV_LCP_LEN) | 890 | if ((current_val - start) > iwe_stream_lcp_len(info)) |
890 | start = current_val; | 891 | start = current_val; |
891 | 892 | ||
892 | memset(&iwe, 0, sizeof(iwe)); | 893 | memset(&iwe, 0, sizeof(iwe)); |
@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
895 | memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); | 896 | memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); |
896 | iwe.cmd = IWEVGENIE; | 897 | iwe.cmd = IWEVGENIE; |
897 | iwe.u.data.length = bss->wpa_ie_len; | 898 | iwe.u.data.length = bss->wpa_ie_len; |
898 | start = iwe_stream_add_point(start, stop, &iwe, buf); | 899 | start = iwe_stream_add_point(info, start, stop, &iwe, buf); |
899 | } | 900 | } |
900 | 901 | ||
901 | memset(&iwe, 0, sizeof(iwe)); | 902 | memset(&iwe, 0, sizeof(iwe)); |
@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
904 | memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); | 905 | memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); |
905 | iwe.cmd = IWEVGENIE; | 906 | iwe.cmd = IWEVGENIE; |
906 | iwe.u.data.length = bss->rsn_ie_len; | 907 | iwe.u.data.length = bss->rsn_ie_len; |
907 | start = iwe_stream_add_point(start, stop, &iwe, buf); | 908 | start = iwe_stream_add_point(info, start, stop, &iwe, buf); |
908 | } | 909 | } |
909 | 910 | ||
910 | if (bss->mesh) { | 911 | if (bss->mesh) { |
@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv, | |||
915 | p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); | 916 | p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); |
916 | iwe.u.data.length = p - custom; | 917 | iwe.u.data.length = p - custom; |
917 | if (iwe.u.data.length) | 918 | if (iwe.u.data.length) |
918 | start = iwe_stream_add_point(start, stop, &iwe, custom); | 919 | start = iwe_stream_add_point(info, start, stop, |
920 | &iwe, custom); | ||
919 | } | 921 | } |
920 | 922 | ||
921 | out: | 923 | out: |
@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1036 | } | 1038 | } |
1037 | 1039 | ||
1038 | /* Translate to WE format this entry */ | 1040 | /* Translate to WE format this entry */ |
1039 | next_ev = lbs_translate_scan(priv, ev, stop, iter_bss); | 1041 | next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss); |
1040 | if (next_ev == NULL) | 1042 | if (next_ev == NULL) |
1041 | continue; | 1043 | continue; |
1042 | ev = next_ev; | 1044 | ev = next_ev; |
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c index 8da352ae6825..5d30c57e3969 100644 --- a/drivers/net/wireless/mac80211_hwsim.c +++ b/drivers/net/wireless/mac80211_hwsim.c | |||
@@ -430,15 +430,16 @@ static int __init init_mac80211_hwsim(void) | |||
430 | hwsim_radios[i] = hw; | 430 | hwsim_radios[i] = hw; |
431 | 431 | ||
432 | data = hw->priv; | 432 | data = hw->priv; |
433 | data->dev = device_create(hwsim_class, NULL, 0, "hwsim%d", i); | 433 | data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw, |
434 | "hwsim%d", i); | ||
434 | if (IS_ERR(data->dev)) { | 435 | if (IS_ERR(data->dev)) { |
435 | printk(KERN_DEBUG "mac80211_hwsim: device_create " | 436 | printk(KERN_DEBUG |
437 | "mac80211_hwsim: device_create_drvdata " | ||
436 | "failed (%ld)\n", PTR_ERR(data->dev)); | 438 | "failed (%ld)\n", PTR_ERR(data->dev)); |
437 | err = -ENOMEM; | 439 | err = -ENOMEM; |
438 | goto failed; | 440 | goto failed; |
439 | } | 441 | } |
440 | data->dev->driver = &mac80211_hwsim_driver; | 442 | data->dev->driver = &mac80211_hwsim_driver; |
441 | dev_set_drvdata(data->dev, hw); | ||
442 | 443 | ||
443 | SET_IEEE80211_DEV(hw, data->dev); | 444 | SET_IEEE80211_DEV(hw, data->dev); |
444 | addr[3] = i >> 8; | 445 | addr[3] = i >> 8; |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 6d13a0d15a0c..b047306bf386 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev, | |||
4046 | * format that the Wireless Tools will understand - Jean II | 4046 | * format that the Wireless Tools will understand - Jean II |
4047 | * Return message length or -errno for fatal errors */ | 4047 | * Return message length or -errno for fatal errors */ |
4048 | static inline char *orinoco_translate_scan(struct net_device *dev, | 4048 | static inline char *orinoco_translate_scan(struct net_device *dev, |
4049 | struct iw_request_info *info, | ||
4049 | char *current_ev, | 4050 | char *current_ev, |
4050 | char *end_buf, | 4051 | char *end_buf, |
4051 | union hermes_scan_info *bss, | 4052 | union hermes_scan_info *bss, |
@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4062 | iwe.cmd = SIOCGIWAP; | 4063 | iwe.cmd = SIOCGIWAP; |
4063 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 4064 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
4064 | memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); | 4065 | memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); |
4065 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); | 4066 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4067 | &iwe, IW_EV_ADDR_LEN); | ||
4066 | 4068 | ||
4067 | /* Other entries will be displayed in the order we give them */ | 4069 | /* Other entries will be displayed in the order we give them */ |
4068 | 4070 | ||
@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4072 | iwe.u.data.length = 32; | 4074 | iwe.u.data.length = 32; |
4073 | iwe.cmd = SIOCGIWESSID; | 4075 | iwe.cmd = SIOCGIWESSID; |
4074 | iwe.u.data.flags = 1; | 4076 | iwe.u.data.flags = 1; |
4075 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); | 4077 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4078 | &iwe, bss->a.essid); | ||
4076 | 4079 | ||
4077 | /* Add mode */ | 4080 | /* Add mode */ |
4078 | iwe.cmd = SIOCGIWMODE; | 4081 | iwe.cmd = SIOCGIWMODE; |
@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4082 | iwe.u.mode = IW_MODE_MASTER; | 4085 | iwe.u.mode = IW_MODE_MASTER; |
4083 | else | 4086 | else |
4084 | iwe.u.mode = IW_MODE_ADHOC; | 4087 | iwe.u.mode = IW_MODE_ADHOC; |
4085 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); | 4088 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4089 | &iwe, IW_EV_UINT_LEN); | ||
4086 | } | 4090 | } |
4087 | 4091 | ||
4088 | channel = bss->s.channel; | 4092 | channel = bss->s.channel; |
@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4091 | iwe.cmd = SIOCGIWFREQ; | 4095 | iwe.cmd = SIOCGIWFREQ; |
4092 | iwe.u.freq.m = channel_frequency[channel-1] * 100000; | 4096 | iwe.u.freq.m = channel_frequency[channel-1] * 100000; |
4093 | iwe.u.freq.e = 1; | 4097 | iwe.u.freq.e = 1; |
4094 | current_ev = iwe_stream_add_event(current_ev, end_buf, | 4098 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4095 | &iwe, IW_EV_FREQ_LEN); | 4099 | &iwe, IW_EV_FREQ_LEN); |
4096 | } | 4100 | } |
4097 | 4101 | ||
@@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4106 | iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; | 4110 | iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; |
4107 | else | 4111 | else |
4108 | iwe.u.qual.qual = 0; | 4112 | iwe.u.qual.qual = 0; |
4109 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); | 4113 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
4114 | &iwe, IW_EV_QUAL_LEN); | ||
4110 | 4115 | ||
4111 | /* Add encryption capability */ | 4116 | /* Add encryption capability */ |
4112 | iwe.cmd = SIOCGIWENCODE; | 4117 | iwe.cmd = SIOCGIWENCODE; |
@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4115 | else | 4120 | else |
4116 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 4121 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
4117 | iwe.u.data.length = 0; | 4122 | iwe.u.data.length = 0; |
4118 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); | 4123 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4124 | &iwe, bss->a.essid); | ||
4119 | 4125 | ||
4120 | /* Add EXTRA: Age to display seconds since last beacon/probe response | 4126 | /* Add EXTRA: Age to display seconds since last beacon/probe response |
4121 | * for given network. */ | 4127 | * for given network. */ |
@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4126 | jiffies_to_msecs(jiffies - last_scanned)); | 4132 | jiffies_to_msecs(jiffies - last_scanned)); |
4127 | iwe.u.data.length = p - custom; | 4133 | iwe.u.data.length = p - custom; |
4128 | if (iwe.u.data.length) | 4134 | if (iwe.u.data.length) |
4129 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom); | 4135 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
4136 | &iwe, custom); | ||
4130 | 4137 | ||
4131 | /* Bit rate is not available in Lucent/Agere firmwares */ | 4138 | /* Bit rate is not available in Lucent/Agere firmwares */ |
4132 | if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { | 4139 | if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { |
4133 | char *current_val = current_ev + IW_EV_LCP_LEN; | 4140 | char *current_val = current_ev + iwe_stream_lcp_len(info); |
4134 | int i; | 4141 | int i; |
4135 | int step; | 4142 | int step; |
4136 | 4143 | ||
@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev, | |||
4149 | break; | 4156 | break; |
4150 | /* Bit rate given in 500 kb/s units (+ 0x80) */ | 4157 | /* Bit rate given in 500 kb/s units (+ 0x80) */ |
4151 | iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); | 4158 | iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); |
4152 | current_val = iwe_stream_add_value(current_ev, current_val, | 4159 | current_val = iwe_stream_add_value(info, current_ev, |
4160 | current_val, | ||
4153 | end_buf, &iwe, | 4161 | end_buf, &iwe, |
4154 | IW_EV_PARAM_LEN); | 4162 | IW_EV_PARAM_LEN); |
4155 | } | 4163 | } |
4156 | /* Check if we added any event */ | 4164 | /* Check if we added any event */ |
4157 | if ((current_val - current_ev) > IW_EV_LCP_LEN) | 4165 | if ((current_val - current_ev) > iwe_stream_lcp_len(info)) |
4158 | current_ev = current_val; | 4166 | current_ev = current_val; |
4159 | } | 4167 | } |
4160 | 4168 | ||
@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev, | |||
4190 | 4198 | ||
4191 | list_for_each_entry(bss, &priv->bss_list, list) { | 4199 | list_for_each_entry(bss, &priv->bss_list, list) { |
4192 | /* Translate to WE format this entry */ | 4200 | /* Translate to WE format this entry */ |
4193 | current_ev = orinoco_translate_scan(dev, current_ev, | 4201 | current_ev = orinoco_translate_scan(dev, info, current_ev, |
4194 | extra + srq->length, | 4202 | extra + srq->length, |
4195 | &bss->bss, | 4203 | &bss->bss, |
4196 | bss->last_scanned); | 4204 | bss->last_scanned); |
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c index 5b375b289036..97fa14e0a479 100644 --- a/drivers/net/wireless/prism54/isl_ioctl.c +++ b/drivers/net/wireless/prism54/isl_ioctl.c | |||
@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info, | |||
571 | */ | 571 | */ |
572 | 572 | ||
573 | static char * | 573 | static char * |
574 | prism54_translate_bss(struct net_device *ndev, char *current_ev, | 574 | prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info, |
575 | char *end_buf, struct obj_bss *bss, char noise) | 575 | char *current_ev, char *end_buf, struct obj_bss *bss, |
576 | char noise) | ||
576 | { | 577 | { |
577 | struct iw_event iwe; /* Temporary buffer */ | 578 | struct iw_event iwe; /* Temporary buffer */ |
578 | short cap; | 579 | short cap; |
@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
584 | memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); | 585 | memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); |
585 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 586 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
586 | iwe.cmd = SIOCGIWAP; | 587 | iwe.cmd = SIOCGIWAP; |
587 | current_ev = | 588 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
588 | iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); | 589 | &iwe, IW_EV_ADDR_LEN); |
589 | 590 | ||
590 | /* The following entries will be displayed in the same order we give them */ | 591 | /* The following entries will be displayed in the same order we give them */ |
591 | 592 | ||
@@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
593 | iwe.u.data.length = bss->ssid.length; | 594 | iwe.u.data.length = bss->ssid.length; |
594 | iwe.u.data.flags = 1; | 595 | iwe.u.data.flags = 1; |
595 | iwe.cmd = SIOCGIWESSID; | 596 | iwe.cmd = SIOCGIWESSID; |
596 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 597 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
597 | &iwe, bss->ssid.octets); | 598 | &iwe, bss->ssid.octets); |
598 | 599 | ||
599 | /* Capabilities */ | 600 | /* Capabilities */ |
@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
610 | iwe.u.mode = IW_MODE_ADHOC; | 611 | iwe.u.mode = IW_MODE_ADHOC; |
611 | iwe.cmd = SIOCGIWMODE; | 612 | iwe.cmd = SIOCGIWMODE; |
612 | if (iwe.u.mode) | 613 | if (iwe.u.mode) |
613 | current_ev = | 614 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
614 | iwe_stream_add_event(current_ev, end_buf, &iwe, | 615 | &iwe, IW_EV_UINT_LEN); |
615 | IW_EV_UINT_LEN); | ||
616 | 616 | ||
617 | /* Encryption capability */ | 617 | /* Encryption capability */ |
618 | if (cap & CAP_CRYPT) | 618 | if (cap & CAP_CRYPT) |
@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
621 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 621 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
622 | iwe.u.data.length = 0; | 622 | iwe.u.data.length = 0; |
623 | iwe.cmd = SIOCGIWENCODE; | 623 | iwe.cmd = SIOCGIWENCODE; |
624 | current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); | 624 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
625 | &iwe, NULL); | ||
625 | 626 | ||
626 | /* Add frequency. (short) bss->channel is the frequency in MHz */ | 627 | /* Add frequency. (short) bss->channel is the frequency in MHz */ |
627 | iwe.u.freq.m = bss->channel; | 628 | iwe.u.freq.m = bss->channel; |
628 | iwe.u.freq.e = 6; | 629 | iwe.u.freq.e = 6; |
629 | iwe.cmd = SIOCGIWFREQ; | 630 | iwe.cmd = SIOCGIWFREQ; |
630 | current_ev = | 631 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
631 | iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); | 632 | &iwe, IW_EV_FREQ_LEN); |
632 | 633 | ||
633 | /* Add quality statistics */ | 634 | /* Add quality statistics */ |
634 | iwe.u.qual.level = bss->rssi; | 635 | iwe.u.qual.level = bss->rssi; |
@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
636 | /* do a simple SNR for quality */ | 637 | /* do a simple SNR for quality */ |
637 | iwe.u.qual.qual = bss->rssi - noise; | 638 | iwe.u.qual.qual = bss->rssi - noise; |
638 | iwe.cmd = IWEVQUAL; | 639 | iwe.cmd = IWEVQUAL; |
639 | current_ev = | 640 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
640 | iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); | 641 | &iwe, IW_EV_QUAL_LEN); |
641 | 642 | ||
642 | /* Add WPA/RSN Information Element, if any */ | 643 | /* Add WPA/RSN Information Element, if any */ |
643 | wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); | 644 | wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); |
644 | if (wpa_ie_len > 0) { | 645 | if (wpa_ie_len > 0) { |
645 | iwe.cmd = IWEVGENIE; | 646 | iwe.cmd = IWEVGENIE; |
646 | iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); | 647 | iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); |
647 | current_ev = iwe_stream_add_point(current_ev, end_buf, | 648 | current_ev = iwe_stream_add_point(info, current_ev, end_buf, |
648 | &iwe, wpa_ie); | 649 | &iwe, wpa_ie); |
649 | } | 650 | } |
650 | /* Do the bitrates */ | 651 | /* Do the bitrates */ |
651 | { | 652 | { |
652 | char * current_val = current_ev + IW_EV_LCP_LEN; | 653 | char *current_val = current_ev + iwe_stream_lcp_len(info); |
653 | int i; | 654 | int i; |
654 | int mask; | 655 | int mask; |
655 | 656 | ||
@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev, | |||
662 | for(i = 0; i < sizeof(scan_rate_list); i++) { | 663 | for(i = 0; i < sizeof(scan_rate_list); i++) { |
663 | if(bss->rates & mask) { | 664 | if(bss->rates & mask) { |
664 | iwe.u.bitrate.value = (scan_rate_list[i] * 500000); | 665 | iwe.u.bitrate.value = (scan_rate_list[i] * 500000); |
665 | current_val = iwe_stream_add_value(current_ev, current_val, | 666 | current_val = iwe_stream_add_value( |
666 | end_buf, &iwe, | 667 | info, current_ev, current_val, |
667 | IW_EV_PARAM_LEN); | 668 | end_buf, &iwe, IW_EV_PARAM_LEN); |
668 | } | 669 | } |
669 | mask <<= 1; | 670 | mask <<= 1; |
670 | } | 671 | } |
671 | /* Check if we added any event */ | 672 | /* Check if we added any event */ |
672 | if ((current_val - current_ev) > IW_EV_LCP_LEN) | 673 | if ((current_val - current_ev) > iwe_stream_lcp_len(info)) |
673 | current_ev = current_val; | 674 | current_ev = current_val; |
674 | } | 675 | } |
675 | 676 | ||
@@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info, | |||
710 | 711 | ||
711 | /* ok now, scan the list and translate its info */ | 712 | /* ok now, scan the list and translate its info */ |
712 | for (i = 0; i < (int) bsslist->nr; i++) { | 713 | for (i = 0; i < (int) bsslist->nr; i++) { |
713 | current_ev = prism54_translate_bss(ndev, current_ev, | 714 | current_ev = prism54_translate_bss(ndev, info, current_ev, |
714 | extra + dwrq->length, | 715 | extra + dwrq->length, |
715 | &(bsslist->bsslist[i]), | 716 | &(bsslist->bsslist[i]), |
716 | noise); | 717 | noise); |
@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev, | |||
2704 | struct prism2_hostapd_param *param) | 2705 | struct prism2_hostapd_param *param) |
2705 | { | 2706 | { |
2706 | islpci_private *priv = netdev_priv(ndev); | 2707 | islpci_private *priv = netdev_priv(ndev); |
2708 | struct iw_request_info info; | ||
2707 | int i, rvalue; | 2709 | int i, rvalue; |
2708 | struct obj_bsslist *bsslist; | 2710 | struct obj_bsslist *bsslist; |
2709 | u32 noise = 0; | 2711 | u32 noise = 0; |
@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev, | |||
2727 | rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); | 2729 | rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); |
2728 | bsslist = r.ptr; | 2730 | bsslist = r.ptr; |
2729 | 2731 | ||
2732 | info.cmd = PRISM54_HOSTAPD; | ||
2733 | info.flags = 0; | ||
2734 | |||
2730 | /* ok now, scan the list and translate its info */ | 2735 | /* ok now, scan the list and translate its info */ |
2731 | for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++) | 2736 | for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++) |
2732 | current_ev = prism54_translate_bss(ndev, current_ev, | 2737 | current_ev = prism54_translate_bss(ndev, &info, current_ev, |
2733 | extra + IW_SCAN_MAX_DATA, | 2738 | extra + IW_SCAN_MAX_DATA, |
2734 | &(bsslist->bsslist[i]), | 2739 | &(bsslist->bsslist[i]), |
2735 | noise); | 2740 | noise); |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index f001f2afd05e..00e965b9da75 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev, | |||
1648 | 1648 | ||
1649 | 1649 | ||
1650 | static char *rndis_translate_scan(struct net_device *dev, | 1650 | static char *rndis_translate_scan(struct net_device *dev, |
1651 | char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid) | 1651 | struct iw_request_info *info, char *cev, |
1652 | char *end_buf, | ||
1653 | struct ndis_80211_bssid_ex *bssid) | ||
1652 | { | 1654 | { |
1653 | #ifdef DEBUG | 1655 | #ifdef DEBUG |
1654 | struct usbnet *usbdev = dev->priv; | 1656 | struct usbnet *usbdev = dev->priv; |
@@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1667 | iwe.cmd = SIOCGIWAP; | 1669 | iwe.cmd = SIOCGIWAP; |
1668 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 1670 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1669 | memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); | 1671 | memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); |
1670 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); | 1672 | cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN); |
1671 | 1673 | ||
1672 | devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), | 1674 | devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), |
1673 | bssid->ssid.essid); | 1675 | bssid->ssid.essid); |
1674 | iwe.cmd = SIOCGIWESSID; | 1676 | iwe.cmd = SIOCGIWESSID; |
1675 | iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); | 1677 | iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); |
1676 | iwe.u.essid.flags = 1; | 1678 | iwe.u.essid.flags = 1; |
1677 | cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid); | 1679 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid); |
1678 | 1680 | ||
1679 | devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); | 1681 | devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); |
1680 | iwe.cmd = SIOCGIWMODE; | 1682 | iwe.cmd = SIOCGIWMODE; |
@@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1690 | iwe.u.mode = IW_MODE_AUTO; | 1692 | iwe.u.mode = IW_MODE_AUTO; |
1691 | break; | 1693 | break; |
1692 | } | 1694 | } |
1693 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); | 1695 | cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN); |
1694 | 1696 | ||
1695 | devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); | 1697 | devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); |
1696 | iwe.cmd = SIOCGIWFREQ; | 1698 | iwe.cmd = SIOCGIWFREQ; |
1697 | dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); | 1699 | dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); |
1698 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); | 1700 | cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN); |
1699 | 1701 | ||
1700 | devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); | 1702 | devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); |
1701 | iwe.cmd = IWEVQUAL; | 1703 | iwe.cmd = IWEVQUAL; |
@@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1704 | iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED | 1706 | iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED |
1705 | | IW_QUAL_LEVEL_UPDATED | 1707 | | IW_QUAL_LEVEL_UPDATED |
1706 | | IW_QUAL_NOISE_INVALID; | 1708 | | IW_QUAL_NOISE_INVALID; |
1707 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); | 1709 | cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN); |
1708 | 1710 | ||
1709 | devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); | 1711 | devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); |
1710 | iwe.cmd = SIOCGIWENCODE; | 1712 | iwe.cmd = SIOCGIWENCODE; |
@@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1714 | else | 1716 | else |
1715 | iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; | 1717 | iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; |
1716 | 1718 | ||
1717 | cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); | 1719 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL); |
1718 | 1720 | ||
1719 | devdbg(usbdev, "RATES:"); | 1721 | devdbg(usbdev, "RATES:"); |
1720 | current_val = cev + IW_EV_LCP_LEN; | 1722 | current_val = cev + iwe_stream_lcp_len(info); |
1721 | iwe.cmd = SIOCGIWRATE; | 1723 | iwe.cmd = SIOCGIWRATE; |
1722 | for (i = 0; i < sizeof(bssid->rates); i++) { | 1724 | for (i = 0; i < sizeof(bssid->rates); i++) { |
1723 | if (bssid->rates[i] & 0x7f) { | 1725 | if (bssid->rates[i] & 0x7f) { |
@@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1725 | ((bssid->rates[i] & 0x7f) * | 1727 | ((bssid->rates[i] & 0x7f) * |
1726 | 500000); | 1728 | 500000); |
1727 | devdbg(usbdev, " %d", iwe.u.bitrate.value); | 1729 | devdbg(usbdev, " %d", iwe.u.bitrate.value); |
1728 | current_val = iwe_stream_add_value(cev, | 1730 | current_val = iwe_stream_add_value(info, cev, |
1729 | current_val, end_buf, &iwe, | 1731 | current_val, end_buf, &iwe, |
1730 | IW_EV_PARAM_LEN); | 1732 | IW_EV_PARAM_LEN); |
1731 | } | 1733 | } |
1732 | } | 1734 | } |
1733 | 1735 | ||
1734 | if ((current_val - cev) > IW_EV_LCP_LEN) | 1736 | if ((current_val - cev) > iwe_stream_lcp_len(info)) |
1735 | cev = current_val; | 1737 | cev = current_val; |
1736 | 1738 | ||
1737 | beacon = le32_to_cpu(bssid->config.beacon_period); | 1739 | beacon = le32_to_cpu(bssid->config.beacon_period); |
@@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1739 | iwe.cmd = IWEVCUSTOM; | 1741 | iwe.cmd = IWEVCUSTOM; |
1740 | snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); | 1742 | snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); |
1741 | iwe.u.data.length = strlen(sbuf); | 1743 | iwe.u.data.length = strlen(sbuf); |
1742 | cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); | 1744 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); |
1743 | 1745 | ||
1744 | atim = le32_to_cpu(bssid->config.atim_window); | 1746 | atim = le32_to_cpu(bssid->config.atim_window); |
1745 | devdbg(usbdev, "ATIM %d", atim); | 1747 | devdbg(usbdev, "ATIM %d", atim); |
1746 | iwe.cmd = IWEVCUSTOM; | 1748 | iwe.cmd = IWEVCUSTOM; |
1747 | snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); | 1749 | snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); |
1748 | iwe.u.data.length = strlen(sbuf); | 1750 | iwe.u.data.length = strlen(sbuf); |
1749 | cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); | 1751 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf); |
1750 | 1752 | ||
1751 | ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); | 1753 | ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); |
1752 | ie_len = min(bssid_len - (int)sizeof(*bssid), | 1754 | ie_len = min(bssid_len - (int)sizeof(*bssid), |
@@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev, | |||
1760 | (ie->id == MFIE_TYPE_RSN) ? 2 : 1); | 1762 | (ie->id == MFIE_TYPE_RSN) ? 2 : 1); |
1761 | iwe.cmd = IWEVGENIE; | 1763 | iwe.cmd = IWEVGENIE; |
1762 | iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN); | 1764 | iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN); |
1763 | cev = iwe_stream_add_point(cev, end_buf, &iwe, | 1765 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, |
1764 | (u8 *)ie); | 1766 | (u8 *)ie); |
1765 | } | 1767 | } |
1766 | 1768 | ||
@@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev, | |||
1803 | devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); | 1805 | devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); |
1804 | 1806 | ||
1805 | while (count && ((void *)bssid + bssid_len) <= (buf + len)) { | 1807 | while (count && ((void *)bssid + bssid_len) <= (buf + len)) { |
1806 | cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA, | 1808 | cev = rndis_translate_scan(dev, info, cev, |
1807 | bssid); | 1809 | extra + IW_SCAN_MAX_DATA, bssid); |
1808 | bssid = (void *)bssid + bssid_len; | 1810 | bssid = (void *)bssid + bssid_len; |
1809 | bssid_len = le32_to_cpu(bssid->length); | 1811 | bssid_len = le32_to_cpu(bssid->length); |
1810 | count--; | 1812 | count--; |
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c index bb3d83560d02..b3dffcfed835 100644 --- a/drivers/net/wireless/rt2x00/rt2400pci.c +++ b/drivers/net/wireless/rt2x00/rt2400pci.c | |||
@@ -632,15 +632,15 @@ static void rt2400pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
632 | struct queue_entry *entry) | 632 | struct queue_entry *entry) |
633 | { | 633 | { |
634 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 634 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
635 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
635 | u32 word; | 636 | u32 word; |
636 | 637 | ||
637 | rt2x00_desc_read(entry_priv->desc, 2, &word); | 638 | rt2x00_desc_read(entry_priv->desc, 2, &word); |
638 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, | 639 | rt2x00_set_field32(&word, RXD_W2_BUFFER_LENGTH, entry->skb->len); |
639 | entry->queue->data_size); | ||
640 | rt2x00_desc_write(entry_priv->desc, 2, word); | 640 | rt2x00_desc_write(entry_priv->desc, 2, word); |
641 | 641 | ||
642 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 642 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
643 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 643 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
644 | rt2x00_desc_write(entry_priv->desc, 1, word); | 644 | rt2x00_desc_write(entry_priv->desc, 1, word); |
645 | 645 | ||
646 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 646 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1012,7 +1012,7 @@ static void rt2400pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1012 | * Start writing the descriptor words. | 1012 | * Start writing the descriptor words. |
1013 | */ | 1013 | */ |
1014 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1014 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 1015 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1016 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1016 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1017 | 1017 | ||
1018 | rt2x00_desc_read(txd, 2, &word); | 1018 | rt2x00_desc_read(txd, 2, &word); |
@@ -1154,7 +1154,7 @@ static void rt2400pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1154 | } | 1154 | } |
1155 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1155 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1156 | 1156 | ||
1157 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); | 1157 | rt2x00lib_txdone(entry, &txdesc); |
1158 | } | 1158 | } |
1159 | } | 1159 | } |
1160 | 1160 | ||
@@ -1366,7 +1366,7 @@ static void rt2400pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1366 | IEEE80211_HW_SIGNAL_DBM; | 1366 | IEEE80211_HW_SIGNAL_DBM; |
1367 | rt2x00dev->hw->extra_tx_headroom = 0; | 1367 | rt2x00dev->hw->extra_tx_headroom = 0; |
1368 | 1368 | ||
1369 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 1369 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1370 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1370 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1371 | rt2x00_eeprom_addr(rt2x00dev, | 1371 | rt2x00_eeprom_addr(rt2x00dev, |
1372 | EEPROM_MAC_ADDR_0)); | 1372 | EEPROM_MAC_ADDR_0)); |
@@ -1412,9 +1412,10 @@ static int rt2400pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1412 | rt2400pci_probe_hw_mode(rt2x00dev); | 1412 | rt2400pci_probe_hw_mode(rt2x00dev); |
1413 | 1413 | ||
1414 | /* | 1414 | /* |
1415 | * This device requires the atim queue | 1415 | * This device requires the atim queue and DMA-mapped skbs. |
1416 | */ | 1416 | */ |
1417 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1417 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1418 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
1418 | 1419 | ||
1419 | /* | 1420 | /* |
1420 | * Set the rssi offset. | 1421 | * Set the rssi offset. |
@@ -1526,7 +1527,7 @@ static int rt2400pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1526 | * Write entire beacon with descriptor to register, | 1527 | * Write entire beacon with descriptor to register, |
1527 | * and kick the beacon generator. | 1528 | * and kick the beacon generator. |
1528 | */ | 1529 | */ |
1529 | memcpy(entry_priv->data, skb->data, skb->len); | 1530 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); |
1530 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | 1531 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
1531 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | 1532 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); |
1532 | 1533 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c index 3c956b91c4e3..0423c251c78e 100644 --- a/drivers/net/wireless/rt2x00/rt2500pci.c +++ b/drivers/net/wireless/rt2x00/rt2500pci.c | |||
@@ -727,10 +727,11 @@ static void rt2500pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
727 | struct queue_entry *entry) | 727 | struct queue_entry *entry) |
728 | { | 728 | { |
729 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 729 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
730 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
730 | u32 word; | 731 | u32 word; |
731 | 732 | ||
732 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 733 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
733 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 734 | rt2x00_set_field32(&word, RXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
734 | rt2x00_desc_write(entry_priv->desc, 1, word); | 735 | rt2x00_desc_write(entry_priv->desc, 1, word); |
735 | 736 | ||
736 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 737 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1171,7 +1172,7 @@ static void rt2500pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1171 | * Start writing the descriptor words. | 1172 | * Start writing the descriptor words. |
1172 | */ | 1173 | */ |
1173 | rt2x00_desc_read(entry_priv->desc, 1, &word); | 1174 | rt2x00_desc_read(entry_priv->desc, 1, &word); |
1174 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, entry_priv->data_dma); | 1175 | rt2x00_set_field32(&word, TXD_W1_BUFFER_ADDRESS, skbdesc->skb_dma); |
1175 | rt2x00_desc_write(entry_priv->desc, 1, word); | 1176 | rt2x00_desc_write(entry_priv->desc, 1, word); |
1176 | 1177 | ||
1177 | rt2x00_desc_read(txd, 2, &word); | 1178 | rt2x00_desc_read(txd, 2, &word); |
@@ -1311,7 +1312,7 @@ static void rt2500pci_txdone(struct rt2x00_dev *rt2x00dev, | |||
1311 | } | 1312 | } |
1312 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); | 1313 | txdesc.retry = rt2x00_get_field32(word, TXD_W0_RETRY_COUNT); |
1313 | 1314 | ||
1314 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); | 1315 | rt2x00lib_txdone(entry, &txdesc); |
1315 | } | 1316 | } |
1316 | } | 1317 | } |
1317 | 1318 | ||
@@ -1688,7 +1689,7 @@ static void rt2500pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1688 | 1689 | ||
1689 | rt2x00dev->hw->extra_tx_headroom = 0; | 1690 | rt2x00dev->hw->extra_tx_headroom = 0; |
1690 | 1691 | ||
1691 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 1692 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1692 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1693 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1693 | rt2x00_eeprom_addr(rt2x00dev, | 1694 | rt2x00_eeprom_addr(rt2x00dev, |
1694 | EEPROM_MAC_ADDR_0)); | 1695 | EEPROM_MAC_ADDR_0)); |
@@ -1752,9 +1753,10 @@ static int rt2500pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1752 | rt2500pci_probe_hw_mode(rt2x00dev); | 1753 | rt2500pci_probe_hw_mode(rt2x00dev); |
1753 | 1754 | ||
1754 | /* | 1755 | /* |
1755 | * This device requires the atim queue | 1756 | * This device requires the atim queue and DMA-mapped skbs. |
1756 | */ | 1757 | */ |
1757 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); | 1758 | __set_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags); |
1759 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
1758 | 1760 | ||
1759 | /* | 1761 | /* |
1760 | * Set the rssi offset. | 1762 | * Set the rssi offset. |
@@ -1842,7 +1844,7 @@ static int rt2500pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
1842 | * Write entire beacon with descriptor to register, | 1844 | * Write entire beacon with descriptor to register, |
1843 | * and kick the beacon generator. | 1845 | * and kick the beacon generator. |
1844 | */ | 1846 | */ |
1845 | memcpy(entry_priv->data, skb->data, skb->len); | 1847 | rt2x00queue_map_txskb(rt2x00dev, intf->beacon->skb); |
1846 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); | 1848 | rt2x00queue_write_tx_descriptor(intf->beacon, &txdesc); |
1847 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); | 1849 | rt2x00dev->ops->lib->kick_tx_queue(rt2x00dev, QID_BEACON); |
1848 | 1850 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c index 0462d6d35b8a..0dd1cb537b92 100644 --- a/drivers/net/wireless/rt2x00/rt2500usb.c +++ b/drivers/net/wireless/rt2x00/rt2500usb.c | |||
@@ -1594,7 +1594,7 @@ static void rt2500usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1594 | 1594 | ||
1595 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1595 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1596 | 1596 | ||
1597 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1597 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1598 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1598 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1599 | rt2x00_eeprom_addr(rt2x00dev, | 1599 | rt2x00_eeprom_addr(rt2x00dev, |
1600 | EEPROM_MAC_ADDR_0)); | 1600 | EEPROM_MAC_ADDR_0)); |
@@ -1678,7 +1678,7 @@ static int rt2500usb_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
1678 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | 1678 | static int rt2500usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) |
1679 | { | 1679 | { |
1680 | struct rt2x00_dev *rt2x00dev = hw->priv; | 1680 | struct rt2x00_dev *rt2x00dev = hw->priv; |
1681 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 1681 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
1682 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); | 1682 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); |
1683 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); | 1683 | struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif); |
1684 | struct queue_entry_priv_usb_bcn *bcn_priv; | 1684 | struct queue_entry_priv_usb_bcn *bcn_priv; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h index 52d8e9688219..6842464dcf3e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00.h +++ b/drivers/net/wireless/rt2x00/rt2x00.h | |||
@@ -44,7 +44,7 @@ | |||
44 | /* | 44 | /* |
45 | * Module information. | 45 | * Module information. |
46 | */ | 46 | */ |
47 | #define DRV_VERSION "2.1.7" | 47 | #define DRV_VERSION "2.1.8" |
48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" | 48 | #define DRV_PROJECT "http://rt2x00.serialmonkey.com" |
49 | 49 | ||
50 | /* | 50 | /* |
@@ -111,33 +111,6 @@ | |||
111 | #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) | 111 | #define EIFS ( SIFS + (8 * (IEEE80211_HEADER + ACK_SIZE)) ) |
112 | 112 | ||
113 | /* | 113 | /* |
114 | * IEEE802.11 header defines | ||
115 | */ | ||
116 | static inline int is_rts_frame(u16 fc) | ||
117 | { | ||
118 | return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | ||
119 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_RTS)); | ||
120 | } | ||
121 | |||
122 | static inline int is_cts_frame(u16 fc) | ||
123 | { | ||
124 | return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_CTL) && | ||
125 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_CTS)); | ||
126 | } | ||
127 | |||
128 | static inline int is_probe_resp(u16 fc) | ||
129 | { | ||
130 | return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
131 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_PROBE_RESP)); | ||
132 | } | ||
133 | |||
134 | static inline int is_beacon(u16 fc) | ||
135 | { | ||
136 | return (((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_MGMT) && | ||
137 | ((fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_BEACON)); | ||
138 | } | ||
139 | |||
140 | /* | ||
141 | * Chipset identification | 114 | * Chipset identification |
142 | * The chipset on the device is composed of a RT and RF chip. | 115 | * The chipset on the device is composed of a RT and RF chip. |
143 | * The chipset combination is important for determining device capabilities. | 116 | * The chipset combination is important for determining device capabilities. |
@@ -628,6 +601,7 @@ enum rt2x00_flags { | |||
628 | DRIVER_REQUIRE_BEACON_GUARD, | 601 | DRIVER_REQUIRE_BEACON_GUARD, |
629 | DRIVER_REQUIRE_ATIM_QUEUE, | 602 | DRIVER_REQUIRE_ATIM_QUEUE, |
630 | DRIVER_REQUIRE_SCHEDULED, | 603 | DRIVER_REQUIRE_SCHEDULED, |
604 | DRIVER_REQUIRE_DMA, | ||
631 | 605 | ||
632 | /* | 606 | /* |
633 | * Driver configuration | 607 | * Driver configuration |
@@ -652,11 +626,7 @@ struct rt2x00_dev { | |||
652 | * When accessing this variable, the rt2x00dev_{pci,usb} | 626 | * When accessing this variable, the rt2x00dev_{pci,usb} |
653 | * macro's should be used for correct typecasting. | 627 | * macro's should be used for correct typecasting. |
654 | */ | 628 | */ |
655 | void *dev; | 629 | struct device *dev; |
656 | #define rt2x00dev_pci(__dev) ( (struct pci_dev *)(__dev)->dev ) | ||
657 | #define rt2x00dev_usb(__dev) ( (struct usb_interface *)(__dev)->dev ) | ||
658 | #define rt2x00dev_usb_dev(__dev)\ | ||
659 | ( (struct usb_device *)interface_to_usbdev(rt2x00dev_usb(__dev)) ) | ||
660 | 630 | ||
661 | /* | 631 | /* |
662 | * Callback functions. | 632 | * Callback functions. |
@@ -931,10 +901,11 @@ static inline u16 get_duration_res(const unsigned int size, const u8 rate) | |||
931 | } | 901 | } |
932 | 902 | ||
933 | /** | 903 | /** |
934 | * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. | 904 | * rt2x00queue_map_txskb - Map a skb into DMA for TX purposes. |
935 | * @queue: The queue for which the skb will be applicable. | 905 | * @rt2x00dev: Pointer to &struct rt2x00_dev. |
906 | * @skb: The skb to map. | ||
936 | */ | 907 | */ |
937 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue); | 908 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); |
938 | 909 | ||
939 | /** | 910 | /** |
940 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input | 911 | * rt2x00queue_create_tx_descriptor - Create TX descriptor from mac80211 input |
@@ -985,26 +956,14 @@ struct data_queue *rt2x00queue_get_queue(struct rt2x00_dev *rt2x00dev, | |||
985 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, | 956 | struct queue_entry *rt2x00queue_get_entry(struct data_queue *queue, |
986 | enum queue_index index); | 957 | enum queue_index index); |
987 | 958 | ||
988 | /** | ||
989 | * rt2x00queue_index_inc - Index incrementation function | ||
990 | * @queue: Queue (&struct data_queue) to perform the action on. | ||
991 | * @index: Index type (&enum queue_index) to perform the action on. | ||
992 | * | ||
993 | * This function will increase the requested index on the queue, | ||
994 | * it will grab the appropriate locks and handle queue overflow events by | ||
995 | * resetting the index to the start of the queue. | ||
996 | */ | ||
997 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | ||
998 | |||
999 | |||
1000 | /* | 959 | /* |
1001 | * Interrupt context handlers. | 960 | * Interrupt context handlers. |
1002 | */ | 961 | */ |
1003 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); | 962 | void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev); |
1004 | void rt2x00lib_txdone(struct queue_entry *entry, | 963 | void rt2x00lib_txdone(struct queue_entry *entry, |
1005 | struct txdone_entry_desc *txdesc); | 964 | struct txdone_entry_desc *txdesc); |
1006 | void rt2x00lib_rxdone(struct queue_entry *entry, | 965 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, |
1007 | struct rxdone_entry_desc *rxdesc); | 966 | struct queue_entry *entry); |
1008 | 967 | ||
1009 | /* | 968 | /* |
1010 | * mac80211 handlers. | 969 | * mac80211 handlers. |
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c index cc4fee105ed6..ae8ab71fe474 100644 --- a/drivers/net/wireless/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/rt2x00/rt2x00dev.c | |||
@@ -469,12 +469,19 @@ static void rt2x00lib_intf_scheduled(struct work_struct *work) | |||
469 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, | 469 | static void rt2x00lib_beacondone_iter(void *data, u8 *mac, |
470 | struct ieee80211_vif *vif) | 470 | struct ieee80211_vif *vif) |
471 | { | 471 | { |
472 | struct rt2x00_dev *rt2x00dev = data; | ||
472 | struct rt2x00_intf *intf = vif_to_intf(vif); | 473 | struct rt2x00_intf *intf = vif_to_intf(vif); |
473 | 474 | ||
474 | if (vif->type != IEEE80211_IF_TYPE_AP && | 475 | if (vif->type != IEEE80211_IF_TYPE_AP && |
475 | vif->type != IEEE80211_IF_TYPE_IBSS) | 476 | vif->type != IEEE80211_IF_TYPE_IBSS) |
476 | return; | 477 | return; |
477 | 478 | ||
479 | /* | ||
480 | * Clean up the beacon skb. | ||
481 | */ | ||
482 | rt2x00queue_free_skb(rt2x00dev, intf->beacon->skb); | ||
483 | intf->beacon->skb = NULL; | ||
484 | |||
478 | spin_lock(&intf->lock); | 485 | spin_lock(&intf->lock); |
479 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; | 486 | intf->delayed_flags |= DELAYED_UPDATE_BEACON; |
480 | spin_unlock(&intf->lock); | 487 | spin_unlock(&intf->lock); |
@@ -498,6 +505,12 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
498 | { | 505 | { |
499 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 506 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
500 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); | 507 | struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(entry->skb); |
508 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | ||
509 | |||
510 | /* | ||
511 | * Unmap the skb. | ||
512 | */ | ||
513 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
501 | 514 | ||
502 | /* | 515 | /* |
503 | * Send frame to debugfs immediately, after this call is completed | 516 | * Send frame to debugfs immediately, after this call is completed |
@@ -546,39 +559,77 @@ void rt2x00lib_txdone(struct queue_entry *entry, | |||
546 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); | 559 | ieee80211_tx_status_irqsafe(rt2x00dev->hw, entry->skb); |
547 | else | 560 | else |
548 | dev_kfree_skb_irq(entry->skb); | 561 | dev_kfree_skb_irq(entry->skb); |
562 | |||
563 | /* | ||
564 | * Make this entry available for reuse. | ||
565 | */ | ||
549 | entry->skb = NULL; | 566 | entry->skb = NULL; |
567 | entry->flags = 0; | ||
568 | |||
569 | rt2x00dev->ops->lib->init_txentry(rt2x00dev, entry); | ||
570 | |||
571 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
572 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
573 | |||
574 | /* | ||
575 | * If the data queue was below the threshold before the txdone | ||
576 | * handler we must make sure the packet queue in the mac80211 stack | ||
577 | * is reenabled when the txdone handler has finished. | ||
578 | */ | ||
579 | if (!rt2x00queue_threshold(entry->queue)) | ||
580 | ieee80211_wake_queue(rt2x00dev->hw, qid); | ||
550 | } | 581 | } |
551 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); | 582 | EXPORT_SYMBOL_GPL(rt2x00lib_txdone); |
552 | 583 | ||
553 | void rt2x00lib_rxdone(struct queue_entry *entry, | 584 | void rt2x00lib_rxdone(struct rt2x00_dev *rt2x00dev, |
554 | struct rxdone_entry_desc *rxdesc) | 585 | struct queue_entry *entry) |
555 | { | 586 | { |
556 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 587 | struct rxdone_entry_desc rxdesc; |
588 | struct sk_buff *skb; | ||
557 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; | 589 | struct ieee80211_rx_status *rx_status = &rt2x00dev->rx_status; |
558 | unsigned int header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
559 | struct ieee80211_supported_band *sband; | 590 | struct ieee80211_supported_band *sband; |
560 | struct ieee80211_hdr *hdr; | 591 | struct ieee80211_hdr *hdr; |
561 | const struct rt2x00_rate *rate; | 592 | const struct rt2x00_rate *rate; |
593 | unsigned int header_size; | ||
562 | unsigned int align; | 594 | unsigned int align; |
563 | unsigned int i; | 595 | unsigned int i; |
564 | int idx = -1; | 596 | int idx = -1; |
565 | u16 fc; | 597 | |
598 | /* | ||
599 | * Allocate a new sk_buffer. If no new buffer available, drop the | ||
600 | * received frame and reuse the existing buffer. | ||
601 | */ | ||
602 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, entry); | ||
603 | if (!skb) | ||
604 | return; | ||
605 | |||
606 | /* | ||
607 | * Unmap the skb. | ||
608 | */ | ||
609 | rt2x00queue_unmap_skb(rt2x00dev, entry->skb); | ||
610 | |||
611 | /* | ||
612 | * Extract the RXD details. | ||
613 | */ | ||
614 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
615 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
566 | 616 | ||
567 | /* | 617 | /* |
568 | * The data behind the ieee80211 header must be | 618 | * The data behind the ieee80211 header must be |
569 | * aligned on a 4 byte boundary. | 619 | * aligned on a 4 byte boundary. |
570 | */ | 620 | */ |
621 | header_size = ieee80211_get_hdrlen_from_skb(entry->skb); | ||
571 | align = ((unsigned long)(entry->skb->data + header_size)) & 3; | 622 | align = ((unsigned long)(entry->skb->data + header_size)) & 3; |
572 | 623 | ||
573 | if (align) { | 624 | if (align) { |
574 | skb_push(entry->skb, align); | 625 | skb_push(entry->skb, align); |
575 | /* Move entire frame in 1 command */ | 626 | /* Move entire frame in 1 command */ |
576 | memmove(entry->skb->data, entry->skb->data + align, | 627 | memmove(entry->skb->data, entry->skb->data + align, |
577 | rxdesc->size); | 628 | rxdesc.size); |
578 | } | 629 | } |
579 | 630 | ||
580 | /* Update data pointers, trim buffer to correct size */ | 631 | /* Update data pointers, trim buffer to correct size */ |
581 | skb_trim(entry->skb, rxdesc->size); | 632 | skb_trim(entry->skb, rxdesc.size); |
582 | 633 | ||
583 | /* | 634 | /* |
584 | * Update RX statistics. | 635 | * Update RX statistics. |
@@ -587,10 +638,10 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
587 | for (i = 0; i < sband->n_bitrates; i++) { | 638 | for (i = 0; i < sband->n_bitrates; i++) { |
588 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); | 639 | rate = rt2x00_get_rate(sband->bitrates[i].hw_value); |
589 | 640 | ||
590 | if (((rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && | 641 | if (((rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && |
591 | (rate->plcp == rxdesc->signal)) || | 642 | (rate->plcp == rxdesc.signal)) || |
592 | (!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP) && | 643 | (!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP) && |
593 | (rate->bitrate == rxdesc->signal))) { | 644 | (rate->bitrate == rxdesc.signal))) { |
594 | idx = i; | 645 | idx = i; |
595 | break; | 646 | break; |
596 | } | 647 | } |
@@ -598,8 +649,8 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
598 | 649 | ||
599 | if (idx < 0) { | 650 | if (idx < 0) { |
600 | WARNING(rt2x00dev, "Frame received with unrecognized signal," | 651 | WARNING(rt2x00dev, "Frame received with unrecognized signal," |
601 | "signal=0x%.2x, plcp=%d.\n", rxdesc->signal, | 652 | "signal=0x%.2x, plcp=%d.\n", rxdesc.signal, |
602 | !!(rxdesc->dev_flags & RXDONE_SIGNAL_PLCP)); | 653 | !!(rxdesc.dev_flags & RXDONE_SIGNAL_PLCP)); |
603 | idx = 0; | 654 | idx = 0; |
604 | } | 655 | } |
605 | 656 | ||
@@ -607,17 +658,17 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
607 | * Only update link status if this is a beacon frame carrying our bssid. | 658 | * Only update link status if this is a beacon frame carrying our bssid. |
608 | */ | 659 | */ |
609 | hdr = (struct ieee80211_hdr *)entry->skb->data; | 660 | hdr = (struct ieee80211_hdr *)entry->skb->data; |
610 | fc = le16_to_cpu(hdr->frame_control); | 661 | if (ieee80211_is_beacon(hdr->frame_control) && |
611 | if (is_beacon(fc) && (rxdesc->dev_flags & RXDONE_MY_BSS)) | 662 | (rxdesc.dev_flags & RXDONE_MY_BSS)) |
612 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc->rssi); | 663 | rt2x00lib_update_link_stats(&rt2x00dev->link, rxdesc.rssi); |
613 | 664 | ||
614 | rt2x00dev->link.qual.rx_success++; | 665 | rt2x00dev->link.qual.rx_success++; |
615 | 666 | ||
616 | rx_status->rate_idx = idx; | 667 | rx_status->rate_idx = idx; |
617 | rx_status->qual = | 668 | rx_status->qual = |
618 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc->rssi); | 669 | rt2x00lib_calculate_link_signal(rt2x00dev, rxdesc.rssi); |
619 | rx_status->signal = rxdesc->rssi; | 670 | rx_status->signal = rxdesc.rssi; |
620 | rx_status->flag = rxdesc->flags; | 671 | rx_status->flag = rxdesc.flags; |
621 | rx_status->antenna = rt2x00dev->link.ant.active.rx; | 672 | rx_status->antenna = rt2x00dev->link.ant.active.rx; |
622 | 673 | ||
623 | /* | 674 | /* |
@@ -626,7 +677,16 @@ void rt2x00lib_rxdone(struct queue_entry *entry, | |||
626 | */ | 677 | */ |
627 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); | 678 | rt2x00debug_dump_frame(rt2x00dev, DUMP_FRAME_RXDONE, entry->skb); |
628 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); | 679 | ieee80211_rx_irqsafe(rt2x00dev->hw, entry->skb, rx_status); |
629 | entry->skb = NULL; | 680 | |
681 | /* | ||
682 | * Replace the skb with the freshly allocated one. | ||
683 | */ | ||
684 | entry->skb = skb; | ||
685 | entry->flags = 0; | ||
686 | |||
687 | rt2x00dev->ops->lib->init_rxentry(rt2x00dev, entry); | ||
688 | |||
689 | rt2x00queue_index_inc(entry->queue, Q_INDEX); | ||
630 | } | 690 | } |
631 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); | 691 | EXPORT_SYMBOL_GPL(rt2x00lib_rxdone); |
632 | 692 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00lib.h b/drivers/net/wireless/rt2x00/rt2x00lib.h index 558f45bf27e3..1d1f0749375e 100644 --- a/drivers/net/wireless/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/rt2x00/rt2x00lib.h | |||
@@ -98,10 +98,57 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev, | |||
98 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, | 98 | void rt2x00lib_config(struct rt2x00_dev *rt2x00dev, |
99 | struct ieee80211_conf *conf, const int force_config); | 99 | struct ieee80211_conf *conf, const int force_config); |
100 | 100 | ||
101 | /* | 101 | /** |
102 | * Queue handlers. | 102 | * DOC: Queue handlers |
103 | */ | ||
104 | |||
105 | /** | ||
106 | * rt2x00queue_alloc_rxskb - allocate a skb for RX purposes. | ||
107 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
108 | * @queue: The queue for which the skb will be applicable. | ||
109 | */ | ||
110 | struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, | ||
111 | struct queue_entry *entry); | ||
112 | |||
113 | /** | ||
114 | * rt2x00queue_unmap_skb - Unmap a skb from DMA. | ||
115 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
116 | * @skb: The skb to unmap. | ||
117 | */ | ||
118 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
119 | |||
120 | /** | ||
121 | * rt2x00queue_free_skb - free a skb | ||
122 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
123 | * @skb: The skb to free. | ||
124 | */ | ||
125 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
126 | |||
127 | /** | ||
128 | * rt2x00queue_free_skb - free a skb | ||
129 | * @rt2x00dev: Pointer to &struct rt2x00_dev. | ||
130 | * @skb: The skb to free. | ||
131 | */ | ||
132 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb); | ||
133 | |||
134 | /** | ||
135 | * rt2x00queue_write_tx_frame - Write TX frame to hardware | ||
136 | * @queue: Queue over which the frame should be send | ||
137 | * @skb: The skb to send | ||
103 | */ | 138 | */ |
104 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); | 139 | int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb); |
140 | |||
141 | /** | ||
142 | * rt2x00queue_index_inc - Index incrementation function | ||
143 | * @queue: Queue (&struct data_queue) to perform the action on. | ||
144 | * @index: Index type (&enum queue_index) to perform the action on. | ||
145 | * | ||
146 | * This function will increase the requested index on the queue, | ||
147 | * it will grab the appropriate locks and handle queue overflow events by | ||
148 | * resetting the index to the start of the queue. | ||
149 | */ | ||
150 | void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index); | ||
151 | |||
105 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); | 152 | void rt2x00queue_init_rx(struct rt2x00_dev *rt2x00dev); |
106 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); | 153 | void rt2x00queue_init_tx(struct rt2x00_dev *rt2x00dev); |
107 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); | 154 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 8d6ad18d3890..adf2876ed8ab 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c | |||
@@ -60,12 +60,8 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry) | |||
60 | * Fill in skb descriptor | 60 | * Fill in skb descriptor |
61 | */ | 61 | */ |
62 | skbdesc = get_skb_frame_desc(entry->skb); | 62 | skbdesc = get_skb_frame_desc(entry->skb); |
63 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
64 | skbdesc->desc = entry_priv->desc; | 63 | skbdesc->desc = entry_priv->desc; |
65 | skbdesc->desc_len = entry->queue->desc_size; | 64 | skbdesc->desc_len = entry->queue->desc_size; |
66 | skbdesc->entry = entry; | ||
67 | |||
68 | memcpy(entry_priv->data, entry->skb->data, entry->skb->len); | ||
69 | 65 | ||
70 | return 0; | 66 | return 0; |
71 | } | 67 | } |
@@ -80,7 +76,6 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
80 | struct queue_entry *entry; | 76 | struct queue_entry *entry; |
81 | struct queue_entry_priv_pci *entry_priv; | 77 | struct queue_entry_priv_pci *entry_priv; |
82 | struct skb_frame_desc *skbdesc; | 78 | struct skb_frame_desc *skbdesc; |
83 | struct rxdone_entry_desc rxdesc; | ||
84 | u32 word; | 79 | u32 word; |
85 | 80 | ||
86 | while (1) { | 81 | while (1) { |
@@ -91,110 +86,27 @@ void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev) | |||
91 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) | 86 | if (rt2x00_get_field32(word, RXD_ENTRY_OWNER_NIC)) |
92 | break; | 87 | break; |
93 | 88 | ||
94 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
95 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
96 | |||
97 | /* | 89 | /* |
98 | * Allocate the sk_buffer and copy all data into it. | 90 | * Fill in desc fields of the skb descriptor |
99 | */ | ||
100 | entry->skb = rt2x00queue_alloc_rxskb(queue); | ||
101 | if (!entry->skb) | ||
102 | return; | ||
103 | |||
104 | memcpy(entry->skb->data, entry_priv->data, rxdesc.size); | ||
105 | skb_trim(entry->skb, rxdesc.size); | ||
106 | |||
107 | /* | ||
108 | * Fill in skb descriptor | ||
109 | */ | 91 | */ |
110 | skbdesc = get_skb_frame_desc(entry->skb); | 92 | skbdesc = get_skb_frame_desc(entry->skb); |
111 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
112 | skbdesc->desc = entry_priv->desc; | 93 | skbdesc->desc = entry_priv->desc; |
113 | skbdesc->desc_len = queue->desc_size; | 94 | skbdesc->desc_len = entry->queue->desc_size; |
114 | skbdesc->entry = entry; | ||
115 | 95 | ||
116 | /* | 96 | /* |
117 | * Send the frame to rt2x00lib for further processing. | 97 | * Send the frame to rt2x00lib for further processing. |
118 | */ | 98 | */ |
119 | rt2x00lib_rxdone(entry, &rxdesc); | 99 | rt2x00lib_rxdone(rt2x00dev, entry); |
120 | |||
121 | if (test_bit(DEVICE_ENABLED_RADIO, &queue->rt2x00dev->flags)) { | ||
122 | rt2x00_set_field32(&word, RXD_ENTRY_OWNER_NIC, 1); | ||
123 | rt2x00_desc_write(entry_priv->desc, 0, word); | ||
124 | } | ||
125 | |||
126 | rt2x00queue_index_inc(queue, Q_INDEX); | ||
127 | } | 100 | } |
128 | } | 101 | } |
129 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); | 102 | EXPORT_SYMBOL_GPL(rt2x00pci_rxdone); |
130 | 103 | ||
131 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
132 | struct txdone_entry_desc *txdesc) | ||
133 | { | ||
134 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | ||
135 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | ||
136 | u32 word; | ||
137 | |||
138 | rt2x00lib_txdone(entry, txdesc); | ||
139 | |||
140 | /* | ||
141 | * Make this entry available for reuse. | ||
142 | */ | ||
143 | entry->flags = 0; | ||
144 | |||
145 | rt2x00_desc_read(entry_priv->desc, 0, &word); | ||
146 | rt2x00_set_field32(&word, TXD_ENTRY_OWNER_NIC, 0); | ||
147 | rt2x00_set_field32(&word, TXD_ENTRY_VALID, 0); | ||
148 | rt2x00_desc_write(entry_priv->desc, 0, word); | ||
149 | |||
150 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
151 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
152 | |||
153 | /* | ||
154 | * If the data queue was below the threshold before the txdone | ||
155 | * handler we must make sure the packet queue in the mac80211 stack | ||
156 | * is reenabled when the txdone handler has finished. | ||
157 | */ | ||
158 | if (!rt2x00queue_threshold(entry->queue)) | ||
159 | ieee80211_wake_queue(rt2x00dev->hw, qid); | ||
160 | |||
161 | } | ||
162 | EXPORT_SYMBOL_GPL(rt2x00pci_txdone); | ||
163 | |||
164 | /* | 104 | /* |
165 | * Device initialization handlers. | 105 | * Device initialization handlers. |
166 | */ | 106 | */ |
167 | #define desc_size(__queue) \ | ||
168 | ({ \ | ||
169 | ((__queue)->limit * (__queue)->desc_size);\ | ||
170 | }) | ||
171 | |||
172 | #define data_size(__queue) \ | ||
173 | ({ \ | ||
174 | ((__queue)->limit * (__queue)->data_size);\ | ||
175 | }) | ||
176 | |||
177 | #define dma_size(__queue) \ | ||
178 | ({ \ | ||
179 | data_size(__queue) + desc_size(__queue);\ | ||
180 | }) | ||
181 | |||
182 | #define desc_offset(__queue, __base, __i) \ | ||
183 | ({ \ | ||
184 | (__base) + data_size(__queue) + \ | ||
185 | ((__i) * (__queue)->desc_size); \ | ||
186 | }) | ||
187 | |||
188 | #define data_offset(__queue, __base, __i) \ | ||
189 | ({ \ | ||
190 | (__base) + \ | ||
191 | ((__i) * (__queue)->data_size); \ | ||
192 | }) | ||
193 | |||
194 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | 107 | static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, |
195 | struct data_queue *queue) | 108 | struct data_queue *queue) |
196 | { | 109 | { |
197 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
198 | struct queue_entry_priv_pci *entry_priv; | 110 | struct queue_entry_priv_pci *entry_priv; |
199 | void *addr; | 111 | void *addr; |
200 | dma_addr_t dma; | 112 | dma_addr_t dma; |
@@ -203,21 +115,21 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
203 | /* | 115 | /* |
204 | * Allocate DMA memory for descriptor and buffer. | 116 | * Allocate DMA memory for descriptor and buffer. |
205 | */ | 117 | */ |
206 | addr = pci_alloc_consistent(pci_dev, dma_size(queue), &dma); | 118 | addr = dma_alloc_coherent(rt2x00dev->dev, |
119 | queue->limit * queue->desc_size, | ||
120 | &dma, GFP_KERNEL | GFP_DMA); | ||
207 | if (!addr) | 121 | if (!addr) |
208 | return -ENOMEM; | 122 | return -ENOMEM; |
209 | 123 | ||
210 | memset(addr, 0, dma_size(queue)); | 124 | memset(addr, 0, queue->limit * queue->desc_size); |
211 | 125 | ||
212 | /* | 126 | /* |
213 | * Initialize all queue entries to contain valid addresses. | 127 | * Initialize all queue entries to contain valid addresses. |
214 | */ | 128 | */ |
215 | for (i = 0; i < queue->limit; i++) { | 129 | for (i = 0; i < queue->limit; i++) { |
216 | entry_priv = queue->entries[i].priv_data; | 130 | entry_priv = queue->entries[i].priv_data; |
217 | entry_priv->desc = desc_offset(queue, addr, i); | 131 | entry_priv->desc = addr + i * queue->desc_size; |
218 | entry_priv->desc_dma = desc_offset(queue, dma, i); | 132 | entry_priv->desc_dma = dma + i * queue->desc_size; |
219 | entry_priv->data = data_offset(queue, addr, i); | ||
220 | entry_priv->data_dma = data_offset(queue, dma, i); | ||
221 | } | 133 | } |
222 | 134 | ||
223 | return 0; | 135 | return 0; |
@@ -226,19 +138,19 @@ static int rt2x00pci_alloc_queue_dma(struct rt2x00_dev *rt2x00dev, | |||
226 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, | 138 | static void rt2x00pci_free_queue_dma(struct rt2x00_dev *rt2x00dev, |
227 | struct data_queue *queue) | 139 | struct data_queue *queue) |
228 | { | 140 | { |
229 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | ||
230 | struct queue_entry_priv_pci *entry_priv = | 141 | struct queue_entry_priv_pci *entry_priv = |
231 | queue->entries[0].priv_data; | 142 | queue->entries[0].priv_data; |
232 | 143 | ||
233 | if (entry_priv->data) | 144 | if (entry_priv->desc) |
234 | pci_free_consistent(pci_dev, dma_size(queue), | 145 | dma_free_coherent(rt2x00dev->dev, |
235 | entry_priv->data, entry_priv->data_dma); | 146 | queue->limit * queue->desc_size, |
236 | entry_priv->data = NULL; | 147 | entry_priv->desc, entry_priv->desc_dma); |
148 | entry_priv->desc = NULL; | ||
237 | } | 149 | } |
238 | 150 | ||
239 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) | 151 | int rt2x00pci_initialize(struct rt2x00_dev *rt2x00dev) |
240 | { | 152 | { |
241 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 153 | struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); |
242 | struct data_queue *queue; | 154 | struct data_queue *queue; |
243 | int status; | 155 | int status; |
244 | 156 | ||
@@ -279,7 +191,7 @@ void rt2x00pci_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
279 | /* | 191 | /* |
280 | * Free irq line. | 192 | * Free irq line. |
281 | */ | 193 | */ |
282 | free_irq(rt2x00dev_pci(rt2x00dev)->irq, rt2x00dev); | 194 | free_irq(to_pci_dev(rt2x00dev->dev)->irq, rt2x00dev); |
283 | 195 | ||
284 | /* | 196 | /* |
285 | * Free DMA | 197 | * Free DMA |
@@ -308,7 +220,7 @@ static void rt2x00pci_free_reg(struct rt2x00_dev *rt2x00dev) | |||
308 | 220 | ||
309 | static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) | 221 | static int rt2x00pci_alloc_reg(struct rt2x00_dev *rt2x00dev) |
310 | { | 222 | { |
311 | struct pci_dev *pci_dev = rt2x00dev_pci(rt2x00dev); | 223 | struct pci_dev *pci_dev = to_pci_dev(rt2x00dev->dev); |
312 | 224 | ||
313 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), | 225 | rt2x00dev->csr.base = ioremap(pci_resource_start(pci_dev, 0), |
314 | pci_resource_len(pci_dev, 0)); | 226 | pci_resource_len(pci_dev, 0)); |
@@ -357,7 +269,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
357 | if (pci_set_mwi(pci_dev)) | 269 | if (pci_set_mwi(pci_dev)) |
358 | ERROR_PROBE("MWI not available.\n"); | 270 | ERROR_PROBE("MWI not available.\n"); |
359 | 271 | ||
360 | if (pci_set_dma_mask(pci_dev, DMA_32BIT_MASK)) { | 272 | if (dma_set_mask(&pci_dev->dev, DMA_32BIT_MASK)) { |
361 | ERROR_PROBE("PCI DMA not supported.\n"); | 273 | ERROR_PROBE("PCI DMA not supported.\n"); |
362 | retval = -EIO; | 274 | retval = -EIO; |
363 | goto exit_disable_device; | 275 | goto exit_disable_device; |
@@ -373,7 +285,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) | |||
373 | pci_set_drvdata(pci_dev, hw); | 285 | pci_set_drvdata(pci_dev, hw); |
374 | 286 | ||
375 | rt2x00dev = hw->priv; | 287 | rt2x00dev = hw->priv; |
376 | rt2x00dev->dev = pci_dev; | 288 | rt2x00dev->dev = &pci_dev->dev; |
377 | rt2x00dev->ops = ops; | 289 | rt2x00dev->ops = ops; |
378 | rt2x00dev->hw = hw; | 290 | rt2x00dev->hw = hw; |
379 | 291 | ||
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.h b/drivers/net/wireless/rt2x00/rt2x00pci.h index 87c4a0cd78db..50c6df4f81db 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.h +++ b/drivers/net/wireless/rt2x00/rt2x00pci.h | |||
@@ -107,9 +107,6 @@ int rt2x00pci_write_tx_data(struct queue_entry *entry); | |||
107 | struct queue_entry_priv_pci { | 107 | struct queue_entry_priv_pci { |
108 | __le32 *desc; | 108 | __le32 *desc; |
109 | dma_addr_t desc_dma; | 109 | dma_addr_t desc_dma; |
110 | |||
111 | void *data; | ||
112 | dma_addr_t data_dma; | ||
113 | }; | 110 | }; |
114 | 111 | ||
115 | /** | 112 | /** |
@@ -118,15 +115,6 @@ struct queue_entry_priv_pci { | |||
118 | */ | 115 | */ |
119 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); | 116 | void rt2x00pci_rxdone(struct rt2x00_dev *rt2x00dev); |
120 | 117 | ||
121 | /** | ||
122 | * rt2x00pci_txdone - Handle TX done events | ||
123 | * @rt2x00dev: Device pointer, see &struct rt2x00_dev. | ||
124 | * @entry: Entry which has completed the transmission of a frame. | ||
125 | * @desc: TX done descriptor | ||
126 | */ | ||
127 | void rt2x00pci_txdone(struct rt2x00_dev *rt2x00dev, struct queue_entry *entry, | ||
128 | struct txdone_entry_desc *desc); | ||
129 | |||
130 | /* | 118 | /* |
131 | * Device initialization handlers. | 119 | * Device initialization handlers. |
132 | */ | 120 | */ |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c index 7b52039b01a6..8e86611791f0 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.c +++ b/drivers/net/wireless/rt2x00/rt2x00queue.c | |||
@@ -25,34 +25,30 @@ | |||
25 | 25 | ||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/dma-mapping.h> | ||
28 | 29 | ||
29 | #include "rt2x00.h" | 30 | #include "rt2x00.h" |
30 | #include "rt2x00lib.h" | 31 | #include "rt2x00lib.h" |
31 | 32 | ||
32 | struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | 33 | struct sk_buff *rt2x00queue_alloc_rxskb(struct rt2x00_dev *rt2x00dev, |
34 | struct queue_entry *entry) | ||
33 | { | 35 | { |
34 | struct sk_buff *skb; | ||
35 | unsigned int frame_size; | 36 | unsigned int frame_size; |
36 | unsigned int reserved_size; | 37 | unsigned int reserved_size; |
38 | struct sk_buff *skb; | ||
39 | struct skb_frame_desc *skbdesc; | ||
37 | 40 | ||
38 | /* | 41 | /* |
39 | * The frame size includes descriptor size, because the | 42 | * The frame size includes descriptor size, because the |
40 | * hardware directly receive the frame into the skbuffer. | 43 | * hardware directly receive the frame into the skbuffer. |
41 | */ | 44 | */ |
42 | frame_size = queue->data_size + queue->desc_size; | 45 | frame_size = entry->queue->data_size + entry->queue->desc_size; |
43 | 46 | ||
44 | /* | 47 | /* |
45 | * For the allocation we should keep a few things in mind: | 48 | * Reserve a few bytes extra headroom to allow drivers some moving |
46 | * 1) 4byte alignment of 802.11 payload | 49 | * space (e.g. for alignment), while keeping the skb aligned. |
47 | * | ||
48 | * For (1) we need at most 4 bytes to guarentee the correct | ||
49 | * alignment. We are going to optimize the fact that the chance | ||
50 | * that the 802.11 header_size % 4 == 2 is much bigger then | ||
51 | * anything else. However since we need to move the frame up | ||
52 | * to 3 bytes to the front, which means we need to preallocate | ||
53 | * 6 bytes. | ||
54 | */ | 50 | */ |
55 | reserved_size = 6; | 51 | reserved_size = 8; |
56 | 52 | ||
57 | /* | 53 | /* |
58 | * Allocate skbuffer. | 54 | * Allocate skbuffer. |
@@ -64,9 +60,56 @@ struct sk_buff *rt2x00queue_alloc_rxskb(struct data_queue *queue) | |||
64 | skb_reserve(skb, reserved_size); | 60 | skb_reserve(skb, reserved_size); |
65 | skb_put(skb, frame_size); | 61 | skb_put(skb, frame_size); |
66 | 62 | ||
63 | /* | ||
64 | * Populate skbdesc. | ||
65 | */ | ||
66 | skbdesc = get_skb_frame_desc(skb); | ||
67 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
68 | skbdesc->entry = entry; | ||
69 | |||
70 | if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags)) { | ||
71 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, | ||
72 | skb->data, | ||
73 | skb->len, | ||
74 | DMA_FROM_DEVICE); | ||
75 | skbdesc->flags |= SKBDESC_DMA_MAPPED_RX; | ||
76 | } | ||
77 | |||
67 | return skb; | 78 | return skb; |
68 | } | 79 | } |
69 | EXPORT_SYMBOL_GPL(rt2x00queue_alloc_rxskb); | 80 | |
81 | void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
82 | { | ||
83 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
84 | |||
85 | skbdesc->skb_dma = dma_map_single(rt2x00dev->dev, skb->data, skb->len, | ||
86 | DMA_TO_DEVICE); | ||
87 | skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; | ||
88 | } | ||
89 | EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); | ||
90 | |||
91 | void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
92 | { | ||
93 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | ||
94 | |||
95 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_RX) { | ||
96 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
97 | DMA_FROM_DEVICE); | ||
98 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_RX; | ||
99 | } | ||
100 | |||
101 | if (skbdesc->flags & SKBDESC_DMA_MAPPED_TX) { | ||
102 | dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, skb->len, | ||
103 | DMA_TO_DEVICE); | ||
104 | skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; | ||
105 | } | ||
106 | } | ||
107 | |||
108 | void rt2x00queue_free_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb) | ||
109 | { | ||
110 | rt2x00queue_unmap_skb(rt2x00dev, skb); | ||
111 | dev_kfree_skb_any(skb); | ||
112 | } | ||
70 | 113 | ||
71 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | 114 | void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, |
72 | struct txentry_desc *txdesc) | 115 | struct txentry_desc *txdesc) |
@@ -80,7 +123,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
80 | unsigned int data_length; | 123 | unsigned int data_length; |
81 | unsigned int duration; | 124 | unsigned int duration; |
82 | unsigned int residual; | 125 | unsigned int residual; |
83 | u16 frame_control; | ||
84 | 126 | ||
85 | memset(txdesc, 0, sizeof(*txdesc)); | 127 | memset(txdesc, 0, sizeof(*txdesc)); |
86 | 128 | ||
@@ -96,11 +138,6 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
96 | data_length = entry->skb->len + 4; | 138 | data_length = entry->skb->len + 4; |
97 | 139 | ||
98 | /* | 140 | /* |
99 | * Read required fields from ieee80211 header. | ||
100 | */ | ||
101 | frame_control = le16_to_cpu(hdr->frame_control); | ||
102 | |||
103 | /* | ||
104 | * Check whether this frame is to be acked. | 141 | * Check whether this frame is to be acked. |
105 | */ | 142 | */ |
106 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) | 143 | if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK)) |
@@ -109,9 +146,10 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
109 | /* | 146 | /* |
110 | * Check if this is a RTS/CTS frame | 147 | * Check if this is a RTS/CTS frame |
111 | */ | 148 | */ |
112 | if (is_rts_frame(frame_control) || is_cts_frame(frame_control)) { | 149 | if (ieee80211_is_rts(hdr->frame_control) || |
150 | ieee80211_is_cts(hdr->frame_control)) { | ||
113 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); | 151 | __set_bit(ENTRY_TXD_BURST, &txdesc->flags); |
114 | if (is_rts_frame(frame_control)) | 152 | if (ieee80211_is_rts(hdr->frame_control)) |
115 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags); | 153 | __set_bit(ENTRY_TXD_RTS_FRAME, &txdesc->flags); |
116 | else | 154 | else |
117 | __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); | 155 | __set_bit(ENTRY_TXD_CTS_FRAME, &txdesc->flags); |
@@ -139,7 +177,8 @@ void rt2x00queue_create_tx_descriptor(struct queue_entry *entry, | |||
139 | * Beacons and probe responses require the tsf timestamp | 177 | * Beacons and probe responses require the tsf timestamp |
140 | * to be inserted into the frame. | 178 | * to be inserted into the frame. |
141 | */ | 179 | */ |
142 | if (txdesc->queue == QID_BEACON || is_probe_resp(frame_control)) | 180 | if (ieee80211_is_beacon(hdr->frame_control) || |
181 | ieee80211_is_probe_resp(hdr->frame_control)) | ||
143 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); | 182 | __set_bit(ENTRY_TXD_REQ_TIMESTAMP, &txdesc->flags); |
144 | 183 | ||
145 | /* | 184 | /* |
@@ -236,6 +275,7 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
236 | { | 275 | { |
237 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); | 276 | struct queue_entry *entry = rt2x00queue_get_entry(queue, Q_INDEX); |
238 | struct txentry_desc txdesc; | 277 | struct txentry_desc txdesc; |
278 | struct skb_frame_desc *skbdesc; | ||
239 | 279 | ||
240 | if (unlikely(rt2x00queue_full(queue))) | 280 | if (unlikely(rt2x00queue_full(queue))) |
241 | return -EINVAL; | 281 | return -EINVAL; |
@@ -256,11 +296,21 @@ int rt2x00queue_write_tx_frame(struct data_queue *queue, struct sk_buff *skb) | |||
256 | entry->skb = skb; | 296 | entry->skb = skb; |
257 | rt2x00queue_create_tx_descriptor(entry, &txdesc); | 297 | rt2x00queue_create_tx_descriptor(entry, &txdesc); |
258 | 298 | ||
299 | /* | ||
300 | * skb->cb array is now ours and we are free to use it. | ||
301 | */ | ||
302 | skbdesc = get_skb_frame_desc(entry->skb); | ||
303 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
304 | skbdesc->entry = entry; | ||
305 | |||
259 | if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { | 306 | if (unlikely(queue->rt2x00dev->ops->lib->write_tx_data(entry))) { |
260 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | 307 | __clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
261 | return -EIO; | 308 | return -EIO; |
262 | } | 309 | } |
263 | 310 | ||
311 | if (test_bit(DRIVER_REQUIRE_DMA, &queue->rt2x00dev->flags)) | ||
312 | rt2x00queue_map_txskb(queue->rt2x00dev, skb); | ||
313 | |||
264 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); | 314 | __set_bit(ENTRY_DATA_PENDING, &entry->flags); |
265 | 315 | ||
266 | rt2x00queue_index_inc(queue, Q_INDEX); | 316 | rt2x00queue_index_inc(queue, Q_INDEX); |
@@ -336,7 +386,6 @@ void rt2x00queue_index_inc(struct data_queue *queue, enum queue_index index) | |||
336 | 386 | ||
337 | spin_unlock_irqrestore(&queue->lock, irqflags); | 387 | spin_unlock_irqrestore(&queue->lock, irqflags); |
338 | } | 388 | } |
339 | EXPORT_SYMBOL_GPL(rt2x00queue_index_inc); | ||
340 | 389 | ||
341 | static void rt2x00queue_reset(struct data_queue *queue) | 390 | static void rt2x00queue_reset(struct data_queue *queue) |
342 | { | 391 | { |
@@ -426,12 +475,41 @@ static int rt2x00queue_alloc_entries(struct data_queue *queue, | |||
426 | return 0; | 475 | return 0; |
427 | } | 476 | } |
428 | 477 | ||
478 | static void rt2x00queue_free_skbs(struct rt2x00_dev *rt2x00dev, | ||
479 | struct data_queue *queue) | ||
480 | { | ||
481 | unsigned int i; | ||
482 | |||
483 | if (!queue->entries) | ||
484 | return; | ||
485 | |||
486 | for (i = 0; i < queue->limit; i++) { | ||
487 | if (queue->entries[i].skb) | ||
488 | rt2x00queue_free_skb(rt2x00dev, queue->entries[i].skb); | ||
489 | } | ||
490 | } | ||
491 | |||
492 | static int rt2x00queue_alloc_rxskbs(struct rt2x00_dev *rt2x00dev, | ||
493 | struct data_queue *queue) | ||
494 | { | ||
495 | unsigned int i; | ||
496 | struct sk_buff *skb; | ||
497 | |||
498 | for (i = 0; i < queue->limit; i++) { | ||
499 | skb = rt2x00queue_alloc_rxskb(rt2x00dev, &queue->entries[i]); | ||
500 | if (!skb) | ||
501 | return -ENOMEM; | ||
502 | queue->entries[i].skb = skb; | ||
503 | } | ||
504 | |||
505 | return 0; | ||
506 | } | ||
507 | |||
429 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | 508 | int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) |
430 | { | 509 | { |
431 | struct data_queue *queue; | 510 | struct data_queue *queue; |
432 | int status; | 511 | int status; |
433 | 512 | ||
434 | |||
435 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); | 513 | status = rt2x00queue_alloc_entries(rt2x00dev->rx, rt2x00dev->ops->rx); |
436 | if (status) | 514 | if (status) |
437 | goto exit; | 515 | goto exit; |
@@ -446,11 +524,14 @@ int rt2x00queue_initialize(struct rt2x00_dev *rt2x00dev) | |||
446 | if (status) | 524 | if (status) |
447 | goto exit; | 525 | goto exit; |
448 | 526 | ||
449 | if (!test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) | 527 | if (test_bit(DRIVER_REQUIRE_ATIM_QUEUE, &rt2x00dev->flags)) { |
450 | return 0; | 528 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], |
529 | rt2x00dev->ops->atim); | ||
530 | if (status) | ||
531 | goto exit; | ||
532 | } | ||
451 | 533 | ||
452 | status = rt2x00queue_alloc_entries(&rt2x00dev->bcn[1], | 534 | status = rt2x00queue_alloc_rxskbs(rt2x00dev, rt2x00dev->rx); |
453 | rt2x00dev->ops->atim); | ||
454 | if (status) | 535 | if (status) |
455 | goto exit; | 536 | goto exit; |
456 | 537 | ||
@@ -468,6 +549,8 @@ void rt2x00queue_uninitialize(struct rt2x00_dev *rt2x00dev) | |||
468 | { | 549 | { |
469 | struct data_queue *queue; | 550 | struct data_queue *queue; |
470 | 551 | ||
552 | rt2x00queue_free_skbs(rt2x00dev, rt2x00dev->rx); | ||
553 | |||
471 | queue_for_each(rt2x00dev, queue) { | 554 | queue_for_each(rt2x00dev, queue) { |
472 | kfree(queue->entries); | 555 | kfree(queue->entries); |
473 | queue->entries = NULL; | 556 | queue->entries = NULL; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h index fcf52520b016..5dd9cca3c62c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00queue.h +++ b/drivers/net/wireless/rt2x00/rt2x00queue.h | |||
@@ -42,15 +42,18 @@ | |||
42 | /** | 42 | /** |
43 | * DOC: Number of entries per queue | 43 | * DOC: Number of entries per queue |
44 | * | 44 | * |
45 | * After research it was concluded that 12 entries in a RX and TX | 45 | * Under normal load without fragmentation 12 entries are sufficient |
46 | * queue would be sufficient. Although this is almost one third of | 46 | * without the queue being filled up to the maximum. When using fragmentation |
47 | * the amount the legacy driver allocated, the queues aren't getting | 47 | * and the queue threshold code we need to add some additional margins to |
48 | * filled to the maximum even when working with the maximum rate. | 48 | * make sure the queue will never (or only under extreme load) fill up |
49 | * completely. | ||
50 | * Since we don't use preallocated DMA having a large number of queue entries | ||
51 | * will have only minimal impact on the memory requirements for the queue. | ||
49 | */ | 52 | */ |
50 | #define RX_ENTRIES 12 | 53 | #define RX_ENTRIES 24 |
51 | #define TX_ENTRIES 12 | 54 | #define TX_ENTRIES 24 |
52 | #define BEACON_ENTRIES 1 | 55 | #define BEACON_ENTRIES 1 |
53 | #define ATIM_ENTRIES 1 | 56 | #define ATIM_ENTRIES 8 |
54 | 57 | ||
55 | /** | 58 | /** |
56 | * enum data_queue_qid: Queue identification | 59 | * enum data_queue_qid: Queue identification |
@@ -82,10 +85,13 @@ enum data_queue_qid { | |||
82 | /** | 85 | /** |
83 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc | 86 | * enum skb_frame_desc_flags: Flags for &struct skb_frame_desc |
84 | * | 87 | * |
88 | * @SKBDESC_DMA_MAPPED_RX: &skb_dma field has been mapped for RX | ||
89 | * @SKBDESC_DMA_MAPPED_TX: &skb_dma field has been mapped for TX | ||
85 | */ | 90 | */ |
86 | //enum skb_frame_desc_flags { | 91 | enum skb_frame_desc_flags { |
87 | // TEMPORARILY EMPTY | 92 | SKBDESC_DMA_MAPPED_RX = (1 << 0), |
88 | //}; | 93 | SKBDESC_DMA_MAPPED_TX = (1 << 1), |
94 | }; | ||
89 | 95 | ||
90 | /** | 96 | /** |
91 | * struct skb_frame_desc: Descriptor information for the skb buffer | 97 | * struct skb_frame_desc: Descriptor information for the skb buffer |
@@ -94,19 +100,20 @@ enum data_queue_qid { | |||
94 | * this structure should not exceed the size of that array (40 bytes). | 100 | * this structure should not exceed the size of that array (40 bytes). |
95 | * | 101 | * |
96 | * @flags: Frame flags, see &enum skb_frame_desc_flags. | 102 | * @flags: Frame flags, see &enum skb_frame_desc_flags. |
97 | * @data: Pointer to data part of frame (Start of ieee80211 header). | 103 | * @desc_len: Length of the frame descriptor. |
98 | * @desc: Pointer to descriptor part of the frame. | 104 | * @desc: Pointer to descriptor part of the frame. |
99 | * Note that this pointer could point to something outside | 105 | * Note that this pointer could point to something outside |
100 | * of the scope of the skb->data pointer. | 106 | * of the scope of the skb->data pointer. |
101 | * @data_len: Length of the frame data. | 107 | * @skb_dma: (PCI-only) the DMA address associated with the sk buffer. |
102 | * @desc_len: Length of the frame descriptor. | ||
103 | * @entry: The entry to which this sk buffer belongs. | 108 | * @entry: The entry to which this sk buffer belongs. |
104 | */ | 109 | */ |
105 | struct skb_frame_desc { | 110 | struct skb_frame_desc { |
106 | unsigned int flags; | 111 | unsigned int flags; |
107 | 112 | ||
108 | void *desc; | ||
109 | unsigned int desc_len; | 113 | unsigned int desc_len; |
114 | void *desc; | ||
115 | |||
116 | dma_addr_t skb_dma; | ||
110 | 117 | ||
111 | struct queue_entry *entry; | 118 | struct queue_entry *entry; |
112 | }; | 119 | }; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00rfkill.c b/drivers/net/wireless/rt2x00/rt2x00rfkill.c index fcef9885ab5e..207281cfa8b7 100644 --- a/drivers/net/wireless/rt2x00/rt2x00rfkill.c +++ b/drivers/net/wireless/rt2x00/rt2x00rfkill.c | |||
@@ -45,14 +45,17 @@ static int rt2x00rfkill_toggle_radio(void *data, enum rfkill_state state) | |||
45 | if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) | 45 | if (!test_bit(DEVICE_STARTED, &rt2x00dev->flags)) |
46 | return 0; | 46 | return 0; |
47 | 47 | ||
48 | if (state == RFKILL_STATE_ON) { | 48 | if (state == RFKILL_STATE_UNBLOCKED) { |
49 | INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); | 49 | INFO(rt2x00dev, "Hardware button pressed, enabling radio.\n"); |
50 | __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); | 50 | __clear_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); |
51 | retval = rt2x00lib_enable_radio(rt2x00dev); | 51 | retval = rt2x00lib_enable_radio(rt2x00dev); |
52 | } else if (state == RFKILL_STATE_OFF) { | 52 | } else if (state == RFKILL_STATE_SOFT_BLOCKED) { |
53 | INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); | 53 | INFO(rt2x00dev, "Hardware button pressed, disabling radio.\n"); |
54 | __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); | 54 | __set_bit(DEVICE_DISABLED_RADIO_HW, &rt2x00dev->flags); |
55 | rt2x00lib_disable_radio(rt2x00dev); | 55 | rt2x00lib_disable_radio(rt2x00dev); |
56 | } else { | ||
57 | WARNING(rt2x00dev, "Received unexpected rfkill state %d.\n", | ||
58 | state); | ||
56 | } | 59 | } |
57 | 60 | ||
58 | return retval; | 61 | return retval; |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.c b/drivers/net/wireless/rt2x00/rt2x00usb.c index 3080969ae5b3..83862e7f7aec 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.c +++ b/drivers/net/wireless/rt2x00/rt2x00usb.c | |||
@@ -40,7 +40,7 @@ int rt2x00usb_vendor_request(struct rt2x00_dev *rt2x00dev, | |||
40 | void *buffer, const u16 buffer_length, | 40 | void *buffer, const u16 buffer_length, |
41 | const int timeout) | 41 | const int timeout) |
42 | { | 42 | { |
43 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 43 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
44 | int status; | 44 | int status; |
45 | unsigned int i; | 45 | unsigned int i; |
46 | unsigned int pipe = | 46 | unsigned int pipe = |
@@ -130,10 +130,9 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
130 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 130 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 131 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
132 | struct txdone_entry_desc txdesc; | 132 | struct txdone_entry_desc txdesc; |
133 | enum data_queue_qid qid = skb_get_queue_mapping(entry->skb); | ||
134 | 133 | ||
135 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 134 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
136 | !__test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 135 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
137 | return; | 136 | return; |
138 | 137 | ||
139 | /* | 138 | /* |
@@ -157,26 +156,12 @@ static void rt2x00usb_interrupt_txdone(struct urb *urb) | |||
157 | txdesc.retry = 0; | 156 | txdesc.retry = 0; |
158 | 157 | ||
159 | rt2x00lib_txdone(entry, &txdesc); | 158 | rt2x00lib_txdone(entry, &txdesc); |
160 | |||
161 | /* | ||
162 | * Make this entry available for reuse. | ||
163 | */ | ||
164 | entry->flags = 0; | ||
165 | rt2x00queue_index_inc(entry->queue, Q_INDEX_DONE); | ||
166 | |||
167 | /* | ||
168 | * If the data queue was below the threshold before the txdone | ||
169 | * handler we must make sure the packet queue in the mac80211 stack | ||
170 | * is reenabled when the txdone handler has finished. | ||
171 | */ | ||
172 | if (!rt2x00queue_threshold(entry->queue)) | ||
173 | ieee80211_wake_queue(rt2x00dev->hw, qid); | ||
174 | } | 159 | } |
175 | 160 | ||
176 | int rt2x00usb_write_tx_data(struct queue_entry *entry) | 161 | int rt2x00usb_write_tx_data(struct queue_entry *entry) |
177 | { | 162 | { |
178 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 163 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
179 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 164 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
180 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 165 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
181 | struct skb_frame_desc *skbdesc; | 166 | struct skb_frame_desc *skbdesc; |
182 | u32 length; | 167 | u32 length; |
@@ -191,10 +176,8 @@ int rt2x00usb_write_tx_data(struct queue_entry *entry) | |||
191 | * Fill in skb descriptor | 176 | * Fill in skb descriptor |
192 | */ | 177 | */ |
193 | skbdesc = get_skb_frame_desc(entry->skb); | 178 | skbdesc = get_skb_frame_desc(entry->skb); |
194 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
195 | skbdesc->desc = entry->skb->data; | 179 | skbdesc->desc = entry->skb->data; |
196 | skbdesc->desc_len = entry->queue->desc_size; | 180 | skbdesc->desc_len = entry->queue->desc_size; |
197 | skbdesc->entry = entry; | ||
198 | 181 | ||
199 | /* | 182 | /* |
200 | * USB devices cannot blindly pass the skb->len as the | 183 | * USB devices cannot blindly pass the skb->len as the |
@@ -264,13 +247,11 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
264 | { | 247 | { |
265 | struct queue_entry *entry = (struct queue_entry *)urb->context; | 248 | struct queue_entry *entry = (struct queue_entry *)urb->context; |
266 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; | 249 | struct rt2x00_dev *rt2x00dev = entry->queue->rt2x00dev; |
267 | struct sk_buff *skb; | 250 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); |
268 | struct skb_frame_desc *skbdesc; | ||
269 | struct rxdone_entry_desc rxdesc; | ||
270 | u8 rxd[32]; | 251 | u8 rxd[32]; |
271 | 252 | ||
272 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || | 253 | if (!test_bit(DEVICE_ENABLED_RADIO, &rt2x00dev->flags) || |
273 | !test_and_clear_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) | 254 | !test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags)) |
274 | return; | 255 | return; |
275 | 256 | ||
276 | /* | 257 | /* |
@@ -278,50 +259,22 @@ static void rt2x00usb_interrupt_rxdone(struct urb *urb) | |||
278 | * to be actually valid, or if the urb is signaling | 259 | * to be actually valid, or if the urb is signaling |
279 | * a problem. | 260 | * a problem. |
280 | */ | 261 | */ |
281 | if (urb->actual_length < entry->queue->desc_size || urb->status) | 262 | if (urb->actual_length < entry->queue->desc_size || urb->status) { |
282 | goto skip_entry; | 263 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); |
264 | usb_submit_urb(urb, GFP_ATOMIC); | ||
265 | return; | ||
266 | } | ||
283 | 267 | ||
284 | /* | 268 | /* |
285 | * Fill in skb descriptor | 269 | * Fill in desc fields of the skb descriptor |
286 | */ | 270 | */ |
287 | skbdesc = get_skb_frame_desc(entry->skb); | ||
288 | memset(skbdesc, 0, sizeof(*skbdesc)); | ||
289 | skbdesc->entry = entry; | ||
290 | skbdesc->desc = rxd; | 271 | skbdesc->desc = rxd; |
291 | skbdesc->desc_len = entry->queue->desc_size; | 272 | skbdesc->desc_len = entry->queue->desc_size; |
292 | 273 | ||
293 | memset(&rxdesc, 0, sizeof(rxdesc)); | ||
294 | rt2x00dev->ops->lib->fill_rxdone(entry, &rxdesc); | ||
295 | |||
296 | /* | ||
297 | * Allocate a new sk buffer to replace the current one. | ||
298 | * If allocation fails, we should drop the current frame | ||
299 | * so we can recycle the existing sk buffer for the new frame. | ||
300 | */ | ||
301 | skb = rt2x00queue_alloc_rxskb(entry->queue); | ||
302 | if (!skb) | ||
303 | goto skip_entry; | ||
304 | |||
305 | /* | 274 | /* |
306 | * Send the frame to rt2x00lib for further processing. | 275 | * Send the frame to rt2x00lib for further processing. |
307 | */ | 276 | */ |
308 | rt2x00lib_rxdone(entry, &rxdesc); | 277 | rt2x00lib_rxdone(rt2x00dev, entry); |
309 | |||
310 | /* | ||
311 | * Replace current entry's skb with the newly allocated one, | ||
312 | * and reinitialize the urb. | ||
313 | */ | ||
314 | entry->skb = skb; | ||
315 | urb->transfer_buffer = entry->skb->data; | ||
316 | urb->transfer_buffer_length = entry->skb->len; | ||
317 | |||
318 | skip_entry: | ||
319 | if (test_bit(DEVICE_ENABLED_RADIO, &entry->queue->rt2x00dev->flags)) { | ||
320 | __set_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags); | ||
321 | usb_submit_urb(urb, GFP_ATOMIC); | ||
322 | } | ||
323 | |||
324 | rt2x00queue_index_inc(entry->queue, Q_INDEX); | ||
325 | } | 278 | } |
326 | 279 | ||
327 | /* | 280 | /* |
@@ -331,6 +284,7 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
331 | { | 284 | { |
332 | struct queue_entry_priv_usb *entry_priv; | 285 | struct queue_entry_priv_usb *entry_priv; |
333 | struct queue_entry_priv_usb_bcn *bcn_priv; | 286 | struct queue_entry_priv_usb_bcn *bcn_priv; |
287 | struct data_queue *queue; | ||
334 | unsigned int i; | 288 | unsigned int i; |
335 | 289 | ||
336 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, | 290 | rt2x00usb_vendor_request_sw(rt2x00dev, USB_RX_CONTROL, 0, 0, |
@@ -339,9 +293,11 @@ void rt2x00usb_disable_radio(struct rt2x00_dev *rt2x00dev) | |||
339 | /* | 293 | /* |
340 | * Cancel all queues. | 294 | * Cancel all queues. |
341 | */ | 295 | */ |
342 | for (i = 0; i < rt2x00dev->rx->limit; i++) { | 296 | queue_for_each(rt2x00dev, queue) { |
343 | entry_priv = rt2x00dev->rx->entries[i].priv_data; | 297 | for (i = 0; i < queue->limit; i++) { |
344 | usb_kill_urb(entry_priv->urb); | 298 | entry_priv = queue->entries[i].priv_data; |
299 | usb_kill_urb(entry_priv->urb); | ||
300 | } | ||
345 | } | 301 | } |
346 | 302 | ||
347 | /* | 303 | /* |
@@ -364,7 +320,7 @@ EXPORT_SYMBOL_GPL(rt2x00usb_disable_radio); | |||
364 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, | 320 | void rt2x00usb_init_rxentry(struct rt2x00_dev *rt2x00dev, |
365 | struct queue_entry *entry) | 321 | struct queue_entry *entry) |
366 | { | 322 | { |
367 | struct usb_device *usb_dev = rt2x00dev_usb_dev(rt2x00dev); | 323 | struct usb_device *usb_dev = to_usb_device_intf(rt2x00dev->dev); |
368 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; | 324 | struct queue_entry_priv_usb *entry_priv = entry->priv_data; |
369 | 325 | ||
370 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, | 326 | usb_fill_bulk_urb(entry_priv->urb, usb_dev, |
@@ -431,8 +387,6 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | |||
431 | entry_priv = queue->entries[i].priv_data; | 387 | entry_priv = queue->entries[i].priv_data; |
432 | usb_kill_urb(entry_priv->urb); | 388 | usb_kill_urb(entry_priv->urb); |
433 | usb_free_urb(entry_priv->urb); | 389 | usb_free_urb(entry_priv->urb); |
434 | if (queue->entries[i].skb) | ||
435 | kfree_skb(queue->entries[i].skb); | ||
436 | } | 390 | } |
437 | 391 | ||
438 | /* | 392 | /* |
@@ -454,10 +408,7 @@ static void rt2x00usb_free_urb(struct rt2x00_dev *rt2x00dev, | |||
454 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | 408 | int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) |
455 | { | 409 | { |
456 | struct data_queue *queue; | 410 | struct data_queue *queue; |
457 | struct sk_buff *skb; | 411 | int status; |
458 | unsigned int entry_size; | ||
459 | unsigned int i; | ||
460 | int uninitialized_var(status); | ||
461 | 412 | ||
462 | /* | 413 | /* |
463 | * Allocate DMA | 414 | * Allocate DMA |
@@ -468,18 +419,6 @@ int rt2x00usb_initialize(struct rt2x00_dev *rt2x00dev) | |||
468 | goto exit; | 419 | goto exit; |
469 | } | 420 | } |
470 | 421 | ||
471 | /* | ||
472 | * For the RX queue, skb's should be allocated. | ||
473 | */ | ||
474 | entry_size = rt2x00dev->rx->data_size + rt2x00dev->rx->desc_size; | ||
475 | for (i = 0; i < rt2x00dev->rx->limit; i++) { | ||
476 | skb = rt2x00queue_alloc_rxskb(rt2x00dev->rx); | ||
477 | if (!skb) | ||
478 | goto exit; | ||
479 | |||
480 | rt2x00dev->rx->entries[i].skb = skb; | ||
481 | } | ||
482 | |||
483 | return 0; | 422 | return 0; |
484 | 423 | ||
485 | exit: | 424 | exit: |
@@ -558,7 +497,7 @@ int rt2x00usb_probe(struct usb_interface *usb_intf, | |||
558 | usb_set_intfdata(usb_intf, hw); | 497 | usb_set_intfdata(usb_intf, hw); |
559 | 498 | ||
560 | rt2x00dev = hw->priv; | 499 | rt2x00dev = hw->priv; |
561 | rt2x00dev->dev = usb_intf; | 500 | rt2x00dev->dev = &usb_intf->dev; |
562 | rt2x00dev->ops = ops; | 501 | rt2x00dev->ops = ops; |
563 | rt2x00dev->hw = hw; | 502 | rt2x00dev->hw = hw; |
564 | mutex_init(&rt2x00dev->usb_cache_mutex); | 503 | mutex_init(&rt2x00dev->usb_cache_mutex); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h index b1187c812e7f..aad794adf52c 100644 --- a/drivers/net/wireless/rt2x00/rt2x00usb.h +++ b/drivers/net/wireless/rt2x00/rt2x00usb.h | |||
@@ -26,6 +26,12 @@ | |||
26 | #ifndef RT2X00USB_H | 26 | #ifndef RT2X00USB_H |
27 | #define RT2X00USB_H | 27 | #define RT2X00USB_H |
28 | 28 | ||
29 | #define to_usb_device_intf(d) \ | ||
30 | ({ \ | ||
31 | struct usb_interface *intf = to_usb_interface(d); \ | ||
32 | interface_to_usbdev(intf); \ | ||
33 | }) | ||
34 | |||
29 | /* | 35 | /* |
30 | * This variable should be used with the | 36 | * This variable should be used with the |
31 | * usb_driver structure initialization. | 37 | * usb_driver structure initialization. |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index 5b7267ece1b9..bbf1048f6400 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -1030,11 +1030,12 @@ static void rt61pci_init_rxentry(struct rt2x00_dev *rt2x00dev, | |||
1030 | struct queue_entry *entry) | 1030 | struct queue_entry *entry) |
1031 | { | 1031 | { |
1032 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; | 1032 | struct queue_entry_priv_pci *entry_priv = entry->priv_data; |
1033 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(entry->skb); | ||
1033 | u32 word; | 1034 | u32 word; |
1034 | 1035 | ||
1035 | rt2x00_desc_read(entry_priv->desc, 5, &word); | 1036 | rt2x00_desc_read(entry_priv->desc, 5, &word); |
1036 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, | 1037 | rt2x00_set_field32(&word, RXD_W5_BUFFER_PHYSICAL_ADDRESS, |
1037 | entry_priv->data_dma); | 1038 | skbdesc->skb_dma); |
1038 | rt2x00_desc_write(entry_priv->desc, 5, word); | 1039 | rt2x00_desc_write(entry_priv->desc, 5, word); |
1039 | 1040 | ||
1040 | rt2x00_desc_read(entry_priv->desc, 0, &word); | 1041 | rt2x00_desc_read(entry_priv->desc, 0, &word); |
@@ -1522,7 +1523,6 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1522 | struct txentry_desc *txdesc) | 1523 | struct txentry_desc *txdesc) |
1523 | { | 1524 | { |
1524 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); | 1525 | struct skb_frame_desc *skbdesc = get_skb_frame_desc(skb); |
1525 | struct queue_entry_priv_pci *entry_priv = skbdesc->entry->priv_data; | ||
1526 | __le32 *txd = skbdesc->desc; | 1526 | __le32 *txd = skbdesc->desc; |
1527 | u32 word; | 1527 | u32 word; |
1528 | 1528 | ||
@@ -1557,7 +1557,7 @@ static void rt61pci_write_tx_desc(struct rt2x00_dev *rt2x00dev, | |||
1557 | 1557 | ||
1558 | rt2x00_desc_read(txd, 6, &word); | 1558 | rt2x00_desc_read(txd, 6, &word); |
1559 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, | 1559 | rt2x00_set_field32(&word, TXD_W6_BUFFER_PHYSICAL_ADDRESS, |
1560 | entry_priv->data_dma); | 1560 | skbdesc->skb_dma); |
1561 | rt2x00_desc_write(txd, 6, word); | 1561 | rt2x00_desc_write(txd, 6, word); |
1562 | 1562 | ||
1563 | if (skbdesc->desc_len > TXINFO_SIZE) { | 1563 | if (skbdesc->desc_len > TXINFO_SIZE) { |
@@ -1767,7 +1767,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1767 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); | 1767 | __set_bit(TXDONE_UNKNOWN, &txdesc.flags); |
1768 | txdesc.retry = 0; | 1768 | txdesc.retry = 0; |
1769 | 1769 | ||
1770 | rt2x00pci_txdone(rt2x00dev, entry_done, &txdesc); | 1770 | rt2x00lib_txdone(entry_done, &txdesc); |
1771 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); | 1771 | entry_done = rt2x00queue_get_entry(queue, Q_INDEX_DONE); |
1772 | } | 1772 | } |
1773 | 1773 | ||
@@ -1787,7 +1787,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
1787 | } | 1787 | } |
1788 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); | 1788 | txdesc.retry = rt2x00_get_field32(reg, STA_CSR4_RETRY_COUNT); |
1789 | 1789 | ||
1790 | rt2x00pci_txdone(rt2x00dev, entry, &txdesc); | 1790 | rt2x00lib_txdone(entry, &txdesc); |
1791 | } | 1791 | } |
1792 | } | 1792 | } |
1793 | 1793 | ||
@@ -1973,7 +1973,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev) | |||
1973 | * To determine the RT chip we have to read the | 1973 | * To determine the RT chip we have to read the |
1974 | * PCI header of the device. | 1974 | * PCI header of the device. |
1975 | */ | 1975 | */ |
1976 | pci_read_config_word(rt2x00dev_pci(rt2x00dev), | 1976 | pci_read_config_word(to_pci_dev(rt2x00dev->dev), |
1977 | PCI_CONFIG_HEADER_DEVICE, &device); | 1977 | PCI_CONFIG_HEADER_DEVICE, &device); |
1978 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); | 1978 | value = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE); |
1979 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); | 1979 | rt2x00pci_register_read(rt2x00dev, MAC_CSR0, ®); |
@@ -2239,7 +2239,7 @@ static void rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
2239 | IEEE80211_HW_SIGNAL_DBM; | 2239 | IEEE80211_HW_SIGNAL_DBM; |
2240 | rt2x00dev->hw->extra_tx_headroom = 0; | 2240 | rt2x00dev->hw->extra_tx_headroom = 0; |
2241 | 2241 | ||
2242 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_pci(rt2x00dev)->dev); | 2242 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
2243 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 2243 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
2244 | rt2x00_eeprom_addr(rt2x00dev, | 2244 | rt2x00_eeprom_addr(rt2x00dev, |
2245 | EEPROM_MAC_ADDR_0)); | 2245 | EEPROM_MAC_ADDR_0)); |
@@ -2302,9 +2302,10 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev) | |||
2302 | rt61pci_probe_hw_mode(rt2x00dev); | 2302 | rt61pci_probe_hw_mode(rt2x00dev); |
2303 | 2303 | ||
2304 | /* | 2304 | /* |
2305 | * This device requires firmware. | 2305 | * This device requires firmware and DMA mapped skbs. |
2306 | */ | 2306 | */ |
2307 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); | 2307 | __set_bit(DRIVER_REQUIRE_FIRMWARE, &rt2x00dev->flags); |
2308 | __set_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags); | ||
2308 | 2309 | ||
2309 | /* | 2310 | /* |
2310 | * Set the rssi offset. | 2311 | * Set the rssi offset. |
@@ -2402,6 +2403,12 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2402 | skb->data, skb->len); | 2403 | skb->data, skb->len); |
2403 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); | 2404 | rt61pci_kick_tx_queue(rt2x00dev, QID_BEACON); |
2404 | 2405 | ||
2406 | /* | ||
2407 | * Clean up beacon skb. | ||
2408 | */ | ||
2409 | dev_kfree_skb_any(skb); | ||
2410 | intf->beacon->skb = NULL; | ||
2411 | |||
2405 | return 0; | 2412 | return 0; |
2406 | } | 2413 | } |
2407 | 2414 | ||
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index 675ff7900eee..3ef318e098e7 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c | |||
@@ -1827,7 +1827,7 @@ static void rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev) | |||
1827 | IEEE80211_HW_SIGNAL_DBM; | 1827 | IEEE80211_HW_SIGNAL_DBM; |
1828 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; | 1828 | rt2x00dev->hw->extra_tx_headroom = TXD_DESC_SIZE; |
1829 | 1829 | ||
1830 | SET_IEEE80211_DEV(rt2x00dev->hw, &rt2x00dev_usb(rt2x00dev)->dev); | 1830 | SET_IEEE80211_DEV(rt2x00dev->hw, rt2x00dev->dev); |
1831 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, | 1831 | SET_IEEE80211_PERM_ADDR(rt2x00dev->hw, |
1832 | rt2x00_eeprom_addr(rt2x00dev, | 1832 | rt2x00_eeprom_addr(rt2x00dev, |
1833 | EEPROM_MAC_ADDR_0)); | 1833 | EEPROM_MAC_ADDR_0)); |
@@ -2007,6 +2007,12 @@ static int rt73usb_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2007 | REGISTER_TIMEOUT32(skb->len)); | 2007 | REGISTER_TIMEOUT32(skb->len)); |
2008 | rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); | 2008 | rt73usb_kick_tx_queue(rt2x00dev, QID_BEACON); |
2009 | 2009 | ||
2010 | /* | ||
2011 | * Clean up the beacon skb. | ||
2012 | */ | ||
2013 | dev_kfree_skb(skb); | ||
2014 | intf->beacon->skb = NULL; | ||
2015 | |||
2010 | return 0; | 2016 | return 0; |
2011 | } | 2017 | } |
2012 | 2018 | ||
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c deleted file mode 100644 index 883af891ebfb..000000000000 --- a/drivers/net/wireless/strip.c +++ /dev/null | |||
@@ -1,2804 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 1996 The Board of Trustees of The Leland Stanford | ||
3 | * Junior University. All Rights Reserved. | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this | ||
6 | * software and its documentation for any purpose and without | ||
7 | * fee is hereby granted, provided that the above copyright | ||
8 | * notice appear in all copies. Stanford University | ||
9 | * makes no representations about the suitability of this | ||
10 | * software for any purpose. It is provided "as is" without | ||
11 | * express or implied warranty. | ||
12 | * | ||
13 | * strip.c This module implements Starmode Radio IP (STRIP) | ||
14 | * for kernel-based devices like TTY. It interfaces between a | ||
15 | * raw TTY, and the kernel's INET protocol layers (via DDI). | ||
16 | * | ||
17 | * Version: @(#)strip.c 1.3 July 1997 | ||
18 | * | ||
19 | * Author: Stuart Cheshire <cheshire@cs.stanford.edu> | ||
20 | * | ||
21 | * Fixes: v0.9 12th Feb 1996 (SC) | ||
22 | * New byte stuffing (2+6 run-length encoding) | ||
23 | * New watchdog timer task | ||
24 | * New Protocol key (SIP0) | ||
25 | * | ||
26 | * v0.9.1 3rd March 1996 (SC) | ||
27 | * Changed to dynamic device allocation -- no more compile | ||
28 | * time (or boot time) limit on the number of STRIP devices. | ||
29 | * | ||
30 | * v0.9.2 13th March 1996 (SC) | ||
31 | * Uses arp cache lookups (but doesn't send arp packets yet) | ||
32 | * | ||
33 | * v0.9.3 17th April 1996 (SC) | ||
34 | * Fixed bug where STR_ERROR flag was getting set unneccessarily | ||
35 | * (causing otherwise good packets to be unneccessarily dropped) | ||
36 | * | ||
37 | * v0.9.4 27th April 1996 (SC) | ||
38 | * First attempt at using "&COMMAND" Starmode AT commands | ||
39 | * | ||
40 | * v0.9.5 29th May 1996 (SC) | ||
41 | * First attempt at sending (unicast) ARP packets | ||
42 | * | ||
43 | * v0.9.6 5th June 1996 (Elliot) | ||
44 | * Put "message level" tags in every "printk" statement | ||
45 | * | ||
46 | * v0.9.7 13th June 1996 (laik) | ||
47 | * Added support for the /proc fs | ||
48 | * | ||
49 | * v0.9.8 July 1996 (Mema) | ||
50 | * Added packet logging | ||
51 | * | ||
52 | * v1.0 November 1996 (SC) | ||
53 | * Fixed (severe) memory leaks in the /proc fs code | ||
54 | * Fixed race conditions in the logging code | ||
55 | * | ||
56 | * v1.1 January 1997 (SC) | ||
57 | * Deleted packet logging (use tcpdump instead) | ||
58 | * Added support for Metricom Firmware v204 features | ||
59 | * (like message checksums) | ||
60 | * | ||
61 | * v1.2 January 1997 (SC) | ||
62 | * Put portables list back in | ||
63 | * | ||
64 | * v1.3 July 1997 (SC) | ||
65 | * Made STRIP driver set the radio's baud rate automatically. | ||
66 | * It is no longer necessarily to manually set the radio's | ||
67 | * rate permanently to 115200 -- the driver handles setting | ||
68 | * the rate automatically. | ||
69 | */ | ||
70 | |||
71 | #ifdef MODULE | ||
72 | static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR"; | ||
73 | #else | ||
74 | static const char StripVersion[] = "1.3A-STUART.CHESHIRE"; | ||
75 | #endif | ||
76 | |||
77 | #define TICKLE_TIMERS 0 | ||
78 | #define EXT_COUNTERS 1 | ||
79 | |||
80 | |||
81 | /************************************************************************/ | ||
82 | /* Header files */ | ||
83 | |||
84 | #include <linux/kernel.h> | ||
85 | #include <linux/module.h> | ||
86 | #include <linux/init.h> | ||
87 | #include <linux/bitops.h> | ||
88 | #include <asm/system.h> | ||
89 | #include <asm/uaccess.h> | ||
90 | |||
91 | # include <linux/ctype.h> | ||
92 | #include <linux/string.h> | ||
93 | #include <linux/mm.h> | ||
94 | #include <linux/interrupt.h> | ||
95 | #include <linux/in.h> | ||
96 | #include <linux/tty.h> | ||
97 | #include <linux/errno.h> | ||
98 | #include <linux/netdevice.h> | ||
99 | #include <linux/inetdevice.h> | ||
100 | #include <linux/etherdevice.h> | ||
101 | #include <linux/skbuff.h> | ||
102 | #include <linux/if_arp.h> | ||
103 | #include <linux/if_strip.h> | ||
104 | #include <linux/proc_fs.h> | ||
105 | #include <linux/seq_file.h> | ||
106 | #include <linux/serial.h> | ||
107 | #include <linux/serialP.h> | ||
108 | #include <linux/rcupdate.h> | ||
109 | #include <net/arp.h> | ||
110 | #include <net/net_namespace.h> | ||
111 | |||
112 | #include <linux/ip.h> | ||
113 | #include <linux/tcp.h> | ||
114 | #include <linux/time.h> | ||
115 | #include <linux/jiffies.h> | ||
116 | |||
117 | /************************************************************************/ | ||
118 | /* Useful structures and definitions */ | ||
119 | |||
120 | /* | ||
121 | * A MetricomKey identifies the protocol being carried inside a Metricom | ||
122 | * Starmode packet. | ||
123 | */ | ||
124 | |||
125 | typedef union { | ||
126 | __u8 c[4]; | ||
127 | __u32 l; | ||
128 | } MetricomKey; | ||
129 | |||
130 | /* | ||
131 | * An IP address can be viewed as four bytes in memory (which is what it is) or as | ||
132 | * a single 32-bit long (which is convenient for assignment, equality testing etc.) | ||
133 | */ | ||
134 | |||
135 | typedef union { | ||
136 | __u8 b[4]; | ||
137 | __u32 l; | ||
138 | } IPaddr; | ||
139 | |||
140 | /* | ||
141 | * A MetricomAddressString is used to hold a printable representation of | ||
142 | * a Metricom address. | ||
143 | */ | ||
144 | |||
145 | typedef struct { | ||
146 | __u8 c[24]; | ||
147 | } MetricomAddressString; | ||
148 | |||
149 | /* Encapsulation can expand packet of size x to 65/64x + 1 | ||
150 | * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>" | ||
151 | * 1 1 1-18 1 4 ? 1 | ||
152 | * eg. <CR>*0000-1234*SIP0<encaps payload><CR> | ||
153 | * We allow 31 bytes for the stars, the key, the address and the <CR>s | ||
154 | */ | ||
155 | #define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L) | ||
156 | |||
157 | /* | ||
158 | * A STRIP_Header is never really sent over the radio, but making a dummy | ||
159 | * header for internal use within the kernel that looks like an Ethernet | ||
160 | * header makes certain other software happier. For example, tcpdump | ||
161 | * already understands Ethernet headers. | ||
162 | */ | ||
163 | |||
164 | typedef struct { | ||
165 | MetricomAddress dst_addr; /* Destination address, e.g. "0000-1234" */ | ||
166 | MetricomAddress src_addr; /* Source address, e.g. "0000-5678" */ | ||
167 | unsigned short protocol; /* The protocol type, using Ethernet codes */ | ||
168 | } STRIP_Header; | ||
169 | |||
170 | typedef struct { | ||
171 | char c[60]; | ||
172 | } MetricomNode; | ||
173 | |||
174 | #define NODE_TABLE_SIZE 32 | ||
175 | typedef struct { | ||
176 | struct timeval timestamp; | ||
177 | int num_nodes; | ||
178 | MetricomNode node[NODE_TABLE_SIZE]; | ||
179 | } MetricomNodeTable; | ||
180 | |||
181 | enum { FALSE = 0, TRUE = 1 }; | ||
182 | |||
183 | /* | ||
184 | * Holds the radio's firmware version. | ||
185 | */ | ||
186 | typedef struct { | ||
187 | char c[50]; | ||
188 | } FirmwareVersion; | ||
189 | |||
190 | /* | ||
191 | * Holds the radio's serial number. | ||
192 | */ | ||
193 | typedef struct { | ||
194 | char c[18]; | ||
195 | } SerialNumber; | ||
196 | |||
197 | /* | ||
198 | * Holds the radio's battery voltage. | ||
199 | */ | ||
200 | typedef struct { | ||
201 | char c[11]; | ||
202 | } BatteryVoltage; | ||
203 | |||
204 | typedef struct { | ||
205 | char c[8]; | ||
206 | } char8; | ||
207 | |||
208 | enum { | ||
209 | NoStructure = 0, /* Really old firmware */ | ||
210 | StructuredMessages = 1, /* Parsable AT response msgs */ | ||
211 | ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */ | ||
212 | }; | ||
213 | |||
214 | struct strip { | ||
215 | int magic; | ||
216 | /* | ||
217 | * These are pointers to the malloc()ed frame buffers. | ||
218 | */ | ||
219 | |||
220 | unsigned char *rx_buff; /* buffer for received IP packet */ | ||
221 | unsigned char *sx_buff; /* buffer for received serial data */ | ||
222 | int sx_count; /* received serial data counter */ | ||
223 | int sx_size; /* Serial buffer size */ | ||
224 | unsigned char *tx_buff; /* transmitter buffer */ | ||
225 | unsigned char *tx_head; /* pointer to next byte to XMIT */ | ||
226 | int tx_left; /* bytes left in XMIT queue */ | ||
227 | int tx_size; /* Serial buffer size */ | ||
228 | |||
229 | /* | ||
230 | * STRIP interface statistics. | ||
231 | */ | ||
232 | |||
233 | unsigned long rx_packets; /* inbound frames counter */ | ||
234 | unsigned long tx_packets; /* outbound frames counter */ | ||
235 | unsigned long rx_errors; /* Parity, etc. errors */ | ||
236 | unsigned long tx_errors; /* Planned stuff */ | ||
237 | unsigned long rx_dropped; /* No memory for skb */ | ||
238 | unsigned long tx_dropped; /* When MTU change */ | ||
239 | unsigned long rx_over_errors; /* Frame bigger then STRIP buf. */ | ||
240 | |||
241 | unsigned long pps_timer; /* Timer to determine pps */ | ||
242 | unsigned long rx_pps_count; /* Counter to determine pps */ | ||
243 | unsigned long tx_pps_count; /* Counter to determine pps */ | ||
244 | unsigned long sx_pps_count; /* Counter to determine pps */ | ||
245 | unsigned long rx_average_pps; /* rx packets per second * 8 */ | ||
246 | unsigned long tx_average_pps; /* tx packets per second * 8 */ | ||
247 | unsigned long sx_average_pps; /* sent packets per second * 8 */ | ||
248 | |||
249 | #ifdef EXT_COUNTERS | ||
250 | unsigned long rx_bytes; /* total received bytes */ | ||
251 | unsigned long tx_bytes; /* total received bytes */ | ||
252 | unsigned long rx_rbytes; /* bytes thru radio i/f */ | ||
253 | unsigned long tx_rbytes; /* bytes thru radio i/f */ | ||
254 | unsigned long rx_sbytes; /* tot bytes thru serial i/f */ | ||
255 | unsigned long tx_sbytes; /* tot bytes thru serial i/f */ | ||
256 | unsigned long rx_ebytes; /* tot stat/err bytes */ | ||
257 | unsigned long tx_ebytes; /* tot stat/err bytes */ | ||
258 | #endif | ||
259 | |||
260 | /* | ||
261 | * Internal variables. | ||
262 | */ | ||
263 | |||
264 | struct list_head list; /* Linked list of devices */ | ||
265 | |||
266 | int discard; /* Set if serial error */ | ||
267 | int working; /* Is radio working correctly? */ | ||
268 | int firmware_level; /* Message structuring level */ | ||
269 | int next_command; /* Next periodic command */ | ||
270 | unsigned int user_baud; /* The user-selected baud rate */ | ||
271 | int mtu; /* Our mtu (to spot changes!) */ | ||
272 | long watchdog_doprobe; /* Next time to test the radio */ | ||
273 | long watchdog_doreset; /* Time to do next reset */ | ||
274 | long gratuitous_arp; /* Time to send next ARP refresh */ | ||
275 | long arp_interval; /* Next ARP interval */ | ||
276 | struct timer_list idle_timer; /* For periodic wakeup calls */ | ||
277 | MetricomAddress true_dev_addr; /* True address of radio */ | ||
278 | int manual_dev_addr; /* Hack: See note below */ | ||
279 | |||
280 | FirmwareVersion firmware_version; /* The radio's firmware version */ | ||
281 | SerialNumber serial_number; /* The radio's serial number */ | ||
282 | BatteryVoltage battery_voltage; /* The radio's battery voltage */ | ||
283 | |||
284 | /* | ||
285 | * Other useful structures. | ||
286 | */ | ||
287 | |||
288 | struct tty_struct *tty; /* ptr to TTY structure */ | ||
289 | struct net_device *dev; /* Our device structure */ | ||
290 | |||
291 | /* | ||
292 | * Neighbour radio records | ||
293 | */ | ||
294 | |||
295 | MetricomNodeTable portables; | ||
296 | MetricomNodeTable poletops; | ||
297 | }; | ||
298 | |||
299 | /* | ||
300 | * Note: manual_dev_addr hack | ||
301 | * | ||
302 | * It is not possible to change the hardware address of a Metricom radio, | ||
303 | * or to send packets with a user-specified hardware source address, thus | ||
304 | * trying to manually set a hardware source address is a questionable | ||
305 | * thing to do. However, if the user *does* manually set the hardware | ||
306 | * source address of a STRIP interface, then the kernel will believe it, | ||
307 | * and use it in certain places. For example, the hardware address listed | ||
308 | * by ifconfig will be the manual address, not the true one. | ||
309 | * (Both addresses are listed in /proc/net/strip.) | ||
310 | * Also, ARP packets will be sent out giving the user-specified address as | ||
311 | * the source address, not the real address. This is dangerous, because | ||
312 | * it means you won't receive any replies -- the ARP replies will go to | ||
313 | * the specified address, which will be some other radio. The case where | ||
314 | * this is useful is when that other radio is also connected to the same | ||
315 | * machine. This allows you to connect a pair of radios to one machine, | ||
316 | * and to use one exclusively for inbound traffic, and the other | ||
317 | * exclusively for outbound traffic. Pretty neat, huh? | ||
318 | * | ||
319 | * Here's the full procedure to set this up: | ||
320 | * | ||
321 | * 1. "slattach" two interfaces, e.g. st0 for outgoing packets, | ||
322 | * and st1 for incoming packets | ||
323 | * | ||
324 | * 2. "ifconfig" st0 (outbound radio) to have the hardware address | ||
325 | * which is the real hardware address of st1 (inbound radio). | ||
326 | * Now when it sends out packets, it will masquerade as st1, and | ||
327 | * replies will be sent to that radio, which is exactly what we want. | ||
328 | * | ||
329 | * 3. Set the route table entry ("route add default ..." or | ||
330 | * "route add -net ...", as appropriate) to send packets via the st0 | ||
331 | * interface (outbound radio). Do not add any route which sends packets | ||
332 | * out via the st1 interface -- that radio is for inbound traffic only. | ||
333 | * | ||
334 | * 4. "ifconfig" st1 (inbound radio) to have hardware address zero. | ||
335 | * This tells the STRIP driver to "shut down" that interface and not | ||
336 | * send any packets through it. In particular, it stops sending the | ||
337 | * periodic gratuitous ARP packets that a STRIP interface normally sends. | ||
338 | * Also, when packets arrive on that interface, it will search the | ||
339 | * interface list to see if there is another interface who's manual | ||
340 | * hardware address matches its own real address (i.e. st0 in this | ||
341 | * example) and if so it will transfer ownership of the skbuff to | ||
342 | * that interface, so that it looks to the kernel as if the packet | ||
343 | * arrived on that interface. This is necessary because when the | ||
344 | * kernel sends an ARP packet on st0, it expects to get a reply on | ||
345 | * st0, and if it sees the reply come from st1 then it will ignore | ||
346 | * it (to be accurate, it puts the entry in the ARP table, but | ||
347 | * labelled in such a way that st0 can't use it). | ||
348 | * | ||
349 | * Thanks to Petros Maniatis for coming up with the idea of splitting | ||
350 | * inbound and outbound traffic between two interfaces, which turned | ||
351 | * out to be really easy to implement, even if it is a bit of a hack. | ||
352 | * | ||
353 | * Having set a manual address on an interface, you can restore it | ||
354 | * to automatic operation (where the address is automatically kept | ||
355 | * consistent with the real address of the radio) by setting a manual | ||
356 | * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF" | ||
357 | * This 'turns off' manual override mode for the device address. | ||
358 | * | ||
359 | * Note: The IEEE 802 headers reported in tcpdump will show the *real* | ||
360 | * radio addresses the packets were sent and received from, so that you | ||
361 | * can see what is really going on with packets, and which interfaces | ||
362 | * they are really going through. | ||
363 | */ | ||
364 | |||
365 | |||
366 | /************************************************************************/ | ||
367 | /* Constants */ | ||
368 | |||
369 | /* | ||
370 | * CommandString1 works on all radios | ||
371 | * Other CommandStrings are only used with firmware that provides structured responses. | ||
372 | * | ||
373 | * ats319=1 Enables Info message for node additions and deletions | ||
374 | * ats319=2 Enables Info message for a new best node | ||
375 | * ats319=4 Enables checksums | ||
376 | * ats319=8 Enables ACK messages | ||
377 | */ | ||
378 | |||
379 | static const int MaxCommandStringLength = 32; | ||
380 | static const int CompatibilityCommand = 1; | ||
381 | |||
382 | static const char CommandString0[] = "*&COMMAND*ATS319=7"; /* Turn on checksums & info messages */ | ||
383 | static const char CommandString1[] = "*&COMMAND*ATS305?"; /* Query radio name */ | ||
384 | static const char CommandString2[] = "*&COMMAND*ATS325?"; /* Query battery voltage */ | ||
385 | static const char CommandString3[] = "*&COMMAND*ATS300?"; /* Query version information */ | ||
386 | static const char CommandString4[] = "*&COMMAND*ATS311?"; /* Query poletop list */ | ||
387 | static const char CommandString5[] = "*&COMMAND*AT~LA"; /* Query portables list */ | ||
388 | typedef struct { | ||
389 | const char *string; | ||
390 | long length; | ||
391 | } StringDescriptor; | ||
392 | |||
393 | static const StringDescriptor CommandString[] = { | ||
394 | {CommandString0, sizeof(CommandString0) - 1}, | ||
395 | {CommandString1, sizeof(CommandString1) - 1}, | ||
396 | {CommandString2, sizeof(CommandString2) - 1}, | ||
397 | {CommandString3, sizeof(CommandString3) - 1}, | ||
398 | {CommandString4, sizeof(CommandString4) - 1}, | ||
399 | {CommandString5, sizeof(CommandString5) - 1} | ||
400 | }; | ||
401 | |||
402 | #define GOT_ALL_RADIO_INFO(S) \ | ||
403 | ((S)->firmware_version.c[0] && \ | ||
404 | (S)->battery_voltage.c[0] && \ | ||
405 | memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address))) | ||
406 | |||
407 | static const char hextable[16] = "0123456789ABCDEF"; | ||
408 | |||
409 | static const MetricomAddress zero_address; | ||
410 | static const MetricomAddress broadcast_address = | ||
411 | { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} }; | ||
412 | |||
413 | static const MetricomKey SIP0Key = { "SIP0" }; | ||
414 | static const MetricomKey ARP0Key = { "ARP0" }; | ||
415 | static const MetricomKey ATR_Key = { "ATR " }; | ||
416 | static const MetricomKey ACK_Key = { "ACK_" }; | ||
417 | static const MetricomKey INF_Key = { "INF_" }; | ||
418 | static const MetricomKey ERR_Key = { "ERR_" }; | ||
419 | |||
420 | static const long MaxARPInterval = 60 * HZ; /* One minute */ | ||
421 | |||
422 | /* | ||
423 | * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for | ||
424 | * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion | ||
425 | * for STRIP encoding, that translates to a maximum payload MTU of 1155. | ||
426 | * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes | ||
427 | * long, including IP header, UDP header, and NFS header. Setting the STRIP | ||
428 | * MTU to 1152 allows us to send default sized NFS packets without fragmentation. | ||
429 | */ | ||
430 | static const unsigned short MAX_SEND_MTU = 1152; | ||
431 | static const unsigned short MAX_RECV_MTU = 1500; /* Hoping for Ethernet sized packets in the future! */ | ||
432 | static const unsigned short DEFAULT_STRIP_MTU = 1152; | ||
433 | static const int STRIP_MAGIC = 0x5303; | ||
434 | static const long LongTime = 0x7FFFFFFF; | ||
435 | |||
436 | /************************************************************************/ | ||
437 | /* Global variables */ | ||
438 | |||
439 | static LIST_HEAD(strip_list); | ||
440 | static DEFINE_SPINLOCK(strip_lock); | ||
441 | |||
442 | /************************************************************************/ | ||
443 | /* Macros */ | ||
444 | |||
445 | /* Returns TRUE if text T begins with prefix P */ | ||
446 | #define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1)) | ||
447 | |||
448 | /* Returns TRUE if text T of length L is equal to string S */ | ||
449 | #define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1)) | ||
450 | |||
451 | #define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' : \ | ||
452 | (X)>='a' && (X)<='f' ? (X)-'a'+10 : \ | ||
453 | (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 ) | ||
454 | |||
455 | #define READHEX16(X) ((__u16)(READHEX(X))) | ||
456 | |||
457 | #define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0) | ||
458 | |||
459 | #define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)])) | ||
460 | |||
461 | #define JIFFIE_TO_SEC(X) ((X) / HZ) | ||
462 | |||
463 | |||
464 | /************************************************************************/ | ||
465 | /* Utility routines */ | ||
466 | |||
467 | static int arp_query(unsigned char *haddr, u32 paddr, | ||
468 | struct net_device *dev) | ||
469 | { | ||
470 | struct neighbour *neighbor_entry; | ||
471 | int ret = 0; | ||
472 | |||
473 | neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev); | ||
474 | |||
475 | if (neighbor_entry != NULL) { | ||
476 | neighbor_entry->used = jiffies; | ||
477 | if (neighbor_entry->nud_state & NUD_VALID) { | ||
478 | memcpy(haddr, neighbor_entry->ha, dev->addr_len); | ||
479 | ret = 1; | ||
480 | } | ||
481 | neigh_release(neighbor_entry); | ||
482 | } | ||
483 | return ret; | ||
484 | } | ||
485 | |||
486 | static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr, | ||
487 | __u8 * end) | ||
488 | { | ||
489 | static const int MAX_DumpData = 80; | ||
490 | __u8 pkt_text[MAX_DumpData], *p = pkt_text; | ||
491 | |||
492 | *p++ = '\"'; | ||
493 | |||
494 | while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) { | ||
495 | if (*ptr == '\\') { | ||
496 | *p++ = '\\'; | ||
497 | *p++ = '\\'; | ||
498 | } else { | ||
499 | if (*ptr >= 32 && *ptr <= 126) { | ||
500 | *p++ = *ptr; | ||
501 | } else { | ||
502 | sprintf(p, "\\%02X", *ptr); | ||
503 | p += 3; | ||
504 | } | ||
505 | } | ||
506 | ptr++; | ||
507 | } | ||
508 | |||
509 | if (ptr == end) | ||
510 | *p++ = '\"'; | ||
511 | *p++ = 0; | ||
512 | |||
513 | printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text); | ||
514 | } | ||
515 | |||
516 | |||
517 | /************************************************************************/ | ||
518 | /* Byte stuffing/unstuffing routines */ | ||
519 | |||
520 | /* Stuffing scheme: | ||
521 | * 00 Unused (reserved character) | ||
522 | * 01-3F Run of 2-64 different characters | ||
523 | * 40-7F Run of 1-64 different characters plus a single zero at the end | ||
524 | * 80-BF Run of 1-64 of the same character | ||
525 | * C0-FF Run of 1-64 zeroes (ASCII 0) | ||
526 | */ | ||
527 | |||
528 | typedef enum { | ||
529 | Stuff_Diff = 0x00, | ||
530 | Stuff_DiffZero = 0x40, | ||
531 | Stuff_Same = 0x80, | ||
532 | Stuff_Zero = 0xC0, | ||
533 | Stuff_NoCode = 0xFF, /* Special code, meaning no code selected */ | ||
534 | |||
535 | Stuff_CodeMask = 0xC0, | ||
536 | Stuff_CountMask = 0x3F, | ||
537 | Stuff_MaxCount = 0x3F, | ||
538 | Stuff_Magic = 0x0D /* The value we are eliminating */ | ||
539 | } StuffingCode; | ||
540 | |||
541 | /* StuffData encodes the data starting at "src" for "length" bytes. | ||
542 | * It writes it to the buffer pointed to by "dst" (which must be at least | ||
543 | * as long as 1 + 65/64 of the input length). The output may be up to 1.6% | ||
544 | * larger than the input for pathological input, but will usually be smaller. | ||
545 | * StuffData returns the new value of the dst pointer as its result. | ||
546 | * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state | ||
547 | * between calls, allowing an encoded packet to be incrementally built up | ||
548 | * from small parts. On the first call, the "__u8 *" pointed to should be | ||
549 | * initialized to NULL; between subsequent calls the calling routine should | ||
550 | * leave the value alone and simply pass it back unchanged so that the | ||
551 | * encoder can recover its current state. | ||
552 | */ | ||
553 | |||
554 | #define StuffData_FinishBlock(X) \ | ||
555 | (*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode) | ||
556 | |||
557 | static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst, | ||
558 | __u8 ** code_ptr_ptr) | ||
559 | { | ||
560 | __u8 *end = src + length; | ||
561 | __u8 *code_ptr = *code_ptr_ptr; | ||
562 | __u8 code = Stuff_NoCode, count = 0; | ||
563 | |||
564 | if (!length) | ||
565 | return (dst); | ||
566 | |||
567 | if (code_ptr) { | ||
568 | /* | ||
569 | * Recover state from last call, if applicable | ||
570 | */ | ||
571 | code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask; | ||
572 | count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask; | ||
573 | } | ||
574 | |||
575 | while (src < end) { | ||
576 | switch (code) { | ||
577 | /* Stuff_NoCode: If no current code, select one */ | ||
578 | case Stuff_NoCode: | ||
579 | /* Record where we're going to put this code */ | ||
580 | code_ptr = dst++; | ||
581 | count = 0; /* Reset the count (zero means one instance) */ | ||
582 | /* Tentatively start a new block */ | ||
583 | if (*src == 0) { | ||
584 | code = Stuff_Zero; | ||
585 | src++; | ||
586 | } else { | ||
587 | code = Stuff_Same; | ||
588 | *dst++ = *src++ ^ Stuff_Magic; | ||
589 | } | ||
590 | /* Note: We optimistically assume run of same -- */ | ||
591 | /* which will be fixed later in Stuff_Same */ | ||
592 | /* if it turns out not to be true. */ | ||
593 | break; | ||
594 | |||
595 | /* Stuff_Zero: We already have at least one zero encoded */ | ||
596 | case Stuff_Zero: | ||
597 | /* If another zero, count it, else finish this code block */ | ||
598 | if (*src == 0) { | ||
599 | count++; | ||
600 | src++; | ||
601 | } else { | ||
602 | StuffData_FinishBlock(Stuff_Zero + count); | ||
603 | } | ||
604 | break; | ||
605 | |||
606 | /* Stuff_Same: We already have at least one byte encoded */ | ||
607 | case Stuff_Same: | ||
608 | /* If another one the same, count it */ | ||
609 | if ((*src ^ Stuff_Magic) == code_ptr[1]) { | ||
610 | count++; | ||
611 | src++; | ||
612 | break; | ||
613 | } | ||
614 | /* else, this byte does not match this block. */ | ||
615 | /* If we already have two or more bytes encoded, finish this code block */ | ||
616 | if (count) { | ||
617 | StuffData_FinishBlock(Stuff_Same + count); | ||
618 | break; | ||
619 | } | ||
620 | /* else, we only have one so far, so switch to Stuff_Diff code */ | ||
621 | code = Stuff_Diff; | ||
622 | /* and fall through to Stuff_Diff case below | ||
623 | * Note cunning cleverness here: case Stuff_Diff compares | ||
624 | * the current character with the previous two to see if it | ||
625 | * has a run of three the same. Won't this be an error if | ||
626 | * there aren't two previous characters stored to compare with? | ||
627 | * No. Because we know the current character is *not* the same | ||
628 | * as the previous one, the first test below will necessarily | ||
629 | * fail and the send half of the "if" won't be executed. | ||
630 | */ | ||
631 | |||
632 | /* Stuff_Diff: We have at least two *different* bytes encoded */ | ||
633 | case Stuff_Diff: | ||
634 | /* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */ | ||
635 | if (*src == 0) { | ||
636 | StuffData_FinishBlock(Stuff_DiffZero + | ||
637 | count); | ||
638 | } | ||
639 | /* else, if we have three in a row, it is worth starting a Stuff_Same block */ | ||
640 | else if ((*src ^ Stuff_Magic) == dst[-1] | ||
641 | && dst[-1] == dst[-2]) { | ||
642 | /* Back off the last two characters we encoded */ | ||
643 | code += count - 2; | ||
644 | /* Note: "Stuff_Diff + 0" is an illegal code */ | ||
645 | if (code == Stuff_Diff + 0) { | ||
646 | code = Stuff_Same + 0; | ||
647 | } | ||
648 | StuffData_FinishBlock(code); | ||
649 | code_ptr = dst - 2; | ||
650 | /* dst[-1] already holds the correct value */ | ||
651 | count = 2; /* 2 means three bytes encoded */ | ||
652 | code = Stuff_Same; | ||
653 | } | ||
654 | /* else, another different byte, so add it to the block */ | ||
655 | else { | ||
656 | *dst++ = *src ^ Stuff_Magic; | ||
657 | count++; | ||
658 | } | ||
659 | src++; /* Consume the byte */ | ||
660 | break; | ||
661 | } | ||
662 | if (count == Stuff_MaxCount) { | ||
663 | StuffData_FinishBlock(code + count); | ||
664 | } | ||
665 | } | ||
666 | if (code == Stuff_NoCode) { | ||
667 | *code_ptr_ptr = NULL; | ||
668 | } else { | ||
669 | *code_ptr_ptr = code_ptr; | ||
670 | StuffData_FinishBlock(code + count); | ||
671 | } | ||
672 | return (dst); | ||
673 | } | ||
674 | |||
675 | /* | ||
676 | * UnStuffData decodes the data at "src", up to (but not including) "end". | ||
677 | * It writes the decoded data into the buffer pointed to by "dst", up to a | ||
678 | * maximum of "dst_length", and returns the new value of "src" so that a | ||
679 | * follow-on call can read more data, continuing from where the first left off. | ||
680 | * | ||
681 | * There are three types of results: | ||
682 | * 1. The source data runs out before extracting "dst_length" bytes: | ||
683 | * UnStuffData returns NULL to indicate failure. | ||
684 | * 2. The source data produces exactly "dst_length" bytes: | ||
685 | * UnStuffData returns new_src = end to indicate that all bytes were consumed. | ||
686 | * 3. "dst_length" bytes are extracted, with more remaining. | ||
687 | * UnStuffData returns new_src < end to indicate that there are more bytes | ||
688 | * to be read. | ||
689 | * | ||
690 | * Note: The decoding may be destructive, in that it may alter the source | ||
691 | * data in the process of decoding it (this is necessary to allow a follow-on | ||
692 | * call to resume correctly). | ||
693 | */ | ||
694 | |||
695 | static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst, | ||
696 | __u32 dst_length) | ||
697 | { | ||
698 | __u8 *dst_end = dst + dst_length; | ||
699 | /* Sanity check */ | ||
700 | if (!src || !end || !dst || !dst_length) | ||
701 | return (NULL); | ||
702 | while (src < end && dst < dst_end) { | ||
703 | int count = (*src ^ Stuff_Magic) & Stuff_CountMask; | ||
704 | switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) { | ||
705 | case Stuff_Diff: | ||
706 | if (src + 1 + count >= end) | ||
707 | return (NULL); | ||
708 | do { | ||
709 | *dst++ = *++src ^ Stuff_Magic; | ||
710 | } | ||
711 | while (--count >= 0 && dst < dst_end); | ||
712 | if (count < 0) | ||
713 | src += 1; | ||
714 | else { | ||
715 | if (count == 0) | ||
716 | *src = Stuff_Same ^ Stuff_Magic; | ||
717 | else | ||
718 | *src = | ||
719 | (Stuff_Diff + | ||
720 | count) ^ Stuff_Magic; | ||
721 | } | ||
722 | break; | ||
723 | case Stuff_DiffZero: | ||
724 | if (src + 1 + count >= end) | ||
725 | return (NULL); | ||
726 | do { | ||
727 | *dst++ = *++src ^ Stuff_Magic; | ||
728 | } | ||
729 | while (--count >= 0 && dst < dst_end); | ||
730 | if (count < 0) | ||
731 | *src = Stuff_Zero ^ Stuff_Magic; | ||
732 | else | ||
733 | *src = | ||
734 | (Stuff_DiffZero + count) ^ Stuff_Magic; | ||
735 | break; | ||
736 | case Stuff_Same: | ||
737 | if (src + 1 >= end) | ||
738 | return (NULL); | ||
739 | do { | ||
740 | *dst++ = src[1] ^ Stuff_Magic; | ||
741 | } | ||
742 | while (--count >= 0 && dst < dst_end); | ||
743 | if (count < 0) | ||
744 | src += 2; | ||
745 | else | ||
746 | *src = (Stuff_Same + count) ^ Stuff_Magic; | ||
747 | break; | ||
748 | case Stuff_Zero: | ||
749 | do { | ||
750 | *dst++ = 0; | ||
751 | } | ||
752 | while (--count >= 0 && dst < dst_end); | ||
753 | if (count < 0) | ||
754 | src += 1; | ||
755 | else | ||
756 | *src = (Stuff_Zero + count) ^ Stuff_Magic; | ||
757 | break; | ||
758 | } | ||
759 | } | ||
760 | if (dst < dst_end) | ||
761 | return (NULL); | ||
762 | else | ||
763 | return (src); | ||
764 | } | ||
765 | |||
766 | |||
767 | /************************************************************************/ | ||
768 | /* General routines for STRIP */ | ||
769 | |||
770 | /* | ||
771 | * set_baud sets the baud rate to the rate defined by baudcode | ||
772 | */ | ||
773 | static void set_baud(struct tty_struct *tty, speed_t baudrate) | ||
774 | { | ||
775 | struct ktermios old_termios; | ||
776 | |||
777 | mutex_lock(&tty->termios_mutex); | ||
778 | old_termios =*(tty->termios); | ||
779 | tty_encode_baud_rate(tty, baudrate, baudrate); | ||
780 | tty->ops->set_termios(tty, &old_termios); | ||
781 | mutex_unlock(&tty->termios_mutex); | ||
782 | } | ||
783 | |||
784 | /* | ||
785 | * Convert a string to a Metricom Address. | ||
786 | */ | ||
787 | |||
788 | #define IS_RADIO_ADDRESS(p) ( \ | ||
789 | isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \ | ||
790 | (p)[4] == '-' && \ | ||
791 | isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8]) ) | ||
792 | |||
793 | static int string_to_radio_address(MetricomAddress * addr, __u8 * p) | ||
794 | { | ||
795 | if (!IS_RADIO_ADDRESS(p)) | ||
796 | return (1); | ||
797 | addr->c[0] = 0; | ||
798 | addr->c[1] = 0; | ||
799 | addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]); | ||
800 | addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]); | ||
801 | addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]); | ||
802 | addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]); | ||
803 | return (0); | ||
804 | } | ||
805 | |||
806 | /* | ||
807 | * Convert a Metricom Address to a string. | ||
808 | */ | ||
809 | |||
810 | static __u8 *radio_address_to_string(const MetricomAddress * addr, | ||
811 | MetricomAddressString * p) | ||
812 | { | ||
813 | sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3], | ||
814 | addr->c[4], addr->c[5]); | ||
815 | return (p->c); | ||
816 | } | ||
817 | |||
818 | /* | ||
819 | * Note: Must make sure sx_size is big enough to receive a stuffed | ||
820 | * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's | ||
821 | * big enough to receive a large radio neighbour list (currently 4K). | ||
822 | */ | ||
823 | |||
824 | static int allocate_buffers(struct strip *strip_info, int mtu) | ||
825 | { | ||
826 | struct net_device *dev = strip_info->dev; | ||
827 | int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096); | ||
828 | int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength; | ||
829 | __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC); | ||
830 | __u8 *s = kmalloc(sx_size, GFP_ATOMIC); | ||
831 | __u8 *t = kmalloc(tx_size, GFP_ATOMIC); | ||
832 | if (r && s && t) { | ||
833 | strip_info->rx_buff = r; | ||
834 | strip_info->sx_buff = s; | ||
835 | strip_info->tx_buff = t; | ||
836 | strip_info->sx_size = sx_size; | ||
837 | strip_info->tx_size = tx_size; | ||
838 | strip_info->mtu = dev->mtu = mtu; | ||
839 | return (1); | ||
840 | } | ||
841 | kfree(r); | ||
842 | kfree(s); | ||
843 | kfree(t); | ||
844 | return (0); | ||
845 | } | ||
846 | |||
847 | /* | ||
848 | * MTU has been changed by the IP layer. | ||
849 | * We could be in | ||
850 | * an upcall from the tty driver, or in an ip packet queue. | ||
851 | */ | ||
852 | static int strip_change_mtu(struct net_device *dev, int new_mtu) | ||
853 | { | ||
854 | struct strip *strip_info = netdev_priv(dev); | ||
855 | int old_mtu = strip_info->mtu; | ||
856 | unsigned char *orbuff = strip_info->rx_buff; | ||
857 | unsigned char *osbuff = strip_info->sx_buff; | ||
858 | unsigned char *otbuff = strip_info->tx_buff; | ||
859 | |||
860 | if (new_mtu > MAX_SEND_MTU) { | ||
861 | printk(KERN_ERR | ||
862 | "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n", | ||
863 | strip_info->dev->name, MAX_SEND_MTU); | ||
864 | return -EINVAL; | ||
865 | } | ||
866 | |||
867 | spin_lock_bh(&strip_lock); | ||
868 | if (!allocate_buffers(strip_info, new_mtu)) { | ||
869 | printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n", | ||
870 | strip_info->dev->name); | ||
871 | spin_unlock_bh(&strip_lock); | ||
872 | return -ENOMEM; | ||
873 | } | ||
874 | |||
875 | if (strip_info->sx_count) { | ||
876 | if (strip_info->sx_count <= strip_info->sx_size) | ||
877 | memcpy(strip_info->sx_buff, osbuff, | ||
878 | strip_info->sx_count); | ||
879 | else { | ||
880 | strip_info->discard = strip_info->sx_count; | ||
881 | strip_info->rx_over_errors++; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | if (strip_info->tx_left) { | ||
886 | if (strip_info->tx_left <= strip_info->tx_size) | ||
887 | memcpy(strip_info->tx_buff, strip_info->tx_head, | ||
888 | strip_info->tx_left); | ||
889 | else { | ||
890 | strip_info->tx_left = 0; | ||
891 | strip_info->tx_dropped++; | ||
892 | } | ||
893 | } | ||
894 | strip_info->tx_head = strip_info->tx_buff; | ||
895 | spin_unlock_bh(&strip_lock); | ||
896 | |||
897 | printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n", | ||
898 | strip_info->dev->name, old_mtu, strip_info->mtu); | ||
899 | |||
900 | kfree(orbuff); | ||
901 | kfree(osbuff); | ||
902 | kfree(otbuff); | ||
903 | return 0; | ||
904 | } | ||
905 | |||
906 | static void strip_unlock(struct strip *strip_info) | ||
907 | { | ||
908 | /* | ||
909 | * Set the timer to go off in one second. | ||
910 | */ | ||
911 | strip_info->idle_timer.expires = jiffies + 1 * HZ; | ||
912 | add_timer(&strip_info->idle_timer); | ||
913 | netif_wake_queue(strip_info->dev); | ||
914 | } | ||
915 | |||
916 | |||
917 | |||
918 | /* | ||
919 | * If the time is in the near future, time_delta prints the number of | ||
920 | * seconds to go into the buffer and returns the address of the buffer. | ||
921 | * If the time is not in the near future, it returns the address of the | ||
922 | * string "Not scheduled" The buffer must be long enough to contain the | ||
923 | * ascii representation of the number plus 9 charactes for the " seconds" | ||
924 | * and the null character. | ||
925 | */ | ||
926 | #ifdef CONFIG_PROC_FS | ||
927 | static char *time_delta(char buffer[], long time) | ||
928 | { | ||
929 | time -= jiffies; | ||
930 | if (time > LongTime / 2) | ||
931 | return ("Not scheduled"); | ||
932 | if (time < 0) | ||
933 | time = 0; /* Don't print negative times */ | ||
934 | sprintf(buffer, "%ld seconds", time / HZ); | ||
935 | return (buffer); | ||
936 | } | ||
937 | |||
938 | /* get Nth element of the linked list */ | ||
939 | static struct strip *strip_get_idx(loff_t pos) | ||
940 | { | ||
941 | struct strip *str; | ||
942 | int i = 0; | ||
943 | |||
944 | list_for_each_entry_rcu(str, &strip_list, list) { | ||
945 | if (pos == i) | ||
946 | return str; | ||
947 | ++i; | ||
948 | } | ||
949 | return NULL; | ||
950 | } | ||
951 | |||
952 | static void *strip_seq_start(struct seq_file *seq, loff_t *pos) | ||
953 | { | ||
954 | rcu_read_lock(); | ||
955 | return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN; | ||
956 | } | ||
957 | |||
958 | static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos) | ||
959 | { | ||
960 | struct list_head *l; | ||
961 | struct strip *s; | ||
962 | |||
963 | ++*pos; | ||
964 | if (v == SEQ_START_TOKEN) | ||
965 | return strip_get_idx(1); | ||
966 | |||
967 | s = v; | ||
968 | l = &s->list; | ||
969 | list_for_each_continue_rcu(l, &strip_list) { | ||
970 | return list_entry(l, struct strip, list); | ||
971 | } | ||
972 | return NULL; | ||
973 | } | ||
974 | |||
975 | static void strip_seq_stop(struct seq_file *seq, void *v) | ||
976 | { | ||
977 | rcu_read_unlock(); | ||
978 | } | ||
979 | |||
980 | static void strip_seq_neighbours(struct seq_file *seq, | ||
981 | const MetricomNodeTable * table, | ||
982 | const char *title) | ||
983 | { | ||
984 | /* We wrap this in a do/while loop, so if the table changes */ | ||
985 | /* while we're reading it, we just go around and try again. */ | ||
986 | struct timeval t; | ||
987 | |||
988 | do { | ||
989 | int i; | ||
990 | t = table->timestamp; | ||
991 | if (table->num_nodes) | ||
992 | seq_printf(seq, "\n %s\n", title); | ||
993 | for (i = 0; i < table->num_nodes; i++) { | ||
994 | MetricomNode node; | ||
995 | |||
996 | spin_lock_bh(&strip_lock); | ||
997 | node = table->node[i]; | ||
998 | spin_unlock_bh(&strip_lock); | ||
999 | seq_printf(seq, " %s\n", node.c); | ||
1000 | } | ||
1001 | } while (table->timestamp.tv_sec != t.tv_sec | ||
1002 | || table->timestamp.tv_usec != t.tv_usec); | ||
1003 | } | ||
1004 | |||
1005 | /* | ||
1006 | * This function prints radio status information via the seq_file | ||
1007 | * interface. The interface takes care of buffer size and over | ||
1008 | * run issues. | ||
1009 | * | ||
1010 | * The buffer in seq_file is PAGESIZE (4K) | ||
1011 | * so this routine should never print more or it will get truncated. | ||
1012 | * With the maximum of 32 portables and 32 poletops | ||
1013 | * reported, the routine outputs 3107 bytes into the buffer. | ||
1014 | */ | ||
1015 | static void strip_seq_status_info(struct seq_file *seq, | ||
1016 | const struct strip *strip_info) | ||
1017 | { | ||
1018 | char temp[32]; | ||
1019 | MetricomAddressString addr_string; | ||
1020 | |||
1021 | /* First, we must copy all of our data to a safe place, */ | ||
1022 | /* in case a serial interrupt comes in and changes it. */ | ||
1023 | int tx_left = strip_info->tx_left; | ||
1024 | unsigned long rx_average_pps = strip_info->rx_average_pps; | ||
1025 | unsigned long tx_average_pps = strip_info->tx_average_pps; | ||
1026 | unsigned long sx_average_pps = strip_info->sx_average_pps; | ||
1027 | int working = strip_info->working; | ||
1028 | int firmware_level = strip_info->firmware_level; | ||
1029 | long watchdog_doprobe = strip_info->watchdog_doprobe; | ||
1030 | long watchdog_doreset = strip_info->watchdog_doreset; | ||
1031 | long gratuitous_arp = strip_info->gratuitous_arp; | ||
1032 | long arp_interval = strip_info->arp_interval; | ||
1033 | FirmwareVersion firmware_version = strip_info->firmware_version; | ||
1034 | SerialNumber serial_number = strip_info->serial_number; | ||
1035 | BatteryVoltage battery_voltage = strip_info->battery_voltage; | ||
1036 | char *if_name = strip_info->dev->name; | ||
1037 | MetricomAddress true_dev_addr = strip_info->true_dev_addr; | ||
1038 | MetricomAddress dev_dev_addr = | ||
1039 | *(MetricomAddress *) strip_info->dev->dev_addr; | ||
1040 | int manual_dev_addr = strip_info->manual_dev_addr; | ||
1041 | #ifdef EXT_COUNTERS | ||
1042 | unsigned long rx_bytes = strip_info->rx_bytes; | ||
1043 | unsigned long tx_bytes = strip_info->tx_bytes; | ||
1044 | unsigned long rx_rbytes = strip_info->rx_rbytes; | ||
1045 | unsigned long tx_rbytes = strip_info->tx_rbytes; | ||
1046 | unsigned long rx_sbytes = strip_info->rx_sbytes; | ||
1047 | unsigned long tx_sbytes = strip_info->tx_sbytes; | ||
1048 | unsigned long rx_ebytes = strip_info->rx_ebytes; | ||
1049 | unsigned long tx_ebytes = strip_info->tx_ebytes; | ||
1050 | #endif | ||
1051 | |||
1052 | seq_printf(seq, "\nInterface name\t\t%s\n", if_name); | ||
1053 | seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No"); | ||
1054 | radio_address_to_string(&true_dev_addr, &addr_string); | ||
1055 | seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c); | ||
1056 | if (manual_dev_addr) { | ||
1057 | radio_address_to_string(&dev_dev_addr, &addr_string); | ||
1058 | seq_printf(seq, " Device address:\t%s\n", addr_string.c); | ||
1059 | } | ||
1060 | seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" : | ||
1061 | !firmware_level ? "Should be upgraded" : | ||
1062 | firmware_version.c); | ||
1063 | if (firmware_level >= ChecksummedMessages) | ||
1064 | seq_printf(seq, " (Checksums Enabled)"); | ||
1065 | seq_printf(seq, "\n"); | ||
1066 | seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c); | ||
1067 | seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c); | ||
1068 | seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left); | ||
1069 | seq_printf(seq, " Receive packet rate: %ld packets per second\n", | ||
1070 | rx_average_pps / 8); | ||
1071 | seq_printf(seq, " Transmit packet rate: %ld packets per second\n", | ||
1072 | tx_average_pps / 8); | ||
1073 | seq_printf(seq, " Sent packet rate: %ld packets per second\n", | ||
1074 | sx_average_pps / 8); | ||
1075 | seq_printf(seq, " Next watchdog probe:\t%s\n", | ||
1076 | time_delta(temp, watchdog_doprobe)); | ||
1077 | seq_printf(seq, " Next watchdog reset:\t%s\n", | ||
1078 | time_delta(temp, watchdog_doreset)); | ||
1079 | seq_printf(seq, " Next gratuitous ARP:\t"); | ||
1080 | |||
1081 | if (!memcmp | ||
1082 | (strip_info->dev->dev_addr, zero_address.c, | ||
1083 | sizeof(zero_address))) | ||
1084 | seq_printf(seq, "Disabled\n"); | ||
1085 | else { | ||
1086 | seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp)); | ||
1087 | seq_printf(seq, " Next ARP interval:\t%ld seconds\n", | ||
1088 | JIFFIE_TO_SEC(arp_interval)); | ||
1089 | } | ||
1090 | |||
1091 | if (working) { | ||
1092 | #ifdef EXT_COUNTERS | ||
1093 | seq_printf(seq, "\n"); | ||
1094 | seq_printf(seq, | ||
1095 | " Total bytes: \trx:\t%lu\ttx:\t%lu\n", | ||
1096 | rx_bytes, tx_bytes); | ||
1097 | seq_printf(seq, | ||
1098 | " thru radio: \trx:\t%lu\ttx:\t%lu\n", | ||
1099 | rx_rbytes, tx_rbytes); | ||
1100 | seq_printf(seq, | ||
1101 | " thru serial port: \trx:\t%lu\ttx:\t%lu\n", | ||
1102 | rx_sbytes, tx_sbytes); | ||
1103 | seq_printf(seq, | ||
1104 | " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n", | ||
1105 | rx_ebytes, tx_ebytes); | ||
1106 | #endif | ||
1107 | strip_seq_neighbours(seq, &strip_info->poletops, | ||
1108 | "Poletops:"); | ||
1109 | strip_seq_neighbours(seq, &strip_info->portables, | ||
1110 | "Portables:"); | ||
1111 | } | ||
1112 | } | ||
1113 | |||
1114 | /* | ||
1115 | * This function is exports status information from the STRIP driver through | ||
1116 | * the /proc file system. | ||
1117 | */ | ||
1118 | static int strip_seq_show(struct seq_file *seq, void *v) | ||
1119 | { | ||
1120 | if (v == SEQ_START_TOKEN) | ||
1121 | seq_printf(seq, "strip_version: %s\n", StripVersion); | ||
1122 | else | ||
1123 | strip_seq_status_info(seq, (const struct strip *)v); | ||
1124 | return 0; | ||
1125 | } | ||
1126 | |||
1127 | |||
1128 | static struct seq_operations strip_seq_ops = { | ||
1129 | .start = strip_seq_start, | ||
1130 | .next = strip_seq_next, | ||
1131 | .stop = strip_seq_stop, | ||
1132 | .show = strip_seq_show, | ||
1133 | }; | ||
1134 | |||
1135 | static int strip_seq_open(struct inode *inode, struct file *file) | ||
1136 | { | ||
1137 | return seq_open(file, &strip_seq_ops); | ||
1138 | } | ||
1139 | |||
1140 | static const struct file_operations strip_seq_fops = { | ||
1141 | .owner = THIS_MODULE, | ||
1142 | .open = strip_seq_open, | ||
1143 | .read = seq_read, | ||
1144 | .llseek = seq_lseek, | ||
1145 | .release = seq_release, | ||
1146 | }; | ||
1147 | #endif | ||
1148 | |||
1149 | |||
1150 | |||
1151 | /************************************************************************/ | ||
1152 | /* Sending routines */ | ||
1153 | |||
1154 | static void ResetRadio(struct strip *strip_info) | ||
1155 | { | ||
1156 | struct tty_struct *tty = strip_info->tty; | ||
1157 | static const char init[] = "ate0q1dt**starmode\r**"; | ||
1158 | StringDescriptor s = { init, sizeof(init) - 1 }; | ||
1159 | |||
1160 | /* | ||
1161 | * If the radio isn't working anymore, | ||
1162 | * we should clear the old status information. | ||
1163 | */ | ||
1164 | if (strip_info->working) { | ||
1165 | printk(KERN_INFO "%s: No response: Resetting radio.\n", | ||
1166 | strip_info->dev->name); | ||
1167 | strip_info->firmware_version.c[0] = '\0'; | ||
1168 | strip_info->serial_number.c[0] = '\0'; | ||
1169 | strip_info->battery_voltage.c[0] = '\0'; | ||
1170 | strip_info->portables.num_nodes = 0; | ||
1171 | do_gettimeofday(&strip_info->portables.timestamp); | ||
1172 | strip_info->poletops.num_nodes = 0; | ||
1173 | do_gettimeofday(&strip_info->poletops.timestamp); | ||
1174 | } | ||
1175 | |||
1176 | strip_info->pps_timer = jiffies; | ||
1177 | strip_info->rx_pps_count = 0; | ||
1178 | strip_info->tx_pps_count = 0; | ||
1179 | strip_info->sx_pps_count = 0; | ||
1180 | strip_info->rx_average_pps = 0; | ||
1181 | strip_info->tx_average_pps = 0; | ||
1182 | strip_info->sx_average_pps = 0; | ||
1183 | |||
1184 | /* Mark radio address as unknown */ | ||
1185 | *(MetricomAddress *) & strip_info->true_dev_addr = zero_address; | ||
1186 | if (!strip_info->manual_dev_addr) | ||
1187 | *(MetricomAddress *) strip_info->dev->dev_addr = | ||
1188 | zero_address; | ||
1189 | strip_info->working = FALSE; | ||
1190 | strip_info->firmware_level = NoStructure; | ||
1191 | strip_info->next_command = CompatibilityCommand; | ||
1192 | strip_info->watchdog_doprobe = jiffies + 10 * HZ; | ||
1193 | strip_info->watchdog_doreset = jiffies + 1 * HZ; | ||
1194 | |||
1195 | /* If the user has selected a baud rate above 38.4 see what magic we have to do */ | ||
1196 | if (strip_info->user_baud > 38400) { | ||
1197 | /* | ||
1198 | * Subtle stuff: Pay attention :-) | ||
1199 | * If the serial port is currently at the user's selected (>38.4) rate, | ||
1200 | * then we temporarily switch to 19.2 and issue the ATS304 command | ||
1201 | * to tell the radio to switch to the user's selected rate. | ||
1202 | * If the serial port is not currently at that rate, that means we just | ||
1203 | * issued the ATS304 command last time through, so this time we restore | ||
1204 | * the user's selected rate and issue the normal starmode reset string. | ||
1205 | */ | ||
1206 | if (strip_info->user_baud == tty_get_baud_rate(tty)) { | ||
1207 | static const char b0[] = "ate0q1s304=57600\r"; | ||
1208 | static const char b1[] = "ate0q1s304=115200\r"; | ||
1209 | static const StringDescriptor baudstring[2] = | ||
1210 | { {b0, sizeof(b0) - 1} | ||
1211 | , {b1, sizeof(b1) - 1} | ||
1212 | }; | ||
1213 | set_baud(tty, 19200); | ||
1214 | if (strip_info->user_baud == 57600) | ||
1215 | s = baudstring[0]; | ||
1216 | else if (strip_info->user_baud == 115200) | ||
1217 | s = baudstring[1]; | ||
1218 | else | ||
1219 | s = baudstring[1]; /* For now */ | ||
1220 | } else | ||
1221 | set_baud(tty, strip_info->user_baud); | ||
1222 | } | ||
1223 | |||
1224 | tty->ops->write(tty, s.string, s.length); | ||
1225 | #ifdef EXT_COUNTERS | ||
1226 | strip_info->tx_ebytes += s.length; | ||
1227 | #endif | ||
1228 | } | ||
1229 | |||
1230 | /* | ||
1231 | * Called by the driver when there's room for more data. If we have | ||
1232 | * more packets to send, we send them here. | ||
1233 | */ | ||
1234 | |||
1235 | static void strip_write_some_more(struct tty_struct *tty) | ||
1236 | { | ||
1237 | struct strip *strip_info = (struct strip *) tty->disc_data; | ||
1238 | |||
1239 | /* First make sure we're connected. */ | ||
1240 | if (!strip_info || strip_info->magic != STRIP_MAGIC || | ||
1241 | !netif_running(strip_info->dev)) | ||
1242 | return; | ||
1243 | |||
1244 | if (strip_info->tx_left > 0) { | ||
1245 | int num_written = | ||
1246 | tty->ops->write(tty, strip_info->tx_head, | ||
1247 | strip_info->tx_left); | ||
1248 | strip_info->tx_left -= num_written; | ||
1249 | strip_info->tx_head += num_written; | ||
1250 | #ifdef EXT_COUNTERS | ||
1251 | strip_info->tx_sbytes += num_written; | ||
1252 | #endif | ||
1253 | } else { /* Else start transmission of another packet */ | ||
1254 | |||
1255 | tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
1256 | strip_unlock(strip_info); | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | static __u8 *add_checksum(__u8 * buffer, __u8 * end) | ||
1261 | { | ||
1262 | __u16 sum = 0; | ||
1263 | __u8 *p = buffer; | ||
1264 | while (p < end) | ||
1265 | sum += *p++; | ||
1266 | end[3] = hextable[sum & 0xF]; | ||
1267 | sum >>= 4; | ||
1268 | end[2] = hextable[sum & 0xF]; | ||
1269 | sum >>= 4; | ||
1270 | end[1] = hextable[sum & 0xF]; | ||
1271 | sum >>= 4; | ||
1272 | end[0] = hextable[sum & 0xF]; | ||
1273 | return (end + 4); | ||
1274 | } | ||
1275 | |||
1276 | static unsigned char *strip_make_packet(unsigned char *buffer, | ||
1277 | struct strip *strip_info, | ||
1278 | struct sk_buff *skb) | ||
1279 | { | ||
1280 | __u8 *ptr = buffer; | ||
1281 | __u8 *stuffstate = NULL; | ||
1282 | STRIP_Header *header = (STRIP_Header *) skb->data; | ||
1283 | MetricomAddress haddr = header->dst_addr; | ||
1284 | int len = skb->len - sizeof(STRIP_Header); | ||
1285 | MetricomKey key; | ||
1286 | |||
1287 | /*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */ | ||
1288 | |||
1289 | if (header->protocol == htons(ETH_P_IP)) | ||
1290 | key = SIP0Key; | ||
1291 | else if (header->protocol == htons(ETH_P_ARP)) | ||
1292 | key = ARP0Key; | ||
1293 | else { | ||
1294 | printk(KERN_ERR | ||
1295 | "%s: strip_make_packet: Unknown packet type 0x%04X\n", | ||
1296 | strip_info->dev->name, ntohs(header->protocol)); | ||
1297 | return (NULL); | ||
1298 | } | ||
1299 | |||
1300 | if (len > strip_info->mtu) { | ||
1301 | printk(KERN_ERR | ||
1302 | "%s: Dropping oversized transmit packet: %d bytes\n", | ||
1303 | strip_info->dev->name, len); | ||
1304 | return (NULL); | ||
1305 | } | ||
1306 | |||
1307 | /* | ||
1308 | * If we're sending to ourselves, discard the packet. | ||
1309 | * (Metricom radios choke if they try to send a packet to their own address.) | ||
1310 | */ | ||
1311 | if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) { | ||
1312 | printk(KERN_ERR "%s: Dropping packet addressed to self\n", | ||
1313 | strip_info->dev->name); | ||
1314 | return (NULL); | ||
1315 | } | ||
1316 | |||
1317 | /* | ||
1318 | * If this is a broadcast packet, send it to our designated Metricom | ||
1319 | * 'broadcast hub' radio (First byte of address being 0xFF means broadcast) | ||
1320 | */ | ||
1321 | if (haddr.c[0] == 0xFF) { | ||
1322 | __be32 brd = 0; | ||
1323 | struct in_device *in_dev; | ||
1324 | |||
1325 | rcu_read_lock(); | ||
1326 | in_dev = __in_dev_get_rcu(strip_info->dev); | ||
1327 | if (in_dev == NULL) { | ||
1328 | rcu_read_unlock(); | ||
1329 | return NULL; | ||
1330 | } | ||
1331 | if (in_dev->ifa_list) | ||
1332 | brd = in_dev->ifa_list->ifa_broadcast; | ||
1333 | rcu_read_unlock(); | ||
1334 | |||
1335 | /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */ | ||
1336 | if (!arp_query(haddr.c, brd, strip_info->dev)) { | ||
1337 | printk(KERN_ERR | ||
1338 | "%s: Unable to send packet (no broadcast hub configured)\n", | ||
1339 | strip_info->dev->name); | ||
1340 | return (NULL); | ||
1341 | } | ||
1342 | /* | ||
1343 | * If we are the broadcast hub, don't bother sending to ourselves. | ||
1344 | * (Metricom radios choke if they try to send a packet to their own address.) | ||
1345 | */ | ||
1346 | if (!memcmp | ||
1347 | (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) | ||
1348 | return (NULL); | ||
1349 | } | ||
1350 | |||
1351 | *ptr++ = 0x0D; | ||
1352 | *ptr++ = '*'; | ||
1353 | *ptr++ = hextable[haddr.c[2] >> 4]; | ||
1354 | *ptr++ = hextable[haddr.c[2] & 0xF]; | ||
1355 | *ptr++ = hextable[haddr.c[3] >> 4]; | ||
1356 | *ptr++ = hextable[haddr.c[3] & 0xF]; | ||
1357 | *ptr++ = '-'; | ||
1358 | *ptr++ = hextable[haddr.c[4] >> 4]; | ||
1359 | *ptr++ = hextable[haddr.c[4] & 0xF]; | ||
1360 | *ptr++ = hextable[haddr.c[5] >> 4]; | ||
1361 | *ptr++ = hextable[haddr.c[5] & 0xF]; | ||
1362 | *ptr++ = '*'; | ||
1363 | *ptr++ = key.c[0]; | ||
1364 | *ptr++ = key.c[1]; | ||
1365 | *ptr++ = key.c[2]; | ||
1366 | *ptr++ = key.c[3]; | ||
1367 | |||
1368 | ptr = | ||
1369 | StuffData(skb->data + sizeof(STRIP_Header), len, ptr, | ||
1370 | &stuffstate); | ||
1371 | |||
1372 | if (strip_info->firmware_level >= ChecksummedMessages) | ||
1373 | ptr = add_checksum(buffer + 1, ptr); | ||
1374 | |||
1375 | *ptr++ = 0x0D; | ||
1376 | return (ptr); | ||
1377 | } | ||
1378 | |||
1379 | static void strip_send(struct strip *strip_info, struct sk_buff *skb) | ||
1380 | { | ||
1381 | MetricomAddress haddr; | ||
1382 | unsigned char *ptr = strip_info->tx_buff; | ||
1383 | int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0; | ||
1384 | int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0 | ||
1385 | && !doreset; | ||
1386 | __be32 addr, brd; | ||
1387 | |||
1388 | /* | ||
1389 | * 1. If we have a packet, encapsulate it and put it in the buffer | ||
1390 | */ | ||
1391 | if (skb) { | ||
1392 | char *newptr = strip_make_packet(ptr, strip_info, skb); | ||
1393 | strip_info->tx_pps_count++; | ||
1394 | if (!newptr) | ||
1395 | strip_info->tx_dropped++; | ||
1396 | else { | ||
1397 | ptr = newptr; | ||
1398 | strip_info->sx_pps_count++; | ||
1399 | strip_info->tx_packets++; /* Count another successful packet */ | ||
1400 | #ifdef EXT_COUNTERS | ||
1401 | strip_info->tx_bytes += skb->len; | ||
1402 | strip_info->tx_rbytes += ptr - strip_info->tx_buff; | ||
1403 | #endif | ||
1404 | /*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */ | ||
1405 | /*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */ | ||
1406 | } | ||
1407 | } | ||
1408 | |||
1409 | /* | ||
1410 | * 2. If it is time for another tickle, tack it on, after the packet | ||
1411 | */ | ||
1412 | if (doprobe) { | ||
1413 | StringDescriptor ts = CommandString[strip_info->next_command]; | ||
1414 | #if TICKLE_TIMERS | ||
1415 | { | ||
1416 | struct timeval tv; | ||
1417 | do_gettimeofday(&tv); | ||
1418 | printk(KERN_INFO "**** Sending tickle string %d at %02d.%06d\n", | ||
1419 | strip_info->next_command, tv.tv_sec % 100, | ||
1420 | tv.tv_usec); | ||
1421 | } | ||
1422 | #endif | ||
1423 | if (ptr == strip_info->tx_buff) | ||
1424 | *ptr++ = 0x0D; | ||
1425 | |||
1426 | *ptr++ = '*'; /* First send "**" to provoke an error message */ | ||
1427 | *ptr++ = '*'; | ||
1428 | |||
1429 | /* Then add the command */ | ||
1430 | memcpy(ptr, ts.string, ts.length); | ||
1431 | |||
1432 | /* Add a checksum ? */ | ||
1433 | if (strip_info->firmware_level < ChecksummedMessages) | ||
1434 | ptr += ts.length; | ||
1435 | else | ||
1436 | ptr = add_checksum(ptr, ptr + ts.length); | ||
1437 | |||
1438 | *ptr++ = 0x0D; /* Terminate the command with a <CR> */ | ||
1439 | |||
1440 | /* Cycle to next periodic command? */ | ||
1441 | if (strip_info->firmware_level >= StructuredMessages) | ||
1442 | if (++strip_info->next_command >= | ||
1443 | ARRAY_SIZE(CommandString)) | ||
1444 | strip_info->next_command = 0; | ||
1445 | #ifdef EXT_COUNTERS | ||
1446 | strip_info->tx_ebytes += ts.length; | ||
1447 | #endif | ||
1448 | strip_info->watchdog_doprobe = jiffies + 10 * HZ; | ||
1449 | strip_info->watchdog_doreset = jiffies + 1 * HZ; | ||
1450 | /*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */ | ||
1451 | } | ||
1452 | |||
1453 | /* | ||
1454 | * 3. Set up the strip_info ready to send the data (if any). | ||
1455 | */ | ||
1456 | strip_info->tx_head = strip_info->tx_buff; | ||
1457 | strip_info->tx_left = ptr - strip_info->tx_buff; | ||
1458 | strip_info->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP); | ||
1459 | |||
1460 | /* | ||
1461 | * 4. Debugging check to make sure we're not overflowing the buffer. | ||
1462 | */ | ||
1463 | if (strip_info->tx_size - strip_info->tx_left < 20) | ||
1464 | printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n", | ||
1465 | strip_info->dev->name, strip_info->tx_left, | ||
1466 | strip_info->tx_size - strip_info->tx_left); | ||
1467 | |||
1468 | /* | ||
1469 | * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in | ||
1470 | * the buffer, strip_write_some_more will send it after the reset has finished | ||
1471 | */ | ||
1472 | if (doreset) { | ||
1473 | ResetRadio(strip_info); | ||
1474 | return; | ||
1475 | } | ||
1476 | |||
1477 | if (1) { | ||
1478 | struct in_device *in_dev; | ||
1479 | |||
1480 | brd = addr = 0; | ||
1481 | rcu_read_lock(); | ||
1482 | in_dev = __in_dev_get_rcu(strip_info->dev); | ||
1483 | if (in_dev) { | ||
1484 | if (in_dev->ifa_list) { | ||
1485 | brd = in_dev->ifa_list->ifa_broadcast; | ||
1486 | addr = in_dev->ifa_list->ifa_local; | ||
1487 | } | ||
1488 | } | ||
1489 | rcu_read_unlock(); | ||
1490 | } | ||
1491 | |||
1492 | |||
1493 | /* | ||
1494 | * 6. If it is time for a periodic ARP, queue one up to be sent. | ||
1495 | * We only do this if: | ||
1496 | * 1. The radio is working | ||
1497 | * 2. It's time to send another periodic ARP | ||
1498 | * 3. We really know what our address is (and it is not manually set to zero) | ||
1499 | * 4. We have a designated broadcast address configured | ||
1500 | * If we queue up an ARP packet when we don't have a designated broadcast | ||
1501 | * address configured, then the packet will just have to be discarded in | ||
1502 | * strip_make_packet. This is not fatal, but it causes misleading information | ||
1503 | * to be displayed in tcpdump. tcpdump will report that periodic APRs are | ||
1504 | * being sent, when in fact they are not, because they are all being dropped | ||
1505 | * in the strip_make_packet routine. | ||
1506 | */ | ||
1507 | if (strip_info->working | ||
1508 | && (long) jiffies - strip_info->gratuitous_arp >= 0 | ||
1509 | && memcmp(strip_info->dev->dev_addr, zero_address.c, | ||
1510 | sizeof(zero_address)) | ||
1511 | && arp_query(haddr.c, brd, strip_info->dev)) { | ||
1512 | /*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n", | ||
1513 | strip_info->dev->name, strip_info->arp_interval / HZ); */ | ||
1514 | strip_info->gratuitous_arp = | ||
1515 | jiffies + strip_info->arp_interval; | ||
1516 | strip_info->arp_interval *= 2; | ||
1517 | if (strip_info->arp_interval > MaxARPInterval) | ||
1518 | strip_info->arp_interval = MaxARPInterval; | ||
1519 | if (addr) | ||
1520 | arp_send(ARPOP_REPLY, ETH_P_ARP, addr, /* Target address of ARP packet is our address */ | ||
1521 | strip_info->dev, /* Device to send packet on */ | ||
1522 | addr, /* Source IP address this ARP packet comes from */ | ||
1523 | NULL, /* Destination HW address is NULL (broadcast it) */ | ||
1524 | strip_info->dev->dev_addr, /* Source HW address is our HW address */ | ||
1525 | strip_info->dev->dev_addr); /* Target HW address is our HW address (redundant) */ | ||
1526 | } | ||
1527 | |||
1528 | /* | ||
1529 | * 7. All ready. Start the transmission | ||
1530 | */ | ||
1531 | strip_write_some_more(strip_info->tty); | ||
1532 | } | ||
1533 | |||
1534 | /* Encapsulate a datagram and kick it into a TTY queue. */ | ||
1535 | static int strip_xmit(struct sk_buff *skb, struct net_device *dev) | ||
1536 | { | ||
1537 | struct strip *strip_info = netdev_priv(dev); | ||
1538 | |||
1539 | if (!netif_running(dev)) { | ||
1540 | printk(KERN_ERR "%s: xmit call when iface is down\n", | ||
1541 | dev->name); | ||
1542 | return (1); | ||
1543 | } | ||
1544 | |||
1545 | netif_stop_queue(dev); | ||
1546 | |||
1547 | del_timer(&strip_info->idle_timer); | ||
1548 | |||
1549 | |||
1550 | if (time_after(jiffies, strip_info->pps_timer + HZ)) { | ||
1551 | unsigned long t = jiffies - strip_info->pps_timer; | ||
1552 | unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t; | ||
1553 | unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t; | ||
1554 | unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t; | ||
1555 | |||
1556 | strip_info->pps_timer = jiffies; | ||
1557 | strip_info->rx_pps_count = 0; | ||
1558 | strip_info->tx_pps_count = 0; | ||
1559 | strip_info->sx_pps_count = 0; | ||
1560 | |||
1561 | strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2; | ||
1562 | strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2; | ||
1563 | strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2; | ||
1564 | |||
1565 | if (rx_pps_count / 8 >= 10) | ||
1566 | printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n", | ||
1567 | strip_info->dev->name, rx_pps_count / 8); | ||
1568 | if (tx_pps_count / 8 >= 10) | ||
1569 | printk(KERN_INFO "%s: WARNING: Tx %ld packets per second.\n", | ||
1570 | strip_info->dev->name, tx_pps_count / 8); | ||
1571 | if (sx_pps_count / 8 >= 10) | ||
1572 | printk(KERN_INFO "%s: WARNING: Sending %ld packets per second.\n", | ||
1573 | strip_info->dev->name, sx_pps_count / 8); | ||
1574 | } | ||
1575 | |||
1576 | spin_lock_bh(&strip_lock); | ||
1577 | |||
1578 | strip_send(strip_info, skb); | ||
1579 | |||
1580 | spin_unlock_bh(&strip_lock); | ||
1581 | |||
1582 | if (skb) | ||
1583 | dev_kfree_skb(skb); | ||
1584 | return 0; | ||
1585 | } | ||
1586 | |||
1587 | /* | ||
1588 | * IdleTask periodically calls strip_xmit, so even when we have no IP packets | ||
1589 | * to send for an extended period of time, the watchdog processing still gets | ||
1590 | * done to ensure that the radio stays in Starmode | ||
1591 | */ | ||
1592 | |||
1593 | static void strip_IdleTask(unsigned long parameter) | ||
1594 | { | ||
1595 | strip_xmit(NULL, (struct net_device *) parameter); | ||
1596 | } | ||
1597 | |||
1598 | /* | ||
1599 | * Create the MAC header for an arbitrary protocol layer | ||
1600 | * | ||
1601 | * saddr!=NULL means use this specific address (n/a for Metricom) | ||
1602 | * saddr==NULL means use default device source address | ||
1603 | * daddr!=NULL means use this destination address | ||
1604 | * daddr==NULL means leave destination address alone | ||
1605 | * (e.g. unresolved arp -- kernel will call | ||
1606 | * rebuild_header later to fill in the address) | ||
1607 | */ | ||
1608 | |||
1609 | static int strip_header(struct sk_buff *skb, struct net_device *dev, | ||
1610 | unsigned short type, const void *daddr, | ||
1611 | const void *saddr, unsigned len) | ||
1612 | { | ||
1613 | struct strip *strip_info = netdev_priv(dev); | ||
1614 | STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header)); | ||
1615 | |||
1616 | /*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type, | ||
1617 | type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */ | ||
1618 | |||
1619 | header->src_addr = strip_info->true_dev_addr; | ||
1620 | header->protocol = htons(type); | ||
1621 | |||
1622 | /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */ | ||
1623 | |||
1624 | if (!daddr) | ||
1625 | return (-dev->hard_header_len); | ||
1626 | |||
1627 | header->dst_addr = *(MetricomAddress *) daddr; | ||
1628 | return (dev->hard_header_len); | ||
1629 | } | ||
1630 | |||
1631 | /* | ||
1632 | * Rebuild the MAC header. This is called after an ARP | ||
1633 | * (or in future other address resolution) has completed on this | ||
1634 | * sk_buff. We now let ARP fill in the other fields. | ||
1635 | * I think this should return zero if packet is ready to send, | ||
1636 | * or non-zero if it needs more time to do an address lookup | ||
1637 | */ | ||
1638 | |||
1639 | static int strip_rebuild_header(struct sk_buff *skb) | ||
1640 | { | ||
1641 | #ifdef CONFIG_INET | ||
1642 | STRIP_Header *header = (STRIP_Header *) skb->data; | ||
1643 | |||
1644 | /* Arp find returns zero if if knows the address, */ | ||
1645 | /* or if it doesn't know the address it sends an ARP packet and returns non-zero */ | ||
1646 | return arp_find(header->dst_addr.c, skb) ? 1 : 0; | ||
1647 | #else | ||
1648 | return 0; | ||
1649 | #endif | ||
1650 | } | ||
1651 | |||
1652 | |||
1653 | /************************************************************************/ | ||
1654 | /* Receiving routines */ | ||
1655 | |||
1656 | /* | ||
1657 | * This function parses the response to the ATS300? command, | ||
1658 | * extracting the radio version and serial number. | ||
1659 | */ | ||
1660 | static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end) | ||
1661 | { | ||
1662 | __u8 *p, *value_begin, *value_end; | ||
1663 | int len; | ||
1664 | |||
1665 | /* Determine the beginning of the second line of the payload */ | ||
1666 | p = ptr; | ||
1667 | while (p < end && *p != 10) | ||
1668 | p++; | ||
1669 | if (p >= end) | ||
1670 | return; | ||
1671 | p++; | ||
1672 | value_begin = p; | ||
1673 | |||
1674 | /* Determine the end of line */ | ||
1675 | while (p < end && *p != 10) | ||
1676 | p++; | ||
1677 | if (p >= end) | ||
1678 | return; | ||
1679 | value_end = p; | ||
1680 | p++; | ||
1681 | |||
1682 | len = value_end - value_begin; | ||
1683 | len = min_t(int, len, sizeof(FirmwareVersion) - 1); | ||
1684 | if (strip_info->firmware_version.c[0] == 0) | ||
1685 | printk(KERN_INFO "%s: Radio Firmware: %.*s\n", | ||
1686 | strip_info->dev->name, len, value_begin); | ||
1687 | sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin); | ||
1688 | |||
1689 | /* Look for the first colon */ | ||
1690 | while (p < end && *p != ':') | ||
1691 | p++; | ||
1692 | if (p >= end) | ||
1693 | return; | ||
1694 | /* Skip over the space */ | ||
1695 | p += 2; | ||
1696 | len = sizeof(SerialNumber) - 1; | ||
1697 | if (p + len <= end) { | ||
1698 | sprintf(strip_info->serial_number.c, "%.*s", len, p); | ||
1699 | } else { | ||
1700 | printk(KERN_DEBUG | ||
1701 | "STRIP: radio serial number shorter (%zd) than expected (%d)\n", | ||
1702 | end - p, len); | ||
1703 | } | ||
1704 | } | ||
1705 | |||
1706 | /* | ||
1707 | * This function parses the response to the ATS325? command, | ||
1708 | * extracting the radio battery voltage. | ||
1709 | */ | ||
1710 | static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end) | ||
1711 | { | ||
1712 | int len; | ||
1713 | |||
1714 | len = sizeof(BatteryVoltage) - 1; | ||
1715 | if (ptr + len <= end) { | ||
1716 | sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr); | ||
1717 | } else { | ||
1718 | printk(KERN_DEBUG | ||
1719 | "STRIP: radio voltage string shorter (%zd) than expected (%d)\n", | ||
1720 | end - ptr, len); | ||
1721 | } | ||
1722 | } | ||
1723 | |||
1724 | /* | ||
1725 | * This function parses the responses to the AT~LA and ATS311 commands, | ||
1726 | * which list the radio's neighbours. | ||
1727 | */ | ||
1728 | static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end) | ||
1729 | { | ||
1730 | table->num_nodes = 0; | ||
1731 | while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) { | ||
1732 | MetricomNode *node = &table->node[table->num_nodes++]; | ||
1733 | char *dst = node->c, *limit = dst + sizeof(*node) - 1; | ||
1734 | while (ptr < end && *ptr <= 32) | ||
1735 | ptr++; | ||
1736 | while (ptr < end && dst < limit && *ptr != 10) | ||
1737 | *dst++ = *ptr++; | ||
1738 | *dst++ = 0; | ||
1739 | while (ptr < end && ptr[-1] != 10) | ||
1740 | ptr++; | ||
1741 | } | ||
1742 | do_gettimeofday(&table->timestamp); | ||
1743 | } | ||
1744 | |||
1745 | static int get_radio_address(struct strip *strip_info, __u8 * p) | ||
1746 | { | ||
1747 | MetricomAddress addr; | ||
1748 | |||
1749 | if (string_to_radio_address(&addr, p)) | ||
1750 | return (1); | ||
1751 | |||
1752 | /* See if our radio address has changed */ | ||
1753 | if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) { | ||
1754 | MetricomAddressString addr_string; | ||
1755 | radio_address_to_string(&addr, &addr_string); | ||
1756 | printk(KERN_INFO "%s: Radio address = %s\n", | ||
1757 | strip_info->dev->name, addr_string.c); | ||
1758 | strip_info->true_dev_addr = addr; | ||
1759 | if (!strip_info->manual_dev_addr) | ||
1760 | *(MetricomAddress *) strip_info->dev->dev_addr = | ||
1761 | addr; | ||
1762 | /* Give the radio a few seconds to get its head straight, then send an arp */ | ||
1763 | strip_info->gratuitous_arp = jiffies + 15 * HZ; | ||
1764 | strip_info->arp_interval = 1 * HZ; | ||
1765 | } | ||
1766 | return (0); | ||
1767 | } | ||
1768 | |||
1769 | static int verify_checksum(struct strip *strip_info) | ||
1770 | { | ||
1771 | __u8 *p = strip_info->sx_buff; | ||
1772 | __u8 *end = strip_info->sx_buff + strip_info->sx_count - 4; | ||
1773 | u_short sum = | ||
1774 | (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) | | ||
1775 | (READHEX16(end[2]) << 4) | (READHEX16(end[3])); | ||
1776 | while (p < end) | ||
1777 | sum -= *p++; | ||
1778 | if (sum == 0 && strip_info->firmware_level == StructuredMessages) { | ||
1779 | strip_info->firmware_level = ChecksummedMessages; | ||
1780 | printk(KERN_INFO "%s: Radio provides message checksums\n", | ||
1781 | strip_info->dev->name); | ||
1782 | } | ||
1783 | return (sum == 0); | ||
1784 | } | ||
1785 | |||
1786 | static void RecvErr(char *msg, struct strip *strip_info) | ||
1787 | { | ||
1788 | __u8 *ptr = strip_info->sx_buff; | ||
1789 | __u8 *end = strip_info->sx_buff + strip_info->sx_count; | ||
1790 | DumpData(msg, strip_info, ptr, end); | ||
1791 | strip_info->rx_errors++; | ||
1792 | } | ||
1793 | |||
1794 | static void RecvErr_Message(struct strip *strip_info, __u8 * sendername, | ||
1795 | const __u8 * msg, u_long len) | ||
1796 | { | ||
1797 | if (has_prefix(msg, len, "001")) { /* Not in StarMode! */ | ||
1798 | RecvErr("Error Msg:", strip_info); | ||
1799 | printk(KERN_INFO "%s: Radio %s is not in StarMode\n", | ||
1800 | strip_info->dev->name, sendername); | ||
1801 | } | ||
1802 | |||
1803 | else if (has_prefix(msg, len, "002")) { /* Remap handle */ | ||
1804 | /* We ignore "Remap handle" messages for now */ | ||
1805 | } | ||
1806 | |||
1807 | else if (has_prefix(msg, len, "003")) { /* Can't resolve name */ | ||
1808 | RecvErr("Error Msg:", strip_info); | ||
1809 | printk(KERN_INFO "%s: Destination radio name is unknown\n", | ||
1810 | strip_info->dev->name); | ||
1811 | } | ||
1812 | |||
1813 | else if (has_prefix(msg, len, "004")) { /* Name too small or missing */ | ||
1814 | strip_info->watchdog_doreset = jiffies + LongTime; | ||
1815 | #if TICKLE_TIMERS | ||
1816 | { | ||
1817 | struct timeval tv; | ||
1818 | do_gettimeofday(&tv); | ||
1819 | printk(KERN_INFO | ||
1820 | "**** Got ERR_004 response at %02d.%06d\n", | ||
1821 | tv.tv_sec % 100, tv.tv_usec); | ||
1822 | } | ||
1823 | #endif | ||
1824 | if (!strip_info->working) { | ||
1825 | strip_info->working = TRUE; | ||
1826 | printk(KERN_INFO "%s: Radio now in starmode\n", | ||
1827 | strip_info->dev->name); | ||
1828 | /* | ||
1829 | * If the radio has just entered a working state, we should do our first | ||
1830 | * probe ASAP, so that we find out our radio address etc. without delay. | ||
1831 | */ | ||
1832 | strip_info->watchdog_doprobe = jiffies; | ||
1833 | } | ||
1834 | if (strip_info->firmware_level == NoStructure && sendername) { | ||
1835 | strip_info->firmware_level = StructuredMessages; | ||
1836 | strip_info->next_command = 0; /* Try to enable checksums ASAP */ | ||
1837 | printk(KERN_INFO | ||
1838 | "%s: Radio provides structured messages\n", | ||
1839 | strip_info->dev->name); | ||
1840 | } | ||
1841 | if (strip_info->firmware_level >= StructuredMessages) { | ||
1842 | /* | ||
1843 | * If this message has a valid checksum on the end, then the call to verify_checksum | ||
1844 | * will elevate the firmware_level to ChecksummedMessages for us. (The actual return | ||
1845 | * code from verify_checksum is ignored here.) | ||
1846 | */ | ||
1847 | verify_checksum(strip_info); | ||
1848 | /* | ||
1849 | * If the radio has structured messages but we don't yet have all our information about it, | ||
1850 | * we should do probes without delay, until we have gathered all the information | ||
1851 | */ | ||
1852 | if (!GOT_ALL_RADIO_INFO(strip_info)) | ||
1853 | strip_info->watchdog_doprobe = jiffies; | ||
1854 | } | ||
1855 | } | ||
1856 | |||
1857 | else if (has_prefix(msg, len, "005")) /* Bad count specification */ | ||
1858 | RecvErr("Error Msg:", strip_info); | ||
1859 | |||
1860 | else if (has_prefix(msg, len, "006")) /* Header too big */ | ||
1861 | RecvErr("Error Msg:", strip_info); | ||
1862 | |||
1863 | else if (has_prefix(msg, len, "007")) { /* Body too big */ | ||
1864 | RecvErr("Error Msg:", strip_info); | ||
1865 | printk(KERN_ERR | ||
1866 | "%s: Error! Packet size too big for radio.\n", | ||
1867 | strip_info->dev->name); | ||
1868 | } | ||
1869 | |||
1870 | else if (has_prefix(msg, len, "008")) { /* Bad character in name */ | ||
1871 | RecvErr("Error Msg:", strip_info); | ||
1872 | printk(KERN_ERR | ||
1873 | "%s: Radio name contains illegal character\n", | ||
1874 | strip_info->dev->name); | ||
1875 | } | ||
1876 | |||
1877 | else if (has_prefix(msg, len, "009")) /* No count or line terminator */ | ||
1878 | RecvErr("Error Msg:", strip_info); | ||
1879 | |||
1880 | else if (has_prefix(msg, len, "010")) /* Invalid checksum */ | ||
1881 | RecvErr("Error Msg:", strip_info); | ||
1882 | |||
1883 | else if (has_prefix(msg, len, "011")) /* Checksum didn't match */ | ||
1884 | RecvErr("Error Msg:", strip_info); | ||
1885 | |||
1886 | else if (has_prefix(msg, len, "012")) /* Failed to transmit packet */ | ||
1887 | RecvErr("Error Msg:", strip_info); | ||
1888 | |||
1889 | else | ||
1890 | RecvErr("Error Msg:", strip_info); | ||
1891 | } | ||
1892 | |||
1893 | static void process_AT_response(struct strip *strip_info, __u8 * ptr, | ||
1894 | __u8 * end) | ||
1895 | { | ||
1896 | u_long len; | ||
1897 | __u8 *p = ptr; | ||
1898 | while (p < end && p[-1] != 10) | ||
1899 | p++; /* Skip past first newline character */ | ||
1900 | /* Now ptr points to the AT command, and p points to the text of the response. */ | ||
1901 | len = p - ptr; | ||
1902 | |||
1903 | #if TICKLE_TIMERS | ||
1904 | { | ||
1905 | struct timeval tv; | ||
1906 | do_gettimeofday(&tv); | ||
1907 | printk(KERN_INFO "**** Got AT response %.7s at %02d.%06d\n", | ||
1908 | ptr, tv.tv_sec % 100, tv.tv_usec); | ||
1909 | } | ||
1910 | #endif | ||
1911 | |||
1912 | if (has_prefix(ptr, len, "ATS300?")) | ||
1913 | get_radio_version(strip_info, p, end); | ||
1914 | else if (has_prefix(ptr, len, "ATS305?")) | ||
1915 | get_radio_address(strip_info, p); | ||
1916 | else if (has_prefix(ptr, len, "ATS311?")) | ||
1917 | get_radio_neighbours(&strip_info->poletops, p, end); | ||
1918 | else if (has_prefix(ptr, len, "ATS319=7")) | ||
1919 | verify_checksum(strip_info); | ||
1920 | else if (has_prefix(ptr, len, "ATS325?")) | ||
1921 | get_radio_voltage(strip_info, p, end); | ||
1922 | else if (has_prefix(ptr, len, "AT~LA")) | ||
1923 | get_radio_neighbours(&strip_info->portables, p, end); | ||
1924 | else | ||
1925 | RecvErr("Unknown AT Response:", strip_info); | ||
1926 | } | ||
1927 | |||
1928 | static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end) | ||
1929 | { | ||
1930 | /* Currently we don't do anything with ACKs from the radio */ | ||
1931 | } | ||
1932 | |||
1933 | static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end) | ||
1934 | { | ||
1935 | if (ptr + 16 > end) | ||
1936 | RecvErr("Bad Info Msg:", strip_info); | ||
1937 | } | ||
1938 | |||
1939 | static struct net_device *get_strip_dev(struct strip *strip_info) | ||
1940 | { | ||
1941 | /* If our hardware address is *manually set* to zero, and we know our */ | ||
1942 | /* real radio hardware address, try to find another strip device that has been */ | ||
1943 | /* manually set to that address that we can 'transfer ownership' of this packet to */ | ||
1944 | if (strip_info->manual_dev_addr && | ||
1945 | !memcmp(strip_info->dev->dev_addr, zero_address.c, | ||
1946 | sizeof(zero_address)) | ||
1947 | && memcmp(&strip_info->true_dev_addr, zero_address.c, | ||
1948 | sizeof(zero_address))) { | ||
1949 | struct net_device *dev; | ||
1950 | read_lock_bh(&dev_base_lock); | ||
1951 | for_each_netdev(&init_net, dev) { | ||
1952 | if (dev->type == strip_info->dev->type && | ||
1953 | !memcmp(dev->dev_addr, | ||
1954 | &strip_info->true_dev_addr, | ||
1955 | sizeof(MetricomAddress))) { | ||
1956 | printk(KERN_INFO | ||
1957 | "%s: Transferred packet ownership to %s.\n", | ||
1958 | strip_info->dev->name, dev->name); | ||
1959 | read_unlock_bh(&dev_base_lock); | ||
1960 | return (dev); | ||
1961 | } | ||
1962 | } | ||
1963 | read_unlock_bh(&dev_base_lock); | ||
1964 | } | ||
1965 | return (strip_info->dev); | ||
1966 | } | ||
1967 | |||
1968 | /* | ||
1969 | * Send one completely decapsulated datagram to the next layer. | ||
1970 | */ | ||
1971 | |||
1972 | static void deliver_packet(struct strip *strip_info, STRIP_Header * header, | ||
1973 | __u16 packetlen) | ||
1974 | { | ||
1975 | struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen); | ||
1976 | if (!skb) { | ||
1977 | printk(KERN_ERR "%s: memory squeeze, dropping packet.\n", | ||
1978 | strip_info->dev->name); | ||
1979 | strip_info->rx_dropped++; | ||
1980 | } else { | ||
1981 | memcpy(skb_put(skb, sizeof(STRIP_Header)), header, | ||
1982 | sizeof(STRIP_Header)); | ||
1983 | memcpy(skb_put(skb, packetlen), strip_info->rx_buff, | ||
1984 | packetlen); | ||
1985 | skb->dev = get_strip_dev(strip_info); | ||
1986 | skb->protocol = header->protocol; | ||
1987 | skb_reset_mac_header(skb); | ||
1988 | |||
1989 | /* Having put a fake header on the front of the sk_buff for the */ | ||
1990 | /* benefit of tools like tcpdump, skb_pull now 'consumes' that */ | ||
1991 | /* fake header before we hand the packet up to the next layer. */ | ||
1992 | skb_pull(skb, sizeof(STRIP_Header)); | ||
1993 | |||
1994 | /* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */ | ||
1995 | strip_info->rx_packets++; | ||
1996 | strip_info->rx_pps_count++; | ||
1997 | #ifdef EXT_COUNTERS | ||
1998 | strip_info->rx_bytes += packetlen; | ||
1999 | #endif | ||
2000 | skb->dev->last_rx = jiffies; | ||
2001 | netif_rx(skb); | ||
2002 | } | ||
2003 | } | ||
2004 | |||
2005 | static void process_IP_packet(struct strip *strip_info, | ||
2006 | STRIP_Header * header, __u8 * ptr, | ||
2007 | __u8 * end) | ||
2008 | { | ||
2009 | __u16 packetlen; | ||
2010 | |||
2011 | /* Decode start of the IP packet header */ | ||
2012 | ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4); | ||
2013 | if (!ptr) { | ||
2014 | RecvErr("IP Packet too short", strip_info); | ||
2015 | return; | ||
2016 | } | ||
2017 | |||
2018 | packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3]; | ||
2019 | |||
2020 | if (packetlen > MAX_RECV_MTU) { | ||
2021 | printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n", | ||
2022 | strip_info->dev->name, packetlen); | ||
2023 | strip_info->rx_dropped++; | ||
2024 | return; | ||
2025 | } | ||
2026 | |||
2027 | /*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */ | ||
2028 | |||
2029 | /* Decode remainder of the IP packet */ | ||
2030 | ptr = | ||
2031 | UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4); | ||
2032 | if (!ptr) { | ||
2033 | RecvErr("IP Packet too short", strip_info); | ||
2034 | return; | ||
2035 | } | ||
2036 | |||
2037 | if (ptr < end) { | ||
2038 | RecvErr("IP Packet too long", strip_info); | ||
2039 | return; | ||
2040 | } | ||
2041 | |||
2042 | header->protocol = htons(ETH_P_IP); | ||
2043 | |||
2044 | deliver_packet(strip_info, header, packetlen); | ||
2045 | } | ||
2046 | |||
2047 | static void process_ARP_packet(struct strip *strip_info, | ||
2048 | STRIP_Header * header, __u8 * ptr, | ||
2049 | __u8 * end) | ||
2050 | { | ||
2051 | __u16 packetlen; | ||
2052 | struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff; | ||
2053 | |||
2054 | /* Decode start of the ARP packet */ | ||
2055 | ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8); | ||
2056 | if (!ptr) { | ||
2057 | RecvErr("ARP Packet too short", strip_info); | ||
2058 | return; | ||
2059 | } | ||
2060 | |||
2061 | packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2; | ||
2062 | |||
2063 | if (packetlen > MAX_RECV_MTU) { | ||
2064 | printk(KERN_INFO | ||
2065 | "%s: Dropping oversized received ARP packet: %d bytes\n", | ||
2066 | strip_info->dev->name, packetlen); | ||
2067 | strip_info->rx_dropped++; | ||
2068 | return; | ||
2069 | } | ||
2070 | |||
2071 | /*printk(KERN_INFO "%s: Got %d byte ARP %s\n", | ||
2072 | strip_info->dev->name, packetlen, | ||
2073 | ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */ | ||
2074 | |||
2075 | /* Decode remainder of the ARP packet */ | ||
2076 | ptr = | ||
2077 | UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8); | ||
2078 | if (!ptr) { | ||
2079 | RecvErr("ARP Packet too short", strip_info); | ||
2080 | return; | ||
2081 | } | ||
2082 | |||
2083 | if (ptr < end) { | ||
2084 | RecvErr("ARP Packet too long", strip_info); | ||
2085 | return; | ||
2086 | } | ||
2087 | |||
2088 | header->protocol = htons(ETH_P_ARP); | ||
2089 | |||
2090 | deliver_packet(strip_info, header, packetlen); | ||
2091 | } | ||
2092 | |||
2093 | /* | ||
2094 | * process_text_message processes a <CR>-terminated block of data received | ||
2095 | * from the radio that doesn't begin with a '*' character. All normal | ||
2096 | * Starmode communication messages with the radio begin with a '*', | ||
2097 | * so any text that does not indicates a serial port error, a radio that | ||
2098 | * is in Hayes command mode instead of Starmode, or a radio with really | ||
2099 | * old firmware that doesn't frame its Starmode responses properly. | ||
2100 | */ | ||
2101 | static void process_text_message(struct strip *strip_info) | ||
2102 | { | ||
2103 | __u8 *msg = strip_info->sx_buff; | ||
2104 | int len = strip_info->sx_count; | ||
2105 | |||
2106 | /* Check for anything that looks like it might be our radio name */ | ||
2107 | /* (This is here for backwards compatibility with old firmware) */ | ||
2108 | if (len == 9 && get_radio_address(strip_info, msg) == 0) | ||
2109 | return; | ||
2110 | |||
2111 | if (text_equal(msg, len, "OK")) | ||
2112 | return; /* Ignore 'OK' responses from prior commands */ | ||
2113 | if (text_equal(msg, len, "ERROR")) | ||
2114 | return; /* Ignore 'ERROR' messages */ | ||
2115 | if (has_prefix(msg, len, "ate0q1")) | ||
2116 | return; /* Ignore character echo back from the radio */ | ||
2117 | |||
2118 | /* Catch other error messages */ | ||
2119 | /* (This is here for backwards compatibility with old firmware) */ | ||
2120 | if (has_prefix(msg, len, "ERR_")) { | ||
2121 | RecvErr_Message(strip_info, NULL, &msg[4], len - 4); | ||
2122 | return; | ||
2123 | } | ||
2124 | |||
2125 | RecvErr("No initial *", strip_info); | ||
2126 | } | ||
2127 | |||
2128 | /* | ||
2129 | * process_message processes a <CR>-terminated block of data received | ||
2130 | * from the radio. If the radio is not in Starmode or has old firmware, | ||
2131 | * it may be a line of text in response to an AT command. Ideally, with | ||
2132 | * a current radio that's properly in Starmode, all data received should | ||
2133 | * be properly framed and checksummed radio message blocks, containing | ||
2134 | * either a starmode packet, or a other communication from the radio | ||
2135 | * firmware, like "INF_" Info messages and &COMMAND responses. | ||
2136 | */ | ||
2137 | static void process_message(struct strip *strip_info) | ||
2138 | { | ||
2139 | STRIP_Header header = { zero_address, zero_address, 0 }; | ||
2140 | __u8 *ptr = strip_info->sx_buff; | ||
2141 | __u8 *end = strip_info->sx_buff + strip_info->sx_count; | ||
2142 | __u8 sendername[32], *sptr = sendername; | ||
2143 | MetricomKey key; | ||
2144 | |||
2145 | /*HexDump("Receiving", strip_info, ptr, end); */ | ||
2146 | |||
2147 | /* Check for start of address marker, and then skip over it */ | ||
2148 | if (*ptr == '*') | ||
2149 | ptr++; | ||
2150 | else { | ||
2151 | process_text_message(strip_info); | ||
2152 | return; | ||
2153 | } | ||
2154 | |||
2155 | /* Copy out the return address */ | ||
2156 | while (ptr < end && *ptr != '*' | ||
2157 | && sptr < ARRAY_END(sendername) - 1) | ||
2158 | *sptr++ = *ptr++; | ||
2159 | *sptr = 0; /* Null terminate the sender name */ | ||
2160 | |||
2161 | /* Check for end of address marker, and skip over it */ | ||
2162 | if (ptr >= end || *ptr != '*') { | ||
2163 | RecvErr("No second *", strip_info); | ||
2164 | return; | ||
2165 | } | ||
2166 | ptr++; /* Skip the second '*' */ | ||
2167 | |||
2168 | /* If the sender name is "&COMMAND", ignore this 'packet' */ | ||
2169 | /* (This is here for backwards compatibility with old firmware) */ | ||
2170 | if (!strcmp(sendername, "&COMMAND")) { | ||
2171 | strip_info->firmware_level = NoStructure; | ||
2172 | strip_info->next_command = CompatibilityCommand; | ||
2173 | return; | ||
2174 | } | ||
2175 | |||
2176 | if (ptr + 4 > end) { | ||
2177 | RecvErr("No proto key", strip_info); | ||
2178 | return; | ||
2179 | } | ||
2180 | |||
2181 | /* Get the protocol key out of the buffer */ | ||
2182 | key.c[0] = *ptr++; | ||
2183 | key.c[1] = *ptr++; | ||
2184 | key.c[2] = *ptr++; | ||
2185 | key.c[3] = *ptr++; | ||
2186 | |||
2187 | /* If we're using checksums, verify the checksum at the end of the packet */ | ||
2188 | if (strip_info->firmware_level >= ChecksummedMessages) { | ||
2189 | end -= 4; /* Chop the last four bytes off the packet (they're the checksum) */ | ||
2190 | if (ptr > end) { | ||
2191 | RecvErr("Missing Checksum", strip_info); | ||
2192 | return; | ||
2193 | } | ||
2194 | if (!verify_checksum(strip_info)) { | ||
2195 | RecvErr("Bad Checksum", strip_info); | ||
2196 | return; | ||
2197 | } | ||
2198 | } | ||
2199 | |||
2200 | /*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */ | ||
2201 | |||
2202 | /* | ||
2203 | * Fill in (pseudo) source and destination addresses in the packet. | ||
2204 | * We assume that the destination address was our address (the radio does not | ||
2205 | * tell us this). If the radio supplies a source address, then we use it. | ||
2206 | */ | ||
2207 | header.dst_addr = strip_info->true_dev_addr; | ||
2208 | string_to_radio_address(&header.src_addr, sendername); | ||
2209 | |||
2210 | #ifdef EXT_COUNTERS | ||
2211 | if (key.l == SIP0Key.l) { | ||
2212 | strip_info->rx_rbytes += (end - ptr); | ||
2213 | process_IP_packet(strip_info, &header, ptr, end); | ||
2214 | } else if (key.l == ARP0Key.l) { | ||
2215 | strip_info->rx_rbytes += (end - ptr); | ||
2216 | process_ARP_packet(strip_info, &header, ptr, end); | ||
2217 | } else if (key.l == ATR_Key.l) { | ||
2218 | strip_info->rx_ebytes += (end - ptr); | ||
2219 | process_AT_response(strip_info, ptr, end); | ||
2220 | } else if (key.l == ACK_Key.l) { | ||
2221 | strip_info->rx_ebytes += (end - ptr); | ||
2222 | process_ACK(strip_info, ptr, end); | ||
2223 | } else if (key.l == INF_Key.l) { | ||
2224 | strip_info->rx_ebytes += (end - ptr); | ||
2225 | process_Info(strip_info, ptr, end); | ||
2226 | } else if (key.l == ERR_Key.l) { | ||
2227 | strip_info->rx_ebytes += (end - ptr); | ||
2228 | RecvErr_Message(strip_info, sendername, ptr, end - ptr); | ||
2229 | } else | ||
2230 | RecvErr("Unrecognized protocol key", strip_info); | ||
2231 | #else | ||
2232 | if (key.l == SIP0Key.l) | ||
2233 | process_IP_packet(strip_info, &header, ptr, end); | ||
2234 | else if (key.l == ARP0Key.l) | ||
2235 | process_ARP_packet(strip_info, &header, ptr, end); | ||
2236 | else if (key.l == ATR_Key.l) | ||
2237 | process_AT_response(strip_info, ptr, end); | ||
2238 | else if (key.l == ACK_Key.l) | ||
2239 | process_ACK(strip_info, ptr, end); | ||
2240 | else if (key.l == INF_Key.l) | ||
2241 | process_Info(strip_info, ptr, end); | ||
2242 | else if (key.l == ERR_Key.l) | ||
2243 | RecvErr_Message(strip_info, sendername, ptr, end - ptr); | ||
2244 | else | ||
2245 | RecvErr("Unrecognized protocol key", strip_info); | ||
2246 | #endif | ||
2247 | } | ||
2248 | |||
2249 | #define TTYERROR(X) ((X) == TTY_BREAK ? "Break" : \ | ||
2250 | (X) == TTY_FRAME ? "Framing Error" : \ | ||
2251 | (X) == TTY_PARITY ? "Parity Error" : \ | ||
2252 | (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error") | ||
2253 | |||
2254 | /* | ||
2255 | * Handle the 'receiver data ready' interrupt. | ||
2256 | * This function is called by the 'tty_io' module in the kernel when | ||
2257 | * a block of STRIP data has been received, which can now be decapsulated | ||
2258 | * and sent on to some IP layer for further processing. | ||
2259 | */ | ||
2260 | |||
2261 | static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, | ||
2262 | char *fp, int count) | ||
2263 | { | ||
2264 | struct strip *strip_info = (struct strip *) tty->disc_data; | ||
2265 | const unsigned char *end = cp + count; | ||
2266 | |||
2267 | if (!strip_info || strip_info->magic != STRIP_MAGIC | ||
2268 | || !netif_running(strip_info->dev)) | ||
2269 | return; | ||
2270 | |||
2271 | spin_lock_bh(&strip_lock); | ||
2272 | #if 0 | ||
2273 | { | ||
2274 | struct timeval tv; | ||
2275 | do_gettimeofday(&tv); | ||
2276 | printk(KERN_INFO | ||
2277 | "**** strip_receive_buf: %3d bytes at %02d.%06d\n", | ||
2278 | count, tv.tv_sec % 100, tv.tv_usec); | ||
2279 | } | ||
2280 | #endif | ||
2281 | |||
2282 | #ifdef EXT_COUNTERS | ||
2283 | strip_info->rx_sbytes += count; | ||
2284 | #endif | ||
2285 | |||
2286 | /* Read the characters out of the buffer */ | ||
2287 | while (cp < end) { | ||
2288 | if (fp && *fp) | ||
2289 | printk(KERN_INFO "%s: %s on serial port\n", | ||
2290 | strip_info->dev->name, TTYERROR(*fp)); | ||
2291 | if (fp && *fp++ && !strip_info->discard) { /* If there's a serial error, record it */ | ||
2292 | /* If we have some characters in the buffer, discard them */ | ||
2293 | strip_info->discard = strip_info->sx_count; | ||
2294 | strip_info->rx_errors++; | ||
2295 | } | ||
2296 | |||
2297 | /* Leading control characters (CR, NL, Tab, etc.) are ignored */ | ||
2298 | if (strip_info->sx_count > 0 || *cp >= ' ') { | ||
2299 | if (*cp == 0x0D) { /* If end of packet, decide what to do with it */ | ||
2300 | if (strip_info->sx_count > 3000) | ||
2301 | printk(KERN_INFO | ||
2302 | "%s: Cut a %d byte packet (%zd bytes remaining)%s\n", | ||
2303 | strip_info->dev->name, | ||
2304 | strip_info->sx_count, | ||
2305 | end - cp - 1, | ||
2306 | strip_info-> | ||
2307 | discard ? " (discarded)" : | ||
2308 | ""); | ||
2309 | if (strip_info->sx_count > | ||
2310 | strip_info->sx_size) { | ||
2311 | strip_info->rx_over_errors++; | ||
2312 | printk(KERN_INFO | ||
2313 | "%s: sx_buff overflow (%d bytes total)\n", | ||
2314 | strip_info->dev->name, | ||
2315 | strip_info->sx_count); | ||
2316 | } else if (strip_info->discard) | ||
2317 | printk(KERN_INFO | ||
2318 | "%s: Discarding bad packet (%d/%d)\n", | ||
2319 | strip_info->dev->name, | ||
2320 | strip_info->discard, | ||
2321 | strip_info->sx_count); | ||
2322 | else | ||
2323 | process_message(strip_info); | ||
2324 | strip_info->discard = 0; | ||
2325 | strip_info->sx_count = 0; | ||
2326 | } else { | ||
2327 | /* Make sure we have space in the buffer */ | ||
2328 | if (strip_info->sx_count < | ||
2329 | strip_info->sx_size) | ||
2330 | strip_info->sx_buff[strip_info-> | ||
2331 | sx_count] = | ||
2332 | *cp; | ||
2333 | strip_info->sx_count++; | ||
2334 | } | ||
2335 | } | ||
2336 | cp++; | ||
2337 | } | ||
2338 | spin_unlock_bh(&strip_lock); | ||
2339 | } | ||
2340 | |||
2341 | |||
2342 | /************************************************************************/ | ||
2343 | /* General control routines */ | ||
2344 | |||
2345 | static int set_mac_address(struct strip *strip_info, | ||
2346 | MetricomAddress * addr) | ||
2347 | { | ||
2348 | /* | ||
2349 | * We're using a manually specified address if the address is set | ||
2350 | * to anything other than all ones. Setting the address to all ones | ||
2351 | * disables manual mode and goes back to automatic address determination | ||
2352 | * (tracking the true address that the radio has). | ||
2353 | */ | ||
2354 | strip_info->manual_dev_addr = | ||
2355 | memcmp(addr->c, broadcast_address.c, | ||
2356 | sizeof(broadcast_address)); | ||
2357 | if (strip_info->manual_dev_addr) | ||
2358 | *(MetricomAddress *) strip_info->dev->dev_addr = *addr; | ||
2359 | else | ||
2360 | *(MetricomAddress *) strip_info->dev->dev_addr = | ||
2361 | strip_info->true_dev_addr; | ||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2365 | static int strip_set_mac_address(struct net_device *dev, void *addr) | ||
2366 | { | ||
2367 | struct strip *strip_info = netdev_priv(dev); | ||
2368 | struct sockaddr *sa = addr; | ||
2369 | printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name); | ||
2370 | set_mac_address(strip_info, (MetricomAddress *) sa->sa_data); | ||
2371 | return 0; | ||
2372 | } | ||
2373 | |||
2374 | static struct net_device_stats *strip_get_stats(struct net_device *dev) | ||
2375 | { | ||
2376 | struct strip *strip_info = netdev_priv(dev); | ||
2377 | static struct net_device_stats stats; | ||
2378 | |||
2379 | memset(&stats, 0, sizeof(struct net_device_stats)); | ||
2380 | |||
2381 | stats.rx_packets = strip_info->rx_packets; | ||
2382 | stats.tx_packets = strip_info->tx_packets; | ||
2383 | stats.rx_dropped = strip_info->rx_dropped; | ||
2384 | stats.tx_dropped = strip_info->tx_dropped; | ||
2385 | stats.tx_errors = strip_info->tx_errors; | ||
2386 | stats.rx_errors = strip_info->rx_errors; | ||
2387 | stats.rx_over_errors = strip_info->rx_over_errors; | ||
2388 | return (&stats); | ||
2389 | } | ||
2390 | |||
2391 | |||
2392 | /************************************************************************/ | ||
2393 | /* Opening and closing */ | ||
2394 | |||
2395 | /* | ||
2396 | * Here's the order things happen: | ||
2397 | * When the user runs "slattach -p strip ..." | ||
2398 | * 1. The TTY module calls strip_open;; | ||
2399 | * 2. strip_open calls strip_alloc | ||
2400 | * 3. strip_alloc calls register_netdev | ||
2401 | * 4. register_netdev calls strip_dev_init | ||
2402 | * 5. then strip_open finishes setting up the strip_info | ||
2403 | * | ||
2404 | * When the user runs "ifconfig st<x> up address netmask ..." | ||
2405 | * 6. strip_open_low gets called | ||
2406 | * | ||
2407 | * When the user runs "ifconfig st<x> down" | ||
2408 | * 7. strip_close_low gets called | ||
2409 | * | ||
2410 | * When the user kills the slattach process | ||
2411 | * 8. strip_close gets called | ||
2412 | * 9. strip_close calls dev_close | ||
2413 | * 10. if the device is still up, then dev_close calls strip_close_low | ||
2414 | * 11. strip_close calls strip_free | ||
2415 | */ | ||
2416 | |||
2417 | /* Open the low-level part of the STRIP channel. Easy! */ | ||
2418 | |||
2419 | static int strip_open_low(struct net_device *dev) | ||
2420 | { | ||
2421 | struct strip *strip_info = netdev_priv(dev); | ||
2422 | |||
2423 | if (strip_info->tty == NULL) | ||
2424 | return (-ENODEV); | ||
2425 | |||
2426 | if (!allocate_buffers(strip_info, dev->mtu)) | ||
2427 | return (-ENOMEM); | ||
2428 | |||
2429 | strip_info->sx_count = 0; | ||
2430 | strip_info->tx_left = 0; | ||
2431 | |||
2432 | strip_info->discard = 0; | ||
2433 | strip_info->working = FALSE; | ||
2434 | strip_info->firmware_level = NoStructure; | ||
2435 | strip_info->next_command = CompatibilityCommand; | ||
2436 | strip_info->user_baud = tty_get_baud_rate(strip_info->tty); | ||
2437 | |||
2438 | printk(KERN_INFO "%s: Initializing Radio.\n", | ||
2439 | strip_info->dev->name); | ||
2440 | ResetRadio(strip_info); | ||
2441 | strip_info->idle_timer.expires = jiffies + 1 * HZ; | ||
2442 | add_timer(&strip_info->idle_timer); | ||
2443 | netif_wake_queue(dev); | ||
2444 | return (0); | ||
2445 | } | ||
2446 | |||
2447 | |||
2448 | /* | ||
2449 | * Close the low-level part of the STRIP channel. Easy! | ||
2450 | */ | ||
2451 | |||
2452 | static int strip_close_low(struct net_device *dev) | ||
2453 | { | ||
2454 | struct strip *strip_info = netdev_priv(dev); | ||
2455 | |||
2456 | if (strip_info->tty == NULL) | ||
2457 | return -EBUSY; | ||
2458 | strip_info->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP); | ||
2459 | |||
2460 | netif_stop_queue(dev); | ||
2461 | |||
2462 | /* | ||
2463 | * Free all STRIP frame buffers. | ||
2464 | */ | ||
2465 | kfree(strip_info->rx_buff); | ||
2466 | strip_info->rx_buff = NULL; | ||
2467 | kfree(strip_info->sx_buff); | ||
2468 | strip_info->sx_buff = NULL; | ||
2469 | kfree(strip_info->tx_buff); | ||
2470 | strip_info->tx_buff = NULL; | ||
2471 | |||
2472 | del_timer(&strip_info->idle_timer); | ||
2473 | return 0; | ||
2474 | } | ||
2475 | |||
2476 | static const struct header_ops strip_header_ops = { | ||
2477 | .create = strip_header, | ||
2478 | .rebuild = strip_rebuild_header, | ||
2479 | }; | ||
2480 | |||
2481 | /* | ||
2482 | * This routine is called by DDI when the | ||
2483 | * (dynamically assigned) device is registered | ||
2484 | */ | ||
2485 | |||
2486 | static void strip_dev_setup(struct net_device *dev) | ||
2487 | { | ||
2488 | /* | ||
2489 | * Finish setting up the DEVICE info. | ||
2490 | */ | ||
2491 | |||
2492 | dev->trans_start = 0; | ||
2493 | dev->last_rx = 0; | ||
2494 | dev->tx_queue_len = 30; /* Drop after 30 frames queued */ | ||
2495 | |||
2496 | dev->flags = 0; | ||
2497 | dev->mtu = DEFAULT_STRIP_MTU; | ||
2498 | dev->type = ARPHRD_METRICOM; /* dtang */ | ||
2499 | dev->hard_header_len = sizeof(STRIP_Header); | ||
2500 | /* | ||
2501 | * dev->priv Already holds a pointer to our struct strip | ||
2502 | */ | ||
2503 | |||
2504 | *(MetricomAddress *) & dev->broadcast = broadcast_address; | ||
2505 | dev->dev_addr[0] = 0; | ||
2506 | dev->addr_len = sizeof(MetricomAddress); | ||
2507 | |||
2508 | /* | ||
2509 | * Pointers to interface service routines. | ||
2510 | */ | ||
2511 | |||
2512 | dev->open = strip_open_low; | ||
2513 | dev->stop = strip_close_low; | ||
2514 | dev->hard_start_xmit = strip_xmit; | ||
2515 | dev->header_ops = &strip_header_ops; | ||
2516 | |||
2517 | dev->set_mac_address = strip_set_mac_address; | ||
2518 | dev->get_stats = strip_get_stats; | ||
2519 | dev->change_mtu = strip_change_mtu; | ||
2520 | } | ||
2521 | |||
2522 | /* | ||
2523 | * Free a STRIP channel. | ||
2524 | */ | ||
2525 | |||
2526 | static void strip_free(struct strip *strip_info) | ||
2527 | { | ||
2528 | spin_lock_bh(&strip_lock); | ||
2529 | list_del_rcu(&strip_info->list); | ||
2530 | spin_unlock_bh(&strip_lock); | ||
2531 | |||
2532 | strip_info->magic = 0; | ||
2533 | |||
2534 | free_netdev(strip_info->dev); | ||
2535 | } | ||
2536 | |||
2537 | |||
2538 | /* | ||
2539 | * Allocate a new free STRIP channel | ||
2540 | */ | ||
2541 | static struct strip *strip_alloc(void) | ||
2542 | { | ||
2543 | struct list_head *n; | ||
2544 | struct net_device *dev; | ||
2545 | struct strip *strip_info; | ||
2546 | |||
2547 | dev = alloc_netdev(sizeof(struct strip), "st%d", | ||
2548 | strip_dev_setup); | ||
2549 | |||
2550 | if (!dev) | ||
2551 | return NULL; /* If no more memory, return */ | ||
2552 | |||
2553 | |||
2554 | strip_info = netdev_priv(dev); | ||
2555 | strip_info->dev = dev; | ||
2556 | |||
2557 | strip_info->magic = STRIP_MAGIC; | ||
2558 | strip_info->tty = NULL; | ||
2559 | |||
2560 | strip_info->gratuitous_arp = jiffies + LongTime; | ||
2561 | strip_info->arp_interval = 0; | ||
2562 | init_timer(&strip_info->idle_timer); | ||
2563 | strip_info->idle_timer.data = (long) dev; | ||
2564 | strip_info->idle_timer.function = strip_IdleTask; | ||
2565 | |||
2566 | |||
2567 | spin_lock_bh(&strip_lock); | ||
2568 | rescan: | ||
2569 | /* | ||
2570 | * Search the list to find where to put our new entry | ||
2571 | * (and in the process decide what channel number it is | ||
2572 | * going to be) | ||
2573 | */ | ||
2574 | list_for_each(n, &strip_list) { | ||
2575 | struct strip *s = hlist_entry(n, struct strip, list); | ||
2576 | |||
2577 | if (s->dev->base_addr == dev->base_addr) { | ||
2578 | ++dev->base_addr; | ||
2579 | goto rescan; | ||
2580 | } | ||
2581 | } | ||
2582 | |||
2583 | sprintf(dev->name, "st%ld", dev->base_addr); | ||
2584 | |||
2585 | list_add_tail_rcu(&strip_info->list, &strip_list); | ||
2586 | spin_unlock_bh(&strip_lock); | ||
2587 | |||
2588 | return strip_info; | ||
2589 | } | ||
2590 | |||
2591 | /* | ||
2592 | * Open the high-level part of the STRIP channel. | ||
2593 | * This function is called by the TTY module when the | ||
2594 | * STRIP line discipline is called for. Because we are | ||
2595 | * sure the tty line exists, we only have to link it to | ||
2596 | * a free STRIP channel... | ||
2597 | */ | ||
2598 | |||
2599 | static int strip_open(struct tty_struct *tty) | ||
2600 | { | ||
2601 | struct strip *strip_info = (struct strip *) tty->disc_data; | ||
2602 | |||
2603 | /* | ||
2604 | * First make sure we're not already connected. | ||
2605 | */ | ||
2606 | |||
2607 | if (strip_info && strip_info->magic == STRIP_MAGIC) | ||
2608 | return -EEXIST; | ||
2609 | |||
2610 | /* | ||
2611 | * We need a write method. | ||
2612 | */ | ||
2613 | |||
2614 | if (tty->ops->write == NULL || tty->ops->set_termios == NULL) | ||
2615 | return -EOPNOTSUPP; | ||
2616 | |||
2617 | /* | ||
2618 | * OK. Find a free STRIP channel to use. | ||
2619 | */ | ||
2620 | if ((strip_info = strip_alloc()) == NULL) | ||
2621 | return -ENFILE; | ||
2622 | |||
2623 | /* | ||
2624 | * Register our newly created device so it can be ifconfig'd | ||
2625 | * strip_dev_init() will be called as a side-effect | ||
2626 | */ | ||
2627 | |||
2628 | if (register_netdev(strip_info->dev) != 0) { | ||
2629 | printk(KERN_ERR "strip: register_netdev() failed.\n"); | ||
2630 | strip_free(strip_info); | ||
2631 | return -ENFILE; | ||
2632 | } | ||
2633 | |||
2634 | strip_info->tty = tty; | ||
2635 | tty->disc_data = strip_info; | ||
2636 | tty->receive_room = 65536; | ||
2637 | |||
2638 | tty_driver_flush_buffer(tty); | ||
2639 | |||
2640 | /* | ||
2641 | * Restore default settings | ||
2642 | */ | ||
2643 | |||
2644 | strip_info->dev->type = ARPHRD_METRICOM; /* dtang */ | ||
2645 | |||
2646 | /* | ||
2647 | * Set tty options | ||
2648 | */ | ||
2649 | |||
2650 | tty->termios->c_iflag |= IGNBRK | IGNPAR; /* Ignore breaks and parity errors. */ | ||
2651 | tty->termios->c_cflag |= CLOCAL; /* Ignore modem control signals. */ | ||
2652 | tty->termios->c_cflag &= ~HUPCL; /* Don't close on hup */ | ||
2653 | |||
2654 | printk(KERN_INFO "STRIP: device \"%s\" activated\n", | ||
2655 | strip_info->dev->name); | ||
2656 | |||
2657 | /* | ||
2658 | * Done. We have linked the TTY line to a channel. | ||
2659 | */ | ||
2660 | return (strip_info->dev->base_addr); | ||
2661 | } | ||
2662 | |||
2663 | /* | ||
2664 | * Close down a STRIP channel. | ||
2665 | * This means flushing out any pending queues, and then restoring the | ||
2666 | * TTY line discipline to what it was before it got hooked to STRIP | ||
2667 | * (which usually is TTY again). | ||
2668 | */ | ||
2669 | |||
2670 | static void strip_close(struct tty_struct *tty) | ||
2671 | { | ||
2672 | struct strip *strip_info = (struct strip *) tty->disc_data; | ||
2673 | |||
2674 | /* | ||
2675 | * First make sure we're connected. | ||
2676 | */ | ||
2677 | |||
2678 | if (!strip_info || strip_info->magic != STRIP_MAGIC) | ||
2679 | return; | ||
2680 | |||
2681 | unregister_netdev(strip_info->dev); | ||
2682 | |||
2683 | tty->disc_data = NULL; | ||
2684 | strip_info->tty = NULL; | ||
2685 | printk(KERN_INFO "STRIP: device \"%s\" closed down\n", | ||
2686 | strip_info->dev->name); | ||
2687 | strip_free(strip_info); | ||
2688 | tty->disc_data = NULL; | ||
2689 | } | ||
2690 | |||
2691 | |||
2692 | /************************************************************************/ | ||
2693 | /* Perform I/O control calls on an active STRIP channel. */ | ||
2694 | |||
2695 | static int strip_ioctl(struct tty_struct *tty, struct file *file, | ||
2696 | unsigned int cmd, unsigned long arg) | ||
2697 | { | ||
2698 | struct strip *strip_info = (struct strip *) tty->disc_data; | ||
2699 | |||
2700 | /* | ||
2701 | * First make sure we're connected. | ||
2702 | */ | ||
2703 | |||
2704 | if (!strip_info || strip_info->magic != STRIP_MAGIC) | ||
2705 | return -EINVAL; | ||
2706 | |||
2707 | switch (cmd) { | ||
2708 | case SIOCGIFNAME: | ||
2709 | if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1)) | ||
2710 | return -EFAULT; | ||
2711 | break; | ||
2712 | case SIOCSIFHWADDR: | ||
2713 | { | ||
2714 | MetricomAddress addr; | ||
2715 | //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name); | ||
2716 | if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress))) | ||
2717 | return -EFAULT; | ||
2718 | return set_mac_address(strip_info, &addr); | ||
2719 | } | ||
2720 | default: | ||
2721 | return tty_mode_ioctl(tty, file, cmd, arg); | ||
2722 | break; | ||
2723 | } | ||
2724 | return 0; | ||
2725 | } | ||
2726 | |||
2727 | |||
2728 | /************************************************************************/ | ||
2729 | /* Initialization */ | ||
2730 | |||
2731 | static struct tty_ldisc strip_ldisc = { | ||
2732 | .magic = TTY_LDISC_MAGIC, | ||
2733 | .name = "strip", | ||
2734 | .owner = THIS_MODULE, | ||
2735 | .open = strip_open, | ||
2736 | .close = strip_close, | ||
2737 | .ioctl = strip_ioctl, | ||
2738 | .receive_buf = strip_receive_buf, | ||
2739 | .write_wakeup = strip_write_some_more, | ||
2740 | }; | ||
2741 | |||
2742 | /* | ||
2743 | * Initialize the STRIP driver. | ||
2744 | * This routine is called at boot time, to bootstrap the multi-channel | ||
2745 | * STRIP driver | ||
2746 | */ | ||
2747 | |||
2748 | static char signon[] __initdata = | ||
2749 | KERN_INFO "STRIP: Version %s (unlimited channels)\n"; | ||
2750 | |||
2751 | static int __init strip_init_driver(void) | ||
2752 | { | ||
2753 | int status; | ||
2754 | |||
2755 | printk(signon, StripVersion); | ||
2756 | |||
2757 | |||
2758 | /* | ||
2759 | * Fill in our line protocol discipline, and register it | ||
2760 | */ | ||
2761 | if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc))) | ||
2762 | printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n", | ||
2763 | status); | ||
2764 | |||
2765 | /* | ||
2766 | * Register the status file with /proc | ||
2767 | */ | ||
2768 | proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops); | ||
2769 | |||
2770 | return status; | ||
2771 | } | ||
2772 | |||
2773 | module_init(strip_init_driver); | ||
2774 | |||
2775 | static const char signoff[] __exitdata = | ||
2776 | KERN_INFO "STRIP: Module Unloaded\n"; | ||
2777 | |||
2778 | static void __exit strip_exit_driver(void) | ||
2779 | { | ||
2780 | int i; | ||
2781 | struct list_head *p,*n; | ||
2782 | |||
2783 | /* module ref count rules assure that all entries are unregistered */ | ||
2784 | list_for_each_safe(p, n, &strip_list) { | ||
2785 | struct strip *s = list_entry(p, struct strip, list); | ||
2786 | strip_free(s); | ||
2787 | } | ||
2788 | |||
2789 | /* Unregister with the /proc/net file here. */ | ||
2790 | proc_net_remove(&init_net, "strip"); | ||
2791 | |||
2792 | if ((i = tty_unregister_ldisc(N_STRIP))) | ||
2793 | printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i); | ||
2794 | |||
2795 | printk(signoff); | ||
2796 | } | ||
2797 | |||
2798 | module_exit(strip_exit_driver); | ||
2799 | |||
2800 | MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>"); | ||
2801 | MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver"); | ||
2802 | MODULE_LICENSE("Dual BSD/GPL"); | ||
2803 | |||
2804 | MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem"); | ||
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index 42a36b3f3ff7..377141995e36 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c | |||
@@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1624 | iwe.cmd = SIOCGIWAP; | 1624 | iwe.cmd = SIOCGIWAP; |
1625 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 1625 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1626 | memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN); | 1626 | memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN); |
1627 | current_ev = iwe_stream_add_event(current_ev, | 1627 | current_ev = iwe_stream_add_event(info, current_ev, |
1628 | extra + IW_SCAN_MAX_DATA, | 1628 | extra + IW_SCAN_MAX_DATA, |
1629 | &iwe, IW_EV_ADDR_LEN); | 1629 | &iwe, IW_EV_ADDR_LEN); |
1630 | iwe.cmd = SIOCGIWESSID; | 1630 | iwe.cmd = SIOCGIWESSID; |
1631 | iwe.u.data.flags = 1; | 1631 | iwe.u.data.flags = 1; |
1632 | iwe.u.data.length = this->bss_set[i].ssid.el.len; | 1632 | iwe.u.data.length = this->bss_set[i].ssid.el.len; |
1633 | current_ev = iwe_stream_add_point(current_ev, | 1633 | current_ev = iwe_stream_add_point(info, current_ev, |
1634 | extra + IW_SCAN_MAX_DATA, | 1634 | extra + IW_SCAN_MAX_DATA, |
1635 | &iwe, | 1635 | &iwe, |
1636 | this->bss_set[i].ssid.essid); | 1636 | this->bss_set[i].ssid.essid); |
1637 | iwe.cmd = SIOCGIWMODE; | 1637 | iwe.cmd = SIOCGIWMODE; |
1638 | iwe.u.mode = this->bss_set[i].bss_type; | 1638 | iwe.u.mode = this->bss_set[i].bss_type; |
1639 | current_ev = iwe_stream_add_event(current_ev, | 1639 | current_ev = iwe_stream_add_event(info, current_ev, |
1640 | extra + IW_SCAN_MAX_DATA, | 1640 | extra + IW_SCAN_MAX_DATA, |
1641 | &iwe, IW_EV_UINT_LEN); | 1641 | &iwe, IW_EV_UINT_LEN); |
1642 | iwe.cmd = SIOCGIWFREQ; | 1642 | iwe.cmd = SIOCGIWFREQ; |
1643 | iwe.u.freq.m = this->bss_set[i].ds_pset.chan; | 1643 | iwe.u.freq.m = this->bss_set[i].ds_pset.chan; |
1644 | iwe.u.freq.e = 0; | 1644 | iwe.u.freq.e = 0; |
1645 | current_ev = iwe_stream_add_event(current_ev, | 1645 | current_ev = iwe_stream_add_event(info, current_ev, |
1646 | extra + IW_SCAN_MAX_DATA, | 1646 | extra + IW_SCAN_MAX_DATA, |
1647 | &iwe, IW_EV_FREQ_LEN); | 1647 | &iwe, IW_EV_FREQ_LEN); |
1648 | iwe.cmd = SIOCGIWENCODE; | 1648 | iwe.cmd = SIOCGIWENCODE; |
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info, | |||
1651 | else | 1651 | else |
1652 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 1652 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
1653 | iwe.u.data.length = 0; | 1653 | iwe.u.data.length = 0; |
1654 | current_ev = iwe_stream_add_point(current_ev, | 1654 | current_ev = iwe_stream_add_point(info, current_ev, |
1655 | extra + IW_SCAN_MAX_DATA, | 1655 | extra + IW_SCAN_MAX_DATA, |
1656 | &iwe, NULL); | 1656 | &iwe, NULL); |
1657 | } | 1657 | } |
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c index d5c0c66188ca..07e4d1f73207 100644 --- a/drivers/net/wireless/zd1201.c +++ b/drivers/net/wireless/zd1201.c | |||
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev, | |||
1152 | iwe.cmd = SIOCGIWAP; | 1152 | iwe.cmd = SIOCGIWAP; |
1153 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; | 1153 | iwe.u.ap_addr.sa_family = ARPHRD_ETHER; |
1154 | memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6); | 1154 | memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6); |
1155 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); | 1155 | cev = iwe_stream_add_event(info, cev, end_buf, |
1156 | &iwe, IW_EV_ADDR_LEN); | ||
1156 | 1157 | ||
1157 | iwe.cmd = SIOCGIWESSID; | 1158 | iwe.cmd = SIOCGIWESSID; |
1158 | iwe.u.data.length = zd->rxdata[i+16]; | 1159 | iwe.u.data.length = zd->rxdata[i+16]; |
1159 | iwe.u.data.flags = 1; | 1160 | iwe.u.data.flags = 1; |
1160 | cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18); | 1161 | cev = iwe_stream_add_point(info, cev, end_buf, |
1162 | &iwe, zd->rxdata+i+18); | ||
1161 | 1163 | ||
1162 | iwe.cmd = SIOCGIWMODE; | 1164 | iwe.cmd = SIOCGIWMODE; |
1163 | if (zd->rxdata[i+14]&0x01) | 1165 | if (zd->rxdata[i+14]&0x01) |
1164 | iwe.u.mode = IW_MODE_MASTER; | 1166 | iwe.u.mode = IW_MODE_MASTER; |
1165 | else | 1167 | else |
1166 | iwe.u.mode = IW_MODE_ADHOC; | 1168 | iwe.u.mode = IW_MODE_ADHOC; |
1167 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); | 1169 | cev = iwe_stream_add_event(info, cev, end_buf, |
1170 | &iwe, IW_EV_UINT_LEN); | ||
1168 | 1171 | ||
1169 | iwe.cmd = SIOCGIWFREQ; | 1172 | iwe.cmd = SIOCGIWFREQ; |
1170 | iwe.u.freq.m = zd->rxdata[i+0]; | 1173 | iwe.u.freq.m = zd->rxdata[i+0]; |
1171 | iwe.u.freq.e = 0; | 1174 | iwe.u.freq.e = 0; |
1172 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); | 1175 | cev = iwe_stream_add_event(info, cev, end_buf, |
1176 | &iwe, IW_EV_FREQ_LEN); | ||
1173 | 1177 | ||
1174 | iwe.cmd = SIOCGIWRATE; | 1178 | iwe.cmd = SIOCGIWRATE; |
1175 | iwe.u.bitrate.fixed = 0; | 1179 | iwe.u.bitrate.fixed = 0; |
1176 | iwe.u.bitrate.disabled = 0; | 1180 | iwe.u.bitrate.disabled = 0; |
1177 | for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) { | 1181 | for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) { |
1178 | iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000; | 1182 | iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000; |
1179 | cev=iwe_stream_add_event(cev, end_buf, &iwe, | 1183 | cev = iwe_stream_add_event(info, cev, end_buf, |
1180 | IW_EV_PARAM_LEN); | 1184 | &iwe, IW_EV_PARAM_LEN); |
1181 | } | 1185 | } |
1182 | 1186 | ||
1183 | iwe.cmd = SIOCGIWENCODE; | 1187 | iwe.cmd = SIOCGIWENCODE; |
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev, | |||
1186 | iwe.u.data.flags = IW_ENCODE_ENABLED; | 1190 | iwe.u.data.flags = IW_ENCODE_ENABLED; |
1187 | else | 1191 | else |
1188 | iwe.u.data.flags = IW_ENCODE_DISABLED; | 1192 | iwe.u.data.flags = IW_ENCODE_DISABLED; |
1189 | cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); | 1193 | cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL); |
1190 | 1194 | ||
1191 | iwe.cmd = IWEVQUAL; | 1195 | iwe.cmd = IWEVQUAL; |
1192 | iwe.u.qual.qual = zd->rxdata[i+4]; | 1196 | iwe.u.qual.qual = zd->rxdata[i+4]; |
1193 | iwe.u.qual.noise= zd->rxdata[i+2]/10-100; | 1197 | iwe.u.qual.noise= zd->rxdata[i+2]/10-100; |
1194 | iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100; | 1198 | iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100; |
1195 | iwe.u.qual.updated = 7; | 1199 | iwe.u.qual.updated = 7; |
1196 | cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); | 1200 | cev = iwe_stream_add_event(info, cev, end_buf, |
1201 | &iwe, IW_EV_QUAL_LEN); | ||
1197 | } | 1202 | } |
1198 | 1203 | ||
1199 | if (!enabled_save) | 1204 | if (!enabled_save) |
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 6d86b365f150..317c5e24f80c 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c | |||
@@ -376,8 +376,6 @@ static int zd_calc_tx_length_us(u8 *service, u8 zd_rate, u16 tx_length) | |||
376 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | 376 | static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, |
377 | struct ieee80211_hdr *header, u32 flags) | 377 | struct ieee80211_hdr *header, u32 flags) |
378 | { | 378 | { |
379 | u16 fctl = le16_to_cpu(header->frame_control); | ||
380 | |||
381 | /* | 379 | /* |
382 | * CONTROL TODO: | 380 | * CONTROL TODO: |
383 | * - if backoff needed, enable bit 0 | 381 | * - if backoff needed, enable bit 0 |
@@ -395,8 +393,7 @@ static void cs_set_control(struct zd_mac *mac, struct zd_ctrlset *cs, | |||
395 | cs->control |= ZD_CS_MULTICAST; | 393 | cs->control |= ZD_CS_MULTICAST; |
396 | 394 | ||
397 | /* PS-POLL */ | 395 | /* PS-POLL */ |
398 | if ((fctl & (IEEE80211_FCTL_FTYPE|IEEE80211_FCTL_STYPE)) == | 396 | if (ieee80211_is_pspoll(header->frame_control)) |
399 | (IEEE80211_FTYPE_CTL|IEEE80211_STYPE_PSPOLL)) | ||
400 | cs->control |= ZD_CS_PS_POLL_FRAME; | 397 | cs->control |= ZD_CS_PS_POLL_FRAME; |
401 | 398 | ||
402 | if (flags & IEEE80211_TX_CTL_USE_RTS_CTS) | 399 | if (flags & IEEE80211_TX_CTL_USE_RTS_CTS) |
@@ -550,13 +547,11 @@ static int zd_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
550 | static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, | 547 | static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, |
551 | struct ieee80211_rx_status *stats) | 548 | struct ieee80211_rx_status *stats) |
552 | { | 549 | { |
553 | u16 fc = le16_to_cpu(rx_hdr->frame_control); | ||
554 | struct sk_buff *skb; | 550 | struct sk_buff *skb; |
555 | struct sk_buff_head *q; | 551 | struct sk_buff_head *q; |
556 | unsigned long flags; | 552 | unsigned long flags; |
557 | 553 | ||
558 | if ((fc & (IEEE80211_FCTL_FTYPE | IEEE80211_FCTL_STYPE)) != | 554 | if (!ieee80211_is_ack(rx_hdr->frame_control)) |
559 | (IEEE80211_FTYPE_CTL | IEEE80211_STYPE_ACK)) | ||
560 | return 0; | 555 | return 0; |
561 | 556 | ||
562 | q = &zd_hw_mac(hw)->ack_wait_queue; | 557 | q = &zd_hw_mac(hw)->ack_wait_queue; |
@@ -584,8 +579,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
584 | const struct rx_status *status; | 579 | const struct rx_status *status; |
585 | struct sk_buff *skb; | 580 | struct sk_buff *skb; |
586 | int bad_frame = 0; | 581 | int bad_frame = 0; |
587 | u16 fc; | 582 | __le16 fc; |
588 | bool is_qos, is_4addr, need_padding; | 583 | int need_padding; |
589 | int i; | 584 | int i; |
590 | u8 rate; | 585 | u8 rate; |
591 | 586 | ||
@@ -644,13 +639,8 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length) | |||
644 | && !mac->pass_ctrl) | 639 | && !mac->pass_ctrl) |
645 | return 0; | 640 | return 0; |
646 | 641 | ||
647 | fc = le16_to_cpu(*((__le16 *) buffer)); | 642 | fc = *(__le16 *)buffer; |
648 | 643 | need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); | |
649 | is_qos = ((fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA) && | ||
650 | (fc & IEEE80211_STYPE_QOS_DATA); | ||
651 | is_4addr = (fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) == | ||
652 | (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS); | ||
653 | need_padding = is_qos ^ is_4addr; | ||
654 | 644 | ||
655 | skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); | 645 | skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); |
656 | if (skb == NULL) | 646 | if (skb == NULL) |