xref: /freebsd/sys/contrib/dev/mediatek/mt76/util.h (revision cbb3ec25236ba72f91cbdf23f8b78b9d1af0cedf)
16c92544dSBjoern A. Zeeb /*-
26c92544dSBjoern A. Zeeb  * SPDX-License-Identifier: BSD-2-Clause
36c92544dSBjoern A. Zeeb  *
4*cbb3ec25SBjoern A. Zeeb  * Copyright (c) 2020,2022-2023 Bjoern A. Zeeb <bz@FreeBSD.org>
56c92544dSBjoern A. Zeeb  *
66c92544dSBjoern A. Zeeb  * Redistribution and use in source and binary forms, with or without
76c92544dSBjoern A. Zeeb  * modification, are permitted provided that the following conditions
86c92544dSBjoern A. Zeeb  * are met:
96c92544dSBjoern A. Zeeb  * 1. Redistributions of source code must retain the above copyright
106c92544dSBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer.
116c92544dSBjoern A. Zeeb  * 2. Redistributions in binary form must reproduce the above copyright
126c92544dSBjoern A. Zeeb  *    notice, this list of conditions and the following disclaimer in the
136c92544dSBjoern A. Zeeb  *    documentation and/or other materials provided with the distribution.
146c92544dSBjoern A. Zeeb  *
156c92544dSBjoern A. Zeeb  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
166c92544dSBjoern A. Zeeb  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
176c92544dSBjoern A. Zeeb  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
186c92544dSBjoern A. Zeeb  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
196c92544dSBjoern A. Zeeb  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
206c92544dSBjoern A. Zeeb  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
216c92544dSBjoern A. Zeeb  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
226c92544dSBjoern A. Zeeb  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
236c92544dSBjoern A. Zeeb  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
246c92544dSBjoern A. Zeeb  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
256c92544dSBjoern A. Zeeb  * SUCH DAMAGE.
266c92544dSBjoern A. Zeeb  *
276c92544dSBjoern A. Zeeb  * $FreeBSD$
286c92544dSBjoern A. Zeeb  */
296c92544dSBjoern A. Zeeb 
306c92544dSBjoern A. Zeeb #ifndef	_MT76_UTIL_H
316c92544dSBjoern A. Zeeb #define	_MT76_UTIL_H
326c92544dSBjoern A. Zeeb 
336c92544dSBjoern A. Zeeb #include <linux/kthread.h>
346c92544dSBjoern A. Zeeb 
356c92544dSBjoern A. Zeeb struct mt76_worker
366c92544dSBjoern A. Zeeb {
376c92544dSBjoern A. Zeeb 	void(*fn)(struct mt76_worker *);
386c92544dSBjoern A. Zeeb 	struct task_struct *task;
396c92544dSBjoern A. Zeeb 	unsigned long state;
406c92544dSBjoern A. Zeeb };
416c92544dSBjoern A. Zeeb 
426c92544dSBjoern A. Zeeb enum mt76_worker_state {
436c92544dSBjoern A. Zeeb 	MT76_WORKER_SCHEDULED,
446c92544dSBjoern A. Zeeb 	MT76_WORKER_RUNNING,
456c92544dSBjoern A. Zeeb };
466c92544dSBjoern A. Zeeb 
476c92544dSBjoern A. Zeeb #if 0
486c92544dSBjoern A. Zeeb bool __mt76_poll(struct mt76_dev *, u32, u32, u32, int);
496c92544dSBjoern A. Zeeb bool __mt76_poll_msec(struct mt76_dev *, u32, u32, u32, int);
506c92544dSBjoern A. Zeeb int mt76_get_min_avg_rssi(struct mt76_dev *, bool);
516c92544dSBjoern A. Zeeb #endif
526c92544dSBjoern A. Zeeb int mt76_wcid_alloc(u32 *, int);
536c92544dSBjoern A. Zeeb int __mt76_worker_fn(void *);
546c92544dSBjoern A. Zeeb 
556c92544dSBjoern A. Zeeb /* wcid_phy_mask is [32] */
566c92544dSBjoern A. Zeeb static inline void
mt76_wcid_mask_set(u32 * mask,u16 bit)576c92544dSBjoern A. Zeeb mt76_wcid_mask_set(u32 *mask, u16 bit)
586c92544dSBjoern A. Zeeb {
596c92544dSBjoern A. Zeeb 
606c92544dSBjoern A. Zeeb 	mask[bit / 32] |= BIT(bit % 32);
616c92544dSBjoern A. Zeeb }
626c92544dSBjoern A. Zeeb 
636c92544dSBjoern A. Zeeb static inline void
mt76_wcid_mask_clear(u32 * mask,u16 bit)646c92544dSBjoern A. Zeeb mt76_wcid_mask_clear(u32 *mask, u16 bit)
656c92544dSBjoern A. Zeeb {
666c92544dSBjoern A. Zeeb 
676c92544dSBjoern A. Zeeb 	mask[bit / 32] &= ~BIT(bit % 32);
686c92544dSBjoern A. Zeeb }
696c92544dSBjoern A. Zeeb 
706c92544dSBjoern A. Zeeb /* See, e.g., __mt76_worker_fn for some details. */
716c92544dSBjoern A. Zeeb static inline int
mt76_worker_setup(struct ieee80211_hw * hw,struct mt76_worker * w,void (* wfunc)(struct mt76_worker *),const char * name)726c92544dSBjoern A. Zeeb mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w,
736c92544dSBjoern A. Zeeb     void (*wfunc)(struct mt76_worker *), const char *name)
746c92544dSBjoern A. Zeeb {
756c92544dSBjoern A. Zeeb 	int rc;
766c92544dSBjoern A. Zeeb 
776c92544dSBjoern A. Zeeb 	if (wfunc)
786c92544dSBjoern A. Zeeb 		w->fn = wfunc;
796c92544dSBjoern A. Zeeb 
806c92544dSBjoern A. Zeeb 	w->task = kthread_run(__mt76_worker_fn, w,
816c92544dSBjoern A. Zeeb 	    "mt76-worker");
826c92544dSBjoern A. Zeeb 
836c92544dSBjoern A. Zeeb 	if (!IS_ERR(w->task))
846c92544dSBjoern A. Zeeb 		return (0);
856c92544dSBjoern A. Zeeb 
866c92544dSBjoern A. Zeeb 	rc = PTR_ERR(w->task);
876c92544dSBjoern A. Zeeb 	w->task = NULL;
886c92544dSBjoern A. Zeeb 	return (rc);
896c92544dSBjoern A. Zeeb }
906c92544dSBjoern A. Zeeb 
916c92544dSBjoern A. Zeeb static inline void
mt76_worker_schedule(struct mt76_worker * w)926c92544dSBjoern A. Zeeb mt76_worker_schedule(struct mt76_worker *w)
936c92544dSBjoern A. Zeeb {
946c92544dSBjoern A. Zeeb 
956c92544dSBjoern A. Zeeb 	if (w->task == NULL)
966c92544dSBjoern A. Zeeb 		return;
976c92544dSBjoern A. Zeeb 
986c92544dSBjoern A. Zeeb 	if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) ||
996c92544dSBjoern A. Zeeb 	    !test_bit(MT76_WORKER_RUNNING, &w->state))
1006c92544dSBjoern A. Zeeb 		wake_up_process(w->task);
1016c92544dSBjoern A. Zeeb }
1026c92544dSBjoern A. Zeeb 
1036c92544dSBjoern A. Zeeb static inline void
mt76_worker_enable(struct mt76_worker * w)1046c92544dSBjoern A. Zeeb mt76_worker_enable(struct mt76_worker *w)
1056c92544dSBjoern A. Zeeb {
1066c92544dSBjoern A. Zeeb 
1076c92544dSBjoern A. Zeeb 	if (w->task == NULL)
1086c92544dSBjoern A. Zeeb 		return;
1096c92544dSBjoern A. Zeeb 
1106c92544dSBjoern A. Zeeb 	kthread_unpark(w->task);
1116c92544dSBjoern A. Zeeb 	mt76_worker_schedule(w);
1126c92544dSBjoern A. Zeeb }
1136c92544dSBjoern A. Zeeb 
1146c92544dSBjoern A. Zeeb static inline void
mt76_worker_disable(struct mt76_worker * w)1156c92544dSBjoern A. Zeeb mt76_worker_disable(struct mt76_worker *w)
1166c92544dSBjoern A. Zeeb {
1176c92544dSBjoern A. Zeeb 
1186c92544dSBjoern A. Zeeb 	if (w->task == NULL)
1196c92544dSBjoern A. Zeeb 		return;
1206c92544dSBjoern A. Zeeb 
1216c92544dSBjoern A. Zeeb 	kthread_park(w->task);
1226c92544dSBjoern A. Zeeb 	WRITE_ONCE(w->state, 0);
1236c92544dSBjoern A. Zeeb }
1246c92544dSBjoern A. Zeeb 
1256c92544dSBjoern A. Zeeb static inline void
mt76_worker_teardown(struct mt76_worker * w)1266c92544dSBjoern A. Zeeb mt76_worker_teardown(struct mt76_worker *w)
1276c92544dSBjoern A. Zeeb {
1286c92544dSBjoern A. Zeeb 
1296c92544dSBjoern A. Zeeb 	if (w->task == NULL)
1306c92544dSBjoern A. Zeeb 		return;
1316c92544dSBjoern A. Zeeb 
1326c92544dSBjoern A. Zeeb 	kthread_stop(w->task);
1336c92544dSBjoern A. Zeeb 	w->task = NULL;
1346c92544dSBjoern A. Zeeb }
1356c92544dSBjoern A. Zeeb 
1366c92544dSBjoern A. Zeeb static inline void
mt76_skb_set_moredata(struct sk_buff * skb,bool moredata)1376c92544dSBjoern A. Zeeb mt76_skb_set_moredata(struct sk_buff *skb, bool moredata)
1386c92544dSBjoern A. Zeeb {
1396c92544dSBjoern A. Zeeb 	/*
1406c92544dSBjoern A. Zeeb 	 * This would be net80211::IEEE80211_FC1_MORE_DATA
1416c92544dSBjoern A. Zeeb 	 * Implement it as mostly LinuxKPI 802.11 to avoid
1426c92544dSBjoern A. Zeeb 	 * further header pollution and possible conflicts.
1436c92544dSBjoern A. Zeeb 	 */
1446c92544dSBjoern A. Zeeb 	struct ieee80211_hdr *hdr;
1456c92544dSBjoern A. Zeeb 	uint16_t val;
1466c92544dSBjoern A. Zeeb 
1476c92544dSBjoern A. Zeeb 	hdr = (struct ieee80211_hdr *)skb->data;
1486c92544dSBjoern A. Zeeb 	val = cpu_to_le16(IEEE80211_FC1_MORE_DATA << 8);
1496c92544dSBjoern A. Zeeb 	if (!moredata)
1506c92544dSBjoern A. Zeeb 		hdr->frame_control &= ~val;
1516c92544dSBjoern A. Zeeb 	else
1526c92544dSBjoern A. Zeeb 		hdr->frame_control |= val;
1536c92544dSBjoern A. Zeeb }
1546c92544dSBjoern A. Zeeb 
1556c92544dSBjoern A. Zeeb #endif	/* _MT76_UTIL_H */
156