Skip to contentSkip to conversation

rt2x00: BBP busy check

PATCH In review Ivo van Doorn 1 participant 1 message Dec 3, 2006

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 7/26 rt2x00: BBP busy check

rt61pci and rt73usb legacy drivers have hinted that there are race conditions with the bbp register handling. This must be fixed by doing a busy check before the actual read command. At the same time we can remove duplicate code by putting that busy check into a seperate function.

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

---

drivers/net/wireless/d80211/rt2x00/rt2400pci.c +36 -18
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
@@ -98,8 +98,7 @@
 	memcpy_toio(rt2x00dev->csr_addr + offset, value, length);
 }
 
-static void rt2x00_bbp_write(const struct rt2x00_dev *rt2x00dev,
-	const u8 reg_id, const u8 value)
+static u32 rt2x00_bbp_check(const struct rt2x00_dev *rt2x00dev)
 {
 	u32 reg;
 	unsigned int i;
@@ -107,14 +106,29 @@
 	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
 		rt2x00_register_read(rt2x00dev, BBPCSR, &reg);
 		if (!rt2x00_get_field32(reg, BBPCSR_BUSY))
-			goto bbp_write;
+			return reg;
 		udelay(REGISTER_BUSY_DELAY);
 	}
 
-	ERROR("BBPCSR register busy. Write failed.\n");
-	return;
+	return 0xffff;
+}
 
-bbp_write:
+static void rt2x00_bbp_write(const struct rt2x00_dev *rt2x00dev,
+	const u8 reg_id, const u8 value)
+{
+	u32 reg;
+
+	/*
+	 *  Wait untill the BBP becomes ready.
+	 */
+	if (rt2x00_bbp_check(rt2x00dev) == 0xffff) {
+		ERROR("BBPCSR register busy. Write failed.\n");
+		return;
+	}
+
+	/*
+	 * Write the data into the BBP.
+	 */
 	reg = 0;
 	rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
 	rt2x00_set_field32(&reg, BBPCSR_REGNUM, reg_id);
@@ -128,10 +142,17 @@
 	const u8 reg_id, u8 *value)
 {
 	u32 reg;
-	unsigned int i;
 
 	/*
-	 * First request the register we wish to read from.
+	 *  Wait untill the BBP becomes ready.
+	 */
+	if (rt2x00_bbp_check(rt2x00dev) == 0xffff) {
+		ERROR("BBPCSR register busy. Read failed.\n");
+		return;
+	}
+
+	/*
+	 * Write the request into the BBP.
 	 */
 	reg = 0;
 	rt2x00_set_field32(&reg, BBPCSR_REGNUM, reg_id);
@@ -140,17 +161,14 @@
 
 	rt2x00_register_write(rt2x00dev, BBPCSR, reg);
 
-	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
-		rt2x00_register_read(rt2x00dev, BBPCSR, &reg);
-		if (!rt2x00_get_field32(reg, BBPCSR_BUSY)) {
-			*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
-			return;
-		}
-		udelay(REGISTER_BUSY_DELAY);
-	}
+	/*
+	 *  Wait untill the BBP becomes ready.
+	 */
+	reg = rt2x00_bbp_check(rt2x00dev);
+	if (reg == 0xffff)
+		ERROR("BBPCSR register busy. Read failed.\n");
 
-	ERROR("BBPCSR register busy. Read failed.\n");
-	*value = 0xff;
+	*value = rt2x00_get_field32(reg, BBPCSR_VALUE);
 }
 
 static void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
drivers/net/wireless/d80211/rt2x00/rt2500pci.c +36 -18

85 lines not on this page · raw message

drivers/net/wireless/d80211/rt2x00/rt2500usb.c +39 -18

89 lines not on this page · raw message

drivers/net/wireless/d80211/rt2x00/rt61pci.c +36 -18

85 lines not on this page · raw message

drivers/net/wireless/d80211/rt2x00/rt73usb.c +36 -18

85 lines not on this page · raw message