|
@@ -1270,25 +1270,32 @@ static int rt61pci_init_registers(struct rt2x00_dev *rt2x00dev)
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|
|
|
|
|
+static int rt61pci_wait_bbp_ready(struct rt2x00_dev *rt2x00dev)
|
|
{
|
|
{
|
|
unsigned int i;
|
|
unsigned int i;
|
|
- u16 eeprom;
|
|
|
|
- u8 reg_id;
|
|
|
|
u8 value;
|
|
u8 value;
|
|
|
|
|
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
|
rt61pci_bbp_read(rt2x00dev, 0, &value);
|
|
rt61pci_bbp_read(rt2x00dev, 0, &value);
|
|
if ((value != 0xff) && (value != 0x00))
|
|
if ((value != 0xff) && (value != 0x00))
|
|
- goto continue_csr_init;
|
|
|
|
- NOTICE(rt2x00dev, "Waiting for BBP register.\n");
|
|
|
|
|
|
+ return 0;
|
|
udelay(REGISTER_BUSY_DELAY);
|
|
udelay(REGISTER_BUSY_DELAY);
|
|
}
|
|
}
|
|
|
|
|
|
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
|
|
ERROR(rt2x00dev, "BBP register access failed, aborting.\n");
|
|
return -EACCES;
|
|
return -EACCES;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int rt61pci_init_bbp(struct rt2x00_dev *rt2x00dev)
|
|
|
|
+{
|
|
|
|
+ unsigned int i;
|
|
|
|
+ u16 eeprom;
|
|
|
|
+ u8 reg_id;
|
|
|
|
+ u8 value;
|
|
|
|
+
|
|
|
|
+ if (unlikely(rt61pci_wait_bbp_ready(rt2x00dev)))
|
|
|
|
+ return -EACCES;
|
|
|
|
|
|
-continue_csr_init:
|
|
|
|
rt61pci_bbp_write(rt2x00dev, 3, 0x00);
|
|
rt61pci_bbp_write(rt2x00dev, 3, 0x00);
|
|
rt61pci_bbp_write(rt2x00dev, 15, 0x30);
|
|
rt61pci_bbp_write(rt2x00dev, 15, 0x30);
|
|
rt61pci_bbp_write(rt2x00dev, 21, 0xc8);
|
|
rt61pci_bbp_write(rt2x00dev, 21, 0xc8);
|
|
@@ -1337,7 +1344,8 @@ static void rt61pci_toggle_rx(struct rt2x00_dev *rt2x00dev,
|
|
|
|
|
|
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
|
|
rt2x00pci_register_read(rt2x00dev, TXRX_CSR0, ®);
|
|
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX,
|
|
rt2x00_set_field32(®, TXRX_CSR0_DISABLE_RX,
|
|
- state == STATE_RADIO_RX_OFF);
|
|
|
|
|
|
+ (state == STATE_RADIO_RX_OFF) ||
|
|
|
|
+ (state == STATE_RADIO_RX_OFF_LINK));
|
|
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
|
|
rt2x00pci_register_write(rt2x00dev, TXRX_CSR0, reg);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1389,17 +1397,10 @@ static int rt61pci_enable_radio(struct rt2x00_dev *rt2x00dev)
|
|
/*
|
|
/*
|
|
* Initialize all registers.
|
|
* Initialize all registers.
|
|
*/
|
|
*/
|
|
- if (rt61pci_init_queues(rt2x00dev) ||
|
|
|
|
- rt61pci_init_registers(rt2x00dev) ||
|
|
|
|
- rt61pci_init_bbp(rt2x00dev)) {
|
|
|
|
- ERROR(rt2x00dev, "Register initialization failed.\n");
|
|
|
|
|
|
+ if (unlikely(rt61pci_init_queues(rt2x00dev) ||
|
|
|
|
+ rt61pci_init_registers(rt2x00dev) ||
|
|
|
|
+ rt61pci_init_bbp(rt2x00dev)))
|
|
return -EIO;
|
|
return -EIO;
|
|
- }
|
|
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Enable interrupts.
|
|
|
|
- */
|
|
|
|
- rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_ON);
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
* Enable RX.
|
|
* Enable RX.
|
|
@@ -1431,11 +1432,6 @@ static void rt61pci_disable_radio(struct rt2x00_dev *rt2x00dev)
|
|
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1);
|
|
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC2, 1);
|
|
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1);
|
|
rt2x00_set_field32(®, TX_CNTL_CSR_ABORT_TX_AC3, 1);
|
|
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
|
rt2x00pci_register_write(rt2x00dev, TX_CNTL_CSR, reg);
|
|
-
|
|
|
|
- /*
|
|
|
|
- * Disable interrupts.
|
|
|
|
- */
|
|
|
|
- rt61pci_toggle_irq(rt2x00dev, STATE_RADIO_IRQ_OFF);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
|
|
static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
|
|
@@ -1443,7 +1439,6 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
|
|
u32 reg;
|
|
u32 reg;
|
|
unsigned int i;
|
|
unsigned int i;
|
|
char put_to_sleep;
|
|
char put_to_sleep;
|
|
- char current_state;
|
|
|
|
|
|
|
|
put_to_sleep = (state != STATE_AWAKE);
|
|
put_to_sleep = (state != STATE_AWAKE);
|
|
|
|
|
|
@@ -1459,16 +1454,12 @@ static int rt61pci_set_state(struct rt2x00_dev *rt2x00dev, enum dev_state state)
|
|
*/
|
|
*/
|
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
|
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
|
|
rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®);
|
|
rt2x00pci_register_read(rt2x00dev, MAC_CSR12, ®);
|
|
- current_state =
|
|
|
|
- rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
|
|
|
|
- if (current_state == !put_to_sleep)
|
|
|
|
|
|
+ state = rt2x00_get_field32(reg, MAC_CSR12_BBP_CURRENT_STATE);
|
|
|
|
+ if (state == !put_to_sleep)
|
|
return 0;
|
|
return 0;
|
|
msleep(10);
|
|
msleep(10);
|
|
}
|
|
}
|
|
|
|
|
|
- NOTICE(rt2x00dev, "Device failed to enter state %d, "
|
|
|
|
- "current device state %d.\n", !put_to_sleep, current_state);
|
|
|
|
-
|
|
|
|
return -EBUSY;
|
|
return -EBUSY;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1486,11 +1477,13 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|
break;
|
|
break;
|
|
case STATE_RADIO_RX_ON:
|
|
case STATE_RADIO_RX_ON:
|
|
case STATE_RADIO_RX_ON_LINK:
|
|
case STATE_RADIO_RX_ON_LINK:
|
|
- rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_ON);
|
|
|
|
- break;
|
|
|
|
case STATE_RADIO_RX_OFF:
|
|
case STATE_RADIO_RX_OFF:
|
|
case STATE_RADIO_RX_OFF_LINK:
|
|
case STATE_RADIO_RX_OFF_LINK:
|
|
- rt61pci_toggle_rx(rt2x00dev, STATE_RADIO_RX_OFF);
|
|
|
|
|
|
+ rt61pci_toggle_rx(rt2x00dev, state);
|
|
|
|
+ break;
|
|
|
|
+ case STATE_RADIO_IRQ_ON:
|
|
|
|
+ case STATE_RADIO_IRQ_OFF:
|
|
|
|
+ rt61pci_toggle_irq(rt2x00dev, state);
|
|
break;
|
|
break;
|
|
case STATE_DEEP_SLEEP:
|
|
case STATE_DEEP_SLEEP:
|
|
case STATE_SLEEP:
|
|
case STATE_SLEEP:
|
|
@@ -1503,6 +1496,10 @@ static int rt61pci_set_device_state(struct rt2x00_dev *rt2x00dev,
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ if (unlikely(retval))
|
|
|
|
+ ERROR(rt2x00dev, "Device failed to enter state %d (%d).\n",
|
|
|
|
+ state, retval);
|
|
|
|
+
|
|
return retval;
|
|
return retval;
|
|
}
|
|
}
|
|
|
|
|