made MAC configurable in ethernet peripheral
Stefan Schuermans

Stefan Schuermans commited on 2012-03-11 20:48:30
Showing 5 changed files, with 70 additions and 11 deletions.

... ...
@@ -7,6 +7,17 @@ static unsigned int eth_idx_hw;
7 7
 static unsigned int eth_rx_buf[2][256];
8 8
 static unsigned int *eth_rx_pos;
9 9
 
10
+/**
11
+ * @brief set MAC address
12
+ * @param[in] mac MAC address
13
+ */
14
+static void eth_mac_set(const unsigned char mac[6])
15
+{
16
+  unsigned int i;
17
+  for (i = 0; i < 6; ++i)
18
+    ((volatile unsigned char *)(eth_ptr + 12))[i] = mac[i];
19
+}
20
+
10 21
 /**
11 22
  * @brief provide new receive buffer
12 23
  * @param[in] ptr pointer to new receive buffer
... ...
@@ -31,6 +42,13 @@ static void * eth_rx_get_pos(void)
31 42
   return (void *)eth_ptr[0];
32 43
 }
33 44
 
45
+/** initialize MAC address */
46
+void eth_mac_init(void)
47
+{
48
+  static const unsigned char mac[6] = {0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
49
+  eth_mac_set(mac);
50
+}
51
+
34 52
 /** initialize receiver */
35 53
 void eth_rx_init(void)
36 54
 {
... ...
@@ -1,6 +1,9 @@
1 1
 #ifndef ETH_H
2 2
 #define ETH_H
3 3
 
4
+/** initialize MAC address */
5
+void eth_mac_init(void);
6
+
4 7
 /** initialize receiver */
5 8
 void eth_rx_init(void);
6 9
 
... ...
@@ -110,6 +110,7 @@ int main()
110 110
   leds_set_state(0x02);
111 111
 
112 112
 #ifdef CFG_ETH_RX
113
+  eth_mac_init();
113 114
   eth_rx_init();
114 115
 #endif
115 116
 
... ...
@@ -100,6 +100,10 @@ ARCHITECTURE a_io_eth OF e_io_eth IS
100 100
     SIGNAL r_tx_en:    std_logic                     := '0';
101 101
     SIGNAL n_tx_en:    std_logic;
102 102
 
103
+    -- MAC address register
104
+    SIGNAL r_mac: std_logic_vector(47 DOWNTO 0) := X"FFFFFFFFFFFF";
105
+    SIGNAL n_mac: std_logic_vector(47 DOWNTO 0);
106
+
103 107
     -- TX busmaster read state machine
104 108
     SIGNAL r_tx_pos:  std_logic_vector(31 DOWNTO 0) := X"00000000";
105 109
     SIGNAL n_tx_pos:  std_logic_vector(31 DOWNTO 0);
... ...
@@ -233,7 +237,7 @@ BEGIN
233 237
             i_data_en => s_rxif_data_en,
234 238
             i_done    => s_rxif_done,
235 239
             i_err     => s_rxif_err,
236
-            i_mac     => X"070605040302",
240
+            i_mac     => r_mac,
237 241
             o_data    => s_rxframe_data,
238 242
             o_data_en => s_rxframe_data_en,
239 243
             o_done    => s_rxframe_done,
... ...
@@ -391,6 +395,7 @@ BEGIN
391 395
             r_tx_start     <= X"00000000";
392 396
             r_tx_end       <= X"00000000";
393 397
             r_tx_en        <= '0';
398
+            r_mac          <= X"FFFFFFFFFFFF";
394 399
         ELSIF rising_edge(clk) THEN
395 400
             r_rx_start     <= n_rx_start;
396 401
             r_rx_cur       <= n_rx_cur;
... ...
@@ -402,12 +407,13 @@ BEGIN
402 407
             r_tx_start     <= n_tx_start;
403 408
             r_tx_end       <= n_tx_end;
404 409
             r_tx_en        <= n_tx_en;
410
+            r_mac          <= n_mac;
405 411
         END IF;
406 412
     END PROCESS p_reg_sync;
407 413
 
408 414
     -- register interface write
409 415
     p_write: PROCESS(r_rx_new_start, r_rx_new_end, r_rx_new_en, s_rx_new,
410
-                     r_tx_start, r_tx_end, r_tx_en, s_txframe_done,
416
+                     r_tx_start, r_tx_end, r_tx_en, s_txframe_done, r_mac,
411 417
                      i_addr, i_wr_data, i_wr_en)
412 418
     BEGIN
413 419
         n_rx_new_start <= r_rx_new_start;
... ...
@@ -416,6 +422,7 @@ BEGIN
416 422
         n_tx_start     <= r_tx_start;
417 423
         n_tx_end       <= r_tx_end;
418 424
         n_tx_en        <= r_tx_en;
425
+        n_mac          <= r_mac;
419 426
         s_txframe_en   <= '0';
420 427
         IF s_rx_new = '1' THEN
421 428
             n_rx_new_en <= '0'; -- new buffer has been overtaken, reset rx_new_en
... ...
@@ -423,28 +430,56 @@ BEGIN
423 430
         IF s_txframe_done = '1' THEN
424 431
             n_tx_en <= '0'; -- TX operation completed, reset tx_en
425 432
         END IF;
426
-        IF i_wr_en = "1111" THEN
427 433
         CASE i_addr IS
428
-                WHEN "0100" => n_rx_new_start <= i_wr_data;
429
-                WHEN "0101" => n_rx_new_end   <= i_wr_data;
430
-                WHEN "0110" => IF i_wr_data(0) = '1' THEN
434
+            WHEN "0100" =>
435
+                IF i_wr_en = "1111" THEN
436
+                    n_rx_new_start <= i_wr_data;
437
+                END IF;
438
+            WHEN "0101" =>
439
+                IF i_wr_en = "1111" THEN
440
+                    n_rx_new_end <= i_wr_data;
441
+                END IF;
442
+            WHEN "0110" =>
443
+                IF i_wr_en(0) = '1' AND i_wr_data(0) = '1' THEN
431 444
                     n_rx_new_en <= '1';
432 445
                 END IF;
433
-                WHEN "1000" => IF r_tx_en = '0' THEN
446
+            WHEN "1000" =>
447
+                IF i_wr_en = "1111" AND r_tx_en = '0' THEN
434 448
                     n_tx_start <= i_wr_data;
435 449
                 END IF;
436
-                WHEN "1001" => IF r_tx_en = '0' THEN
450
+            WHEN "1001" =>
451
+                IF i_wr_en = "1111" AND r_tx_en = '0' THEN
437 452
                     n_tx_end <= i_wr_data;
438 453
                 END IF;
439
-                WHEN "1010" => IF i_wr_data(0) = '1' THEN
454
+            WHEN "1010" =>
455
+                IF i_wr_en(0) = '1' AND i_wr_data(0) = '1' THEN
440 456
                     IF r_tx_en = '0' THEN
441 457
                         s_txframe_en <= '1';
442 458
                     END IF;
443 459
                     n_tx_en <= '1';
444 460
                 END IF;
461
+            WHEN "1100" =>
462
+                IF i_wr_en(0) = '1' THEN
463
+                    n_mac(7 DOWNTO 0) <= i_wr_data(7 DOWNTO 0);
464
+                END IF;
465
+                IF i_wr_en(1) = '1' THEN
466
+                    n_mac(15 DOWNTO 8) <= i_wr_data(15 DOWNTO 8);
467
+                END IF;
468
+                IF i_wr_en(2) = '1' THEN
469
+                    n_mac(23 DOWNTO 16) <= i_wr_data(23 DOWNTO 16);
470
+                END IF;
471
+                IF i_wr_en(3) = '1' THEN
472
+                    n_mac(31 DOWNTO 24) <= i_wr_data(31 DOWNTO 24);
473
+                END IF;
474
+            WHEN "1101" =>
475
+                IF i_wr_en(0) = '1' THEN
476
+                    n_mac(39 DOWNTO 32) <= i_wr_data(7 DOWNTO 0);
477
+                END IF;
478
+                IF i_wr_en(1) = '1' THEN
479
+                    n_mac(47 DOWNTO 40) <= i_wr_data(15 DOWNTO 8);
480
+                END IF;
445 481
             WHEN OTHERS => NULL;
446 482
         END CASE;
447
-        END IF;
448 483
     END PROCESS p_write;
449 484
 
450 485
     -- register interface read
... ...
@@ -465,6 +500,8 @@ BEGIN
465 500
                 WHEN "1000" => o_rd_data              <= r_tx_start;
466 501
                 WHEN "1001" => o_rd_data              <= r_tx_end;
467 502
                 WHEN "1010" => o_rd_data(0)           <= r_tx_en;
503
+                WHEN "1100" => o_rd_data              <= r_mac(31 DOWNTO 0);
504
+                WHEN "1101" => o_rd_data(15 DOWNTO 0) <= r_mac(47 DOWNTO 32);
468 505
                 WHEN OTHERS => NULL;
469 506
             END CASE;
470 507
         END IF;
... ...
@@ -407,7 +407,7 @@
407 407
     <property xil_pn:name="Shift Register Extraction" xil_pn:value="true" xil_pn:valueState="default"/>
408 408
     <property xil_pn:name="Show All Models" xil_pn:value="false" xil_pn:valueState="default"/>
409 409
     <property xil_pn:name="Simulation Model Target" xil_pn:value="VHDL" xil_pn:valueState="default"/>
410
-    <property xil_pn:name="Simulation Run Time ISim" xil_pn:value="1 ms" xil_pn:valueState="non-default"/>
410
+    <property xil_pn:name="Simulation Run Time ISim" xil_pn:value="2 ms" xil_pn:valueState="non-default"/>
411 411
     <property xil_pn:name="Simulation Run Time Map" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
412 412
     <property xil_pn:name="Simulation Run Time Par" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
413 413
     <property xil_pn:name="Simulation Run Time Translate" xil_pn:value="1000 ns" xil_pn:valueState="default"/>
414 414