Hi Samuel
On Wed, Jul 06, 2011 at 07:49:57AM +0000, Chang, Samuel wrote:
> Subject: Correct the cfg80211 bss signal strenth format
>
> BOO # 10279 - Strength in list-service is always 100, which is wrong
>
> ar6003_cfg80211_rssi_signal_fix.patch is based on an accepted patch -
> kernel-adaptation-mrst-2.6.37.6-92.2 and ar6003_cfg_syncup_v2.patch.
>
> Signed-off-by: Samuel Chang <[email protected]>
Acked-by: Samuel Ortiz <[email protected]>
Kristen, would you mind pushing that one (i.e.
ar6003_cfg80211_rssi_signal_fix.patch) forward ?
Cheers,
Samuel.
> diff -ruN
> kernel-2.6.37.6-24.3_cfg80211_fix_patch_1/drivers/staging/ar6003/os/linux/cfg80211.c
>
> kernel-2.6.37.6-24.3_cfg80211_rssi_patch_1.1/drivers/staging/ar6003/os/linux/cfg80211.c
> ---
> kernel-2.6.37.6-24.3_cfg80211_fix_patch_1/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-06-29 11:09:42.519414000 +0800
> +++
> kernel-2.6.37.6-24.3_cfg80211_rssi_patch_1.1/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-07-06 14:58:11.257184423 +0800
> @@ -804,7 +804,7 @@
>
> freq = cie->ie_chan;
> channel = ieee80211_get_channel(wiphy, freq);
> - signal = ni->ni_snr * 100;
> + signal = ni->ni_snr * 100 - 9500;
>
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
> ("%s: bssid %02x:%02x:%02x:%02x:%02x:%02x channel %d
> freq %d size %d\n",
> diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h
> --- kernel-2.6.37.6-92.2/drivers/staging/ar6003/include/common/wmi.h
> 2011-06-15 02:06:12.863498128 +0800
> +++
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/include/common/wmi.h
> 2011-06-29 08:31:52.440455388 +0800
> @@ -552,6 +552,11 @@
> LEAP_AUTH = 0x04, /* different from IEEE_AUTH_MODE
> definitions */
> } DOT11_AUTH_MODE;
>
> +enum {
> + AUTH_IDLE,
> + AUTH_OPEN_IN_PROGRESS,
> +};
> +
> typedef enum {
> NONE_AUTH = 0x01,
> WPA_AUTH = 0x02,
> diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c
> --- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/ar6000_drv.c
> 2011-06-15 02:06:12.859498118 +0800
> +++
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/ar6000_drv.c
> 2011-06-29 09:34:20.847042734 +0800
> @@ -1946,6 +1946,8 @@
> SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
> wdev->netdev = dev;
> arPriv->arNetworkType = INFRA_NETWORK;
> + ar->smeState = SME_DISCONNECTED;
> + arPriv->arAutoAuthStage = AUTH_IDLE;
> #endif /* ATH6K_CONFIG_CFG80211 */
>
> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
> diff -ruN kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c
> --- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-06-28 20:57:34.000000000 +0800
> +++
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-06-29 11:09:42.519414972 +0800
> @@ -169,6 +169,10 @@
> case NL80211_AUTHTYPE_NETWORK_EAP:
> arPriv->arDot11AuthMode = LEAP_AUTH;
> break;
> + case NL80211_AUTHTYPE_AUTOMATIC:
> + arPriv->arDot11AuthMode = OPEN_AUTH;
> + arPriv->arAutoAuthStage = AUTH_OPEN_IN_PROGRESS;
> + break;
> default:
> arPriv->arDot11AuthMode = OPEN_AUTH;
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
> @@ -249,6 +253,7 @@
> unsigned char *ie = sme->ie;
>
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
> + ar->smeState = SME_CONNECTING;
>
> if(ar->arWmiReady == FALSE) {
> AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n",
> __func__));
> @@ -302,12 +307,6 @@
> return -EINTR;
> }
> }
> - up(&arPriv->arPrivSem);
> -
> - if(down_interruptible(&arPriv->arPrivSem)) {
> - AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n",
> __func__));
> - return -ERESTARTSYS;
> - }
>
> if(arPriv->arConnected == TRUE &&
> arPriv->arSsidLen == sme->ssid_len &&
> @@ -316,7 +315,9 @@
> status = wmi_reconnect_cmd(arPriv->arWmi,
> arSta->arReqBssid,
> arPriv->arChannelHint);
> -
> +
> + up(&arPriv->arPrivSem);
> +
> if (status != A_OK) {
> AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd
> failed\n", __func__));
> return -EIO;
> @@ -461,6 +462,7 @@
> unsigned char *ptr_ie_buf = ie_buf;
> unsigned char *ieeemgmtbuf = NULL;
> A_UINT8 source_mac[ATH_MAC_LEN];
> + AR_SOFTC_T *ar = arPriv->arSoftc;
>
> A_UINT8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/
> sizeof(A_UINT16); /* listen interval */
> @@ -474,6 +476,7 @@
>
> assocReqLen -= assocReqIeOffset;
> assocRespLen -= assocRespIeOffset;
> + arPriv->arAutoAuthStage = AUTH_IDLE;
>
> if((ADHOC_NETWORK & networkType)) {
> if(NL80211_IFTYPE_ADHOC != arPriv->wdev->iftype) {
> @@ -502,7 +505,15 @@
> ((ADHOC_NETWORK & networkType) ?
> WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
> ((ADHOC_NETWORK & networkType) ?
> WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
>
> - if(!bss) {
> + /*
> + * Earlier we were updating the cfg about bss by making a beacon frame
> + * only if the entry for bss is not there. This can have some issue if
> + * ROAM event is generated and a heavy traffic is ongoing. The ROAM
> + * event is handled through a work queue and by the time it really gets
> + * handled, BSS would have been aged out. So it is better to update the
> + * cfg about BSS irrespective of its entry being present right now or
> + * not.
> + */
> if (ADHOC_NETWORK & networkType) {
> /* construct 802.11 mgmt beacon */
> if(ptr_ie_buf) {
> @@ -543,6 +554,7 @@
> if(!ieeemgmtbuf) {
> AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
> ("%s: ieeeMgmtbuf alloc error\n", __func__));
> + cfg80211_put_bss(bss);
> return;
> }
>
> @@ -572,7 +584,6 @@
> signal, GFP_ATOMIC);
> A_FREE(ieeemgmtbuf);
> cfg80211_put_bss(bss);
> - }
>
> if((ADHOC_NETWORK & networkType)) {
> cfg80211_ibss_joined(arPriv->arNetDev, bssid, GFP_ATOMIC);
> @@ -581,6 +592,7 @@
>
> if (FALSE == arPriv->arConnected) {
> /* inform connect result to cfg80211 */
> + ar->smeState = SME_DISCONNECTED;
> cfg80211_connect_result(arPriv->arNetDev, bssid,
> assocReqIe, assocReqLen,
> assocRespIe, assocRespLen,
> @@ -642,6 +654,14 @@
> A_UINT8 *bssid, A_UINT8 assocRespLen,
> A_UINT8 *assocInfo, A_UINT16
> protocolReasonStatus)
> {
> + A_UINT16 status;
> + AR_SOFTC_STA_T *arSta = &arPriv->arSta;
> + AR_SOFTC_T *ar = (AR_SOFTC_T *)arPriv->arSoftc;
> +
> + if (arPriv->scan_request) {
> + cfg80211_scan_done(arPriv->scan_request, true);
> + arPriv->scan_request = NULL;
> + }
>
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
>
> @@ -664,18 +684,74 @@
> }
> }
>
> - if(FALSE == arPriv->arConnected) {
> + if(true == arSta->arConnectPending) {
> if(NO_NETWORK_AVAIL == reason) {
> /* connect cmd failed */
> - cfg80211_connect_result(arPriv->arNetDev, bssid,
> - NULL, 0,
> - NULL, 0,
> - WLAN_STATUS_UNSPECIFIED_FAILURE,
> - GFP_ATOMIC);
> - }
> + wmi_disconnect_cmd(arPriv->arWmi);
> + } else if (reason == DISCONNECT_CMD) {
> + if (arPriv->arAutoAuthStage) {
> + /*
> + * If the current auth algorithm is open try shared
> + * and make autoAuthStage idle. We do not make it
> + * leap for now being.
> + */
> + if (arPriv->arDot11AuthMode == OPEN_AUTH) {
> + struct ar_key *key = NULL;
> + key = &arPriv->keys[arPriv->arDefTxKeyIndex];
> + if (down_interruptible(&ar->arSem)) {
> + AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:
> busy, couldn't get access\n", __func__));
> + return;
> + }
> +
> + arPriv->arDot11AuthMode = SHARED_AUTH;
> + arPriv->arAutoAuthStage = AUTH_IDLE;
> +
> + wmi_addKey_cmd(arPriv->arWmi,
> arPriv->arDefTxKeyIndex,
> + arPriv->arPairwiseCrypto,
> + GROUP_USAGE | TX_USAGE,
> + key->key_len,
> + NULL,
> + key->key, KEY_OP_INIT_VAL, NULL,
> + NO_SYNC_WMIFLAG);
> +
> + status = wmi_connect_cmd(arPriv->arWmi,
> + arPriv->arNetworkType,
> +
> arPriv->arDot11AuthMode,
> + arPriv->arAuthMode,
> +
> arPriv->arPairwiseCrypto,
> +
> arPriv->arPairwiseCryptoLen,
> + arPriv->arGroupCrypto,
> +
> arPriv->arGroupCryptoLen,
> + arPriv->arSsidLen,
> + arPriv->arSsid,
> + arSta->arReqBssid,
> + arPriv->arChannelHint,
> +
> arSta->arConnectCtrlFlags);
> + up(&ar->arSem);
> +
> + } else if (arPriv->arDot11AuthMode == SHARED_AUTH) {
> + /* should not reach here */
> + }
> + } else {
> + arSta->arConnectPending = false;
> + if (ar->smeState == SME_CONNECTING) {
> + cfg80211_connect_result(arPriv->arNetDev, bssid,
> + NULL, 0,
> + NULL, 0,
> +
> WLAN_STATUS_UNSPECIFIED_FAILURE,
> + GFP_ATOMIC);
> + } else {
> + cfg80211_disconnected(arPriv->arNetDev,
> + reason,
> + NULL, 0,
> + GFP_ATOMIC);
> + }
> + ar->smeState = SME_DISCONNECTED;
> + }
> + }
> } else {
> - /* connection loss due to disconnect cmd or low rssi */
> - cfg80211_disconnected(arPriv->arNetDev, reason, NULL, 0, GFP_ATOMIC);
> + if (reason != DISCONNECT_CMD)
> + wmi_disconnect_cmd(arPriv->arWmi);
> }
> }
>
> @@ -812,10 +888,11 @@
> if(arPriv->scan_request)
> {
> /* Translate data to cfg80211 mgmt format */
> + if (arPriv->arWmi)
> wmi_iterate_nodes(arPriv->arWmi, ar6k_cfg80211_scan_node,
> arPriv->wdev->wiphy);
>
> - cfg80211_scan_done(arPriv->scan_request,
> - (status & A_ECANCELED) ? true : false);
> + cfg80211_scan_done(arPriv->scan_request,
> + ((status & A_ECANCELED) || (status & A_EBUSY)) ? true : false);
>
> if(arPriv->scan_request->n_ssids &&
> arPriv->scan_request->ssids[0].ssid_len) {
> @@ -1026,6 +1103,7 @@
> AR_SOFTC_T *ar = arPriv->arSoftc;
> struct ar_key *key = NULL;
> A_STATUS status = A_OK;
> + u8 key_usage;
>
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
>
> @@ -1052,17 +1130,20 @@
> return -EINVAL;
> }
>
> - if (arPriv->arAuthMode < WPA_AUTH) {
> - arPriv->arDefTxKeyIndex = key_index;
> - key = &arPriv->keys[arPriv->arDefTxKeyIndex];
> - status = wmi_addKey_cmd(arPriv->arWmi, arPriv->arDefTxKeyIndex,
> - arPriv->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
> + key_usage = GROUP_USAGE;
> + if (WEP_CRYPT == arPriv->arPairwiseCrypto) {
> + key_usage |= TX_USAGE;
> + }
> +
> + arPriv->arDefTxKeyIndex = key_index;
> + key = &arPriv->keys[arPriv->arDefTxKeyIndex];
> + status = wmi_addKey_cmd(arPriv->arWmi, arPriv->arDefTxKeyIndex,
> + arPriv->arPairwiseCrypto, key_usage,
> key->key_len, key->seq, key->key,
> KEY_OP_INIT_VAL,
> NULL, SYNC_BOTH_WMIFLAG);
> - if (status != A_OK) {
> - return -EIO;
> - }
> - }
> + if (status != A_OK) {
> + return -EIO;
> + }
> return 0;
> }
>
> @@ -1469,6 +1550,152 @@
> WLAN_CIPHER_SUITE_CCMP,
> };
>
> +bool is_rate_legacy(s32 rate)
> +{
> + static const s32 legacy[] = { 1000, 2000, 5500, 11000,
> + 6000, 9000, 12000, 18000, 24000,
> + 36000, 48000, 54000 };
> + u8 i;
> +
> + for (i = 0; i < ARRAY_SIZE(legacy); i++) {
> + if (rate == legacy[i])
> + return true;
> + }
> +
> + return false;
> +}
> +
> +bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
> +{
> + static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
> + 52000, 58500, 65000, 72200 };
> + u8 i;
> +
> + for (i = 0; i < ARRAY_SIZE(ht20); i++) {
> + if (rate == ht20[i]) {
> + if (i == ARRAY_SIZE(ht20) - 1)
> + /* last rate uses sgi */
> + *sgi = true;
> + else
> + *sgi = false;
> +
> + *mcs = i;
> + return true;
> + }
> + }
> + return false;
> +}
> +
> +bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
> +{
> + static const s32 ht40[] = { 13500, 27000, 40500, 54000,
> + 81000, 108000, 121500, 135000,
> + 150000 };
> + u8 i;
> +
> + for (i = 0; i < ARRAY_SIZE(ht40); i++) {
> + if (rate == ht40[i]) {
> + if (i == ARRAY_SIZE(ht40) - 1)
> + /* last rate uses sgi */
> + *sgi = true;
> + else
> + *sgi = false;
> +
> + *mcs = i;
> + return true;
> + }
> + }
> +
> + return false;
> +}
> +
> +static int ar6k_get_station(struct wiphy *wiphy, struct net_device *dev,
> + u8 *mac, struct station_info *sinfo)
> +{
> + AR_SOFTC_DEV_T *arPriv = (AR_SOFTC_DEV_T *)ar6k_priv(dev);
> + AR_SOFTC_T *ar = arPriv->arSoftc;
> + long left;
> + bool sgi;
> + s32 rate;
> + int ret;
> + u8 mcs;
> +
> + if (memcmp(mac, arPriv->arBssid, ETH_ALEN) != 0)
> + return -ENOENT;
> +
> + if (down_interruptible(&ar->arSem))
> + return -EBUSY;
> +
> + arPriv->statsUpdatePending = true;
> +
> + ret = wmi_get_stats_cmd(arPriv->arWmi);
> +
> + if (ret != 0) {
> + up(&ar->arSem);
> + return -EIO;
> + }
> +
> + left = wait_event_interruptible_timeout(arPriv->arEvent,
> + arPriv->statsUpdatePending ==
> false,
> + wmitimeout * HZ);
> +
> + up(&ar->arSem);
> +
> + if (left == 0)
> + return -ETIMEDOUT;
> + else if (left < 0)
> + return left;
> +
> + if (arPriv->arTargetStats.rx_bytes) {
> + sinfo->rx_bytes = arPriv->arTargetStats.rx_bytes;
> + sinfo->filled |= STATION_INFO_RX_BYTES;
> + sinfo->rx_packets = arPriv->arTargetStats.rx_packets;
> + sinfo->filled |= STATION_INFO_RX_PACKETS;
> + }
> +
> + if (arPriv->arTargetStats.tx_bytes) {
> + sinfo->tx_bytes = arPriv->arTargetStats.tx_bytes;
> + sinfo->filled |= STATION_INFO_TX_BYTES;
> + sinfo->tx_packets = arPriv->arTargetStats.tx_packets;
> + sinfo->filled |= STATION_INFO_TX_PACKETS;
> + }
> +
> + sinfo->signal = arPriv->arTargetStats.cs_rssi;
> + sinfo->filled |= STATION_INFO_SIGNAL;
> +
> + rate = arPriv->arTargetStats.tx_unicast_rate;
> +
> + if (is_rate_legacy(rate)) {
> + sinfo->txrate.legacy = rate / 100;
> + } else if (is_rate_ht20(rate, &mcs, &sgi)) {
> + if (sgi) {
> + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
> + sinfo->txrate.mcs = mcs - 1;
> + } else {
> + sinfo->txrate.mcs = mcs;
> + }
> +
> + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
> + } else if (is_rate_ht40(rate, &mcs, &sgi)) {
> + if (sgi) {
> + sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
> + sinfo->txrate.mcs = mcs - 1;
> + } else {
> + sinfo->txrate.mcs = mcs;
> + }
> +
> + sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
> + sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
> + } else {
> + WARN(1, "invalid rate: %d", rate);
> + return 0;
> + }
> +
> + sinfo->filled |= STATION_INFO_TX_BITRATE;
> +
> + return 0;
> +}
> +
> static struct
> cfg80211_ops ar6k_cfg80211_ops = {
> .change_virtual_intf = ar6k_cfg80211_change_iface,
> @@ -1489,6 +1716,7 @@
> .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
> .join_ibss = ar6k_cfg80211_join_ibss,
> .leave_ibss = ar6k_cfg80211_leave_ibss,
> + .get_station = ar6k_get_station,
> };
>
> struct wireless_dev *
> diff -ruN
> kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
> --- kernel-2.6.37.6-92.2/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
> 2011-06-15 02:06:12.863498128 +0800
> +++
> kernel-2.6.37.6-92.2_cfg80211_fix_patch/drivers/staging/ar6003/os/linux/include/ar6000_drv.h
> 2011-06-29 08:32:44.112711621 +0800
> @@ -427,6 +427,13 @@
> A_UINT8 seq_len;
> A_UINT32 cipher;
> };
> +
> +enum {
> + SME_DISCONNECTED,
> + SME_CONNECTING,
> + SME_CONNECTED
> +};
> +
> #endif /* ATH6K_CONFIG_CFG80211 */
>
>
> @@ -574,6 +581,7 @@
> A_UINT8 rxMetaVersion;
> A_INT32 (*exitCallback)(void *config); /* generic
> callback at AR6K exit */
> HIF_DEVICE_OS_DEVICE_INFO osDevInfo;
> + A_UINT32 smeState;
> A_UINT16 arWlanPowerState;
> A_BOOL arPlatPowerOff;
> USER_RSSI_CPENSATION rssi_compensation_param;
> @@ -729,6 +737,7 @@
> AR_SOFTC_T *arSoftc;
> A_UINT8 arHoldConnection;
> A_UINT8 num_sta;
> + A_UINT8 arAutoAuthStage;
> }AR_SOFTC_DEV_T;
>
> #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0)
>
> Subject: Correct the cfg80211 bss signal strenth format
>
> Signed-off-by: Samuel Chang <[email protected]>
>
> diff -ruN
> kernel-2.6.37.6-24.3_cfg80211_fix_patch_1/drivers/staging/ar6003/os/linux/cfg80211.c
>
> kernel-2.6.37.6-24.3_cfg80211_rssi_patch_1.1/drivers/staging/ar6003/os/linux/cfg80211.c
> ---
> kernel-2.6.37.6-24.3_cfg80211_fix_patch_1/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-06-29 11:09:42.519414000 +0800
> +++
> kernel-2.6.37.6-24.3_cfg80211_rssi_patch_1.1/drivers/staging/ar6003/os/linux/cfg80211.c
> 2011-07-06 14:58:11.257184423 +0800
> @@ -804,7 +804,7 @@
>
> freq = cie->ie_chan;
> channel = ieee80211_get_channel(wiphy, freq);
> - signal = ni->ni_snr * 100;
> + signal = ni->ni_snr * 100 - 9500;
>
> AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
> ("%s: bssid %02x:%02x:%02x:%02x:%02x:%02x channel %d
> freq %d size %d\n",
--
Intel Open Source Technology Centre
http://oss.intel.com/
_______________________________________________
MeeGo-kernel mailing list
[email protected]
http://lists.meego.com/listinfo/meego-kernel