linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] ocp enet
  2002-02-27 23:32 [PATCH] ocp enet John Tyner
@ 2002-02-27 16:35 ` Armin
  2002-03-04 21:17   ` andrew may
  0 siblings, 1 reply; 8+ messages in thread
From: Armin @ 2002-02-27 16:35 UTC (permalink / raw)
  To: John Tyner; +Cc: linuxppc-embedded


John Tyner wrote:
>>From andrew may <acmay@acmay.homeip.net>:
>
> Added Am79C874 support
> Improved find_phy function:
>   use Min/Max Phy addr defines (not sure if MAX_NUM_PHYS is still needed)
>   continue to look for phy if we find a phy we don't support instead of panic
>   detect/report missing pullup problem
>   removed unused phy_id_done
> enet_open
>   checks for undetected phy and fails if no know phy is present
> enet_open/close
>  checks for completion of soft reset (writing 0 to soft reset has no effect)
>
>
> ------------------------------------------------------------------------


Thanks,

I want to try in on a few boards I have before it goes in.

--armin


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH] ocp enet
@ 2002-02-27 23:32 John Tyner
  2002-02-27 16:35 ` Armin
  0 siblings, 1 reply; 8+ messages in thread
From: John Tyner @ 2002-02-27 23:32 UTC (permalink / raw)
  To: linuxppc-embedded

[-- Attachment #1: Type: TEXT/PLAIN, Size: 482 bytes --]

>From andrew may <acmay@acmay.homeip.net>:

Added Am79C874 support
Improved find_phy function:
  use Min/Max Phy addr defines (not sure if MAX_NUM_PHYS is still needed)
  continue to look for phy if we find a phy we don't support instead of panic
  detect/report missing pullup problem
  removed unused phy_id_done
enet_open
  checks for undetected phy and fails if no know phy is present
enet_open/close
 checks for completion of soft reset (writing 0 to soft reset has no effect)

[-- Attachment #2: Type: TEXT/PLAIN, Size: 6942 bytes --]

diff -ur linux-base/drivers/net/ibm_ocp_enet.c linux-ppc/drivers/net/ibm_ocp_enet.c
--- linux-base/drivers/net/ibm_ocp_enet.c	Tue Feb 26 16:56:02 2002
+++ linux-ppc/drivers/net/ibm_ocp_enet.c	Wed Feb 27 15:04:30 2002
@@ -170,7 +170,10 @@
 	emacp = (emac_t *) dev->base_addr;
 	emac_ier = 0;
 	fep->sequence_done = 0;
-
+        if( !fep->phy ){
+                printk(KERN_NOTICE "%s: Cannot open interface without phy\n", dev->name );
+                return -ENODEV;
+        }
 	/* although the probe has already reset the chip we do it again here */
 	printk(KERN_NOTICE "Reset ethernet interfaces\n");
 
@@ -182,7 +185,11 @@
 	eieio();
 
 	for (loop = 0; loop < 1000; loop++) ;
-	emacp->em0mr0 = emacp->em0mr0 & ~EMAC_M0_SRST;
+	if( emacp->em0mr0 & EMAC_M0_SRST ){
+                eieio();
+                printk(KERN_NOTICE "%s: Cannot open interface without Link\n", dev->name );
+                return -ENODEV;
+        }
 	eieio();
 
 	/* Set the MAL configuration register */
@@ -404,7 +411,10 @@
 
 	for (delay = 0; delay < 1000; delay++) ;
 
-	emacp->em0mr0 = emacp->em0mr0 & ~EMAC_M0_SRST;
+	if( emacp->em0mr0 & EMAC_M0_SRST ){
+                /*not sure what to do here hopefully it clears before another open*/
+                printk( KERN_ERR "%s: Phy SoftReset didn't clear, no link?\n", dev->name );
+        }
 	eieio();
 
 	/*
diff -ur linux-base/drivers/net/ibm_ocp_enet.h linux-ppc/drivers/net/ibm_ocp_enet.h
--- linux-base/drivers/net/ibm_ocp_enet.h	Wed Feb 27 13:14:51 2002
+++ linux-ppc/drivers/net/ibm_ocp_enet.h	Wed Feb 27 14:44:56 2002
@@ -74,6 +74,8 @@
 #define BL_MAL_TXEOB		5
 #define BL_MAL_RXEOB		6
 
+#define MIN_PHY_ADDR            0x00
+#define MAX_PHY_ADDR            0x1f
 #define MAX_NUM_PHYS		4
 
 /* Transmitter timeout. */
@@ -163,7 +165,6 @@
 	int tx_slot;
 	int ack_slot;
 	uint phy_id;
-	uint phy_id_done;
 	uint phy_status;
 	uint phy_speed;
 	uint phy_duplex;
diff -ur linux-base/drivers/net/ibm_ocp_phy.c linux-ppc/drivers/net/ibm_ocp_phy.c
--- linux-base/drivers/net/ibm_ocp_phy.c	Tue Feb 26 16:56:45 2002
+++ linux-ppc/drivers/net/ibm_ocp_phy.c	Wed Feb 27 14:59:32 2002
@@ -736,6 +736,74 @@
 };
 
 /* ------------------------------------------------------------------------- */
+/* The AMD Am79C874 NetPHY-1LP same as AC101                                 */
+/* This is a hackish copy of the 75 right now. It works for now.             */
+/* It has 100FX support that I have not been able to add/test yet            */
+/*                                                                Andrew May */
+/* Using the same register definitions same as Am79c875*/
+
+static void
+mii_parse_Am79C874_pcr(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_CONF_SPMASK);
+	printk("mii_reg 0x%x status 0x%x mask 0x%x\n", mii_reg, fep->phy_status,
+	       (mii_reg >> 5));
+
+	switch ((mii_reg >> 5)) {
+	case 0x1:
+		*s |= PHY_STAT_10HDX;
+		break;
+
+	case 0x3:
+		*s |= PHY_STAT_10FDX;
+		break;
+
+	case 0x7:
+		*s |= PHY_STAT_100HDX;
+		break;
+
+	case 0xf:
+		*s |= PHY_STAT_100FDX;
+		break;
+	}
+}
+static phy_info_t phy_info_Am79C874 = {
+	0x0022561b,
+	"Am79c874",
+	0,
+	(const phy_cmd_t[]) {	/* config */
+
+			     /* parse cr and anar to get some info */
+
+			     {mk_mii_read(MII_REG_CR), mii_parse_cr},
+			     {mk_mii_read(MII_REG_ANAR), mii_parse_anar},
+			     {mk_mii_end,}
+			     },
+	(const phy_cmd_t[]) {	/* startup - enable interrupts */
+			     {mk_mii_write(MII_REG_CR, PHY_BMCR_AUTON), NULL},	/* Auto neg. on */
+                             /*{ mk_mii_write(MII_AM79C875_MFR, 0x4000), NULL},*/ /* int 1 to signle interrupt */
+                             /*{ mk_mii_write(MII_AM79C875_ICR, 0x00ff), NULL },*/ /* enable interrupts */
+			     {mk_mii_write(MII_REG_CR, PHY_BMCR_RST_NEG), NULL},	/* autonegotiate */
+			     {mk_mii_end,}
+			     },
+	(const phy_cmd_t[]) {	/* ack_int */
+
+			     {mk_mii_read(MII_AM79C875_ICR), NULL},
+			     {mk_mii_read(MII_REG_SR), mii_parse_sr},
+			     {mk_mii_read(MII_REG_ANAR), mii_parse_anar},
+			     {mk_mii_read(MII_REG_ANAR),
+			      mii_parse_Am79C874_pcr},
+			     {mk_mii_end,}
+			     },
+	(const phy_cmd_t[]) {	/* shutdown - nothing */
+			     {mk_mii_end,}
+			     },
+};
+
+/* ------------------------------------------------------------------------- */
 /* The Broadcom BCM5221 */
 
 /* register definitions */
@@ -841,6 +909,7 @@
 	&phy_info_dp83846A,
 	&phy_info_lu3x31ft,
 	&phy_info_Am79C875,
+	&phy_info_Am79C874,
 	&phy_info_bcm5221,
 	NULL
 };
@@ -966,39 +1035,46 @@
 {
 	struct fec_enet_private *fep;
 	int i;
-	uint phy_reg, phy_reg2;
-	uint phytype;
+	uint phy_reg;
 
 	fep = (struct fec_enet_private *) dev->priv;
-	for (i = 0; i < MAX_NUM_PHYS; i++) {
+	for (i = MIN_PHY_ADDR; i <= MAX_PHY_ADDR; i++) {
 		fep->phy_addr = i;
 		if (!(fec_enet_mdio_read(dev, mk_mii_read(MII_REG_PHYIR1),
-					&phy_reg)) && 
-		    !(fec_enet_mdio_read(dev, mk_mii_read(MII_REG_PHYIR2),
-		                        &phy_reg2)))
+                                         &phy_reg)) )
 			break;
+        got_bad_phy:
 	}
 
-	fep->phy_addr = i;
-	if ((phytype = (phy_reg & 0xffff)) != 0xffff) {
-		/* Got first part of ID, now get remainder. */
-		fep->phy_id = phytype << 16;
-		fec_enet_mdio_read(dev, mk_mii_read(MII_REG_PHYIR2), &phy_reg);
-		fep->phy_id |= (phy_reg & 0xffff);
+        if( i <= MAX_PHY_ADDR ){
+		/* Got 2nd part of ID, now get remainder. */
+                fep->phy_id = (phy_reg&0xffff) << 16;
+
+                if( fec_enet_mdio_read(dev, mk_mii_read(MII_REG_PHYIR2),
+                                       &phy_reg) ){
+                        if( i == MIN_PHY_ADDR )
+                                printk( KERN_ERR "%s: Got bad Phy Read, missing MDIO pullup?\n", dev->name );
+                        goto got_bad_phy;
+                }
+
+		fep->phy_id |= (phy_reg&0xffff);
+
 		for (i = 0; phy_info[i]; i++)
 			if (phy_info[i]->id ==
 			    (fep->phy_id >> phy_info[i]->shift))
 				break;
-		if (!phy_info[i])
-			panic("%s: PHY id 0x%08x is not supported!\n",
-			      dev->name, fep->phy_id);
+		if (!phy_info[i]){
+			printk( KERN_ERR "%s: PHY id 0x%08x is not supported!\n",
+                                dev->name, fep->phy_id);
+                        i = fep->phy_addr;
+                        goto got_bad_phy;
+                }
 
 		fep->phy = phy_info[i];
-		fep->phy_id_done = 1;
 
 		printk("%s: Phy @ 0x%x, type %s (0x%08x)\n",
 		       dev->name, fep->phy_addr, fep->phy->name, fep->phy_id);
-	} else
-		printk("fec: No PHY device found.\n");
-
+	} else {
+                printk("%s: No PHY device found.\n", dev->name);
+        }
 }

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-03-04 21:17   ` andrew may
@ 2002-03-04 14:31     ` Armin
  2002-03-05  3:53       ` andrew may
  0 siblings, 1 reply; 8+ messages in thread
