This is the mail archive of the ecos-patches@sourceware.org mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RLTK8139 writing of MAC addr to eeprom patch


Hello all,

This patch can write in MAC address at EEPROM.

Be no-no generally, but I think that necessary by an embedded system.

Thanks
Hajime Ishitani
Index: ecos/packages/devs/eth/rltk/8139/current/ChangeLog
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/rltk/8139/current/ChangeLog,v
retrieving revision 1.8
diff -u -r1.8 ChangeLog
--- ecos/packages/devs/eth/rltk/8139/current/ChangeLog	18 Dec 2006 00:49:10 -0000	1.8
+++ ecos/packages/devs/eth/rltk/8139/current/ChangeLog	30 May 2007 05:21:39 -0000
@@ -1,3 +1,9 @@
+2007-05-30  Hajime Ishitani <pigmon@mail.snd.co.jp>
+
+	* src/if_8139.c:
+	* cdl/rltk_8139_eth_drivers.cdl
+	add write in MAC address at EEPROM by SIOCSIFHWADDR.
+
 2006-12-17  Hajime Ishitani <pigmon@mail.snd.co.jp>
 
 	* src/if_8139.c:
Index: ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl,v
retrieving revision 1.1
diff -u -r1.1 rltk_8139_eth_drivers.cdl
--- ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl	13 Nov 2003 13:39:08 -0000	1.1
+++ ecos/packages/devs/eth/rltk/8139/current/cdl/rltk_8139_eth_drivers.cdl	30 May 2007 05:21:39 -0000
@@ -123,17 +123,17 @@
 #	}
 #    }
 
