Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3b908870 authored by Jeff Garzik's avatar Jeff Garzik
Browse files

Merge branch 'upstream-fixes' of...

Merge branch 'upstream-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-2.6 into upstream-fixes
parents 3b85418b 7c241d37
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -421,6 +421,14 @@ L: linux-hams@vger.kernel.org
W:	http://www.baycom.org/~tom/ham/ham.html
S:	Maintained

BCM43XX WIRELESS DRIVER
P:	Michael Buesch
M:	mb@bu3sch.de
P:	Stefano Brivio
M:	st3@riseup.net
W:	http://bcm43xx.berlios.de/
S:	Maintained

BEFS FILE SYSTEM
P:	Sergey S. Kostyliov
M:	rathamahata@php4.ru
+8 −0
Original line number Diff line number Diff line
@@ -213,6 +213,14 @@ static inline
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring)
{
}
static inline
void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring)
{
}
static inline
void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
{
}

#endif /* CONFIG_BCM43XX_DMA */
#endif /* BCM43xx_DMA_H_ */
+62 −30
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
#include "bcm43xx_pio.h"
#include "bcm43xx_main.h"
#include "bcm43xx_xmit.h"
#include "bcm43xx_power.h"

#include <linux/delay.h>

@@ -44,10 +45,10 @@ static void tx_octet(struct bcm43xx_pioqueue *queue,
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
				  octet);
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
				  BCM43xx_PIO_TXCTL_WRITEHI);
				  BCM43xx_PIO_TXCTL_WRITELO);
	} else {
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
				  BCM43xx_PIO_TXCTL_WRITEHI);
				  BCM43xx_PIO_TXCTL_WRITELO);
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
				  octet);
	}
@@ -103,7 +104,7 @@ static void tx_complete(struct bcm43xx_pioqueue *queue,
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA,
				  skb->data[skb->len - 1]);
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
				  BCM43xx_PIO_TXCTL_WRITEHI |
				  BCM43xx_PIO_TXCTL_WRITELO |
				  BCM43xx_PIO_TXCTL_COMPLETE);
	} else {
		bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
@@ -112,9 +113,10 @@ static void tx_complete(struct bcm43xx_pioqueue *queue,
}

static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
			   int packetindex)
			   struct bcm43xx_pio_txpacket *packet)
{
	u16 cookie = 0x0000;
	int packetindex;

	/* We use the upper 4 bits for the PIO
	 * controller ID and the lower 12 bits
@@ -135,6 +137,7 @@ static u16 generate_cookie(struct bcm43xx_pioqueue *queue,
	default:
		assert(0);
	}
	packetindex = pio_txpacket_getindex(packet);
	assert(((u16)packetindex & 0xF000) == 0x0000);
	cookie |= (u16)packetindex;

@@ -184,7 +187,7 @@ static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue,
	bcm43xx_generate_txhdr(queue->bcm,
			       &txhdr, skb->data, skb->len,
			       (packet->xmitted_frags == 0),
			       generate_cookie(queue, pio_txpacket_getindex(packet)));
			       generate_cookie(queue, packet));

	tx_start(queue);
	octets = skb->len + sizeof(txhdr);
@@ -241,7 +244,7 @@ static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet)
		queue->tx_devq_packets++;
		queue->tx_devq_used += octets;

		assert(packet->xmitted_frags <= packet->txb->nr_frags);
		assert(packet->xmitted_frags < packet->txb->nr_frags);
		packet->xmitted_frags++;
		packet->xmitted_octets += octets;
	}
@@ -257,8 +260,14 @@ static void tx_tasklet(unsigned long d)
	unsigned long flags;
	struct bcm43xx_pio_txpacket *packet, *tmp_packet;
	int err;
	u16 txctl;

	bcm43xx_lock_mmio(bcm, flags);

	txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
	if (txctl & BCM43xx_PIO_TXCTL_SUSPEND)
		goto out_unlock;

	list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) {
		assert(packet->xmitted_frags < packet->txb->nr_frags);
		if (packet->xmitted_frags == 0) {
@@ -288,6 +297,7 @@ static void tx_tasklet(unsigned long d)
	next_packet:
		continue;
	}
out_unlock:
	bcm43xx_unlock_mmio(bcm, flags);
}

@@ -330,12 +340,19 @@ struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm,
		     (unsigned long)queue);

	value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD);
	value |= BCM43xx_SBF_XFER_REG_BYTESWAP;
	value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP;
	bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value);

	qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE);
	if (qsize == 0) {
		printk(KERN_ERR PFX "ERROR: This card does not support PIO "
				    "operation mode. Please use DMA mode "
				    "(module parameter pio=0).\n");
		goto err_freequeue;
	}
	if (qsize <= BCM43xx_PIO_TXQADJUST) {
		printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize);
		printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n",
		       qsize);
		goto err_freequeue;
	}
	qsize -= BCM43xx_PIO_TXQADJUST;
@@ -444,15 +461,10 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
{
	struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1;
	struct bcm43xx_pio_txpacket *packet;
	u16 tmp;

	assert(!queue->tx_suspended);
	assert(!list_empty(&queue->txfree));

	tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL);
	if (tmp & BCM43xx_PIO_TXCTL_SUSPEND)
		return -EBUSY;

	packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list);
	packet->txb = txb;
	packet->xmitted_frags = 0;
@@ -462,7 +474,7 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm,
	assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS);

	/* Suspend TX, if we are out of packets in the "free" queue. */
	if (unlikely(list_empty(&queue->txfree))) {
	if (list_empty(&queue->txfree)) {
		netif_stop_queue(queue->bcm->net_dev);
		queue->tx_suspended = 1;
	}
@@ -480,15 +492,15 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,

	queue = parse_cookie(bcm, status->cookie, &packet);
	assert(queue);
//TODO
if (!queue)
return;

	free_txpacket(packet, 1);
	if (unlikely(queue->tx_suspended)) {
	if (queue->tx_suspended) {
		queue->tx_suspended = 0;
		netif_wake_queue(queue->bcm->net_dev);
	}
	/* If there are packets on the txqueue, poke the tasklet. */
	/* If there are packets on the txqueue, poke the tasklet
	 * to transmit them.
	 */
	if (!list_empty(&queue->txqueue))
		tasklet_schedule(&queue->txtask);
}
@@ -519,12 +531,9 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
	int i, preamble_readwords;
	struct sk_buff *skb;

return;
	tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL);
	if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) {
		dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk.
	if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE))
		return;
	}
	bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL,
			  BCM43xx_PIO_RXCTL_DATAAVAILABLE);

