/** @brief copy UDL data in an skb to a circular TXQ Enqueues a frame in @b @@skb to the @b @@dev TXQ if there is enough space in the TXQ, then releases @b @@skb. @param mld the pointer to a mem_link_device instance @param dev the pointer to a mem_ipc_device instance @param skb the pointer to an sk_buff instance @retval "> 0" the size of the frame written in the TXQ @retval "< 0" an error code (-EBUSY, -ENOSPC, or -EIO) */ static inline int udl_write(struct mem_link_device *mld, struct mem_ipc_device *dev, struct sk_buff *skb) { unsigned int count = skb->len; char *src = skb->data; char *dst = get_txq_buff(dev); unsigned int qsize = get_txq_buff_size(dev); unsigned int in = get_txq_head(dev); unsigned int out = get_txq_tail(dev); int space; space = check_udl_space(mld, dev, qsize, in, out, count); if (unlikely(space < 0)) return space; barrier(); circ_write(dst, src, qsize, in, count); barrier(); set_txq_head(dev, circ_new_ptr(qsize, in, count)); /* Commit the item before incrementing the head */ smp_mb(); return count; }
/** @brief copy data in an skb to a circular TXQ Enqueues a frame in @b @@skb to the @b @@dev TXQ if there is enough space in the TXQ, then releases @b @@skb. @param mld the pointer to a mem_link_device instance @param dev the pointer to a mem_ipc_device instance @param skb the pointer to an sk_buff instance @retval "> 0" the size of the frame written in the TXQ @retval "< 0" an error code (-EBUSY, -ENOSPC, or -EIO) */ static int txq_write(struct mem_link_device *mld, struct mem_ipc_device *dev, struct sk_buff *skb) { char *src = skb->data; unsigned int count = skb->len; char *dst = get_txq_buff(dev); unsigned int qsize = get_txq_buff_size(dev); unsigned int in = get_txq_head(dev); unsigned int out = get_txq_tail(dev); int space; space = check_txq_space(mld, dev, qsize, in, out, count); if (unlikely(space < 0)) return space; #ifdef DEBUG_MODEM_IF_LINK_TX /* Record the time-stamp */ getnstimeofday(&skbpriv(skb)->ts); #endif circ_write(dst, src, qsize, in, count); set_txq_head(dev, circ_new_ptr(qsize, in, count)); /* Commit the item before incrementing the head */ smp_mb(); #ifdef DEBUG_MODEM_IF_LINK_TX if (likely(src)) log_ipc_pkt(sipc5_get_ch_id(src), LINK, TX, skb, true, true); #endif dev_kfree_skb_any(skb); return count; }