util.h 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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 void
  26. mt76_wcid_mask_set(u32 *mask, int idx)
  27. {
  28. mask[idx / 32] |= BIT(idx % 32);
  29. }
  30. static inline void
  31. mt76_wcid_mask_clear(u32 *mask, int idx)
  32. {
  33. mask[idx / 32] &= ~BIT(idx % 32);
  34. }
  35. static inline void
  36. mt76_skb_set_moredata(struct sk_buff *skb, bool enable)
  37. {
  38. struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
  39. if (enable)
  40. hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
  41. else
  42. hdr->frame_control &= ~cpu_to_le16(IEEE80211_FCTL_MOREDATA);
  43. }
  44. int __mt76_worker_fn(void *ptr);
  45. static inline int
  46. mt76_worker_setup(struct ieee80211_hw *hw, struct mt76_worker *w,
  47. void (*fn)(struct mt76_worker *),
  48. const char *name)
  49. {
  50. const char *dev_name = wiphy_name(hw->wiphy);
  51. int ret;
  52. if (fn)
  53. w->fn = fn;
  54. w->task = kthread_run(__mt76_worker_fn, w,
  55. "mt76-%s %s", name, dev_name);
  56. if (IS_ERR(w->task)) {
  57. ret = PTR_ERR(w->task);
  58. w->task = NULL;
  59. return ret;
  60. }
  61. return 0;
  62. }
  63. static inline void mt76_worker_schedule(struct mt76_worker *w)
  64. {
  65. if (!w->task)
  66. return;
  67. if (!test_and_set_bit(MT76_WORKER_SCHEDULED, &w->state) &&
  68. !test_bit(MT76_WORKER_RUNNING, &w->state))
  69. wake_up_process(w->task);
  70. }
  71. static inline void mt76_worker_disable(struct mt76_worker *w)
  72. {
  73. if (!w->task)
  74. return;
  75. kthread_park(w->task);
  76. WRITE_ONCE(w->state, 0);
  77. }
  78. static inline void mt76_worker_enable(struct mt76_worker *w)
  79. {
  80. if (!w->task)
  81. return;
  82. kthread_unpark(w->task);
  83. mt76_worker_schedule(w);
  84. }
  85. static inline void mt76_worker_teardown(struct mt76_worker *w)
  86. {
  87. if (!w->task)
  88. return;
  89. kthread_stop(w->task);
  90. w->task = NULL;
  91. }
  92. #endif