Пример #1
0
/**
@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;
}