[TEST] Does this help 1GB memory problem?
The patch below implements a quick-and-dirty approach to solving the problem of DMA with more than 1 GB memory. Unfortunately, I don't have the hardware to test it. The patch is intended for the wireless-2.6 tree. It will not work with 2.6.18-rcX. Please report your results, and the log messages. Thanks, Larry Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_dma.c === --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -215,15 +215,36 @@ void free_descriptor_buffer(struct bcm43 static int alloc_ringmemory(struct bcm43xx_dmaring *ring) { struct device *dev = (ring-bcm-pci_dev-dev); + int i, j; + struct { + dma_addr_t dmabase; + void *descbase; + } dma_trial[10]; - ring-descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, + for (i=0; i10; i++) { + ring-descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, (ring-dmabase), GFP_KERNEL); - if (!ring-descbase) { - printk(KERN_ERR PFX DMA ringmemory allocation failed\n); - return -ENOMEM; + if (!ring-descbase) { + printk(KERN_ERR PFX DMA ringmemory allocation failed\n); + return -ENOMEM; + } + if (ring-dmabase + BCM43xx_DMA_RINGMEMSIZE 0x3fff) + goto low_mem_ok; + dma_trial[i].descbase = ring-descbase; + dma_trial[i].dmabase = ring-dmabase; + printk(KERN_INFO PFX Trial %d: dmabase = 0x%.8x\n, i+1, ring-dmabase); } + printk(KERN_INFO PFX Unable to get DMA memory below 1 GB boundary.\n); + +low_mem_ok: memset(ring-descbase, 0, BCM43xx_DMA_RINGMEMSIZE); + if (i != 0) { + for (j=0; ji; j++)/* get rid of any trials that failed */ + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, + dma_trial[j].descbase, dma_trial[j].dmabase); + } + return 0; } ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
On Tuesday 19 September 2006 18:40, Larry Finger wrote: The patch below implements a quick-and-dirty approach to solving the problem of DMA with more than 1 GB memory. Unfortunately, I don't have the hardware to test it. The patch is intended for the wireless-2.6 tree. It will not work with 2.6.18-rcX. Please report your results, and the log messages. Q: Does this help 1GB memory problem? A: No ;) Please lookup old SVN archives, where I implemented such a dirty workaround like this. 1) We also need to have descriptor buffers under 1G 2) I think it's clear to you, that this is based on pure luck, as retrying 10 times can easily fail as well as only trying once. If you want 1G, get a device which supports this. Thanks, Larry Index: wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_dma.c === --- wireless-2.6.orig/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ wireless-2.6/drivers/net/wireless/bcm43xx/bcm43xx_dma.c @@ -215,15 +215,36 @@ void free_descriptor_buffer(struct bcm43 static int alloc_ringmemory(struct bcm43xx_dmaring *ring) { struct device *dev = (ring-bcm-pci_dev-dev); + int i, j; + struct { + dma_addr_t dmabase; + void *descbase; + } dma_trial[10]; - ring-descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, + for (i=0; i10; i++) { + ring-descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, (ring-dmabase), GFP_KERNEL); - if (!ring-descbase) { - printk(KERN_ERR PFX DMA ringmemory allocation failed\n); - return -ENOMEM; + if (!ring-descbase) { + printk(KERN_ERR PFX DMA ringmemory allocation failed\n); + return -ENOMEM; + } + if (ring-dmabase + BCM43xx_DMA_RINGMEMSIZE 0x3fff) + goto low_mem_ok; + dma_trial[i].descbase = ring-descbase; + dma_trial[i].dmabase = ring-dmabase; + printk(KERN_INFO PFX Trial %d: dmabase = 0x%.8x\n, i+1, ring-dmabase); } + printk(KERN_INFO PFX Unable to get DMA memory below 1 GB boundary.\n); + +low_mem_ok: memset(ring-descbase, 0, BCM43xx_DMA_RINGMEMSIZE); + if (i != 0) { + for (j=0; ji; j++)/* get rid of any trials that failed */ + dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, + dma_trial[j].descbase, dma_trial[j].dmabase); + } + return 0; } ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev -- Greetings Michael. ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
Am Dienstag 19 September 2006 18:50 schrieb Michael Buesch: If you want 1G, get a device which supports this. I am not affected by this issue but as mentioned earlier: could you fall back to non-dma mode? If not, you should fail completely instead of trying to run a setup that is know to not work correctly. HS ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
Michael Buesch wrote: On Tuesday 19 September 2006 18:40, Larry Finger wrote: Q: Does this help 1GB memory problem? A: No ;) Please lookup old SVN archives, where I implemented such a dirty workaround like this. 1) We also need to have descriptor buffers under 1G 2) I think it's clear to you, that this is based on pure luck, as retrying 10 times can easily fail as well as only trying once. If you want 1G, get a device which supports this. Sorry that I didn't see your workaround in the SVN archives. I found what Linville did for the b44 chip. In your estimation, should it be possible to implement a test for 30-bit hardware and more than 1 GB memory early enough to switch the interface to pio mode? Larry ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
On Tue, 2006-09-19 at 12:45 -0500, Larry Finger wrote: Michael Buesch wrote: On Tuesday 19 September 2006 18:40, Larry Finger wrote: Q: Does this help 1GB memory problem? A: No ;) Please lookup old SVN archives, where I implemented such a dirty workaround like this. 1) We also need to have descriptor buffers under 1G 2) I think it's clear to you, that this is based on pure luck, as retrying 10 times can easily fail as well as only trying once. If you want 1G, get a device which supports this. Sorry that I didn't see your workaround in the SVN archives. I found what Linville did for the b44 chip. In your estimation, should it be possible to implement a test for 30-bit hardware and more than 1 GB memory early enough to switch the interface to pio mode? Larry Must admit the patch seemed like a stretch, but tried it anyway, as predicted, the same exception still exists. OK, I have'nt been hacking the kernel for many years now but how does the Win XP driver then work with ndiswrapper. Surely it should be failing with a similar problem on the same hardware? From dmesg I see the following, this tells me there are both DMA and DMA32 available? On node 0 totalpages: 514181 DMA zone: 2384 pages, LIFO batch:0 DMA32 zone: 511797 pages, LIFO batch:31 I am assuming DMA is 16 bit, so is there no way to force the kernel to only return a DMA allocation 2^30. In other words from the DMA zone and not the DMA32 zone? ~Z~ ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
On Tue, 2006-09-19 at 18:50 +0200, Michael Buesch wrote: If you want 1G, get a device which supports this. This is really not an option. First and foremost reason is that I like many others use a notebook with built in hardware. So the option to simply replace the hardware is unrealistic at best. Secondly even newer hardware like the Acer Ferrari 5000, Asus Lamborghini and many more now supports memory way above 1GB. The Acer for instance supports upto 4GB RAM. Saying that there simply is no way to get a working driver for that kind of hardware will only cause people to rethink moving to linux and sticky with what works Win XP / Vista. Now I'm no Win fan by any chance and I have been a long supporter, user and hacker of linux since the days when the network drivers were still embeded inside the kernel, back in '94. We've come along way since then and I simply can't believe that there is absolutely no way of working around this problem. BTW. The Acer Ferrari 5000 still uses a Broadcom chipset for it's wireless hadrware. ~Z~ ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: Support Quality display
On 9/19/06, Larry Finger [EMAIL PROTECTED] wrote: Tsai Dung-Bang wrote: Dear All Thanks for this great driver. I would like to know when will support quality display? When I use iwconfig, the quality always displays 100% and it's inconvenience to choice which AP is better for me. ps. I use softmac version driver built in kernel 2.6.17 2.6.18 will have a better quality display. The new code sets the quality uses a It seems to me it's not in 2.6.18. Best regards, Bin guessed value for the hypothetical rssi_max and sets the quality as 100 * rssi/rssi_max. On my system with my Linksys WPC54G about 2 meter from the AP, my quality is 86%. If I take the computer into the living room, which is about 15 m from the AP, the quality drops to ~50%. AFAIK, there is no standard way to calculate quality. Note: iwconfig gives the same quality, signal and noise values as are found in /proc/net/wireless. If you use 'iwlist s', the quality is always 100%, but the signal and noise values are correct. I have not tried to fix this bug as there are more important ones to be squashed. Larry ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
Zahir Toufie wrote: Must admit the patch seemed like a stretch, but tried it anyway, as predicted, the same exception still exists. OK, I have'nt been hacking the kernel for many years now but how does the Win XP driver then work with ndiswrapper. Surely it should be failing with a similar problem on the same hardware? From what I understand, there is a long-standing bug in the DMA memory allocation routine. The net effect is that it either makes the full 4 GB (32 bit) range available, or it limits one to a 16 Mb (24 bit) limit. A problem is that for large systems, all memory in the lower 16 MB is probably used before the bcm43xx driver tries to get its allocation. This faulty allocation scheme is maintained to keep heritage devices from breaking. Windows probably has implemented the allocation scheme correctly. I'm not sure how ndiswrapper gets around the problem. What I would like to do is find where the distinction is made between 32- and 24-bit DMA and prepare a mod that an individual user could apply to make their interface work. It should be safe to assume that any system with 2 GB of memory probably doesn't have any such heritage equipment! In any case, this patch would _NEVER_ make it into the stable tree. So far, I have not found and/or understood this part of the code. Any pointers as to where to look would be appreciated. Larry ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: [TEST] Does this help 1GB memory problem?
On Tuesday 19 September 2006 20:55, Zahir Toufie wrote: On Tue, 2006-09-19 at 18:50 +0200, Michael Buesch wrote: If you want 1G, get a device which supports this. This is really not an option. First and foremost reason is that I like many others use a notebook with built in hardware. So the option to simply replace the hardware is unrealistic at best. Secondly even newer hardware like the Acer Ferrari 5000, Asus Lamborghini and many more now supports memory way above 1GB. The Acer for instance supports upto 4GB RAM. Saying that there simply is no way to get a working driver for that kind of hardware will only cause people to rethink moving to linux and sticky with what works Win XP / Vista. Now I'm no Win fan by any chance and I have been a long supporter, user and hacker of linux since the days when the network drivers were still embeded inside the kernel, back in '94. We've come along way since then and I simply can't believe that there is absolutely no way of working around this problem. Oh, come one. If you are a long supporter, user and hacker, you can surely come up with a good solution that a) works and b) is not a damn ugly hack This is the same issue as with PCI-E hardware. _Lots_ of people request it, but nobody is going to implement and test it. Well, I can't do it for you, as I don't have the hardware. -- Greetings Michael. ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: Support Quality display
Bin Zhang wrote: On 9/19/06, Larry Finger [EMAIL PROTECTED] wrote: It seems to me it's not in 2.6.18. I should not have trusted my memory. The change missed the 2.6.18 window, but it is in wireless-2.6 and will be in 2.6.19. Larry ___ Bcm43xx-dev mailing list Bcm43xx-dev@lists.berlios.de https://lists.berlios.de/mailman/listinfo/bcm43xx-dev
Re: Support Quality display
The patch to add quality to 2.6.18 is attached. Larry diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 5c36e29..0ca9f29 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c @@ -47,6 +47,8 @@ #include bcm43xx_phy.h #define BCM43xx_WX_VERSION 18 #define MAX_WX_STRING 80 +/* FIXME: the next line is a guess as to what the maximum RSSI value might be */ +#define RX_RSSI_MAX60 static int bcm43xx_wx_get_name(struct net_device *net_dev, @@ -226,16 +228,15 @@ static int bcm43xx_wx_get_rangeparams(st range-throughput = 27 * 1000 * 1000; range-max_qual.qual = 100; - /* TODO: Real max RSSI */ - range-max_qual.level = 3; - range-max_qual.noise = 100; - range-max_qual.updated = 7; - - range-avg_qual.qual = 70; - range-avg_qual.level = 2; - range-avg_qual.noise = 40; - range-avg_qual.updated = 7; - + range-max_qual.level = 152; /* set floor at -104 dBm (152 - 256) */ + range-max_qual.noise = 152; + range-max_qual.updated = IW_QUAL_ALL_UPDATED; + + range-avg_qual.qual = 50; + range-avg_qual.level = 0; + range-avg_qual.noise = 0; + range-avg_qual.updated = IW_QUAL_ALL_UPDATED; + range-min_rts = BCM43xx_MIN_RTS_THRESHOLD; range-max_rts = BCM43xx_MAX_RTS_THRESHOLD; range-min_frag = MIN_FRAG_THRESHOLD; @@ -827,6 +828,10 @@ static struct iw_statistics *bcm43xx_get struct bcm43xx_private *bcm = bcm43xx_priv(net_dev); struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); struct iw_statistics *wstats; + struct ieee80211_network *network = NULL; + static int tmp_level = 0; + static int tmp_qual = 0; + unsigned long flags; wstats = bcm-stats.wstats; if (!mac-associated) { @@ -844,16 +849,28 @@ static struct iw_statistics *bcm43xx_get wstats-qual.level = 0; wstats-qual.noise = 0; wstats-qual.updated = 7; - wstats-qual.updated |= IW_QUAL_NOISE_INVALID | - IW_QUAL_QUAL_INVALID | IW_QUAL_LEVEL_INVALID; + wstats-qual.updated |= IW_QUAL_ALL_UPDATED; return wstats; } /* fill in the real statistics when iface associated */ - wstats-qual.qual = 100; // TODO: get the real signal quality - wstats-qual.level = 3 - bcm-stats.link_quality; + spin_lock_irqsave(mac-ieee-lock, flags); + list_for_each_entry(network, mac-ieee-network_list, list) { + if (!memcmp(mac-associnfo.bssid, network-bssid, ETH_ALEN)) { + if (!tmp_level) { /* get initial values */ + tmp_level = network-stats.signal; + tmp_qual = network-stats.rssi; + } else {/* smooth results */ + tmp_level = (15 * tmp_level + network-stats.signal)/16; + tmp_qual = (15 * tmp_qual + network-stats.rssi)/16; + } + break; + } + } + spin_unlock_irqrestore(mac-ieee-lock, flags); + wstats-qual.level = tmp_level; + wstats-qual.qual = 100*tmp_qual/RX_RSSI_MAX; wstats-qual.noise = bcm-stats.noise; - wstats-qual.updated = IW_QUAL_QUAL_UPDATED | IW_QUAL_LEVEL_UPDATED | - IW_QUAL_NOISE_UPDATED; + wstats-qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM; wstats-discard.code = bcm-ieee-ieee_stats.rx_discards_undecryptable; wstats-discard.retries = bcm-ieee-ieee_stats.tx_retry_limit_exceeded; wstats-discard.nwid = bcm-ieee-ieee_stats.tx_discards_wrong_sa; diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c index 6dbd855..2a4e37f 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.c @@ -492,16 +492,16 @@ int bcm43xx_rx(struct bcm43xx_private *b memset(stats, 0, sizeof(stats)); stats.mac_time = le16_to_cpu(rxhdr-mactime); - stats.rssi = bcm43xx_rssi_postprocess(bcm, rxhdr-rssi, is_ofdm, + stats.rssi = rxhdr-rssi; + stats.signal = bcm43xx_rssi_postprocess(bcm, rxhdr-rssi, is_ofdm, !!(rxflags1 BCM43xx_RXHDR_FLAGS1_2053RSSIADJ), !!(rxflags3 BCM43xx_RXHDR_FLAGS3_2050RSSIADJ)); - stats.signal = rxhdr-signal_quality; //FIXME +// stats.signal = rxhdr-signal_quality; //FIXME //TODO stats.noise = if (is_ofdm) stats.rate = bcm43xx_plcp_get_bitrate_ofdm(plcp); else stats.rate = bcm43xx_plcp_get_bitrate_cck(plcp); -//printk(RX ofdm %d, rate == %u\n, is_ofdm, stats.rate);