at master 115 lines 2.1 kB view raw
1/* SPDX-License-Identifier: BSD-3-Clause-Clear */ 2/* 3 * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> 4 */ 5 6#ifndef __MT76_UTIL_H 7#define __MT76_UTIL_H 8 9#include <linux/skbuff.h> 10#include <linux/bitops.h> 11#include <linux/bitfield.h> 12#include <net/mac80211.h> 13 14struct mt76_worker 15{ 16 struct task_struct *task; 17 void (*fn)(struct mt76_worker *); 18 unsigned long state; 19}; 20 21enum { 22 MT76_WORKER_SCHEDULED, 23 MT76_WORKER_RUNNING, 24}; 25 26#define MT76_INCR(_var, _size) \ 27 (_var = (((_var) + 1) % (_size))) 28 29int mt76_wcid_alloc(u32 *mask, int size); 30 31static inline void 32mt76_wcid_mask_set(u32 *mask, int idx) 33{ 34 mask[idx / 32] |= BIT(idx % 32); 35} 36 37static inline void 38mt76_wcid_mask_clear(u32 *mask, int idx) 39{ 40 mask[idx / 32] &= ~BIT(idx % 32); 41} 42 43static inline void 44mt76_skb_set_moredata(struct sk_buff *skb, bool enable) 45{ 46 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 47 48 if (enable) 49 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA); 50 else 51 hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA); 52} 53 54int __mt76_worker_fn(void *ptr); 55 56static inline int 57mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w, 58 void (*fn)(struct mt76_worker *), 59 const char *name) 60{ 61 const char *dev_name = wiphy_name(hw->wiphy); 62 int ret; 63 64 if (fn) 65 w->fn = fn; 66 w->task = kthread_run(__mt76_worker_fn, w, 67 "mt76-%s %s", name, dev_name); 68 69 if (IS_ERR(w->task)) { 70 ret = PTR_ERR(w->task); 71 w->task = NULL; 72 return ret; 73 } 74 75 return 0; 76} 77 78static inline void mt76_worker_schedule(struct mt76_worker *w) 79{ 80 if (!w->task) 81 return; 82 83 if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) && 84 !test_bit(MT76_WORKER_RUNNING, &w->state)) 85 wake_up_process(w->task); 86} 87 88static inline void mt76_worker_disable(struct mt76_worker *w) 89{ 90 if (!w->task) 91 return; 92 93 kthread_park(w->task); 94 WRITE_ONCE(w->state, 0); 95} 96 97static inline void mt76_worker_enable(struct mt76_worker *w) 98{ 99 if (!w->task) 100 return; 101 102 kthread_unpark(w->task); 103 mt76_worker_schedule(w); 104} 105 106static inline void mt76_worker_teardown(struct mt76_worker *w) 107{ 108 if (!w->task) 109 return; 110 111 kthread_stop(w->task); 112 w->task = NULL; 113} 114 115#endif