brintos

brintos / linux-shallow public Read only

0
0
Text · 34.3 KiB · 8f9fe23 Raw
1312 lines · c
1/*2 * Copyright (c) 2004-2011 Atheros Communications Inc.3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.4 *5 * Permission to use, copy, modify, and/or distribute this software for any6 * purpose with or without fee is hereby granted, provided that the above7 * copyright notice and this permission notice appear in all copies.8 *9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.16 */17 18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt19 20#include "core.h"21#include "hif-ops.h"22#include "cfg80211.h"23#include "target.h"24#include "debug.h"25 26struct ath6kl_sta *ath6kl_find_sta(struct ath6kl_vif *vif, u8 *node_addr)27{28	struct ath6kl *ar = vif->ar;29	struct ath6kl_sta *conn = NULL;30	u8 i, max_conn;31 32	if (is_zero_ether_addr(node_addr))33		return NULL;34 35	max_conn = (vif->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;36 37	for (i = 0; i < max_conn; i++) {38		if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {39			conn = &ar->sta_list[i];40			break;41		}42	}43 44	return conn;45}46 47struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)48{49	struct ath6kl_sta *conn = NULL;50	u8 ctr;51 52	for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {53		if (ar->sta_list[ctr].aid == aid) {54			conn = &ar->sta_list[ctr];55			break;56		}57	}58	return conn;59}60 61static void ath6kl_add_new_sta(struct ath6kl_vif *vif, u8 *mac, u16 aid,62			       u8 *wpaie, size_t ielen, u8 keymgmt,63			       u8 ucipher, u8 auth, u8 apsd_info)64{65	struct ath6kl *ar = vif->ar;66	struct ath6kl_sta *sta;67	u8 free_slot;68 69	free_slot = aid - 1;70 71	sta = &ar->sta_list[free_slot];72	memcpy(sta->mac, mac, ETH_ALEN);73	if (ielen <= ATH6KL_MAX_IE)74		memcpy(sta->wpa_ie, wpaie, ielen);75	sta->aid = aid;76	sta->keymgmt = keymgmt;77	sta->ucipher = ucipher;78	sta->auth = auth;79	sta->apsd_info = apsd_info;80 81	ar->sta_list_index = ar->sta_list_index | (1 << free_slot);82	ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);83	aggr_conn_init(vif, vif->aggr_cntxt, sta->aggr_conn);84}85 86static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)87{88	struct ath6kl_sta *sta = &ar->sta_list[i];89	struct ath6kl_mgmt_buff *entry, *tmp;90 91	/* empty the queued pkts in the PS queue if any */92	spin_lock_bh(&sta->psq_lock);93	skb_queue_purge(&sta->psq);94	skb_queue_purge(&sta->apsdq);95 96	if (sta->mgmt_psq_len != 0) {97		list_for_each_entry_safe(entry, tmp, &sta->mgmt_psq, list) {98			kfree(entry);99		}100		INIT_LIST_HEAD(&sta->mgmt_psq);101		sta->mgmt_psq_len = 0;102	}103 104	spin_unlock_bh(&sta->psq_lock);105 106	memset(&ar->ap_stats.sta[sta->aid - 1], 0,107	       sizeof(struct wmi_per_sta_stat));108	eth_zero_addr(sta->mac);109	memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);110	sta->aid = 0;111	sta->sta_flags = 0;112 113	ar->sta_list_index = ar->sta_list_index & ~(1 << i);114	aggr_reset_state(sta->aggr_conn);115}116 117static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)118{119	u8 i, removed = 0;120 121	if (is_zero_ether_addr(mac))122		return removed;123 124	if (is_broadcast_ether_addr(mac)) {125		ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");126 127		for (i = 0; i < AP_MAX_NUM_STA; i++) {128			if (!is_zero_ether_addr(ar->sta_list[i].mac)) {129				ath6kl_sta_cleanup(ar, i);130				removed = 1;131			}132		}133	} else {134		for (i = 0; i < AP_MAX_NUM_STA; i++) {135			if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {136				ath6kl_dbg(ATH6KL_DBG_TRC,137					   "deleting station %pM aid=%d reason=%d\n",138					   mac, ar->sta_list[i].aid, reason);139				ath6kl_sta_cleanup(ar, i);140				removed = 1;141				break;142			}143		}144	}145 146	return removed;147}148 149enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)150{151	struct ath6kl *ar = devt;152	return ar->ac2ep_map[ac];153}154 155struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)156{157	struct ath6kl_cookie *cookie;158 159	cookie = ar->cookie_list;160	if (cookie != NULL) {161		ar->cookie_list = cookie->arc_list_next;162		ar->cookie_count--;163	}164 165	return cookie;166}167 168void ath6kl_cookie_init(struct ath6kl *ar)169{170	u32 i;171 172	ar->cookie_list = NULL;173	ar->cookie_count = 0;174 175	memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));176 177	for (i = 0; i < MAX_COOKIE_NUM; i++)178		ath6kl_free_cookie(ar, &ar->cookie_mem[i]);179}180 181void ath6kl_cookie_cleanup(struct ath6kl *ar)182{183	ar->cookie_list = NULL;184	ar->cookie_count = 0;185}186 187void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)188{189	/* Insert first */190 191	if (!ar || !cookie)192		return;193 194	cookie->arc_list_next = ar->cookie_list;195	ar->cookie_list = cookie;196	ar->cookie_count++;197}198 199/*200 * Read from the hardware through its diagnostic window. No cooperation201 * from the firmware is required for this.202 */203int ath6kl_diag_read32(struct ath6kl *ar, u32 address, u32 *value)204{205	int ret;206 207	ret = ath6kl_hif_diag_read32(ar, address, value);208	if (ret) {209		ath6kl_warn("failed to read32 through diagnose window: %d\n",210			    ret);211		return ret;212	}213 214	return 0;215}216 217/*218 * Write to the ATH6KL through its diagnostic window. No cooperation from219 * the Target is required for this.220 */221int ath6kl_diag_write32(struct ath6kl *ar, u32 address, __le32 value)222{223	int ret;224 225	ret = ath6kl_hif_diag_write32(ar, address, value);226 227	if (ret) {228		ath6kl_err("failed to write 0x%x during diagnose window to 0x%x\n",229			   address, value);230		return ret;231	}232 233	return 0;234}235 236int ath6kl_diag_read(struct ath6kl *ar, u32 address, void *data, u32 length)237{238	u32 count, *buf = data;239	int ret;240 241	if (WARN_ON(length % 4))242		return -EINVAL;243 244	for (count = 0; count < length / 4; count++, address += 4) {245		ret = ath6kl_diag_read32(ar, address, &buf[count]);246		if (ret)247			return ret;248	}249 250	return 0;251}252 253int ath6kl_diag_write(struct ath6kl *ar, u32 address, void *data, u32 length)254{255	u32 count;256	__le32 *buf = data;257	int ret;258 259	if (WARN_ON(length % 4))260		return -EINVAL;261 262	for (count = 0; count < length / 4; count++, address += 4) {263		ret = ath6kl_diag_write32(ar, address, buf[count]);264		if (ret)265			return ret;266	}267 268	return 0;269}270 271int ath6kl_read_fwlogs(struct ath6kl *ar)272{273	struct ath6kl_dbglog_hdr debug_hdr;274	struct ath6kl_dbglog_buf debug_buf;275	u32 address, length, firstbuf, debug_hdr_addr;276	int ret, loop;277	u8 *buf;278 279	buf = kmalloc(ATH6KL_FWLOG_PAYLOAD_SIZE, GFP_KERNEL);280	if (!buf)281		return -ENOMEM;282 283	address = TARG_VTOP(ar->target_type,284			    ath6kl_get_hi_item_addr(ar,285						    HI_ITEM(hi_dbglog_hdr)));286 287	ret = ath6kl_diag_read32(ar, address, &debug_hdr_addr);288	if (ret)289		goto out;290 291	/* Get the contents of the ring buffer */292	if (debug_hdr_addr == 0) {293		ath6kl_warn("Invalid address for debug_hdr_addr\n");294		ret = -EINVAL;295		goto out;296	}297 298	address = TARG_VTOP(ar->target_type, debug_hdr_addr);299	ret = ath6kl_diag_read(ar, address, &debug_hdr, sizeof(debug_hdr));300	if (ret)301		goto out;302 303	address = TARG_VTOP(ar->target_type,304			    le32_to_cpu(debug_hdr.dbuf_addr));305	firstbuf = address;306	ret = ath6kl_diag_read(ar, address, &debug_buf, sizeof(debug_buf));307	if (ret)308		goto out;309 310	loop = 100;311 312	do {313		address = TARG_VTOP(ar->target_type,314				    le32_to_cpu(debug_buf.buffer_addr));315		length = le32_to_cpu(debug_buf.length);316 317		if (length != 0 && (le32_to_cpu(debug_buf.length) <=318				    le32_to_cpu(debug_buf.bufsize))) {319			length = ALIGN(length, 4);320 321			ret = ath6kl_diag_read(ar, address,322					       buf, length);323			if (ret)324				goto out;325 326			ath6kl_debug_fwlog_event(ar, buf, length);327		}328 329		address = TARG_VTOP(ar->target_type,330				    le32_to_cpu(debug_buf.next));331		ret = ath6kl_diag_read(ar, address, &debug_buf,332				       sizeof(debug_buf));333		if (ret)334			goto out;335 336		loop--;337 338		if (WARN_ON(loop == 0)) {339			ret = -ETIMEDOUT;340			goto out;341		}342	} while (address != firstbuf);343 344out:345	kfree(buf);346 347	return ret;348}349 350static void ath6kl_install_static_wep_keys(struct ath6kl_vif *vif)351{352	u8 index;353	u8 keyusage;354 355	for (index = 0; index <= WMI_MAX_KEY_INDEX; index++) {356		if (vif->wep_key_list[index].key_len) {357			keyusage = GROUP_USAGE;358			if (index == vif->def_txkey_index)359				keyusage |= TX_USAGE;360 361			ath6kl_wmi_addkey_cmd(vif->ar->wmi, vif->fw_vif_idx,362					      index,363					      WEP_CRYPT,364					      keyusage,365					      vif->wep_key_list[index].key_len,366					      NULL, 0,367					      vif->wep_key_list[index].key,368					      KEY_OP_INIT_VAL, NULL,369					      NO_SYNC_WMIFLAG);370		}371	}372}373 374void ath6kl_connect_ap_mode_bss(struct ath6kl_vif *vif, u16 channel)375{376	struct ath6kl *ar = vif->ar;377	struct ath6kl_req_key *ik;378	int res;379	u8 key_rsc[ATH6KL_KEY_SEQ_LEN];380 381	ik = &ar->ap_mode_bkey;382 383	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "AP mode started on %u MHz\n", channel);384 385	switch (vif->auth_mode) {386	case NONE_AUTH:387		if (vif->prwise_crypto == WEP_CRYPT)388			ath6kl_install_static_wep_keys(vif);389		if (!ik->valid || ik->key_type != WAPI_CRYPT)390			break;391		/* for WAPI, we need to set the delayed group key, continue: */392		fallthrough;393	case WPA_PSK_AUTH:394	case WPA2_PSK_AUTH:395	case (WPA_PSK_AUTH | WPA2_PSK_AUTH):396		if (!ik->valid)397			break;398 399		ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,400			   "Delayed addkey for the initial group key for AP mode\n");401		memset(key_rsc, 0, sizeof(key_rsc));402		res = ath6kl_wmi_addkey_cmd(403			ar->wmi, vif->fw_vif_idx, ik->key_index, ik->key_type,404			GROUP_USAGE, ik->key_len, key_rsc, ATH6KL_KEY_SEQ_LEN,405			ik->key,406			KEY_OP_INIT_VAL, NULL, SYNC_BOTH_WMIFLAG);407		if (res) {408			ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,409				   "Delayed addkey failed: %d\n", res);410		}411		break;412	}413 414	if (ar->last_ch != channel)415		/* we actually don't know the phymode, default to HT20 */416		ath6kl_cfg80211_ch_switch_notify(vif, channel, WMI_11G_HT20);417 418	ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx, NONE_BSS_FILTER, 0);419	set_bit(CONNECTED, &vif->flags);420	netif_carrier_on(vif->ndev);421}422 423void ath6kl_connect_ap_mode_sta(struct ath6kl_vif *vif, u16 aid, u8 *mac_addr,424				u8 keymgmt, u8 ucipher, u8 auth,425				u8 assoc_req_len, u8 *assoc_info, u8 apsd_info)426{427	u8 *ies = NULL, *wpa_ie = NULL, *pos;428	size_t ies_len = 0;429	struct station_info *sinfo;430 431	ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n", mac_addr, aid);432 433	if (aid < 1 || aid > AP_MAX_NUM_STA)434		return;435 436	if (assoc_req_len > sizeof(struct ieee80211_hdr_3addr)) {437		struct ieee80211_mgmt *mgmt =438			(struct ieee80211_mgmt *) assoc_info;439		if (ieee80211_is_assoc_req(mgmt->frame_control) &&440		    assoc_req_len >= sizeof(struct ieee80211_hdr_3addr) +441		    sizeof(mgmt->u.assoc_req)) {442			ies = mgmt->u.assoc_req.variable;443			ies_len = assoc_info + assoc_req_len - ies;444		} else if (ieee80211_is_reassoc_req(mgmt->frame_control) &&445			   assoc_req_len >= sizeof(struct ieee80211_hdr_3addr)446			   + sizeof(mgmt->u.reassoc_req)) {447			ies = mgmt->u.reassoc_req.variable;448			ies_len = assoc_info + assoc_req_len - ies;449		}450	}451 452	pos = ies;453	while (pos && pos + 1 < ies + ies_len) {454		if (pos + 2 + pos[1] > ies + ies_len)455			break;456		if (pos[0] == WLAN_EID_RSN)457			wpa_ie = pos; /* RSN IE */458		else if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&459			 pos[1] >= 4 &&460			 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2) {461			if (pos[5] == 0x01)462				wpa_ie = pos; /* WPA IE */463			else if (pos[5] == 0x04) {464				wpa_ie = pos; /* WPS IE */465				break; /* overrides WPA/RSN IE */466			}467		} else if (pos[0] == 0x44 && wpa_ie == NULL) {468			/*469			 * Note: WAPI Parameter Set IE re-uses Element ID that470			 * was officially allocated for BSS AC Access Delay. As471			 * such, we need to be a bit more careful on when472			 * parsing the frame. However, BSS AC Access Delay473			 * element is not supposed to be included in474			 * (Re)Association Request frames, so this should not475			 * cause problems.476			 */477			wpa_ie = pos; /* WAPI IE */478			break;479		}480		pos += 2 + pos[1];481	}482 483	ath6kl_add_new_sta(vif, mac_addr, aid, wpa_ie,484			   wpa_ie ? 2 + wpa_ie[1] : 0,485			   keymgmt, ucipher, auth, apsd_info);486 487	/* send event to application */488	sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);489	if (!sinfo)490		return;491 492	/* TODO: sinfo.generation */493 494	sinfo->assoc_req_ies = ies;495	sinfo->assoc_req_ies_len = ies_len;496 497	cfg80211_new_sta(vif->ndev, mac_addr, sinfo, GFP_KERNEL);498 499	netif_wake_queue(vif->ndev);500 501	kfree(sinfo);502}503 504void disconnect_timer_handler(struct timer_list *t)505{506	struct ath6kl_vif *vif = from_timer(vif, t, disconnect_timer);507 508	ath6kl_init_profile_info(vif);509	ath6kl_disconnect(vif);510}511 512void ath6kl_disconnect(struct ath6kl_vif *vif)513{514	if (test_bit(CONNECTED, &vif->flags) ||515	    test_bit(CONNECT_PEND, &vif->flags)) {516		ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);517		/*518		 * Disconnect command is issued, clear the connect pending519		 * flag. The connected flag will be cleared in520		 * disconnect event notification.521		 */522		clear_bit(CONNECT_PEND, &vif->flags);523	}524}525 526/* WMI Event handlers */527 528void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver,529			enum wmi_phy_cap cap)530{531	struct ath6kl *ar = devt;532 533	memcpy(ar->mac_addr, datap, ETH_ALEN);534 535	ath6kl_dbg(ATH6KL_DBG_BOOT,536		   "ready event mac addr %pM sw_ver 0x%x abi_ver 0x%x cap 0x%x\n",537		   ar->mac_addr, sw_ver, abi_ver, cap);538 539	ar->version.wlan_ver = sw_ver;540	ar->version.abi_ver = abi_ver;541	ar->hw.cap = cap;542 543	if (strlen(ar->wiphy->fw_version) == 0) {544		snprintf(ar->wiphy->fw_version,545			 sizeof(ar->wiphy->fw_version),546			 "%u.%u.%u.%u",547			 (ar->version.wlan_ver & 0xf0000000) >> 28,548			 (ar->version.wlan_ver & 0x0f000000) >> 24,549			 (ar->version.wlan_ver & 0x00ff0000) >> 16,550			 (ar->version.wlan_ver & 0x0000ffff));551	}552 553	/* indicate to the waiting thread that the ready event was received */554	set_bit(WMI_READY, &ar->flag);555	wake_up(&ar->event_wq);556}557 558void ath6kl_scan_complete_evt(struct ath6kl_vif *vif, int status)559{560	struct ath6kl *ar = vif->ar;561	bool aborted = false;562 563	if (status != WMI_SCAN_STATUS_SUCCESS)564		aborted = true;565 566	ath6kl_cfg80211_scan_complete_event(vif, aborted);567 568	if (!ar->usr_bss_filter) {569		clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);570		ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,571					 NONE_BSS_FILTER, 0);572	}573 574	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "scan complete: %d\n", status);575}576 577static int ath6kl_commit_ch_switch(struct ath6kl_vif *vif, u16 channel)578{579	struct ath6kl *ar = vif->ar;580 581	vif->profile.ch = cpu_to_le16(channel);582 583	switch (vif->nw_type) {584	case AP_NETWORK:585		/*586		 * reconfigure any saved RSN IE capabilites in the beacon /587		 * probe response to stay in sync with the supplicant.588		 */589		if (vif->rsn_capab &&590		    test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,591			     ar->fw_capabilities))592			ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,593					      WLAN_EID_RSN, WMI_RSN_IE_CAPB,594					      (const u8 *) &vif->rsn_capab,595					      sizeof(vif->rsn_capab));596 597		return ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx,598						    &vif->profile);599	default:600		ath6kl_err("won't switch channels nw_type=%d\n", vif->nw_type);601		return -ENOTSUPP;602	}603}604 605static void ath6kl_check_ch_switch(struct ath6kl *ar, u16 channel)606{607	struct ath6kl_vif *vif;608	int res = 0;609 610	if (!ar->want_ch_switch)611		return;612 613	spin_lock_bh(&ar->list_lock);614	list_for_each_entry(vif, &ar->vif_list, list) {615		if (ar->want_ch_switch & (1 << vif->fw_vif_idx))616			res = ath6kl_commit_ch_switch(vif, channel);617 618		/* if channel switch failed, oh well we tried */619		ar->want_ch_switch &= ~(1 << vif->fw_vif_idx);620 621		if (res)622			ath6kl_err("channel switch failed nw_type %d res %d\n",623				   vif->nw_type, res);624	}625	spin_unlock_bh(&ar->list_lock);626}627 628void ath6kl_connect_event(struct ath6kl_vif *vif, u16 channel, u8 *bssid,629			  u16 listen_int, u16 beacon_int,630			  enum network_type net_type, u8 beacon_ie_len,631			  u8 assoc_req_len, u8 assoc_resp_len,632			  u8 *assoc_info)633{634	struct ath6kl *ar = vif->ar;635 636	ath6kl_cfg80211_connect_event(vif, channel, bssid,637				      listen_int, beacon_int,638				      net_type, beacon_ie_len,639				      assoc_req_len, assoc_resp_len,640				      assoc_info);641 642	memcpy(vif->bssid, bssid, sizeof(vif->bssid));643	vif->bss_ch = channel;644 645	if (vif->nw_type == INFRA_NETWORK) {646		ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,647					      vif->listen_intvl_t, 0);648		ath6kl_check_ch_switch(ar, channel);649	}650 651	netif_wake_queue(vif->ndev);652 653	/* Update connect & link status atomically */654	spin_lock_bh(&vif->if_lock);655	set_bit(CONNECTED, &vif->flags);656	clear_bit(CONNECT_PEND, &vif->flags);657	netif_carrier_on(vif->ndev);658	spin_unlock_bh(&vif->if_lock);659 660	aggr_reset_state(vif->aggr_cntxt->aggr_conn);661	vif->reconnect_flag = 0;662 663	if ((vif->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {664		memset(ar->node_map, 0, sizeof(ar->node_map));665		ar->node_num = 0;666		ar->next_ep_id = ENDPOINT_2;667	}668 669	if (!ar->usr_bss_filter) {670		set_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);671		ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,672					 CURRENT_BSS_FILTER, 0);673	}674}675 676void ath6kl_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid, bool ismcast)677{678	struct ath6kl_sta *sta;679	struct ath6kl *ar = vif->ar;680	u8 tsc[6];681 682	/*683	 * For AP case, keyid will have aid of STA which sent pkt with684	 * MIC error. Use this aid to get MAC & send it to hostapd.685	 */686	if (vif->nw_type == AP_NETWORK) {687		sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));688		if (!sta)689			return;690 691		ath6kl_dbg(ATH6KL_DBG_TRC,692			   "ap tkip mic error received from aid=%d\n", keyid);693 694		memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */695		cfg80211_michael_mic_failure(vif->ndev, sta->mac,696					     NL80211_KEYTYPE_PAIRWISE, keyid,697					     tsc, GFP_KERNEL);698	} else {699		ath6kl_cfg80211_tkip_micerr_event(vif, keyid, ismcast);700	}701}702 703static void ath6kl_update_target_stats(struct ath6kl_vif *vif, u8 *ptr, u32 len)704{705	struct wmi_target_stats *tgt_stats =706		(struct wmi_target_stats *) ptr;707	struct ath6kl *ar = vif->ar;708	struct target_stats *stats = &vif->target_stats;709	struct tkip_ccmp_stats *ccmp_stats;710	s32 rate;711	u8 ac;712 713	if (len < sizeof(*tgt_stats))714		return;715 716	ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");717 718	stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);719	stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);720	stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);721	stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);722	stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);723	stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);724	stats->tx_bcast_pkt  += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);725	stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);726	stats->tx_rts_success_cnt +=727		le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);728 729	for (ac = 0; ac < WMM_NUM_AC; ac++)730		stats->tx_pkt_per_ac[ac] +=731			le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);732 733	stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);734	stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);735	stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);736	stats->tx_mult_retry_cnt +=737		le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);738	stats->tx_rts_fail_cnt +=739		le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);740 741	rate = a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate);742	stats->tx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);743 744	stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);745	stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);746	stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);747	stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);748	stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);749	stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);750	stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);751	stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);752	stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);753	stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);754	stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);755	stats->rx_key_cache_miss +=756		le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);757	stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);758	stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);759 760	rate = a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate);761	stats->rx_ucast_rate = ath6kl_wmi_get_rate(ar->wmi, rate);762 763	ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;764 765	stats->tkip_local_mic_fail +=766		le32_to_cpu(ccmp_stats->tkip_local_mic_fail);767	stats->tkip_cnter_measures_invoked +=768		le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);769	stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);770 771	stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);772	stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);773 774	stats->pwr_save_fail_cnt +=775		le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);776	stats->noise_floor_calib =777		a_sle32_to_cpu(tgt_stats->noise_floor_calib);778 779	stats->cs_bmiss_cnt +=780		le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);781	stats->cs_low_rssi_cnt +=782		le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);783	stats->cs_connect_cnt +=784		le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);785	stats->cs_discon_cnt +=786		le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);787 788	stats->cs_ave_beacon_rssi =789		a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);790 791	stats->cs_last_roam_msec =792		tgt_stats->cserv_stats.cs_last_roam_msec;793	stats->cs_snr = tgt_stats->cserv_stats.cs_snr;794	stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);795 796	stats->lq_val = le32_to_cpu(tgt_stats->lq_val);797 798	stats->wow_pkt_dropped +=799		le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);800	stats->wow_host_pkt_wakeups +=801		tgt_stats->wow_stats.wow_host_pkt_wakeups;802	stats->wow_host_evt_wakeups +=803		tgt_stats->wow_stats.wow_host_evt_wakeups;804	stats->wow_evt_discarded +=805		le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);806 807	stats->arp_received = le32_to_cpu(tgt_stats->arp_stats.arp_received);808	stats->arp_replied = le32_to_cpu(tgt_stats->arp_stats.arp_replied);809	stats->arp_matched = le32_to_cpu(tgt_stats->arp_stats.arp_matched);810 811	if (test_bit(STATS_UPDATE_PEND, &vif->flags)) {812		clear_bit(STATS_UPDATE_PEND, &vif->flags);813		wake_up(&ar->event_wq);814	}815}816 817static void ath6kl_add_le32(__le32 *var, __le32 val)818{819	*var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));820}821 822void ath6kl_tgt_stats_event(struct ath6kl_vif *vif, u8 *ptr, u32 len)823{824	struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;825	struct ath6kl *ar = vif->ar;826	struct wmi_ap_mode_stat *ap = &ar->ap_stats;827	struct wmi_per_sta_stat *st_ap, *st_p;828	u8 ac;829 830	if (vif->nw_type == AP_NETWORK) {831		if (len < sizeof(*p))832			return;833 834		for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {835			st_ap = &ap->sta[ac];836			st_p = &p->sta[ac];837 838			ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);839			ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);840			ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);841			ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);842			ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);843			ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);844			ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);845			ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);846		}847 848	} else {849		ath6kl_update_target_stats(vif, ptr, len);850	}851}852 853void ath6kl_wakeup_event(void *dev)854{855	struct ath6kl *ar = dev;856 857	wake_up(&ar->event_wq);858}859 860void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)861{862	struct ath6kl *ar = devt;863 864	ar->tx_pwr = tx_pwr;865	wake_up(&ar->event_wq);866}867 868void ath6kl_pspoll_event(struct ath6kl_vif *vif, u8 aid)869{870	struct ath6kl_sta *conn;871	struct sk_buff *skb;872	bool psq_empty = false;873	struct ath6kl *ar = vif->ar;874	struct ath6kl_mgmt_buff *mgmt_buf;875 876	conn = ath6kl_find_sta_by_aid(ar, aid);877 878	if (!conn)879		return;880	/*881	 * Send out a packet queued on ps queue. When the ps queue882	 * becomes empty update the PVB for this station.883	 */884	spin_lock_bh(&conn->psq_lock);885	psq_empty  = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);886	spin_unlock_bh(&conn->psq_lock);887 888	if (psq_empty)889		/* TODO: Send out a NULL data frame */890		return;891 892	spin_lock_bh(&conn->psq_lock);893	if (conn->mgmt_psq_len > 0) {894		mgmt_buf = list_first_entry(&conn->mgmt_psq,895					struct ath6kl_mgmt_buff, list);896		list_del(&mgmt_buf->list);897		conn->mgmt_psq_len--;898		spin_unlock_bh(&conn->psq_lock);899 900		conn->sta_flags |= STA_PS_POLLED;901		ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx,902					 mgmt_buf->id, mgmt_buf->freq,903					 mgmt_buf->wait, mgmt_buf->buf,904					 mgmt_buf->len, mgmt_buf->no_cck);905		conn->sta_flags &= ~STA_PS_POLLED;906		kfree(mgmt_buf);907	} else {908		skb = skb_dequeue(&conn->psq);909		spin_unlock_bh(&conn->psq_lock);910 911		conn->sta_flags |= STA_PS_POLLED;912		ath6kl_data_tx(skb, vif->ndev);913		conn->sta_flags &= ~STA_PS_POLLED;914	}915 916	spin_lock_bh(&conn->psq_lock);917	psq_empty  = skb_queue_empty(&conn->psq) && (conn->mgmt_psq_len == 0);918	spin_unlock_bh(&conn->psq_lock);919 920	if (psq_empty)921		ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, conn->aid, 0);922}923 924void ath6kl_dtimexpiry_event(struct ath6kl_vif *vif)925{926	bool mcastq_empty = false;927	struct sk_buff *skb;928	struct ath6kl *ar = vif->ar;929 930	/*931	 * If there are no associated STAs, ignore the DTIM expiry event.932	 * There can be potential race conditions where the last associated933	 * STA may disconnect & before the host could clear the 'Indicate934	 * DTIM' request to the firmware, the firmware would have just935	 * indicated a DTIM expiry event. The race is between 'clear DTIM936	 * expiry cmd' going from the host to the firmware & the DTIM937	 * expiry event happening from the firmware to the host.938	 */939	if (!ar->sta_list_index)940		return;941 942	spin_lock_bh(&ar->mcastpsq_lock);943	mcastq_empty = skb_queue_empty(&ar->mcastpsq);944	spin_unlock_bh(&ar->mcastpsq_lock);945 946	if (mcastq_empty)947		return;948 949	/* set the STA flag to dtim_expired for the frame to go out */950	set_bit(DTIM_EXPIRED, &vif->flags);951 952	spin_lock_bh(&ar->mcastpsq_lock);953	while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {954		spin_unlock_bh(&ar->mcastpsq_lock);955 956		ath6kl_data_tx(skb, vif->ndev);957 958		spin_lock_bh(&ar->mcastpsq_lock);959	}960	spin_unlock_bh(&ar->mcastpsq_lock);961 962	clear_bit(DTIM_EXPIRED, &vif->flags);963 964	/* clear the LSB of the BitMapCtl field of the TIM IE */965	ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx, MCAST_AID, 0);966}967 968void ath6kl_disconnect_event(struct ath6kl_vif *vif, u8 reason, u8 *bssid,969			     u8 assoc_resp_len, u8 *assoc_info,970			     u16 prot_reason_status)971{972	struct ath6kl *ar = vif->ar;973 974	if (vif->nw_type == AP_NETWORK) {975		/* disconnect due to other STA vif switching channels */976		if (reason == BSS_DISCONNECTED &&977		    prot_reason_status == WMI_AP_REASON_STA_ROAM) {978			ar->want_ch_switch |= 1 << vif->fw_vif_idx;979			/* bail back to this channel if STA vif fails connect */980			ar->last_ch = le16_to_cpu(vif->profile.ch);981		}982 983		if (prot_reason_status == WMI_AP_REASON_MAX_STA) {984			/* send max client reached notification to user space */985			cfg80211_conn_failed(vif->ndev, bssid,986					     NL80211_CONN_FAIL_MAX_CLIENTS,987					     GFP_KERNEL);988		}989 990		if (prot_reason_status == WMI_AP_REASON_ACL) {991			/* send blocked client notification to user space */992			cfg80211_conn_failed(vif->ndev, bssid,993					     NL80211_CONN_FAIL_BLOCKED_CLIENT,994					     GFP_KERNEL);995		}996 997		if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))998			return;999 1000		/* if no more associated STAs, empty the mcast PS q */1001		if (ar->sta_list_index == 0) {1002			spin_lock_bh(&ar->mcastpsq_lock);1003			skb_queue_purge(&ar->mcastpsq);1004			spin_unlock_bh(&ar->mcastpsq_lock);1005 1006			/* clear the LSB of the TIM IE's BitMapCtl field */1007			if (test_bit(WMI_READY, &ar->flag))1008				ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,1009						       MCAST_AID, 0);1010		}1011 1012		if (!is_broadcast_ether_addr(bssid)) {1013			/* send event to application */1014			cfg80211_del_sta(vif->ndev, bssid, GFP_KERNEL);1015		}1016 1017		if (memcmp(vif->ndev->dev_addr, bssid, ETH_ALEN) == 0) {1018			memset(vif->wep_key_list, 0, sizeof(vif->wep_key_list));1019			clear_bit(CONNECTED, &vif->flags);1020		}1021		return;1022	}1023 1024	ath6kl_cfg80211_disconnect_event(vif, reason, bssid,1025					 assoc_resp_len, assoc_info,1026					 prot_reason_status);1027 1028	aggr_reset_state(vif->aggr_cntxt->aggr_conn);1029 1030	del_timer(&vif->disconnect_timer);1031 1032	ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "disconnect reason is %d\n", reason);1033 1034	/*1035	 * If the event is due to disconnect cmd from the host, only they1036	 * the target would stop trying to connect. Under any other1037	 * condition, target would keep trying to connect.1038	 */1039	if (reason == DISCONNECT_CMD) {1040		if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))1041			ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,1042						 NONE_BSS_FILTER, 0);1043	} else {1044		set_bit(CONNECT_PEND, &vif->flags);1045		if (((reason == ASSOC_FAILED) &&1046		     (prot_reason_status == 0x11)) ||1047		    ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0) &&1048		     (vif->reconnect_flag == 1))) {1049			set_bit(CONNECTED, &vif->flags);1050			return;1051		}1052	}1053 1054	/* restart disconnected concurrent vifs waiting for new channel */1055	ath6kl_check_ch_switch(ar, ar->last_ch);1056 1057	/* update connect & link status atomically */1058	spin_lock_bh(&vif->if_lock);1059	clear_bit(CONNECTED, &vif->flags);1060	netif_carrier_off(vif->ndev);1061	spin_unlock_bh(&vif->if_lock);1062 1063	if ((reason != CSERV_DISCONNECT) || (vif->reconnect_flag != 1))1064		vif->reconnect_flag = 0;1065 1066	if (reason != CSERV_DISCONNECT)1067		ar->user_key_ctrl = 0;1068 1069	netif_stop_queue(vif->ndev);1070	memset(vif->bssid, 0, sizeof(vif->bssid));1071	vif->bss_ch = 0;1072 1073	ath6kl_tx_data_cleanup(ar);1074}1075 1076struct ath6kl_vif *ath6kl_vif_first(struct ath6kl *ar)1077{1078	struct ath6kl_vif *vif;1079 1080	spin_lock_bh(&ar->list_lock);1081	if (list_empty(&ar->vif_list)) {1082		spin_unlock_bh(&ar->list_lock);1083		return NULL;1084	}1085 1086	vif = list_first_entry(&ar->vif_list, struct ath6kl_vif, list);1087 1088	spin_unlock_bh(&ar->list_lock);1089 1090	return vif;1091}1092 1093static int ath6kl_open(struct net_device *dev)1094{1095	struct ath6kl_vif *vif = netdev_priv(dev);1096 1097	set_bit(WLAN_ENABLED, &vif->flags);1098 1099	if (test_bit(CONNECTED, &vif->flags)) {1100		netif_carrier_on(dev);1101		netif_wake_queue(dev);1102	} else {1103		netif_carrier_off(dev);1104	}1105 1106	return 0;1107}1108 1109static int ath6kl_close(struct net_device *dev)1110{1111	struct ath6kl_vif *vif = netdev_priv(dev);1112 1113	netif_stop_queue(dev);1114 1115	ath6kl_cfg80211_stop(vif);1116 1117	clear_bit(WLAN_ENABLED, &vif->flags);1118 1119	return 0;1120}1121 1122static int ath6kl_set_features(struct net_device *dev,1123			       netdev_features_t features)1124{1125	struct ath6kl_vif *vif = netdev_priv(dev);1126	struct ath6kl *ar = vif->ar;1127	int err = 0;1128 1129	if ((features & NETIF_F_RXCSUM) &&1130	    (ar->rx_meta_ver != WMI_META_VERSION_2)) {1131		ar->rx_meta_ver = WMI_META_VERSION_2;1132		err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,1133							 vif->fw_vif_idx,1134							 ar->rx_meta_ver, 0, 0);1135		if (err) {1136			dev->features = features & ~NETIF_F_RXCSUM;1137			return err;1138		}1139	} else if (!(features & NETIF_F_RXCSUM) &&1140		   (ar->rx_meta_ver == WMI_META_VERSION_2)) {1141		ar->rx_meta_ver = 0;1142		err = ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,1143							 vif->fw_vif_idx,1144							 ar->rx_meta_ver, 0, 0);1145		if (err) {1146			dev->features = features | NETIF_F_RXCSUM;1147			return err;1148		}1149	}1150 1151	return err;1152}1153 1154static void ath6kl_set_multicast_list(struct net_device *ndev)1155{1156	struct ath6kl_vif *vif = netdev_priv(ndev);1157	bool mc_all_on = false;1158	int mc_count = netdev_mc_count(ndev);1159	struct netdev_hw_addr *ha;1160	bool found;1161	struct ath6kl_mc_filter *mc_filter, *tmp;1162	struct list_head mc_filter_new;1163	int ret;1164 1165	if (!test_bit(WMI_READY, &vif->ar->flag) ||1166	    !test_bit(WLAN_ENABLED, &vif->flags))1167		return;1168 1169	/* Enable multicast-all filter. */1170	mc_all_on = !!(ndev->flags & IFF_PROMISC) ||1171		    !!(ndev->flags & IFF_ALLMULTI) ||1172		    !!(mc_count > ATH6K_MAX_MC_FILTERS_PER_LIST);1173 1174	if (mc_all_on)1175		set_bit(NETDEV_MCAST_ALL_ON, &vif->flags);1176	else1177		clear_bit(NETDEV_MCAST_ALL_ON, &vif->flags);1178 1179	if (test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,1180		     vif->ar->fw_capabilities)) {1181		mc_all_on = mc_all_on || (vif->ar->state == ATH6KL_STATE_ON);1182	}1183 1184	if (!(ndev->flags & IFF_MULTICAST)) {1185		mc_all_on = false;1186		set_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);1187	} else {1188		clear_bit(NETDEV_MCAST_ALL_OFF, &vif->flags);1189	}1190 1191	/* Enable/disable "multicast-all" filter*/1192	ath6kl_dbg(ATH6KL_DBG_TRC, "%s multicast-all filter\n",1193		   mc_all_on ? "enabling" : "disabling");1194 1195	ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi, vif->fw_vif_idx,1196						  mc_all_on);1197	if (ret) {1198		ath6kl_warn("Failed to %s multicast-all receive\n",1199			    mc_all_on ? "enable" : "disable");1200		return;1201	}1202 1203	if (test_bit(NETDEV_MCAST_ALL_ON, &vif->flags))1204		return;1205 1206	/* Keep the driver and firmware mcast list in sync. */1207	list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {1208		found = false;1209		netdev_for_each_mc_addr(ha, ndev) {1210			if (memcmp(ha->addr, mc_filter->hw_addr,1211				   ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {1212				found = true;1213				break;1214			}1215		}1216 1217		if (!found) {1218			/*1219			 * Delete the filter which was previously set1220			 * but not in the new request.1221			 */1222			ath6kl_dbg(ATH6KL_DBG_TRC,1223				   "Removing %pM from multicast filter\n",1224				   mc_filter->hw_addr);1225			ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,1226					vif->fw_vif_idx, mc_filter->hw_addr,1227					false);1228			if (ret) {1229				ath6kl_warn("Failed to remove multicast filter:%pM\n",1230					    mc_filter->hw_addr);1231				return;1232			}1233 1234			list_del(&mc_filter->list);1235			kfree(mc_filter);1236		}1237	}1238 1239	INIT_LIST_HEAD(&mc_filter_new);1240 1241	netdev_for_each_mc_addr(ha, ndev) {1242		found = false;1243		list_for_each_entry(mc_filter, &vif->mc_filter, list) {1244			if (memcmp(ha->addr, mc_filter->hw_addr,1245				   ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE) == 0) {1246				found = true;1247				break;1248			}1249		}1250 1251		if (!found) {1252			mc_filter = kzalloc(sizeof(struct ath6kl_mc_filter),1253					    GFP_ATOMIC);1254			if (!mc_filter) {1255				WARN_ON(1);1256				goto out;1257			}1258 1259			memcpy(mc_filter->hw_addr, ha->addr,1260			       ATH6KL_MCAST_FILTER_MAC_ADDR_SIZE);1261			/* Set the multicast filter */1262			ath6kl_dbg(ATH6KL_DBG_TRC,1263				   "Adding %pM to multicast filter list\n",1264				   mc_filter->hw_addr);1265			ret = ath6kl_wmi_add_del_mcast_filter_cmd(vif->ar->wmi,1266					vif->fw_vif_idx, mc_filter->hw_addr,1267					true);1268			if (ret) {1269				ath6kl_warn("Failed to add multicast filter :%pM\n",1270					    mc_filter->hw_addr);1271				kfree(mc_filter);1272				goto out;1273			}1274 1275			list_add_tail(&mc_filter->list, &mc_filter_new);1276		}1277	}1278 1279out:1280	list_splice_tail(&mc_filter_new, &vif->mc_filter);1281}1282 1283static const struct net_device_ops ath6kl_netdev_ops = {1284	.ndo_open               = ath6kl_open,1285	.ndo_stop               = ath6kl_close,1286	.ndo_start_xmit         = ath6kl_data_tx,1287	.ndo_set_features       = ath6kl_set_features,1288	.ndo_set_rx_mode	= ath6kl_set_multicast_list,1289};1290 1291void init_netdev(struct net_device *dev)1292{1293	struct ath6kl *ar = ath6kl_priv(dev);1294 1295	dev->netdev_ops = &ath6kl_netdev_ops;1296	dev->needs_free_netdev = true;1297	dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;1298 1299	dev->needed_headroom = ETH_HLEN;1300	dev->needed_headroom += roundup(sizeof(struct ath6kl_llc_snap_hdr) +1301					sizeof(struct wmi_data_hdr) +1302					HTC_HDR_LENGTH +1303					WMI_MAX_TX_META_SZ +1304					ATH6KL_HTC_ALIGN_BYTES, 4);1305 1306	if (!test_bit(ATH6KL_FW_CAPABILITY_NO_IP_CHECKSUM,1307		      ar->fw_capabilities))1308		dev->hw_features |= NETIF_F_IP_CSUM | NETIF_F_RXCSUM;1309 1310	return;1311}1312