Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
On Thu, Apr 27, 2006 at 02:12:09PM -0700, Caitlin Bestler ([EMAIL PROTECTED]) wrote: > So the real issue is when there is an intelligent device that > uses hardware packet classification to place the packet in > the correct ring. We don't want to bypass packet filtering, > but it would be terribly wasteful to reclassify the packet. > Intelligent NICs will have packet classification capabilities > to support RDMA and iSCSI. Those capabilities should be available > to benefit SOCK_STREAM and SOCK_DGRAM users as well without it > being a choice of either turning all stack control over to > the NIC or ignorign all NIC capabilities beyound pretending > to be a dumb Ethernet NIC. Btw, how is it supposed to work without header split capabale hardware? -- Evgeniy Polyakov - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
On Thu, Apr 27, 2006 at 01:09:18PM -0700, David S. Miller ([EMAIL PROTECTED]) wrote: > Evgeniy, the difference between this and your work is that you did not > have an intelligent piece of hardware that could be told to recognize > flows, and only put packets for a specific flow into that's flow's > buffer pool. There are the most "intellegent" NICs which use MMIO copy like Realtek 8139 :) which were used in receiving zero-copy [1] project. There was special alorithm researched for receiving zero-copy [1] to allow to put not page-aligned TCP frames into pages, but there was other problem when page was committed, since no byte commit is allowed in VFS. In this case we do not have that problem, but instead we must force userspace to be very smart when dealing with mapped buffers, instead of simple recv(). And for sending it must be even smarter, since data must be properly aligned. And what about crappy hardware which can DMA only into limited memory area, or NIC that can not do sg? Or do we need remapping for NIC that can not do checksum calculation? > > If we want to dma data from nic into premapped userspace area, this will > > strike with message sizes/misalignment/slow read and so on, so > > preallocation has even more problems. > > I do not really think this is an issue, we put the full packet into > user space and teach it where the offset is to the actual data. > We'll do the same things we do today to try and get the data area > aligned. User can do whatever is logical and relevant on his end > to deal with strange cases. > > In fact we can specify that card has to take some care to get data > area of packet aligned on say an 8 byte boundary or something like > that. When we don't have hardware assist, we are going to be doing > copies. Userspace must be too smart, and as we saw with various java tests, it can not be so even now. And what if pages are shared and several threads are trying to write into the same remapped area? Will we use COW and be blamed like Mach and FreeBSD developers? :) > > I do think that significant win in VJ's tests belongs not to remapping > > and cache-oriented changes, but to move all protocol processing into > > process' context. > > I partly disagree. The biggest win is eliminating all of the control > overhead (all of "softint RX + protocol demux + IP route lookup + > socket lookup" is turned into single flow demux), and the SMP safe > data structure which makes it realistic enough to always move the bulk > of the packet work to the socket's home cpu. > > I do not think userspace protocol implementation buys enough to > justify it. We have to do the protection switch in and out of kernel > space anyways, so why not still do the protected protocol processing > work in the kernel? It is still being done on the user's behalf, > contributes to his time slice, and avoids all of the terrible issues > of userspace protocol implementations. After hard irq softirq is scheduled, then later userspace is scheduled, at least 2 context switch just to move a packet, and "slow" userspace code is interrupted by both irqs again... I run some tests on ppc32 embedded boards which showed that rescheduling latency tend to have milliseconds delay sometimes (about 4 running processes on 200mhz cpu), although we do not have some real-time requirements here it is not a good sign... > And I also want to note that even if the whole idea explodes and > cannot be made to work, there are good arguments for transitioning > to SKB'less drivers for their own sake. So work will really not > be lost. > > Let's have 100 different implementations of net channels! :-) :) -- Evgeniy Polyakov - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: E1000 stopped transmitting in rc3.
Dave Jones wrote: With 2.6.17-rc3, my E1000 won't get a dhcp lease. Looking at tcpdump and ifconfig output, it's easy to see why. It's recieving packets, but the packets transmitted field of ifconfig never increases. The last version I have built that worked ok was 2.6.17rc2-git3 *puzzled* the only patch between 2.6.17rc2 and 2.6.17rc3 contains an rx-path patch, but nothing that affects tx. All the other patches sent earlier are queued for 2.6.18 so they don't apply. Auke - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [LARTC] how to change classful netem loss probability?
And if its not possible to change the probability, is there another method I can use instead? > Hi, > > I am using netem to add loss and then adding another qdisc within netem > according to the wiki. Then i want to change the netem drop probability > without having to delete the qdisc and recreate it. I try it but I get > invalid argument: > > thorium-ini hedpe # tc qdisc add dev ath0 root handle 1:0 netem drop 1% > thorium-ini hedpe # tc qdisc add dev ath0 parent 1:1 handle 10: xcp > capacity 54Mbit limit 500 thorium-ini hedpe # tc -s qdisc ls dev ath0 qdisc > netem 1: limit 1000 loss 1% Sent 0 bytes 0 pkts (dropped 0, overlimits 0) > qdisc xcp 10: parent 1:1 capacity 52734Kbit limit 500p Sent 0 bytes 0 pkts > (dropped 0, overlimits 0) thorium-ini hedpe # tc qdisc change dev ath0 > root handle 1:0 netem drop 1% RTNETLINK answers: Invalid argument > thorium-ini hedpe # tc qdisc change dev ath0 root netem drop 1% RTNETLINK > answers: Invalid argument > > any ideas? > > Thanks! George ___ LARTC mailing > list LARTC@mailman.ds9a.nl > http://mailman.ds9a.nl/cgi-bin/mailman/listinfo/lartc > > -- - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 20/24] NET: e1000: Update truesize with the length of the packet for packet split
-stable review patch. If anyone has any objections, please let us know. -- Update skb with the real packet size. Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]> Signed-off-by: Auke Kok <[EMAIL PROTECTED]> Signed-off-by: John Ronciak <[EMAIL PROTECTED]> Signed-off-by: Greg Kroah-Hartman <[EMAIL PROTECTED]> --- drivers/net/e1000/e1000_main.c |1 + 1 file changed, 1 insertion(+) --- linux-2.6.16.11.orig/drivers/net/e1000/e1000_main.c +++ linux-2.6.16.11/drivers/net/e1000/e1000_main.c @@ -3851,6 +3851,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt skb_shinfo(skb)->nr_frags++; skb->len += length; skb->data_len += length; + skb->truesize += length; } e1000_rx_checksum(adapter, staterr, -- - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
E1000 stopped transmitting in rc3.
With 2.6.17-rc3, my E1000 won't get a dhcp lease. Looking at tcpdump and ifconfig output, it's easy to see why. It's recieving packets, but the packets transmitted field of ifconfig never increases. The last version I have built that worked ok was 2.6.17rc2-git3 NIC is .. 03:0e.0 Ethernet controller: Intel Corporation 82545GM Gigabit Ethernet Controller (rev 04) (8086:1026) Dave -- http://www.codemonkey.org.uk - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/10] [IOAT] I/OAT patches repost
Chris Leech wrote: Netperf2 TOT now accesses the buffer that was just recv()'d rather than the one that is about to be recv()'d. We've posted netperf2 results with I/OAT enabled/disabled and the data access option on/off at http://kernel.org/pub/linux/kernel/people/grover/ioat/netperf-icb-1.5-postscaling-both.pdf calling it netperf data verification is a quite overstated - all netperf does is read from or write to the buffer. there is no check of data integrity or anything rick jones - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/10] [IOAT] I/OAT patches repost
> Netperf2 TOT now accesses the buffer that was just recv()'d rather than > the one that is about to be recv()'d. We've posted netperf2 results with I/OAT enabled/disabled and the data access option on/off at http://kernel.org/pub/linux/kernel/people/grover/ioat/netperf-icb-1.5-postscaling-both.pdf This link has also been added to the I/OAT page on the LinuxNet wiki. - Chris - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/10] [IOAT] I/OAT patches repost
On 4/20/06, David S. Miller <[EMAIL PROTECTED]> wrote: > Yes, and it means that the memory bandwidth costs are equivalent > between I/O AT and cpu copy. The following is a response from the I/OAT architects. I only point out that this is not coming directly from me because I have not seen the data to verify the claims regarding the speed of a copy vs a load and the cost of the rep mov instruction. I'll encourage more direct participation in this discussion from the architects moving forward. - Chris Let's talk about the caching benefits that is seemingly lost when using the DMA engine. The intent of the DMA engine is to save CPU cycles spent in copying data (rep mov). In cases where the destination is already warm in cache (due to destination buffer re-use) and the source is in memory, the cycles spent in a host copy is not just due to the cache misses it encounters in the process of bringing in the source but also due to the execution of rep move itself within the host core. If you contrast this to simply touching (loading) the data residing in memory, the cost of this load is primarily the cost of the cache misses and not so much CPU execution time. Given this, some of the following points are noteworthy: 1. While the DMA engine forces the destination to be in memory and touching it may cause the same number of observable cache misses as a host copy assuming a cache warmed destination, the cost of the host copy (in terms of CPU cycles) is much more than the cost of the touch. 2. CPU hardware prefetchers do a pretty good job of staying ahead of the fetch stream to minimize cache misses. So for loads of medium to large buffers, cache misses form a much smaller component of the data fetch time…most of it is dominated by front side bus (FSB) or Memory bandwidth. For small buffers, we do not use the DMA engine but if we had to, we would insert SW prefetches that do reasonably well. 3. If the destination wasn't already warm in cache i.e., it was in memory or some CPU other cache, host copy will have to snoop and bring the destination in and will encounter additional misses on the destination buffer as well. These misses are the same as those encountered in #1 above when using the DMA engine and touching the data afterwards. So in effect it becomes a wash when compared to the DMA engine's behavior. The case where the destination is already warm in cache is common in benchmarks such as iperf, ttcp etc. where the same buffer is reused over and over again. Real applications typically will not exhibit this aggressive buffer re-use behavior. 4. It may take a large number of packets (and several interrupts) to satisfy a large posted buffer (say 64KB). Even if you use host copy to warm the cache with the destination, there is no guarantee that some or all of the destination will stay in the cache before the application has a chance to read the data. 5. The source data payload (skb ->data) is typically needed only once for the copy and has no use later. The host copy brings it into the cache and may end up polluting the cache, and consuming FSB bandwidth whereas the DMA engine avoids this altogether. The IxChariot data posted earlier that touches the data and yet shows I/OAT benefit is due to some of the reasons above. Bottom line is that I agree with the cache benefit argument of host copy for small buffers (64B to 512B) but for larger buffers and certain application scenarios (destination in memory), the DMA engine will show better performance regardless of where the destination buffer resided to begin with and where it is accessed from. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: IP1000 gigabit nic driver
Francois Romieu wrote: David Gómez <[EMAIL PROTECTED]> : [...] Does anybody in this list know why the IP1000 driver is not included in the kernel ? Afaik the driver has never been submitted for inclusion. At least not on netdev@vger.kernel.org (hint, hint). [...] The card in question is: Sundance Technology Inc IC Plus IP1000 and the driver can be found in sundance web, sources URL please ? included. I tried to contact the author but my email bounced. There's no LICENSE in the source, just copyrigth sentences in the .c files, so i'm not sure under which license it's distributed :-?. /me goes to http://www.icplus.com.tw/driver-pp-IP1000A.html $ unzip -c IP1000A-Linux-driver-v2.09f.zip | grep MODULE_LICENSE MODULE_LICENSE("GPL"); It's a bit bloaty but it does not seem too bad (not mergeable "as is" though). Do you volunteer to test random cra^W^W carefully engineered code on your computer to help the rework/merging process ? I finally got around to putting a 2nd NIC in my box that has one of this chips and was going to start fixing the driver up and preparing it for submission this weekend. Or I might try rewriting from scratch based on the datasheet depending on how horrific the code looks on closer inspection. Not got a whole lot of time to do this so no timescale for completion... David Vrabel - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 20/32] rt2x00: byte ordering correctness
On Fri, Apr 28, 2006 at 12:03:12AM +0200, Ivo van Doorn wrote: > From: Ivo van Doorn <[EMAIL PROTECTED]> > > Fix various little/big endian conversions. > rt2500pci should use cpu_to_le32 and rt2500usb should not. While you're at it can you add __be* annotations to the hardware datastructures so the endianess handling can be verified using sparse? - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/32] rt2x00: use pci_*_consistent for DMA mapping
On Fri, Apr 28, 2006 at 12:02:52AM +0200, Ivo van Doorn wrote: > From: Ivo van Doorn <[EMAIL PROTECTED]> > > Instead of dma_*_coherent > use pci_*consistent functions. No point in doing that, quite reverse as you use the gfp_mask argument which is a (small) pessimation here. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 11/32] rt2x00: Add more register defines
From: Ivo van Doorn <[EMAIL PROTECTED]> During the work on rt2x00 several new registers could be defined. This will add all those new registers, and will in the next couple of patches be used. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 21:36:19.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 21:43:27.0 +0200 @@ -43,6 +43,13 @@ #define RF5222 0x0010 /* + * RT2560 version + */ +#define RT2560_VERSION_B 2 +#define RT2560_VERSION_C 3 +#define RT2560_VERSION_D 4 + +/* * Control/Status Registers(CSR). * Some values are set in TU, whereas 1 TU == 1024 us. */ @@ -558,15 +565,23 @@ * Statistic Register. * CNT1: PLCP error count. * CNT2: Long error count. - * CNT3: CCA false alarm count. - * CNT4: Rx FIFO overflow count. - * CNT5: Tx FIFO underrun count. */ #define TIMECSR2 0x00a8 #define CNT1 0x00ac #define CNT2 0x00b0 #define TIMECSR3 0x00b4 + +/* + * CNT3: CCA false alarm count. + */ #define CNT3 0x00b8 +#define CNT3_FALSE_CCA FIELD32(0x) + +/* + * Statistic Register. + * CNT4: Rx FIFO overflow count. + * CNT5: Tx FIFO underrun count. + */ #define CNT4 0x00bc #define CNT5 0x00c0 @@ -840,6 +855,10 @@ * BBPCSR1: BBP TX configuration. */ #define BBPCSR10x015c +#define BBPCSR1_CCKFIELD32(0x0003) +#define BBPCSR1_CCK_FLIP FIELD32(0x0004) +#define BBPCSR1_OFDM FIELD32(0x0003) +#define BBPCSR1_OFDM_FLIP FIELD32(0x0004) /* * Dual band configuration registers. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.h 2006-04-27 21:42:29.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h 2006-04-27 21:43:27.0 +0200 @@ -160,10 +160,28 @@ #define MAC_CSR19 0x0426 /* - * LED control registers. + * MAC_CSR20: LED control register. + * ACTIVITY: 0: idle, 1: active. + * LINK: 0: linkoff, 1: linkup. + * ACTIVITY_POLARITY: 0: active low, 1: active high. */ #define MAC_CSR20 0x0428 +#define MAC_CSR20_ACTIVITY FIELD16(0x0001) +#define MAC_CSR20_LINK FIELD16(0x0002) +#define MAC_CSR20_ACTIVITY_POLARITYFIELD16(0x0004) + +/* + * MAC_CSR21: LED control register. + * ON_PERIOD: On period, default 70ms. + * OFF_PERIOD: Off period, default 30ms. + */ #define MAC_CSR21 0x042a +#define MAC_CSR21_ON_PERIODFIELD16(0x00ff) +#define MAC_CSR21_OFF_PERIOD FIELD16(0xff00) + +/* + * Collision window control register. + */ #define MAC_CSR22 0x042c /* @@ -373,10 +391,18 @@ /* * BBP pre-TX registers. * PHY_CSR5: BBP pre-TX CCK. - * PHY_CSR6: BBP pre-TX OFDM. */ #define PHY_CSR5 0x04ca +#define PHY_CSR5_CCK FIELD16(0x0003) +#define PHY_CSR5_CCK_FLIP FIELD16(0x0004) + +/* + * BBP pre-TX registers. + * PHY_CSR6: BBP pre-TX OFDM. + */ #define PHY_CSR6 0x04cc +#define PHY_CSR6_OFDM FIELD16(0x0003) +#define PHY_CSR6_OFDM_FLIP FIELD16(0x0004) /* * PHY_CSR7: BBP access register 0. @@ -459,6 +485,12 @@ * HW MAC address. */ #define EEPROM_MAC_ADDR0x0004 +#define EEPROM_MAC_ADDR_BYTE0 FIELD16(0x00ff) +#define EEPROM_MAC_ADDR_BYTE1 FIELD16(0xff00) +#define EEPROM_MAC_ADDR_BYTE2 FIELD16(0x00ff) +#define EEPROM_MAC_ADDR_BYTE3 FIELD16(0xff00) +#define EEPROM_MAC_ADDR_BYTE4 FIELD16(0x00ff) +#define EEPROM_MAC_ADDR_BYTE5 FIELD16(0xff00) /* * EEPROM antenna. pgpJBQTAX9fIU.pgp Description: PGP signature
[PATCH 13/32] rt2x00: Tune link depending on link quality
From: Ivo van Doorn <[EMAIL PROTECTED]> Add link tuning capabilities, and call this function every time the rxdone handler has finished. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:42:29.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:45:08.0 +0200 @@ -618,6 +618,41 @@ rt2400pci_config_rate(struct rt2x00_pci } /* + * Link tuning + */ +static void +rt2400pci_link_tuner(struct rt2x00_pci *rt2x00pci) +{ + u8 reg; + charfalse_cca_delta; + + /* +* Read false CCA counter. +*/ + rt2x00_bbp_read(rt2x00pci, 39, ®); + + /* +* Determine difference with previous CCA counter. +*/ + false_cca_delta = reg - rt2x00pci->false_cca; + rt2x00pci->false_cca = reg; + + /* +* Check if the difference is higher than the +* threshold and if so, tune the link. +*/ + if (false_cca_delta >= 8) { + /* +* Read and update RX AGC VGC. +*/ + rt2x00_bbp_read(rt2x00pci, 13, ®); + reg += 2; + if (reg < 0x20) + rt2x00_bbp_write(rt2x00pci, 13, reg); + } +} + +/* * TX descriptor initialization */ static void @@ -779,6 +814,9 @@ rt2400pci_rxdone(void *data) memcpy(skb_put(skb, size), entry->data_addr, size); + ring->params.rx.ssi = + rt2x00_get_field32(rxd->word2, RXD_W2_RSSI); + __ieee80211_rx(net_dev, skb, &ring->params.rx); } @@ -786,6 +824,11 @@ rt2400pci_rxdone(void *data) rt2x00_ring_index_inc(&rt2x00pci->rx); } + + /* +* Tune link for optimal performance. +*/ + rt2400pci_link_tuner(rt2x00pci); } static void diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:36:19.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:45:08.0 +0200 @@ -926,6 +926,11 @@ struct rt2x00_pci{ struct workqueue_struct *workqueue; /* +* False CCA count. +*/ + int false_cca; + + /* * EEPROM bus width. */ u8 eeprom_width; diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:42:29.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:45:08.0 +0200 @@ -661,6 +661,51 @@ rt2500pci_config_rate(struct rt2x00_pci } /* + * Link tuning + */ +static void +rt2500pci_link_tuner(struct rt2x00_pci *rt2x00pci, char rssi) +{ + u32 reg; + u8 reg_r17; + + /* +* Don't perform any tuning during scan. +*/ + if (rt2x00pci->scan) + return; + + rt2x00_register_read(rt2x00pci, CSR0, ®); + rt2x00_bbp_read(rt2x00pci, 17, ®_r17); + + if (reg < RT2560_VERSION_D) + goto dynamic_cca_tune; + + if (rssi < 40) { + if (reg_r17 >= 0x41) + rt2x00_bbp_write(rt2x00pci, 17, reg_r17); + return; + } else if (rssi >= 62) { + if (reg_r17 != 0x50) + rt2x00_bbp_write(rt2x00pci, 17, 0x50); + return; + } else if (reg_r17 >= 0x41) { + rt2x00_bbp_write(rt2x00pci, 17, reg_r17); + return; + } + +dynamic_cca_tune: + rt2x00_register_read(rt2x00pci, CNT3, ®); + + reg = rt2x00_get_field32(reg, CNT3_FALSE_CCA); + + if (reg > 512 && reg_r17 < 0x40) + rt2x00_bbp_write(rt2x00pci, 17, ++reg_r17); + else if (reg < 100 && reg_r17 > 0x32) + rt2x00_bbp_write(rt2x00pci, 17, --reg_r17); +} + +/* * TX descriptor initialization */ static void @@ -819,6 +864,14 @@ rt2500pci_rxdone(void *data) struct sk_buff *skb; struct rxd *rxd; u16 size; + u8 rssi_count; + chartotal_rssi; + + /* +* Initialize variable for average RSSI calculation. +*/ + rssi_count = 0;
[PATCH 24/32] rt2x00: Use correct desc_addr and data_addr
From: Ivo van Doorn <[EMAIL PROTECTED]> USB buffer don't have a seperate descriptor ring and data ring. The location of the descriptor area and data area depends on the type of ring. Add functions to determine the correct location and use these instead of the invalid desc_addr and data_addr pointers. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:54:33.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:55:14.0 +0200 @@ -740,7 +740,7 @@ rt2500usb_rxdone(void *data) while (1) { entry = rt2x00_get_data_entry(ring); - rxd = entry->desc_addr; + rxd = rt2x00usb_rxdesc_addr(entry); /* * There has been a problem. Ignore packet. @@ -769,7 +769,8 @@ rt2500usb_rxdone(void *data) skb_reserve(skb, NET_IP_ALIGN); - memcpy(skb_put(skb, size), entry->data_addr, size); + memcpy(skb_put(skb, size), + rt2x00usb_rxdata_addr(entry), size); rt2x00usb->rx_params.ssi = rt2x00_get_field32(rxd->word1, RXD_W1_RSSI); @@ -805,7 +806,7 @@ rt2500usb_txdone(void *data) while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); - txd = entry->desc_addr; + txd = rt2x00usb_txdesc_addr(entry); ack = rt2x00_get_field32(txd->word0, TXD_W0_ACK); @@ -937,16 +938,14 @@ rt2500usb_alloc_ring( entry[counter].urb = usb_alloc_urb(0, GFP_KERNEL); else entry[counter].urb = NULL; - if (entry[counter].urb == NULL) + if (!entry[counter].urb) status = -ENOMEM; entry[counter].skb = NULL; - entry[counter].desc_addr = ring->data_addr - + (counter * ring->desc_size); entry[counter].data_addr = ring->data_addr - + (ring->stats.limit * ring->desc_size) + + (counter * ring->desc_size) + (counter * ring->data_size); entry[counter].data_dma = ring->data_dma - + (ring->stats.limit * ring->desc_size) + + (counter * ring->desc_size) + (counter * ring->data_size); } @@ -959,7 +958,7 @@ rt2500usb_free_ring(struct rt2x00_usb *r struct data_entry *entry; u8 counter; - if (ring->entry) + if (!ring->entry) goto exit; entry = (struct data_entry*)ring->entry; @@ -1091,9 +1090,9 @@ rt2500usb_init_registers(struct rt2x00_u return -EBUSY; rt2x00_vendor_request(rt2x00usb, USB_DEVICE_MODE, - USB_VENDOR_REQUEST_OUT, USB_MODE_TEST, 0x00, NULL, 0); + USB_VENDOR_REQUEST_OUT, 0x00, USB_MODE_TEST, NULL, 0); rt2x00_vendor_request(rt2x00usb, USB_SINGLE_WRITE, - USB_VENDOR_REQUEST_OUT, 0x0308, 0x00f0, NULL, 0); + USB_VENDOR_REQUEST_OUT, 0x0308, 0xf0, NULL, 0); rt2x00_register_write(rt2x00usb, TXRX_CSR2, 0x0001); rt2x00_register_write(rt2x00usb, MAC_CSR13, 0x); @@ -1242,9 +1241,9 @@ rt2500usb_tx(struct net_device *net_dev, return NET_RX_DROP; entry = rt2x00_get_data_entry(ring); - txd = entry->desc_addr; + txd = rt2x00usb_txdesc_addr(entry); - memcpy(entry->data_addr, skb->data, skb->len); + memcpy(rt2x00usb_txdata_addr(entry), skb->data, skb->len); rt2500usb_write_tx_desc(rt2x00usb, txd, skb, control); entry->skb = skb; @@ -1621,8 +1620,9 @@ rt2500usb_beacon_update(struct net_devic */ control->queue = IEEE80211_TX_QUEUE_BEACON; - memcpy(entry->data_addr, skb->data, skb->len); - rt2500usb_write_tx_desc(rt2x00usb, entry->desc_addr, skb, control); + memcpy(rt2x00usb_txdata_addr(entry), skb->data, skb->len); + rt2500usb_write_tx_desc(rt2x00usb, + rt2x00usb_txdesc_addr(entry), skb, control); usb_fill_bulk_urb( entry->urb, @@ -1658,6 +1658,14 @@ rt2500usb_init_eeprom(struct rt2x00_usb rt2x00_set_chip(&rt2x00usb->chip, RT2570, rt2x00_get_field16(eeprom, EEPROM_ANTENNA_RF_TYPE)); + if (!rt2x00_rf(&rt2x00usb->chip, RF2522) + && !rt2x00_rf(&rt2x00usb->chip, RF2523) + && !rt2x00_rf(&rt2x00usb->chip, RF2524) + && !rt2x00_rf(&rt2x00usb->chip, RF2525) + && !rt2x00_rf(&rt2x00usb->chip, RF2525E) + && !rt2x00_rf(&rt2x
[PATCH 15/32] rt2x00: Move rx_params to correct location
From: Ivo van Doorn <[EMAIL PROTECTED]> Store rx_params seperately outside the ring structure. This is more safer and required because of some changes in the way the rings are stored in the structure in the following patches. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:47:22.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:47:52.0 +0200 @@ -475,8 +475,8 @@ rt2400pci_config_channel(struct rt2x00_p /* * Update active info for RX. */ - rt2x00pci->rx.params.rx.freq = freq; - rt2x00pci->rx.params.rx.channel = channel; + rt2x00pci->rx_params.freq = freq; + rt2x00pci->rx_params.channel = channel; /* * Clear false CRC during channel switch. @@ -534,7 +534,7 @@ rt2400pci_config_antenna(struct rt2x00_p /* * Update active info for RX. */ - rt2x00pci->rx.params.rx.antenna = antenna; + rt2x00pci->rx_params.antenna = antenna; } static void @@ -814,10 +814,10 @@ rt2400pci_rxdone(void *data) memcpy(skb_put(skb, size), entry->data_addr, size); - ring->params.rx.ssi = + rt2x00pci->rx_params.ssi = rt2x00_get_field32(rxd->word2, RXD_W2_RSSI); - __ieee80211_rx(net_dev, skb, &ring->params.rx); + __ieee80211_rx(net_dev, skb, &rt2x00pci->rx_params); } rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1); @@ -981,8 +981,8 @@ rt2400pci_alloc_ring( /* * Initialize ring parameters. */ - ring->params.tx.cw_min = 5; /* cw_min: 2^5 = 32. */ - ring->params.tx.cw_max = 10;/* cw_max: 2^10 = 1024. */ + ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ + ring->tx_params.cw_max = 10;/* cw_max: 2^10 = 1024. */ rt2x00_ring_index_clear(ring); @@ -1374,7 +1374,7 @@ rt2400pci_tx(struct net_device *net_dev, * queue. This is the alternative since we cannot * set the CWmin and CWmax per descriptor. */ - rt2400pci_config_cw(rt2x00pci, &ring->params.tx); + rt2400pci_config_cw(rt2x00pci, &ring->tx_params); rt2x00_register_write(rt2x00pci, TXCSR0, reg); return 0; @@ -1544,7 +1544,7 @@ rt2400pci_config_update(void *data) /* * Update active info for RX. */ - rt2x00pci->rx.params.rx.phymode = conf->phymode; + rt2x00pci->rx_params.phymode = conf->phymode; } static int @@ -1599,7 +1599,7 @@ rt2400pci_scan(void *data) * Switch channel and update active info for RX. */ if (rt2x00pci->scan->state == IEEE80211_SCAN_START) { - rt2x00pci->rx.params.rx.phymode = + rt2x00pci->rx_params.phymode = rt2x00pci->scan->conf.scan_phymode; rt2400pci_config_channel(rt2x00pci, @@ -1610,7 +1610,7 @@ rt2400pci_scan(void *data) rt2400pci_config_txpower(rt2x00pci, rt2x00pci->scan->conf.scan_power_level); } else { - rt2x00pci->rx.params.rx.phymode = + rt2x00pci->rx_params.phymode = rt2x00pci->scan->conf.running_phymode; rt2400pci_config_channel(rt2x00pci, @@ -1726,7 +1726,7 @@ rt2400pci_conf_tx(struct net_device *net else return -EINVAL; - memcpy(&ring->params, params, sizeof(*params)); + memcpy(&ring->tx_params, params, sizeof(*params)); /* * TODO: We can't use different cw_min and cw_max variables @@ -1737,14 +1737,14 @@ rt2400pci_conf_tx(struct net_device *net * RT2400 registers require to know the bit number 'n'. */ if (params->cw_min) - ring->params.tx.cw_min = HIGHEST_BIT16(params->cw_min) + 1; + ring->tx_params.cw_min = HIGHEST_BIT16(params->cw_min) + 1; else - ring->params.tx.cw_min = 5; /* cw_min: 2^5 = 32. */ + ring->tx_params.cw_min = 5; /* cw_min: 2^5 = 32. */ if (params->cw_max) - ring->params.tx.cw_max = HIGHEST_BIT16(params->cw_max) + 1; + ring->tx_params.cw_max = HIGHEST_BIT16(params->cw_max) + 1; else - ring->params.tx.cw_max = 10; /* cw_min: 2^10 = 1024. */ + ring->tx_params.cw_max = 10; /* cw_min: 2^10 = 1024. */ return 0; } diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-
[PATCH 32/32] rt2x00: misc fixes
From: Ivo van Doorn <[EMAIL PROTECTED]> Misc. small fixes. Add small comments, remove unwanted whitespaces etc. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:05:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:06:22.0 +0200 @@ -1003,7 +1003,7 @@ rt2400pci_txdone(void *data) int tx_status; int ack; -while (!rt2x00_ring_empty(ring)) { + while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->desc_addr; @@ -1212,7 +1212,7 @@ rt2400pci_free_ring(struct rt2x00_pci *r ring->data_addr, ring->data_dma); ring->data_addr = NULL; - kfree(ring->entry); + kfree(ring->entry); ring->entry = NULL; } @@ -1318,6 +1318,9 @@ rt2400pci_init_rings(struct rt2x00_pci * { u32 reg; + /* +* Initialize rings. +*/ rt2400pci_init_rxdesc(rt2x00pci, &rt2x00pci->ring[RING_RX]); rt2400pci_init_txdesc(rt2x00pci, &rt2x00pci->ring[RING_TX]); rt2400pci_init_txdesc(rt2x00pci, &rt2x00pci->ring[RING_ATIM]); @@ -1847,7 +1850,7 @@ rt2400pci_config_interface(struct net_de rt2400pci_config_bssid(rt2x00pci, conf->bssid); return 0; - } +} static void rt2400pci_set_multicast_list(struct net_device *net_dev, diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:05:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:06:22.0 +0200 @@ -487,7 +487,7 @@ rt2500pci_config_channel(struct rt2x00_p if (rt2x00_rf(&rt2x00pci->chip, RF5222)) { if (channel < 14) { - rf1 = cpu_to_le32(0x00022020); + rf1 = cpu_to_le32(0x00022020); rf4 = cpu_to_le32(0x0a0b); } else if (channel == 14) { rf1 = cpu_to_le32(0x00022010); @@ -501,7 +501,7 @@ rt2500pci_config_channel(struct rt2x00_p } else if (channel < 161) { rf1 = cpu_to_le32(0x00022020); rf4 = cpu_to_le32(0x0a07); - } + } } INFO("Switching channel. RF1: 0x%08x, RF2: 0x%08x, RF3: 0x%08x, " @@ -1091,7 +1091,7 @@ rt2500pci_txdone(void *data) int tx_status; int ack; -while (!rt2x00_ring_empty(ring)) { + while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->desc_addr; @@ -1301,7 +1301,7 @@ rt2500pci_free_ring(struct rt2x00_pci *r ring->data_addr, ring->data_dma); ring->data_addr = NULL; - kfree(ring->entry); + kfree(ring->entry); ring->entry = NULL; } @@ -2438,7 +2438,7 @@ rt2500pci_init_hw_channels(struct rt2x00 for (counter = 0; counter < ARRAY_SIZE(vals); counter++) channels[counter].val = cpu_to_le32(vals[counter] | rf2_base); - } + } if (rt2x00_rf(&rt2x00pci->chip, RF5222)) { static u32 vals[] = { 0x00018896, 0x0001889a, 0x0001889e, 0x000188a2, @@ -2453,7 +2453,7 @@ rt2500pci_init_hw_channels(struct rt2x00 for (counter = 0; counter < ARRAY_SIZE(vals); counter++) (chan++)->val = cpu_to_le32(vals[counter]); - } + } /* * Set TX power, each EEPROM TXpower entry @@ -2472,7 +2472,7 @@ rt2500pci_init_hw_channels(struct rt2x00 rt2x00_get_field16(eeprom, EEPROM_TXPOWER_2); if (channels[(counter * 2) + 1].power_level > 0x20) channels[(counter * 2) + 1].power_level = 0x18; - } + } /* * Set device specific, but channel independent RF values. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 22:05:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 22:08:38.0 +0200 @@ -335,7 +335,7 @@ rt2500usb_config_channel(struct rt2x00_u || rt2x00_rf(&rt2x00usb->chip, RF2524)
[PATCH 12/32] rt2x00: Add USB ID's
From: Ivo van Doorn <[EMAIL PROTECTED]> Remove the rt73usb ID that accidently sneaked into rt2500usb. And add new rt2500usb ID's. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:42:29.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:44:33.0 +0200 @@ -2192,6 +2192,7 @@ static struct usb_device_id rt2500usb_de { USB_DEVICE(0x0b05, 0x1707), .driver_info = RT2570}, /* Belkin */ { USB_DEVICE(0x050d, 0x7050), .driver_info = RT2570}, + { USB_DEVICE(0x050d, 0x7051), .driver_info = RT2570}, { USB_DEVICE(0x050d, 0x705a), .driver_info = RT2570}, /* Cisco Systems */ { USB_DEVICE(0x13b1, 0x000d), .driver_info = RT2570}, @@ -2201,7 +2202,6 @@ static struct usb_device_id rt2500usb_de { USB_DEVICE(0x14b2, 0x3c02), .driver_info = RT2570}, /* D-LINK */ { USB_DEVICE(0x2001, 0x3c00), .driver_info = RT2570}, - { USB_DEVICE(0x07d1, 0x3c03), .driver_info = RT2570}, /* Gigabyte */ { USB_DEVICE(0x1044, 0x8001), .driver_info = RT2570}, { USB_DEVICE(0x1044, 0x8007), .driver_info = RT2570}, @@ -2224,6 +2224,10 @@ static struct usb_device_id rt2500usb_de { USB_DEVICE(0x0707, 0xee13), .driver_info = RT2570}, /* Spairon */ { USB_DEVICE(0x114b, 0x0110), .driver_info = RT2570}, + /* Trust */ + { USB_DEVICE(0x0eb0, 0x9020), .driver_info = RT2570}, + /* Zinwell */ + { USB_DEVICE(0x5a57, 0x0260), .driver_info = RT2570}, {0,} }; pgpUozaXKP7GJ.pgp Description: PGP signature
[PATCH 3/32] rt2x00: use pci_*_consistent for DMA mapping
From: Ivo van Doorn <[EMAIL PROTECTED]> Add linux/dma-mapping.h header to allow compilation on some architectures. Instead of dma_*_coherent use pci_*consistent functions. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:36:17.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:37:02.0 +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -928,8 +929,8 @@ rt2400pci_alloc_ring( /* * Allocate DMA memory for descriptor and buffer. */ - ring->data_addr = dma_alloc_coherent(&rt2x00pci->pci_dev->dev, - rt2x00_get_ring_size(ring), &ring->data_dma, GFP_KERNEL); + ring->data_addr = pci_alloc_consistent(rt2x00pci->pci_dev, + rt2x00_get_ring_size(ring), &ring->data_dma); if (!ring->data_addr) { kfree(ring->entry); return -ENOMEM; @@ -959,7 +960,7 @@ static void rt2400pci_free_ring(struct rt2x00_pci *rt2x00pci, struct data_ring *ring) { if (ring->data_addr) - dma_free_coherent(&rt2x00pci->pci_dev->dev, + pci_free_consistent(rt2x00pci->pci_dev, rt2x00_get_ring_size(ring), ring->data_addr, ring->data_dma); ring->data_addr = NULL; diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:36:17.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:37:02.0 +0200 @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -964,8 +965,8 @@ rt2500pci_alloc_ring( /* * Allocate DMA memory for descriptor and buffer. */ - ring->data_addr = dma_alloc_coherent(&rt2x00pci->pci_dev->dev, - rt2x00_get_ring_size(ring), &ring->data_dma, GFP_KERNEL); + ring->data_addr = pci_alloc_consistent(rt2x00pci->pci_dev, + rt2x00_get_ring_size(ring), &ring->data_dma); if (!ring->data_addr) { kfree(ring->entry); return -ENOMEM; @@ -995,7 +996,7 @@ static void rt2500pci_free_ring(struct rt2x00_pci *rt2x00pci, struct data_ring *ring) { if (ring->data_addr) - dma_free_coherent(&rt2x00pci->pci_dev->dev, + pci_free_consistent(rt2x00pci->pci_dev, rt2x00_get_ring_size(ring), ring->data_addr, ring->data_dma); ring->data_addr = NULL; pgpJFezwDatSd.pgp Description: PGP signature
[PATCH 17/32] rt2x00: Put net_device structure in data_ring
From: Ivo van Doorn <[EMAIL PROTECTED]> Change the structure stored in the data_ring structure from the rt2x00_pci or rt2x00_usb to net_device. This allows for better type checking, and the net_dev is more often used in the interrupt handlers. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:48:21.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:49:08.0 +0200 @@ -760,10 +760,8 @@ rt2400pci_write_tx_desc( static void rt2400pci_beacondone(void *data) { - struct data_ring*ring = (struct data_ring*)data; - struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)ring->dev; - struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); - struct sk_buff *skb; + struct data_ring*ring = (struct data_ring*)data; + struct sk_buff *skb; struct ieee80211_tx_control beacon; memset(&beacon, 0x00, sizeof(beacon)); @@ -771,11 +769,11 @@ rt2400pci_beacondone(void *data) /* * TODO: What value should be passed as bss_idx? */ - skb = ieee80211_beacon_get(net_dev, 0, &beacon); + skb = ieee80211_beacon_get(ring->net_dev, 0, &beacon); if (!skb) return; - rt2400pci_beacon_update(net_dev, skb, &beacon); + rt2400pci_beacon_update(ring->net_dev, skb, &beacon); dev_kfree_skb_any(skb); } @@ -784,8 +782,8 @@ static void rt2400pci_rxdone(void *data) { struct data_ring*ring = (struct data_ring*)data; - struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)ring->dev; - struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); + struct rt2x00_pci *rt2x00pci = + ieee80211_dev_hw_data(ring->net_dev); struct data_entry *entry; struct sk_buff *skb; struct rxd *rxd; @@ -817,7 +815,8 @@ rt2400pci_rxdone(void *data) rt2x00pci->rx_params.ssi = rt2x00_get_field32(rxd->word2, RXD_W2_RSSI); - __ieee80211_rx(net_dev, skb, &rt2x00pci->rx_params); + __ieee80211_rx(ring->net_dev, + skb, &rt2x00pci->rx_params); } rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1); @@ -835,8 +834,8 @@ static void rt2400pci_txdone(void *data) { struct data_ring*ring = (struct data_ring*)data; - struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)ring->dev; - struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); + struct rt2x00_pci *rt2x00pci = + ieee80211_dev_hw_data(ring->net_dev); struct data_entry *entry; struct txd *txd; int tx_status; @@ -881,7 +880,8 @@ rt2400pci_txdone(void *data) entry->tx_status.retry_count = rt2x00_get_field32( txd->word0, TXD_W0_RETRY_COUNT); - ieee80211_tx_status(net_dev, entry->skb, &entry->tx_status); + ieee80211_tx_status(ring->net_dev, + entry->skb, &entry->tx_status); rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0); entry->skb = NULL; @@ -975,7 +975,7 @@ rt2400pci_alloc_ring( /* *Set device structure. */ - ring->dev = rt2x00pci; + ring->net_dev = pci_get_drvdata(rt2x00pci->pci_dev); /* * Initialize work structure for deferred work. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:48:21.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:49:08.0 +0200 @@ -834,10 +834,8 @@ rt2500pci_write_tx_desc( static void rt2500pci_beacondone(void *data) { - struct data_ring*ring = (struct data_ring*)data; - struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)ring->dev; - struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); - struct sk_buff *skb; + struct data_ring*ring = (struct data_ring*)data; + struct sk_buff *skb; struct ieee80211_tx_control beacon; memset(&beacon, 0x00, sizeof(beacon)); @@ -845,11 +843,11 @@ rt2500pci_beacondone(void *data) /* * TODO: What value should be passed as bss_idx? */ - skb = ieee80211_beac
[PATCH 26/32] rt2x00: Move all USB and PCI common data into seperate headers
From: Ivo van Doorn <[EMAIL PROTECTED]> Now that rt2x00_pci and rt2x00_usb structures in the various headers are generic enough, add 2 header files rt2x00pci and rt2x00usb and make them contain all common information of the PCI or USB modules. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> Available on server: http://mendiosus.nl/rt2x00/rt2x00-26-dev.diff pgp2HdaloG1JW.pgp Description: PGP signature
[PATCH 19/32] rt2x00: Fix panics in interrupt handlers
From: Ivo van Doorn <[EMAIL PROTECTED]> Fix panics when the interrupt handlers are being run while the ring is empty. During the interrupt handling break the loop correctly when an error has been detected, more work is being done after the loop. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:49:59.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:50:36.0 +0200 @@ -844,7 +844,7 @@ rt2400pci_rxdone(void *data) && !rt2x00_get_field32(rxd->word0, RXD_W0_PHYSICAL_ERROR)) { skb = dev_alloc_skb(size + NET_IP_ALIGN); if (!skb) - return; + break; skb_reserve(skb, NET_IP_ALIGN); @@ -859,7 +859,7 @@ rt2400pci_rxdone(void *data) rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1); - rt2x00_ring_index_inc(&rt2x00pci->rx); + rt2x00_ring_index_inc(ring); } /* @@ -879,7 +879,7 @@ rt2400pci_txdone(void *data) int tx_status; int ack; - do { +while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->desc_addr; @@ -925,7 +925,7 @@ rt2400pci_txdone(void *data) entry->skb = NULL; rt2x00_ring_index_done_inc(ring); - } while (!rt2x00_ring_empty(ring)); + } /* * Check if we are waiting on an empty queue diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:49:59.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:50:36.0 +0200 @@ -926,7 +926,7 @@ rt2500pci_rxdone(void *data) && !rt2x00_get_field32(rxd->word0, RXD_W0_PHYSICAL_ERROR)) { skb = dev_alloc_skb(size + NET_IP_ALIGN); if (!skb) - return; + break; skb_reserve(skb, NET_IP_ALIGN); @@ -943,7 +943,7 @@ rt2500pci_rxdone(void *data) } rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1); - rt2x00_ring_index_inc(&rt2x00pci->rx); + rt2x00_ring_index_inc(ring); } /* @@ -964,7 +964,7 @@ rt2500pci_txdone(void *data) int tx_status; int ack; - do { +while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->desc_addr; @@ -1010,7 +1010,7 @@ rt2500pci_txdone(void *data) entry->skb = NULL; rt2x00_ring_index_done_inc(ring); - } while (!rt2x00_ring_empty(ring)); + } /* * Check if we are waiting on an empty queue diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:49:59.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:50:36.0 +0200 @@ -808,7 +808,7 @@ rt2500usb_txdone(void *data) struct txd *txd; int ack; - do { +while (!rt2x00_ring_empty(ring)) { entry = rt2x00_get_data_entry_done(ring); txd = entry->desc_addr; @@ -843,7 +843,7 @@ rt2500usb_txdone(void *data) entry->skb = NULL; rt2x00_ring_index_done_inc(entry->ring); - } while (!rt2x00_ring_empty(ring)); + } /* * Check if we are waiting on an empty queue pgprpPT39wqU1.pgp Description: PGP signature
[PATCH 28/32] rt2x00: Support TXRX led handling
From: Ivo van Doorn <[EMAIL PROTECTED]> Create more advanced led handling, enable txrx activity by switching on and off the led at interrupt time. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:03:48.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:04:19.0 +0200 @@ -669,6 +669,57 @@ rt2400pci_link_tuner(struct rt2x00_pci * } /* + * LED functions. + */ +static void +rt2400pci_enable_led(struct rt2x00_pci *rt2x00pci) +{ + u32 reg; + + rt2x00_register_read(rt2x00pci, LEDCSR, ®); + + rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 30); + rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 70); + + if (rt2x00pci->led_mode == LED_MODE_TXRX_ACTIVITY) { + rt2x00_set_field32(®, LEDCSR_LINK, 1); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); + } else if (rt2x00pci->led_mode == LED_MODE_ASUS) { + rt2x00_set_field32(®, LEDCSR_LINK, 0); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); + } else { + rt2x00_set_field32(®, LEDCSR_LINK, 1); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, 1); + } + + rt2x00_register_write(rt2x00pci, LEDCSR, reg); +} + +static void +rt2400pci_disable_led(struct rt2x00_pci *rt2x00pci) +{ + u32 reg; + + rt2x00_register_read(rt2x00pci, LEDCSR, ®); + rt2x00_set_field32(®, LEDCSR_LINK, 0); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); + rt2x00_register_write(rt2x00pci, LEDCSR, reg); +} + +static void +rt2400pci_activity_led(struct rt2x00_pci *rt2x00pci, char activity) +{ + u32 reg; + + if (rt2x00pci->led_mode != LED_MODE_TXRX_ACTIVITY) + return; + + rt2x00_register_read(rt2x00pci, LEDCSR, ®); + rt2x00_set_field32(®, LEDCSR_ACTIVITY, activity); + rt2x00_register_write(rt2x00pci, LEDCSR, reg); +} + +/* * Device state switch. * This will put the device to sleep, or awake it. */ @@ -882,6 +933,11 @@ rt2400pci_rxdone(void *data) * Tune link for optimal performance. */ rt2400pci_link_tuner(rt2x00pci); + + /* +* Update LED. +*/ + rt2400pci_activity_led(rt2x00pci, 0); } static void @@ -987,10 +1043,13 @@ rt2400pci_interrupt(int irq, void *dev_i /* * 2 - Rx ring done interrupt. +* Enable the TXRX activity led. */ - if (rt2x00_get_field32(reg, CSR7_RXDONE)) + if (rt2x00_get_field32(reg, CSR7_RXDONE)) { queue_work(rt2x00pci->workqueue, &rt2x00pci->ring[RING_RX].irq_work); + rt2400pci_activity_led(rt2x00pci, 1); + } /* * 3 - Atim ring transmit done interrupt. @@ -1333,13 +1392,6 @@ rt2400pci_init_registers(struct rt2x00_p rt2x00_set_field32(®, RALINKCSR_AR_BBP_ID1, 154); rt2x00_register_write(rt2x00pci, RALINKCSR, reg); - rt2x00_register_read(rt2x00pci, LEDCSR, ®); - rt2x00_set_field32(®, LEDCSR_ON_PERIOD, 30); - rt2x00_set_field32(®, LEDCSR_OFF_PERIOD, 70); - rt2x00_set_field32(®, LEDCSR_LINK, 0); - rt2x00_set_field32(®, LEDCSR_ACTIVITY, 0); - rt2x00_register_write(rt2x00pci, LEDCSR, reg); - rt2x00_register_read(rt2x00pci, CSR1, ®); rt2x00_set_field32(®, CSR1_SOFT_RESET, 1); rt2x00_set_field32(®, CSR1_BBP_RESET, 0); @@ -1555,6 +1607,11 @@ rt2400pci_open(struct net_device *net_de } /* +* Enable LED +*/ + rt2400pci_enable_led(rt2x00pci); + + /* * Enable interrupts. */ rt2x00_register_read(rt2x00pci, CSR8, ®); @@ -1597,11 +1654,9 @@ rt2400pci_stop(struct net_device *net_de rt2x00_register_write(rt2x00pci, RXCSR0, reg); /* -* Switch off LED. +* Disable LED */ - rt2x00_register_read(rt2x00pci, LEDCSR, ®); - rt2x00_set_field32(®, LEDCSR_LINK, 0); - rt2x00_register_write(rt2x00pci, LEDCSR, reg); + rt2400pci_disable_led(rt2x00pci); /* * Disable interrupts. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:03:48.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:04:19.0 +0200 @@ -722,6 +722,57 @@ dynamic_cca_tune: } /* + * LED functions. + */ +static void +rt2500pci_enable_led(struct rt2x00_pci *rt2x00pci) +{ + u32 reg; + + rt2x00_register_read(rt2x00pci, LEDCSR, ®
[PATCH 14/32] rt2x00: Allocate eeprom memory
From: Ivo van Doorn <[EMAIL PROTECTED]> Make the EEPROM array in rt2x00_pci and rt2x00_usb a pointer, and allocate the memory seperately. This is needed for make the structures more generic for all rt2x00 pci or usb modules. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:45:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:47:22.0 +0200 @@ -1831,7 +1831,6 @@ rt2400pci_init_eeprom(struct rt2x00_pci u32 reg; u16 value; u16 eeprom; - int counter; /* * 1 - Detect EEPROM width. @@ -1886,8 +1885,12 @@ rt2400pci_init_eeprom(struct rt2x00_pci /* * 7 - Read BBP data from EEPROM and store in private structure. */ + rt2x00pci->eeprom = kzalloc(EEPROM_BBP_SIZE * sizeof(u16), GFP_KERNEL); + if (!rt2x00pci->eeprom) + return -ENOMEM; + rt2x00_eeprom_multiread(rt2x00pci, EEPROM_BBP_START, - &rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); + rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); return 0; } @@ -2197,6 +2200,8 @@ rt2400pci_uninitialize(struct net_device del_timer_sync(&rt2x00pci->poll_timer); #endif /* CONFIG_RT2400PCI_BUTTON */ + kfree(rt2x00pci->eeprom); + if (likely(rt2x00pci->csr_addr)) { iounmap(rt2x00pci->csr_addr); rt2x00pci->csr_addr = NULL; diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:45:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:47:22.0 +0200 @@ -945,7 +945,7 @@ struct rt2x00_pci{ /* * EEPROM BBP data. */ - u16 eeprom[EEPROM_BBP_SIZE]; + u16 *eeprom; /* * Low level statistics which will have diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:45:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:47:22.0 +0200 @@ -1939,7 +1939,6 @@ rt2500pci_init_eeprom(struct rt2x00_pci u32 reg; u16 value; u16 eeprom; - int counter; /* * 1 - Detect EEPROM width. @@ -1998,8 +1997,12 @@ rt2500pci_init_eeprom(struct rt2x00_pci /* * 7 - Read BBP data from EEPROM and store in private structure. */ + rt2x00pci->eeprom = kzalloc(EEPROM_BBP_SIZE * sizeof(u16), GFP_KERNEL); + if (!rt2x00pci->eeprom) + return -ENOMEM; + rt2x00_eeprom_multiread(rt2x00pci, EEPROM_BBP_START, - &rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); + rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); return 0; } @@ -2495,6 +2498,8 @@ rt2500pci_uninitialize(struct net_device del_timer_sync(&rt2x00pci->poll_timer); #endif /* CONFIG_RT2500PCI_BUTTON */ + kfree(rt2x00pci->eeprom); + if (likely(rt2x00pci->csr_addr)) { iounmap(rt2x00pci->csr_addr); rt2x00pci->csr_addr = NULL; diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 21:43:27.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 21:47:22.0 +0200 @@ -1215,7 +1215,7 @@ struct rt2x00_pci{ /* * EEPROM BBP data. */ - u16 eeprom[EEPROM_BBP_SIZE]; + u16 *eeprom; /* * Low level statistics which will have diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:45:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:47:22.0 +0200 @@ -1657,9 +1657,12 @@ rt2500usb_init_e
[PATCH 29/32] rt2x00: dscape compatibilitiy
From: Ivo van Doorn <[EMAIL PROTECTED]> Latest dscape patches have broken rt2x00, fix compile issues, and support the new features. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> Available on server: http://mendiosus.nl/rt2x00/rt2x00-29-compat.diff pgpdvt1YheaxX.pgp Description: PGP signature
[PATCH 0/32] rt2x00
Hi, Here follows quite a large series of patches for rt2x00 for the wireless-dev tree. This will bring rt2x00 in wireless-dev up to date with our CVS tree except that rt61pci and rt73usb are not yet send along. They will follow within a week. Apologies for the long delay but due to time limitations the highest priority was put on the CVS tree and not on the regularly sending of patches. We will do our best to send more frequent updates, so next time other developers of rt2x00 will also be sending the patches. A short summary of all patches the are following: [PATCH 1/32] rt2x00: code style fix [PATCH 2/32] rt2x00: use enumerations [PATCH 3/32] rt2x00: use pci_*_consistent for DMA mapping [PATCH 4/32] rt2x00: Add eeprom_multiread function [PATCH 5/32] rt2x00: Optimize RATE flag handling [PATCH 6/32] rt2x00: Use arraylike accessors for entries in DMA ring [PATCH 7/32] rt2x00: make vals static [PATCH 8/32] rt2x00: Invalid memory allocation check [PATCH 9/32] rt2x00: Fix antenna configuration [PATCH 10/32] rt2x00: Move TSF counting activation to correct funtion [PATCH 11/32] rt2x00: Add more register defines [PATCH 12/32] rt2x00: Add USB ID's [PATCH 13/32] rt2x00: Tune link depending on link quality [PATCH 14/32] rt2x00: Allocate eeprom memory [PATCH 15/32] rt2x00: Move rx_params to correct location [PATCH 16/32] rt2x00: Make sure TX rings are empty when scanning [PATCH 17/32] rt2x00: Put net_device structure in data_ring [PATCH 18/32] rt2x00: Make sure device has reached requested state while suspend/resume [PATCH 19/32] rt2x00: Fix panics in interrupt handlers [PATCH 20/32] rt2x00: byte ordering correctness [PATCH 21/32] rt2x00: PRIO ring should be treated as regular TX ring [PATCH 22/32] rt2x00: Allocate ring structures in single array [PATCH 23/32] rt2x00: Make correct cast in USB interrupt [PATCH 24/32] rt2x00: Use correct desc_addr and data_addr [PATCH 25/32] rt2x00: Add flag handlers [PATCH 26/32] rt2x00: Move all USB and PCI common data into seperate headers [PATCH 27/32] rt2x00: Put Hardware button in generic header [PATCH 28/32] rt2x00: Support TXRX led handling [PATCH 29/32] rt2x00: dscape compatibilitiy [PATCH 30/32] rt2x00: Correctly initialize TX power in registers [PATCH 31/32] rt2x00: Correctly initialization and uninitialization of device [PATCH 32/32] rt2x00: misc fixes Some of the patches are quite big and placed on an external server, the link for that patch will be placed in that particular mail. All other patches are inlined but are also available on the same server: http://mendiosus.nl/rt2x00/rt2x00-01-code-style.diff http://mendiosus.nl/rt2x00/rt2x00-02-enum.diff http://mendiosus.nl/rt2x00/rt2x00-03-dma-mapping.diff http://mendiosus.nl/rt2x00/rt2x00-04-eeprom-multiread.diff http://mendiosus.nl/rt2x00/rt2x00-05-txrate.diff http://mendiosus.nl/rt2x00/rt2x00-06-array.diff http://mendiosus.nl/rt2x00/rt2x00-07-static.diff http://mendiosus.nl/rt2x00/rt2x00-08-rate-check.diff http://mendiosus.nl/rt2x00/rt2x00-09-antenna.diff http://mendiosus.nl/rt2x00/rt2x00-10-tsf-counting.diff http://mendiosus.nl/rt2x00/rt2x00-11-register.diff http://mendiosus.nl/rt2x00/rt2x00-12-usb-ids.diff http://mendiosus.nl/rt2x00/rt2x00-13-link-tuner.diff http://mendiosus.nl/rt2x00/rt2x00-14-eeprom.diff http://mendiosus.nl/rt2x00/rt2x00-15-txrx-params.diff http://mendiosus.nl/rt2x00/rt2x00-16-scan-params.diff http://mendiosus.nl/rt2x00/rt2x00-17-ringdev.diff http://mendiosus.nl/rt2x00/rt2x00-18-suspend.diff http://mendiosus.nl/rt2x00/rt2x00-19-ring.diff http://mendiosus.nl/rt2x00/rt2x00-20-endian.diff http://mendiosus.nl/rt2x00/rt2x00-21-prio.diff http://mendiosus.nl/rt2x00/rt2x00-22-rings.diff http://mendiosus.nl/rt2x00/rt2x00-23-usbhandler.diff http://mendiosus.nl/rt2x00/rt2x00-24-usbfixes.diff http://mendiosus.nl/rt2x00/rt2x00-25-flags.diff http://mendiosus.nl/rt2x00/rt2x00-26-dev.diff http://mendiosus.nl/rt2x00/rt2x00-27-button.diff http://mendiosus.nl/rt2x00/rt2x00-28-led.diff http://mendiosus.nl/rt2x00/rt2x00-29-compat.diff http://mendiosus.nl/rt2x00/rt2x00-30-config.diff http://mendiosus.nl/rt2x00/rt2x00-31-init.diff http://mendiosus.nl/rt2x00/rt2x00-32-misc.diff IvD pgpzoTJPlHGw1.pgp Description: PGP signature
[PATCH 1/32] rt2x00: code style fix
From: Ivo van Doorn <[EMAIL PROTECTED]> Coding style fix for all rt2x00 drivers. This change was requested on the netdev list some time ago, but the patch send then didn't contain all requested changes. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> Available on server: http://mendiosus.nl/rt2x00/rt2x00-01-code-style.diff pgprZQNrY8QfI.pgp Description: PGP signature
[PATCH 2/32] rt2x00: use enumerations
From: Ivo van Doorn <[EMAIL PROTECTED]> The led_mode defines are equal in all drivers, and should be placed in the common rt2x00.h header. Make the led_mode, tx_status and dev_state defines into enumerations. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 00:52:56.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:25:33.0 +0200 @@ -936,11 +936,6 @@ struct rt2x00_pci{ * Led status */ u8 led_mode; -#define LED_MODE_DEFAULT 0 -#define LED_MODE_TXRX_ACTIVITY 1 -#define LED_MODE_SINGLE2 -#define LED_MODE_ASUS 3 -#define LED_MODE_ALPHA 4 /* * EEPROM BBP data. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 00:52:56.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h 2006-04-27 21:25:33.0 +0200 @@ -1192,11 +1192,6 @@ struct rt2x00_pci{ * Led status */ u8 led_mode; -#define LED_MODE_DEFAULT 0 -#define LED_MODE_TXRX_ACTIVITY 1 -#define LED_MODE_SINGLE2 -#define LED_MODE_ASUS 3 -#define LED_MODE_ALPHA 4 /* * EEPROM BBP data. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.h 2006-04-27 00:52:56.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h 2006-04-27 21:25:33.0 +0200 @@ -691,11 +691,6 @@ struct rt2x00_usb{ * Led status */ u8 led_mode; -#define LED_MODE_DEFAULT 0 -#define LED_MODE_TXRX_ACTIVITY 1 -#define LED_MODE_SINGLE2 -#define LED_MODE_ASUS 3 -#define LED_MODE_ALPHA 4 /* * EEPROM BBP data. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:23:26.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:25:33.0 +0200 @@ -96,11 +96,34 @@ static int rt2x00_debug_level = 0; /* * TX result flags. */ -#define TX_SUCCESS 0 -#define TX_SUCCESS_RETRY 1 -#define TX_FAIL_RETRY 2 -#define TX_FAIL_INVALID3 -#define TX_FAIL_OTHER 4 +enum TX_STATUS { + TX_SUCCESS = 0, + TX_SUCCESS_RETRY= 1, + TX_FAIL_RETRY = 2, + TX_FAIL_INVALID = 3, + TX_FAIL_OTHER = 4, +}; + +/* + * Led mode values. + */ +enum led_mode { + LED_MODE_DEFAULT= 0, + LED_MODE_TXRX_ACTIVITY = 1, + LED_MODE_SIGNAL_STRENGTH= 2, + LED_MODE_ASUS = 3, + LED_MODE_ALPHA = 4, +}; + +/* + * Device states + */ +enum dev_state { + STATE_DEEP_SLEEP= 0, + STATE_SLEEP = 1, + STATE_STANDBY = 2, + STATE_AWAKE = 3, +}; /* * Macros for determining which is the lowest or highest bit pgpGba0MaNdiB.pgp Description: PGP signature
[PATCH 27/32] rt2x00: Put Hardware button in generic header
From: Ivo van Doorn <[EMAIL PROTECTED]> Put the hardware button handling as much as possible in the new generic header for PCI. The individial .c files should now only contain the polling function to check the state of the hardware button. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:57:18.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:03:48.0 +0200 @@ -38,10 +38,6 @@ #include #include -#ifdef CONFIG_RT2400PCI_BUTTON -#include -#endif /* CONFIG_RT2400PCI_BUTTON */ - #include /* @@ -364,6 +360,24 @@ rt2x00_eeprom_multiread( rt2x00_eeprom_read(rt2x00pci, word + counter, data++); } +#ifdef CONFIG_RT2400PCI_BUTTON +/* + * Hardware button poll handler. + */ +static void +rt2400pci_button_poll(unsigned long data) +{ + struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)data; + u32 reg; + + rt2x00_register_read(rt2x00pci, GPIOCSR, ®); + rt2x00pci_button_status( + rt2x00pci, rt2x00_get_field32(reg, GPIOCSR_BIT0)); +} +#else /* CONFIG_RT2400PCI_BUTTON */ +static void rt2400pci_button_poll(struct rt2x00_pci *rt2x00pci){} +#endif /* CONFIG_RT2400PCI_BUTTON */ + /* * Configuration handlers. */ @@ -2258,24 +2272,10 @@ rt2400pci_initialize(struct pci_dev *pci || rt2400pci_init_hw(rt2x00pci)) goto exit_destroy_workqueue; -#ifdef CONFIG_RT2400PCI_BUTTON - strcpy(acpi_device_class(&rt2x00pci->acpi_dev), DRV_NAME "_button"); - strcpy(acpi_device_bid(&rt2x00pci->acpi_dev), DRV_NAME); - strcpy(acpi_device_name(&rt2x00pci->acpi_dev), DRV_NAME); - - init_timer(&rt2x00pci->poll_timer); - - if (rt2x00_poll_delay - && rt2x00pci->button_status != BUTTON_STATUS_UNAVAILABLE) { - rt2x00pci->button_status = rt2400pci_poll(rt2x00pci); - rt2x00pci->poll_delay = rt2x00_poll_delay * (HZ / 10); - rt2x00pci->poll_timer.function = rt2400pci_poll_expire; - rt2x00pci->poll_timer.data = (unsigned long)rt2x00pci; - rt2x00pci->poll_timer.expires = - jiffies + rt2x00pci->poll_delay; - add_timer(&rt2x00pci->poll_timer); - }; -#endif /* CONFIG_RT2400PCI_BUTTON */ + /* +* If required start hardware button polling. +*/ + rt2x00pci_button_start(rt2x00pci, rt2400pci_button_poll); return 0; @@ -2294,13 +2294,10 @@ rt2400pci_uninitialize(struct net_device { struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); -#ifdef CONFIG_RT2400PCI_BUTTON /* * Shutdown poll_timer for hardware button. */ - rt2x00pci->button_status = BUTTON_STATUS_UNAVAILABLE; - del_timer_sync(&rt2x00pci->poll_timer); -#endif /* CONFIG_RT2400PCI_BUTTON */ + rt2x00pci_button_stop(rt2x00pci); kfree(rt2x00pci->eeprom); @@ -2506,40 +2503,6 @@ rt2400pci_resume(struct pci_dev *pci_dev } #endif /* CONFIG_PM */ -#ifdef CONFIG_RT2400PCI_BUTTON -static int -rt2400pci_poll(struct rt2x00_pci *rt2x00pci) -{ - u32 reg; - - rt2x00_register_read(rt2x00pci, GPIOCSR, ®); - return rt2x00_get_field32(reg, GPIOCSR_BIT0); -} - -static void -rt2400pci_poll_expire(unsigned long data) -{ - struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)data; - u16 status; - - status = rt2400pci_poll(rt2x00pci); - - if (rt2x00pci->button_status != BUTTON_STATUS_UNAVAILABLE) - return; - - if (status != rt2x00pci->button_status) { - rt2x00pci->button_status = status; - acpi_bus_generate_event(&rt2x00pci->acpi_dev, - ACPI_TYPE_EVENT, rt2x00pci->button_status); - } - - rt2x00pci->poll_timer.expires = jiffies + rt2x00pci->poll_delay; - - if (rt2x00pci->button_status != BUTTON_STATUS_UNAVAILABLE) - add_timer(&rt2x00pci->poll_timer); -} -#endif /* CONFIG_RT2400PCI_BUTTON */ - /* * RT2400pci module information. */ diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:57:18.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 22:03:48.0 +0200 @@ -863,21 +863,4 @@ static int rt2400pci_beacon_update(struc struct sk_buff *skb, struct ieee80211_tx_control *control); static int rt2400pci_tx_last_beacon(struct net_device *net_dev); -/* - * HW button support structures and variables. - * The de
[PATCH 22/32] rt2x00: Allocate ring structures in single array
From: Ivo van Doorn <[EMAIL PROTECTED]> Allocate all ring structures seperately and as an array of rings. This will make the rt2x00_pci and rt2x00_usb structures more generic for all rt2x00 modules. Use seperate function to convert a dscape ring ID to the address of the actual ring. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> Available on server: http://mendiosus.nl/rt2x00/rt2x00-22-rings.diff pgp37E3iQh6EF.pgp Description: PGP signature
[PATCH 30/32] rt2x00: Correctly initialize TX power in registers
From: Ivo van Doorn <[EMAIL PROTECTED]> The rate does not need to be configured for each TX packet. The actual rate for sending is determined in the PLCP, the rate configuration is only capable of setting the supported rates, which is dependent of the physical mode we are in. When we the configuration function is called, disable the RX for proper behaviour. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:04:47.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:05:21.0 +0200 @@ -660,6 +660,22 @@ rt2400pci_config_rate(struct rt2x00_pci } static void +rt2400pci_config_phymode(struct rt2x00_pci *rt2x00pci, const int phymode) +{ + struct ieee80211_rate *rate; + + rate = &rt2x00pci->hw.modes[0].rates[ + rt2x00pci->hw.modes[0].num_rates - 1]; + + rt2400pci_config_rate(rt2x00pci, rate->val2); + + /* +* Update physical mode for rx ring. +*/ + rt2x00pci->rx_params.phymode = phymode; +} + +static void rt2400pci_config_mac_address(struct rt2x00_pci *rt2x00pci, void *addr) { u32 reg[2] = {0, 0}; @@ -815,11 +831,6 @@ rt2400pci_write_tx_desc( u16 signal; u16 service; - /* -* Update rate control register. -*/ - rt2400pci_config_rate(rt2x00pci, control->tx_rate); - rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 1); rt2x00_set_field32(&txd->word0, TXD_W0_ACK, !control->no_ack); @@ -1545,14 +1556,6 @@ rt2400pci_tx(struct net_device *net_dev, rt2x00_ring_index_inc(ring); - /* -* We are going to cheat now, we update the register -* with the CWmin and CWmax values for the current -* queue. This is the alternative since we cannot -* set the CWmin and CWmax per descriptor. -*/ - rt2400pci_config_cw(rt2x00pci, &ring->tx_params); - rt2x00_register_read(rt2x00pci, TXCSR0, ®); if (control->queue == IEEE80211_TX_QUEUE_DATA0) rt2x00_set_field32(®, TXCSR0_KICK_PRIO, 1); @@ -1769,19 +1772,46 @@ rt2400pci_config_update(void *data) struct rt2x00_pci *rt2x00pci = data; struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev); + u32 reg; + + /* +* Some configuration changes require the RX to be disabled. +*/ + if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) { + rt2x00_register_read(rt2x00pci, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 1); + rt2x00_register_write(rt2x00pci, RXCSR0, reg); + } - rt2400pci_config_bssid(rt2x00pci, conf->client_bssid); - rt2400pci_config_type(rt2x00pci, conf->mode); rt2400pci_config_channel(rt2x00pci, conf->channel_val, conf->channel, conf->freq); rt2400pci_config_txpower(rt2x00pci, conf->power_level); rt2400pci_config_antenna(rt2x00pci, conf->antenna_sel); rt2400pci_config_duration(rt2x00pci, conf->short_slot_time); + rt2400pci_config_phymode(rt2x00pci, conf->phymode); /* -* Update active info for RX. +* Reenable RX only if the radio should be on. */ - rt2x00pci->rx_params.phymode = conf->phymode; + if (conf->radio_enabled) { + if (!GET_FLAG(rt2x00pci, RADIO_ENABLED)) { + if (rt2400pci_open(net_dev)) { + ERROR("Failed to enabled radio.\n"); + return; + } + } else { + rt2x00_register_read(rt2x00pci, RXCSR0, ®); + rt2x00_set_field32(®, RXCSR0_DISABLE_RX, 0); + rt2x00_register_write(rt2x00pci, RXCSR0, reg); + } + } else { + if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) { + if (rt2400pci_stop(net_dev)) { + ERROR("Failed to disable radio.\n"); + return; + } + } + } } static int @@ -1863,8 +1893,8 @@ rt2400pci_scan(void *data) * Switch channel and update active info for RX. */ if (rt2x00pci->scan->state == IEEE80211_SCAN_START) { - rt2x00pci->rx_params.phymode = - rt2x00pci->scan->conf.scan_phymode; + rt2400pci_config_phymode(rt2x00pci, + rt2x00pci->scan->conf.scan_phymode); rt2400pci_config_channel(rt2x00pci, rt2x00
[PATCH 31/32] rt2x00: Correctly initialization and uninitialization of device
From: Ivo van Doorn <[EMAIL PROTECTED]> Fix several hardware initialization and uninitalization problems by incorrectly flushing workqueues. Fix the memory leak when freeing the ieee80211_hw structure. Allow device to connect to 802.11g networks by default instead of 802.11b. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:05:21.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 22:05:52.0 +0200 @@ -1719,6 +1719,11 @@ rt2400pci_stop(struct net_device *net_de } /* +* Flush out all pending work. +*/ + flush_workqueue(rt2x00pci->workqueue); + + /* * Free DMA rings. */ rt2400pci_free_rings(rt2x00pci); @@ -2441,7 +2446,7 @@ rt2400pci_initialize(struct pci_dev *pci rt2x00pci->workqueue = create_singlethread_workqueue(DRV_NAME); if (!rt2x00pci->workqueue) - goto exit_iounmap; + goto exit; /* * Initialize cofniguration work. @@ -2457,21 +2462,25 @@ rt2400pci_initialize(struct pci_dev *pci if (rt2400pci_init_eeprom(rt2x00pci) || rt2400pci_init_mac(rt2x00pci) || rt2400pci_init_hw(rt2x00pci)) - goto exit_destroy_workqueue; + goto exit; /* * If required start hardware button polling. */ rt2x00pci_button_start(rt2x00pci, rt2400pci_button_poll); - return 0; + /* +* Register hardware. +*/ + if (ieee80211_register_hw(net_dev, &rt2x00pci->hw)) { + ERROR("Failed to register device.\n"); + goto exit; + } -exit_destroy_workqueue: - destroy_workqueue(rt2x00pci->workqueue); + return 0; -exit_iounmap: - iounmap(rt2x00pci->csr_addr); - rt2x00pci->csr_addr = NULL; +exit: + rt2400pci_uninitialize(net_dev); return -ENODEV; } @@ -2482,26 +2491,39 @@ rt2400pci_uninitialize(struct net_device struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); /* +* Unregister hardware. +*/ + ieee80211_unregister_hw(net_dev); + + /* * Shutdown poll_timer for hardware button. */ rt2x00pci_button_stop(rt2x00pci); kfree(rt2x00pci->eeprom); + /* +* Release CSR memory. +*/ if (likely(rt2x00pci->csr_addr)) { iounmap(rt2x00pci->csr_addr); rt2x00pci->csr_addr = NULL; } + /* +* Free workqueue. +*/ if (likely(rt2x00pci->workqueue)) { - flush_workqueue(rt2x00pci->workqueue); destroy_workqueue(rt2x00pci->workqueue); rt2x00pci->workqueue = NULL; } + /* +* Free ieee80211_hw memory. +*/ if (likely(rt2x00pci->hw.modes)) { - kfree(rt2x00pci->hw.modes->channels); - kfree(rt2x00pci->hw.modes->rates); + kfree(rt2x00pci->hw.modes->channels); + kfree(rt2x00pci->hw.modes->rates); kfree(rt2x00pci->hw.modes); rt2x00pci->hw.modes = NULL; } @@ -2514,7 +2536,6 @@ static int rt2400pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id) { struct net_device *net_dev; - struct rt2x00_pci *rt2x00pci; int status; if (unlikely(id->driver_data != RT2460)) { @@ -2559,19 +2580,9 @@ rt2400pci_probe(struct pci_dev *pci_dev, ERROR("Failed to initialize device.\n"); goto exit_free_device; } - rt2x00pci = ieee80211_dev_hw_data(net_dev); - - status = ieee80211_register_hw(net_dev, &rt2x00pci->hw); - if (status) { - ERROR("Failed to register device.\n"); - goto exit_uninitialize_device; - } return 0; -exit_uninitialize_device: - rt2400pci_uninitialize(net_dev); - exit_free_device: ieee80211_free_hw(net_dev); @@ -2592,7 +2603,7 @@ rt2400pci_remove(struct pci_dev *pci_dev { struct net_device *net_dev = pci_get_drvdata(pci_dev); - ieee80211_unregister_hw(net_dev); + net_dev->stop(net_dev); rt2400pci_uninitialize(net_dev); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:05:21.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 22:05:52.0 +0200 @@ -1845,6 +1845,11 @@ rt2500pci_stop(struct
[PATCH 6/32] rt2x00: Use arraylike accessors for entries in DMA ring
From: Ivo van Doorn <[EMAIL PROTECTED]> Make the code a bit more readable by using array like accessors for pointers in a loop. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:39:24.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:40:06.0 +0200 @@ -951,15 +951,15 @@ rt2400pci_alloc_ring( * Initialize all ring entries to contain valid * addresses. */ + entry = (struct data_entry*)ring->entry; for (counter = 0; counter < ring->stats.limit; counter++) { - entry = ring->entry + (counter * ring->entry_size); - entry->skb = NULL; - entry->desc_addr = ring->data_addr + entry[counter].skb = NULL; + entry[counter].desc_addr = ring->data_addr + (counter * ring->desc_size); - entry->data_addr = ring->data_addr + entry[counter].data_addr = ring->data_addr + (ring->stats.limit * ring->desc_size) + (counter * ring->data_size); - entry->data_dma = ring->data_dma + entry[counter].data_dma = ring->data_dma + (ring->stats.limit * ring->desc_size) + (counter * ring->data_size); } @@ -989,14 +989,14 @@ rt2400pci_init_rxdesc(struct rt2x00_pci memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); + entry = (struct data_entry*)ring->entry; for (counter = 0; counter < ring->stats.limit; counter++) { - entry = ring->entry + (counter * ring->entry_size); - rxd = entry->desc_addr; + rxd = entry[counter].desc_addr; rt2x00_set_field32(&rxd->word2, RXD_W2_BUFFER_LENGTH, ring->data_size); rt2x00_set_field32(&rxd->word1, RXD_W1_BUFFER_ADDRESS, - entry->data_dma); + entry[counter].data_dma); rt2x00_set_field32(&rxd->word0, RXD_W0_OWNER_NIC, 1); } @@ -1012,14 +1012,14 @@ rt2400pci_init_txdesc(struct rt2x00_pci memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); + entry = (struct data_entry*)ring->entry; for (counter = 0; counter < ring->stats.limit; counter++) { - entry = ring->entry + (counter * ring->entry_size); - txd = entry->desc_addr; + txd = entry[counter].desc_addr; rt2x00_set_field32(&txd->word2, TXD_W2_BUFFER_LENGTH, ring->data_size); rt2x00_set_field32(&txd->word1, TXD_W1_BUFFER_ADDRESS, - entry->data_dma); + entry[counter].data_dma); rt2x00_set_field32(&txd->word0, TXD_W0_VALID, 0); rt2x00_set_field32(&txd->word0, TXD_W0_OWNER_NIC, 0); } diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:39:24.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:40:06.0 +0200 @@ -987,15 +987,15 @@ rt2500pci_alloc_ring( * Initialize all ring entries to contain valid * addresses. */ + entry = (struct data_entry*)ring->entry; for (counter = 0; counter < ring->stats.limit; counter++) { - entry = ring->entry + (counter * ring->entry_size); - entry->skb = NULL; - entry->desc_addr = ring->data_addr + entry[counter].skb = NULL; + entry[counter].desc_addr = ring->data_addr + (counter * ring->desc_size); - entry->data_addr = ring->data_addr + entry[counter].data_addr = ring->data_addr + (ring->stats.limit * ring->desc_size) + (counter * ring->data_size); - entry->data_dma = ring->data_dma + entry[counter].data_dma = ring->data_dma + (ring->stats.limit * ring->desc_size) + (counter * ring->data_size); } @@ -1025,12 +1025,12 @@ rt2500pci_init_rxdesc(struct rt2x00_pci memset(ring->data_addr, 0x00, rt2x00_get_ring_size(ring)); + entry = (struct data_entry*)ring->entry; for (counter = 0; counter < ring->stats.limit; counter++) { - entry = ring->entry + (counter * ring->entry_size); - rxd = entry->desc_addr; + rxd = entry[counter].desc_addr;
[PATCH 21/32] rt2x00: PRIO ring should be treated as regular TX ring
From: Ivo van Doorn <[EMAIL PROTECTED]> Remove PRIO_ENTRIES define, the prio ring should be treated as a regular TX ring. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:50:36.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:52:01.0 +0200 @@ -1145,7 +1145,7 @@ rt2400pci_allocate_rings(struct rt2x00_p ATIM_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd)) || rt2400pci_alloc_ring( rt2x00pci, &rt2x00pci->prio, rt2400pci_txdone, - PRIO_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) + TX_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) || rt2400pci_alloc_ring( rt2x00pci, &rt2x00pci->beacon, rt2400pci_beacondone, BEACON_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd))) { diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:51:11.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:52:01.0 +0200 @@ -1227,7 +1227,7 @@ rt2500pci_allocate_rings(struct rt2x00_p ATIM_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd)) || rt2500pci_alloc_ring( rt2x00pci, &rt2x00pci->prio, rt2500pci_txdone, - PRIO_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) + TX_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) || rt2500pci_alloc_ring( rt2x00pci, &rt2x00pci->beacon, rt2500pci_beacondone, BEACON_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd))) { diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:51:11.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:52:01.0 +0200 @@ -996,7 +996,7 @@ rt2500usb_allocate_rings(struct rt2x00_u ATIM_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd)) || rt2500usb_alloc_ring( rt2x00usb, &rt2x00usb->prio, &rt2500usb_txdone, - PRIO_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) + TX_ENTRIES, DATA_FRAME_SIZE, sizeof(struct txd)) || rt2500usb_alloc_ring( rt2x00usb, &rt2x00usb->beacon, &rt2500usb_beacondone, BEACON_ENTRIES, MGMT_FRAME_SIZE, sizeof(struct txd))) { diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:49:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:52:01.0 +0200 @@ -90,7 +90,6 @@ static int rt2x00_debug_level = 0; #define RX_ENTRIES 12 #define TX_ENTRIES 12 #define ATIM_ENTRIES 1 -#define PRIO_ENTRIES 6 #define BEACON_ENTRIES 1 /* pgpMtc6npJUhB.pgp Description: PGP signature
[PATCH 10/32] rt2x00: Move TSF counting activation to correct funtion
From: Ivo van Doorn <[EMAIL PROTECTED]> Move the enabling of TSF counting into *_config_mode where it actually belongs. For rt2500usb this means that the rt2500usb_reset_tsf function is now removed since it is still unknown in what registers the TSF counters are stored in. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:41:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:42:29.0 +0200 @@ -385,6 +385,9 @@ rt2400pci_config_mode(struct rt2x00_pci { u32 reg; + /* +* Apply hardware packet filter. +*/ rt2x00_register_read(rt2x00pci, RXCSR0, ®); if (mode == IW_MODE_ADHOC @@ -408,6 +411,19 @@ rt2400pci_config_mode(struct rt2x00_pci } rt2x00_register_write(rt2x00pci, RXCSR0, reg); + + /* +* Enable TSF counter. +*/ + rt2x00_register_read(rt2x00pci, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); + if (mode == IW_MODE_ADHOC) + rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); + else if (mode == IW_MODE_INFRA) + rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); + else + rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); + rt2x00_register_write(rt2x00pci, CSR14, reg); } static void @@ -1723,21 +1739,10 @@ static void rt2400pci_reset_tsf(struct net_device *net_dev) { struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); - struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev); u32 reg = 0; rt2x00_register_write(rt2x00pci, CSR16, reg); rt2x00_register_write(rt2x00pci, CSR17, reg); - - rt2x00_register_read(rt2x00pci, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); - if (conf->mode == IW_MODE_ADHOC) - rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); - else if (conf->mode == IW_MODE_INFRA) - rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); - else - rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); - rt2x00_register_write(rt2x00pci, CSR14, reg); } static int diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:41:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:42:29.0 +0200 @@ -385,6 +385,9 @@ rt2500pci_config_mode(struct rt2x00_pci { u32 reg; + /* +* Apply hardware packet filter. +*/ rt2x00_register_read(rt2x00pci, RXCSR0, ®); if (mode == IW_MODE_ADHOC @@ -411,6 +414,19 @@ rt2500pci_config_mode(struct rt2x00_pci rt2x00_set_field32(®, RXCSR0_DROP_BCAST, 0); rt2x00_register_write(rt2x00pci, RXCSR0, reg); + + /* +* Enable TSF counter. +*/ + rt2x00_register_read(rt2x00pci, CSR14, ®); + rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); + if (mode == IW_MODE_ADHOC) + rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); + else if (mode == IW_MODE_INFRA) + rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); + else + rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); + rt2x00_register_write(rt2x00pci, CSR14, reg); } static void @@ -1809,21 +1825,10 @@ static void rt2500pci_reset_tsf(struct net_device *net_dev) { struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); - struct ieee80211_conf *conf = ieee80211_get_hw_conf(net_dev); u32 reg = 0; rt2x00_register_write(rt2x00pci, CSR16, reg); rt2x00_register_write(rt2x00pci, CSR17, reg); - - rt2x00_register_read(rt2x00pci, CSR14, ®); - rt2x00_set_field32(®, CSR14_TSF_COUNT, 1); - if (conf->mode == IW_MODE_ADHOC) - rt2x00_set_field32(®, CSR14_TSF_SYNC, 2); - else if (conf->mode == IW_MODE_INFRA) - rt2x00_set_field32(®, CSR14_TSF_SYNC, 1); - else - rt2x00_set_field32(®, CSR14_TSF_SYNC, 0); - rt2x00_register_write(rt2x00pci, CSR14, reg); } static int diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:41:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:42:29.0 +0200 @@ -268,6 +268,9 @@ rt2500usb_config_mode(struct rt2x00_usb {
[PATCH 16/32] rt2x00: Make sure TX rings are empty when scanning
From: Ivo van Doorn <[EMAIL PROTECTED]> Improve the waiting when a skb buffer needs to be send before the channel switch. This also makes sure no pending packets are still on the TX ring while making the channel switch. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:47:52.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:48:21.0 +0200 @@ -838,7 +838,6 @@ rt2400pci_txdone(void *data) struct rt2x00_pci *rt2x00pci = (struct rt2x00_pci*)ring->dev; struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); struct data_entry *entry; - struct skb_cb *cb; struct txd *txd; int tx_status; int ack; @@ -851,13 +850,6 @@ rt2400pci_txdone(void *data) || !rt2x00_get_field32(txd->word0, TXD_W0_VALID)) break; - /* -* Check if this frame was send for the scan routine. -*/ - cb = (struct skb_cb*)&entry->skb->cb; - if (rt2x00pci->scan && cb->scan_complete) - complete(&rt2x00pci->scan->completion); - ack = rt2x00_get_field32(txd->word0, TXD_W0_ACK); /* @@ -896,6 +888,18 @@ rt2400pci_txdone(void *data) rt2x00_ring_index_done_inc(ring); } while (!rt2x00_ring_empty(ring)); + + /* +* Check if we are waiting on an empty queue +* to start scanning. +*/ + if (rt2x00pci->scan + && rt2x00_ring_empty(&rt2x00pci->tx) + && rt2x00_ring_empty(&rt2x00pci->atim) + && rt2x00_ring_empty(&rt2x00pci->prio)) { + rt2x00pci->scan->status = SCANNING_READY; + complete(&rt2x00pci->scan->completion); + } } static irqreturn_t @@ -1517,6 +1521,14 @@ rt2400pci_stop(struct net_device *net_de rt2x00_register_write(rt2x00pci, CSR8, reg); /* +* Cancel scanning. +*/ + if (rt2x00pci->scan) { + rt2x00pci->scan->status = SCANNING_CANCELLED; + complete_all(&rt2x00pci->scan->completion); + } + + /* * Free DMA rings. */ rt2400pci_free_rings(rt2x00pci); @@ -1564,35 +1576,23 @@ static void rt2400pci_scan(void *data) { struct rt2x00_pci *rt2x00pci = data; - struct net_device *net_dev = pci_get_drvdata(rt2x00pci->pci_dev); - struct skb_cb *cb; if (unlikely(!rt2x00pci->scan)) return; /* -* Check if we have to send a packet before the -* channel switch. +* Before we can start switch the channel for scanning +* we need to wait untill all TX rings are empty to +* guarentee that all frames are send on the correct channel. */ - if (rt2x00pci->scan->conf.skb) { - cb = (struct skb_cb*)&rt2x00pci->scan->conf.skb->cb; - cb->scan_complete = 1; - - if (rt2400pci_tx(net_dev, rt2x00pci->scan->conf.skb, - rt2x00pci->scan->conf.tx_control)) - goto exit; - - /* -* Wait for the frame to be correctly transmitted. -*/ + if (rt2x00pci->scan->status != SCANNING_READY) wait_for_completion(&rt2x00pci->scan->completion); - } /* * Check if this scan has been cancelled while * work was still scheduled. */ - if (rt2x00pci->scan->cancelled) + if (rt2x00pci->scan->status == SCANNING_CANCELLED) goto exit; /* @@ -1633,9 +1633,24 @@ rt2400pci_passive_scan(struct net_device { struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); + if (rt2x00pci->scan) + return -EBUSY; + + /* +* Allocate scanning structure to store scanning info. +*/ rt2x00pci->scan = kmalloc(sizeof(struct scanning), GFP_ATOMIC); if (!rt2x00pci->scan) - return 0; + return -ENOMEM; + + /* +* Check if we have to send a packet before the +* channel switch. +*/ + if (conf->skb) { + if (rt2400pci_tx(net_dev, conf->skb, conf->tx_control)) + goto exit; + } /* * Initialize Scanning structure. @@ -1646,14 +1661,21 @@ rt2400pci_passive_scan(struct net_device rt2x00pci->scan->state = state; - rt2x00pci->scan->cancelled = 0; + rt2x00pci->scan->status = 0; /* * Queue work. */ - queue_work(rt2
[PATCH 5/32] rt2x00: Optimize RATE flag handling
From: Ivo van Doorn <[EMAIL PROTECTED]> Optimize RATE flags by using the FIELD32() macro's, also make the unit in which the rate is handled the same as is used in the dscape stack. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:38:23.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:39:24.0 +0200 @@ -550,7 +550,7 @@ rt2400pci_config_duration(struct rt2x00_ rt2x00_register_read(rt2x00pci, CSR19, ®); value = SIFS + (2 * short_slot_time); rt2x00_set_field32(®, CSR19_DIFS, value); - value = SIFS + get_duration(IEEE80211_HEADER + ACK_SIZE, 2); + value = SIFS + get_duration(IEEE80211_HEADER + ACK_SIZE, 10); rt2x00_set_field32(®, CSR19_EIFS, value); rt2x00_register_write(rt2x00pci, CSR19, reg); @@ -580,11 +580,11 @@ rt2400pci_config_rate(struct rt2x00_pci value = SIFS + PLCP + (2 * (conf->short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME)) + preamble - + get_duration(ACK_SIZE, 2); + + get_duration(ACK_SIZE, 10); rt2x00_set_field32(®[0], TXCSR1_ACK_TIMEOUT, value); value = SIFS + PLCP + preamble - + get_duration(ACK_SIZE, 2); + + get_duration(ACK_SIZE, 10); rt2x00_set_field32(®[0], TXCSR1_ACK_CONSUME_TIME, value); rt2x00_register_write(rt2x00pci, TXCSR1, reg[0]); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:38:23.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:39:24.0 +0200 @@ -565,7 +565,7 @@ rt2500pci_config_duration(struct rt2x00_ rt2x00_register_read(rt2x00pci, CSR19, ®); value = SIFS + (2 * short_slot_time); rt2x00_set_field32(®, CSR19_DIFS, value); - value = SIFS + get_duration(IEEE80211_HEADER + ACK_SIZE, 2); + value = SIFS + get_duration(IEEE80211_HEADER + ACK_SIZE, 10); rt2x00_set_field32(®, CSR19_EIFS, value); rt2x00_register_write(rt2x00pci, CSR19, reg); @@ -595,11 +595,11 @@ rt2500pci_config_rate(struct rt2x00_pci value = SIFS + PLCP + (2 * (conf->short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME)) + preamble - + get_duration(ACK_SIZE, 2); + + get_duration(ACK_SIZE, 10); rt2x00_set_field32(®[0], TXCSR1_ACK_TIMEOUT, value); value = SIFS + PLCP + preamble - + get_duration(ACK_SIZE, 2); + + get_duration(ACK_SIZE, 10); rt2x00_set_field32(®[0], TXCSR1_ACK_CONSUME_TIME, value); rt2x00_register_write(rt2x00pci, TXCSR1, reg[0]); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:38:23.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:39:24.0 +0200 @@ -467,7 +467,7 @@ rt2500usb_config_rate(struct rt2x00_usb value = SIFS + PLCP + (2 * (conf->short_slot_time ? SHORT_SLOT_TIME : SLOT_TIME)) + preamble - + get_duration(ACK_SIZE, 2); + + get_duration(ACK_SIZE, 10); rt2x00_set_field16_nb(®, TXRX_CSR1_ACK_TIMEOUT, value); rt2x00_register_write(rt2x00usb, TXRX_CSR1, reg); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:36:19.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h 2006-04-27 21:39:24.0 +0200 @@ -609,71 +609,69 @@ struct scanning{ * passed to the ieee80211 kernel. We need to make it a consist of * multiple fields because we want to store more then 1 device specific * values inside the value. - * 1 - rate, stored as 0.5Mbit/s. - * 2 - MASK_RATE, which rates are enabled in this mode, this mask + * 1 - rate, stored as 100 kbit/s. + * 2 - preamble, short_preamble enabled flag. + * 3 - MASK_RATE, which rates are enabled in this mode, this mask * corresponds with the TX register format for the current device. - * 3 - plcp, 802.11b rates are device specific, + * 4 - plcp, 802.11b rates are device specific, * 802.11g rates are set according to the
[PATCH 23/32] rt2x00: Make correct cast in USB interrupt
From: Ivo van Doorn <[EMAIL PROTECTED]> The USB interrupt handler receives the entry in the ring and not the ring itself. Also check if the status indicates an error before queueing the work. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:53:13.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:54:33.0 +0200 @@ -856,11 +856,14 @@ rt2500usb_txdone(void *data) static void rt2500usb_interrupt(struct urb *urb, struct pt_regs *regs) { - struct data_ring*ring = (struct data_ring*)urb->context; + struct data_entry *entry = (struct data_entry*)urb->context; struct rt2x00_usb *rt2x00usb = - ieee80211_dev_hw_data(ring->net_dev); + ieee80211_dev_hw_data(entry->ring->net_dev); - queue_work(rt2x00usb->workqueue, &ring->irq_work); + if (urb->status) + return; + + queue_work(rt2x00usb->workqueue, &entry->ring->irq_work); } /* @@ -1064,7 +1067,6 @@ rt2500usb_init_txring(struct rt2x00_usb } } - static int rt2500usb_init_rings(struct rt2x00_usb *rt2x00usb) { @@ -1798,7 +1800,7 @@ rt2500usb_init_hw_channels(struct rt2x00 for (counter = 0; counter < ARRAY_SIZE(vals); counter++) channels[counter].val = vals[counter] | rf2_base; } else if (rt2x00_rf(&rt2x00usb->chip, RF2525E)) { - u32 vals[] = { + static u32 vals[] = { 0x089a, 0x089e, 0x089e, 0x08a2, 0x08a2, 0x08a6, 0x08a6, 0x08aa, 0x08aa, 0x08ae, 0x08ae, 0x08b2, pgpbQxcfC8dzs.pgp Description: PGP signature
[PATCH 7/32] rt2x00: make vals static
From: Ivo van Doorn <[EMAIL PROTECTED]> The vals[] arrays in *_init_hw_channels can be made static to optimize memory and reduce stack size. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:40:06.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:40:43.0 +0200 @@ -1868,7 +1868,7 @@ rt2400pci_init_hw_channels(struct rt2x00 { int counter; u16 eeprom; - u32 vals[] = { + static u32 vals[] = { 0x000c1fda, 0x000c1fee, 0x000c2002, 0x000c2016, 0x000c202a, 0x000c203e, 0x000c2052, 0x000c2066, 0x000c207a, 0x000c208e, 0x000c20a2, 0x000c20b6, diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:40:06.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:40:43.0 +0200 @@ -1929,9 +1929,9 @@ rt2500pci_init_hw_channels(struct rt2x00 struct ieee80211_channel *channels) { int counter; - u16 eeprom; u32 rf2_base; - struct { + u16 eeprom; + static struct { unsigned int chip; u32 val[3]; } rf[] = { @@ -1947,16 +1947,16 @@ rt2500pci_init_hw_channels(struct rt2x00 * Channel initialization. * First we set the basic variables. */ - for (counter = 0; counter < 13; counter++) { - channels[counter].chan = counter + 1; + for (counter = 0; counter < 13; counter++) { + channels[counter].chan = counter + 1; channels[counter].freq = 2407 + ((counter + 1) * 5); channels[counter].flag = IEEE80211_CHAN_W_IBSS | IEEE80211_CHAN_W_ACTIVE_SCAN | IEEE80211_CHAN_W_SCAN; channels[counter].antenna_max = 0xff; - } + } - channels[13].chan = 14; - channels[13].freq = 2484; + channels[13].chan = 14; + channels[13].freq = 2484; channels[13].flag = IEEE80211_CHAN_W_IBSS | IEEE80211_CHAN_W_ACTIVE_SCAN | IEEE80211_CHAN_W_SCAN; channels[13].antenna_max = 0xff; @@ -1988,7 +1988,7 @@ rt2500pci_init_hw_channels(struct rt2x00 rf2_base = 0x0008; if (rt2x00_rf(&rt2x00pci->chip, RF2522)) { - u32 vals[] = { + static u32 vals[] = { 0x000c1fda, 0x000c1fee, 0x000c2002, 0x000c2016, 0x000c202a, 0x000c203e, 0x000c2052, 0x000c2066, 0x000c207a, 0x000c208e, 0x000c20a2, 0x000c20b6, @@ -2000,7 +2000,7 @@ rt2500pci_init_hw_channels(struct rt2x00 } else if (rt2x00_rf(&rt2x00pci->chip, RF2523) || rt2x00_rf(&rt2x00pci->chip, RF2524) || rt2x00_rf(&rt2x00pci->chip, RF2525)) { - u32 vals[] = { + static u32 vals[] = { 0x0c9e, 0x0ca2, 0x0ca6, 0x0caa, 0x0cae, 0x0cb2, 0x0cb6, 0x0cba, 0x0cbe, 0x0d02, 0x0d06, 0x0d0a, @@ -2012,7 +2012,7 @@ rt2500pci_init_hw_channels(struct rt2x00 cpu_to_le32(vals[counter] | rf2_base); } else if (rt2x00_rf(&rt2x00pci->chip, RF2525E) || rt2x00_rf(&rt2x00pci->chip, RF5222)) { - u32 vals[] = { + static u32 vals[] = { 0x1136, 0x113a, 0x113e, 0x1182, 0x1186, 0x118a, 0x118e, 0x1192, 0x1196, 0x119a, 0x119e, 0x11a2, @@ -2024,7 +2024,7 @@ rt2500pci_init_hw_channels(struct rt2x00 cpu_to_le32(vals[counter] | rf2_base); } if (rt2x00_rf(&rt2x00pci->chip, RF5222)) { - u32 vals[] = { + static u32 vals[] = { 0x00018896, 0x0001889a, 0x0001889e, 0x000188a2, 0x000188a6, 0x000188aa, 0x000188ae, 0x000188b2, 0x8802, 0x8806, 0x880a, 0x880e, diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:40:06.0 +0200 +++ wi
[PATCH 20/32] rt2x00: byte ordering correctness
From: Ivo van Doorn <[EMAIL PROTECTED]> Fix various little/big endian conversions. rt2500pci should use cpu_to_le32 and rt2500usb should not. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:50:36.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:51:11.0 +0200 @@ -441,7 +441,7 @@ rt2500pci_config_channel(struct rt2x00_p txpower = (txpower > 31) ? 31 : txpower; if (rt2x00_rf(&rt2x00pci->chip, RF2525E) && channel == 14) - rf4 |= 0x0010; + rf4 |= cpu_to_le32(0x0010); if (rt2x00_rf(&rt2x00pci->chip, RF5222)) { if (channel < 14) { diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:50:36.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:51:11.0 +0200 @@ -324,20 +324,20 @@ rt2500usb_config_channel(struct rt2x00_u if (rt2x00_rf(&rt2x00usb->chip, RF5222)) { if (channel < 14) { - rf1 = cpu_to_le32(0x00022020); - rf4 = cpu_to_le32(0x0a0b); + rf1 = 0x00022020; + rf4 = 0x0a0b; } else if (channel == 14) { - rf1 = cpu_to_le32(0x00022010); - rf4 = cpu_to_le32(0x0a1b); + rf1 = 0x00022010; + rf4 = 0x0a1b; } else if (channel < 64) { - rf1 = cpu_to_le32(0x00022010); - rf4 = cpu_to_le32(0x0a1f); + rf1 = 0x00022010; + rf4 = 0x0a1f; } else if (channel < 140) { - rf1 = cpu_to_le32(0x00022010); - rf4 = cpu_to_le32(0x0a0f); + rf1 = 0x00022010; + rf4 = 0x0a0f; } else if (channel < 161) { - rf1 = cpu_to_le32(0x00022020); - rf4 = cpu_to_le32(0x0a07); + rf1 = 0x00022020; + rf4 = 0x0a07; } } @@ -1829,7 +1829,7 @@ rt2500usb_init_hw_channels(struct rt2x00 }; for (counter = 0; counter < ARRAY_SIZE(vals); counter++) - channels[counter].val = cpu_to_le32(vals[counter]); + channels[counter].val = vals[counter]; } else if (rt2x00_rf(&rt2x00usb->chip, RF2523) || rt2x00_rf(&rt2x00usb->chip, RF2524) || rt2x00_rf(&rt2x00usb->chip, RF2525)) { @@ -1841,8 +1841,7 @@ rt2500usb_init_hw_channels(struct rt2x00 }; for (counter = 0; counter < ARRAY_SIZE(vals); counter++) - channels[counter].val = - cpu_to_le32(vals[counter] | rf2_base); + channels[counter].val = vals[counter] | rf2_base; } else if (rt2x00_rf(&rt2x00usb->chip, RF2525E)) { u32 vals[] = { 0x089a, 0x089e, 0x089e, 0x08a2, @@ -1852,7 +1851,7 @@ rt2500usb_init_hw_channels(struct rt2x00 }; for (counter = 0; counter < ARRAY_SIZE(vals); counter++) - channels[counter].val = cpu_to_le32(vals[counter]); + channels[counter].val = vals[counter]; } else if (rt2x00_rf(&rt2x00usb->chip, RF5222)) { static u32 vals[] = { 0x1136, 0x113a, 0x113e, 0x1182, @@ -1868,7 +1867,7 @@ rt2500usb_init_hw_channels(struct rt2x00 }; for (counter = 0; counter < ARRAY_SIZE(vals); counter++) - channels[counter].val = cpu_to_le32(vals[counter]); + channels[counter].val = vals[counter]; } /* @@ -1895,9 +1894,9 @@ rt2500usb_init_hw_channels(struct rt2x00 */ for (counter = 0; counter < ARRAY_SIZE(rf); counter++) { if (rt2x00_rf(&rt2x00usb->chip, rf[counter].chip)) { - rt2x00usb->rf1 = cpu_to_le32(rf[counter].val[0]); - rt2x00usb->rf3 = cpu_to_le32(rf[counter].val[1]); - rt2x00usb->rf4 = cpu_to_le32(rf[counter].val[2]); + rt2x00usb->rf1 = rf[counter].val[0]; + rt2x00usb->rf3 = rf[counter].val[1]; + rt2x00usb->rf4 = rf[counter
[PATCH 8/32] rt2x00: Invalid memory allocation check
From: Ivo van Doorn <[EMAIL PROTECTED]> Fix invalid check when allocating the memory for the rate structures. Instead of the channel pointer the rates pointer should be verified. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:40:43.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:41:20.0 +0200 @@ -2036,7 +2036,7 @@ rt2400pci_init_hw(struct rt2x00_pci *rt2 hw->modes->num_rates = 4; hw->modes->rates = kzalloc(sizeof(struct ieee80211_rate) * 4, GFP_KERNEL); - if (!hw->modes->channels) + if (!hw->modes->rates) goto exit_free_channels; /* diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:40:43.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:41:20.0 +0200 @@ -2236,7 +2236,7 @@ rt2500pci_init_hw(struct rt2x00_pci *rt2 hw->modes->rates = kzalloc((sizeof(struct ieee80211_rate) * 12), GFP_KERNEL); - if (!hw->modes->channels) + if (!hw->modes->rates) goto exit_free_channels; } else { hw->num_modes = 3; @@ -2255,7 +2255,7 @@ rt2500pci_init_hw(struct rt2x00_pci *rt2 hw->modes->rates = kzalloc((sizeof(struct ieee80211_rate) * 12), GFP_KERNEL); - if (!hw->modes->channels) + if (!hw->modes->rates) goto exit_free_channels; } diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:40:43.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:41:20.0 +0200 @@ -1931,7 +1931,7 @@ rt2500usb_init_hw(struct rt2x00_usb *rt2 hw->modes->rates = kzalloc((sizeof(struct ieee80211_rate) * 12), GFP_KERNEL); - if (!hw->modes->channels) + if (!hw->modes->rates) goto exit_free_channels; } else { hw->num_modes = 3; @@ -1950,7 +1950,7 @@ rt2500usb_init_hw(struct rt2x00_usb *rt2 hw->modes->rates = kzalloc((sizeof(struct ieee80211_rate) * 12), GFP_KERNEL); - if (!hw->modes->channels) + if (!hw->modes->rates) goto exit_free_channels; } pgp2KiQ7ZKxrx.pgp Description: PGP signature
[PATCH 9/32] rt2x00: Fix antenna configuration
From: Ivo van Doorn <[EMAIL PROTECTED]> The handling of the antenna configuration was not completely correct. For all modules the double clearing of some bits can be reduced, and for rt2500pci and rt2500usb some registers were not corretly changed. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:41:20.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:41:52.0 +0200 @@ -485,6 +485,9 @@ rt2400pci_config_antenna(struct rt2x00_p rt2x00_bbp_read(rt2x00pci, 4, ®_rx); rt2x00_bbp_read(rt2x00pci, 1, ®_tx); + /* +* Clear current config antenna bits. +*/ reg_rx &= ~0x06; reg_tx &= ~0x03; @@ -495,18 +498,18 @@ rt2400pci_config_antenna(struct rt2x00_p */ if (antenna == 0) { /* Diversity. */ - reg_rx = (reg_rx & 0xf9) | 0x02; - reg_tx = (reg_tx & 0xfc) | 0x01; + reg_rx |= 0x02; + reg_tx |= 0x01; } else if (antenna == 1) { /* RX: Antenna B */ - reg_rx = (reg_rx & 0xf9) | 0x04; + reg_rx |= 0x04; /* TX: Antenna A */ - reg_tx = (reg_tx & 0xfc) | 0x00; + reg_tx |= 0x00; } else if (antenna == 2) { /* RX: Antenna A */ - reg_rx = (reg_rx & 0xf9) | 0x00; + reg_rx |= 0x00; /* TX: Antenna B */ - reg_tx = (reg_tx & 0xfc) | 0x02; + reg_tx |= 0x02; } rt2x00_bbp_write(rt2x00pci, 4, reg_rx); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:41:20.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:41:52.0 +0200 @@ -506,12 +506,17 @@ rt2500pci_config_channel(struct rt2x00_p static void rt2500pci_config_antenna(struct rt2x00_pci *rt2x00pci, int antenna) { + u32 reg; u8 reg_rx; u8 reg_tx; + rt2x00_register_read(rt2x00pci, BBPCSR1, ®); rt2x00_bbp_read(rt2x00pci, 14, ®_rx); rt2x00_bbp_read(rt2x00pci, 2, ®_tx); + /* +* Clear current config antenna bits. +*/ reg_rx &= ~0x06; reg_tx &= ~0x03; @@ -522,20 +527,46 @@ rt2500pci_config_antenna(struct rt2x00_p */ if (antenna == 0) { /* Diversity. */ - reg_rx = (reg_rx & 0xf9) | 0x02; - reg_tx = (reg_tx & 0xfc) | 0x01; + reg_rx |= 0x02; + reg_tx |= 0x01; + rt2x00_set_field32(®, BBPCSR1_CCK, 2); + rt2x00_set_field32(®, BBPCSR1_OFDM, 2); } else if (antenna == 1) { /* RX: Antenna B */ - reg_rx = (reg_rx & 0xf9) | 0x04; + reg_rx |= 0x04; /* TX: Antenna A */ - reg_tx = (reg_tx & 0xfc) | 0x00; + reg_tx |= 0x00; + rt2x00_set_field32(®, BBPCSR1_CCK, 0); + rt2x00_set_field32(®, BBPCSR1_OFDM, 0); } else if (antenna == 2) { /* RX: Antenna A */ - reg_rx = (reg_rx & 0xf9) | 0x00; + reg_rx |= 0x00; /* TX: Antenna B */ - reg_tx = (reg_tx & 0xfc) | 0x02; + reg_tx |= 0x02; + rt2x00_set_field32(®, BBPCSR1_CCK, 2); + rt2x00_set_field32(®, BBPCSR1_OFDM, 2); + } + + /* +* RT2525E and RT5222 need to flip TX I/Q +*/ + if (rt2x00_rf(&rt2x00pci->chip, RF2525E) + || rt2x00_rf(&rt2x00pci->chip, RF5222)) { + reg_tx |= 0x04; + rt2x00_set_field32(®, BBPCSR1_CCK_FLIP, 1); + rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 1); + + /* +* RT2525E does not need RX I/Q Flip. +*/ + if (rt2x00_rf(&rt2x00pci->chip, RF2525E)) + reg_rx &= ~0x04; + } else { + rt2x00_set_field32(®, BBPCSR1_CCK_FLIP, 0); + rt2x00_set_field32(®, BBPCSR1_OFDM_FLIP, 0); } + rt2x00_register_write(rt2x00pci, BBPCSR1, reg); rt2x00_bbp_write(rt2x00pci, 14, reg_rx); rt2x00_bbp_write(rt2x00pci, 2, reg_tx); diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-
[PATCH 25/32] rt2x00: Add flag handlers
From: Ivo van Doorn <[EMAIL PROTECTED]> Add flag handlers to set the state and capabilities of the driver. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:53:13.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:56:05.0 +0200 @@ -1099,7 +1099,7 @@ rt2400pci_allocate_rings(struct rt2x00_p return -ENOMEM; } - rt2x00pci->atim_available = 1; + SET_FLAG(rt2x00pci, ATIM_AVAILABLE); if (rt2400pci_alloc_ring( rt2x00pci, &rt2x00pci->ring[RING_RX], rt2400pci_rxdone, @@ -1549,6 +1549,8 @@ rt2400pci_open(struct net_device *net_de rt2x00_set_field32(®, CSR8_RXDONE, 0); rt2x00_register_write(rt2x00pci, CSR8, reg); + SET_FLAG(rt2x00pci, RADIO_ENABLED); + return 0; exit_fail: @@ -1563,6 +1565,8 @@ rt2400pci_stop(struct net_device *net_de struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); u32 reg; + CLEAR_FLAG(rt2x00pci, RADIO_ENABLED); + rt2x00_register_write(rt2x00pci, PWRCSR0, 0); /* @@ -1972,16 +1976,11 @@ rt2400pci_init_eeprom(struct rt2x00_pci rt2x00pci->led_mode = rt2x00_get_field16(eeprom, EEPROM_ANTENNA_LED_MODE); -#ifdef CONFIG_RT2400PCI_BUTTON /* * 6 - Detect if this device has an hardware controlled radio. -* If this device is not hardware controlled, disable polling timer. */ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_HARDWARE_RADIO)) - rt2x00pci->button_status = BUTTON_STATUS_OFF; - else - rt2x00pci->button_status = BUTTON_STATUS_UNAVAILABLE; -#endif /* CONFIG_RT2400PCI_BUTTON */ + SET_FLAG(rt2x00pci, HARDWARE_BUTTON); /* * 7 - Read BBP data from EEPROM and store in private structure. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:53:13.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h 2006-04-27 21:56:05.0 +0200 @@ -868,6 +868,11 @@ struct data_entry{ * Device specific structure. */ struct rt2x00_pci{ + /* +* Device flags. +*/ + unsigned intflags; + #ifdef CONFIG_RT2400PCI_BUTTON /* * ACPI device for generation of ACPI events. @@ -935,8 +940,6 @@ struct rt2x00_pci{ */ int false_cca; - int atim_available; - /* * EEPROM bus width. */ @@ -987,7 +990,7 @@ rt2x00pci_get_ring(struct rt2x00_pci *rt { u8 atim; - atim = rt2x00pci->atim_available; + atim = GET_FLAG(rt2x00pci, ATIM_AVAILABLE); /* * Check if the rings have been allocated. diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:53:13.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:56:05.0 +0200 @@ -1180,7 +1180,7 @@ rt2500pci_allocate_rings(struct rt2x00_p return -ENOMEM; } - rt2x00pci->atim_available = 1; + SET_FLAG(rt2x00pci, ATIM_AVAILABLE); if (rt2500pci_alloc_ring( rt2x00pci, &rt2x00pci->ring[RING_RX], rt2500pci_rxdone, @@ -1657,6 +1657,8 @@ rt2500pci_open(struct net_device *net_de rt2x00_set_field32(®, CSR8_RXDONE, 0); rt2x00_register_write(rt2x00pci, CSR8, reg); + SET_FLAG(rt2x00pci, RADIO_ENABLED); + return 0; exit_fail: @@ -1671,6 +1673,8 @@ rt2500pci_stop(struct net_device *net_de struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); u32 reg; + CLEAR_FLAG(rt2x00pci, RADIO_ENABLED); + rt2x00_register_write(rt2x00pci, PWRCSR0, 0); /* @@ -1929,7 +1933,7 @@ rt2500pci_conf_tx(struct net_device *net /* * The passed variables are stored as real value ((2^n)-1). -* RT2400 registers require to know the bit number 'n'. +* RT2500 registers require to know the bit number 'n'. */ if (params->cw_min) ring->tx_params.cw_min = HIGHEST_BIT16(params->cw_min) + 1; @@ -2075,16 +2079,11 @@ rt2500pci_init_eeprom(struct rt2x00_p
[PATCH 4/32] rt2x00: Add eeprom_multiread function
From: Ivo van Doorn <[EMAIL PROTECTED]> Add the eeprom_multiread function and clean up the code a bit by using it as well. ;) Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:37:02.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:38:23.0 +0200 @@ -351,6 +351,17 @@ rt2x00_eeprom_read( rt2x00_eeprom_pulse_low(rt2x00pci, &flags); } +static void +rt2x00_eeprom_multiread( + const struct rt2x00_pci *rt2x00pci, + const u8 word, u16 *data, const u16 length) +{ + int counter; + + for (counter = 0; counter < (length / sizeof(u16)); counter++) + rt2x00_eeprom_read(rt2x00pci, word + counter, data++); +} + /* * Configuration handlers. */ @@ -1824,9 +1835,8 @@ rt2400pci_init_eeprom(struct rt2x00_pci /* * 7 - Read BBP data from EEPROM and store in private structure. */ - for (counter = 0; counter < EEPROM_BBP_SIZE; counter++) - rt2x00_eeprom_read(rt2x00pci, EEPROM_BBP_START + counter, - &rt2x00pci->eeprom[counter]); + rt2x00_eeprom_multiread(rt2x00pci, EEPROM_BBP_START, + &rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); return 0; } diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:37:02.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-04-27 21:38:23.0 +0200 @@ -351,6 +351,17 @@ rt2x00_eeprom_read( rt2x00_eeprom_pulse_low(rt2x00pci, &flags); } +static void +rt2x00_eeprom_multiread( + const struct rt2x00_pci *rt2x00pci, + const u8 word, u16 *data, const u16 length) +{ + int counter; + + for (counter = 0; counter < (length / sizeof(u16)); counter++) + rt2x00_eeprom_read(rt2x00pci, word + counter, data++); +} + /* * Configuration handlers. */ @@ -1886,9 +1897,8 @@ rt2500pci_init_eeprom(struct rt2x00_pci /* * 7 - Read BBP data from EEPROM and store in private structure. */ - for (counter = 0; counter < EEPROM_BBP_SIZE; counter++) - rt2x00_eeprom_read(rt2x00pci, EEPROM_BBP_START + counter, - &rt2x00pci->eeprom[counter]); + rt2x00_eeprom_multiread(rt2x00pci, EEPROM_BBP_START, + &rt2x00pci->eeprom, EEPROM_BBP_SIZE * sizeof(u16)); return 0; } diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:36:17.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-04-27 21:38:23.0 +0200 @@ -228,11 +228,21 @@ rf_write: static inline void rt2x00_eeprom_read( const struct rt2x00_usb *rt2x00usb, - const u16 offset, u16 *value, const u16 length) + const u16 word, u16 *data) { rt2x00_vendor_request( rt2x00usb, USB_EEPROM_READ, USB_VENDOR_REQUEST_IN, - offset, 0x00, value, length); + word, 0x00, data, 2); +} + +static void +rt2x00_eeprom_multiread( + const struct rt2x00_usb *rt2x00usb, + const u8 word, u16 *data, const u16 length) +{ + rt2x00_vendor_request( + rt2x00usb, USB_EEPROM_READ, USB_VENDOR_REQUEST_IN, + word, 0x00, data, length); } /* @@ -1552,7 +1562,7 @@ rt2500usb_init_eeprom(struct rt2x00_usb /* * 1 - Read EEPROM word for configuration. */ - rt2x00_eeprom_read(rt2x00usb, EEPROM_ANTENNA, &eeprom, 2); + rt2x00_eeprom_read(rt2x00usb, EEPROM_ANTENNA, &eeprom); /* * 2 - Identify RF chipset. @@ -1579,7 +1589,7 @@ rt2500usb_init_eeprom(struct rt2x00_usb * 5 - Read BBP data from EEPROM and store in private structure. */ memset(&rt2x00usb->eeprom, 0x00, sizeof(rt2x00usb->eeprom)); - rt2x00_eeprom_read(rt2x00usb, EEPROM_BBP_START, + rt2x00_eeprom_multiread(rt2x00usb, EEPROM_BBP_START, &rt2x00usb->eeprom[0], EEPROM_BBP_SIZE); return 0; @@ -1595,7 +1605,7 @@ rt2500usb_init_mac(struct rt2x00_usb *rt /* * Read MAC address from EEPROM. */ - rt2x00_eeprom_read(rt2x00usb, EEPROM_MAC_ADDR, ®[0], 6); + rt2x00_eeprom_multiread(rt2x00usb, EEPROM_MAC_ADDR, ®[0], 6); net_dev->dev_addr[0] = rt2x00_get_field16(reg[0], MAC_CSR2_BYTE0);
[PATCH 18/32] rt2x00: Make sure device has reached requested state while suspend/resume
From: Ivo van Doorn <[EMAIL PROTECTED]> Add the *_set_state functions which makes sure the device is switching state to awake or sleep. Fix bad behaviour in the suspend routine, and disable the radio before suspending. Signed-off-by: Ivo van Doorn <[EMAIL PROTECTED]> diff -uprN wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c --- wireless-dev-rt2x00/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:49:08.0 +0200 +++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-04-27 21:49:59.0 +0200 @@ -653,6 +653,44 @@ rt2400pci_link_tuner(struct rt2x00_pci * } /* + * Device state switch. + * This will put the device to sleep, or awake it. + */ +static int +rt2400pci_set_state(struct rt2x00_pci *rt2x00pci, enum dev_state state) +{ + u32 reg; + int counter; + charput_to_sleep; + + put_to_sleep = (state != STATE_AWAKE); + + rt2x00_register_read(rt2x00pci, PWRCSR1, ®); + rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); + rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, state); + rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, state); + rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, put_to_sleep); + rt2x00_register_write(rt2x00pci, PWRCSR1, reg); + + /* +* Device is not guarenteed to be in the requested state yet. +* We must wait untill the register indicates that the +* device has entered the correct state. +*/ + for (counter = 0; counter < REGISTER_BUSY_COUNT; counter++) { + rt2x00_register_read(rt2x00pci, PWRCSR1, ®); + if ((rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE) == state) + && (rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE) == state)) + return 0; + msleep(10); + } + + NOTICE("Device failed to %s.\n" , put_to_sleep ? "suspend" : "resume"); + + return -EBUSY; +} + +/* * TX descriptor initialization */ static void @@ -1190,6 +1228,9 @@ rt2400pci_init_registers(struct rt2x00_p { u32 reg; + if (rt2400pci_set_state(rt2x00pci, STATE_AWAKE)) + return -EBUSY; + rt2x00_register_write(rt2x00pci, PWRCSR0, cpu_to_le32(0x3f3b3100)); rt2x00_register_write(rt2x00pci, PSCSR0, cpu_to_le32(0x00020002)); @@ -2342,57 +2383,42 @@ rt2400pci_remove(struct pci_dev *pci_dev } #ifdef CONFIG_PM -static int rt2400pci_resume(struct pci_dev *pci_dev); - static int rt2400pci_suspend(struct pci_dev *pci_dev, pm_message_t state) { struct net_device *net_dev = pci_get_drvdata(pci_dev); struct rt2x00_pci *rt2x00pci = ieee80211_dev_hw_data(net_dev); - int counter; - u32 reg; NOTICE("Going to sleep.\n"); - if (ieee80211_netif_oper(net_dev, NETIF_DETACH)) - return -EBUSY; - - rt2x00_register_read(rt2x00pci, PWRCSR1, ®); - rt2x00_set_field32(®, PWRCSR1_SET_STATE, 1); - rt2x00_set_field32(®, PWRCSR1_BBP_DESIRE_STATE, 1); - rt2x00_set_field32(®, PWRCSR1_RF_DESIRE_STATE, 1); - rt2x00_set_field32(®, PWRCSR1_PUT_TO_SLEEP, 1); - rt2x00_register_write(rt2x00pci, PWRCSR1, reg); - /* -* Device is not guarenteed to be asleep yet. -* We must wait untill the register indicates -* device has been correctly put to sleep. +* If radio was enabled, stop radio and +* set the resume flag to the radio will be enabled +* when resuming. */ - for (counter = 0; counter < REGISTER_BUSY_COUNT; counter++) { - rt2x00_register_read(rt2x00pci, PWRCSR1, ®); - if ((rt2x00_get_field32(reg, PWRCSR1_BBP_CURR_STATE) == 1) - && (rt2x00_get_field32(reg, PWRCSR1_RF_CURR_STATE) == 1)) - break; - NOTICE("Waiting for device to sleep.\n"); - msleep(10); + if (GET_FLAG(rt2x00pci, RADIO_ENABLED)) { + if (net_dev->stop(net_dev)) + return -EBUSY; + SET_FLAG(rt2x00pci, RADIO_RESUME); } - if (counter == REGISTER_BUSY_COUNT) - goto exit; - - if (pci_enable_wake(pci_dev, pci_choose_state(pci_dev, state), 1) - || pci_save_state(pci_dev) - || pci_set_power_state(pci_dev, pci_choose_state(pci_dev, state))) - goto exit; - - return 0; + /* +* Set device mode to sleep for power management. +*/ + if (rt2400pci_set_state(rt2x00pci, STATE_SLEEP)) + return -EBUSY; -exit: - ERROR("Failed to suspend device.\n"); + /* +* Uninitialize hardware. +*/ + rt2400pci_uninitialize(net_dev); - rt2400pci_resume(pci_dev); - return
Re: Netpoll checksum issue
On Thu, Apr 27, 2006 at 08:57:33PM +0800, Aubrey wrote: > > Is there any update of this issue? Assuming that the CHECKSUM_UNNECESSARY line wasn't there, then the problem is simply that your packet has the wrong UDP checksum. So I suggest that you print the packet out and compare it with the original to see where the corruption is. I don't see how the generic networking stack or netpoll could be causing your problem. Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 2.6.16.11 BUG at tg3.c:2917
On Thu, Apr 27, 2006 at 08:45:24AM -0700, Michael Chan wrote: > On Thu, 2006-04-27 at 12:52 -0400, Ed L. Cashin wrote: > > -- [please bite here ] - > > Kernel BUG at drivers/net/tg3.c:2917 > > invalid opcode: [1] SMP > > CPU 0 > > Most likely caused by IO re-ordering. Try the test patch in this > discussion: > > http://marc.theaimsgroup.com/?l=linux-netdev&m=113890239404768&w=2 I'm afraid I might be generating noise here. After my initial post I found that I cannot trigger a panic without the latest changes to the aoe driver in place. I haven't been able to trigger a panic using the aoe driver inside 2.6.16.11. I think we've identified the problem in the aoe driver, but if I'm wrong, I will certainly try the TG3_FLAG_MBOX_WRITE_REORDER patch you mention. -- Ed L Cashin <[EMAIL PROTECTED]> - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
[EMAIL PROTECTED] wrote: > From: Evgeniy Polyakov <[EMAIL PROTECTED]> > Date: Thu, 27 Apr 2006 15:51:26 +0400 > >> There are some caveats here found while developing zero-copy sniffer >> [1]. Project's goal was to remap skbs into userspace in real-time. >> While absolute numbers (posted to netdev@) were really high, it is >> only applicable to read-only application. As was shown in IOAT >> thread, data must be warmed in caches, so reading from mapped area >> will be as fast as memcpy() (read+write), and copy_to_user() >> actually almost equal to memcpy() (benchmarks were posted to >> netdev@). And we must add remapping overhead. > > Yes, all of these issues are related quite strongly. Thanks > for making the connection explicit. > > But, the mapping overhead is zero for this net channel stuff, > at least as it is implemented and designed by Kelly. Ring > buffer is setup ahead of time into the user's address space, > and a ring of buffers into that area are given to the networking card. > > We remember the translations here, so no get_user_pages() on > each transfer and garbage like that. And yes this all harks > back to the issues that are discussed in Chapter 5 of > Networking Algorithmics. > But the core thing to understand is that by defining a new > API and setting up the buffer pool ahead of time, we avoid all of the > get_user_pages() overhead while retaining full kernel/user protection. > > Evgeniy, the difference between this and your work is that > you did not have an intelligent piece of hardware that could > be told to recognize flows, and only put packets for a > specific flow into that's flow's buffer pool. > >> If we want to dma data from nic into premapped userspace area, this >> will strike with message sizes/misalignment/slow read and so on, so >> preallocation has even more problems. > > I do not really think this is an issue, we put the full > packet into user space and teach it where the offset is to > the actual data. > We'll do the same things we do today to try and get the data > area aligned. User can do whatever is logical and relevant > on his end to deal with strange cases. > > In fact we can specify that card has to take some care to get > data area of packet aligned on say an 8 byte boundary or > something like that. When we don't have hardware assist, we > are going to be doing copies. > >> This change also requires significant changes in application, at >> least until recv/send are changed, which is not the best thing to do. > > This is exactly the point, we can only do a good job and > receive zero copy if we can change the interfaces, and that's > exactly what we're doing here. > >> I do think that significant win in VJ's tests belongs not to >> remapping and cache-oriented changes, but to move all protocol >> processing into process' context. > > I partly disagree. The biggest win is eliminating all of the > control overhead (all of "softint RX + protocol demux + IP > route lookup + socket lookup" is turned into single flow > demux), and the SMP safe data structure which makes it > realistic enough to always move the bulk of the packet work > to the socket's home cpu. > > I do not think userspace protocol implementation buys enough > to justify it. We have to do the protection switch in and > out of kernel space anyways, so why not still do the > protected protocol processing work in the kernel? It is > still being done on the user's behalf, contributes to his > time slice, and avoids all of the terrible issues of > userspace protocol implementations. > > So in my mind, the optimal situation from both a protection > preservation and also a performance perspective is net > channels to kernel socket protocol processing, buffers DMA'd > directly into userspace if hardware assist is present. > Having a ring that is already flow qualified is indeed the most important savings, and worth pursuing even if reaching consensus on how to safely enable user-mode L4 processing. The latter *can* be a big advantage when the L4 processing can be done based on a user-mode call from an already scheduled process. But the benefit is not there for a process that needs to be woken up each time it receives a short request. So the real issue is when there is an intelligent device that uses hardware packet classification to place the packet in the correct ring. We don't want to bypass packet filtering, but it would be terribly wasteful to reclassify the packet. Intelligent NICs will have packet classification capabilities to support RDMA and iSCSI. Those capabilities should be available to benefit SOCK_STREAM and SOCK_DGRAM users as well without it being a choice of either turning all stack control over to the NIC or ignorign all NIC capabilities beyound pretending to be a dumb Ethernet NIC. For example, counting packets within an approved connection is a valid goal that the final solution should support. But would a simple count be sufficient, or do we truly need the full
Re: tune back idle cwnd closing?
having looked now at both 2861 and the 99 paper it references I see lots of "may's" "mights" and "belief" but nothing "real world." the CWV vs non CWV was done against a TCP that did indeed reset cwnd after an RTT of idle, so it wasn't showing reset at idle versus no reset at idle. just CWV's less draconian (?) reset than the non CWV stack. the experimental validation in the 99 paper was still a simulation using dummynet and a number of buffers rather smaller than what modem banks were offering at the time, and it was for a modem, rather than any other sort of link. and when they did use a real modem, the buffering in the modem bank seems to have made the whole thing moot. there was nothing about effect on intranets, or high-speed long hauls or any of that. what that means wrt having a sysctl to enable/disable functionality still listed as experimental i'm not sure rick jones - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] e1000 performance patch
On Thu, Apr 27, 2006 at 09:07:36AM -0700, Rick Jones wrote: >There should be three basic measures there - one is the single-instance >request-response test. The idea is to see minimum latency. That test >likes to see the interrupt throttle rate made very high, or disabled >completely. > >The aggregate TCP_RR's and the TCP_STREAM tests are there to show what >effect that has on the ability to do aggregate request/response and a >bulk transfer. I guess the whole point of my patch is to try to handle all these cases efficiently without user intervention by making the driver self-tune the InterruptThrottleRate depending on what traffic it's seeing. I think it's doing the right things so far - at least it's a good compromise - it probably won't ever be ideal in all workloads. >>can netperf (or some other tool) mix up big and small message sizes >>like 'the real world' perhaps does? >>that might help me find a good frequency at which to try to adapt the >>ITR... (eg. 1, 10, 100 or 1000 times a second) > >There is the "vst" (variable size test IIRC) in netperf4: > >http://www.netperf.org/svn/netperf4/branches/glib_migration > >The docs for netperf4 are presently pathetic. Feel free to email me for >bootstrapping information. Basically, you'll need pkg-config, libxml2 >and glib-2.0 on the system. thanks. I'll check it out. actually, thinking about it more, the worst case for the patched driver is a quiescent system (where ITR will be maximum) which then sees a stream of large messages - say 500MB (~=5s at 1Gbit). so until the watchdog kicks in (every 2s at the moment) and lowers the ITR then the load on the cpu will be high. The only solution for this is to run the ITR resetting watchdog as often as possible. ie. times per second. And then test it on real codes that do some sort of large message bursty communication and see if they run faster or slower. The patched driver will actually deal fairly well with a mixed size workload as some of the workload will be large messages and that will (on average) lower the ITR automatically. cheers, robin - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [stable] [PATCH] e1000: Update truesize with the length of the packet for packet split
On Tue, Apr 25, 2006 at 11:16:29PM -0700, Kok, Auke wrote: > > Update skb with the real packet size. > > > Signed-off-by: Jesse Brandeburg <[EMAIL PROTECTED]> > Signed-off-by: Auke Kok <[EMAIL PROTECTED]> > Signed-off-by: John Ronciak <[EMAIL PROTECTED]> queued to -stable. thanks, greg k-h - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: tune back idle cwnd closing?
From: John Heffner <[EMAIL PROTECTED]> Date: Thu, 27 Apr 2006 13:47:33 -0400 > (Most OS's don't do 2861, and it is not a standard.) Are you so sure? Doing cwnd timeout largely predates the congestion window validation work, in fact by several years. In RFC 2581, it mentions Van Jacobson's recommendation of this idle period behavior, as just one example. Your arguments about "all the feedback mechanisms are in place, so not reducing the cwnd after idle doesn't hurt congestion control" could be applied to the packet retransmit timeout handling of the congestion window, and I think that's kind of silly. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
From: Evgeniy Polyakov <[EMAIL PROTECTED]> Date: Thu, 27 Apr 2006 15:51:26 +0400 > There are some caveats here found while developing zero-copy sniffer > [1]. Project's goal was to remap skbs into userspace in real-time. > While absolute numbers (posted to netdev@) were really high, it is only > applicable to read-only application. As was shown in IOAT thread, > data must be warmed in caches, so reading from mapped area will be as > fast as memcpy() (read+write), and copy_to_user() actually almost equal > to memcpy() (benchmarks were posted to netdev@). And we must add > remapping overhead. Yes, all of these issues are related quite strongly. Thanks for making the connection explicit. But, the mapping overhead is zero for this net channel stuff, at least as it is implemented and designed by Kelly. Ring buffer is setup ahead of time into the user's address space, and a ring of buffers into that area are given to the networking card. We remember the translations here, so no get_user_pages() on each transfer and garbage like that. And yes this all harks back to the issues that are discussed in Chapter 5 of Networking Algorithmics. But the core thing to understand is that by defining a new API and setting up the buffer pool ahead of time, we avoid all of the get_user_pages() overhead while retaining full kernel/user protection. Evgeniy, the difference between this and your work is that you did not have an intelligent piece of hardware that could be told to recognize flows, and only put packets for a specific flow into that's flow's buffer pool. > If we want to dma data from nic into premapped userspace area, this will > strike with message sizes/misalignment/slow read and so on, so > preallocation has even more problems. I do not really think this is an issue, we put the full packet into user space and teach it where the offset is to the actual data. We'll do the same things we do today to try and get the data area aligned. User can do whatever is logical and relevant on his end to deal with strange cases. In fact we can specify that card has to take some care to get data area of packet aligned on say an 8 byte boundary or something like that. When we don't have hardware assist, we are going to be doing copies. > This change also requires significant changes in application, at least > until recv/send are changed, which is not the best thing to do. This is exactly the point, we can only do a good job and receive zero copy if we can change the interfaces, and that's exactly what we're doing here. > I do think that significant win in VJ's tests belongs not to remapping > and cache-oriented changes, but to move all protocol processing into > process' context. I partly disagree. The biggest win is eliminating all of the control overhead (all of "softint RX + protocol demux + IP route lookup + socket lookup" is turned into single flow demux), and the SMP safe data structure which makes it realistic enough to always move the bulk of the packet work to the socket's home cpu. I do not think userspace protocol implementation buys enough to justify it. We have to do the protection switch in and out of kernel space anyways, so why not still do the protected protocol processing work in the kernel? It is still being done on the user's behalf, contributes to his time slice, and avoids all of the terrible issues of userspace protocol implementations. So in my mind, the optimal situation from both a protection preservation and also a performance perspective is net channels to kernel socket protocol processing, buffers DMA'd directly into userspace if hardware assist is present. > I fully agree with Dave that it must be implemented step-by-step, and > the most significant, IMHO, is moving protocol processing into socket's > "place". This will force to netfilter changes, but I do think that for > the proof-of-concept code we can turn it off. And I also want to note that even if the whole idea explodes and cannot be made to work, there are good arguments for transitioning to SKB'less drivers for their own sake. So work will really not be lost. Let's have 100 different implementations of net channels! :-) - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: IP1000 gigabit nic driver
David G??mez <[EMAIL PROTECTED]> : [...] > Does anybody in this list know why the IP1000 driver is not > included in the kernel ? Afaik the driver has never been submitted for inclusion. At least not on netdev@vger.kernel.org (hint, hint). [...] > The card in question is: > > Sundance Technology Inc IC Plus IP1000 > > and the driver can be found in sundance web, sources URL please ? > included. I tried to contact the author but my email > bounced. > > There's no LICENSE in the source, just copyrigth > sentences in the .c files, so i'm not sure under > which license it's distributed :-?. /me goes to http://www.icplus.com.tw/driver-pp-IP1000A.html $ unzip -c IP1000A-Linux-driver-v2.09f.zip | grep MODULE_LICENSE MODULE_LICENSE("GPL"); It's a bit bloaty but it does not seem too bad (not mergeable "as is" though). Do you volunteer to test random cra^W^W carefully engineered code on your computer to help the rework/merging process ? -- Ueimor - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] selective ethtool diagnostic test method
Ethtool Maintainers, WRT my RFC (http://www.spinics.net/lists/netdev/msg02806.html) regarding enhancing ethtool posted on 04/11/06, would such a patch be accepted by the maintainers of ethtool? I don't want to spend time on these changes just to have them rejected. I've not received any objections for such changes thus far. It may be several months before we can get to implementing the changes. Please, can I get a thumbs up or down from the ethtool maintainers on netdev? Thanks, Tc - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: tune back idle cwnd closing?
David S. Miller wrote: From: John Heffner <[EMAIL PROTECTED]> Given that RFC2681 is Experimental (and I'm not aware of any current efforts in the IETF to push it to the standard track), IHMO it would not be inappropriate to make this behavior controlled via sysctl. I have to respectfully disagree. This is the price you pay when the network's congestion is being measured by probing, information becomes stale over time if you don't send any probes. And this change of congestion state is real and happens frequently for most end to end users. When you're bursty application is not sending, other flows can take up the pipe space you are not using, and you must reprobe to figure that out. A lot of the time doing 2861 is a good thing, since if you have a long pause, you've lost your ack clock, and you don't want to send a window-sized burst because you'll probably overflow a queue somewhere and step on your own feet. Since we don't have a pacing mechanism, a slow start is really the only way to do this. I don't entirely buy the "staleness" argument. I don't think that *not* doing 2861 will affect the stability of congestion control, since all of the response mechanisms are still in place. (Most OS's don't do 2861, and it is not a standard.) If you have a long RTT, short RTT flows can make a big difference in congestion in a period much smaller than your timeout. In fact, congestion information is *always* stale by the time you get it. :) Sometimes having cwnd validation turned on will make your applications perform better, sometimes worse. I don't think it would be incorrect to add a switch. One question is whether it's worth adding the switch (i.e., do enough people care?). Myself, I'd be interested to see some quantitative comparisons of performance with a "real" application affected by this. Thanks, -John - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: 2.6.16.11 BUG at tg3.c:2917
On Thu, 2006-04-27 at 12:52 -0400, Ed L. Cashin wrote: > -- [please bite here ] - > Kernel BUG at drivers/net/tg3.c:2917 > invalid opcode: [1] SMP > CPU 0 Most likely caused by IO re-ordering. Try the test patch in this discussion: http://marc.theaimsgroup.com/?l=linux-netdev&m=113890239404768&w=2 - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
2.6.16.11 BUG at tg3.c:2917
Hi. On 2.6.15.7 and 2.6.16.11, I have seen panics under heavy NFS write load on an x86_64 system with two onboard Broadcom gigabit NICs. It's a Supermicro P8SCi motherboard with an EMT64 Intel CPU. The aoe driver in use is the aoe6-26 driver from the Coraid website. I haven't yet trimmed down the test case or tried using the aoe driver that comes with 2.6.16.11. Right now there's kernel NFS exporting an XFS filesystem on a logical volume backed by 3 AoE devices. I'm including two panics here. There's a relevant-looking discussion of the same bug from May 2005 at the URL below. http://oss.sgi.com/projects/netdev/archive/2004-05/msg00378.html --- [cut here ] - [please bite here ] - Kernel BUG at drivers/net/tg3.c:2917 invalid opcode: [1] SMP CPU 0 Modules linked in: nfsd lockd nfs_acl sunrpc xfs exportfs dm_mod aoe ipv6 rtc piix i2c_i801 psmouse evdev i2c_core unix Pid: 3053, comm: nfsd Not tainted 2.6.16.11-c1 #1 RIP: 0010:[] {tg3_poll+179} RSP: :8039cc38 EFLAGS: 00010246 RAX: 01fb RBX: RCX: 0003 RDX: 0038 RSI: 81003f03f180 RDI: 810001fbb980 RBP: 81003d82df88 R08: 0400 R09: 81003e5fae18 R10: 81003ee86a80 R11: 00c4 R12: 81003f0d0500 R13: 01fb R14: 0016 R15: 810023088c30 FS: 2b4cde2ee6d0() GS:803e6000() knlGS: CS: 0010 DS: ES: CR0: 8005003b CR2: 00438010 CR3: 25729000 CR4: 06e0 Process nfsd (pid: 3053, threadinfo 81003d6fc000, task 81003f304140) Stack: 0046 802427b4 8039ccd4 81003f0d 81003dfec000 0014002c 00ca 00ca81ca 81003dfdd920 81003f0d059c Call Trace: {task_in_intr+240} {net_rx_action+165} {__do_softirq+86} {call_softirq+30} {do_softirq+44} {local_bh_enable+105} {dev_queue_xmit+551} {:aoe:aoenet_xmit+26} {:aoe:aoeblk_make_request+413} {generic_make_request+335} {:dm_mod:__map_bio+66} {:dm_mod:__split_bio+365} {:xfs:linvfs_get_block+0} {:dm_mod:dm_request+262} {generic_make_request+335} {submit_bio+184} {:xfs:xfs_buf_iorequest+828} {default_wake_function+0} {:xfs:xfs_buf_associate_memory+117} {:xfs:xlog_bdstrat_cb+22} {:xfs:xlog_state_release_iclog+695} {:xfs:xlog_write+1509} {:xfs:xfs_log_write+42} {:xfs:_xfs_trans_commit+1294} {:xfs:kmem_zone_alloc+73} {:xfs:kmem_zone_zalloc+28} {:xfs:xfs_itruncate_finish+530} {:xfs:xfs_inactive_free_eofblocks+384} {:xfs:linvfs_release+0} {:xfs:xfs_release+152} {:xfs:linvfs_release+23} {__fput+155} {:nfsd:nfsd_write+196} {:nfsd:nfsd3_proc_write+231} {:nfsd:nfsd_dispatch+221} {:sunrpc:svc_process+975} {__down_read+18} {:nfsd:nfsd+451} {child_rip+8} {:nfsd:nfsd+0} {child_rip+0} Code: 0f 0b 68 83 5f 2f 80 c2 65 0b 49 8b 44 24 40 8b 93 88 00 00 RIP {tg3_poll+179} RSP <0>Kernel panic - not syncing: Aiee, killing interrupt handler! --- [cut here ] - [please bite here ] - Kernel BUG at drivers/net/tg3.c:2914 invalid operand: [1] SMP CPU 0 Modules linked in: nfsd lockd nfs_acl sunrpc dm_mod aoe xfs exportfs ipv6 i2c_i801 i2c_core piix md_mod rtc psmouse unix Pid: 88, comm: kswapd0 Not tainted 2.6.15.7-c1 #1 RIP: 0010:[] {tg3_poll+179} RSP: :80395e08 EFLAGS: 00010246 RAX: 0066 RBX: RCX: 0002 RDX: 0028 RSI: 81003e999d80 RDI: 810001fbba40 RBP: 81003dd63990 R08: 80395ea8 R09: 81003dc2ce18 R10: 003a R11: 80395ea8 R12: 81003f1a3500 R13: 0066 R14: 00a9 R15: 80395f08 FS: () GS:803e1800() knlGS: CS: 0010 DS: 0018 ES: 0018 CR0: 8005003b CR2: 004a12a7 CR3: 077ab000 CR4: 06e0 Process kswapd0 (pid: 88, threadinfo 81003f5d8000, task 81003f594790) Stack: 803c8980 1d4c 80395ea4 81003f1a3000 81003db45000 0040 0049 0049003b 81003e52c740 81003f1a359c Call Trace: {net_rx_action+165} {__do_softirq+86} {call_softirq+31} {do_softirq+44} {do_IRQ+52} {ret_from_intr+0} {cache_flusharray+30} {:xfs:linvfs_release_page+0} {_write_unlock_irqrestore+9} {test_clear_page_dirty+152} {try_to_free_buffers+116} {:xfs:linvfs_release_page+0} {:xfs:linvfs_release_page+133} {shrink_zone+2695} {activate_task+140} {try_to_wake_up+1110} {balance_pgdat+535} {kswapd+256} {autoremove_wake_function+0} {child_rip+8} {kswapd+0} {child_rip+0} Code: 0f 0b 68 ba 2d 2f 80 c2 62 0b 49 8b 44 24 40 8b 93 80 00 00 RIP {tg3_poll+179} RSP <0>Kernel panic - not syncing: A
[RFC PATCH] [IPV6]: Fix race in route selection.
Hello. We eliminated rt6_dflt_lock (to protect default router pointer) at 2.6.17-rc1, and introduced rt6_select() for general router selection. The function is called in the context of rt6_lock read-lock held, but this means, we have some race conditions when we do round-robin. Am I correct? If so, we should put some spin_lock for serialization. Comments? Signed-off-by; YOSHIFUJI Hideaki <[EMAIL PROTECTED]> Or, should we run whole part of rt6_select() under some lock? diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 7907874..0190e39 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -317,7 +317,7 @@ static struct rt6_info *rt6_select(struc __FUNCTION__, head, head ? *head : NULL, oif); for (rt = rt0, metric = rt0->rt6i_metric; -rt && rt->rt6i_metric == metric; +rt && rt->rt6i_metric == metric && (!last || rt != rt0); rt = rt->u.next) { int m; @@ -343,9 +343,12 @@ static struct rt6_info *rt6_select(struc (strict & RT6_SELECT_F_REACHABLE) && last && last != rt0) { /* no entries matched; do round-robin */ + static spinlock_t lock = SPIN_LOCK_UNLOCKED; + spin_lock(&lock); *head = rt0->u.next; rt0->u.next = last->u.next; last->u.next = rt0; + spin_unlock(&lock); } RT6_TRACE("%s() => %p, score=%d\n", -- YOSHIFUJI Hideaki @ USAGI Project <[EMAIL PROTECTED]> GPG-FP : 9022 65EB 1ECF 3AD1 0BDF 80D8 4807 F894 E062 0EEA - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] e1000 performance patch
but clearly I should be using netperf to get more accurate cpu numbers and a more convincing aggregate table :-) Well, I'll not stop you :) It is a bit rough/messy as a writeup, but here is what I've seen wrt the latency vs throughput tradeoffs: ftp://ftp.cup.hp.com/dist/networking/briefs/nic_latency_vs_tput.txt from a quick read it looks like just the case with 32kB messages, multiple simultaneous clients, and driver set to unlimited ITR sees reduced throughput. is that right? if so, then I'm not surprised. There should be three basic measures there - one is the single-instance request-response test. The idea is to see minimum latency. That test likes to see the interrupt throttle rate made very high, or disabled completely. The aggregate TCP_RR's and the TCP_STREAM tests are there to show what effect that has on the ability to do aggregate request/response and a bulk transfer. but overall I'm actually more worried about a mix of small and large messages than multiple clients. a large/small mix might well occur in 'the real world' and it'll be 2s until the watchdog routine can adapt the ITR. potentially that 2s will be at 200k ITR which is too high for large messages, and up to 2s of cpu will be burnt needlessly. can netperf (or some other tool) mix up big and small message sizes like 'the real world' perhaps does? that might help me find a good frequency at which to try to adapt the ITR... (eg. 1, 10, 100 or 1000 times a second) There is the "vst" (variable size test IIRC) in netperf4: http://www.netperf.org/svn/netperf4/branches/glib_migration The docs for netperf4 are presently pathetic. Feel free to email me for bootstrapping information. Basically, you'll need pkg-config, libxml2 and glib-2.0 on the system. cheers, robin - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 7/9] e100: disable interrupts at boot
On Thursday 27 April 2006 04:00, Jeff Garzik wrote: > [EMAIL PROTECTED] wrote: > > From: Bjorn Helgaas <[EMAIL PROTECTED]> > > > > Apparently the Intel PRO/100 device enables interrupts on reset. Unless > > firmware explicitly disables PRO/100 interrupts, we can get a flood of > > interrupts when a driver attaches to an unrelated device that happens to > > share the PRO/100 IRQ. > > > > This should resolve this "irq 11: nobody cared" bug report: > > http://bugzilla.kernel.org/show_bug.cgi?id=5918 > > > > Signed-off-by: Bjorn Helgaas <[EMAIL PROTECTED]> > > Cc: Jesse Brandeburg <[EMAIL PROTECTED]> > > Cc: Jeff Kirsher <[EMAIL PROTECTED]> > > Cc: John Ronciak <[EMAIL PROTECTED]> > > Cc: <[EMAIL PROTECTED]> > > Cc: <[EMAIL PROTECTED]> > > Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> > > I'm really worried that we are burdening the kernel for a very very rare > condition. Do we want to apply this for one stupid firmware? > > Can't early userspace just run setpci to fix this one? I don't think so, because the problem occurs as soon as any driver enables IRQ 11. I agree that it's rare, but it's a real pain to debug it and identify it when it occurs. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Netpoll checksum issue
Hi Herbert, Is there any update of this issue? Regards, - Aubrey On 4/24/06, Aubrey <[EMAIL PROTECTED]> wrote: > On 4/24/06, Herbert Xu <[EMAIL PROTECTED]> wrote: > > On Mon, Apr 24, 2006 at 01:42:12PM +0800, Aubrey wrote: > > > > > > dev->last_rx = jiffies; > > > skb->dev = dev; > > > skb->protocol = eth_type_trans(skb, dev); > > > skb->ip_summed = CHECKSUM_UNNECESSARY; > > > netif_rx(skb); > > > > This doesn't make sense. First of all you're setting ip_summed to > > CHECK_UNNECESSARY unconditionally which is most likely wrong. > > > > What's more, if this was the driver that you were using, then > > checksum_udp couldn't possibly fail since the first thing it does > > is check ip_summed. > > Hmm, when I change the code in __netpoll_rx, there is no the following > one line in the driver: > == > skb->ip_summed = CHECKSUM_UNNECESSARY; > == > > The above one line code in the driver is just a workaround. > > Regards, > -Aubrey > - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/17] d80211 patches
On Wednesday 26 April 2006 21:39, John W. Linville wrote: > On Fri, Apr 21, 2006 at 10:52:10PM +0200, Jiri Benc wrote: > > On Fri, 21 Apr 2006 22:52:08 +0200, Michael Buesch wrote: > > > Can you please send your hacky patch for the bcm43xx > > > to me, so I can come up with a clean one? > > > > Sure, actually I planned to do it in a few minutes :-) > > Hacky or not, I'm applying this patch to keep the bcm43xx driver > from breaking. That's perfectly fine. The correct patch needs a little bit of rewriting in the "mode" code. I will do that after I finished the 4318 fixes (should take quite some time). -- Greetings Michael. pgp30SC3FNYzE.pgp Description: PGP signature
[PATCH] DECnet: Fix level1 router hello
This patch fixes hello messages sent when a node is a level 1 router. Slightly contrary to the spec (maybe) VMS ignores hello messages that do not name level2 routers that it also knows about. So, here we simply name all the routers that the node knows about rather just other level1 routers. (I hope the patch is clearer than the description. sorry). Patrick Signed-off-by: Patrick Caulfield <[EMAIL PROTECTED]> diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c index 7c8692c..66e230c 100644 --- a/net/decnet/dn_neigh.c +++ b/net/decnet/dn_neigh.c @@ -493,7 +493,6 @@ struct elist_cb_state { static void neigh_elist_cb(struct neighbour *neigh, void *_info) { struct elist_cb_state *s = _info; - struct dn_dev *dn_db; struct dn_neigh *dn; if (neigh->dev != s->dev) @@ -503,10 +502,6 @@ static void neigh_elist_cb(struct neighb if (!(dn->flags & (DN_NDFLAG_R1|DN_NDFLAG_R2))) return; - dn_db = (struct dn_dev *) s->dev->dn_ptr; - if (dn_db->parms.forwarding == 1 && (dn->flags & DN_NDFLAG_R2)) - return; - if (s->t == s->n) s->rs = dn_find_slot(s->ptr, s->n, dn->priority); else - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[IPSEC]: Fix IP ID selection
Hi Dave: I was looking through the xfrm input/output code in order to abstract out the address family specific encapsulation/decapsulation code. During that process I found this bug in the IP ID selection code in xfrm4_output.c. At that point dst is still the xfrm_dst for the current SA which represents an internal flow as far as the IPsec tunnel is concerned. Since the IP ID is going to sit on the outside of the encapsulated packet, we obviously want the external flow which is just dst->child. The fix is trivial. Signed-off-by: Herbert Xu <[EMAIL PROTECTED]> Cheers, -- Visit Openswan at http://www.openswan.org/ Email: Herbert Xu ~{PmV>HI~} <[EMAIL PROTECTED]> Home Page: http://gondor.apana.org.au/~herbert/ PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c index 32ad229..4ef8efa 100644 --- a/net/ipv4/xfrm4_output.c +++ b/net/ipv4/xfrm4_output.c @@ -62,7 +62,7 @@ top_iph->frag_off = (flags & XFRM_STATE_NOPMTUDISC) ? 0 : (iph->frag_off & htons(IP_DF)); if (!top_iph->frag_off) - __ip_select_ident(top_iph, dst, 0); + __ip_select_ident(top_iph, dst->child, 0); top_iph->ttl = dst_metric(dst->child, RTAX_HOPLIMIT);
Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
On Wed, Apr 26, 2006 at 11:25:01PM -0700, David S. Miller ([EMAIL PROTECTED]) wrote: > > We approached this from the understanding that an intelligent NIC > > will be able to transition directly to userspace, which is a major > > win. 0 copies to userspace would be sweet. I think we can still > > achieve this using your scheme without *too* much pain. > > Understood. What's your basic idea? Just make the buffers in the > pool large enough to fit the SKB encapsulation at the end? There are some caveats here found while developing zero-copy sniffer [1]. Project's goal was to remap skbs into userspace in real-time. While absolute numbers (posted to netdev@) were really high, it is only applicable to read-only application. As was shown in IOAT thread, data must be warmed in caches, so reading from mapped area will be as fast as memcpy() (read+write), and copy_to_user() actually almost equal to memcpy() (benchmarks were posted to netdev@). And we must add remapping overhead. If we want to dma data from nic into premapped userspace area, this will strike with message sizes/misalignment/slow read and so on, so preallocation has even more problems. This change also requires significant changes in application, at least until recv/send are changed, which is not the best thing to do. So I think that mapping itself can be done as some additional socket option or something not turnedon by default. I do think that significant win in VJ's tests belongs not to remapping and cache-oriented changes, but to move all protocol processing into process' context. I fully agree with Dave that it must be implemented step-by-step, and the most significant, IMHO, is moving protocol processing into socket's "place". This will force to netfilter changes, but I do think that for the proof-of-concept code we can turn it off. I will start to work in this direction next week after aio_sendfile() is completed. So, we will have three attempts to write incompatible stacks - and that is good :) No one need an excuse to rewrite something, as I read in Rusty's blog... Thanks. [1]. http://tservice.net.ru/~s0mbre/old/?section=projects&item=af_tlb -- Evgeniy Polyakov - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 2/9] tulip: NatSemi DP83840A PHY fix
On 4/27/06, Jeff Garzik <[EMAIL PROTECTED]> wrote: > [EMAIL PROTECTED] wrote: > > + if (startup) { > > + int timeout = 10; /* max 1 ms */ > > for (i = 0; i < reset_length; i++) > > > > iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); > > + > > + /* flush posted writes */ > > + ioread32(ioaddr + CSR15); > > + > > + /* Sect 3.10.3 in DP83840A.pdf (p39) > > */ > > + udelay(500); > > + > > + /* Section 4.2 in DP83840A.pdf (p43) > > */ > > + /* and IEEE 802.3 "22.2.4.1.1 Reset" > > */ > > + while (timeout-- && > > + (tulip_mdio_read (dev, > > phy_num, MII_BMCR) & BMCR_RESET)) > > + udelay(100); > > > What can we do about this? > > Its a huge delay to be taken inside a spinlock. This is device setup code. ISTR Grant showing other similar examples of delays in such code in the kernel. Unless you keep configuring/deconfiguring the device, and assuming you hit worst case scenario everytime, it won't be a problem. But if you're doing that, you already have a problem elsewhere. Or am I missing something? > Anybody interested to converting the driver to use schedule_work() or > similar? That question has been raised months ago without any significant outcome. Maybe it's time to move on? This code does respect hardware specs, at least, which isn't the case of existing code, and fixes a bug... HTH T-Bone -- Thibaut VARENE http://www.parisc-linux.org/~varenet/ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 7/9] e100: disable interrupts at boot
[EMAIL PROTECTED] wrote: From: Bjorn Helgaas <[EMAIL PROTECTED]> Apparently the Intel PRO/100 device enables interrupts on reset. Unless firmware explicitly disables PRO/100 interrupts, we can get a flood of interrupts when a driver attaches to an unrelated device that happens to share the PRO/100 IRQ. This should resolve this "irq 11: nobody cared" bug report: http://bugzilla.kernel.org/show_bug.cgi?id=5918 Signed-off-by: Bjorn Helgaas <[EMAIL PROTECTED]> Cc: Jesse Brandeburg <[EMAIL PROTECTED]> Cc: Jeff Kirsher <[EMAIL PROTECTED]> Cc: John Ronciak <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> I'm really worried that we are burdening the kernel for a very very rare condition. Do we want to apply this for one stupid firmware? Can't early userspace just run setpci to fix this one? Jeff - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 8/9] forcedeth: suggested cleanups
[EMAIL PROTECTED] wrote: From: Ingo Oeser <[EMAIL PROTECTED]> general: - endian annotation of the ring descriptors nv_getlen(): - use htons() instead of __constant_htons() to improvde readability and let the compiler constant fold it. nv_rx_process(): - use a real for() loop in processing instead of goto and break - consolidate rx_errors increment - count detected rx_length_errors Signed-off-by: Ingo Oeser <[EMAIL PROTECTED]> Cc: Manfred Spraul <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> ACK, but I'm holding off applying this while trying to get 4 apply-able patches out of NVIDIA and Manfred :) Jeff - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 3/9] natsemi: Add support for using MII port with no PHY
[EMAIL PROTECTED] wrote: From: Mark Brown <[EMAIL PROTECTED]> Provide a module option which configures the natsemi driver to use the external MII port on the chip but ignore any PHYs that may be attached to it. The link state will be left as it was when the driver started and can be configured via ethtool. Any PHYs that are present can be accessed via the MII ioctl()s. This is useful for systems where the device is connected without a PHY or where either information or actions outside the scope of the driver are required in order to use the PHYs. Signed-off-by: Mark Brown <[EMAIL PROTECTED]> Cc: Tim Hockin <[EMAIL PROTECTED]> Cc: Jeff Garzik <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> NAK. The proper way to do this is via the force_media boolean flag found in several net drivers. In general I agree with the motivation to do something like this... Jeff - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [patch 2/9] tulip: NatSemi DP83840A PHY fix
[EMAIL PROTECTED] wrote: + if (startup) { + int timeout = 10; /* max 1 ms */ for (i = 0; i < reset_length; i++) iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); + + /* flush posted writes */ + ioread32(ioaddr + CSR15); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); What can we do about this? Its a huge delay to be taken inside a spinlock. Anybody interested to converting the driver to use schedule_work() or similar? Jeff - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 3/9] natsemi: Add support for using MII port with no PHY
From: Mark Brown <[EMAIL PROTECTED]> Provide a module option which configures the natsemi driver to use the external MII port on the chip but ignore any PHYs that may be attached to it. The link state will be left as it was when the driver started and can be configured via ethtool. Any PHYs that are present can be accessed via the MII ioctl()s. This is useful for systems where the device is connected without a PHY or where either information or actions outside the scope of the driver are required in order to use the PHYs. Signed-off-by: Mark Brown <[EMAIL PROTECTED]> Cc: Tim Hockin <[EMAIL PROTECTED]> Cc: Jeff Garzik <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/natsemi.c | 105 +--- 1 files changed, 67 insertions(+), 38 deletions(-) diff -puN drivers/net/natsemi.c~natsemi-add-support-for-using-mii-port-with-no-phy drivers/net/natsemi.c --- devel/drivers/net/natsemi.c~natsemi-add-support-for-using-mii-port-with-no-phy 2006-04-10 23:21:19.0 -0700 +++ devel-akpm/drivers/net/natsemi.c2006-04-10 23:21:19.0 -0700 @@ -259,7 +259,7 @@ MODULE_PARM_DESC(debug, "DP8381x default MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames"); MODULE_PARM_DESC(options, - "DP8381x: Bits 0-3: media type, bit 17: full duplex"); + "DP8381x: Bits 0-3: media type, bit 17: full duplex, bit 18: ignore PHY"); MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)"); /* @@ -690,6 +690,8 @@ struct netdev_private { u32 intr_status; /* Do not touch the nic registers */ int hands_off; + /* Don't pay attention to the reported link state. */ + int ignore_phy; /* external phy that is used: only valid if dev->if_port != PORT_TP */ int mii; int phy_addr_external; @@ -894,7 +896,19 @@ static int __devinit natsemi_probe1 (str np->intr_status = 0; np->eeprom_size = NATSEMI_DEF_EEPROM_SIZE; + option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; + if (dev->mem_start) + option = dev->mem_start; + + /* Ignore the PHY status? */ + if (option & 0x400) { + np->ignore_phy = 1; + } else { + np->ignore_phy = 0; + } + /* Initial port: +* - If configured to ignore the PHY set up for external. * - If the nic was configured to use an external phy and if find_mii * finds a phy: use external port, first phy that replies. * - Otherwise: internal port. @@ -902,7 +916,7 @@ static int __devinit natsemi_probe1 (str * The address would be used to access a phy over the mii bus, but * the internal phy is accessed through mapped registers. */ - if (readl(ioaddr + ChipConfig) & CfgExtPhy) + if (np->ignore_phy || readl(ioaddr + ChipConfig) & CfgExtPhy) dev->if_port = PORT_MII; else dev->if_port = PORT_TP; @@ -912,7 +926,9 @@ static int __devinit natsemi_probe1 (str if (dev->if_port != PORT_TP) { np->phy_addr_external = find_mii(dev); - if (np->phy_addr_external == PHY_ADDR_NONE) { + /* If we're ignoring the PHY it doesn't matter if we can't +* find one. */ + if (!np->ignore_phy && np->phy_addr_external == PHY_ADDR_NONE) { dev->if_port = PORT_TP; np->phy_addr_external = PHY_ADDR_INTERNAL; } @@ -920,10 +936,6 @@ static int __devinit natsemi_probe1 (str np->phy_addr_external = PHY_ADDR_INTERNAL; } - option = find_cnt < MAX_UNITS ? options[find_cnt] : 0; - if (dev->mem_start) - option = dev->mem_start; - /* The lower four bits are the media type. */ if (option) { if (option & 0x200) @@ -957,7 +969,10 @@ static int __devinit natsemi_probe1 (str if (mtu) dev->mtu = mtu; - netif_carrier_off(dev); + if (np->ignore_phy) + netif_carrier_on(dev); + else + netif_carrier_off(dev); /* get the initial settings from hardware */ tmp= mdio_read(dev, MII_BMCR); @@ -1005,6 +1020,8 @@ static int __devinit natsemi_probe1 (str printk("%02x, IRQ %d", dev->dev_addr[i], irq); if (dev->if_port == PORT_TP) printk(", port TP.\n"); + else if (np->ignore_phy) + printk(", port MII, ignoring PHY\n"); else printk(", port MII, phy ad %d.\n", np->phy_addr_external); } @@ -1685,42 +1702,44 @@ static void check_link(struct net_device { struct netdev_private *np = netdev_priv(dev); void __iomem * ioaddr = ns_ioaddr(dev); - int duplex; + int duplex = np->full_dupl
[patch 8/9] forcedeth: suggested cleanups
From: Ingo Oeser <[EMAIL PROTECTED]> general: - endian annotation of the ring descriptors nv_getlen(): - use htons() instead of __constant_htons() to improvde readability and let the compiler constant fold it. nv_rx_process(): - use a real for() loop in processing instead of goto and break - consolidate rx_errors increment - count detected rx_length_errors Signed-off-by: Ingo Oeser <[EMAIL PROTECTED]> Cc: Manfred Spraul <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/forcedeth.c | 59 -- 1 files changed, 26 insertions(+), 33 deletions(-) diff -puN drivers/net/forcedeth.c~forcedeth-suggested-cleanups drivers/net/forcedeth.c --- devel/drivers/net/forcedeth.c~forcedeth-suggested-cleanups 2006-04-10 23:21:26.0 -0700 +++ devel-akpm/drivers/net/forcedeth.c 2006-04-10 23:21:26.0 -0700 @@ -328,17 +328,18 @@ enum { NvRegMSIXIrqStatus = 0x3f0, }; -/* Big endian: should work, but is untested */ +/* Big endian: should work, but is untested. + * So give arch maintainers a hint here. -ioe */ struct ring_desc { - u32 PacketBuffer; - u32 FlagLen; + __le32 PacketBuffer; + __le32 FlagLen; }; struct ring_desc_ex { - u32 PacketBufferHigh; - u32 PacketBufferLow; - u32 TxVlan; - u32 FlagLen; + __le32 PacketBufferHigh; + __le32 PacketBufferLow; + __le32 TxVlan; + __le32 FlagLen; }; typedef union _ring_type { @@ -1403,7 +1404,7 @@ static int nv_getlen(struct net_device * int protolen; /* length as stored in the proto field */ /* 1) calculate len according to header */ - if ( ((struct vlan_ethhdr *)packet)->h_vlan_proto == __constant_htons(ETH_P_8021Q)) { + if (((struct vlan_ethhdr *)packet)->h_vlan_proto == htons(ETH_P_8021Q)) { protolen = ntohs( ((struct vlan_ethhdr *)packet)->h_vlan_encapsulated_proto ); hdrlen = VLAN_HLEN; } else { @@ -1453,12 +1454,10 @@ static void nv_rx_process(struct net_dev u32 vlanflags = 0; - for (;;) { + for (; np->cur_rx - np->refill_rx < RX_RING; np->cur_rx++) { struct sk_buff *skb; int len; int i; - if (np->cur_rx - np->refill_rx >= RX_RING) - break; /* we scanned the whole ring - do not continue */ i = np->cur_rx % RX_RING; if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) { @@ -1498,33 +1497,29 @@ static void nv_rx_process(struct net_dev /* look at what we actually got: */ if (np->desc_ver == DESC_VER_1) { if (!(Flags & NV_RX_DESCRIPTORVALID)) - goto next_pkt; + continue; if (Flags & NV_RX_ERROR) { if (Flags & NV_RX_MISSEDFRAME) { np->stats.rx_missed_errors++; - np->stats.rx_errors++; - goto next_pkt; + goto error_pkt; } if (Flags & (NV_RX_ERROR1|NV_RX_ERROR2|NV_RX_ERROR3)) { - np->stats.rx_errors++; - goto next_pkt; + goto error_pkt; } if (Flags & NV_RX_CRCERR) { np->stats.rx_crc_errors++; - np->stats.rx_errors++; - goto next_pkt; + goto error_pkt; } if (Flags & NV_RX_OVERFLOW) { np->stats.rx_over_errors++; - np->stats.rx_errors++; - goto next_pkt; + goto error_pkt; } if (Flags & NV_RX_ERROR4) { len = nv_getlen(dev, np->rx_skbuff[i]->data, len); if (len < 0) { - np->stats.rx_errors++; - goto next_pkt; + np->stats.rx_length_errors++; + goto error_pkt; } } /* framing errors are soft errors. */ @@ -1536,28 +1531,25 @@ static void nv_rx_process(struct net_dev }
[patch 4/9] PCI Error Recovery: e1000 network device driver
From: Linas Vepstas <[EMAIL PROTECTED]> Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel gigabit ethernet e1000 device driver. The patch has been tested, and appears to work well. [EMAIL PROTECTED]: minor cleanups] Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]> Acked-by: Jesse Brandeburg <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/e1000/e1000_main.c | 116 ++- 1 files changed, 115 insertions(+), 1 deletion(-) diff -puN drivers/net/e1000/e1000_main.c~pci-error-recovery-e1000-network-device-driver drivers/net/e1000/e1000_main.c --- devel/drivers/net/e1000/e1000_main.c~pci-error-recovery-e1000-network-device-driver 2006-04-22 01:39:15.0 -0700 +++ devel-akpm/drivers/net/e1000/e1000_main.c 2006-04-22 01:39:15.0 -0700 @@ -227,6 +227,16 @@ static int e1000_resume(struct pci_dev * static void e1000_netpoll (struct net_device *netdev); #endif +static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state); +static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev); +static void e1000_io_resume(struct pci_dev *pdev); + +static struct pci_error_handlers e1000_err_handler = { + .error_detected = e1000_io_error_detected, + .slot_reset = e1000_io_slot_reset, + .resume = e1000_io_resume, +}; static struct pci_driver e1000_driver = { .name = e1000_driver_name, @@ -236,8 +246,9 @@ static struct pci_driver e1000_driver = /* Power Managment Hooks */ #ifdef CONFIG_PM .suspend = e1000_suspend, - .resume = e1000_resume + .resume = e1000_resume, #endif + .err_handler = &e1000_err_handler, }; MODULE_AUTHOR("Intel Corporation, <[EMAIL PROTECTED]>"); @@ -3076,6 +3087,10 @@ e1000_update_stats(struct e1000_adapter #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF + /* Prevent stats update while adapter is being reset */ + if (adapter->link_speed == 0) + return; + spin_lock_irqsave(&adapter->stats_lock, flags); /* these counters are modified from e1000_adjust_tbi_stats, @@ -4625,4 +4640,103 @@ e1000_netpoll(struct net_device *netdev) } #endif +/** + * e1000_io_error_detected - called when PCI error is detected + * @pdev: Pointer to PCI device + * @state: The current pci conneection state + * + * This function is called after a PCI bus error affecting + * this device has been detected. + */ +static pci_ers_result_t e1000_io_error_detected(struct pci_dev *pdev, + pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + + netif_device_detach(netdev); + + if (netif_running(netdev)) + e1000_down(adapter); + + /* Request a slot slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * e1000_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch, as if from a cold-boot. Implementation + * resembles the first-half of the e1000_resume routine. + */ +static pci_ers_result_t e1000_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + + if (pci_enable_device(pdev)) { + printk(KERN_ERR "e1000: Cannot re-enable PCI device after " + "reset.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + pci_enable_wake(pdev, 3, 0); + pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ + + /* Perform card reset only on one instance of the card */ + if (PCI_FUNC (pdev->devfn) != 0) + return PCI_ERS_RESULT_RECOVERED; + + e1000_reset(adapter); + E1000_WRITE_REG(&adapter->hw, WUS, ~0); + + return PCI_ERS_RESULT_RECOVERED; +} + +/** + * e1000_io_resume - called when traffic can start flowing again. + * @pdev: Pointer to PCI device + * + * This callback is called when the error recovery driver tells us that + * its OK to resume normal operation. Implementation resembles the + * second-half of the e1000_resume routine. + */ +static void e1000_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct e1000_adapter *adapter = netdev->priv; + uint32_t manc, swsm; + + if (netif_running(netdev)) { + if (e1000_up(adapter)) { + printk(KERN_ERR "e1000: can't bring device back up " + "after reset\n"); + return; + } + } + + netif_device_attach(netdev); + + if (adapter->hw.mac_type >= e1000_82540 && + adapter->hw.media_type =
[patch 2/9] tulip: NatSemi DP83840A PHY fix
From: Thibaut VARENE <[EMAIL PROTECTED]> Fix a problem with Tulip 21142 HP branded PCI cards (PN#: B5509-66001), which feature a NatSemi DP83840A PHY. Without that patch, it is impossible to properly initialize the card's PHY, and it's thus impossible to monitor/configure it. It's a timing/posting problem, and it is solved exactly the same way Grant fixed it elsewhere already. Signed-off-by: Thibaut VARENE <[EMAIL PROTECTED]> Cc: Jeff Garzik <[EMAIL PROTECTED]> Acked-by: Grant Grundler <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/tulip/media.c | 18 +- 1 files changed, 17 insertions(+), 1 deletion(-) diff -puN drivers/net/tulip/media.c~tulip-natsemi-dp83840a-phy-fix drivers/net/tulip/media.c --- devel/drivers/net/tulip/media.c~tulip-natsemi-dp83840a-phy-fix 2006-04-10 23:21:18.0 -0700 +++ devel-akpm/drivers/net/tulip/media.c2006-04-10 23:21:18.0 -0700 @@ -261,11 +261,27 @@ void tulip_select_media(struct net_devic u16 *reset_sequence = &((u16*)(p+3))[init_length]; int reset_length = p[2 + init_length*2]; misc_info = reset_sequence + reset_length; - if (startup) + if (startup) { + int timeout = 10; /* max 1 ms */ for (i = 0; i < reset_length; i++) iowrite32(get_u16(&reset_sequence[i]) << 16, ioaddr + CSR15); + + /* flush posted writes */ + ioread32(ioaddr + CSR15); + + /* Sect 3.10.3 in DP83840A.pdf (p39) */ + udelay(500); + + /* Section 4.2 in DP83840A.pdf (p43) */ + /* and IEEE 802.3 "22.2.4.1.1 Reset" */ + while (timeout-- && + (tulip_mdio_read (dev, phy_num, MII_BMCR) & BMCR_RESET)) + udelay(100); + } for (i = 0; i < init_length; i++) iowrite32(get_u16(&init_sequence[i]) << 16, ioaddr + CSR15); + + ioread32(ioaddr + CSR15); /* flush posted writes */ } else { u8 *init_sequence = p + 2; u8 *reset_sequence = p + 3 + init_length; _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 7/9] e100: disable interrupts at boot
From: Bjorn Helgaas <[EMAIL PROTECTED]> Apparently the Intel PRO/100 device enables interrupts on reset. Unless firmware explicitly disables PRO/100 interrupts, we can get a flood of interrupts when a driver attaches to an unrelated device that happens to share the PRO/100 IRQ. This should resolve this "irq 11: nobody cared" bug report: http://bugzilla.kernel.org/show_bug.cgi?id=5918 Signed-off-by: Bjorn Helgaas <[EMAIL PROTECTED]> Cc: Jesse Brandeburg <[EMAIL PROTECTED]> Cc: Jeff Kirsher <[EMAIL PROTECTED]> Cc: John Ronciak <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Cc: <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/pci/quirks.c | 57 + 1 files changed, 57 insertions(+) diff -puN drivers/pci/quirks.c~e100-disable-interrupts-at-boot drivers/pci/quirks.c --- devel/drivers/pci/quirks.c~e100-disable-interrupts-at-boot 2006-04-14 23:41:34.0 -0700 +++ devel-akpm/drivers/pci/quirks.c 2006-04-14 23:41:34.0 -0700 @@ -1374,6 +1374,63 @@ static void __devinit quirk_netmos(struc } DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NETMOS, PCI_ANY_ID, quirk_netmos); +static void __devinit quirk_e100_interrupt(struct pci_dev *dev) +{ + u16 command; + u32 bar; + u8 __iomem *csr; + u8 cmd_hi; + + switch (dev->device) { + /* PCI IDs taken from drivers/net/e100.c */ + case 0x1029: + case 0x1030 ... 0x1034: + case 0x1038 ... 0x103E: + case 0x1050 ... 0x1057: + case 0x1059: + case 0x1064 ... 0x106B: + case 0x1091 ... 0x1095: + case 0x1209: + case 0x1229: + case 0x2449: + case 0x2459: + case 0x245D: + case 0x27DC: + break; + default: + return; + } + + /* +* Some firmware hands off the e100 with interrupts enabled, +* which can cause a flood of interrupts if packets are +* received before the driver attaches to the device. So +* disable all e100 interrupts here. The driver will +* re-enable them when it's ready. +*/ + pci_read_config_word(dev, PCI_COMMAND, &command); + pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &bar); + + if (!(command & PCI_COMMAND_MEMORY) || !bar) + return; + + csr = ioremap(bar, 8); + if (!csr) { + printk(KERN_WARNING "PCI: Can't map %s e100 registers\n", + pci_name(dev)); + return; + } + + cmd_hi = readb(csr + 3); + if (cmd_hi == 0) { + printk(KERN_WARNING "PCI: Firmware left %s e100 interrupts " + "enabled, disabling\n", pci_name(dev)); + writeb(1, csr + 3); + } + + iounmap(csr); +} +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_e100_interrupt); static void __devinit fixup_rev1_53c810(struct pci_dev* dev) { _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 1/9] smc911x Kconfig fix
From: Andrew Morton <[EMAIL PROTECTED]> In file included from drivers/net/smc911x.c:84: drivers/net/smc911x.h:46:9: warning: "SMC_USE_16BIT" is not defined drivers/net/smc911x.h:60:9: warning: "SMC_USE_32BIT" is not defined drivers/net/smc911x.h:73:10: warning: "SMC_USE_PXA_DMA" is not defined drivers/net/smc911x.c: In function `smc911x_reset': drivers/net/smc911x.c:247: warning: implicit declaration of function `SMC_inl' drivers/net/smc911x.c:249: warning: implicit declaration of function `SMC_outl' Cc: Dustin McIntire <[EMAIL PROTECTED]> Cc: Jeff Garzik <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/Kconfig |2 +- 1 files changed, 1 insertion(+), 1 deletion(-) diff -puN drivers/net/Kconfig~smc911x-Kconfig-fix drivers/net/Kconfig --- devel/drivers/net/Kconfig~smc911x-Kconfig-fix 2006-04-26 20:42:30.0 -0700 +++ devel-akpm/drivers/net/Kconfig 2006-04-26 20:42:56.0 -0700 @@ -869,7 +869,7 @@ config SMC911X tristate "SMSC LAN911[5678] support" select CRC32 select MII - depends on NET_ETHERNET + depends on NET_ETHERNET && ARCH_PXA help This is a driver for SMSC's LAN911x series of Ethernet chipsets including the new LAN9115, LAN9116, LAN9117, and LAN9118. _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 6/9] e1000: prevent statistics from getting garbled during reset
From: Linas Vepstas <[EMAIL PROTECTED]> If a PCI bus error/fault triggers a PCI bus reset, attempts to get the ethernet packet count statistics from the hardware will fail, returning garbage data upstream. This patch skips statistics data collection if the PCI device is not on the bus. This patch presumes that an earlier patch, [PATCH] PCI Error Recovery: e1000 network device driver has already been applied. Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]> Cc: John Ronciak <[EMAIL PROTECTED]> Cc: Jesse Brandeburg <[EMAIL PROTECTED]> Cc: Jeff Kirsher <[EMAIL PROTECTED]> Cc: Jeff Garzik <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/e1000/e1000_main.c |8 +++- 1 files changed, 7 insertions(+), 1 deletion(-) diff -puN drivers/net/e1000/e1000_main.c~e1000-prevent-statistics-from-getting-garbled-during-reset drivers/net/e1000/e1000_main.c --- devel/drivers/net/e1000/e1000_main.c~e1000-prevent-statistics-from-getting-garbled-during-reset 2006-04-14 23:41:34.0 -0700 +++ devel-akpm/drivers/net/e1000/e1000_main.c 2006-04-14 23:41:34.0 -0700 @@ -3082,14 +3082,20 @@ void e1000_update_stats(struct e1000_adapter *adapter) { struct e1000_hw *hw = &adapter->hw; + struct pci_dev *pdev = adapter->pdev; unsigned long flags; uint16_t phy_tmp; #define PHY_IDLE_ERROR_COUNT_MASK 0x00FF - /* Prevent stats update while adapter is being reset */ + /* +* Prevent stats update while adapter is being reset, or if the pci +* connection is down. +*/ if (adapter->link_speed == 0) return; + if (pdev->error_state && pdev->error_state != pci_channel_io_normal) + return; spin_lock_irqsave(&adapter->stats_lock, flags); _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch 5/9] PCI Error Recovery: e100 network device driver
From: [EMAIL PROTECTED] (Linas Vepstas) Various PCI bus errors can be signaled by newer PCI controllers. This patch adds the PCI error recovery callbacks to the intel ethernet e100 device driver. The patch has been tested, and appears to work well. Signed-off-by: Linas Vepstas <[EMAIL PROTECTED]> Acked-by: Jesse Brandeburg <[EMAIL PROTECTED]> Signed-off-by: Andrew Morton <[EMAIL PROTECTED]> --- drivers/net/e100.c | 75 +++ 1 files changed, 75 insertions(+) diff -puN drivers/net/e100.c~pci-error-recovery-e100-network-device-driver drivers/net/e100.c --- devel/drivers/net/e100.c~pci-error-recovery-e100-network-device-driver 2006-04-10 23:21:20.0 -0700 +++ devel-akpm/drivers/net/e100.c 2006-04-10 23:21:20.0 -0700 @@ -2726,6 +2726,80 @@ static void e100_shutdown(struct pci_dev DPRINTK(PROBE,ERR, "Error enabling wake\n"); } +/* -- PCI Error Recovery infrastructure -- */ +/** + * e100_io_error_detected - called when PCI error is detected. + * @pdev: Pointer to PCI device + * @state: The current pci conneection state + */ +static pci_ers_result_t e100_io_error_detected(struct pci_dev *pdev, pci_channel_state_t state) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + + /* Similar to calling e100_down(), but avoids adpater I/O. */ + netdev->stop(netdev); + + /* Detach; put netif into state similar to hotplug unplug. */ + netif_poll_enable(netdev); + netif_device_detach(netdev); + + /* Request a slot reset. */ + return PCI_ERS_RESULT_NEED_RESET; +} + +/** + * e100_io_slot_reset - called after the pci bus has been reset. + * @pdev: Pointer to PCI device + * + * Restart the card from scratch. + */ +static pci_ers_result_t e100_io_slot_reset(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct nic *nic = netdev_priv(netdev); + + if (pci_enable_device(pdev)) { + printk(KERN_ERR "e100: Cannot re-enable PCI device after reset.\n"); + return PCI_ERS_RESULT_DISCONNECT; + } + pci_set_master(pdev); + + /* Only one device per card can do a reset */ + if (0 != PCI_FUNC(pdev->devfn)) + return PCI_ERS_RESULT_RECOVERED; + e100_hw_reset(nic); + e100_phy_init(nic); + + return PCI_ERS_RESULT_RECOVERED; +} + +/** + * e100_io_resume - resume normal operations + * @pdev: Pointer to PCI device + * + * Resume normal operations after an error recovery + * sequence has been completed. + */ +static void e100_io_resume(struct pci_dev *pdev) +{ + struct net_device *netdev = pci_get_drvdata(pdev); + struct nic *nic = netdev_priv(netdev); + + /* ack any pending wake events, disable PME */ + pci_enable_wake(pdev, 0, 0); + + netif_device_attach(netdev); + if (netif_running(netdev)) { + e100_open(netdev); + mod_timer(&nic->watchdog, jiffies); + } +} + +static struct pci_error_handlers e100_err_handler = { + .error_detected = e100_io_error_detected, + .slot_reset = e100_io_slot_reset, + .resume = e100_io_resume, +}; static struct pci_driver e100_driver = { .name = DRV_NAME, @@ -2737,6 +2811,7 @@ static struct pci_driver e100_driver = { .resume = e100_resume, #endif .shutdown = e100_shutdown, + .err_handler = &e100_err_handler, }; static int __init e100_init_module(void) _ - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC] bridge: partial rtnetlink hooks
Stephen Hemminger wrote: > This is the start of adding support for rtnetlink to the bridge code. > So far it only supports accessing the list of links and notifying > about link changes. It is just a prototype to get early feedback, don't > use to build your own masterpiece yet. > > +static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) > +{ > + struct net_device *dev; > + int idx = 0; > + int err = 0; > + > + printk(KERN_DEBUG "bridge dump ifinfo\n"); > + for (dev = dev_base; dev; dev = dev->next) { > + struct net_bridge_port *p = rcu_dereference(dev->br_port); I think using rcu_dereference (especially without rcu_read_lock()) is a bit misleading, the pointer is actually protected by the RTNL at this point. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] Rough VJ Channel Implementation - vj_core.patch
From: Andi Kleen <[EMAIL PROTECTED]> Date: Thu, 27 Apr 2006 08:41:51 +0200 > Yes but all clients will see all the data from all sockets don't > they? [Unless you have a RDMA nic that can scale to hundred > thousands of connections, but let's assume standard hardware for > now] Each netchannel, which goes to a specific socket, has a ring buffer of packets the NIC can use. Those packets are mmap()'d into userspace so we can control the layout, the page boundaries, etc. and the NIC will only DMA packets matching that channel ID into that userland area. Have a look at the code Kelly posted. - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html