From: Armin @ 2002-03-04 14:31 UTC (permalink / raw)
  To: andrew may; +Cc: John Tyner, linuxppc-embedded


andrew may wrote:
> On Wed, Feb 27, 2002 at 04:35:05PM +0000, Armin wrote:
>
>>Thanks,
>>
>>I want to try in on a few boards I have before it goes in.
>>
>>--armin
>>
>
> Have you gotten a chance to try it yet? The testing I have
> done has not shown any problems and I have been able to test
> just about all of the cases. Boards with/without the correct
> pull-ups. Remove the correct phy-id from the table. Booting
> without a link.
>
> Here is another patch that for the driver. It removes some
> cut and paste code from the rx interupts and breaks the work
> into rx_clean and rx_fill functions. rx_fill is also called from
> open.
>


Yes I have.

I added history info and sent it to Tom to check in.

I will look into this patch and will try it after Tom gets done.

armin


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-02-27 16:35 ` Armin
@ 2002-03-04 21:17   ` andrew may
  2002-03-04 14:31     ` Armin
  0 siblings, 1 reply; 8+ messages in thread
From: andrew may @ 2002-03-04 21:17 UTC (permalink / raw)
  To: Armin; +Cc: John Tyner, linuxppc-embedded

[-- Attachment #1: Type: text/plain, Size: 984 bytes --]

On Wed, Feb 27, 2002 at 04:35:05PM +0000, Armin wrote:
> Thanks,
>
> I want to try in on a few boards I have before it goes in.
>
> --armin

Have you gotten a chance to try it yet? The testing I have
done has not shown any problems and I have been able to test
just about all of the cases. Boards with/without the correct
pull-ups. Remove the correct phy-id from the table. Booting
without a link.

Here is another patch that for the driver. It removes some
cut and paste code from the rx interupts and breaks the work
into rx_clean and rx_fill functions. rx_fill is also called from
open.

If rx_fill fails to alloc a skb, it leave the rx_slot there, so
the next time through rx_clean skips over all the slots without
skb's and hopefully rx_fill with then be able to do the alloc.
This prevents taking a rxde interrupt for a single alloc failure.

I also added a skb_res module parm, I should have defaulted it
down to 0 for most people, but I forgot and left it at the value
I use.

[-- Attachment #2: ocp_enet.diff2 --]
[-- Type: text/plain, Size: 12870 bytes --]

--- drivers/net/ibm_ocp_enet.c	Thu Feb 28 12:17:17 2002
+++ drivers/net/ibm_ocp_enet.c	Mon Mar  4 12:54:51 2002
@@ -123,6 +123,8 @@
 void ppc405_eth_txde(int, void *, struct pt_regs *);
 void ppc405_eth_rxde(int, void *, struct pt_regs *);
 void ppc405_eth_mac(int, void *, struct pt_regs *);
+static void ppc405_rx_fill(struct net_device *, int);
+static int ppc405_rx_clean(struct net_device *);

 int fec_enet_mdio_read(struct net_device *dev, int reg, uint * value);
 int fec_enet_mdio_write(struct net_device *dev, int reg);
@@ -156,6 +158,12 @@

 int zmii_bridge;

+static int skb_res=(64+2);
+MODULE_PARM(skb_res, "i");
+MODULE_PARM_DESC(skb_res, "Amount of data to reserve on skb buffs\n"
+                 "The 405 handles a missaligned IP header fine but\n"
+                 "this can help if you are routing to a tunnel or a device that needs aligned data" );
+
 static int
 ppc405_enet_open(struct net_device *dev)
 {
@@ -216,21 +224,17 @@
 	fep->tx_desc[loop - 1].ctrl |= MAL_TX_CTRL_WRAP;

 	/* Format the receive descriptor ring. */
-	for (loop = 0; loop < NUM_RX_BUFF; loop++) {
-		fep->rx_skb[loop] = dev_alloc_skb(DESC_RX_BUF_SIZE);
-		fep->rx_desc[loop].data_len = 0;
-		fep->rx_desc[loop].data_ptr =
-		    (char *) virt_to_phys(fep->rx_skb[loop]->data);
-		fep->rx_desc[loop].ctrl = MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
-
-		dma_cache_wback_inv((unsigned long)
-				    fep->rx_skb[loop]->data, DESC_RX_BUF_SIZE);
-	}
-
-	fep->rx_desc[loop - 1].ctrl |= MAL_RX_CTRL_WRAP;
+	fep->rx_slot = 0;
+        ppc405_rx_fill(dev,0);
+        if( fep->rx_slot != 0 ){
+                printk(KERN_ERR "%s: Not enough mem for RxChain durning Open?\n", dev->name );
+                /*We couldn't fill the ring at startup?
+                 *We could clean up and fail to open but right now we will try to
+                 *carry on. It may be a sign of a bad NUM_RX_BUFF value
+                 */
+        }

 	fep->tx_cnt = 0;
-	fep->rx_slot = 0;
 	fep->tx_slot = 0;
 	fep->ack_slot = 0;

@@ -918,133 +922,145 @@

 	return;
 }
+/*
+  Fill/Re-fill the rx chain with valid ctrl/ptrs.
+  This function will fill from rx_slot up to the parm end.
+  So to completely fill the chain pre-set rx_slot to 0 and
+  pass in an end of 0.
+ */
+static void ppc405_rx_fill(struct net_device *dev, int end)
+{
+        int i;
+	struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
+        unsigned char* ptr;
+
+        i=fep->rx_slot;
+        do {
+                if( fep->rx_skb[i] != NULL ){
+                        /*We will trust the skb is still in a good state */
+                        ptr =
+                                (char *) virt_to_phys(fep->rx_skb[i]->data);
+                }else{
+
+                        fep->rx_skb[i] = dev_alloc_skb(DESC_RX_BUF_SIZE+skb_res);
+
+                        if( fep->rx_skb[i] == NULL ){
+                                /* Keep rx_slot here, the next time clean/fill is called
+                                 * we will try again before the MAL wraps back here
+                                 * If the MAL tries to use this descriptor with
+                                 * the EMPTY bit off it will cause the
+                                 * rxde interrupt.  That is where we will
+                                 * try again to allocate an sk_buff.
+                                 */
+                                break;
+
+                        }
+
+                        if( skb_res ) skb_reserve(fep->rx_skb[i], skb_res);
+
+                        dma_cache_wback_inv((unsigned long) fep->rx_skb[i]->
+                                            data, DESC_RX_BUF_SIZE);
+                        ptr =
+                                (char *) virt_to_phys(fep->rx_skb[i]->data);
+                }
+                fep->rx_desc[i].ctrl      =
+                        MAL_RX_CTRL_EMPTY |
+                        MAL_RX_CTRL_INTR  | /*could be smarter about this to avoid ints at high loads*/
+                        (i == (NUM_RX_BUFF-1) ? MAL_RX_CTRL_WRAP : 0);
+
+                fep->rx_desc[i].data_ptr  = ptr;
+        }while( (i = (i+1) % NUM_RX_BUFF) != end );

-void
-ppc405_eth_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
+        fep->rx_slot = i;
+}
+static int ppc405_rx_clean(struct net_device *dev)
 {
-	struct net_device *dev;
+        int i;
 	int error, frame_length;
-	struct fec_enet_private *fep;
-	mal_desc_t *rx_desc;
-	struct sk_buff *skb_rx, **skb_rx_p;
-	int first_time;
-
-	/*
-	 * Protect against ppc405_eth_rxde() modifying data structures
-	 * this function is using.  Note that ppc405_eth_rxde() does
-	 * not have to protect against this function because if an rxde
-	 * interrupt occurs the hardware will have disabled the EMAC and
-	 * thus the rxeob interrupt will not occur until ppc405_eth_rxde()
-	 * re-enables the EMAC.
-	 */
-
-	dev = (struct net_device *) dev_instance;
-	fep = dev->priv;
-	disable_irq(irq_resource[fep->emac_num][BL_MAL_RXDE].irq);
-
-	first_time = 1;
-	frame_length = 0;
+	struct fec_enet_private *fep = (struct fec_enet_private *)dev->priv;
+        unsigned short ctrl;

-      do_it_again:
-	rx_desc = &fep->rx_desc[fep->rx_slot];
-	skb_rx_p = &fep->rx_skb[fep->rx_slot];
-	skb_rx = *skb_rx_p;
+        i = fep->rx_slot;

-	while ((!(rx_desc->ctrl & MAL_RX_CTRL_EMPTY)) && (skb_rx != NULL)) {
+        do{
+                if( fep->rx_skb[i] == NULL )
+                        goto skip;/*we have already handled the packet but haved failed to alloc*/
+                /*
+                   since rx_desc is in uncached mem we don't keep reading it directly
+                   we pull out a local copy of ctrl and do the checks on the copy.
+                */
+                ctrl      = fep->rx_desc[i].ctrl;
+                if( ctrl & MAL_RX_CTRL_EMPTY )
+                        break; /*we don't have any more ready packets*/

-		if (rx_desc->ctrl & EMAC_BAD_RX_PACKET) {
+		if (ctrl & EMAC_BAD_RX_PACKET) {

 			fep->stats.rx_errors++;
 			fep->stats.rx_dropped++;

-			if (rx_desc->ctrl & EMAC_RX_ST_OE)
+			if (ctrl & EMAC_RX_ST_OE)
 				fep->stats.rx_fifo_errors++;
-			if (rx_desc->ctrl & EMAC_RX_ST_AE)
+			if (ctrl & EMAC_RX_ST_AE)
 				fep->stats.rx_frame_errors++;
-			if (rx_desc->ctrl & EMAC_RX_ST_BFCS)
+			if (ctrl & EMAC_RX_ST_BFCS)
 				fep->stats.rx_crc_errors++;
-			if (rx_desc->ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
-					     EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
+			if (ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
+                                    EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
 				fep->stats.rx_length_errors++;
-
-			rx_desc->ctrl &= ~EMAC_BAD_RX_PACKET;
-			rx_desc->ctrl |= MAL_RX_CTRL_EMPTY;
-
 		} else {

 			/* Send the skb up the chain. */
+			frame_length = fep->rx_desc[i].data_len - 4;

-			frame_length = rx_desc->data_len - 4;
-
-			skb_put(skb_rx, frame_length);
-			skb_rx->dev = dev;
-			skb_rx->protocol = eth_type_trans(skb_rx, dev);
+			skb_put(fep->rx_skb[i], frame_length);
+			fep->rx_skb[i]->dev = dev;
+			fep->rx_skb[i]->protocol = eth_type_trans(fep->rx_skb[i], dev);

-			error = netif_rx(skb_rx);
+			error = netif_rx(fep->rx_skb[i]);
 			if ((error == NET_RX_DROP) || (error == NET_RX_BAD)) {
 				fep->stats.rx_dropped++;
 			} else {
 				fep->stats.rx_packets++;
 				fep->stats.rx_bytes += frame_length;
 			}
-
-			*skb_rx_p = dev_alloc_skb(DESC_RX_BUF_SIZE);
-
-			if (*skb_rx_p == NULL) {
-
-				/* When MAL tries to use this descriptor with
-				 * the EMPTY bit off it will cause the
-				 * rxde interrupt.  That is where we will
-				 * try again to allocate an sk_buff.
-				 */
-
-			} else {
-
-				skb_rx = *skb_rx_p;
-
-				dma_cache_wback_inv((unsigned long) skb_rx->
-						    data, DESC_RX_BUF_SIZE);
-				rx_desc->data_ptr =
-				    (char *) virt_to_phys(skb_rx->data);
-				rx_desc->ctrl |= MAL_RX_CTRL_EMPTY;
-			}
+                        fep->rx_skb[i] = NULL;
 		}
+        skip:
+	}while( (i = (i+1) % NUM_RX_BUFF) != fep->rx_slot );
+        return i;
+}

-		if (++fep->rx_slot >= NUM_RX_BUFF)
-			fep->rx_slot = 0;
-
-		rx_desc = &fep->rx_desc[fep->rx_slot];
-		skb_rx_p = &fep->rx_skb[fep->rx_slot];
-		skb_rx = *skb_rx_p;
-	}
+void
+ppc405_eth_rxeob(int irq, void *dev_instance, struct pt_regs *regs)
+{
+        int i;
+	struct net_device *dev;
+	struct fec_enet_private *fep;

 	/*
-	 * Don't stay stuck in this handler forever.
-	 * The first time through:
-	 *   Acknowledge the interrupt from the MAL.
-	 *   If another interrupt has come in, go back and process it.
-	 *   (Otherwise, return; the interrupt has been cleared in the device.)
-	 * The second time through:
-	 *   Don't acknowledge the interrupt from the MAL, just return.
-	 *   If another interrupt has come in, ignore it.
-	 *   Didn't acknowledge the interrupt.  That means the UIC interrupt
-	 *     will be reasserted as soon as it is acknowledged and we'll end
-	 *     up in this handler again soon (possibly with no new data to
-	 *     process).  But, in the meantime, other interrupt handlers will
-	 *     have had a shot at the cpu.
+	 * Protect against ppc405_eth_rxde() modifying data structures
+	 * this function is using.  Note that ppc405_eth_rxde() does
+	 * not have to protect against this function because if an rxde
+	 * interrupt occurs the hardware will have disabled the EMAC and
+	 * thus the rxeob interrupt will not occur until ppc405_eth_rxde()
+	 * re-enables the EMAC.
 	 */

-	if (first_time) {
+	dev = (struct net_device *) dev_instance;
+	fep = dev->priv;
+	disable_irq(irq_resource[fep->emac_num][BL_MAL_RXDE].irq);

-		/* Ack the interrupt bits */
-		set_malrxeobisr(fep->mal_num, get_malrxeobisr(fep->mal_num));
+        /*
+         *There was a rx_clean loop before the int ack then a goto to loop
+         *again. This should have a similar behaivor.
+         *
+         */
+        ppc405_rx_clean(dev);
+        /* Ack the interrupt bits */
+        set_malrxeobisr(fep->mal_num, get_malrxeobisr(fep->mal_num));

-		/* make sure no interrupt gets lost */
-		if (!(rx_desc->ctrl & MAL_RX_CTRL_EMPTY)) {
-			first_time = 0;
-			goto do_it_again;
-		}
-	}
+        i = ppc405_rx_clean(dev);
+        ppc405_rx_fill(dev, i);

 	enable_irq(irq_resource[fep->emac_num][BL_MAL_RXDE].irq);

@@ -1089,12 +1105,7 @@
 {
 	struct net_device *dev;
 	struct fec_enet_private *fep;
-	int curr;
-	int end;
-	int frame_length, error;
-	mal_desc_t *rx_desc;
-	struct sk_buff *skb_rx, **skb_rx_p;
-
+
 	dev = (struct net_device *) dev_instance;
 	fep = dev->priv;

@@ -1114,92 +1125,14 @@
 	ppc405_eth_mal_dump(dev, KERN_DEBUG);
 	ppc405_eth_desc_dump(dev, KERN_DEBUG);
 #endif
-
-	curr = fep->rx_slot;
-	end = curr;
-
-	do {
-		rx_desc = &fep->rx_desc[curr];
-
-		if (rx_desc->ctrl & MAL_RX_CTRL_EMPTY) {
-			if (++curr >= NUM_RX_BUFF)
-				curr = 0;
-			continue;
-		}
-
-		if (rx_desc->ctrl & EMAC_BAD_RX_PACKET) {
-
-			fep->stats.rx_errors++;
-			fep->stats.rx_dropped++;
-			if (rx_desc->ctrl & EMAC_RX_ST_OE)
-				fep->stats.rx_fifo_errors++;
-			if (rx_desc->ctrl & EMAC_RX_ST_AE)
-				fep->stats.rx_frame_errors++;
-			if (rx_desc->ctrl & EMAC_RX_ST_BFCS)
-				fep->stats.rx_crc_errors++;
-			if (rx_desc->ctrl & (EMAC_RX_ST_RP | EMAC_RX_ST_PTL |
-					     EMAC_RX_ST_ORE | EMAC_RX_ST_IRE))
-				fep->stats.rx_length_errors++;
-
-			rx_desc->ctrl &= ~EMAC_BAD_RX_PACKET;
-			rx_desc->ctrl |= MAL_RX_CTRL_EMPTY;
-
-		} else {
-
-			/* Send the skb up the chain. */
-			frame_length = rx_desc->data_len - 4;
-
-			skb_rx_p = &fep->rx_skb[curr];
-			skb_rx = *skb_rx_p;
-
-			if (*skb_rx_p) {
-
-				skb_put(skb_rx, frame_length);
-				skb_rx->dev = dev;
-				skb_rx->protocol = eth_type_trans(skb_rx, dev);
-
-				error = netif_rx(skb_rx);
-				if ((error == NET_RX_DROP) ||
-				    (error == NET_RX_BAD)) {
-					fep->stats.rx_dropped++;
-				} else {
-					fep->stats.rx_packets++;
-					fep->stats.rx_bytes += frame_length;
-				}
-			}
-
-			*skb_rx_p = dev_alloc_skb(DESC_RX_BUF_SIZE);
-
-			if (*skb_rx_p == NULL) {
-
-				/* When MAL tries to use this descriptor with
-				 * the EMPTY bit off it will cause the
-				 * rxde interrupt.  That is where we will
-				 * try again to allocate an sk_buff.
-				 */
-
-			} else {
-
-				skb_rx = *skb_rx_p;
-				dma_cache_wback_inv((unsigned long)
-						    skb_rx->data,
-						    DESC_RX_BUF_SIZE);
-				rx_desc->data_ptr = (char *)
-				    virt_to_phys(skb_rx->data);
-
-				rx_desc->ctrl |= MAL_RX_CTRL_EMPTY;
-			}
-		}
-
-		if (++curr >= NUM_RX_BUFF)
-			curr = 0;
-
-	} while (curr != end);
+        /* so do we have any good packets still?*/
+        ppc405_rx_clean(dev);

 	/* When the interface is restarted it resets processing to the first
 	 * descriptor in the table.
 	 */
 	fep->rx_slot = 0;
+        ppc405_rx_fill(dev, 0);

 	/* Clear the interrupt */
 	set_malrxdeir(fep->mal_num, get_malrxdeir(fep->mal_num));

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-03-04 14:31     ` Armin
@ 2002-03-05  3:53       ` andrew may
  2002-03-05 10:51         ` Armin
  0 siblings, 1 reply; 8+ messages in thread
