qual->false_cca = bbp;
}
+static inline void rt2400pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ rt2400pci_bbp_write(rt2x00dev, 13, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+}
+
static void rt2400pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt2400pci_bbp_write(rt2x00dev, 13, 0x08);
- rt2x00dev->link.vgc_level = 0x08;
+ rt2400pci_set_vgc(rt2x00dev, 0x08);
}
static void rt2400pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- u8 reg;
+ struct link *link = &rt2x00dev->link;
/*
* The link tuner should not run longer then 60 seconds,
* and should run once every 2 seconds.
*/
- if (rt2x00dev->link.count > 60 || !(rt2x00dev->link.count & 1))
+ if (link->count > 60 || !(link->count & 1))
return;
/*
* Base r13 link tuning on the false cca count.
*/
- rt2400pci_bbp_read(rt2x00dev, 13, ®);
-
- if (rt2x00dev->link.qual.false_cca > 512 && reg < 0x20) {
- rt2400pci_bbp_write(rt2x00dev, 13, ++reg);
- rt2x00dev->link.vgc_level = reg;
- } else if (rt2x00dev->link.qual.false_cca < 100 && reg > 0x08) {
- rt2400pci_bbp_write(rt2x00dev, 13, --reg);
- rt2x00dev->link.vgc_level = reg;
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < 0x20))
+ rt2400pci_set_vgc(rt2x00dev, ++link->vgc_level);
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > 0x08))
+ rt2400pci_set_vgc(rt2x00dev, --link->vgc_level);
}
/*
qual->false_cca = rt2x00_get_field32(reg, CNT3_FALSE_CCA);
}
+static inline void rt2500pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level_reg != vgc_level) {
+ rt2500pci_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt2500pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt2500pci_bbp_write(rt2x00dev, 17, 0x48);
- rt2x00dev->link.vgc_level = 0x48;
+ rt2500pci_set_vgc(rt2x00dev, 0x48);
}
static void rt2500pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
/*
* To prevent collisions with MAC ASIC on chipsets
* seconds while being associated.
*/
if (rt2x00_rev(&rt2x00dev->chip) < RT2560_VERSION_D &&
- rt2x00dev->intf_associated &&
- rt2x00dev->link.count > 20)
+ rt2x00dev->intf_associated && link->count > 20)
return;
- rt2500pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Chipset versions C and lower should directly continue
* to the dynamic CCA tuning. Chipset version D and higher
* then corrupt the R17 tuning. To remidy this the tuning should
* be stopped (While making sure the R17 value will not exceed limits)
*/
- if (rssi < -80 && rt2x00dev->link.count > 20) {
- if (r17 >= 0x41) {
- r17 = rt2x00dev->link.vgc_level;
- rt2500pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if (rssi < -80 && link->count > 20) {
+ if (link->vgc_level_reg >= 0x41)
+ rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
return;
}
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != 0x50)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x50);
+ rt2500pci_set_vgc(rt2x00dev, 0x50);
return;
}
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- if (r17 != 0x41)
- rt2500pci_bbp_write(rt2x00dev, 17, 0x41);
+ rt2500pci_set_vgc(rt2x00dev, 0x41);
return;
}
* Leave short or middle distance condition, restore r17
* to the dynamic tuning range.
*/
- if (r17 >= 0x41) {
- rt2500pci_bbp_write(rt2x00dev, 17, rt2x00dev->link.vgc_level);
+ if (link->vgc_level_reg >= 0x41) {
+ rt2500pci_set_vgc(rt2x00dev, link->vgc_level);
return;
}
* R17 is inside the dynamic tuning range,
* start tuning the link based on the false cca counter.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < 0x40) {
- rt2500pci_bbp_write(rt2x00dev, 17, ++r17);
- rt2x00dev->link.vgc_level = r17;
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > 0x32) {
- rt2500pci_bbp_write(rt2x00dev, 17, --r17);
- rt2x00dev->link.vgc_level = r17;
+ if (link->qual.false_cca > 512 && link->vgc_level_reg < 0x40) {
+ rt2500pci_set_vgc(rt2x00dev, ++link->vgc_level_reg);
+ link->vgc_level = link->vgc_level_reg;
+ } else if (link->qual.false_cca < 100 && link->vgc_level_reg > 0x32) {
+ rt2500pci_set_vgc(rt2x00dev, --link->vgc_level_reg);
+ link->vgc_level = link->vgc_level_reg;
}
}
struct link_ant ant;
/*
- * Active VGC level
+ * Active VGC level (for false cca tuning)
*/
- int vgc_level;
+ u8 vgc_level;
+
+ /*
+ * VGC level as configured in register
+ */
+ u8 vgc_level_reg;
/*
* Work structure for scheduling periodic link tuning.
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
+static inline void rt61pci_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level != vgc_level) {
+ rt61pci_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt61pci_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt61pci_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt61pci_set_vgc(rt2x00dev, 0x20);
}
static void rt61pci_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
u8 up_bound;
u8 low_bound;
- rt61pci_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
* Special big-R17 for very short distance
*/
if (rssi >= -35) {
- if (r17 != 0x60)
- rt61pci_bbp_write(rt2x00dev, 17, 0x60);
+ rt61pci_set_vgc(rt2x00dev, 0x60);
return;
}
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != up_bound)
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ rt61pci_set_vgc(rt2x00dev, up_bound);
return;
}
* Special big-R17 for middle-short distance
*/
if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ rt61pci_set_vgc(rt2x00dev, low_bound + 0x10);
return;
}
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- low_bound += 0x08;
- if (r17 != low_bound)
- rt61pci_bbp_write(rt2x00dev, 17, low_bound);
+ rt61pci_set_vgc(rt2x00dev, low_bound + 0x08);
return;
}
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt61pci_bbp_write(rt2x00dev, 17, up_bound);
+ if (link->vgc_level > up_bound) {
+ rt61pci_set_vgc(rt2x00dev, up_bound);
return;
}
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- if (++r17 > up_bound)
- r17 = up_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- if (--r17 < low_bound)
- r17 = low_bound;
- rt61pci_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+ rt61pci_set_vgc(rt2x00dev, ++link->vgc_level);
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+ rt61pci_set_vgc(rt2x00dev, --link->vgc_level);
}
/*
qual->false_cca = rt2x00_get_field32(reg, STA_CSR1_FALSE_CCA_ERROR);
}
+static inline void rt73usb_set_vgc(struct rt2x00_dev *rt2x00dev, u8 vgc_level)
+{
+ if (rt2x00dev->link.vgc_level != vgc_level) {
+ rt73usb_bbp_write(rt2x00dev, 17, vgc_level);
+ rt2x00dev->link.vgc_level = vgc_level;
+ rt2x00dev->link.vgc_level_reg = vgc_level;
+ }
+}
+
static void rt73usb_reset_tuner(struct rt2x00_dev *rt2x00dev)
{
- rt73usb_bbp_write(rt2x00dev, 17, 0x20);
- rt2x00dev->link.vgc_level = 0x20;
+ rt73usb_set_vgc(rt2x00dev, 0x20);
}
static void rt73usb_link_tuner(struct rt2x00_dev *rt2x00dev)
{
- int rssi = rt2x00_get_link_rssi(&rt2x00dev->link);
- u8 r17;
+ struct link *link = &rt2x00dev->link;
+ int rssi = rt2x00_get_link_rssi(link);
u8 up_bound;
u8 low_bound;
- rt73usb_bbp_read(rt2x00dev, 17, &r17);
-
/*
* Determine r17 bounds.
*/
* Special big-R17 for very short distance
*/
if (rssi > -35) {
- if (r17 != 0x60)
- rt73usb_bbp_write(rt2x00dev, 17, 0x60);
+ rt73usb_set_vgc(rt2x00dev, 0x60);
return;
}
* Special big-R17 for short distance
*/
if (rssi >= -58) {
- if (r17 != up_bound)
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ rt73usb_set_vgc(rt2x00dev, up_bound);
return;
}
* Special big-R17 for middle-short distance
*/
if (rssi >= -66) {
- low_bound += 0x10;
- if (r17 != low_bound)
- rt73usb_bbp_write(rt2x00dev, 17, low_bound);
+ rt73usb_set_vgc(rt2x00dev, low_bound + 0x10);
return;
}
* Special mid-R17 for middle distance
*/
if (rssi >= -74) {
- if (r17 != (low_bound + 0x10))
- rt73usb_bbp_write(rt2x00dev, 17, low_bound + 0x08);
+ rt73usb_set_vgc(rt2x00dev, low_bound + 0x08);
return;
}
if (low_bound > up_bound)
up_bound = low_bound;
- if (r17 > up_bound) {
- rt73usb_bbp_write(rt2x00dev, 17, up_bound);
+ if (link->vgc_level > up_bound) {
+ rt73usb_set_vgc(rt2x00dev, up_bound);
return;
}
* r17 does not yet exceed upper limit, continue and base
* the r17 tuning on the false CCA count.
*/
- if (rt2x00dev->link.qual.false_cca > 512 && r17 < up_bound) {
- r17 += 4;
- if (r17 > up_bound)
- r17 = up_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- } else if (rt2x00dev->link.qual.false_cca < 100 && r17 > low_bound) {
- r17 -= 4;
- if (r17 < low_bound)
- r17 = low_bound;
- rt73usb_bbp_write(rt2x00dev, 17, r17);
- }
+ if ((link->qual.false_cca > 512) && (link->vgc_level < up_bound))
+ rt73usb_set_vgc(rt2x00dev,
+ min_t(u8, link->vgc_level + 4, up_bound));
+ else if ((link->qual.false_cca < 100) && (link->vgc_level > low_bound))
+ rt73usb_set_vgc(rt2x00dev,
+ max_t(u8, link->vgc_level - 4, low_bound));
}
/*