Subject: [PATCH 25/32] rt2x00: Add flag handlers

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

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

Add flag handlers to set the state and capabilities of
the driver.

Signed-off-by: Ivo van Doorn <[email-masked]>

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.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.c	2006-04-27 21:56:05.000000000 +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(&reg, 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.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2400pci.h	2006-04-27 21:56:05.000000000 +0200
@@ -868,6 +868,11 @@ struct data_entry{
  * Device specific structure.
  */
 struct rt2x00_pci{
+	/*
+	 * Device flags.
+	 */
+	unsigned int				flags;
+
 #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.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.c	2006-04-27 21:56:05.000000000 +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(&reg, 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_pci 
 	rt2x00pci->led_mode = rt2x00_get_field16(eeprom,
 				EEPROM_ANTENNA_LED_MODE);
 
-#ifdef CONFIG_RT2500PCI_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_RT2500PCI_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/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:53:13.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500pci.h	2006-04-27 21:56:05.000000000 +0200
@@ -1137,6 +1137,11 @@ struct data_entry{
  * Device specific structure.
  */
 struct rt2x00_pci{
+	/*
+	 * Device flags.
+	 */
+	unsigned int				flags;
+
 #ifdef CONFIG_RT2500PCI_BUTTON
 	/*
 	 * ACPI device for generation of ACPI events.
@@ -1200,8 +1205,6 @@ struct rt2x00_pci{
 	 */
 	struct ieee80211_rx_status		rx_params;
 
-	u16					atim_available;
-
 	/*
 	 * EEPROM bus width.
 	 */
@@ -1252,7 +1255,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/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:55:14.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.c	2006-04-27 21:56:05.000000000 +0200
@@ -742,10 +742,14 @@ rt2500usb_rxdone(void *data)
 		entry = rt2x00_get_data_entry(ring);
 		rxd = rt2x00usb_rxdesc_addr(entry);
 
+		if (GET_FLAG(entry, ENTRY_OWNER_NIC))
+			break;
+
 		/*
-		* There has been a problem. Ignore packet.
-		*/
+		 * There has been a problem. Ignore packet.
+		 */
 		if (entry->urb->status) {
+			SET_FLAG(entry, ENTRY_OWNER_NIC);
 			usb_submit_urb(entry->urb, GFP_ATOMIC);
 			rt2x00_ring_index_inc(ring);
 			continue;
@@ -782,6 +786,7 @@ rt2500usb_rxdone(void *data)
 			total_rssi += rt2x00usb->rx_params.ssi;
 		}
 
+		SET_FLAG(entry, ENTRY_OWNER_NIC);
 		usb_submit_urb(entry->urb, GFP_ATOMIC);
 
 		rt2x00_ring_index_inc(ring);
@@ -808,6 +813,9 @@ rt2500usb_txdone(void *data)
 		entry = rt2x00_get_data_entry_done(ring);
 		txd = rt2x00usb_txdesc_addr(entry);
 
+		if (GET_FLAG(entry, ENTRY_OWNER_NIC))
+			break;
+
 		ack = rt2x00_get_field32(txd->word0, TXD_W0_ACK);
 	
 		/*
@@ -861,6 +869,9 @@ rt2500usb_interrupt(struct urb *urb, str
 	struct rt2x00_usb	*rt2x00usb =
 		ieee80211_dev_hw_data(entry->ring->net_dev);
 
+	if (!GET_FLAG(rt2x00usb, RADIO_ENABLED))
+		return;
+
 	if (urb->status)
 		return;
 
@@ -989,7 +1000,7 @@ rt2500usb_allocate_rings(struct rt2x00_u
 		return -ENOMEM;
 	}
 
-	rt2x00usb->atim_available = 1;
+	SET_FLAG(rt2x00usb, ATIM_AVAILABLE);
 
 	if (rt2500usb_alloc_ring(
 		rt2x00usb, &rt2x00usb->ring[RING_RX], &rt2500usb_rxdone,
@@ -1049,6 +1060,7 @@ rt2500usb_init_rxring(struct rt2x00_usb 
 			ring->entry_size + ring->desc_size,
 			rt2500usb_interrupt,
 			&entry[counter]);
+		SET_FLAG(&entry[counter], ENTRY_OWNER_NIC | ENTRY_TYPE_RX);
 		usb_submit_urb(entry[counter].urb, GFP_ATOMIC);
 	}
 }
@@ -1063,6 +1075,7 @@ rt2500usb_init_txring(struct rt2x00_usb 
 	for (counter = 0; counter < ring->stats.limit; counter++) {
 		entry[counter].urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 		entry[counter].urb->transfer_dma = entry[counter].data_dma;
+		CLEAR_FLAGS(&entry[counter]);
 	}
 }
 
@@ -1223,6 +1236,8 @@ rt2500usb_tx(struct net_device *net_dev,
 	struct sk_buff *skb, struct ieee80211_tx_control *control)
 {
 	struct rt2x00_usb	*rt2x00usb = ieee80211_dev_hw_data(net_dev);
+	struct usb_devive	*usb_dev =
+		interface_to_usbdev(rt2x00usb->usb_intf);
 	struct data_ring	*ring;
 	struct data_entry	*entry;
 	struct txd		*txd;
@@ -1247,6 +1262,7 @@ rt2500usb_tx(struct net_device *net_dev,
 	rt2500usb_write_tx_desc(rt2x00usb, txd, skb, control);
 	entry->skb = skb;
 
+	SET_FLAG(entry, ENTRY_OWNER_NIC);
 	usb_fill_bulk_urb(
 		entry->urb,
 		usb_dev,
@@ -1320,6 +1336,8 @@ rt2500usb_open(struct net_device *net_de
 	rt2x00_set_field16_nb(&reg, TXRX_CSR2_DISABLE_RX, 0);
 	rt2x00_register_write(rt2x00usb, TXRX_CSR2, reg);
 
+	SET_FLAG(rt2x00usb, RADIO_ENABLED);
+
 	return 0;
 
 exit_fail:
@@ -1336,6 +1354,8 @@ rt2500usb_stop(struct net_device *net_de
 	int			counter;
 	u16			reg;
 
+	CLEAR_FLAG(rt2x00usb, RADIO_ENABLED);
+
 	/*
 	 * Cancel RX.
 	 */
@@ -1609,6 +1629,8 @@ rt2500usb_beacon_update(struct net_devic
 	struct sk_buff *skb, struct ieee80211_tx_control *control)
 {
 	struct rt2x00_usb	*rt2x00usb = ieee80211_dev_hw_data(net_dev);
+	struct usb_devive	*usb_dev =
+		interface_to_usbdev(rt2x00usb->usb_intf);
 	struct data_entry	*entry;
 
 	entry = rt2x00_get_data_entry(&rt2x00usb->ring[RING_BEACON]);
@@ -1624,6 +1646,7 @@ rt2500usb_beacon_update(struct net_devic
 	rt2500usb_write_tx_desc(rt2x00usb,
 		rt2x00usb_txdesc_addr(entry), skb, control);
 
+	SET_FLAG(entry, ENTRY_OWNER_NIC);
 	usb_fill_bulk_urb(
 		entry->urb,
 		usb_dev,
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:55:14.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2500usb.h	2006-04-27 21:56:05.000000000 +0200
@@ -648,6 +648,13 @@ struct rxd{
  */
 struct data_entry{
 	/*
+	 * Status flag.
+	 */
+	unsigned int			flags;
+#define ENTRY_OWNER_NIC			0x00000001
+#define ENTRY_TYPE_RX			0x00000002
+
+	/*
 	 * Ring we belong to.
 	 */
 	struct data_ring		*ring;
@@ -717,6 +724,11 @@ rt2x00usb_txdesc_addr(struct data_entry 
  */
 struct rt2x00_usb{
 	/*
+	 * Device flags.
+	 */
+	unsigned int				flags;
+
+	/*
 	 * PCI device structure.
 	 */
 	struct usb_interface			*usb_intf;
@@ -748,8 +760,6 @@ struct rt2x00_usb{
 	 */
 	struct ieee80211_rx_status		rx_params;
 
-	u8					atim_available;
-
 	/*
 	 * Alignment.
 	 */
@@ -798,7 +808,7 @@ rt2x00usb_get_ring(struct rt2x00_usb *rt
 {
 	u8					atim;
 
-	atim = rt2x00usb->atim_available;
+	atim = GET_FLAG(rt2x00usb, ATIM_AVAILABLE);
 
 	/*
 	 * Check if the rings have been allocated.
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:52:01.000000000 +0200
+++ wireless-dev-rt2x00-patch/drivers/net/wireless/d80211/rt2x00/rt2x00.h	2006-04-27 21:56:05.000000000 +0200
@@ -93,6 +93,32 @@ static int rt2x00_debug_level = 0;
 #define BEACON_ENTRIES			1
 
 /*
+ * Flag handlers
+ */
+#define SET_FLAG(__dev, __flag)		( (__dev)->flags |= (__flag) )
+#define GET_FLAG(__dev, __flag)		( !!((__dev)->flags & (__flag)) )
+#define CLEAR_FLAG(__dev, __flag)	( (__dev)->flags &= ~(__flag) )
+#define CLEAR_FLAGS(__dev)		( (__dev)->flags = 0 )
+
+/*
+ * Device flags
+ */
+#define INTERFACE_INITIALIZED			0x00000001
+#define INTERFACE_PROMISC			0x00000002
+#define FIRMWARE_FAILED				0x00000004
+#define FIRMWARE_LOADED				0x00000008
+#define RADIO_ENABLED				0x00000010
+#define RADIO_RESUME				0x00000020
+#define ATIM_AVAILABLE				0x00000040
+#define FRAME_TYPE				0x00000080
+#define EXTERNAL_LNA				0x00000100
+#define EXTERNAL_LNA_A				0x00000200
+#define EXTERNAL_LNA_BG				0x00000400
+#define RF_SEQUENCE				0x00000800
+#define DOUBLE_ANTENNA				0x00001000
+#define HARDWARE_BUTTON				0x00002000
+
+/*
  * TX result flags.
  */
 enum TX_STATUS {