^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Authors:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Alexander Aring <aar@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on: net/mac80211/util.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "ieee802154_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "driver-ops.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) /* privid for wpan_phys to determine whether they belong to us or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) const void *const mac802154_wpan_phy_privid = &mac802154_wpan_phy_privid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) void ieee802154_wake_queue(struct ieee802154_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) struct ieee802154_local *local = hw_to_local(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) struct ieee802154_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) list_for_each_entry_rcu(sdata, &local->interfaces, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) if (!sdata->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) netif_wake_queue(sdata->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) EXPORT_SYMBOL(ieee802154_wake_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) void ieee802154_stop_queue(struct ieee802154_hw *hw)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) struct ieee802154_local *local = hw_to_local(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) struct ieee802154_sub_if_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) rcu_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) list_for_each_entry_rcu(sdata, &local->interfaces, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (!sdata->dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) netif_stop_queue(sdata->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) rcu_read_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) EXPORT_SYMBOL(ieee802154_stop_queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) struct ieee802154_local *local =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) container_of(timer, struct ieee802154_local, ifs_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) ieee802154_wake_queue(&local->hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) return HRTIMER_NORESTART;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) bool ifs_handling)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (ifs_handling) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) struct ieee802154_local *local = hw_to_local(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) u8 max_sifs_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* If transceiver sets CRC on his own we need to use lifs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * threshold len above 16 otherwise 18, because it's not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * part of skb->len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (hw->flags & IEEE802154_HW_TX_OMIT_CKSUM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) max_sifs_size = IEEE802154_MAX_SIFS_FRAME_SIZE -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) IEEE802154_FCS_LEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) max_sifs_size = IEEE802154_MAX_SIFS_FRAME_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) if (skb->len > max_sifs_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) hrtimer_start(&local->ifs_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) hw->phy->lifs_period * NSEC_PER_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) HRTIMER_MODE_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) hrtimer_start(&local->ifs_timer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) hw->phy->sifs_period * NSEC_PER_USEC,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) HRTIMER_MODE_REL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ieee802154_wake_queue(hw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) dev_consume_skb_any(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) EXPORT_SYMBOL(ieee802154_xmit_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) void ieee802154_stop_device(struct ieee802154_local *local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) flush_workqueue(local->workqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) hrtimer_cancel(&local->ifs_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) drv_stop(local);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }