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

Commit c9c3b1a5 authored by Ivo van Doorn's avatar Ivo van Doorn Committed by John W. Linville
Browse files

rt2x00: Cleanup indirect register access



All code which accessed indirect registers was similar
in respect to the for-loop, the given timeout, etc.
Move it into a seperate function, which for PCI drivers
can be moved into rt2x00pci.

This allows us to cleanup the cleanup the code further
by removing the goto statementsand making the codepath
look a bit nicer.

Signed-off-by: default avatarIvo van Doorn <IvDoorn@gmail.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 9764f3f9
Loading
Loading
Loading
Loading
+42 −83
Original line number Diff line number Diff line
@@ -49,20 +49,10 @@
 * the access attempt is considered to have failed,
 * and we will print an error.
 */
static u32 rt2400pci_bbp_check(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;
	unsigned int i;

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2x00pci_register_read(rt2x00dev, BBPCSR, &reg);
		if (!rt2x00_get_field32(reg, BBPCSR_BUSY))
			break;
		udelay(REGISTER_BUSY_DELAY);
	}

	return reg;
}
#define WAIT_FOR_BBP(__dev, __reg) \
	rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
#define WAIT_FOR_RF(__dev, __reg) \
	rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))

static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
				const unsigned int word, const u8 value)
@@ -72,15 +62,10 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2400pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;

	/*
	 * Write the data into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
@@ -88,15 +73,9 @@ static void rt2400pci_bbp_write(struct rt2x00_dev *rt2x00dev,
		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);

		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);

	return;

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
}

static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -107,15 +86,14 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2400pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;

	/*
	 * Write the request into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the read request into the register.
	 * After the data has been written, we wait until hardware
	 * returns the correct value, if at any time the register
	 * doesn't become available in time, reg will be 0xffffffff
	 * which means we return 0xff to the caller.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
@@ -123,49 +101,29 @@ static void rt2400pci_bbp_read(struct rt2x00_dev *rt2x00dev,

		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2400pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;
		WAIT_FOR_BBP(rt2x00dev, &reg);
	}

	*value = rt2x00_get_field32(reg, BBPCSR_VALUE);

	mutex_unlock(&rt2x00dev->csr_mutex);

	return;

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
	*value = 0xff;
}

static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,
			       const unsigned int word, const u32 value)
{
	u32 reg;
	unsigned int i;

	if (!word)
		return;

	mutex_lock(&rt2x00dev->csr_mutex);

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
		if (!rt2x00_get_field32(reg, RFCSR_BUSY))
			goto rf_write;
		udelay(REGISTER_BUSY_DELAY);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
	ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
	return;

rf_write:
	/*
	 * Wait until the RF becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, RFCSR_VALUE, value);
		rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
@@ -174,6 +132,7 @@ static void rt2400pci_rf_write(struct rt2x00_dev *rt2x00dev,

		rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
		rt2x00_rf_write(rt2x00dev, word, value);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
}
+42 −83
Original line number Diff line number Diff line
@@ -49,20 +49,10 @@
 * the access attempt is considered to have failed,
 * and we will print an error.
 */
static u32 rt2500pci_bbp_check(struct rt2x00_dev *rt2x00dev)
{
	u32 reg;
	unsigned int i;

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2x00pci_register_read(rt2x00dev, BBPCSR, &reg);
		if (!rt2x00_get_field32(reg, BBPCSR_BUSY))
			break;
		udelay(REGISTER_BUSY_DELAY);
	}

	return reg;
}
#define WAIT_FOR_BBP(__dev, __reg) \
	rt2x00pci_regbusy_read((__dev), BBPCSR, BBPCSR_BUSY, (__reg))
#define WAIT_FOR_RF(__dev, __reg) \
	rt2x00pci_regbusy_read((__dev), RFCSR, RFCSR_BUSY, (__reg))

static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
				const unsigned int word, const u8 value)
@@ -72,15 +62,10 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;

	/*
	 * Write the data into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, BBPCSR_VALUE, value);
		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
@@ -88,15 +73,9 @@ static void rt2500pci_bbp_write(struct rt2x00_dev *rt2x00dev,
		rt2x00_set_field32(&reg, BBPCSR_WRITE_CONTROL, 1);

		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);

	return;

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "BBPCSR register busy. Write failed.\n");
}

static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -107,15 +86,14 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;

	/*
	 * Write the request into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the read request into the register.
	 * After the data has been written, we wait until hardware
	 * returns the correct value, if at any time the register
	 * doesn't become available in time, reg will be 0xffffffff
	 * which means we return 0xff to the caller.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, BBPCSR_REGNUM, word);
		rt2x00_set_field32(&reg, BBPCSR_BUSY, 1);
@@ -123,49 +101,29 @@ static void rt2500pci_bbp_read(struct rt2x00_dev *rt2x00dev,

		rt2x00pci_register_write(rt2x00dev, BBPCSR, reg);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500pci_bbp_check(rt2x00dev);
	if (rt2x00_get_field32(reg, BBPCSR_BUSY))
		goto exit_fail;
		WAIT_FOR_BBP(rt2x00dev, &reg);
	}

	*value = rt2x00_get_field32(reg, BBPCSR_VALUE);

	mutex_unlock(&rt2x00dev->csr_mutex);

	return;

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "BBPCSR register busy. Read failed.\n");
	*value = 0xff;
}

static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,
			       const unsigned int word, const u32 value)
{
	u32 reg;
	unsigned int i;

	if (!word)
		return;

	mutex_lock(&rt2x00dev->csr_mutex);

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2x00pci_register_read(rt2x00dev, RFCSR, &reg);
		if (!rt2x00_get_field32(reg, RFCSR_BUSY))
			goto rf_write;
		udelay(REGISTER_BUSY_DELAY);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
	ERROR(rt2x00dev, "RFCSR register busy. Write failed.\n");
	return;

rf_write:
	/*
	 * Wait until the RF becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field32(&reg, RFCSR_VALUE, value);
		rt2x00_set_field32(&reg, RFCSR_NUMBER_OF_BITS, 20);
@@ -174,6 +132,7 @@ static void rt2500pci_rf_write(struct rt2x00_dev *rt2x00dev,

		rt2x00pci_register_write(rt2x00dev, RFCSR, reg);
		rt2x00_rf_write(rt2x00dev, word, value);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
}
+60 −80
Original line number Diff line number Diff line
@@ -57,7 +57,7 @@ static inline void rt2500usb_register_read(struct rt2x00_dev *rt2x00dev,
	__le16 reg;
	rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
				      USB_VENDOR_REQUEST_IN, offset,
				      &reg, sizeof(u16), REGISTER_TIMEOUT);
				      &reg, sizeof(reg), REGISTER_TIMEOUT);
	*value = le16_to_cpu(reg);
}

@@ -68,7 +68,7 @@ static inline void rt2500usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
	__le16 reg;
	rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
				       USB_VENDOR_REQUEST_IN, offset,
				       &reg, sizeof(u16), REGISTER_TIMEOUT);
				       &reg, sizeof(reg), REGISTER_TIMEOUT);
	*value = le16_to_cpu(reg);
}

@@ -89,7 +89,7 @@ static inline void rt2500usb_register_write(struct rt2x00_dev *rt2x00dev,
	__le16 reg = cpu_to_le16(value);
	rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_WRITE,
				      USB_VENDOR_REQUEST_OUT, offset,
				      &reg, sizeof(u16), REGISTER_TIMEOUT);
				      &reg, sizeof(reg), REGISTER_TIMEOUT);
}

static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
@@ -99,7 +99,7 @@ static inline void rt2500usb_register_write_lock(struct rt2x00_dev *rt2x00dev,
	__le16 reg = cpu_to_le16(value);
	rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_WRITE,
				       USB_VENDOR_REQUEST_OUT, offset,
				       &reg, sizeof(u16), REGISTER_TIMEOUT);
				       &reg, sizeof(reg), REGISTER_TIMEOUT);
}

static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
@@ -112,21 +112,32 @@ static inline void rt2500usb_register_multiwrite(struct rt2x00_dev *rt2x00dev,
				      REGISTER_TIMEOUT16(length));
}

static u16 rt2500usb_bbp_check(struct rt2x00_dev *rt2x00dev)
static int rt2500usb_regbusy_read(struct rt2x00_dev *rt2x00dev,
				  const unsigned int offset,
				  struct rt2x00_field16 field,
				  u16 *reg)
{
	u16 reg;
	unsigned int i;

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2500usb_register_read_lock(rt2x00dev, PHY_CSR8, &reg);
		if (!rt2x00_get_field16(reg, PHY_CSR8_BUSY))
			break;
		rt2500usb_register_read_lock(rt2x00dev, offset, reg);
		if (!rt2x00_get_field16(*reg, field))
			return 1;
		udelay(REGISTER_BUSY_DELAY);
	}

	return reg;
	ERROR(rt2x00dev, "Indirect register access failed: "
	      "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
	*reg = ~0;

	return 0;
}

#define WAIT_FOR_BBP(__dev, __reg) \
	rt2500usb_regbusy_read((__dev), PHY_CSR8, PHY_CSR8_BUSY, (__reg))
#define WAIT_FOR_RF(__dev, __reg) \
	rt2500usb_regbusy_read((__dev), PHY_CSR10, PHY_CSR10_RF_BUSY, (__reg))

static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
				const unsigned int word, const u8 value)
{
@@ -135,30 +146,19 @@ static void rt2500usb_bbp_write(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500usb_bbp_check(rt2x00dev);
	if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
		goto exit_fail;

	/*
	 * Write the data into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field16(&reg, PHY_CSR7_DATA, value);
		rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
		rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 0);

		rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);

	return;

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "PHY_CSR8 register busy. Write failed.\n");
}

static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
@@ -169,65 +169,44 @@ static void rt2500usb_bbp_read(struct rt2x00_dev *rt2x00dev,
	mutex_lock(&rt2x00dev->csr_mutex);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500usb_bbp_check(rt2x00dev);
	if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
		goto exit_fail;

	/*
	 * Write the request into the BBP.
	 * Wait until the BBP becomes available, afterwards we
	 * can safely write the read request into the register.
	 * After the data has been written, we wait until hardware
	 * returns the correct value, if at any time the register
	 * doesn't become available in time, reg will be 0xffffffff
	 * which means we return 0xff to the caller.
	 */
	if (WAIT_FOR_BBP(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field16(&reg, PHY_CSR7_REG_ID, word);
		rt2x00_set_field16(&reg, PHY_CSR7_READ_CONTROL, 1);

		rt2500usb_register_write_lock(rt2x00dev, PHY_CSR7, reg);

	/*
	 * Wait until the BBP becomes ready.
	 */
	reg = rt2500usb_bbp_check(rt2x00dev);
	if (rt2x00_get_field16(reg, PHY_CSR8_BUSY))
		goto exit_fail;

		if (WAIT_FOR_BBP(rt2x00dev, &reg))
			rt2500usb_register_read_lock(rt2x00dev, PHY_CSR7, &reg);
	*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);

	mutex_unlock(&rt2x00dev->csr_mutex);
	}

	return;
	*value = rt2x00_get_field16(reg, PHY_CSR7_DATA);