@@ -538,8 +547,7 @@ return;
	return;
data_ready:

//FIXME: endianess in this function.
	len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA));
	len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
	if (unlikely(len > 0x700)) {
		pio_rx_error(queue, 0, "len > 0x700");
		return;
@@ -555,7 +563,7 @@ return;
		preamble_readwords = 18 / sizeof(u16);
	for (i = 0; i < preamble_readwords; i++) {
		tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
		preamble[i + 1] = cpu_to_be16(tmp);//FIXME?
		preamble[i + 1] = cpu_to_le16(tmp);
	}
	rxhdr = (struct bcm43xx_rxhdr *)preamble;
	rxflags2 = le16_to_cpu(rxhdr->flags2);
@@ -591,16 +599,40 @@ return;
	}
	skb_put(skb, len);
	for (i = 0; i < len - 1; i += 2) {
		tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA));
		*((u16 *)(skb->data + i)) = tmp;
		tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
		*((u16 *)(skb->data + i)) = cpu_to_le16(tmp);
	}
	if (len % 2) {
		tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA);
		skb->data[len - 1] = (tmp & 0x00FF);
/* The specs say the following is required, but
 * it is wrong and corrupts the PLCP. If we don't do
 * this, the PLCP seems to be correct. So ifdef it out for now.
 */
#if 0
		if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME)
			skb->data[0x20] = (tmp & 0xFF00) >> 8;
			skb->data[2] = (tmp & 0xFF00) >> 8;
		else
			skb->data[0x1E] = (tmp & 0xFF00) >> 8;
			skb->data[0] = (tmp & 0xFF00) >> 8;
#endif
	}
	skb_trim(skb, len - IEEE80211_FCS_LEN);
	bcm43xx_rx(queue->bcm, skb, rxhdr);
}

void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
{
	bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1);
	bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
			  bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
			  | BCM43xx_PIO_TXCTL_SUSPEND);
}

void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
{
	bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL,
			  bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL)
			  & ~BCM43xx_PIO_TXCTL_SUSPEND);
	bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1);
	tasklet_schedule(&queue->txtask);
}
+14 −2
Original line number Diff line number Diff line
@@ -14,8 +14,8 @@
#define BCM43xx_PIO_RXCTL		0x08
#define BCM43xx_PIO_RXDATA		0x0A

#define BCM43xx_PIO_TXCTL_WRITEHI	(1 << 0)
#define BCM43xx_PIO_TXCTL_WRITELO	(1 << 1)
#define BCM43xx_PIO_TXCTL_WRITELO	(1 << 0)
#define BCM43xx_PIO_TXCTL_WRITEHI	(1 << 1)
#define BCM43xx_PIO_TXCTL_COMPLETE	(1 << 2)
#define BCM43xx_PIO_TXCTL_INIT		(1 << 3)
#define BCM43xx_PIO_TXCTL_SUSPEND	(1 << 7)
@@ -95,6 +95,7 @@ void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue,
		       u16 offset, u16 value)
{
	bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value);
	mmiowb();
}


@@ -107,6 +108,9 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm,
				   struct bcm43xx_xmitstatus *status);
void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue);

void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue);
void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue);

#else /* CONFIG_BCM43XX_PIO */

static inline
@@ -133,6 +137,14 @@ static inline
void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue)
{
}
static inline
void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue)
{
}
static inline
void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue)
{
}

#endif /* CONFIG_BCM43XX_PIO */
#endif /* BCM43xx_PIO_H_ */
+2 −2
Original line number Diff line number Diff line
@@ -1860,7 +1860,7 @@ static char * __prism2_translate_scan(local_info_t *local,
	memset(&iwe, 0, sizeof(iwe));
	iwe.cmd = SIOCGIWFREQ;
	if (scan) {
		chan = scan->chid;
		chan = le16_to_cpu(scan->chid);
	} else if (bss) {
		chan = bss->chan;
	} else {
@@ -1868,7 +1868,7 @@ static char * __prism2_translate_scan(local_info_t *local,
	}

	if (chan > 0) {
		iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
		iwe.u.freq.m = freq_list[chan - 1] * 100000;
		iwe.u.freq.e = 1;
		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
						  IW_EV_FREQ_LEN);
Loading