|
@@ -424,6 +424,29 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
|
|
|
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE,
|
|
|
!rt2x00_rf(&rt2x00dev->chip, RF5225));
|
|
|
|
|
|
+ /*
|
|
|
+ * Configure the TX antenna.
|
|
|
+ */
|
|
|
+ switch (ant->tx) {
|
|
|
+ case ANTENNA_A:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
|
|
|
+ break;
|
|
|
+ case ANTENNA_SW_DIVERSITY:
|
|
|
+ case ANTENNA_HW_DIVERSITY:
|
|
|
+ /*
|
|
|
+ * NOTE: We should never come here because rt2x00lib is
|
|
|
+ * supposed to catch this and send us the correct antenna
|
|
|
+ * explicitely. However we are nog going to bug about this.
|
|
|
+ * Instead, just default to antenna B.
|
|
|
+ */
|
|
|
+ case ANTENNA_B:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Configure the RX antenna.
|
|
|
+ */
|
|
|
switch (ant->rx) {
|
|
|
case ANTENNA_HW_DIVERSITY:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
|
|
@@ -433,11 +456,6 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
|
|
|
case ANTENNA_A:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
|
-
|
|
|
- if (rt2x00dev->curr_hwmode == HWMODE_A)
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
|
|
|
- else
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
break;
|
|
|
case ANTENNA_SW_DIVERSITY:
|
|
|
/*
|
|
@@ -449,11 +467,6 @@ static void rt61pci_config_antenna_5x(struct rt2x00_dev *rt2x00dev,
|
|
|
case ANTENNA_B:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
|
-
|
|
|
- if (rt2x00dev->curr_hwmode == HWMODE_A)
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
- else
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -478,13 +491,35 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
|
|
|
!test_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags));
|
|
|
|
|
|
+ /*
|
|
|
+ * Configure the TX antenna.
|
|
|
+ */
|
|
|
+ switch (ant->tx) {
|
|
|
+ case ANTENNA_A:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
|
|
|
+ break;
|
|
|
+ case ANTENNA_SW_DIVERSITY:
|
|
|
+ case ANTENNA_HW_DIVERSITY:
|
|
|
+ /*
|
|
|
+ * NOTE: We should never come here because rt2x00lib is
|
|
|
+ * supposed to catch this and send us the correct antenna
|
|
|
+ * explicitely. However we are nog going to bug about this.
|
|
|
+ * Instead, just default to antenna B.
|
|
|
+ */
|
|
|
+ case ANTENNA_B:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * Configure the RX antenna.
|
|
|
+ */
|
|
|
switch (ant->rx) {
|
|
|
case ANTENNA_HW_DIVERSITY:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
|
|
|
break;
|
|
|
case ANTENNA_A:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
break;
|
|
|
case ANTENNA_SW_DIVERSITY:
|
|
|
/*
|
|
@@ -495,7 +530,6 @@ static void rt61pci_config_antenna_2x(struct rt2x00_dev *rt2x00dev,
|
|
|
*/
|
|
|
case ANTENNA_B:
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -530,74 +564,75 @@ static void rt61pci_config_antenna_2529(struct rt2x00_dev *rt2x00dev,
|
|
|
u8 r3;
|
|
|
u8 r4;
|
|
|
u8 r77;
|
|
|
+ u8 rx_ant;
|
|
|
|
|
|
rt61pci_bbp_read(rt2x00dev, 3, &r3);
|
|
|
rt61pci_bbp_read(rt2x00dev, 4, &r4);
|
|
|
rt61pci_bbp_read(rt2x00dev, 77, &r77);
|
|
|
+
|
|
|
rt2x00_eeprom_read(rt2x00dev, EEPROM_NIC, &eeprom);
|
|
|
+ rx_ant = !!(rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) & 2);
|
|
|
|
|
|
rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 0);
|
|
|
|
|
|
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
|
|
|
- rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 1);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
|
|
|
- } else if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY)) {
|
|
|
- if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED) >= 2) {
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
- rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
- }
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
|
|
|
- } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
|
|
|
- rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
|
+ /*
|
|
|
+ * Configure the TX antenna.
|
|
|
+ */
|
|
|
+ switch (ant->tx) {
|
|
|
+ case ANTENNA_A:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 0);
|
|
|
+ break;
|
|
|
+ case ANTENNA_SW_DIVERSITY:
|
|
|
+ case ANTENNA_HW_DIVERSITY:
|
|
|
+ /*
|
|
|
+ * NOTE: We should never come here because rt2x00lib is
|
|
|
+ * supposed to catch this and send us the correct antenna
|
|
|
+ * explicitely. However we are nog going to bug about this.
|
|
|
+ * Instead, just default to antenna B.
|
|
|
+ */
|
|
|
+ case ANTENNA_B:
|
|
|
+ rt2x00_set_field8(&r77, BBP_R77_TX_ANTENNA, 3);
|
|
|
+ break;
|
|
|
+ }
|
|
|
|
|
|
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
|
|
|
- case 0:
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
|
|
|
- break;
|
|
|
- case 1:
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
|
|
|
- break;
|
|
|
- }
|
|
|
- } else if (!rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY) &&
|
|
|
- !rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY)) {
|
|
|
+ /*
|
|
|
+ * Configure the RX antenna.
|
|
|
+ */
|
|
|
+ switch (ant->rx) {
|
|
|
+ case ANTENNA_A:
|
|
|
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 0, rx_ant);
|
|
|
+ break;
|
|
|
+ case ANTENNA_SW_DIVERSITY:
|
|
|
+ case ANTENNA_HW_DIVERSITY:
|
|
|
+ /*
|
|
|
+ * NOTE: We should never come here because rt2x00lib is
|
|
|
+ * supposed to catch this and send us the correct antenna
|
|
|
+ * explicitely. However we are nog going to bug about this.
|
|
|
+ * Instead, just default to antenna B.
|
|
|
+ */
|
|
|
+ case ANTENNA_B:
|
|
|
+ rt61pci_config_antenna_2529_rx(rt2x00dev, 1, rx_ant);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ /*
|
|
|
+ * FIXME: We are using the default antenna setup to
|
|
|
+ * determine the remaining settings. This because we
|
|
|
+ * need to know what the EEPROM indicated.
|
|
|
+ * It is however unclear if this is required, and overall
|
|
|
+ * using the default antenna settings here is incorrect
|
|
|
+ * since mac80211 might have told us to use fixed settings.
|
|
|
+ */
|
|
|
+ if (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY)
|
|
|
+ rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2);
|
|
|
+ else
|
|
|
rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 1);
|
|
|
- rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END, 0);
|
|
|
|
|
|
- switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
|
|
|
- case 0:
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
|
|
|
- rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 1);
|
|
|
- break;
|
|
|
- case 1:
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 0);
|
|
|
- rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 0);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
- rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 0, 0);
|
|
|
- break;
|
|
|
- case 3:
|
|
|
- rt2x00_set_field8(&r77, BBP_R77_PAIR, 3);
|
|
|
- rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
- rt61pci_config_antenna_2529_rx(rt2x00dev, 1, 1);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
+ rt2x00_set_field8(&r4, BBP_R4_RX_FRAME_END,
|
|
|
+ (rt2x00dev->default_ant.tx == ANTENNA_SW_DIVERSITY) &&
|
|
|
+ (rt2x00dev->default_ant.rx == ANTENNA_SW_DIVERSITY));
|
|
|
|
|
|
+ rt61pci_bbp_write(rt2x00dev, 77, r77);
|
|
|
rt61pci_bbp_write(rt2x00dev, 3, r3);
|
|
|
rt61pci_bbp_write(rt2x00dev, 4, r4);
|
|
|
}
|
|
@@ -2030,6 +2065,12 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
+ /*
|
|
|
+ * Determine number of antenna's.
|
|
|
+ */
|
|
|
+ if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
|
|
|
+ __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
|
|
|
+
|
|
|
/*
|
|
|
* Identify default antenna configuration.
|
|
|
*/
|
|
@@ -2044,12 +2085,6 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|
|
if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_FRAME_TYPE))
|
|
|
__set_bit(CONFIG_FRAME_TYPE, &rt2x00dev->flags);
|
|
|
|
|
|
- /*
|
|
|
- * Determine number of antenna's.
|
|
|
- */
|
|
|
- if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
|
|
|
- __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
|
|
|
-
|
|
|
/*
|
|
|
* Detect if this device has an hardware controlled radio.
|
|
|
*/
|
|
@@ -2077,6 +2112,38 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
|
|
|
if (rt2x00_get_field16(eeprom, EEPROM_NIC_EXTERNAL_LNA_BG))
|
|
|
__set_bit(CONFIG_EXTERNAL_LNA_BG, &rt2x00dev->flags);
|
|
|
|
|
|
+ /*
|
|
|
+ * When working with a RF2529 chip without double antenna
|
|
|
+ * the antenna settings should be gathered from the NIC
|
|
|
+ * eeprom word.
|
|
|
+ */
|
|
|
+ if (rt2x00_rf(&rt2x00dev->chip, RF2529) &&
|
|
|
+ !test_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags)) {
|
|
|
+ switch (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_RX_FIXED)) {
|
|
|
+ case 0:
|
|
|
+ rt2x00dev->default_ant.tx = ANTENNA_B;
|
|
|
+ rt2x00dev->default_ant.rx = ANTENNA_A;
|
|
|
+ break;
|
|
|
+ case 1:
|
|
|
+ rt2x00dev->default_ant.tx = ANTENNA_B;
|
|
|
+ rt2x00dev->default_ant.rx = ANTENNA_B;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ rt2x00dev->default_ant.tx = ANTENNA_A;
|
|
|
+ rt2x00dev->default_ant.rx = ANTENNA_A;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ rt2x00dev->default_ant.tx = ANTENNA_A;
|
|
|
+ rt2x00dev->default_ant.rx = ANTENNA_B;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_TX_DIVERSITY))
|
|
|
+ rt2x00dev->default_ant.tx = ANTENNA_SW_DIVERSITY;
|
|
|
+ if (rt2x00_get_field16(eeprom, EEPROM_NIC_ENABLE_DIVERSITY))
|
|
|
+ rt2x00dev->default_ant.rx = ANTENNA_SW_DIVERSITY;
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
* Store led settings, for correct led behaviour.
|
|
|
* If the eeprom value is invalid,
|