| 1 | --- a/drivers/net/wireless/hostap/hostap_ap.c |
| 2 | +++ b/drivers/net/wireless/hostap/hostap_ap.c |
| 3 | @@ -2335,13 +2335,13 @@ int prism2_ap_get_sta_qual(local_info_t |
| 4 | addr[count].sa_family = ARPHRD_ETHER; |
| 5 | memcpy(addr[count].sa_data, sta->addr, ETH_ALEN); |
| 6 | if (sta->last_rx_silence == 0) |
| 7 | - qual[count].qual = sta->last_rx_signal < 27 ? |
| 8 | - 0 : (sta->last_rx_signal - 27) * 92 / 127; |
| 9 | + qual[count].qual = (sta->last_rx_signal - 156) == 0 ? |
| 10 | + 0 : (sta->last_rx_signal - 156) * 92 / 64; |
| 11 | else |
| 12 | - qual[count].qual = sta->last_rx_signal - |
| 13 | - sta->last_rx_silence - 35; |
| 14 | - qual[count].level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); |
| 15 | - qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); |
| 16 | + qual[count].qual = (sta->last_rx_signal - |
| 17 | + sta->last_rx_silence) * 92 / 64; |
| 18 | + qual[count].level = sta->last_rx_signal; |
| 19 | + qual[count].noise = sta->last_rx_silence; |
| 20 | qual[count].updated = sta->last_rx_updated; |
| 21 | |
| 22 | sta->last_rx_updated = IW_QUAL_DBM; |
| 23 | @@ -2407,13 +2407,13 @@ int prism2_ap_translate_scan(struct net_ |
| 24 | memset(&iwe, 0, sizeof(iwe)); |
| 25 | iwe.cmd = IWEVQUAL; |
| 26 | if (sta->last_rx_silence == 0) |
| 27 | - iwe.u.qual.qual = sta->last_rx_signal < 27 ? |
| 28 | - 0 : (sta->last_rx_signal - 27) * 92 / 127; |
| 29 | + iwe.u.qual.qual = (sta->last_rx_signal -156) == 0 ? |
| 30 | + 0 : (sta->last_rx_signal - 156) * 92 / 64; |
| 31 | else |
| 32 | - iwe.u.qual.qual = sta->last_rx_signal - |
| 33 | - sta->last_rx_silence - 35; |
| 34 | - iwe.u.qual.level = HFA384X_LEVEL_TO_dBm(sta->last_rx_signal); |
| 35 | - iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); |
| 36 | + iwe.u.qual.qual = (sta->last_rx_signal - |
| 37 | + sta->last_rx_silence) * 92 / 64; |
| 38 | + iwe.u.qual.level = sta->last_rx_signal; |
| 39 | + iwe.u.qual.noise = sta->last_rx_silence; |
| 40 | iwe.u.qual.updated = sta->last_rx_updated; |
| 41 | iwe.len = IW_EV_QUAL_LEN; |
| 42 | current_ev = iwe_stream_add_event(info, current_ev, end_buf, |
| 43 | --- a/drivers/net/wireless/hostap/hostap_config.h |
| 44 | +++ b/drivers/net/wireless/hostap/hostap_config.h |
| 45 | @@ -45,4 +45,9 @@ |
| 46 | */ |
| 47 | /* #define PRISM2_NO_STATION_MODES */ |
| 48 | |
| 49 | +/* Enable TX power Setting functions |
| 50 | + * (min att = -128 , max att = 127) |
| 51 | + */ |
| 52 | +#define RAW_TXPOWER_SETTING |
| 53 | + |
| 54 | #endif /* HOSTAP_CONFIG_H */ |
| 55 | --- a/drivers/net/wireless/hostap/hostap.h |
| 56 | +++ b/drivers/net/wireless/hostap/hostap.h |
| 57 | @@ -90,6 +90,7 @@ extern const struct iw_handler_def hosta |
| 58 | extern const struct ethtool_ops prism2_ethtool_ops; |
| 59 | |
| 60 | int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); |
| 61 | +int hostap_restore_power(struct net_device *dev); |
| 62 | |
| 63 | |
| 64 | #endif /* HOSTAP_H */ |
| 65 | --- a/drivers/net/wireless/hostap/hostap_hw.c |
| 66 | +++ b/drivers/net/wireless/hostap/hostap_hw.c |
| 67 | @@ -932,6 +932,7 @@ static int hfa384x_set_rid(struct net_de |
| 68 | prism2_hw_reset(dev); |
| 69 | } |
| 70 | |
| 71 | + hostap_restore_power(dev); |
| 72 | return res; |
| 73 | } |
| 74 | |
| 75 | --- a/drivers/net/wireless/hostap/hostap_info.c |
| 76 | +++ b/drivers/net/wireless/hostap/hostap_info.c |
| 77 | @@ -432,6 +432,11 @@ static void handle_info_queue_linkstatus |
| 78 | } |
| 79 | |
| 80 | /* Get BSSID if we have a valid AP address */ |
| 81 | + |
| 82 | + if ( val == HFA384X_LINKSTATUS_CONNECTED || |
| 83 | + val == HFA384X_LINKSTATUS_DISCONNECTED ) |
| 84 | + hostap_restore_power(local->dev); |
| 85 | + |
| 86 | if (connected) { |
| 87 | netif_carrier_on(local->dev); |
| 88 | netif_carrier_on(local->ddev); |
| 89 | --- a/drivers/net/wireless/hostap/hostap_ioctl.c |
| 90 | +++ b/drivers/net/wireless/hostap/hostap_ioctl.c |
| 91 | @@ -1476,23 +1476,20 @@ static int prism2_txpower_hfa386x_to_dBm |
| 92 | val = 255; |
| 93 | |
| 94 | tmp = val; |
| 95 | - tmp >>= 2; |
| 96 | |
| 97 | - return -12 - tmp; |
| 98 | + return tmp; |
| 99 | } |
| 100 | |
| 101 | static u16 prism2_txpower_dBm_to_hfa386x(int val) |
| 102 | { |
| 103 | signed char tmp; |
| 104 | |
| 105 | - if (val > 20) |
| 106 | - return 128; |
| 107 | - else if (val < -43) |
| 108 | + if (val > 127) |
| 109 | return 127; |
| 110 | + else if (val < -128) |
| 111 | + return 128; |
| 112 | |
| 113 | tmp = val; |
| 114 | - tmp = -12 - tmp; |
| 115 | - tmp <<= 2; |
| 116 | |
| 117 | return (unsigned char) tmp; |
| 118 | } |
| 119 | @@ -4056,3 +4053,35 @@ int hostap_ioctl(struct net_device *dev, |
| 120 | |
| 121 | return ret; |
| 122 | } |
| 123 | + |
| 124 | +/* BUG FIX: Restore power setting value when lost due to F/W bug */ |
| 125 | + |
| 126 | +int hostap_restore_power(struct net_device *dev) |
| 127 | +{ |
| 128 | + struct hostap_interface *iface = netdev_priv(dev); |
| 129 | + local_info_t *local = iface->local; |
| 130 | + |
| 131 | + u16 val; |
| 132 | + int ret = 0; |
| 133 | + |
| 134 | + if (local->txpower_type == PRISM2_TXPOWER_OFF) { |
| 135 | + val = 0xff; /* use all standby and sleep modes */ |
| 136 | + ret = local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, |
| 137 | + HFA386X_CR_A_D_TEST_MODES2, |
| 138 | + &val, NULL); |
| 139 | + } |
| 140 | + |
| 141 | +#ifdef RAW_TXPOWER_SETTING |
| 142 | + if (local->txpower_type == PRISM2_TXPOWER_FIXED) { |
| 143 | + val = HFA384X_TEST_CFG_BIT_ALC; |
| 144 | + local->func->cmd(dev, HFA384X_CMDCODE_TEST | |
| 145 | + (HFA384X_TEST_CFG_BITS << 8), 0, &val, NULL); |
| 146 | + val = prism2_txpower_dBm_to_hfa386x(local->txpower); |
| 147 | + ret = (local->func->cmd(dev, HFA384X_CMDCODE_WRITEMIF, |
| 148 | + HFA386X_CR_MANUAL_TX_POWER, &val, NULL)); |
| 149 | + } |
| 150 | +#endif /* RAW_TXPOWER_SETTING */ |
| 151 | + return (ret ? -EOPNOTSUPP : 0); |
| 152 | +} |
| 153 | + |
| 154 | +EXPORT_SYMBOL(hostap_restore_power); |
| 155 | |