util.h 2.1 KB

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