Merge branch 'upstream-fixes' into upstream
[pandora-kernel.git] / drivers / net / wireless / zd1211rw / zd_chip.c
index aa79282..7c4e32c 100644 (file)
@@ -42,12 +42,11 @@ void zd_chip_init(struct zd_chip *chip,
 
 void zd_chip_clear(struct zd_chip *chip)
 {
-       mutex_lock(&chip->mutex);
+       ZD_ASSERT(!mutex_is_locked(&chip->mutex));
        zd_usb_clear(&chip->usb);
        zd_rf_clear(&chip->rf);
-       mutex_unlock(&chip->mutex);
        mutex_destroy(&chip->mutex);
-       memset(chip, 0, sizeof(*chip));
+       ZD_MEMCLEAR(chip, sizeof(*chip));
 }
 
 static int scnprint_mac_oui(const u8 *addr, char *buffer, size_t size)
@@ -68,10 +67,11 @@ static int scnprint_id(struct zd_chip *chip, char *buffer, size_t size)
        i += scnprint_mac_oui(chip->e2p_mac, buffer+i, size-i);
        i += scnprintf(buffer+i, size-i, " ");
        i += zd_rf_scnprint_id(&chip->rf, buffer+i, size-i);
-       i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c", chip->pa_type,
+       i += scnprintf(buffer+i, size-i, " pa%1x %c%c%c%c", chip->pa_type,
                chip->patch_cck_gain ? 'g' : '-',
                chip->patch_cr157 ? '7' : '-',
-               chip->patch_6m_band_edge ? '6' : '-');
+               chip->patch_6m_band_edge ? '6' : '-',
+               chip->new_phy_layout ? 'N' : '-');
        return i;
 }
 
@@ -330,13 +330,14 @@ static int read_pod(struct zd_chip *chip, u8 *rf_type)
        chip->patch_cck_gain = (value >> 8) & 0x1;
        chip->patch_cr157 = (value >> 13) & 0x1;
        chip->patch_6m_band_edge = (value >> 21) & 0x1;
+       chip->new_phy_layout = (value >> 31) & 0x1;
 
        dev_dbg_f(zd_chip_dev(chip),
                "RF %s %#01x PA type %#01x patch CCK %d patch CR157 %d "
-               "patch 6M %d\n",
+               "patch 6M %d new PHY %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->patch_cr157, chip->patch_6m_band_edge, chip->new_phy_layout);
        return 0;
 error:
        *rf_type = 0;
@@ -344,6 +345,7 @@ error:
        chip->patch_cck_gain = 0;
        chip->patch_cr157 = 0;
        chip->patch_6m_band_edge = 0;
+       chip->new_phy_layout = 0;
        return r;
 }
 
@@ -717,7 +719,7 @@ static int zd1211b_hw_reset_phy(struct zd_chip *chip)
                { CR21,  0x0e }, { CR22,  0x23 }, { CR23,  0x90 },
                { CR24,  0x14 }, { CR25,  0x40 }, { CR26,  0x10 },
                { CR27,  0x10 }, { CR28,  0x7f }, { CR29,  0x80 },
-               { CR30,  0x49 }, /* jointly decoder, no ASIC */
+               { CR30,  0x4b }, /* ASIC/FWT, no jointly decoder */
                { CR31,  0x60 }, { CR32,  0x43 }, { CR33,  0x08 },
                { CR34,  0x06 }, { CR35,  0x0a }, { CR36,  0x00 },
                { CR37,  0x00 }, { CR38,  0x38 }, { CR39,  0x0c },
@@ -807,7 +809,6 @@ static int zd1211_hw_init_hmac(struct zd_chip *chip)
                { CR_ACK_TIMEOUT_EXT,           0x80 },
                { CR_ADDA_PWR_DWN,              0x00 },
                { CR_ACK_TIME_80211,            0x100 },
-               { CR_IFS_VALUE,                 0x547c032 },
                { CR_RX_PE_DELAY,               0x70 },
                { CR_PS_CTRL,                   0x10000000 },
                { CR_RTS_CTS_RATE,              0x02030203 },
@@ -854,11 +855,10 @@ static int zd1211b_hw_init_hmac(struct zd_chip *chip)
                { CR_ACK_TIMEOUT_EXT,           0x80 },
                { CR_ADDA_PWR_DWN,              0x00 },
                { CR_ACK_TIME_80211,            0x100 },
-               { CR_IFS_VALUE,                 0x547c032 },
                { CR_RX_PE_DELAY,               0x70 },
                { CR_PS_CTRL,                   0x10000000 },
                { CR_RTS_CTS_RATE,              0x02030203 },
-               { CR_RX_THRESHOLD,              0x000c0640 },
+               { CR_RX_THRESHOLD,              0x000c0eff, },
                { CR_AFTER_PNP,                 0x1 },
                { CR_WEP_PROTECT,               0x114 },
        };
@@ -970,10 +970,15 @@ static int hw_init(struct zd_chip *chip)
        r = hw_init_hmac(chip);
        if (r)
                return r;
-       r = set_beacon_interval(chip, 100);
+
+       /* Although the vendor driver defaults to a different value during
+        * init, it overwrites the IFS value with the following every time
+        * the channel changes. We should aim to be more intelligent... */
+       r = zd_iowrite32_locked(chip, IFS_VALUE_DEFAULT, CR_IFS_VALUE);
        if (r)
                return r;
-       return 0;
+
+       return set_beacon_interval(chip, 100);
 }
 
 #ifdef DEBUG
@@ -1644,3 +1649,34 @@ int zd_rfwritev_locked(struct zd_chip *chip,
 
        return 0;
 }
+
+/*
+ * We can optionally program the RF directly through CR regs, if supported by
+ * the hardware. This is much faster than the older method.
+ */
+int zd_rfwrite_cr_locked(struct zd_chip *chip, u32 value)
+{
+       struct zd_ioreq16 ioreqs[] = {
+               { CR244, (value >> 16) & 0xff },
+               { CR243, (value >>  8) & 0xff },
+               { CR242,  value        & 0xff },
+       };
+       ZD_ASSERT(mutex_is_locked(&chip->mutex));
+       return zd_iowrite16a_locked(chip, ioreqs, ARRAY_SIZE(ioreqs));
+}
+
+int zd_rfwritev_cr_locked(struct zd_chip *chip,
+                         const u32 *values, unsigned int count)
+{
+       int r;
+       unsigned int i;
+
+       for (i = 0; i < count; i++) {
+               r = zd_rfwrite_cr_locked(chip, values[i]);
+               if (r)
+                       return r;
+       }
+
+       return 0;
+}
+