u16 offset:15;
u16 len;
u16 cpu_tag[10];
- /* software mangement and data part */
- struct sk_buff *skb;
} __packed __aligned(1);
/* SOC/driver shared coherent ring descriptors */
struct rteth_tx_info {
int slot;
+ struct sk_buff *skb[RTETH_TX_RING_SIZE];
};
struct n_event {
static void rteth_free_tx_buffers(struct rteth_ctrl *ctrl)
{
- struct rteth_packet *packet;
+ struct rteth_tx_info *tx_info;
for (int r = 0; r < RTETH_TX_RINGS; r++) {
+ tx_info = &ctrl->tx_info[r];
for (int i = 0; i < RTETH_TX_RING_SIZE; i++) {
- packet = &ctrl->tx_data[r].packet[i];
- if (!packet->skb)
+ dma_addr_t dma = ctrl->tx_data[r].packet[i].dma;
+
+ if (!tx_info->skb[i])
continue;
- dma_unmap_single(&ctrl->pdev->dev, packet->dma,
- packet->skb->len, DMA_TO_DEVICE);
- rteth_free_skb(&packet->skb);
+ dma_unmap_single(&ctrl->pdev->dev, dma,
+ tx_info->skb[i]->len, DMA_TO_DEVICE);
+ rteth_free_skb(&tx_info->skb[i]);
}
}
}
for (int r = 0; r < RTETH_TX_RINGS; r++) {
for (int i = 0; i < RTETH_TX_RING_SIZE; i++) {
- ctrl->tx_data[r].packet[i].skb = NULL;
+ ctrl->tx_info[r].skb[i] = NULL;
ctrl->tx_data[r].ring[i] = ctrl->tx_dma +
sizeof(struct rteth_tx_data) * r +
offsetof(struct rteth_tx_data, packet) +
int port, val, slot, len = skb->len, ring = skb_get_queue_mapping(skb);
struct rteth_ctrl *ctrl = netdev_priv(dev);
struct rteth_packet *packet;
+ struct sk_buff **packet_skb;
dma_addr_t packet_dma;
port = rteth_get_dsa_port(skb, dev);
slot = ctrl->tx_info[ring].slot;
packet = &ctrl->tx_data[ring].packet[slot];
packet_dma = ctrl->tx_data[ring].ring[slot];
+ packet_skb = &ctrl->tx_info[ring].skb[slot];
if (unlikely(packet_dma & RING_OWN_HW)) {
netif_stop_subqueue(dev, ring);
return NETDEV_TX_BUSY;
}
- if (likely(packet->skb)) {
+ if (likely(*packet_skb)) {
/* cleanup old data of this slot */
- dma_unmap_single(&ctrl->pdev->dev, packet->dma, packet->skb->len, DMA_TO_DEVICE);
- dev_consume_skb_any(packet->skb);
+ dma_unmap_single(&ctrl->pdev->dev, packet->dma, (*packet_skb)->len, DMA_TO_DEVICE);
+ dev_consume_skb_any(*packet_skb);
}
+ *packet_skb = skb;
packet->len = len;
- packet->skb = skb;
packet->dma = dma_map_single(&ctrl->pdev->dev, skb->data, len, DMA_TO_DEVICE);
if (unlikely(dma_mapping_error(&ctrl->pdev->dev, packet->dma))) {
- dev->stats.tx_errors += rteth_free_skb(&packet->skb);
+ dev->stats.tx_errors += rteth_free_skb(packet_skb);
return NETDEV_TX_OK;
}