xref: /freebsd/sys/dev/iwm/if_iwm_sf.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
1cd684decSAdrian Chadd /*
2cd684decSAdrian Chadd  * Copyright (c) 2014 genua mbh <info@genua.de>
3cd684decSAdrian Chadd  * Copyright (c) 2014 Fixup Software Ltd.
4cd684decSAdrian Chadd  *
5cd684decSAdrian Chadd  * Permission to use, copy, modify, and distribute this software for any
6cd684decSAdrian Chadd  * purpose with or without fee is hereby granted, provided that the above
7cd684decSAdrian Chadd  * copyright notice and this permission notice appear in all copies.
8cd684decSAdrian Chadd  *
9cd684decSAdrian Chadd  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10cd684decSAdrian Chadd  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11cd684decSAdrian Chadd  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12cd684decSAdrian Chadd  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13cd684decSAdrian Chadd  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14cd684decSAdrian Chadd  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15cd684decSAdrian Chadd  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16cd684decSAdrian Chadd  */
17cd684decSAdrian Chadd 
18cd684decSAdrian Chadd /*-
19cd684decSAdrian Chadd  * Based on BSD-licensed source modules in the Linux iwlwifi driver,
20cd684decSAdrian Chadd  * which were used as the reference documentation for this implementation.
21cd684decSAdrian Chadd  *
22cd684decSAdrian Chadd  * Driver version we are currently based off of is
23cd684decSAdrian Chadd  * Linux 4.7.3 (tag id d7f6728f57e3ecbb7ef34eb7d9f564d514775d75)
24cd684decSAdrian Chadd  *
25cd684decSAdrian Chadd  ******************************************************************************
26cd684decSAdrian Chadd  *
27cd684decSAdrian Chadd  * This file is provided under a dual BSD/GPLv2 license.  When using or
28cd684decSAdrian Chadd  * redistributing this file, you may do so under either license.
29cd684decSAdrian Chadd  *
30cd684decSAdrian Chadd  * GPL LICENSE SUMMARY
31cd684decSAdrian Chadd  *
32cd684decSAdrian Chadd  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
33cd684decSAdrian Chadd  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
34cd684decSAdrian Chadd  *
35cd684decSAdrian Chadd  * This program is free software; you can redistribute it and/or modify
36cd684decSAdrian Chadd  * it under the terms of version 2 of the GNU General Public License as
37cd684decSAdrian Chadd  * published by the Free Software Foundation.
38cd684decSAdrian Chadd  *
39cd684decSAdrian Chadd  * This program is distributed in the hope that it will be useful, but
40cd684decSAdrian Chadd  * WITHOUT ANY WARRANTY; without even the implied warranty of
41cd684decSAdrian Chadd  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
42cd684decSAdrian Chadd  * General Public License for more details.
43cd684decSAdrian Chadd  *
44cd684decSAdrian Chadd  * You should have received a copy of the GNU General Public License
45cd684decSAdrian Chadd  * along with this program; if not, write to the Free Software
46cd684decSAdrian Chadd  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
47cd684decSAdrian Chadd  * USA
48cd684decSAdrian Chadd  *
49cd684decSAdrian Chadd  * The full GNU General Public License is included in this distribution
50cd684decSAdrian Chadd  * in the file called COPYING.
51cd684decSAdrian Chadd  *
52cd684decSAdrian Chadd  * Contact Information:
53cd684decSAdrian Chadd  *  Intel Linux Wireless <linuxwifi@intel.com>
54cd684decSAdrian Chadd  * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
55cd684decSAdrian Chadd  *
56cd684decSAdrian Chadd  * BSD LICENSE
57cd684decSAdrian Chadd  *
58cd684decSAdrian Chadd  * Copyright(c) 2013 - 2014 Intel Corporation. All rights reserved.
59cd684decSAdrian Chadd  * Copyright(c) 2013 - 2014 Intel Mobile Communications GmbH
60cd684decSAdrian Chadd  * All rights reserved.
61cd684decSAdrian Chadd  *
62cd684decSAdrian Chadd  * Redistribution and use in source and binary forms, with or without
63cd684decSAdrian Chadd  * modification, are permitted provided that the following conditions
64cd684decSAdrian Chadd  * are met:
65cd684decSAdrian Chadd  *
66cd684decSAdrian Chadd  *  * Redistributions of source code must retain the above copyright
67cd684decSAdrian Chadd  *    notice, this list of conditions and the following disclaimer.
68cd684decSAdrian Chadd  *  * Redistributions in binary form must reproduce the above copyright
69cd684decSAdrian Chadd  *    notice, this list of conditions and the following disclaimer in
70cd684decSAdrian Chadd  *    the documentation and/or other materials provided with the
71cd684decSAdrian Chadd  *    distribution.
72cd684decSAdrian Chadd  *  * Neither the name Intel Corporation nor the names of its
73cd684decSAdrian Chadd  *    contributors may be used to endorse or promote products derived
74cd684decSAdrian Chadd  *    from this software without specific prior written permission.
75cd684decSAdrian Chadd  *
76cd684decSAdrian Chadd  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
77cd684decSAdrian Chadd  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
78cd684decSAdrian Chadd  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
79cd684decSAdrian Chadd  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
80cd684decSAdrian Chadd  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
81cd684decSAdrian Chadd  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
82cd684decSAdrian Chadd  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
83cd684decSAdrian Chadd  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
84cd684decSAdrian Chadd  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
85cd684decSAdrian Chadd  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
86cd684decSAdrian Chadd  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
87cd684decSAdrian Chadd  *
88cd684decSAdrian Chadd  *****************************************************************************/
89cd684decSAdrian Chadd 
90cd684decSAdrian Chadd #include <sys/cdefs.h>
91cd684decSAdrian Chadd #include "opt_wlan.h"
92cd684decSAdrian Chadd #include "opt_iwm.h"
93cd684decSAdrian Chadd 
94cd684decSAdrian Chadd #include <sys/param.h>
95cd684decSAdrian Chadd #include <sys/bus.h>
96cd684decSAdrian Chadd #include <sys/conf.h>
97cd684decSAdrian Chadd #include <sys/endian.h>
98cd684decSAdrian Chadd #include <sys/firmware.h>
99cd684decSAdrian Chadd #include <sys/kernel.h>
100cd684decSAdrian Chadd #include <sys/malloc.h>
101cd684decSAdrian Chadd #include <sys/mbuf.h>
102cd684decSAdrian Chadd #include <sys/mutex.h>
103cd684decSAdrian Chadd #include <sys/module.h>
104cd684decSAdrian Chadd #include <sys/proc.h>
105cd684decSAdrian Chadd #include <sys/rman.h>
106cd684decSAdrian Chadd #include <sys/socket.h>
107cd684decSAdrian Chadd #include <sys/sockio.h>
108cd684decSAdrian Chadd #include <sys/sysctl.h>
109cd684decSAdrian Chadd #include <sys/linker.h>
110cd684decSAdrian Chadd 
111cd684decSAdrian Chadd #include <machine/bus.h>
112cd684decSAdrian Chadd #include <machine/endian.h>
113cd684decSAdrian Chadd #include <machine/resource.h>
114cd684decSAdrian Chadd 
115cd684decSAdrian Chadd #include <net/if.h>
116cd684decSAdrian Chadd #include <net/if_var.h>
117cd684decSAdrian Chadd #include <net/if_arp.h>
118cd684decSAdrian Chadd #include <net/if_dl.h>
119cd684decSAdrian Chadd #include <net/if_media.h>
120cd684decSAdrian Chadd #include <net/if_types.h>
121cd684decSAdrian Chadd #include <net/bpf.h>
122cd684decSAdrian Chadd 
123cd684decSAdrian Chadd #include <netinet/in.h>
124cd684decSAdrian Chadd #include <netinet/in_systm.h>
125cd684decSAdrian Chadd #include <netinet/if_ether.h>
126cd684decSAdrian Chadd #include <netinet/ip.h>
127cd684decSAdrian Chadd 
128cd684decSAdrian Chadd #include <net80211/ieee80211_var.h>
129cd684decSAdrian Chadd #include <net80211/ieee80211_regdomain.h>
130cd684decSAdrian Chadd #include <net80211/ieee80211_ratectl.h>
131cd684decSAdrian Chadd #include <net80211/ieee80211_radiotap.h>
132cd684decSAdrian Chadd 
133cd684decSAdrian Chadd #include <dev/iwm/if_iwmreg.h>
134cd684decSAdrian Chadd #include <dev/iwm/if_iwmvar.h>
135cd684decSAdrian Chadd #include <dev/iwm/if_iwm_config.h>
136cd684decSAdrian Chadd #include <dev/iwm/if_iwm_debug.h>
137cd684decSAdrian Chadd #include <dev/iwm/if_iwm_util.h>
138cd684decSAdrian Chadd #include <dev/iwm/if_iwm_sf.h>
139cd684decSAdrian Chadd 
140cd684decSAdrian Chadd /*
141cd684decSAdrian Chadd  * Aging and idle timeouts for the different possible scenarios
142cd684decSAdrian Chadd  * in default configuration
143cd684decSAdrian Chadd  */
144cd684decSAdrian Chadd static const uint32_t
145cd684decSAdrian Chadd sf_full_timeout_def[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
146cd684decSAdrian Chadd 	{
147cd684decSAdrian Chadd 		htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER_DEF),
148cd684decSAdrian Chadd 		htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
149cd684decSAdrian Chadd 	},
150cd684decSAdrian Chadd 	{
151cd684decSAdrian Chadd 		htole32(IWM_SF_AGG_UNICAST_AGING_TIMER_DEF),
152cd684decSAdrian Chadd 		htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER_DEF)
153cd684decSAdrian Chadd 	},
154cd684decSAdrian Chadd 	{
155cd684decSAdrian Chadd 		htole32(IWM_SF_MCAST_AGING_TIMER_DEF),
156cd684decSAdrian Chadd 		htole32(IWM_SF_MCAST_IDLE_TIMER_DEF)
157cd684decSAdrian Chadd 	},
158cd684decSAdrian Chadd 	{
159cd684decSAdrian Chadd 		htole32(IWM_SF_BA_AGING_TIMER_DEF),
160cd684decSAdrian Chadd 		htole32(IWM_SF_BA_IDLE_TIMER_DEF)
161cd684decSAdrian Chadd 	},
162cd684decSAdrian Chadd 	{
163cd684decSAdrian Chadd 		htole32(IWM_SF_TX_RE_AGING_TIMER_DEF),
164cd684decSAdrian Chadd 		htole32(IWM_SF_TX_RE_IDLE_TIMER_DEF)
165cd684decSAdrian Chadd 	},
166cd684decSAdrian Chadd };
167cd684decSAdrian Chadd 
168cd684decSAdrian Chadd /*
169cd684decSAdrian Chadd  * Aging and idle timeouts for the different possible scenarios
170cd684decSAdrian Chadd  * in single BSS MAC configuration.
171cd684decSAdrian Chadd  */
172cd684decSAdrian Chadd static const uint32_t
173cd684decSAdrian Chadd sf_full_timeout[IWM_SF_NUM_SCENARIO][IWM_SF_NUM_TIMEOUT_TYPES] = {
174cd684decSAdrian Chadd 	{
175cd684decSAdrian Chadd 		htole32(IWM_SF_SINGLE_UNICAST_AGING_TIMER),
176cd684decSAdrian Chadd 		htole32(IWM_SF_SINGLE_UNICAST_IDLE_TIMER)
177cd684decSAdrian Chadd 	},
178cd684decSAdrian Chadd 	{
179cd684decSAdrian Chadd 		htole32(IWM_SF_AGG_UNICAST_AGING_TIMER),
180cd684decSAdrian Chadd 		htole32(IWM_SF_AGG_UNICAST_IDLE_TIMER)
181cd684decSAdrian Chadd 	},
182cd684decSAdrian Chadd 	{
183cd684decSAdrian Chadd 		htole32(IWM_SF_MCAST_AGING_TIMER),
184cd684decSAdrian Chadd 		htole32(IWM_SF_MCAST_IDLE_TIMER)
185cd684decSAdrian Chadd 	},
186cd684decSAdrian Chadd 	{
187cd684decSAdrian Chadd 		htole32(IWM_SF_BA_AGING_TIMER),
188cd684decSAdrian Chadd 		htole32(IWM_SF_BA_IDLE_TIMER)
189cd684decSAdrian Chadd 	},
190cd684decSAdrian Chadd 	{
191cd684decSAdrian Chadd 		htole32(IWM_SF_TX_RE_AGING_TIMER),
192cd684decSAdrian Chadd 		htole32(IWM_SF_TX_RE_IDLE_TIMER)
193cd684decSAdrian Chadd 	},
194cd684decSAdrian Chadd };
195cd684decSAdrian Chadd 
196cd684decSAdrian Chadd static void
iwm_fill_sf_command(struct iwm_softc * sc,struct iwm_sf_cfg_cmd * sf_cmd,struct ieee80211_node * ni)197*e7065dd1SMark Johnston iwm_fill_sf_command(struct iwm_softc *sc, struct iwm_sf_cfg_cmd *sf_cmd,
198cd684decSAdrian Chadd 	struct ieee80211_node *ni)
199cd684decSAdrian Chadd {
200cd684decSAdrian Chadd 	int i, j, watermark;
201cd684decSAdrian Chadd 
202cd684decSAdrian Chadd 	sf_cmd->watermark[IWM_SF_LONG_DELAY_ON] = htole32(IWM_SF_W_MARK_SCAN);
203cd684decSAdrian Chadd 
204cd684decSAdrian Chadd 	/*
205cd684decSAdrian Chadd 	 * If we are in association flow - check antenna configuration
206cd684decSAdrian Chadd 	 * capabilities of the AP station, and choose the watermark accordingly.
207cd684decSAdrian Chadd 	 */
208cd684decSAdrian Chadd 	if (ni) {
209cd684decSAdrian Chadd 		if (ni->ni_flags & IEEE80211_NODE_HT) {
210cd684decSAdrian Chadd 			watermark = IWM_SF_W_MARK_SISO;
211cd684decSAdrian Chadd 		} else {
212cd684decSAdrian Chadd 			watermark = IWM_SF_W_MARK_LEGACY;
213cd684decSAdrian Chadd 		}
214cd684decSAdrian Chadd 	/* default watermark value for unassociated mode. */
215cd684decSAdrian Chadd 	} else {
216cd684decSAdrian Chadd 		watermark = IWM_SF_W_MARK_MIMO2;
217cd684decSAdrian Chadd 	}
218cd684decSAdrian Chadd 	sf_cmd->watermark[IWM_SF_FULL_ON] = htole32(watermark);
219cd684decSAdrian Chadd 
220cd684decSAdrian Chadd 	for (i = 0; i < IWM_SF_NUM_SCENARIO; i++) {
221cd684decSAdrian Chadd 		for (j = 0; j < IWM_SF_NUM_TIMEOUT_TYPES; j++) {
222cd684decSAdrian Chadd 			sf_cmd->long_delay_timeouts[i][j] =
223cd684decSAdrian Chadd 					htole32(IWM_SF_LONG_DELAY_AGING_TIMER);
224cd684decSAdrian Chadd 		}
225cd684decSAdrian Chadd 	}
226cd684decSAdrian Chadd 
227cd684decSAdrian Chadd 	if (ni) {
228cd684decSAdrian Chadd 		_Static_assert(sizeof(sf_full_timeout) == sizeof(uint32_t) *
229cd684decSAdrian Chadd 		    IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
230cd684decSAdrian Chadd 		    "sf_full_timeout has wrong size");
231cd684decSAdrian Chadd 
232cd684decSAdrian Chadd 		memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
233cd684decSAdrian Chadd 		       sizeof(sf_full_timeout));
234cd684decSAdrian Chadd 	} else {
235cd684decSAdrian Chadd 		_Static_assert(sizeof(sf_full_timeout_def) == sizeof(uint32_t) *
236cd684decSAdrian Chadd 		    IWM_SF_NUM_SCENARIO * IWM_SF_NUM_TIMEOUT_TYPES,
237cd684decSAdrian Chadd 		    "sf_full_timeout_def has wrong size");
238cd684decSAdrian Chadd 
239cd684decSAdrian Chadd 		memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def,
240cd684decSAdrian Chadd 		       sizeof(sf_full_timeout_def));
241cd684decSAdrian Chadd 	}
242cd684decSAdrian Chadd }
243cd684decSAdrian Chadd 
244cd684decSAdrian Chadd static int
iwm_sf_config(struct iwm_softc * sc,struct ieee80211_node * ni,enum iwm_sf_state new_state)245*e7065dd1SMark Johnston iwm_sf_config(struct iwm_softc *sc, struct ieee80211_node *ni,
246cd684decSAdrian Chadd 	enum iwm_sf_state new_state)
247cd684decSAdrian Chadd {
248cd684decSAdrian Chadd 	struct iwm_sf_cfg_cmd sf_cmd = {
249eecff6a7SAdrian Chadd 		.state = htole32(new_state),
250cd684decSAdrian Chadd 	};
251cd684decSAdrian Chadd 	int ret = 0;
252cd684decSAdrian Chadd 
253cd684decSAdrian Chadd #ifdef notyet	/* only relevant for sdio variants */
254cd684decSAdrian Chadd 	if (sc->cfg->disable_dummy_notification)
255cd684decSAdrian Chadd 		sf_cmd.state |= htole32(IWM_SF_CFG_DUMMY_NOTIF_OFF);
256cd684decSAdrian Chadd #endif
257cd684decSAdrian Chadd 
258cd684decSAdrian Chadd 	/*
259cd684decSAdrian Chadd 	 * If an associated AP sta changed its antenna configuration, the state
260cd684decSAdrian Chadd 	 * will remain FULL_ON but SF parameters need to be reconsidered.
261cd684decSAdrian Chadd 	 */
262cd684decSAdrian Chadd 	if (new_state != IWM_SF_FULL_ON && sc->sf_state == new_state)
263cd684decSAdrian Chadd 		return 0;
264cd684decSAdrian Chadd 
265cd684decSAdrian Chadd 	switch (new_state) {
266cd684decSAdrian Chadd 	case IWM_SF_UNINIT:
267*e7065dd1SMark Johnston 		iwm_fill_sf_command(sc, &sf_cmd, NULL);
268cd684decSAdrian Chadd 		break;
269cd684decSAdrian Chadd 	case IWM_SF_FULL_ON:
270*e7065dd1SMark Johnston 		iwm_fill_sf_command(sc, &sf_cmd, ni);
271cd684decSAdrian Chadd 		break;
272cd684decSAdrian Chadd 	case IWM_SF_INIT_OFF:
273*e7065dd1SMark Johnston 		iwm_fill_sf_command(sc, &sf_cmd, NULL);
274cd684decSAdrian Chadd 		break;
275cd684decSAdrian Chadd 	default:
276cd684decSAdrian Chadd 		device_printf(sc->sc_dev,
277cd684decSAdrian Chadd 		    "Invalid state: %d. not sending Smart Fifo cmd\n",
278cd684decSAdrian Chadd 		    new_state);
279cd684decSAdrian Chadd 		return EINVAL;
280cd684decSAdrian Chadd 	}
281cd684decSAdrian Chadd 
282*e7065dd1SMark Johnston 	ret = iwm_send_cmd_pdu(sc, IWM_REPLY_SF_CFG_CMD, IWM_CMD_ASYNC,
283cd684decSAdrian Chadd 				   sizeof(sf_cmd), &sf_cmd);
284cd684decSAdrian Chadd 	if (!ret)
285cd684decSAdrian Chadd 		sc->sf_state = new_state;
286cd684decSAdrian Chadd 
287cd684decSAdrian Chadd 	return ret;
288cd684decSAdrian Chadd }
289cd684decSAdrian Chadd 
290cd684decSAdrian Chadd /*
291cd684decSAdrian Chadd  * Update Smart fifo:
292cd684decSAdrian Chadd  * Count bound interfaces that are not to be removed, ignoring p2p devices,
293cd684decSAdrian Chadd  * and set new state accordingly.
294cd684decSAdrian Chadd  */
295cd684decSAdrian Chadd int
iwm_sf_update(struct iwm_softc * sc,struct ieee80211vap * changed_vif,boolean_t remove_vif)296*e7065dd1SMark Johnston iwm_sf_update(struct iwm_softc *sc, struct ieee80211vap *changed_vif,
297cd684decSAdrian Chadd 	boolean_t remove_vif)
298cd684decSAdrian Chadd {
299cd684decSAdrian Chadd 	enum iwm_sf_state new_state;
300cd684decSAdrian Chadd 	struct ieee80211_node *ni = NULL;
301cd684decSAdrian Chadd 	int num_active_macs = 0;
302cd684decSAdrian Chadd 
303cd684decSAdrian Chadd 	/* If changed_vif exists and is not to be removed, add to the count */
304cd684decSAdrian Chadd 	if (changed_vif && !remove_vif)
305cd684decSAdrian Chadd 		num_active_macs++;
306cd684decSAdrian Chadd 
307cd684decSAdrian Chadd 	switch (num_active_macs) {
308cd684decSAdrian Chadd 	case 0:
309cd684decSAdrian Chadd 		/* If there are no active macs - change state to SF_INIT_OFF */
310cd684decSAdrian Chadd 		new_state = IWM_SF_INIT_OFF;
311cd684decSAdrian Chadd 		break;
312cd684decSAdrian Chadd 	case 1:
313cd684decSAdrian Chadd 		if (!changed_vif)
314cd684decSAdrian Chadd 			return EINVAL;
315cd684decSAdrian Chadd 		ni = changed_vif->iv_bss;
316cd684decSAdrian Chadd 		if (ni != NULL && IWM_NODE(ni)->in_assoc &&
317cd684decSAdrian Chadd 		    changed_vif->iv_dtim_period) {
318cd684decSAdrian Chadd 			new_state = IWM_SF_FULL_ON;
319cd684decSAdrian Chadd 		} else {
320cd684decSAdrian Chadd 			new_state = IWM_SF_INIT_OFF;
321cd684decSAdrian Chadd 		}
322cd684decSAdrian Chadd 		break;
323cd684decSAdrian Chadd 	default:
324cd684decSAdrian Chadd 		/* If there are multiple active macs - change to SF_UNINIT */
325cd684decSAdrian Chadd 		new_state = IWM_SF_UNINIT;
326cd684decSAdrian Chadd 	}
327*e7065dd1SMark Johnston 	return iwm_sf_config(sc, ni, new_state);
328cd684decSAdrian Chadd }
329