/* * 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; }
/* * 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; }
/* * 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; }