udelay(lp->data->t_sifs);
        }
 
-       ieee802154_xmit_complete(lp->hw, skb);
+       ieee802154_xmit_complete(lp->hw, skb, false);
 }
 
 static void
 
 
 #define IEEE802154_EXTENDED_ADDR_LEN   8
 
+#define IEEE802154_LIFS_PERIOD         40
+#define IEEE802154_SIFS_PERIOD         12
+
 #define IEEE802154_FC_TYPE_BEACON      0x0     /* Frame is beacon */
 #define        IEEE802154_FC_TYPE_DATA         0x1     /* Frame is data */
 #define IEEE802154_FC_TYPE_ACK         0x2     /* Frame is acknowledgment */
 
 
        s32 cca_ed_level;
 
+       /* PHY depended MAC PIB values */
+
+       /* 802.15.4 acronym: Tdsym in usec */
+       u8 symbol_duration;
+       /* lifs and sifs periods timing */
+       u16 lifs_period;
+       u16 sifs_period;
+
        struct device dev;
 
        char priv[0] __aligned(NETDEV_ALIGN);
 
 
 void ieee802154_wake_queue(struct ieee802154_hw *hw);
 void ieee802154_stop_queue(struct ieee802154_hw *hw);
-void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb);
+void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
+                             bool ifs_handling);
 
 #endif /* NET_MAC802154_H */
 
 #define __IEEE802154_I_H
 
 #include <linux/mutex.h>
+#include <linux/hrtimer.h>
 #include <net/cfg802154.h>
 #include <net/mac802154.h>
 #include <net/ieee802154_netdev.h>
         */
        struct workqueue_struct *workqueue;
 
+       struct hrtimer ifs_timer;
+
        bool started;
 
        struct tasklet_struct tasklet;
 void mac802154_wpan_setup(struct net_device *dev);
 netdev_tx_t
 ieee802154_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
+enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer);
 
 /* MIB callbacks */
 void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val);
 
 
        ASSERT_RTNL();
 
+       hrtimer_cancel(&local->ifs_timer);
+
        netif_stop_queue(dev);
        local->open_count--;
 
 
 }
 EXPORT_SYMBOL(ieee802154_free_hw);
 
+static void ieee802154_setup_wpan_phy_pib(struct wpan_phy *wpan_phy)
+{
+       /* TODO warn on empty symbol_duration
+        * Should be done when all drivers sets this value.
+        */
+
+       wpan_phy->lifs_period = IEEE802154_LIFS_PERIOD *
+                               wpan_phy->symbol_duration;
+       wpan_phy->sifs_period = IEEE802154_SIFS_PERIOD *
+                               wpan_phy->symbol_duration;
+}
+
 int ieee802154_register_hw(struct ieee802154_hw *hw)
 {
        struct ieee802154_local *local = hw_to_local(hw);
                goto out;
        }
 
+       hrtimer_init(&local->ifs_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
+       local->ifs_timer.function = ieee802154_xmit_ifs_timer;
+
        wpan_phy_set_dev(local->phy, local->hw.parent);
 
+       ieee802154_setup_wpan_phy_pib(local->phy);
+
        rc = wpan_phy_register(local->phy);
        if (rc < 0)
                goto out_wq;
 
        if (res)
                goto err_tx;
 
-       ieee802154_xmit_complete(&local->hw, skb);
+       ieee802154_xmit_complete(&local->hw, skb, false);
 
        dev->stats.tx_packets++;
        dev->stats.tx_bytes += skb->len;
 
 }
 EXPORT_SYMBOL(ieee802154_stop_queue);
 
-void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb)
+enum hrtimer_restart ieee802154_xmit_ifs_timer(struct hrtimer *timer)
 {
-       ieee802154_wake_queue(hw);
-       consume_skb(skb);
+       struct ieee802154_local *local =
+               container_of(timer, struct ieee802154_local, ifs_timer);
+
+       ieee802154_wake_queue(&local->hw);
+
+       return HRTIMER_NORESTART;
+}
+
+void ieee802154_xmit_complete(struct ieee802154_hw *hw, struct sk_buff *skb,
+                             bool ifs_handling)
+{
+       if (ifs_handling) {
+               struct ieee802154_local *local = hw_to_local(hw);
+
+               if (skb->len > 18)
+                       hrtimer_start(&local->ifs_timer,
+                                     ktime_set(0, hw->phy->lifs_period * NSEC_PER_USEC),
+                                     HRTIMER_MODE_REL);
+               else
+                       hrtimer_start(&local->ifs_timer,
+                                     ktime_set(0, hw->phy->sifs_period * NSEC_PER_USEC),
+                                     HRTIMER_MODE_REL);
+
+               consume_skb(skb);
+       } else {
+               ieee802154_wake_queue(hw);
+               consume_skb(skb);
+       }
 }
 EXPORT_SYMBOL(ieee802154_xmit_complete);