[aadk-commits] dbailey: uClinux/trunk r77 -
/uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/...
aadk-commits at lists.digium.com
aadk-commits at lists.digium.com
Wed Dec 20 14:30:52 MST 2006
Author: dbailey
Date: Wed Dec 20 15:30:51 2006
New Revision: 77
URL: http://svn.digium.com/view/aadk?view=rev&rev=77
Log:
Corrected a bug with skb free in hard transmit - Now I wait for DMA to finish before freeing.
Modified:
uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/net/bfin_mac.c
Modified: uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/net/bfin_mac.c
URL: http://svn.digium.com/view/aadk/uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/net/bfin_mac.c?view=diff&rev=77&r1=76&r2=77
==============================================================================
--- uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/net/bfin_mac.c (original)
+++ uClinux/trunk/uClinux-dist/linux-2.6.x/drivers/net/bfin_mac.c Wed Dec 20 15:30:51 2006
@@ -149,9 +149,7 @@
/* init rx_list */
for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
-
tmp_desc = rx_desc + i;
-
tmp_desc->skb = bf537_alloc_skb(1560 + 4);
if (i == 0) {
@@ -207,6 +205,10 @@
tmp_desc = tx_list_head;
for (i = 0; i < CONFIG_BFIN_TX_DESC_NUM; i++) {
if (tmp_desc != NULL) {
+ if (tmp_desc->skb) {
+ dev_kfree_skb(tmp_desc->skb);
+ tmp_desc->skb = NULL;
+ }
#if defined(CONFIG_BFIN_MAC_USE_L1)
l1_data_A_sram_free((unsigned long)tmp_desc);
#else
@@ -219,8 +221,10 @@
tmp_desc = rx_list_head;
for (i = 0; i < CONFIG_BFIN_RX_DESC_NUM; i++) {
if (tmp_desc != NULL) {
- if (tmp_desc->skb)
- kfree_skb(tmp_desc->skb);
+ if (tmp_desc->skb) {
+ dev_kfree_skb(tmp_desc->skb);
+ tmp_desc->skb = NULL;
+ }
#if defined(CONFIG_BFIN_MAC_USE_L1)
l1_data_A_sram_free((unsigned long)tmp_desc);
#else
@@ -485,7 +489,11 @@
do {
tx_list_head->desc_a.config.b_DMA_EN = 0;
tx_list_head->status.status_word = 0;
- tx_list_head = tx_list_head->next;
+ if (tx_list_head->skb) { /* If TX Buff had attached to skb, release it */
+ dev_kfree_skb(tx_list_head->skb);
+ tx_list_head->skb = NULL;
+ }
+ tx_list_head = tx_list_head->next;
} while (tx_list_head->status.status_word != 0);
return; // released something, just return;
}
@@ -495,11 +503,15 @@
if (current_tx_ptr->next->next == tx_list_head) {
while (tx_list_head->status.status_word == 0) {
udelay(10);
- if (tx_list_head->status.status_word != 0 || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
- do {
- tx_list_head->desc_a.config.b_DMA_EN = 0;
- tx_list_head->status.status_word = 0;
- tx_list_head = tx_list_head->next;
+ if (tx_list_head->status.status_word != 0 || !(bfin_read_DMA2_IRQ_STATUS() & 0x08)) {
+ do {
+ tx_list_head->desc_a.config.b_DMA_EN = 0;
+ tx_list_head->status.status_word = 0;
+ if (tx_list_head->skb) { /* If TX Buff had attached to skb, release it */
+ dev_kfree_skb(tx_list_head->skb);
+ tx_list_head->skb = NULL;
+ }
+ tx_list_head = tx_list_head->next;
} while (tx_list_head->status.status_word != 0);
break;
}
@@ -520,67 +532,65 @@
static int bf537mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
- struct bf537mac_local *lp = netdev_priv(dev);
- unsigned int data;
- unsigned long flags;
+ struct bf537mac_local *lp = netdev_priv(dev);
+ unsigned int data;
/* warning: printk in this function may cause error */
- spin_lock_irqsave(&lp->lock, flags);
+/* Do we need some sort of protection against reentrancy since eth0 and eth1 are using this function */
+ current_tx_ptr->skb = skb; /* attach the skb to the DMA buffer descriptor */
// Is skb->data always 16-bit aligned? Do we need to memcpy((char *)(tail->packet + 2),skb->data,len)?
- if (((((unsigned int)(skb->data)) & 0x03) == 2) && (skb_headroom(skb) >= 6)) {
+ if (((((unsigned int)(skb->data)) & 0x03) == 2) && (skb_headroom(skb) >= 6)) {
//move skb->data to current_tx_ptr payload
#ifdef TRACE_PACKETS
- lp->stats.tx_dropped++;
+ lp->stats.tx_dropped++;
#endif
- data = (unsigned int)(skb->data);
- data -= 6;
- *((unsigned short *)data) = (unsigned short)(skb->len + 6);
- memmove((char *)(data + 2), (char *)(data + 6), 12);
- setup_hdr((unsigned char *)(data + 14), lp->amlan);
- current_tx_ptr->desc_a.start_addr = (unsigned long)data;
- if (current_tx_ptr->status.status_word != 0)
+ data = (unsigned int)(skb->data);
+ data -= 6;
+ *((unsigned short *)data) = (unsigned short)(skb->len + 4);
+ memmove((char *)(data + 2), (char *)(data + 6), 12);
+ setup_hdr((unsigned char *)(data + 14), lp->amlan);
+ current_tx_ptr->desc_a.start_addr = (unsigned long)data;
+ if (current_tx_ptr->status.status_word != 0)
current_tx_ptr->status.status_word = 0;
- blackfin_dcache_invalidate_range(data, (data+(skb->len)) + 6); //this is important!
-
- } else {
+ blackfin_dcache_invalidate_range(data, (data+(skb->len)) + 6); //this is important!
+
+ } else {
#ifdef TRACE_PACKETS
/* XXX use error counter to track complex transmits */
- lp->stats.tx_errors++;
+ lp->stats.tx_errors++;
#endif
- *((unsigned short *)(current_tx_ptr->packet)) = (unsigned short)(skb->len + 6);
- memcpy((char *)(current_tx_ptr->packet + 2),skb->data,(12));
+ *((unsigned short *)(current_tx_ptr->packet)) = (unsigned short)(skb->len + 4);
+ memcpy((char *)(current_tx_ptr->packet + 2),skb->data,(12));
#ifdef TRACE_PACKETS
- if (lp->amlan)
- lp->stats.tx_errors++;
+ if (lp->amlan)
+ lp->stats.tx_errors++;
#endif
- setup_hdr((unsigned char *)(current_tx_ptr->packet + 14), lp->amlan);
- memcpy((char *)(current_tx_ptr->packet + 18),skb->data + 12,(skb->len - 12));
- current_tx_ptr->desc_a.start_addr = (unsigned long)current_tx_ptr->packet;
- if (current_tx_ptr->status.status_word != 0)
- current_tx_ptr->status.status_word = 0;
- blackfin_dcache_invalidate_range((unsigned int)current_tx_ptr->packet, (unsigned int)(current_tx_ptr->packet + skb->len) + 6);
- }
-
- current_tx_ptr->desc_a.config.b_DMA_EN = 1; //enable this packet's dma
-
- if (bfin_read_DMA2_IRQ_STATUS() & 0x08) { //tx dma is running, just return
- goto out;
- } else { //tx dma is not running
- bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
- bfin_write_DMA2_CONFIG(*((unsigned short *)(&(current_tx_ptr->desc_a.config)))); // dma enabled, read from memory, size is 6
- // Turn on the EMAC tx
- bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
- }
-
- out:
- adjust_tx_list();
- current_tx_ptr = current_tx_ptr->next;
- dev->trans_start = jiffies;
- lp->stats.tx_packets++;
- lp->stats.tx_bytes += (skb->len);
- spin_unlock_irqrestore(&lp->lock, flags);
- dev_kfree_skb(skb);
+ setup_hdr((unsigned char *)(current_tx_ptr->packet + 14), lp->amlan);
+ memcpy((char *)(current_tx_ptr->packet + 18),skb->data + 12,(skb->len - 12));
+ current_tx_ptr->desc_a.start_addr = (unsigned long)current_tx_ptr->packet;
+ if (current_tx_ptr->status.status_word != 0)
+ current_tx_ptr->status.status_word = 0;
+ blackfin_dcache_invalidate_range((unsigned int)current_tx_ptr->packet, (unsigned int)(current_tx_ptr->packet + skb->len) + 6);
+ }
+
+ current_tx_ptr->desc_a.config.b_DMA_EN = 1; //enable this packet's dma
+
+ if (bfin_read_DMA2_IRQ_STATUS() & 0x08) { //tx dma is running, just return
+ goto out;
+ } else { //tx dma is not running
+ bfin_write_DMA2_NEXT_DESC_PTR(&(current_tx_ptr->desc_a));
+ bfin_write_DMA2_CONFIG(*((unsigned short *)(&(current_tx_ptr->desc_a.config)))); // dma enabled, read from memory, size is 6
+ // Turn on the EMAC tx
+ bfin_write_EMAC_OPMODE(bfin_read_EMAC_OPMODE() | TE);
+ }
+
+ out:
+ adjust_tx_list();
+ current_tx_ptr = current_tx_ptr->next;
+ dev->trans_start = jiffies;
+ lp->stats.tx_packets++;
+ lp->stats.tx_bytes += (skb->len);
return 0;
}
@@ -634,21 +644,19 @@
lp->stats.rx_dropped++;
#endif
}
-
-
/*
- if (len >= 300) {
- printk("going to copy the big packet\n");
+ if (len >= 300) {
+ printk("going to copy the big packet\n");
for (i=0;i<len;i++) {
printk("%.2x-",((unsigned char *)pkt)[i]);
if (((i%8)==0) && (i!=0)) printk("\n");
}
- printk("\n");
+ printk("\n");
}
*/
#if 0
- printk("Rx: %02x%02x\n", skb->data[14], skb->data[15]);
+ printk("Rx: %02x%02x\n", skb->data[14], skb->data[15]);
#endif
dev->last_rx = jiffies;
@@ -659,12 +667,12 @@
lp->stats.rx_bytes += len;
out:
- if (!rx_desc->skb)
- rx_desc->skb = bf537_alloc_skb(1560 + 4);
- if (rx_desc->skb)
- rx_desc->desc_a.start_addr = (unsigned long)rx_desc->skb->data;
- else
- rx_desc->desc_a.start_addr = (unsigned long)rx_desc->packet;
+ if (!rx_desc->skb)
+ rx_desc->skb = bf537_alloc_skb(1560 + 4);
+ if (rx_desc->skb)
+ rx_desc->desc_a.start_addr = (unsigned long)rx_desc->skb->data;
+ else
+ rx_desc->desc_a.start_addr = (unsigned long)rx_desc->packet;
return;
}
@@ -878,7 +886,6 @@
/* free the rx/tx buffers */
desc_list_free();
}
-
return 0;
}
@@ -1028,7 +1035,6 @@
dev_set_drvdata(dev, ndev);
- //printk("bf537_mac: probe finished\n");
return ret;
}
More information about the aadk-commits
mailing list