From: andrew may @ 2002-03-05  3:53 UTC (permalink / raw)
  To: Armin; +Cc: andrew may, linuxppc-embedded


On Mon, Mar 04, 2002 at 02:31:15PM +0000, Armin wrote:
> andrew may wrote:
> > On Wed, Feb 27, 2002 at 04:35:05PM +0000, Armin wrote:
> >
> >>Thanks,
> >>
> >>I want to try in on a few boards I have before it goes in.
> >>
> >>--armin
> >>
> >
> > Have you gotten a chance to try it yet? The testing I have
> > done has not shown any problems and I have been able to test
> > just about all of the cases. Boards with/without the correct
> > pull-ups. Remove the correct phy-id from the table. Booting
> > without a link.
> >
> > Here is another patch that for the driver. It removes some
> > cut and paste code from the rx interupts and breaks the work
> > into rx_clean and rx_fill functions. rx_fill is also called from
> > open.
> >
>
>
> Yes I have.
>
> I added history info and sent it to Tom to check in.

Thanks
>
> I will look into this patch and will try it after Tom gets done.

Well I just noticed that building as a module is pretty far from
working at the moment. Are there any plans to fix this? I am not
sure how to cleanly get this working since there are all sorts of
exports/externs that need to be fixed up. The tulip driver should
be a good example, but it is broken off into it's own dir and I
don't know if we want to do this for the ocp_enet as well.

