diff options
Diffstat (limited to 'drivers/net/wireless/bcm43xx')
-rw-r--r-- | drivers/net/wireless/bcm43xx/Kconfig | 3 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx.h | 17 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | 8 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 13 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_power.c | 115 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_power.h | 9 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 115 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h | 16 | ||||
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 8 |
11 files changed, 179 insertions, 128 deletions
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig index 418465600a77..25ea4748f0b9 100644 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ b/drivers/net/wireless/bcm43xx/Kconfig | |||
@@ -17,8 +17,11 @@ config BCM43XX_DEBUG | |||
17 | 17 | ||
18 | config BCM43XX_DMA | 18 | config BCM43XX_DMA |
19 | bool | 19 | bool |
20 | depends on BCM43XX | ||
21 | |||
20 | config BCM43XX_PIO | 22 | config BCM43XX_PIO |
21 | bool | 23 | bool |
24 | depends on BCM43XX | ||
22 | 25 | ||
23 | choice | 26 | choice |
24 | prompt "BCM43xx data transfer mode" | 27 | prompt "BCM43xx data transfer mode" |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index dcadd295de4f..2e83083935e1 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include "bcm43xx_debugfs.h" | 16 | #include "bcm43xx_debugfs.h" |
17 | #include "bcm43xx_leds.h" | 17 | #include "bcm43xx_leds.h" |
18 | #include "bcm43xx_sysfs.h" | ||
19 | 18 | ||
20 | 19 | ||
21 | #define PFX KBUILD_MODNAME ": " | 20 | #define PFX KBUILD_MODNAME ": " |
@@ -638,8 +637,6 @@ struct bcm43xx_key { | |||
638 | }; | 637 | }; |
639 | 638 | ||
640 | struct bcm43xx_private { | 639 | struct bcm43xx_private { |
641 | struct bcm43xx_sysfs sysfs; | ||
642 | |||
643 | struct ieee80211_device *ieee; | 640 | struct ieee80211_device *ieee; |
644 | struct ieee80211softmac_device *softmac; | 641 | struct ieee80211softmac_device *softmac; |
645 | 642 | ||
@@ -772,6 +769,20 @@ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) | |||
772 | return ieee80211softmac_priv(dev); | 769 | return ieee80211softmac_priv(dev); |
773 | } | 770 | } |
774 | 771 | ||
772 | struct device; | ||
773 | |||
774 | static inline | ||
775 | struct bcm43xx_private * dev_to_bcm(struct device *dev) | ||
776 | { | ||
777 | struct net_device *net_dev; | ||
778 | struct bcm43xx_private *bcm; | ||
779 | |||
780 | net_dev = dev_get_drvdata(dev); | ||
781 | bcm = bcm43xx_priv(net_dev); | ||
782 | |||
783 | return bcm; | ||
784 | } | ||
785 | |||
775 | 786 | ||
776 | /* Helper function, which returns a boolean. | 787 | /* Helper function, which returns a boolean. |
777 | * TRUE, if PIO is used; FALSE, if DMA is used. | 788 | * TRUE, if PIO is used; FALSE, if DMA is used. |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index d2c3401e9b70..35a4fcb6d923 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | |||
@@ -452,12 +452,12 @@ void bcm43xx_printk_dump(const char *data, | |||
452 | size_t i; | 452 | size_t i; |
453 | char c; | 453 | char c; |
454 | 454 | ||
455 | printk(KERN_INFO PFX "Data dump (%s, %u bytes):", | 455 | printk(KERN_INFO PFX "Data dump (%s, %zd bytes):", |
456 | description, size); | 456 | description, size); |
457 | for (i = 0; i < size; i++) { | 457 | for (i = 0; i < size; i++) { |
458 | c = data[i]; | 458 | c = data[i]; |
459 | if (i % 8 == 0) | 459 | if (i % 8 == 0) |
460 | printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff); | 460 | printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff); |
461 | else | 461 | else |
462 | printk("0x%02x, ", c & 0xff); | 462 | printk("0x%02x, ", c & 0xff); |
463 | } | 463 | } |
@@ -472,12 +472,12 @@ void bcm43xx_printk_bitdump(const unsigned char *data, | |||
472 | int j; | 472 | int j; |
473 | const unsigned char *d; | 473 | const unsigned char *d; |
474 | 474 | ||
475 | printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***", | 475 | printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***", |
476 | description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); | 476 | description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); |
477 | for (i = 0; i < bytes; i++) { | 477 | for (i = 0; i < bytes; i++) { |
478 | d = data + i; | 478 | d = data + i; |
479 | if (i % 8 == 0) | 479 | if (i % 8 == 0) |
480 | printk("\n" KERN_INFO PFX "0x%08x: ", i); | 480 | printk("\n" KERN_INFO PFX "0x%08zx: ", i); |
481 | if (msb_to_lsb) { | 481 | if (msb_to_lsb) { |
482 | for (j = 7; j >= 0; j--) { | 482 | for (j = 7; j >= 0; j--) { |
483 | if (*d & (1 << j)) | 483 | if (*d & (1 << j)) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index c3681b8f09b4..bbecba02e697 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c | |||
@@ -196,8 +196,9 @@ static int alloc_ringmemory(struct bcm43xx_dmaring *ring) | |||
196 | } | 196 | } |
197 | if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { | 197 | if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { |
198 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " | 198 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " |
199 | "(0x%08x, len: %lu)\n", | 199 | "(0x%llx, len: %lu)\n", |
200 | ring->dmabase, BCM43xx_DMA_RINGMEMSIZE); | 200 | (unsigned long long)ring->dmabase, |
201 | BCM43xx_DMA_RINGMEMSIZE); | ||
201 | dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, | 202 | dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, |
202 | ring->vbase, ring->dmabase); | 203 | ring->vbase, ring->dmabase); |
203 | return -ENOMEM; | 204 | return -ENOMEM; |
@@ -307,8 +308,8 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring, | |||
307 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); | 308 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); |
308 | dev_kfree_skb_any(skb); | 309 | dev_kfree_skb_any(skb); |
309 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " | 310 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " |
310 | "(0x%08x, len: %u)\n", | 311 | "(0x%llx, len: %u)\n", |
311 | dmaaddr, ring->rx_buffersize); | 312 | (unsigned long long)dmaaddr, ring->rx_buffersize); |
312 | return -ENOMEM; | 313 | return -ENOMEM; |
313 | } | 314 | } |
314 | meta->skb = skb; | 315 | meta->skb = skb; |
@@ -729,8 +730,8 @@ static int dma_tx_fragment(struct bcm43xx_dmaring *ring, | |||
729 | if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { | 730 | if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { |
730 | return_slot(ring, slot); | 731 | return_slot(ring, slot); |
731 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " | 732 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " |
732 | "(0x%08x, len: %u)\n", | 733 | "(0x%llx, len: %u)\n", |
733 | meta->dmaaddr, skb->len); | 734 | (unsigned long long)meta->dmaaddr, skb->len); |
734 | return -ENOMEM; | 735 | return -ENOMEM; |
735 | } | 736 | } |
736 | 737 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index c37371fc9e01..9a06e61df0a2 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "bcm43xx_wx.h" | 52 | #include "bcm43xx_wx.h" |
53 | #include "bcm43xx_ethtool.h" | 53 | #include "bcm43xx_ethtool.h" |
54 | #include "bcm43xx_xmit.h" | 54 | #include "bcm43xx_xmit.h" |
55 | #include "bcm43xx_sysfs.h" | ||
55 | 56 | ||
56 | 57 | ||
57 | MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); | 58 | MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); |
@@ -3522,6 +3523,7 @@ static inline int bcm43xx_tx(struct bcm43xx_private *bcm, | |||
3522 | err = bcm43xx_pio_tx(bcm, txb); | 3523 | err = bcm43xx_pio_tx(bcm, txb); |
3523 | else | 3524 | else |
3524 | err = bcm43xx_dma_tx(bcm, txb); | 3525 | err = bcm43xx_dma_tx(bcm, txb); |
3526 | bcm->net_dev->trans_start = jiffies; | ||
3525 | 3527 | ||
3526 | return err; | 3528 | return err; |
3527 | } | 3529 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index 0a66f43ca0c0..33137165727f 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c | |||
@@ -2151,6 +2151,7 @@ int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm) | |||
2151 | phy->tssi2dbm = NULL; | 2151 | phy->tssi2dbm = NULL; |
2152 | printk(KERN_ERR PFX "Could not generate " | 2152 | printk(KERN_ERR PFX "Could not generate " |
2153 | "tssi2dBm table\n"); | 2153 | "tssi2dBm table\n"); |
2154 | kfree(dyn_tssi2dbm); | ||
2154 | return -ENODEV; | 2155 | return -ENODEV; |
2155 | } | 2156 | } |
2156 | phy->tssi2dbm = dyn_tssi2dbm; | 2157 | phy->tssi2dbm = dyn_tssi2dbm; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c index 3c92b62807c5..6569da3a7a39 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |||
@@ -35,77 +35,101 @@ | |||
35 | #include "bcm43xx_main.h" | 35 | #include "bcm43xx_main.h" |
36 | 36 | ||
37 | 37 | ||
38 | /* Get the Slow Clock Source */ | ||
39 | static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm) | ||
40 | { | ||
41 | u32 tmp; | ||
42 | int err; | ||
43 | |||
44 | assert(bcm->current_core == &bcm->core_chipcommon); | ||
45 | if (bcm->current_core->rev < 6) { | ||
46 | if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA || | ||
47 | bcm->bustype == BCM43xx_BUSTYPE_SB) | ||
48 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
49 | if (bcm->bustype == BCM43xx_BUSTYPE_PCI) { | ||
50 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); | ||
51 | assert(!err); | ||
52 | if (tmp & 0x10) | ||
53 | return BCM43xx_PCTL_CLKSRC_PCI; | ||
54 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
55 | } | ||
56 | } | ||
57 | if (bcm->current_core->rev < 10) { | ||
58 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); | ||
59 | tmp &= 0x7; | ||
60 | if (tmp == 0) | ||
61 | return BCM43xx_PCTL_CLKSRC_LOPWROS; | ||
62 | if (tmp == 1) | ||
63 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
64 | if (tmp == 2) | ||
65 | return BCM43xx_PCTL_CLKSRC_PCI; | ||
66 | } | ||
67 | |||
68 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
69 | } | ||
70 | |||
38 | /* Get max/min slowclock frequency | 71 | /* Get max/min slowclock frequency |
39 | * as described in http://bcm-specs.sipsolutions.net/PowerControl | 72 | * as described in http://bcm-specs.sipsolutions.net/PowerControl |
40 | */ | 73 | */ |
41 | static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, | 74 | static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, |
42 | int get_max) | 75 | int get_max) |
43 | { | 76 | { |
44 | int limit = 0; | 77 | int limit; |
78 | int clocksrc; | ||
45 | int divisor; | 79 | int divisor; |
46 | int selection; | ||
47 | int err; | ||
48 | u32 tmp; | 80 | u32 tmp; |
49 | struct bcm43xx_coreinfo *old_core; | ||
50 | 81 | ||
51 | if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) | 82 | assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL); |
52 | goto out; | 83 | assert(bcm->current_core == &bcm->core_chipcommon); |
53 | old_core = bcm->current_core; | ||
54 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | ||
55 | if (err) | ||
56 | goto out; | ||
57 | 84 | ||
85 | clocksrc = bcm43xx_pctl_get_slowclksrc(bcm); | ||
58 | if (bcm->current_core->rev < 6) { | 86 | if (bcm->current_core->rev < 6) { |
59 | if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) || | 87 | switch (clocksrc) { |
60 | (bcm->bustype == BCM43xx_BUSTYPE_SB)) { | 88 | case BCM43xx_PCTL_CLKSRC_PCI: |
61 | selection = 1; | 89 | divisor = 64; |
90 | break; | ||
91 | case BCM43xx_PCTL_CLKSRC_XTALOS: | ||
62 | divisor = 32; | 92 | divisor = 32; |
63 | } else { | 93 | break; |
64 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); | 94 | default: |
65 | if (err) { | 95 | assert(0); |
66 | printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n"); | 96 | divisor = 1; |
67 | goto out_switchback; | ||
68 | } | ||
69 | if (tmp & 0x10) { | ||
70 | /* PCI */ | ||
71 | selection = 2; | ||
72 | divisor = 64; | ||
73 | } else { | ||
74 | /* XTAL */ | ||
75 | selection = 1; | ||
76 | divisor = 32; | ||
77 | } | ||
78 | } | 97 | } |
79 | } else if (bcm->current_core->rev < 10) { | 98 | } else if (bcm->current_core->rev < 10) { |
80 | selection = (tmp & 0x07); | 99 | switch (clocksrc) { |
81 | if (selection) { | 100 | case BCM43xx_PCTL_CLKSRC_LOPWROS: |
101 | divisor = 1; | ||
102 | break; | ||
103 | case BCM43xx_PCTL_CLKSRC_XTALOS: | ||
104 | case BCM43xx_PCTL_CLKSRC_PCI: | ||
82 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); | 105 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); |
83 | divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); | 106 | divisor = ((tmp & 0xFFFF0000) >> 16) + 1; |
84 | } else | 107 | divisor *= 4; |
108 | break; | ||
109 | default: | ||
110 | assert(0); | ||
85 | divisor = 1; | 111 | divisor = 1; |
112 | } | ||
86 | } else { | 113 | } else { |
87 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); | 114 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); |
88 | divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); | 115 | divisor = ((tmp & 0xFFFF0000) >> 16) + 1; |
89 | selection = 1; | 116 | divisor *= 4; |
90 | } | 117 | } |
91 | 118 | ||
92 | switch (selection) { | 119 | switch (clocksrc) { |
93 | case 0: | 120 | case BCM43xx_PCTL_CLKSRC_LOPWROS: |
94 | /* LPO */ | ||
95 | if (get_max) | 121 | if (get_max) |
96 | limit = 43000; | 122 | limit = 43000; |
97 | else | 123 | else |
98 | limit = 25000; | 124 | limit = 25000; |
99 | break; | 125 | break; |
100 | case 1: | 126 | case BCM43xx_PCTL_CLKSRC_XTALOS: |
101 | /* XTAL */ | ||
102 | if (get_max) | 127 | if (get_max) |
103 | limit = 20200000; | 128 | limit = 20200000; |
104 | else | 129 | else |
105 | limit = 19800000; | 130 | limit = 19800000; |
106 | break; | 131 | break; |
107 | case 2: | 132 | case BCM43xx_PCTL_CLKSRC_PCI: |
108 | /* PCI */ | ||
109 | if (get_max) | 133 | if (get_max) |
110 | limit = 34000000; | 134 | limit = 34000000; |
111 | else | 135 | else |
@@ -113,17 +137,14 @@ static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, | |||
113 | break; | 137 | break; |
114 | default: | 138 | default: |
115 | assert(0); | 139 | assert(0); |
140 | limit = 0; | ||
116 | } | 141 | } |
117 | limit /= divisor; | 142 | limit /= divisor; |
118 | 143 | ||
119 | out_switchback: | ||
120 | err = bcm43xx_switch_core(bcm, old_core); | ||
121 | assert(err == 0); | ||
122 | |||
123 | out: | ||
124 | return limit; | 144 | return limit; |
125 | } | 145 | } |
126 | 146 | ||
147 | |||
127 | /* init power control | 148 | /* init power control |
128 | * as described in http://bcm-specs.sipsolutions.net/PowerControl | 149 | * as described in http://bcm-specs.sipsolutions.net/PowerControl |
129 | */ | 150 | */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h index 5f63640810bd..c966ab3a5a8c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.h | |||
@@ -33,6 +33,15 @@ | |||
33 | 33 | ||
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | 35 | ||
36 | /* Clock sources */ | ||
37 | enum { | ||
38 | /* PCI clock */ | ||
39 | BCM43xx_PCTL_CLKSRC_PCI, | ||
40 | /* Crystal slow clock oscillator */ | ||
41 | BCM43xx_PCTL_CLKSRC_XTALOS, | ||
42 | /* Low power oscillator */ | ||
43 | BCM43xx_PCTL_CLKSRC_LOPWROS, | ||
44 | }; | ||
36 | 45 | ||
37 | struct bcm43xx_private; | 46 | struct bcm43xx_private; |
38 | 47 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index c44d890b949b..b438f48e891d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | |||
@@ -71,14 +71,46 @@ static int get_boolean(const char *buf, size_t count) | |||
71 | return -EINVAL; | 71 | return -EINVAL; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) | ||
75 | { | ||
76 | int i, pos = 0; | ||
77 | |||
78 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | ||
79 | pos += snprintf(buf + pos, buf_len - pos - 1, | ||
80 | "%04X", swab16(sprom[i]) & 0xFFFF); | ||
81 | } | ||
82 | pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); | ||
83 | |||
84 | return pos + 1; | ||
85 | } | ||
86 | |||
87 | static int hex2sprom(u16 *sprom, const char *dump, size_t len) | ||
88 | { | ||
89 | char tmp[5] = { 0 }; | ||
90 | int cnt = 0; | ||
91 | unsigned long parsed; | ||
92 | |||
93 | if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) | ||
94 | return -EINVAL; | ||
95 | |||
96 | while (cnt < BCM43xx_SPROM_SIZE) { | ||
97 | memcpy(tmp, dump, 4); | ||
98 | dump += 4; | ||
99 | parsed = simple_strtoul(tmp, NULL, 16); | ||
100 | sprom[cnt++] = swab16((u16)parsed); | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
74 | static ssize_t bcm43xx_attr_sprom_show(struct device *dev, | 106 | static ssize_t bcm43xx_attr_sprom_show(struct device *dev, |
75 | struct device_attribute *attr, | 107 | struct device_attribute *attr, |
76 | char *buf) | 108 | char *buf) |
77 | { | 109 | { |
78 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); | 110 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
79 | u16 *sprom; | 111 | u16 *sprom; |
80 | unsigned long flags; | 112 | unsigned long flags; |
81 | int i, err; | 113 | int err; |
82 | 114 | ||
83 | if (!capable(CAP_NET_ADMIN)) | 115 | if (!capable(CAP_NET_ADMIN)) |
84 | return -EPERM; | 116 | return -EPERM; |
@@ -91,55 +123,53 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, | |||
91 | bcm43xx_lock_mmio(bcm, flags); | 123 | bcm43xx_lock_mmio(bcm, flags); |
92 | assert(bcm->initialized); | 124 | assert(bcm->initialized); |
93 | err = bcm43xx_sprom_read(bcm, sprom); | 125 | err = bcm43xx_sprom_read(bcm, sprom); |
94 | if (!err) { | 126 | if (!err) |
95 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | 127 | err = sprom2hex(sprom, buf, PAGE_SIZE); |
96 | buf[i * 2] = sprom[i] & 0x00FF; | ||
97 | buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8; | ||
98 | } | ||
99 | } | ||
100 | bcm43xx_unlock_mmio(bcm, flags); | 128 | bcm43xx_unlock_mmio(bcm, flags); |
101 | kfree(sprom); | 129 | kfree(sprom); |
102 | 130 | ||
103 | return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16); | 131 | return err; |
104 | } | 132 | } |
105 | 133 | ||
106 | static ssize_t bcm43xx_attr_sprom_store(struct device *dev, | 134 | static ssize_t bcm43xx_attr_sprom_store(struct device *dev, |
107 | struct device_attribute *attr, | 135 | struct device_attribute *attr, |
108 | const char *buf, size_t count) | 136 | const char *buf, size_t count) |
109 | { | 137 | { |
110 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); | 138 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
111 | u16 *sprom; | 139 | u16 *sprom; |
112 | unsigned long flags; | 140 | unsigned long flags; |
113 | int i, err; | 141 | int err; |
114 | 142 | ||
115 | if (!capable(CAP_NET_ADMIN)) | 143 | if (!capable(CAP_NET_ADMIN)) |
116 | return -EPERM; | 144 | return -EPERM; |
117 | 145 | ||
118 | if (count != BCM43xx_SPROM_SIZE * sizeof(u16)) | ||
119 | return -EINVAL; | ||
120 | sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), | 146 | sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), |
121 | GFP_KERNEL); | 147 | GFP_KERNEL); |
122 | if (!sprom) | 148 | if (!sprom) |
123 | return -ENOMEM; | 149 | return -ENOMEM; |
124 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | 150 | err = hex2sprom(sprom, buf, count); |
125 | sprom[i] = buf[i * 2] & 0xFF; | 151 | if (err) |
126 | sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8; | 152 | goto out_kfree; |
127 | } | ||
128 | bcm43xx_lock_mmio(bcm, flags); | 153 | bcm43xx_lock_mmio(bcm, flags); |
129 | assert(bcm->initialized); | 154 | assert(bcm->initialized); |
130 | err = bcm43xx_sprom_write(bcm, sprom); | 155 | err = bcm43xx_sprom_write(bcm, sprom); |
131 | bcm43xx_unlock_mmio(bcm, flags); | 156 | bcm43xx_unlock_mmio(bcm, flags); |
157 | out_kfree: | ||
132 | kfree(sprom); | 158 | kfree(sprom); |
133 | 159 | ||
134 | return err ? err : count; | 160 | return err ? err : count; |
135 | 161 | ||
136 | } | 162 | } |
137 | 163 | ||
164 | static DEVICE_ATTR(sprom, 0600, | ||
165 | bcm43xx_attr_sprom_show, | ||
166 | bcm43xx_attr_sprom_store); | ||
167 | |||
138 | static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, | 168 | static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, |
139 | struct device_attribute *attr, | 169 | struct device_attribute *attr, |
140 | char *buf) | 170 | char *buf) |
141 | { | 171 | { |
142 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); | 172 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
143 | unsigned long flags; | 173 | unsigned long flags; |
144 | int err; | 174 | int err; |
145 | ssize_t count = 0; | 175 | ssize_t count = 0; |
@@ -175,7 +205,7 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
175 | struct device_attribute *attr, | 205 | struct device_attribute *attr, |
176 | const char *buf, size_t count) | 206 | const char *buf, size_t count) |
177 | { | 207 | { |
178 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); | 208 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
179 | unsigned long flags; | 209 | unsigned long flags; |
180 | int err; | 210 | int err; |
181 | int mode; | 211 | int mode; |
@@ -215,11 +245,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
215 | return err ? err : count; | 245 | return err ? err : count; |
216 | } | 246 | } |
217 | 247 | ||
248 | static DEVICE_ATTR(interference, 0644, | ||
249 | bcm43xx_attr_interfmode_show, | ||
250 | bcm43xx_attr_interfmode_store); | ||
251 | |||
218 | static ssize_t bcm43xx_attr_preamble_show(struct device *dev, | 252 | static ssize_t bcm43xx_attr_preamble_show(struct device *dev, |
219 | struct device_attribute *attr, | 253 | struct device_attribute *attr, |
220 | char *buf) | 254 | char *buf) |
221 | { | 255 | { |
222 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); | 256 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
223 | unsigned long flags; | 257 | unsigned long flags; |
224 | int err; | 258 | int err; |
225 | ssize_t count; | 259 | ssize_t count; |
@@ -245,7 +279,7 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, | |||
245 | struct device_attribute *attr, | 279 | struct device_attribute *attr, |
246 | const char *buf, size_t count) | 280 | const char *buf, size_t count) |
247 | { | 281 | { |
248 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); | 282 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
249 | unsigned long flags; | 283 | unsigned long flags; |
250 | int err; | 284 | int err; |
251 | int value; | 285 | int value; |
@@ -267,56 +301,41 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, | |||
267 | return err ? err : count; | 301 | return err ? err : count; |
268 | } | 302 | } |
269 | 303 | ||
304 | static DEVICE_ATTR(shortpreamble, 0644, | ||
305 | bcm43xx_attr_preamble_show, | ||
306 | bcm43xx_attr_preamble_store); | ||
307 | |||
270 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) | 308 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) |
271 | { | 309 | { |
272 | struct device *dev = &bcm->pci_dev->dev; | 310 | struct device *dev = &bcm->pci_dev->dev; |
273 | struct bcm43xx_sysfs *sysfs = &bcm->sysfs; | ||
274 | int err; | 311 | int err; |
275 | 312 | ||
276 | assert(bcm->initialized); | 313 | assert(bcm->initialized); |
277 | 314 | ||
278 | sysfs->attr_sprom.attr.name = "sprom"; | 315 | err = device_create_file(dev, &dev_attr_sprom); |
279 | sysfs->attr_sprom.attr.owner = THIS_MODULE; | ||
280 | sysfs->attr_sprom.attr.mode = 0600; | ||
281 | sysfs->attr_sprom.show = bcm43xx_attr_sprom_show; | ||
282 | sysfs->attr_sprom.store = bcm43xx_attr_sprom_store; | ||
283 | err = device_create_file(dev, &sysfs->attr_sprom); | ||
284 | if (err) | 316 | if (err) |
285 | goto out; | 317 | goto out; |
286 | 318 | err = device_create_file(dev, &dev_attr_interference); | |
287 | sysfs->attr_interfmode.attr.name = "interference"; | ||
288 | sysfs->attr_interfmode.attr.owner = THIS_MODULE; | ||
289 | sysfs->attr_interfmode.attr.mode = 0600; | ||
290 | sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show; | ||
291 | sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store; | ||
292 | err = device_create_file(dev, &sysfs->attr_interfmode); | ||
293 | if (err) | 319 | if (err) |
294 | goto err_remove_sprom; | 320 | goto err_remove_sprom; |
295 | 321 | err = device_create_file(dev, &dev_attr_shortpreamble); | |
296 | sysfs->attr_preamble.attr.name = "shortpreamble"; | ||
297 | sysfs->attr_preamble.attr.owner = THIS_MODULE; | ||
298 | sysfs->attr_preamble.attr.mode = 0600; | ||
299 | sysfs->attr_preamble.show = bcm43xx_attr_preamble_show; | ||
300 | sysfs->attr_preamble.store = bcm43xx_attr_preamble_store; | ||
301 | err = device_create_file(dev, &sysfs->attr_preamble); | ||
302 | if (err) | 322 | if (err) |
303 | goto err_remove_interfmode; | 323 | goto err_remove_interfmode; |
304 | 324 | ||
305 | out: | 325 | out: |
306 | return err; | 326 | return err; |
307 | err_remove_interfmode: | 327 | err_remove_interfmode: |
308 | device_remove_file(dev, &sysfs->attr_interfmode); | 328 | device_remove_file(dev, &dev_attr_interference); |
309 | err_remove_sprom: | 329 | err_remove_sprom: |
310 | device_remove_file(dev, &sysfs->attr_sprom); | 330 | device_remove_file(dev, &dev_attr_sprom); |
311 | goto out; | 331 | goto out; |
312 | } | 332 | } |
313 | 333 | ||
314 | void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) | 334 | void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) |
315 | { | 335 | { |
316 | struct device *dev = &bcm->pci_dev->dev; | 336 | struct device *dev = &bcm->pci_dev->dev; |
317 | struct bcm43xx_sysfs *sysfs = &bcm->sysfs; | ||
318 | 337 | ||
319 | device_remove_file(dev, &sysfs->attr_preamble); | 338 | device_remove_file(dev, &dev_attr_shortpreamble); |
320 | device_remove_file(dev, &sysfs->attr_interfmode); | 339 | device_remove_file(dev, &dev_attr_interference); |
321 | device_remove_file(dev, &sysfs->attr_sprom); | 340 | device_remove_file(dev, &dev_attr_sprom); |
322 | } | 341 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h index 57f14514e3e0..cc701df71e2a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h | |||
@@ -1,22 +1,6 @@ | |||
1 | #ifndef BCM43xx_SYSFS_H_ | 1 | #ifndef BCM43xx_SYSFS_H_ |
2 | #define BCM43xx_SYSFS_H_ | 2 | #define BCM43xx_SYSFS_H_ |
3 | 3 | ||
4 | #include <linux/device.h> | ||
5 | |||
6 | |||
7 | struct bcm43xx_sysfs { | ||
8 | struct device_attribute attr_sprom; | ||
9 | struct device_attribute attr_interfmode; | ||
10 | struct device_attribute attr_preamble; | ||
11 | }; | ||
12 | |||
13 | #define devattr_to_bcm(attr, attr_name) ({ \ | ||
14 | struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \ | ||
15 | __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \ | ||
16 | __p = container_of(__s, struct bcm43xx_private, sysfs); \ | ||
17 | __p; \ | ||
18 | }) | ||
19 | |||
20 | struct bcm43xx_private; | 4 | struct bcm43xx_private; |
21 | 5 | ||
22 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); | 6 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 3daee828ef4b..3edbb481a0a0 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -962,22 +962,22 @@ static const struct iw_priv_args bcm43xx_priv_wx_args[] = { | |||
962 | { | 962 | { |
963 | .cmd = PRIV_WX_SET_SHORTPREAMBLE, | 963 | .cmd = PRIV_WX_SET_SHORTPREAMBLE, |
964 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 964 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
965 | .name = "set_shortpreambl", | 965 | .name = "set_shortpreamb", |
966 | }, | 966 | }, |
967 | { | 967 | { |
968 | .cmd = PRIV_WX_GET_SHORTPREAMBLE, | 968 | .cmd = PRIV_WX_GET_SHORTPREAMBLE, |
969 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 969 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
970 | .name = "get_shortpreambl", | 970 | .name = "get_shortpreamb", |
971 | }, | 971 | }, |
972 | { | 972 | { |
973 | .cmd = PRIV_WX_SET_SWENCRYPTION, | 973 | .cmd = PRIV_WX_SET_SWENCRYPTION, |
974 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 974 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
975 | .name = "set_swencryption", | 975 | .name = "set_swencrypt", |
976 | }, | 976 | }, |
977 | { | 977 | { |
978 | .cmd = PRIV_WX_GET_SWENCRYPTION, | 978 | .cmd = PRIV_WX_GET_SWENCRYPTION, |
979 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 979 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
980 | .name = "get_swencryption", | 980 | .name = "get_swencrypt", |
981 | }, | 981 | }, |
982 | { | 982 | { |
983 | .cmd = PRIV_WX_SPROM_WRITE, | 983 | .cmd = PRIV_WX_SPROM_WRITE, |