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, |