Hi,
This patch firstly adds support for the config key to set the MAC address.
It also adds functionality to reset the ownership bits for the most recent
transmitted TX buffers descriptors. Failure to do this leads to a Buffer
Underrun Fault in interrupt mode.
John Eigelaar
? at91_eth.patch
Index: ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/arm/at91/current/ChangeLog,v
retrieving revision 1.1
diff -u -F^f -r1.1 ChangeLog
--- ChangeLog 5 Mar 2007 19:08:10 -0000 1.1
+++ ChangeLog 23 Mar 2007 13:14:49 -0000
@@ -1,3 +1,9 @@
+2007-03-23 John Eigelaar <[EMAIL PROTECTED]>
+
+ * src/if_at91.c: Added support for the ETH_DRV_SET_MAC_ADDRESS
+ control key. Added functionality to clear the transmit buffer ownershiop
+ bits when the TXCOMP status is detected.
+
2007-01-17 John Eigelaar <[EMAIL PROTECTED]>
* src/if_at91.c * include/at91_eth.cdl: Working implementation
Index: src/if_at91.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/arm/at91/current/src/if_at91.c,v
retrieving revision 1.1
diff -u -F^f -r1.1 if_at91.c
--- src/if_at91.c 5 Mar 2007 19:08:10 -0000 1.1
+++ src/if_at91.c 23 Mar 2007 13:14:51 -0000
@@ -174,6 +174,7 @@
tbd_t tbd[CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS];
unsigned long curr_tx_key;
cyg_bool tx_busy;
+ cyg_uint32 last_tbd_idx;
cyg_uint32 curr_tbd_idx;
cyg_uint32 curr_rbd_idx;
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
@@ -660,8 +661,33 @@
at91_eth_control(struct eth_drv_sc *sc, unsigned long key,
void *data, int length)
{
- diag_printf("%s.%d: key %lx\n", __FUNCTION__, __LINE__, key);
- return (1);
+
+ switch (key)
+ {
+ case ETH_DRV_SET_MAC_ADDRESS:
+ {
+ if(length >= ETHER_ADDR_LEN)
+ {
+ at91_eth_stop(sc);
+
+ cyg_uint8 * enaddr = (cyg_uint8 *)data;
+ debug1_printf("AT91_ETH: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ enaddr[0],enaddr[1],enaddr[2],
+ enaddr[3],enaddr[4],enaddr[5]);
+
+ at91_set_mac((at91_eth_priv_t *)sc->driver_private,enaddr,1);
+ at91_eth_start(sc,enaddr,0);
+ return 0;
+ }
+ return 1;
+ }
+ default:
+ {
+ diag_printf("%s.%d: key %lx\n", __FUNCTION__, __LINE__, key);
+ return (1);
+ }
+ }
+
}
// This function is called to see if another packet can be sent.
@@ -700,6 +726,9 @@
cyg_uint32 sr;
priv->tx_busy = true;
+
+ priv->last_tbd_idx = priv->curr_tbd_idx;
+
for(i = 0;i<sg_len;i++)
{
priv->tbd[priv->curr_tbd_idx].addr = sg_list[i].buf;
@@ -730,6 +759,24 @@
at91_start_transmitter(priv);
}
+static void at91_reset_tbd(at91_eth_priv_t *priv)
+{
+ while(priv->curr_tbd_idx != priv->last_tbd_idx)
+ {
+ if(priv->last_tbd_idx == (CYGNUM_DEVS_ETH_ARM_AT91_TX_BUFS-1))
+ {
+ priv->tbd[priv->last_tbd_idx].sr = (AT91_EMAC_TBD_SR_USED|AT91_EMAC_TBD_SR_WRAP);
+ priv->last_tbd_idx = 0;
+ }
+ else
+ {
+ priv->tbd[priv->last_tbd_idx].sr = AT91_EMAC_TBD_SR_USED;
+ priv->last_tbd_idx++;
+ }
+ }
+}
+
+
//======================================================================
#ifdef CYGINT_IO_ETH_INT_SUPPORT_REQUIRED
@@ -810,6 +857,7 @@
/* Check that the last transmission is completed */
if (tsr&AT91_EMAC_TSR_COMP) //5
{
+ at91_reset_tbd(priv);
_eth_drv_tx_done(sc,priv->curr_tx_key,0);
priv->tx_busy = false;
}