Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 111902
b: refs/heads/master
c: 4df89bd
h: refs/heads/master
v: v3
  • Loading branch information
Lennert Buytenhek authored and Lennert Buytenhek committed Sep 19, 2008
1 parent 123fec9 commit 251e59e
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 49 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 170e7108a368c52df1ec466966fd1db6e45a7ad2
refs/heads/master: 4df89bd5a5fc33860f15f5f001a78f2b3f150725
95 changes: 47 additions & 48 deletions trunk/drivers/net/mv643xx_eth.c
Original file line number Diff line number Diff line change
Expand Up @@ -699,79 +699,74 @@ static inline __be16 sum16_as_be(__sum16 sum)
return (__force __be16)sum;
}

static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
static int txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
{
struct mv643xx_eth_private *mp = txq_to_mp(txq);
int nr_frags = skb_shinfo(skb)->nr_frags;
int tx_index;
struct tx_desc *desc;
u32 cmd_sts;
u16 l4i_chk;
int length;

cmd_sts = TX_FIRST_DESC | GEN_CRC | BUFFER_OWNED_BY_DMA;

tx_index = txq_alloc_desc_index(txq);
desc = &txq->tx_desc_area[tx_index];

if (nr_frags) {
txq_submit_frag_skb(txq, skb);
length = skb_headlen(skb);
} else {
cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
length = skb->len;
}

desc->byte_cnt = length;
desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
l4i_chk = 0;

if (skb->ip_summed == CHECKSUM_PARTIAL) {
int mac_hdr_len;
int tag_bytes;

BUG_ON(skb->protocol != htons(ETH_P_IP) &&
skb->protocol != htons(ETH_P_8021Q));

cmd_sts |= GEN_TCP_UDP_CHECKSUM |
GEN_IP_V4_CHECKSUM |
ip_hdr(skb)->ihl << TX_IHL_SHIFT;
tag_bytes = (void *)ip_hdr(skb) - (void *)skb->data - ETH_HLEN;
if (unlikely(tag_bytes & ~12)) {
if (skb_checksum_help(skb) == 0)
goto no_csum;
kfree_skb(skb);
return 1;
}

mac_hdr_len = (void *)ip_hdr(skb) - (void *)skb->data;
switch (mac_hdr_len - ETH_HLEN) {
case 0:
break;
case 4:
cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
break;
case 8:
cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
break;
case 12:
if (tag_bytes & 4)
cmd_sts |= MAC_HDR_EXTRA_4_BYTES;
if (tag_bytes & 8)
cmd_sts |= MAC_HDR_EXTRA_8_BYTES;
break;
default:
if (net_ratelimit())
dev_printk(KERN_ERR, &txq_to_mp(txq)->dev->dev,
"mac header length is %d?!\n", mac_hdr_len);
break;
}

cmd_sts |= GEN_TCP_UDP_CHECKSUM |
GEN_IP_V4_CHECKSUM |
ip_hdr(skb)->ihl << TX_IHL_SHIFT;

switch (ip_hdr(skb)->protocol) {
case IPPROTO_UDP:
cmd_sts |= UDP_FRAME;
desc->l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
l4i_chk = ntohs(sum16_as_be(udp_hdr(skb)->check));
break;
case IPPROTO_TCP:
desc->l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
l4i_chk = ntohs(sum16_as_be(tcp_hdr(skb)->check));
break;
default:
BUG();
}
} else {
no_csum:
/* Errata BTS #50, IHL must be 5 if no HW checksum */
cmd_sts |= 5 << TX_IHL_SHIFT;
desc->l4i_chk = 0;
}

tx_index = txq_alloc_desc_index(txq);
desc = &txq->tx_desc_area[tx_index];

if (nr_frags) {
txq_submit_frag_skb(txq, skb);
length = skb_headlen(skb);
} else {
cmd_sts |= ZERO_PADDING | TX_LAST_DESC | TX_ENABLE_INTERRUPT;
length = skb->len;
}

desc->l4i_chk = l4i_chk;
desc->byte_cnt = length;
desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);

__skb_queue_tail(&txq->tx_skb, skb);

/* ensure all other descriptors are written before first cmd_sts */
Expand All @@ -786,6 +781,8 @@ static void txq_submit_skb(struct tx_queue *txq, struct sk_buff *skb)
txq_enable(txq);

txq->tx_desc_count += nr_frags + 1;

return 0;
}

static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
Expand All @@ -794,7 +791,6 @@ static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
int queue;
struct tx_queue *txq;
struct netdev_queue *nq;
int entries_left;

queue = skb_get_queue_mapping(skb);
txq = mp->txq + queue;
Expand All @@ -815,14 +811,17 @@ static int mv643xx_eth_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
}

txq_submit_skb(txq, skb);
txq->tx_bytes += skb->len;
txq->tx_packets++;
dev->trans_start = jiffies;
if (!txq_submit_skb(txq, skb)) {
int entries_left;

txq->tx_bytes += skb->len;
txq->tx_packets++;
dev->trans_start = jiffies;

entries_left = txq->tx_ring_size - txq->tx_desc_count;
if (entries_left < MAX_SKB_FRAGS + 1)
netif_tx_stop_queue(nq);
entries_left = txq->tx_ring_size - txq->tx_desc_count;
if (entries_left < MAX_SKB_FRAGS + 1)
netif_tx_stop_queue(nq);
}

return NETDEV_TX_OK;
}
Expand Down

0 comments on commit 251e59e

Please sign in to comment.