* [PATCH 07/26] rt2x00: BBP busy check
@ 2006-12-03 18:19 Ivo van Doorn
0 siblings, 0 replies; only message in thread
From: Ivo van Doorn @ 2006-12-03 18:19 UTC (permalink / raw)
To: John W. Linville; +Cc: netdev
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 <IvDoorn@gmail.com>
---
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2400pci.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2400pci.c
--- wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-12-02 23:56:59.000000000 +0100
+++ wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2400pci.c 2006-12-03 12:38:28.000000000 +0100
@@ -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, ®);
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(®, BBPCSR_VALUE, value);
rt2x00_set_field32(®, 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(®, 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, ®);
- 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,
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2500pci.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2500pci.c
--- wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-12-03 00:09:32.000000000 +0100
+++ wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2500pci.c 2006-12-03 12:34:39.000000000 +0100
@@ -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, ®);
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(®, BBPCSR_VALUE, value);
rt2x00_set_field32(®, 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(®, 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, ®);
- 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,
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2500usb.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2500usb.c
--- wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-12-03 00:01:21.000000000 +0100
+++ wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt2500usb.c 2006-12-03 12:35:13.000000000 +0100
@@ -117,8 +117,7 @@
offset, 0x00, value, length);
}
-static void rt2x00_bbp_write(const struct rt2x00_dev *rt2x00dev,
- const u8 reg_id, const u8 value)
+static u16 rt2x00_bbp_check(const struct rt2x00_dev *rt2x00dev)
{
u16 reg;
unsigned int i;
@@ -126,14 +125,29 @@
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00_register_read(rt2x00dev, PHY_CSR8, ®);
if (!rt2x00_get_field16(reg, PHY_CSR8_BBP_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)
+{
+ u16 reg;
+
+ /*
+ * Wait untill the BBP becomes ready.
+ */
+ if (rt2x00_bbp_check(rt2x00dev) == 0xffff) {
+ ERROR("PHY_CSR8 register busy. Write failed.\n");
+ return;
+ }
+
+ /*
+ * Write the data into the BBP.
+ */
reg = 0;
rt2x00_set_field16(®, PHY_CSR7_BBP_DATA, value);
rt2x00_set_field16(®, PHY_CSR7_BBP_REG_ID, reg_id);
@@ -146,28 +160,35 @@
const u8 reg_id, u8 *value)
{
u16 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("PHY_CSR8 register busy. Read failed.\n");
+ return;
+ }
+
+ /*
+ * Write the request into the BBP.
*/
+ reg =0;
rt2x00_set_field16(®, PHY_CSR7_BBP_REG_ID, reg_id);
rt2x00_set_field16(®, PHY_CSR7_BBP_READ_CONTROL, 1);
rt2x00_register_write(rt2x00dev, PHY_CSR7, reg);
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00_register_read(rt2x00dev, PHY_CSR8, ®);
- if (!rt2x00_get_field16(reg, PHY_CSR8_BBP_BUSY)) {
- rt2x00_register_read(rt2x00dev, PHY_CSR7, ®);
- *value = rt2x00_get_field16(reg, PHY_CSR7_BBP_DATA);
- return;
- }
- udelay(REGISTER_BUSY_DELAY);
+ /*
+ * Wait untill the BBP becomes ready.
+ */
+ if (rt2x00_bbp_check(rt2x00dev) == 0xffff) {
+ ERROR("PHY_CSR8 register busy. Read failed.\n");
+ *value = 0xff;
+ return;
}
- ERROR("BBPCSR register busy. Read failed.\n");
- *value = 0xff;
+ rt2x00_register_read(rt2x00dev, PHY_CSR7, ®);
+ *value = rt2x00_get_field16(reg, PHY_CSR7_BBP_DATA);
}
static void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt61pci.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt61pci.c
--- wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-12-03 00:04:48.000000000 +0100
+++ wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt61pci.c 2006-12-03 12:35:34.000000000 +0100
@@ -105,8 +105,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;
@@ -114,14 +113,29 @@
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00_register_read(rt2x00dev, PHY_CSR3, ®);
if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
- goto bbp_write;
+ return reg;
udelay(REGISTER_BUSY_DELAY);
}
- ERROR("PHY_CSR3 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("PHY_CSR3 register busy. Write failed.\n");
+ return;
+ }
+
+ /*
+ * Write the data into the BBP.
+ */
reg = 0;
rt2x00_set_field32(®, PHY_CSR3_VALUE, value);
rt2x00_set_field32(®, PHY_CSR3_REGNUM, reg_id);
@@ -135,10 +149,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("PHY_CSR3 register busy. Read failed.\n");
+ return;
+ }
+
+ /*
+ * Write the request into the BBP.
*/
reg =0;
rt2x00_set_field32(®, PHY_CSR3_REGNUM, reg_id);
@@ -147,17 +168,14 @@
rt2x00_register_write(rt2x00dev, PHY_CSR3, reg);
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00_register_read(rt2x00dev, PHY_CSR3, ®);
- if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
- *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
- return;
- }
- udelay(REGISTER_BUSY_DELAY);
- }
+ /*
+ * Wait untill the BBP becomes ready.
+ */
+ reg = rt2x00_bbp_check(rt2x00dev);
+ if (reg == 0xffff)
+ ERROR("PHY_CSR3 register busy. Read failed.\n");
- ERROR("PHY_CSR3 register busy. Read failed.\n");
- *value = 0xff;
+ *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
}
static void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
diff -rU3 wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt73usb.c wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt73usb.c
--- wireless-dev-d80211/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-12-03 00:13:18.000000000 +0100
+++ wireless-dev-bbp/drivers/net/wireless/d80211/rt2x00/rt73usb.c 2006-12-03 12:35:52.000000000 +0100
@@ -119,8 +119,7 @@
offset, 0x00, 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;
@@ -128,14 +127,29 @@
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
rt2x00_register_read(rt2x00dev, PHY_CSR3, ®);
if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY))
- goto bbp_write;
+ return reg;
udelay(REGISTER_BUSY_DELAY);
}
- ERROR("PHY_CSR3 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("PHY_CSR3 register busy. Write failed.\n");
+ return;
+ }
+
+ /*
+ * Write the data into the BBP.
+ */
reg = 0;
rt2x00_set_field32(®, PHY_CSR3_VALUE, value);
rt2x00_set_field32(®, PHY_CSR3_REGNUM, reg_id);
@@ -149,10 +163,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("PHY_CSR3 register busy. Read failed.\n");
+ return;
+ }
+
+ /*
+ * Write the request into the BBP.
*/
reg =0;
rt2x00_set_field32(®, PHY_CSR3_REGNUM, reg_id);
@@ -161,17 +182,14 @@
rt2x00_register_write(rt2x00dev, PHY_CSR3, reg);
- for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
- rt2x00_register_read(rt2x00dev, PHY_CSR3, ®);
- if (!rt2x00_get_field32(reg, PHY_CSR3_BUSY)) {
- *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
- return;
- }
- udelay(REGISTER_BUSY_DELAY);
- }
+ /*
+ * Wait untill the BBP becomes ready.
+ */
+ reg = rt2x00_bbp_check(rt2x00dev);
+ if (reg == 0xffff)
+ ERROR("PHY_CSR3 register busy. Read failed.\n");
- ERROR("PHY_CSR3 register busy. Read failed.\n");
- *value = 0xff;
+ *value = rt2x00_get_field32(reg, PHY_CSR3_VALUE);
}
static void rt2x00_rf_write(const struct rt2x00_dev *rt2x00dev,
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2006-12-03 18:19 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-12-03 18:19 [PATCH 07/26] rt2x00: BBP busy check Ivo van Doorn
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.