util.h 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /* SPDX-License-Identifier: GPL-2.0-only */
  2. /*
  3. * Copyright (C) 2016 Felix Fietkau <[email protected]>
  4. * Copyright (C) 2004 - 2009 Ivo van Doorn <[email protected]>
  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_run(__mt76_worker_fn, w,
  60. "mt76-%s %s", name, dev_name);
  61. if (IS_ERR(w->task)) {
  62. ret = PTR_ERR(w->task);
  63. w->task = NULL;
  64. return ret;
  65. }
  66. return 0;
  67. }
  68. static inline void mt76_worker_schedule(struct mt76_worker *w)
  69. {
  70. if (!w->task)
  71. return;
  72. if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) &&
  73. !test_bit(MT76_WORKER_RUNNING, &w->state))
  74. wake_up_process(w->task);
  75. }
  76. static inline void mt76_worker_disable(struct mt76_worker *w)
  77. {
  78. if (!w->task)
  79. return;
  80. kthread_park(w->task);
  81. WRITE_ONCE(w->state, 0);
  82. }
  83. static inline void mt76_worker_enable(struct mt76_worker *w)
  84. {
  85. if (!w->task)
  86. return;
  87. kthread_unpark(w->task);
  88. mt76_worker_schedule(w);
  89. }
  90. static inline void mt76_worker_teardown(struct mt76_worker *w)
  91. {
  92. if (!w->task)
  93. return;
  94. kthread_stop(w->task);
  95. w->task = NULL;
  96. }
  97. #endif