| Index: chromeos/drivers/ath6kl/wmi/wmi.c
|
| diff --git a/chromeos/drivers/ath6kl/wmi/wmi.c b/chromeos/drivers/ath6kl/wmi/wmi.c
|
| index 76ed7dae3331254251ecefa0b2a09bf5e061ac39..7800778099bd74d2ca4310f5e4f102959b968ba9 100644
|
| --- a/chromeos/drivers/ath6kl/wmi/wmi.c
|
| +++ b/chromeos/drivers/ath6kl/wmi/wmi.c
|
| @@ -1,15 +1,18 @@
|
| //------------------------------------------------------------------------------
|
| -// <copyright file="wmi.c" company="Atheros">
|
| -// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
|
| +// Copyright (c) 2004-2010 Atheros Corporation. All rights reserved.
|
| //
|
| -// This program is free software; you can redistribute it and/or modify
|
| -// it under the terms of the GNU General Public License version 2 as
|
| -// published by the Free Software Foundation;
|
| //
|
| -// Software distributed under the License is distributed on an "AS
|
| -// IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
| -// implied. See the License for the specific language governing
|
| -// rights and limitations under the License.
|
| +// Permission to use, copy, modify, and/or distribute this software for any
|
| +// purpose with or without fee is hereby granted, provided that the above
|
| +// copyright notice and this permission notice appear in all copies.
|
| +//
|
| +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
| +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
| +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
| +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
| +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
| +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
| +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
| //
|
| //
|
| //------------------------------------------------------------------------------
|
| @@ -43,7 +46,7 @@
|
|
|
| #define ATH_DEBUG_WMI ATH_DEBUG_MAKE_MODULE_MASK(0)
|
|
|
| -#ifdef DEBUG
|
| +#ifdef ATH_DEBUG_MODULE
|
|
|
| static ATH_DEBUG_MASK_DESCRIPTION wmi_debug_desc[] = {
|
| { ATH_DEBUG_WMI , "General WMI Tracing"},
|
| @@ -126,6 +129,9 @@ wmi_get_pmkid_list_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
|
| static A_STATUS
|
| wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
|
|
|
| +static A_STATUS
|
| +wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len);
|
| +
|
| #ifdef CONFIG_HOST_GPIO_SUPPORT
|
| static A_STATUS wmi_gpio_intr_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
|
| static A_STATUS wmi_gpio_data_rx(struct wmi_t *wmip, A_UINT8 *datap, int len);
|
| @@ -288,8 +294,8 @@ typedef PREPACK struct _iphdr {
|
|
|
| #include "athendpack.h"
|
|
|
| -A_INT16 rssi_event_value = 0;
|
| -A_INT16 snr_event_value = 0;
|
| +static A_INT16 rssi_event_value = 0;
|
| +static A_INT16 snr_event_value = 0;
|
|
|
| A_BOOL is_probe_ssid = FALSE;
|
|
|
| @@ -300,12 +306,16 @@ wmi_init(void *devt)
|
|
|
| A_REGISTER_MODULE_DEBUG_INFO(wmi);
|
|
|
| - wmip = A_MALLOC(sizeof(struct wmi_t));
|
| + wmip = A_MALLOC (sizeof(struct wmi_t));
|
| if (wmip == NULL) {
|
| return (NULL);
|
| }
|
| - A_MEMZERO(wmip, sizeof(*wmip));
|
| - A_MUTEX_INIT(&wmip->wmi_lock);
|
| + A_MEMZERO(wmip, sizeof(struct wmi_t ));
|
| +#ifdef THREAD_X
|
| + INIT_WMI_LOCK(wmip);
|
| +#else
|
| + A_MUTEX_INIT(&wmip->wmi_lock);
|
| +#endif
|
| wmip->wmi_devt = devt;
|
| wlan_node_table_init(wmip, &wmip->wmi_scan_table);
|
| wmi_qos_state_init(wmip);
|
| @@ -365,7 +375,11 @@ wmi_shutdown(struct wmi_t *wmip)
|
| if (wmip != NULL) {
|
| wlan_node_table_cleanup(&wmip->wmi_scan_table);
|
| if (A_IS_MUTEX_VALID(&wmip->wmi_lock)) {
|
| +#ifdef THREAD_X
|
| + DELETE_WMI_LOCK(&wmip);
|
| +#else
|
| A_MUTEX_DELETE(&wmip->wmi_lock);
|
| +#endif
|
| }
|
| A_FREE(wmip);
|
| }
|
| @@ -574,10 +588,18 @@ A_UINT8 wmi_implicit_create_pstream(struct wmi_t *wmip, void *osbuf, A_UINT32 la
|
| }
|
| }
|
|
|
| +
|
| + /* workaround for WMM S5 */
|
| + if ((WMM_AC_VI == wmip->wmi_traffic_class) && ((5 == userPriority) || (4 == userPriority)))
|
| + {
|
| + userPriority = 1;
|
| + }
|
| +
|
| trafficClass = convert_userPriority_to_trafficClass(userPriority);
|
|
|
| WMI_DATA_HDR_SET_UP(dtHdr, userPriority);
|
| - //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT; /* lower 3-bits are 802.1d priority */
|
| + /* lower 3-bits are 802.1d priority */
|
| + //dtHdr->info |= (userPriority & WMI_DATA_HDR_UP_MASK) << WMI_DATA_HDR_UP_SHIFT;
|
|
|
| LOCK_WMI(wmip);
|
| streamExists = wmip->wmi_fatPipeExists;
|
| @@ -722,6 +744,8 @@ wmi_dot11_hdr_remove(struct wmi_t *wmip, void *osbuf)
|
| llcHdr = (ATH_LLC_SNAP_HDR *)(datap);
|
|
|
| macHdr.typeOrLen = llcHdr->etherType;
|
| + A_MEMZERO(macHdr.dstMac, sizeof(macHdr.dstMac));
|
| + A_MEMZERO(macHdr.srcMac, sizeof(macHdr.srcMac));
|
|
|
| switch (wh.i_fc[1] & IEEE80211_FC1_DIR_MASK) {
|
| case IEEE80211_FC1_DIR_NODS:
|
| @@ -1109,6 +1133,10 @@ wmi_control_rx(struct wmi_t *wmip, void *osbuf)
|
| A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
|
| status = wmi_set_params_event_rx(wmip, datap, len);
|
| break;
|
| + case (WMI_ACM_REJECT_EVENTID):
|
| + A_DPRINTF(DBG_WMI, (DBGFMT "WMI_SET_PARAMS_REPLY Event\n", DBGARG));
|
| + status = wmi_acm_reject_event_rx(wmip, datap, len);
|
| + break;
|
| #ifdef ATH_AR6K_11N_SUPPORT
|
| case (WMI_ADDBA_REQ_EVENTID):
|
| status = wmi_addba_req_event_rx(wmip, datap, len);
|
| @@ -1329,6 +1357,7 @@ static A_STATUS
|
| wmi_disconnect_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| {
|
| WMI_DISCONNECT_EVENT *ev;
|
| + wmip->wmi_traffic_class = 100;
|
|
|
| if (len < sizeof(WMI_DISCONNECT_EVENT)) {
|
| return A_EINVAL;
|
| @@ -1427,11 +1456,9 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| buf = datap + sizeof(WMI_BSS_INFO_HDR);
|
| len -= sizeof(WMI_BSS_INFO_HDR);
|
|
|
| - A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
|
| - "bssid \"%02x:%02x:%02x:%02x:%02x:%02x\"\n", DBGARG,
|
| - bih->channel, (unsigned char) bih->rssi, bih->bssid[0],
|
| - bih->bssid[1], bih->bssid[2], bih->bssid[3], bih->bssid[4],
|
| - bih->bssid[5]));
|
| + A_DPRINTF(DBG_WMI2, (DBGFMT "bssInfo event - ch %u, rssi %02x, "
|
| + "bssid \"%pM\"\n", DBGARG, bih->channel,
|
| + (unsigned char) bih->rssi, bih->bssid));
|
|
|
| if(wps_enable && (bih->frameType == PROBERESP_FTYPE) ) {
|
| wmi_node_return(wmip, bss);
|
| @@ -1460,17 +1487,17 @@ wmi_bssInfo_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| }
|
| }
|
|
|
| - /*
|
| - * Use the current average rssi of associated AP base on assumpiton
|
| + /*
|
| + * Use the current average rssi of associated AP base on assumpiton
|
| * 1. Most os with GUI will update RSSI by wmi_get_stats_cmd() periodically
|
| * 2. wmi_get_stats_cmd(..) will be called when calling wmi_startscan_cmd(...)
|
| * The average value of RSSI give end-user better feeling for instance value of scan result
|
| * It also sync up RSSI info in GUI between scan result and RSSI signal icon
|
| */
|
| - if (bss && IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
|
| + if (IEEE80211_ADDR_EQ(wmip->wmi_bssid, bih->bssid)) {
|
| bih->rssi = bss->ni_rssi;
|
| bih->snr = bss->ni_snr;
|
| - }
|
| + }
|
|
|
| wlan_node_reclaim(&wmip->wmi_scan_table, bss);
|
| }
|
| @@ -1789,6 +1816,9 @@ wmi_scanComplete_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| WMI_SCAN_COMPLETE_EVENT *ev;
|
|
|
| ev = (WMI_SCAN_COMPLETE_EVENT *)datap;
|
| + if ((A_STATUS)ev->status == A_OK) {
|
| + wlan_refresh_inactive_nodes(&wmip->wmi_scan_table);
|
| + }
|
| A_WMI_SCANCOMPLETE_EVENT(wmip->wmi_devt, (A_STATUS) ev->status);
|
| is_probe_ssid = FALSE;
|
|
|
| @@ -1961,6 +1991,7 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| {
|
| WMI_CAC_EVENT *reply;
|
| WMM_TSPEC_IE *tspec_ie;
|
| + A_UINT16 activeTsids;
|
|
|
| if (len < sizeof(*reply)) {
|
| return A_EINVAL;
|
| @@ -1977,7 +2008,6 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| (tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
|
| }
|
| else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
|
| - A_UINT16 activeTsids;
|
| A_UINT8 i;
|
|
|
| /* following assumes that there is only one outstanding ADDTS request
|
| @@ -1995,6 +2025,29 @@ wmi_cac_event_rx(struct wmi_t *wmip, A_UINT8 *datap, int len)
|
| wmi_delete_pstream_cmd(wmip, reply->ac, i);
|
| }
|
| }
|
| + /*
|
| + * Ev#72990: Clear active tsids and Add missing handling
|
| + * for delete qos stream from AP
|
| + */
|
| + else if (reply->cac_indication == CAC_INDICATION_DELETE) {
|
| + A_UINT8 tsid = 0;
|
| +
|
| + tspec_ie = (WMM_TSPEC_IE *) &(reply->tspecSuggestion);
|
| + tsid= ((tspec_ie->tsInfo_info >> TSPEC_TSID_S) & TSPEC_TSID_MASK);
|
| + LOCK_WMI(wmip);
|
| + wmip->wmi_streamExistsForAC[reply->ac] &= ~(1<<tsid);
|
| + activeTsids = wmip->wmi_streamExistsForAC[reply->ac];
|
| + UNLOCK_WMI(wmip);
|
| +
|
| +
|
| + /* Indicate stream inactivity to driver layer only if all tsids
|
| + * within this AC are deleted.
|
| + */
|
| + if (!activeTsids) {
|
| + A_WMI_STREAM_TX_INACTIVE(wmip->wmi_devt, reply->ac);
|
| + wmip->wmi_fatPipeExists &= ~(1 << reply->ac);
|
| + }
|
| + }
|
|
|
| A_WMI_CAC_EVENT(wmip->wmi_devt, reply->ac,
|
| reply->cac_indication, reply->statusCode,
|
| @@ -2372,6 +2425,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
|
| {
|
| void *osbuf;
|
| WMI_CONNECT_CMD *cc;
|
| + wmip->wmi_traffic_class = 100;
|
|
|
| if ((pairwiseCrypto == NONE_CRYPT) && (groupCrypto != NONE_CRYPT)) {
|
| return A_EINVAL;
|
| @@ -2409,7 +2463,7 @@ wmi_connect_cmd(struct wmi_t *wmip, NETWORK_TYPE netType,
|
| if (bssid != NULL) {
|
| A_MEMCPY(cc->bssid, bssid, ATH_MAC_LEN);
|
| }
|
| -
|
| +
|
| wmip->wmi_pair_crypto_type = pairwiseCrypto;
|
| wmip->wmi_grp_crypto_type = groupCrypto;
|
|
|
| @@ -2421,6 +2475,7 @@ wmi_reconnect_cmd(struct wmi_t *wmip, A_UINT8 *bssid, A_UINT16 channel)
|
| {
|
| void *osbuf;
|
| WMI_RECONNECT_CMD *cc;
|
| + wmip->wmi_traffic_class = 100;
|
|
|
| osbuf = A_NETBUF_ALLOC(sizeof(WMI_RECONNECT_CMD));
|
| if (osbuf == NULL) {
|
| @@ -2445,6 +2500,7 @@ A_STATUS
|
| wmi_disconnect_cmd(struct wmi_t *wmip)
|
| {
|
| A_STATUS status;
|
| + wmip->wmi_traffic_class = 100;
|
|
|
| /* Bug fix for 24817(elevator bug) - the disconnect command does not
|
| need to do a SYNC before.*/
|
| @@ -3343,11 +3399,11 @@ wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_IN
|
| {
|
| void *osbuf;
|
| WMI_BIT_RATE_CMD *cmd;
|
| - A_INT8 drix, mrix, crix;
|
| + A_INT8 drix, mrix, crix, ret_val;
|
|
|
| if (dataRate != -1) {
|
| - drix = wmi_validate_bitrate(wmip, dataRate);
|
| - if(drix == A_EINVAL){
|
| + ret_val = wmi_validate_bitrate(wmip, dataRate, &drix);
|
| + if(ret_val == A_EINVAL){
|
| return A_EINVAL;
|
| }
|
| } else {
|
| @@ -3355,16 +3411,16 @@ wmi_set_bitrate_cmd(struct wmi_t *wmip, A_INT32 dataRate, A_INT32 mgmtRate, A_IN
|
| }
|
|
|
| if (mgmtRate != -1) {
|
| - mrix = wmi_validate_bitrate(wmip, mgmtRate);
|
| - if(mrix == A_EINVAL){
|
| + ret_val = wmi_validate_bitrate(wmip, mgmtRate, &mrix);
|
| + if(ret_val == A_EINVAL){
|
| return A_EINVAL;
|
| }
|
| } else {
|
| mrix = -1;
|
| }
|
| if (ctlRate != -1) {
|
| - crix = wmi_validate_bitrate(wmip, ctlRate);
|
| - if(crix == A_EINVAL){
|
| + ret_val = wmi_validate_bitrate(wmip, ctlRate, &crix);
|
| + if(ret_val == A_EINVAL){
|
| return A_EINVAL;
|
| }
|
| } else {
|
| @@ -3434,7 +3490,7 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
|
| break;
|
|
|
| case WMI_11G_MODE:
|
| - case WMI_11AG_MODE:
|
| + case WMI_11AG_MODE:
|
| if (wmip->wmi_ht_allowed[A_BAND_24GHZ]){
|
| if ((rateIndex < MODE_G_SUPPORT_RATE_START) || (rateIndex > MODE_GHT20_SUPPORT_RATE_STOP)) {
|
| isValid = FALSE;
|
| @@ -3444,7 +3500,7 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
|
| isValid = FALSE;
|
| }
|
| }
|
| - break;
|
| + break;
|
| default:
|
| A_ASSERT(FALSE);
|
| break;
|
| @@ -3454,30 +3510,26 @@ wmi_is_bitrate_index_valid(struct wmi_t *wmip, A_INT32 rateIndex)
|
| }
|
|
|
| A_INT8
|
| -wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate)
|
| +wmi_validate_bitrate(struct wmi_t *wmip, A_INT32 rate, A_INT8 *rate_idx)
|
| {
|
| A_INT8 i;
|
| - if (rate != -1)
|
| +
|
| + for (i=0;;i++)
|
| {
|
| - for (i=0;;i++)
|
| - {
|
| - if (wmi_rateTable[(A_UINT32) i][0] == 0) {
|
| - return A_EINVAL;
|
| - }
|
| - if (wmi_rateTable[(A_UINT32) i][0] == rate) {
|
| - break;
|
| - }
|
| + if (wmi_rateTable[(A_UINT32) i][0] == 0) {
|
| + return A_EINVAL;
|
| + }
|
| + if (wmi_rateTable[(A_UINT32) i][0] == rate) {
|
| + break;
|
| }
|
| - }
|
| - else{
|
| - i = -1;
|
| }
|
|
|
| if(wmi_is_bitrate_index_valid(wmip, (A_INT32) i) != TRUE) {
|
| return A_EINVAL;
|
| }
|
|
|
| - return i;
|
| + *rate_idx = i;
|
| + return A_OK;
|
| }
|
|
|
| A_STATUS
|
| @@ -5339,6 +5391,14 @@ wmi_find_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
|
| }
|
|
|
|
|
| +#ifdef THREAD_X
|
| +void
|
| +wmi_refresh_scan_table (struct wmi_t *wmip)
|
| +{
|
| + wlan_refresh_inactive_nodes (&wmip->wmi_scan_table);
|
| +}
|
| +#endif
|
| +
|
| void
|
| wmi_free_allnodes(struct wmi_t *wmip)
|
| {
|
| @@ -5379,7 +5439,7 @@ wmi_dset_open_reply(struct wmi_t *wmip,
|
| void *osbuf;
|
| WMIX_DSETOPEN_REPLY_CMD *open_reply;
|
|
|
| - A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%x\n", DBGARG, (int)wmip));
|
| + A_DPRINTF(DBG_WMI, (DBGFMT "Enter - wmip=0x%lx\n", DBGARG, (unsigned long)wmip));
|
|
|
| osbuf = A_NETBUF_ALLOC(sizeof(*open_reply));
|
| if (osbuf == NULL) {
|
| @@ -5448,6 +5508,18 @@ wmi_set_params_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
|
|
|
|
|
|
|
| +static A_STATUS
|
| +wmi_acm_reject_event_rx(struct wmi_t *wmip, A_UINT8 *datap, A_UINT32 len)
|
| +{
|
| + WMI_ACM_REJECT_EVENT *ev;
|
| +
|
| + ev = (WMI_ACM_REJECT_EVENT *)datap;
|
| + wmip->wmi_traffic_class = ev->trafficClass;
|
| + printk("ACM REJECT %d\n",wmip->wmi_traffic_class);
|
| + return A_OK;
|
| +}
|
| +
|
| +
|
| #ifdef CONFIG_HOST_DSET_SUPPORT
|
| A_STATUS
|
| wmi_dset_data_reply(struct wmi_t *wmip,
|
| @@ -6330,7 +6402,7 @@ wmi_set_ht_cap_cmd(struct wmi_t *wmip, WMI_SET_HT_CAP_CMD *cmd)
|
| htCap = (WMI_SET_HT_CAP_CMD *)(A_NETBUF_DATA(osbuf));
|
| A_MEMZERO(htCap, sizeof(*htCap));
|
| A_MEMCPY(htCap, cmd, sizeof(*htCap));
|
| -
|
| +
|
| return (wmi_cmd_send(wmip, osbuf, WMI_SET_HT_CAP_CMDID,
|
| NO_SYNC_WMIFLAG));
|
| }
|
| @@ -6546,6 +6618,27 @@ wmi_set_pmk_cmd(struct wmi_t *wmip, A_UINT8 *pmk)
|
| return (wmi_cmd_send(wmip, osbuf, WMI_SET_PMK_CMDID, NO_SYNC_WMIFLAG));
|
| }
|
|
|
| +A_STATUS
|
| +wmi_SGI_cmd(struct wmi_t *wmip, A_UINT32 sgiMask, A_UINT8 sgiPERThreshold)
|
| +{
|
| + void *osbuf;
|
| + WMI_SET_TX_SGI_PARAM_CMD *cmd;
|
| +
|
| + osbuf = A_NETBUF_ALLOC(sizeof(*cmd));
|
| + if (osbuf == NULL) {
|
| + return A_NO_MEMORY ;
|
| + }
|
| +
|
| + A_NETBUF_PUT(osbuf, sizeof(*cmd));
|
| +
|
| + cmd = (WMI_SET_TX_SGI_PARAM_CMD *)(A_NETBUF_DATA(osbuf));
|
| + A_MEMZERO(cmd, sizeof(*cmd));
|
| + cmd->sgiMask = sgiMask;
|
| + cmd->sgiPERThreshold = sgiPERThreshold;
|
| + return (wmi_cmd_send(wmip, osbuf, WMI_SET_TX_SGI_PARAM_CMDID,
|
| + NO_SYNC_WMIFLAG));
|
| +}
|
| +
|
| bss_t *
|
| wmi_find_matching_Ssidnode (struct wmi_t *wmip, A_UCHAR *pSsid,
|
| A_UINT32 ssidLength,
|
|
|