Esempio n. 1
0
/*
 * Transmit a packet to the base station on behalf of the network stack
 *
 *
 * Returns: NETDEV_TX_OK (always, even in case of error)
 *
 * In case of error, we just drop it. Reasons:
 *
 *  - we add a hw header to each skb, and if the network stack
 *    retries, we have no way to know if that skb has it or not.
 *
 *  - network protocols have their own drop-recovery mechanisms
 *
 *  - there is not much else we can do
 *
 * If the device is idle, we need to wake it up; that is an operation
 * that will sleep. See i2400m_net_wake_tx() for details.
 */
static
netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb,
					 struct net_device *net_dev)
{
	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
	struct device *dev = i2400m_dev(i2400m);
	int result = -1;

	d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);

	if (skb_header_cloned(skb) && 
	    pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
		goto drop;

	if (i2400m->state == I2400M_SS_IDLE)
		result = i2400m_net_wake_tx(i2400m, net_dev, skb);
	else
		result = i2400m_net_tx(i2400m, net_dev, skb);
	if (result <  0) {
drop:
		net_dev->stats.tx_dropped++;
	} else {
		net_dev->stats.tx_packets++;
		net_dev->stats.tx_bytes += skb->len;
	}
	dev_kfree_skb(skb);
	d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
	return NETDEV_TX_OK;
}
Esempio n. 2
0
/*
 * Transmit a packet to the base station on behalf of the network stack
 *
 *
 * Returns: NETDEV_TX_OK (always, even in case of error)
 *
 * In case of error, we just drop it. Reasons:
 *
 *  - we add a hw header to each skb, and if the network stack
 *    retries, we have no way to know if that skb has it or not.
 *
 *  - network protocols have their own drop-recovery mechanisms
 *
 *  - there is not much else we can do
 *
 * If the device is idle, we need to wake it up; that is an operation
 * that will sleep. See i2400m_net_wake_tx() for details.
 */
static
netdev_tx_t i2400m_hard_start_xmit(struct sk_buff *skb,
					 struct net_device *net_dev)
{
	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
	struct device *dev = i2400m_dev(i2400m);
	int result;

	d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
	if (skb_header_cloned(skb)) {
		/*
		 * Make tcpdump/wireshark happy -- if they are
		 * running, the skb is cloned and we will overwrite
		 * the mac fields in i2400m_tx_prep_header. Expand
		 * seems to fix this...
		 */
		result = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
		if (result) {
			result = NETDEV_TX_BUSY;
			goto error_expand;
		}
	}

	if (i2400m->state == I2400M_SS_IDLE)
		result = i2400m_net_wake_tx(i2400m, net_dev, skb);
	else
		result = i2400m_net_tx(i2400m, net_dev, skb);
	if (result <  0)
		net_dev->stats.tx_dropped++;
	else {
		net_dev->stats.tx_packets++;
		net_dev->stats.tx_bytes += skb->len;
	}
	result = NETDEV_TX_OK;
error_expand:
	kfree_skb(skb);
	d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
	return result;
}
Esempio n. 3
0
/*
 * Transmit a packet to the base station on behalf of the network stack
 *
 *
 * Returns: NETDEV_TX_OK (always, even in case of error)
 *
 * In case of error, we just drop it. Reasons:
 *
 *  - we add a hw header to each skb, and if the network stack
 *    retries, we have no way to know if that skb has it or not.
 *
 *  - network protocols have their own drop-recovery mechanisms
 *
 *  - there is not much else we can do
 *
 * If the device is idle, we need to wake it up; that is an operation
 * that will sleep. See i2400m_net_wake_tx() for details.
 */
static
int i2400m_hard_start_xmit(struct sk_buff *skb,
			   struct net_device *net_dev)
{
	int result;
	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
	struct device *dev = i2400m_dev(i2400m);

	d_fnstart(3, dev, "(skb %p net_dev %p)\n", skb, net_dev);
	if (i2400m->state == I2400M_SS_IDLE)
		result = i2400m_net_wake_tx(i2400m, net_dev, skb);
	else
		result = i2400m_net_tx(i2400m, net_dev, skb);
	if (result <  0)
		net_dev->stats.tx_dropped++;
	else {
		net_dev->stats.tx_packets++;
		net_dev->stats.tx_bytes += skb->len;
	}
	kfree_skb(skb);
	result = NETDEV_TX_OK;
	d_fnend(3, dev, "(skb %p net_dev %p) = %d\n", skb, net_dev, result);
	return result;
}