diff options
Diffstat (limited to 'drivers/net/wireless/zd1211rw/zd_chip.c')
-rw-r--r-- | drivers/net/wireless/zd1211rw/zd_chip.c | 137 |
1 files changed, 55 insertions, 82 deletions
diff --git a/drivers/net/wireless/zd1211rw/zd_chip.c b/drivers/net/wireless/zd1211rw/zd_chip.c index 7c4e32c..aa661b2 100644 --- a/drivers/net/wireless/zd1211rw/zd_chip.c +++ b/drivers/net/wireless/zd1211rw/zd_chip.c @@ -249,7 +249,6 @@ int zd_ioread16(struct zd_chip *chip, zd_addr_t addr, u16 *value) { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_ioread16_locked(chip, value, addr); mutex_unlock(&chip->mutex); @@ -260,7 +259,6 @@ int zd_ioread32(struct zd_chip *chip, zd_addr_t addr, u32 *value) { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_ioread32_locked(chip, value, addr); mutex_unlock(&chip->mutex); @@ -271,7 +269,6 @@ int zd_iowrite16(struct zd_chip *chip, zd_addr_t addr, u16 value) { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_iowrite16_locked(chip, value, addr); mutex_unlock(&chip->mutex); @@ -282,7 +279,6 @@ int zd_iowrite32(struct zd_chip *chip, zd_addr_t addr, u32 value) { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_iowrite32_locked(chip, value, addr); mutex_unlock(&chip->mutex); @@ -294,7 +290,6 @@ int zd_ioread32v(struct zd_chip *chip, const zd_addr_t *addresses, { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_ioread32v_locked(chip, values, addresses, count); mutex_unlock(&chip->mutex); @@ -306,7 +301,6 @@ int zd_iowrite32a(struct zd_chip *chip, const struct zd_ioreq32 *ioreqs, { int r; - ZD_ASSERT(!mutex_is_locked(&chip->mutex)); mutex_lock(&chip->mutex); r = zd_iowrite32a_locked(chip, ioreqs, count); mutex_unlock(&chip->mutex); @@ -331,13 +325,22 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type) chip->patch_cr157 = (value >> 13) & 0x1; chip->patch_6m_band_edge = (value >> 21) & 0x1; chip->new_phy_layout = (value >> 31) & 0x1; + chip->link_led = ((value >> 4) & 1) ? LED1 : LED2; + chip->supports_tx_led = 1; + if (value & (1 << 24)) { /* LED scenario */ + if (value & (1 << 29)) + chip->supports_tx_led = 0; + } dev_dbg_f(zd_chip_dev(chip), "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d " - "patch 6M %d new PHY %d\n", + "patch 6M %d new PHY %d link LED%d tx led %d\n", zd_rf_name(*rf_type), *rf_type, chip->pa_type, chip->patch_cck_gain, - chip->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout); + chip->patch_cr157, chip->patch_6m_band_edge, + chip->new_phy_layout, + chip->link_led == LED1 ? 1 : 2, + chip->supports_tx_led); return 0; error: *rf_type = 0; @@ -1181,7 +1184,7 @@ static int update_pwr_int(struct zd_chip *chip, u8 channel) u8 value = chip->pwr_int_values[channel - 1]; dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_int %#04x\n", channel, value); - return zd_iowrite32_locked(chip, value, CR31); + return zd_iowrite16_locked(chip, value, CR31); } static int update_pwr_cal(struct zd_chip *chip, u8 channel) @@ -1189,12 +1192,12 @@ static int update_pwr_cal(struct zd_chip *chip, u8 channel) u8 value = chip->pwr_cal_values[channel-1]; dev_dbg_f(zd_chip_dev(chip), "channel %d pwr_cal %#04x\n", channel, value); - return zd_iowrite32_locked(chip, value, CR68); + return zd_iowrite16_locked(chip, value, CR68); } static int update_ofdm_cal(struct zd_chip *chip, u8 channel) { - struct zd_ioreq32 ioreqs[3]; + struct zd_ioreq16 ioreqs[3]; ioreqs[0].addr = CR67; ioreqs[0].value = chip->ofdm_cal_values[OFDM_36M_INDEX][channel-1]; @@ -1206,7 +1209,7 @@ static int update_ofdm_cal(struct zd_chip *chip, u8 channel) dev_dbg_f(zd_chip_dev(chip), "channel %d ofdm_cal 36M %#04x 48M %#04x 54M %#04x\n", channel, ioreqs[0].value, ioreqs[1].value, ioreqs[2].value); - return zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); } static int update_channel_integration_and_calibration(struct zd_chip *chip, @@ -1218,7 +1221,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, if (r) return r; if (chip->is_zd1211b) { - static const struct zd_ioreq32 ioreqs[] = { + static const struct zd_ioreq16 ioreqs[] = { { CR69, 0x28 }, {}, { CR69, 0x2a }, @@ -1230,7 +1233,7 @@ static int update_channel_integration_and_calibration(struct zd_chip *chip, r = update_pwr_cal(chip, channel); if (r) return r; - r = zd_iowrite32a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); if (r) return r; } @@ -1252,7 +1255,7 @@ static int patch_cck_gain(struct zd_chip *chip) if (r) return r; dev_dbg_f(zd_chip_dev(chip), "patching value %x\n", value & 0xff); - return zd_iowrite32_locked(chip, value & 0xff, CR47); + return zd_iowrite16_locked(chip, value & 0xff, CR47); } int zd_chip_set_channel(struct zd_chip *chip, u8 channel) @@ -1295,89 +1298,60 @@ u8 zd_chip_get_channel(struct zd_chip *chip) return channel; } -static u16 led_mask(int led) +int zd_chip_control_leds(struct zd_chip *chip, enum led_status status) { - switch (led) { - case 1: - return LED1; - case 2: - return LED2; - default: - return 0; - } -} - -static int read_led_reg(struct zd_chip *chip, u16 *status) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_ioread16_locked(chip, status, CR_LED); -} - -static int write_led_reg(struct zd_chip *chip, u16 status) -{ - ZD_ASSERT(mutex_is_locked(&chip->mutex)); - return zd_iowrite16_locked(chip, status, CR_LED); -} + static const zd_addr_t a[] = { + FW_LINK_STATUS, + CR_LED, + }; -int zd_chip_led_status(struct zd_chip *chip, int led, enum led_status status) -{ - int r, ret; - u16 mask = led_mask(led); - u16 reg; + int r; + u16 v[ARRAY_SIZE(a)]; + struct zd_ioreq16 ioreqs[ARRAY_SIZE(a)] = { + [0] = { FW_LINK_STATUS }, + [1] = { CR_LED }, + }; + u16 other_led; - if (!mask) - return -EINVAL; mutex_lock(&chip->mutex); - r = read_led_reg(chip, ®); + r = zd_ioread16v_locked(chip, v, (const zd_addr_t *)a, ARRAY_SIZE(a)); if (r) - return r; + goto out; + + other_led = chip->link_led == LED1 ? LED2 : LED1; + switch (status) { - case LED_STATUS: - return (reg & mask) ? LED_ON : LED_OFF; case LED_OFF: - reg &= ~mask; - ret = LED_OFF; + ioreqs[0].value = FW_LINK_OFF; + ioreqs[1].value = v[1] & ~(LED1|LED2); break; - case LED_FLIP: - reg ^= mask; - ret = (reg&mask) ? LED_ON : LED_OFF; + case LED_SCANNING: + ioreqs[0].value = FW_LINK_OFF; + ioreqs[1].value = v[1] & ~other_led; + if (get_seconds() % 3 == 0) { + ioreqs[1].value &= ~chip->link_led; + } else { + ioreqs[1].value |= chip->link_led; + } break; - case LED_ON: - reg |= mask; - ret = LED_ON; + case LED_ASSOCIATED: + ioreqs[0].value = FW_LINK_TX; + ioreqs[1].value = v[1] & ~other_led; + ioreqs[1].value |= chip->link_led; break; default: - return -EINVAL; - } - r = write_led_reg(chip, reg); - if (r) { - ret = r; + r = -EINVAL; goto out; } -out: - mutex_unlock(&chip->mutex); - return r; -} - -int zd_chip_led_flip(struct zd_chip *chip, int led, - const unsigned int *phases_msecs, unsigned int count) -{ - int i, r; - enum led_status status; - r = zd_chip_led_status(chip, led, LED_STATUS); - if (r) - return r; - status = r; - for (i = 0; i < count; i++) { - r = zd_chip_led_status(chip, led, LED_FLIP); - if (r < 0) + if (v[0] != ioreqs[0].value || v[1] != ioreqs[1].value) { + r = zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs)); + if (r) goto out; - msleep(phases_msecs[i]); } - + r = 0; out: - zd_chip_led_status(chip, led, status); + mutex_unlock(&chip->mutex); return r; } @@ -1679,4 +1653,3 @@ int zd_rfwritev_cr_locked(struct zd_chip *chip, return 0; } - |