-#    cdl_component CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM {
-#	display "SIOCSIFHWADDR records MAC address in EEPROM"
-#	default_value 0
-#	description   "
-#	    The ioctl() socket call with operand SIOCSIFHWADDR sets the
-#	    interface hardware address - the MAC address or ethernet
-#	    address.  This option causes the new MAC address to be written
-#	    into the EEPROM associated with the interface, so that the new
-#	    MAC address is permanently recorded.  Doing this should be a
-#	    carefully chosen decision, hence this option."
-#    }
+    cdl_component CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM {
+    display "SIOCSIFHWADDR records MAC address in EEPROM"
+    default_value 0
+    description   "
+        The ioctl() socket call with operand SIOCSIFHWADDR sets the
+        interface hardware address - the MAC address or ethernet
+        address.  This option causes the new MAC address to be written
+        into the EEPROM associated with the interface, so that the new
+        MAC address is permanently recorded.  Doing this should be a
+        carefully chosen decision, hence this option."
+    }
 
     cdl_option CYGNUM_DEVS_ETH_RLTK_8139_RX_BUF_LEN_IDX {
         display       "Size of the receive ring"
Index: ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c
===================================================================
RCS file: /cvs/ecos/ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c,v
retrieving revision 1.8
diff -u -r1.8 if_8139.c
--- ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c	18 Dec 2006 00:49:10 -0000	1.8
+++ ecos/packages/devs/eth/rltk/8139/current/src/if_8139.c	30 May 2007 05:21:39 -0000
@@ -177,10 +177,44 @@
 static void rltk8139_poll(struct eth_drv_sc *sc);
 static int rltk8139_int_vector(struct eth_drv_sc *sc);
 
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+static cyg_uint16 rltk8139_eeprom_read( char *cpErAddr, cyg_uint8 Cmd, cyg_uint8 RomAdr );
+static void rltk8139_eeprom_write( char *cpErAddr, cyg_uint8 Cmd, cyg_uint8 RomAdr, cyg_uint16 SrcData );
+#endif
+
 #ifdef DEBUG_RLTK8139_DRIVER
 void rltk8139_print_state(struct eth_drv_sc *sc);
 #endif
 
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+#define EEPROM_CMD_READ         0x06  // eeprom read command
+#define EEPROM_CMD_WRITE        0x05  // eeprom write command
+#define EEPROM_PG_ON            0x80
+#define EEPROM_PG_EECS          0x08
+#define EEPROM_PG_EESK          0x04
+#define EEPROM_PG_EEDI          0x02
+#define EEPROM_PG_EEDO          0x01
+#define EEPROM_WR_BUSY_RETRIES  100   // ready wait re-try count
+
+#define	EEPROM_MASK(_param0_,_param1_)            ((_param0_ & _param1_) ? EEPROM_PG_EEDI : 0 )
+
+
+#define EEPROM_WR_DATA(_addr_,_txdata_)           HAL_WRITE_UINT8(_addr_,_txdata_);
+
+#define EEPROM_WR_DATAPULSE(_addr_,_txdata_)      HAL_WRITE_UINT8(_addr_,_txdata_); \
+                                                  cyg_thread_delay(0); \
+                                                  HAL_WRITE_UINT8(_addr_,_txdata_ | EEPROM_PG_EESK);
+
+#define EEPROM_RD_DATA(_addr_,_txdata_,_rxdata_)  { \
+                                                  cyg_uint16  read_data; \
+                                                  HAL_WRITE_UINT8(_addr_,_txdata_); \
+                                                  cyg_thread_delay(1); \
+                                                  HAL_READ_UINT8(_addr_, read_data); \
+                                                  _rxdata_ <<= 1; \
+                                                  _rxdata_ |= ((read_data & EEPROM_PG_EEDO) ? 0x0001 : 0x0000 ); \
+                                                  HAL_WRITE_UINT8(_addr_,_txdata_ | EEPROM_PG_EESK); }
+#endif
+
 /*
  * Define inline functions to access the card. This will also handle
  * endianess issues in one place. This code was lifted from the eCos
@@ -778,6 +812,11 @@
   int i;
   Rltk8139_t *rltk8139_info;
 
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+  cyg_uint16 WrData, RdData;
+  cyg_uint8  *pSrcData;
+  int iRetry;
+#endif
 
 #ifdef DEBUG_RLTK8139_DRIVER
   diag_printf("rltk8139_control(%08x, %lx)\n", sc, key);
@@ -796,6 +835,26 @@
       rltk8139_info->mac[i] = *(((cyg_uint8 *)data) + i);
       OUTB(rltk8139_info->mac[i], rltk8139_info->base_address + IDR0 + i);
     }
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+    pSrcData = (cyg_uint8 *)data;
+    for(i = 0; i < 3; i++){
+      WrData  = ((cyg_uint16)(*pSrcData++)) & 0xff;
+      WrData |=  ((cyg_uint16)(*pSrcData++)) << 8;
+      for( iRetry = 0; iRetry < 3; iRetry++){
+        rltk8139_eeprom_write(
+                         (char *)(rltk8139_info->base_address + CR9346),
+                                           EEPROM_CMD_WRITE, i + 7, WrData);
+        RdData = rltk8139_eeprom_read(
+                         (char *)(rltk8139_info->base_address + CR9346),
+                                           EEPROM_CMD_READ, i + 7);
+        if( RdData == WrData ){
+          break;
+        }
+      }
+    }
+#endif
+
     return 0;
 #endif
 
@@ -1332,3 +1391,137 @@
   }
 }
 #endif
+
+
+#ifdef CYGPKG_DEVS_ETH_RLTK_8139_WRITE_EEPROM
+/*
+ * Read mac_address from EEPROM.
+ */
+static cyg_uint16
+rltk8139_eeprom_read( char *rtl_addr, cyg_uint8 eeprom_cmd, cyg_uint8 eeprom_addr )
+{
+cyg_uint8   read_data;                   // read from eeprom bit data
+cyg_uint8   org_param;                   // original register parameter
+cyg_uint8   mask_bit8;                   // mask bit
+int         icount;                      // for loop counter
+
+    // get old parameter
+    HAL_READ_UINT8( rtl_addr, org_param );
+
+    // ready
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON );
+
+    // set command
+    mask_bit8 = 0x04;
+    for(icount = 0; icount < 3; icount++){
+        EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_cmd ));
+        mask_bit8 >>= 1;
+    }
+
+    // set address
+    mask_bit8 = 0x20;
+    for(icount = 0; icount < 6; icount++){
+        EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_addr ));
+        mask_bit8 >>= 1;
+    }
+
+    // read data
+    read_data = 0;
+    for(icount = 0; icount < 16; icount++){
+        EEPROM_RD_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS, read_data );
+    }
+
+    // close
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+    // put old parameter
+    HAL_WRITE_UINT8(rtl_addr, org_param);
+
+    return(read_data);
+}
+
+
+/*
+ * Write in mac_address at EEPROM.
+ */
+static void
+rltk8139_eeprom_write( char *rtl_addr, cyg_uint8 eeprom_cmd, cyg_uint8 eeprom_addr, cyg_uint16 src_data )
+{
+cyg_uint8   read_data;                   // read from eeprom bit data
+cyg_uint8   org_param;                   // original register parameter
+cyg_uint8   mask_bit8;                   // mask bit
+cyg_uint16  mask_bit16;                  // mask bit for write data
+int         icount;                      // for loop counter
+
+    // get old parameter
+    HAL_READ_UINT8( rtl_addr, org_param );
+
+    // ready
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EESK );
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+    // set EWEN (eeprom write enable)
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EEDI );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+    EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON );
+
+    // set command
+    mask_bit8 = 0x04;
+    for(icount = 0; icount < 3; icount++){
+        EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_cmd ));
+        mask_bit8 >>= 1;
+    }
+
+    // set address
+    mask_bit8 = 0x20;
+    for(icount = 0; icount < 6; icount++){
+        EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit8, eeprom_addr ));
+        mask_bit8 >>= 1;
+    }
+
+    // set data
+    mask_bit16 = 0x8000;
+    for(icount = 0; icount < 16; icount++){
+        EEPROM_WR_DATAPULSE( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_MASK( mask_bit16, src_data ));
+        mask_bit16 >>= 1;
+    }
+
+    // close
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EESK );
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON );
+
+    // write ready check
+    EEPROM_WR_DATA( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+
+    // wait busy disable
+    icount = 0;
+    while( 1 ){
+        cyg_thread_delay( 1 );
+        HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS | EEPROM_PG_EESK );
+        HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON | EEPROM_PG_EECS );
+        HAL_READ_UINT8( rtl_addr, read_data );
+        if(( read_data & EEPROM_PG_EEDO ) != 0 ){
+            break;
+        }
+        if( icount++ >= EEPROM_WR_BUSY_RETRIES ){
+            diag_printf("EEPROM write wait error adr=0x%02x data=0x%04x\n", eeprom_addr, src_data );
+            break;
+        }
+    }
+    HAL_WRITE_UINT8( rtl_addr, EEPROM_PG_ON );
+
+    // put old parameter
+    HAL_WRITE_UINT8( rtl_addr, org_param );
+}
+
+#endif

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]