exit_fail:
	mutex_unlock(&rt2x00dev->csr_mutex);

	ERROR(rt2x00dev, "PHY_CSR8 register busy. Read failed.\n");
	*value = 0xff;
}

static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,
			       const unsigned int word, const u32 value)
{
	u16 reg;
	unsigned int i;

	if (!word)
		return;

	mutex_lock(&rt2x00dev->csr_mutex);

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2500usb_register_read_lock(rt2x00dev, PHY_CSR10, &reg);
		if (!rt2x00_get_field16(reg, PHY_CSR10_RF_BUSY))
			goto rf_write;
		udelay(REGISTER_BUSY_DELAY);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
	ERROR(rt2x00dev, "PHY_CSR10 register busy. Write failed.\n");
	return;

rf_write:
	/*
	 * Wait until the RF becomes available, afterwards we
	 * can safely write the new data into the register.
	 */
	if (WAIT_FOR_RF(rt2x00dev, &reg)) {
		reg = 0;
		rt2x00_set_field16(&reg, PHY_CSR9_RF_VALUE, value);
		rt2500usb_register_write_lock(rt2x00dev, PHY_CSR9, reg);
@@ -240,6 +219,7 @@ static void rt2500usb_rf_write(struct rt2x00_dev *rt2x00dev,

		rt2500usb_register_write_lock(rt2x00dev, PHY_CSR10, reg);
		rt2x00_rf_write(rt2x00dev, word, value);
	}

	mutex_unlock(&rt2x00dev->csr_mutex);
}
+25 −0
Original line number Diff line number Diff line
@@ -31,6 +31,31 @@
#include "rt2x00.h"
#include "rt2x00pci.h"

/*
 * Register access.
 */
int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
			   const unsigned int offset,
			   const struct rt2x00_field32 field,
			   u32 *reg)
{
	unsigned int i;

	for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
		rt2x00pci_register_read(rt2x00dev, offset, reg);
		if (!rt2x00_get_field32(*reg, field))
			return 1;
		udelay(REGISTER_BUSY_DELAY);
	}

	ERROR(rt2x00dev, "Indirect register access failed: "
	      "offset=0x%.08x, value=0x%.08x\n", offset, *reg);
	*reg = ~0;

	return 0;
}
EXPORT_SYMBOL_GPL(rt2x00pci_regbusy_read);

/*
 * TX data handlers.
 */
+18 −0
Original line number Diff line number Diff line
@@ -76,6 +76,24 @@ rt2x00pci_register_multiwrite(struct rt2x00_dev *rt2x00dev,
	memcpy_toio(rt2x00dev->csr.base + offset, value, length);
}

/**
 * rt2x00pci_regbusy_read - Read from register with busy check
 * @rt2x00dev: Device pointer, see &struct rt2x00_dev.
 * @offset: Register offset
 * @field: Field to check if register is busy
 * @reg: Pointer to where register contents should be stored
 *
 * This function will read the given register, and checks if the
 * register is busy. If it is, it will sleep for a couple of
 * microseconds before reading the register again. If the register
 * is not read after a certain timeout, this function will return
 * FALSE.
 */
int rt2x00pci_regbusy_read(struct rt2x00_dev *rt2x00dev,
			   const unsigned int offset,
			   const struct rt2x00_field32 field,
			   u32 *reg);

/**
 * rt2x00pci_write_tx_data - Initialize data for TX operation
 * @entry: The entry where the frame is located
Loading