I can resend with a .h change and config.in change to pull the
skb_res value out as a build option, but I want to see if anyone
has any other comments before hand.


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-03-05  3:53       ` andrew may
@ 2002-03-05 10:51         ` Armin
  2002-03-06 22:15           ` andrew may
  0 siblings, 1 reply; 8+ messages in thread
From: Armin @ 2002-03-05 10:51 UTC (permalink / raw)
  To: andrew may; +Cc: linuxppc-embedded


andrew may wrote:

>
> Well I just noticed that building as a module is pretty far from
> working at the moment. Are there any plans to fix this?

Havn't thought about it but sound like it needs to addressed.

> I am not
> sure how to cleanly get this working since there are all sorts of
> exports/externs that need to be fixed up.

I can add it to my TODO list unless you need it asap?

> I
> don't know if we want to do this for the ocp_enet as well.
>
fine with me.

> I can resend with a .h change and config.in change to pull the
> skb_res value out as a build option, but I want to see if anyone
> has any other comments before hand.
>
fine

-armin


** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-03-06 22:15           ` andrew may
@ 2002-03-06 16:09             ` Armin
  0 siblings, 0 replies; 8+ messages in thread
From: Armin @ 2002-03-06 16:09 UTC (permalink / raw)
  To: andrew may; +Cc: linuxppc-embedded


andrew may wrote:
> On Tue, Mar 05, 2002 at 10:51:38AM +0000, Armin wrote:
>
>>andrew may wrote:
>>
>>
>>>Well I just noticed that building as a module is pretty far from
>>>working at the moment. Are there any plans to fix this?
>>>
>>Havn't thought about it but sound like it needs to addressed.
>>
>>
>>>I am not
>>>sure how to cleanly get this working since there are all sorts of
>>>exports/externs that need to be fixed up.
>>>
>>I can add it to my TODO list unless you need it asap?
>>
>
> No there is no rush getting this working as a module. I would like
> a nice way to set the amount to reserve on the skb dynamically
> though.
>
>
>>>I
>>>don't know if we want to do this for the ocp_enet as well.
>>>
>>>
>>fine with me.
>>
>
> So would it be easier to just ask someone with bk access to the
> tree to add the dir and move the files rather than do a patch.
>
>

There should be a patch since we need to have our own Makefile and its
my responsiblilty to do the work not them.  I will have it done in the
next few days.

--armin

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH] ocp enet
  2002-03-05 10:51         ` Armin
