util.h 2.3 KB

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