diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index c57d39002bfb01872f56fe29499a4c37447d8fb6..7c97761034e7a47b7a70cd5251f6bddc5cdddf9a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c @@ -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, diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h index 6721d7dd32bc67222f2feae5730fc6f2050cc610..ba51016494031611096b423ba300d7fc9f6f24fa 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.h +++ b/drivers/net/wireless/rt2x00/rt61pci.h @@ -1083,7 +1083,7 @@ struct hw_pairwise_ta_entry { /* * R77 */ -#define BBP_R77_PAIR FIELD8(0x03) +#define BBP_R77_TX_ANTENNA FIELD8(0x03) /* * RF registers diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c index e3d5e78661ea64c3aa670ddacb7ef28766a8964e..b9d5310c386f503a8c8dbf85d0e00f05152d57f1 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.c +++ b/drivers/net/wireless/rt2x00/rt73usb.c @@ -408,6 +408,29 @@ static void rt73usb_config_antenna_5x(struct rt2x00_dev *rt2x00dev, rt2x00_set_field8(&r3, BBP_R3_SMART_MODE, 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; + } + + /* + * Configure the RX antenna. + */ switch (ant->rx) { case ANTENNA_HW_DIVERSITY: rt2x00_set_field8(&r4, BBP_R4_RX_ANTENNA, 2); @@ -417,11 +440,6 @@ static void rt73usb_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: /* @@ -433,11 +451,6 @@ static void rt73usb_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; } @@ -461,13 +474,35 @@ static void rt73usb_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: /* @@ -478,7 +513,6 @@ static void rt73usb_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; } diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h index f0951519f74b32592077587d22dfa304d5b9e9fe..13f479c7da0d5023e619feb5dbc06601ba661689 100644 --- a/drivers/net/wireless/rt2x00/rt73usb.h +++ b/drivers/net/wireless/rt2x00/rt73usb.h @@ -719,7 +719,7 @@ struct hw_pairwise_ta_entry { /* * R77 */ -#define BBP_R77_PAIR FIELD8(0x03) +#define BBP_R77_TX_ANTENNA FIELD8(0x03) /* * RF registers