@ 2002-03-06 22:15           ` andrew may
  2002-03-06 16:09             ` Armin
  0 siblings, 1 reply; 8+ messages in thread
From: andrew may @ 2002-03-06 22:15 UTC (permalink / raw)
  To: Armin; +Cc: andrew may, linuxppc-embedded


On Tue, Mar 05, 2002 at 10:51:38AM +0000, Armin wrote:
>
> andrew may wrote:
>
> >
> > Well I just noticed that building as a module is pretty far from
> > working at the moment. Are there any plans to fix this?
>
> Havn't thought about it but sound like it needs to addressed.
>
> > I am not
> > sure how to cleanly get this working since there are all sorts of
> > exports/externs that need to be fixed up.
>
> I can add it to my TODO list unless you need it asap?

No there is no rush getting this working as a module. I would like
a nice way to set the amount to reserve on the skb dynamically
though.

> > I
> > don't know if we want to do this for the ocp_enet as well.
> >
> fine with me.

So would it be easier to just ask someone with bk access to the
tree to add the dir and move the files rather than do a patch.

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2002-03-06 22:15 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-02-27 23:32 [PATCH] ocp enet John Tyner
2002-02-27 16:35 ` Armin
2002-03-04 21:17   ` andrew may
2002-03-04 14:31     ` Armin
2002-03-05  3:53       ` andrew may
2002-03-05 10:51         ` Armin
2002-03-06 22:15           ` andrew may
2002-03-06 16:09             ` Armin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).