Subject: [PATCH 24/32] rt2x00: Use correct desc_addr and data_addr

From: Ivo van Doorn <[email-masked]>
Date: Fri, 28 Apr 2006 00:03:15 +0200

From: Ivo van Doorn <[email-masked]>

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-masked]>

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.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c	2006-04-27 21:55:14.000000000 +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, 0x1111);
@@ -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(&rt2x00usb->chip, RF5222))
+		return -ENODEV;
+
 	/*
 	 * 3 - Identify default antenna configuration.
 	 * Ralink devices have have antenna options for both TX as RX.
@@ -1691,26 +1699,27 @@ rt2500usb_init_mac(struct rt2x00_usb *rt
 {
 	struct net_device	*net_dev = usb_get_intfdata(
 						rt2x00usb->usb_intf);
-	u16			reg[3] = {0, 0, 0};
+	u16			eeprom[3] = {0, 0, 0};
 
 	/*
 	 * Read MAC address from EEPROM.
 	 */
-	rt2x00_eeprom_multiread(rt2x00usb, EEPROM_MAC_ADDR, &reg[0], 6);
+	rt2x00_eeprom_multiread(rt2x00usb, EEPROM_MAC_ADDR, &eeprom[0], 6);
 
-	net_dev->dev_addr[0] = rt2x00_get_field16(reg[0], MAC_CSR2_BYTE0);
-	net_dev->dev_addr[1] = rt2x00_get_field16(reg[0], MAC_CSR2_BYTE1);
-	net_dev->dev_addr[2] = rt2x00_get_field16(reg[1], MAC_CSR3_BYTE2);
-	net_dev->dev_addr[3] = rt2x00_get_field16(reg[1], MAC_CSR3_BYTE3);
-	net_dev->dev_addr[4] = rt2x00_get_field16(reg[2], MAC_CSR4_BYTE4);
-	net_dev->dev_addr[5] = rt2x00_get_field16(reg[2], MAC_CSR4_BYTE5);
+	net_dev->dev_addr[0] = rt2x00_get_field16(eeprom[0], MAC_CSR2_BYTE0);
+	net_dev->dev_addr[1] = rt2x00_get_field16(eeprom[0], MAC_CSR2_BYTE1);
+	net_dev->dev_addr[2] = rt2x00_get_field16(eeprom[1], MAC_CSR3_BYTE2);
+	net_dev->dev_addr[3] = rt2x00_get_field16(eeprom[1], MAC_CSR3_BYTE3);
+	net_dev->dev_addr[4] = rt2x00_get_field16(eeprom[2], MAC_CSR4_BYTE4);
+	net_dev->dev_addr[5] = rt2x00_get_field16(eeprom[2], MAC_CSR4_BYTE5);
 
 	net_dev->addr_len = 6;
 
 	/*
 	 * Write MAC address to register.
 	 */
-	rt2x00_register_multiwrite(rt2x00usb, MAC_CSR2, &reg[0], sizeof(reg));
+	rt2x00_register_multiwrite(rt2x00usb, MAC_CSR2,
+		&eeprom[0], sizeof(reg));
 
 	return 0;
 }
@@ -1730,7 +1739,7 @@ rt2500usb_init_hw_channels(struct rt2x00
 		{ RF2523,	{ 0x00022010, 0x000e0111, 0x00000a1b } },
 		{ RF2524,	{ 0x00032020, 0x00000101, 0x00000a1b } },
 		{ RF2525,	{ 0x00022020, 0x00060111, 0x00000a1b } },
-		{ RF2525E,	{ 0x00022020, 0x00060111, 0x00000000 } },
+		{ RF2525E,	{ 0x00022010, 0x00060111, 0x00000000 } },
 		{ RF5222,	{ 0x00000000, 0x00000101, 0x00000000 } }
 	};
 
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:53:13.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h	2006-04-27 21:55:14.000000000 +0200
@@ -683,6 +683,36 @@ struct data_entry{
 } __attribute__ ((packed));
 
 /*
+ * The location of the descriptor is variating and depends
+ * on the fact if it is a TX or RX ring and the length of the packet.
+ * We need some small handlers to properly access the descriptors.
+ */
+static inline void*
+rt2x00usb_rxdata_addr(struct data_entry *entry)
+{
+	return entry->data_addr;
+}
+
+static inline void*
+rt2x00usb_rxdesc_addr(struct data_entry *entry)
+{
+	return entry->data_addr +
+		(entry->urb->actual_length - entry->ring->desc_size);
+}
+
+static inline void*
+rt2x00usb_txdata_addr(struct data_entry *entry)
+{
+	return entry->data_addr + entry->ring->desc_size;
+}
+
+static inline void*
+rt2x00usb_txdesc_addr(struct data_entry *entry)
+{
+	return entry->data_addr;
+}
+
+/*
  * Device specific structure.
  */
 struct rt2x00_usb{