/* This module implements the Qualcomm Atheros UART protocol for * kernel-based UART device; it is essentially an Ethernet-to-UART * serial converter;
*/
switch (retcode) { case QCAFRM_GATHER: case QCAFRM_NOHEAD: break; case QCAFRM_NOTAIL:
netdev_dbg(netdev, "recv: no RX tail\n");
n_stats->rx_errors++;
n_stats->rx_dropped++; break; case QCAFRM_INVLEN:
netdev_dbg(netdev, "recv: invalid RX length\n");
n_stats->rx_errors++;
n_stats->rx_dropped++; break; default:
n_stats->rx_packets++;
n_stats->rx_bytes += retcode;
skb_put(qca->rx_skb, retcode);
qca->rx_skb->protocol = eth_type_trans(
qca->rx_skb, qca->rx_skb->dev);
skb_checksum_none_assert(qca->rx_skb);
netif_rx(qca->rx_skb);
qca->rx_skb = netdev_alloc_skb_ip_align(netdev,
netdev->mtu +
VLAN_ETH_HLEN); if (!qca->rx_skb) {
netdev_dbg(netdev, "recv: out of RX resources\n");
n_stats->rx_errors++; return i;
}
}
}
return i;
}
/* Write out any remaining transmit buffer. Scheduled when tty is writable */ staticvoid qcauart_transmit(struct work_struct *work)
{ struct qcauart *qca = container_of(work, struct qcauart, tx_work); struct net_device_stats *n_stats = &qca->net_dev->stats; int written;
spin_lock_bh(&qca->lock);
/* First make sure we're connected. */ if (!netif_running(qca->net_dev)) {
spin_unlock_bh(&qca->lock); return;
}
if (qca->tx_left <= 0) { /* Now serial buffer is almost free & we can start * transmission of another packet
*/
n_stats->tx_packets++;
spin_unlock_bh(&qca->lock);
netif_wake_queue(qca->net_dev); return;
}
written = serdev_device_write_buf(qca->serdev, qca->tx_head,
qca->tx_left); if (written > 0) {
qca->tx_left -= written;
qca->tx_head += written;
}
spin_unlock_bh(&qca->lock);
}
/* Called by the driver when there's room for more data. * Schedule the transmit.
*/ staticvoid qca_tty_wakeup(struct serdev_device *serdev)
{ struct qcauart *qca = serdev_device_get_drvdata(serdev);
ret = of_get_ethdev_address(serdev->dev.of_node, qca->net_dev); if (ret) {
eth_hw_addr_random(qca->net_dev);
dev_info(&serdev->dev, "Using random MAC address: %pM\n",
qca->net_dev->dev_addr);
}
ret = register_netdev(qcauart_dev); if (ret) {
dev_err(&serdev->dev, "Unable to register net device %s\n",
qcauart_dev->name);
serdev_device_close(serdev);
cancel_work_sync(&qca->tx_work); goto free;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.