fxmac_rs/
fxmac.rs

1//! Core FXMAC Ethernet controller functionality.
2//!
3//! This module provides the main data structures and functions for controlling
4//! the FXMAC Ethernet MAC controller.
5
6use core::sync::atomic::Ordering;
7
8use crate::fxmac_const::*;
9use crate::fxmac_dma::*;
10use crate::fxmac_intr::*;
11use crate::fxmac_phy::*;
12use crate::utils::*;
13use alloc::boxed::Box;
14
15/// Handler type for DMA send (TX) interrupts.
16pub const FXMAC_HANDLER_DMASEND: u32 = 1;
17/// Handler type for DMA receive (RX) interrupts.
18pub const FXMAC_HANDLER_DMARECV: u32 = 2;
19/// Handler type for error interrupts.
20pub const FXMAC_HANDLER_ERROR: u32 = 3;
21/// Handler type for link status change interrupts.
22pub const FXMAC_HANDLER_LINKCHANGE: u32 = 4;
23/// Handler type for TX descriptor queue restart.
24pub const FXMAC_HANDLER_RESTART: u32 = 5;
25
26/// Link status: down.
27pub const FXMAC_LINKDOWN: u32 = 0;
28/// Link status: up.
29pub const FXMAC_LINKUP: u32 = 1;
30/// Link status: negotiating.
31pub const FXMAC_NEGOTIATING: u32 = 2;
32
33/// FXMAC0 peripheral clock frequency in Hz.
34pub const FXMAC0_PCLK: u32 = 50000000;
35/// FXMAC0 hotplug IRQ number.
36pub const FXMAC0_HOTPLUG_IRQ_NUM: u32 = 53 + 30;
37/// Maximum number of hardware queues supported.
38pub const FXMAC_QUEUE_MAX_NUM: u32 = 4;
39
40/// Mask for upper 32 bits of 64-bit address.
41pub const ULONG64_HI_MASK: u64 = 0xFFFFFFFF00000000;
42/// Mask for lower 32 bits of 64-bit address.
43pub const ULONG64_LO_MASK: u64 = !ULONG64_HI_MASK;
44
45/// Component is initialized and ready.
46pub const FT_COMPONENT_IS_READY: u32 = 0x11111111;
47/// Component is started.
48pub const FT_COMPONENT_IS_STARTED: u32 = 0x22222222;
49
50/// Memory page size in bytes.
51pub const PAGE_SIZE: usize = 4096;
52/// Base address of FXMAC0 controller.
53pub(crate) const FXMAC_IOBASE: u64 = 0x3200c000;
54
55/// Main FXMAC Ethernet controller instance.
56///
57/// This structure holds all state information for an FXMAC controller instance,
58/// including configuration, DMA queues, and runtime status.
59///
60/// # Thread Safety
61///
62/// This structure implements `Send` and `Sync` for use across threads, but
63/// external synchronization is required for concurrent access to mutable state.
64///
65/// # Example
66///
67/// ```ignore
68/// let hwaddr: [u8; 6] = [0x55, 0x44, 0x33, 0x22, 0x11, 0x00];
69/// let fxmac: &'static mut FXmac = xmac_init(&hwaddr);
70///
71/// // Check link status
72/// if fxmac.link_status == FXMAC_LINKUP {
73///     println!("Network link is up!");
74/// }
75/// ```
76pub struct FXmac {
77    /// Hardware configuration settings.
78    pub config: FXmacConfig,
79    /// Device initialization state (FT_COMPONENT_IS_READY when initialized).
80    pub is_ready: u32,
81    /// Device running state (FT_COMPONENT_IS_STARTED when active).
82    pub is_started: u32,
83    /// Current link status (FXMAC_LINKUP, FXMAC_LINKDOWN, or FXMAC_NEGOTIATING).
84    pub link_status: u32,
85    /// Currently enabled MAC options.
86    pub options: u32,
87    /// Interrupt mask for enabled interrupts.
88    pub mask: u32,
89    /// Capability mask bits.
90    pub caps: u32,
91    /// Network buffer management (lwIP port compatibility).
92    pub lwipport: FXmacLwipPort,
93    /// Transmit buffer descriptor queue.
94    pub tx_bd_queue: FXmacQueue,
95    /// Receive buffer descriptor queue.
96    pub rx_bd_queue: FXmacQueue,
97    /// Hardware module identification number.
98    pub moudle_id: u32,
99    /// Maximum transmission unit size.
100    pub max_mtu_size: u32,
101    /// Maximum frame size including headers.
102    pub max_frame_size: u32,
103    /// PHY address on the MDIO bus.
104    pub phy_address: u32,
105    /// Receive buffer mask for speed settings.
106    pub rxbuf_mask: u32,
107}
108
109// SAFETY: FXmac can be sent between threads as long as proper synchronization
110// is used for concurrent access.
111unsafe impl Send for FXmac {}
112// SAFETY: FXmac can be shared between threads with external synchronization.
113unsafe impl Sync for FXmac {}
114
115/// Hardware configuration for the FXMAC controller.
116///
117/// This structure contains all hardware-level configuration parameters
118/// required to initialize and operate the FXMAC Ethernet controller.
119pub struct FXmacConfig {
120    /// Instance identifier for multi-controller setups.
121    pub instance_id: u32,
122    /// Base address of the MAC controller registers.
123    pub base_address: u64,
124    /// Base address for extended mode configuration.
125    pub extral_mode_base: u64,
126    /// Base address for loopback configuration.
127    pub extral_loopback_base: u64,
128    /// PHY interface type (SGMII, RGMII, etc.).
129    pub interface: FXmacPhyInterface,
130    /// Link speed in Mbps (10, 100, 1000, etc.).
131    pub speed: u32,
132    /// Duplex mode: 1 for full-duplex, 0 for half-duplex.
133    pub duplex: u32,
134    /// Auto-negotiation enable: 1 to enable, 0 to disable.
135    pub auto_neg: u32,
136    /// Peripheral clock frequency in Hz.
137    pub pclk_hz: u32,
138    /// Maximum number of hardware queues.
139    pub max_queue_num: u32,
140    /// TX queue index (0 to FXMAC_QUEUE_MAX_NUM-1).
141    pub tx_queue_id: u32,
142    /// RX queue index (0 to FXMAC_QUEUE_MAX_NUM-1).
143    pub rx_queue_id: u32,
144    /// Hotplug IRQ number.
145    pub hotplug_irq_num: u32,
146    /// DMA burst length setting.
147    pub dma_brust_length: u32,
148    /// Default network configuration options.
149    pub network_default_config: u32,
150    /// IRQ numbers for each hardware queue.
151    pub queue_irq_num: [u32; FXMAC_QUEUE_MAX_NUM as usize],
152    /// Capability flags (e.g., tail pointer support).
153    pub caps: u32,
154    /// MAC address (6 bytes).
155    pub mac: [u8; 6],
156}
157
158/// Hardware queue structure for TX/RX operations.
159pub struct FXmacQueue {
160    /// Queue identifier.
161    pub queue_id: u32,
162    /// Buffer descriptor ring for this queue.
163    pub bdring: FXmacBdRing,
164}
165
166/// PHY interface mode definitions.
167///
168/// Specifies the physical layer interface type used for communication
169/// between the MAC controller and the PHY chip.
170#[derive(Debug, Clone, Copy, PartialEq)]
171pub enum FXmacPhyInterface {
172    /// SGMII (Serial Gigabit Media Independent Interface).
173    FXMAC_PHY_INTERFACE_MODE_SGMII = 0,
174    /// RMII (Reduced Media Independent Interface).
175    FXMAC_PHY_INTERFACE_MODE_RMII = 1,
176    /// RGMII (Reduced Gigabit Media Independent Interface).
177    FXMAC_PHY_INTERFACE_MODE_RGMII = 2,
178    /// XGMII (10 Gigabit Media Independent Interface).
179    FXMAC_PHY_INTERFACE_MODE_XGMII = 3,
180    /// USXGMII (Universal Serial 10 Gigabit Media Independent Interface).
181    FXMAC_PHY_INTERFACE_MODE_USXGMII = 4,
182    /// 5GBASE-R interface mode.
183    FXMAC_PHY_INTERFACE_MODE_5GBASER = 5,
184    /// 2500BASE-X interface mode.
185    FXMAC_PHY_INTERFACE_MODE_2500BASEX = 6,
186}
187
188/// Reads a memory-mapped register via a physical address.
189///
190/// The address is translated using the platform's [`KernelFunc::phys_to_virt`]
191/// implementation before a volatile read is performed.
192pub fn read_reg<T>(src: *const T) -> T {
193    unsafe {
194        core::ptr::read_volatile(
195            crate_interface::call_interface!(crate::KernelFunc::phys_to_virt(src as usize))
196                as *const T,
197        )
198    }
199}
200
201/// Writes a value to a memory-mapped register via a physical address.
202///
203/// The address is translated using the platform's [`KernelFunc::phys_to_virt`]
204/// implementation before a volatile write is performed.
205pub fn write_reg<T>(dst: *mut T, value: T) {
206    unsafe {
207        core::ptr::write_volatile(
208            crate_interface::call_interface!(crate::KernelFunc::phys_to_virt(dst as usize))
209                as *mut T,
210            value,
211        );
212    }
213}
214
215/// Initializes the FXMAC Ethernet controller.
216///
217/// This function performs complete hardware initialization of the FXMAC controller,
218/// including:
219/// - Hardware reset and configuration
220/// - PHY initialization and link establishment
221/// - DMA buffer descriptor ring setup
222/// - Interrupt handler registration
223/// - MAC address configuration
224///
225/// # Arguments
226///
227/// * `hwaddr` - A 6-byte MAC address to assign to the controller.
228///
229/// # Returns
230///
231/// A static mutable reference to the initialized [`FXmac`] instance.
232///
233/// # Panics
234///
235/// This function may panic if:
236/// - PHY initialization fails
237/// - DMA memory allocation fails
238///
239/// # Example
240///
241/// ```ignore
242/// // Define the MAC address
243/// let hwaddr: [u8; 6] = [0x55, 0x44, 0x33, 0x22, 0x11, 0x00];
244///
245/// // Initialize the controller
246/// let fxmac = xmac_init(&hwaddr);
247///
248/// // The controller is now ready for packet transmission and reception
249/// assert_eq!(fxmac.is_started, FT_COMPONENT_IS_STARTED);
250/// ```
251///
252/// # Note
253///
254/// The returned reference has `'static` lifetime and is stored in a global
255/// atomic pointer. Only one instance should be active at a time.
256pub fn xmac_init(hwaddr: &[u8; 6]) -> &'static mut FXmac {
257    /*
258    FXmacConfig mac_config:
259    mac_config.instance_id=0,
260    mac_config.base_address=0x3200c000,
261    mac_config.extral_mode_base=0x3200dc00,
262    mac_config.extral_loopback_base=0x3200dc04,
263    mac_config.interface=0,
264    mac_config.speed=100,
265    mac_config.duplex=1,
266    mac_config.auto_neg=0,
267    mac_config.pclk_hz=50000000,
268    mac_config.max_queue_num=4,
269    mac_config.tx_queue_id=0,
270    mac_config.rx_queue_id=0
271    mac_config.hotplug_irq_num=83,
272    mac_config.dma_brust_length=16,
273    mac_config.network_default_config=0x37f0,
274    mac_config.queue_irq_num[0]=87,
275    mac_config.caps=0
276    */
277    let mut mac_config: FXmacConfig = FXmacConfig {
278        instance_id: FXMAC0_ID,
279        base_address: FXMAC0_BASE_ADDR as u64,
280        extral_mode_base: FXMAC0_MODE_SEL_BASE_ADDR as u64,
281        extral_loopback_base: FXMAC0_LOOPBACK_SEL_BASE_ADDR as u64,
282        interface: FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_SGMII,
283        speed: 100,
284        duplex: 1,
285        auto_neg: 0,
286        pclk_hz: FXMAC0_PCLK,
287        max_queue_num: 4, // .max_queue_num = 16
288        tx_queue_id: 0,
289        rx_queue_id: 0,
290        hotplug_irq_num: FXMAC0_HOTPLUG_IRQ_NUM,
291        dma_brust_length: 16,
292        network_default_config: FXMAC_DEFAULT_OPTIONS,
293        queue_irq_num: [
294            FXMAC0_QUEUE0_IRQ_NUM,
295            FXMAC0_QUEUE1_IRQ_NUM,
296            FXMAC0_QUEUE2_IRQ_NUM,
297            FXMAC0_QUEUE3_IRQ_NUM,
298        ],
299        caps: 0,
300        mac: *hwaddr,
301    };
302
303    let mut xmac = FXmac {
304        config: mac_config,
305        is_ready: FT_COMPONENT_IS_READY,
306        is_started: 0,
307        link_status: FXMAC_LINKDOWN,
308        options: 0,
309        mask: 0,
310        caps: 0,
311        lwipport: FXmacLwipPort {
312            buffer: FXmacNetifBuffer::default(),
313            feature: FXMAC_LWIP_PORT_CONFIG_MULTICAST_ADDRESS_FILITER,
314            hwaddr: *hwaddr,
315            recv_flg: 0,
316        },
317        tx_bd_queue: FXmacQueue {
318            queue_id: 0,
319            bdring: FXmacBdRing::default(),
320        },
321        rx_bd_queue: FXmacQueue {
322            queue_id: 0,
323            bdring: FXmacBdRing::default(),
324        },
325        moudle_id: 0,
326        max_mtu_size: 0,
327        max_frame_size: 0,
328        phy_address: 0,
329        rxbuf_mask: 0,
330    };
331
332    // xmac_config: interface=FXMAC_PHY_INTERFACE_MODE_SGMII, autonegotiation=0, phy_speed=FXMAC_PHY_SPEED_100M, phy_duplex=FXMAC_PHY_FULL_DUPLEX
333    // FXmacDmaReset, moudle_id=12, max_frame_size=1518, max_queue_num=4 (或16), dma_brust_length=16
334    // network_default_config = 0x37f0, base_address=0x3200c000,FXMAC_RXBUF_HASH_MASK: GENMASK(30, 29)= 0x60000000 (0b 0110_0000_0000_0000_0000000000000000)
335
336    // mii_interface = 1 = FXMAC_LWIP_PORT_INTERFACE_SGMII;
337
338    // FXmacLwipPortInit():
339    /* step 1: initialize instance */
340    /* step 2: depend on config set some options : JUMBO / IGMP */
341    /* step 3: FXmacSelectClk */
342    /* step 4: FXmacInitInterface */
343    /* step 5: initialize phy */
344    /* step 6: initialize dma */
345    /* step 7: initialize interrupt */
346    /* step 8: start mac */
347
348    let mut status: u32 = 0;
349
350    // Reset the hardware and set default options
351    //xmac.link_status = FXMAC_LINKDOWN;
352    //xmac.is_ready = FT_COMPONENT_IS_READY;
353
354    FXmacReset(&mut xmac);
355
356    // irq_handler = (FXmacIrqHandler)FXmacIrqStubHandler;
357    // interrupts bit mask
358    xmac.mask = FXMAC_IXR_LINKCHANGE_MASK
359        | FXMAC_IXR_TX_ERR_MASK
360        | FXMAC_IXR_RX_ERR_MASK
361        | FXMAC_IXR_RXCOMPL_MASK; // FXMAC_INTR_MASK // 这里打开收包中断,关闭发包中断
362
363    if (xmac.config.caps & FXMAC_CAPS_TAILPTR) != 0 {
364        FXmacSetOptions(&mut xmac, FXMAC_TAIL_PTR_OPTION, 0);
365        xmac.mask &= !FXMAC_IXR_TXUSED_MASK;
366    }
367
368    // xmac.lwipport.feature = LWIP_PORT_MODE_MULTICAST_ADDRESS_FILITER;
369    FxmacFeatureSetOptions(xmac.lwipport.feature, &mut xmac);
370
371    status = FXmacSetMacAddress(&xmac.lwipport.hwaddr, 0);
372
373    //mac_config.interface = FXMAC_PHY_INTERFACE_MODE_SGMII;
374
375    if xmac.config.interface != FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_USXGMII {
376        /* initialize phy */
377        status = FXmacPhyInit(&mut xmac, XMAC_PHY_RESET_ENABLE);
378        if status != 0 {
379            warn!("FXmacPhyInit is error");
380        }
381    } else {
382        info!("interface == FXMAC_PHY_INTERFACE_MODE_USXGMII");
383    }
384
385    FXmacSelectClk(&mut xmac);
386    FXmacInitInterface(&mut xmac);
387
388    // initialize dma
389    let mut dmacrreg: u32 = read_reg((xmac.config.base_address + FXMAC_DMACR_OFFSET) as *const u32);
390    dmacrreg &= !(FXMAC_DMACR_BLENGTH_MASK);
391    dmacrreg |= FXMAC_DMACR_INCR16_AHB_AXI_BURST; /* Attempt to use bursts of up to 16. */
392    write_reg(
393        (xmac.config.base_address + FXMAC_DMACR_OFFSET) as *mut u32,
394        dmacrreg,
395    );
396
397    FXmacInitDma(&mut xmac);
398
399    // initialize interrupt
400    // 网卡中断初始化设置
401    FXmacSetupIsr(&mut xmac);
402
403    // end of FXmacLwipPortInit()
404
405    if (xmac.lwipport.feature & FXMAC_LWIP_PORT_CONFIG_UNICAST_ADDRESS_FILITER) != 0 {
406        debug!("Set unicast hash table");
407        FXmac_SetHash(&mut xmac, hwaddr);
408    }
409
410    /* 注册了 lwip_port->ops:
411    ethernetif_link_detect()
412    ethernetif_input()
413    ethernetif_deinit()
414    ethernetif_start() -> FXmacLwipPortStart() -> FXmacStart()
415    ethernetif_debug()
416    */
417
418    // ethernetif_start()
419    // start mac
420    FXmacStart(&mut xmac);
421
422    // 开始发包的函数:FXmacLwipPortTx()->FXmacSgsend() -> FXmacSendHandler() -> FXmacProcessSentBds()
423    // 触发中断函数:FXmacIntrHandler()
424    // 收包handle: FXmacRecvIsrHandler()->FXmacRecvHandler
425
426    //XMAC.store(Box::into_raw(Box::new(xmac)), Ordering::Relaxed);
427
428    // Box::leak方法,它可以将一个变量从内存中泄漏, 将其变为'static生命周期,因此可以赋值给全局静态变量
429    let xmac_ref = Box::leak(Box::new(xmac));
430    XMAC.store(xmac_ref as *mut FXmac, Ordering::Relaxed);
431
432    xmac_ref
433}
434
435/// Starts the Ethernet controller.
436///
437/// This enables TX/RX paths based on configured options, starts DMA channels,
438/// and enables the device interrupt mask.
439///
440/// # Panics
441///
442/// Panics if the instance is not in the ready state.
443pub fn FXmacStart(instance_p: &mut FXmac) {
444    assert!(instance_p.is_ready == FT_COMPONENT_IS_READY);
445
446    /* clear any existed int status */
447    write_reg(
448        (instance_p.config.base_address + FXMAC_ISR_OFFSET) as *mut u32,
449        FXMAC_IXR_ALL_MASK,
450    );
451
452    /* Enable transmitter if not already enabled */
453    if (instance_p.config.network_default_config & FXMAC_TRANSMITTER_ENABLE_OPTION) != 0 {
454        let reg_val =
455            read_reg((instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *const u32);
456        if (reg_val & FXMAC_NWCTRL_TXEN_MASK) == 0 {
457            write_reg(
458                (instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *mut u32,
459                reg_val | FXMAC_NWCTRL_TXEN_MASK,
460            );
461        }
462    }
463
464    /* Enable receiver if not already enabled */
465    if (instance_p.config.network_default_config & FXMAC_RECEIVER_ENABLE_OPTION) != 0 {
466        let reg_val =
467            read_reg((instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *const u32);
468        info!("Enable receiver, FXMAC_NWCTRL_OFFSET = {:#x}", reg_val);
469        if (reg_val & FXMAC_NWCTRL_RXEN_MASK) == 0 {
470            write_reg(
471                (instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *mut u32,
472                reg_val | FXMAC_NWCTRL_RXEN_MASK,
473            );
474        }
475    }
476    info!(
477        "FXMAC_NWCTRL_OFFSET = {:#x}",
478        read_reg((instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *const u32)
479    );
480
481    info!("Enable TX and RX by Mask={:#x}", instance_p.mask);
482
483    // 使能网卡中断: Enable TX and RX interrupt
484    //FXMAC_INT_ENABLE(instance_p, instance_p->mask);
485    // Enable interrupts specified in 'Mask'. The corresponding interrupt for each bit set to 1 in 'Mask', will be enabled.
486    write_reg(
487        (instance_p.config.base_address + FXMAC_IER_OFFSET) as *mut u32,
488        instance_p.mask & FXMAC_IXR_ALL_MASK,
489    );
490
491    // Mark as started
492    instance_p.is_started = FT_COMPONENT_IS_STARTED;
493}
494
495/// Gracefully stops the Ethernet MAC.
496///
497/// This disables interrupts, stops DMA channels, and shuts down TX/RX paths.
498///
499/// # Panics
500///
501/// Panics if the instance is not in the ready state.
502pub fn FXmacStop(instance_p: &mut FXmac) {
503    assert!(instance_p.is_ready == FT_COMPONENT_IS_READY);
504    // Disable all interrupts
505    write_reg(
506        (instance_p.config.base_address + FXMAC_IDR_OFFSET) as *mut u32,
507        FXMAC_IXR_ALL_MASK,
508    );
509
510    /* Disable the receiver & transmitter */
511    let mut reg_val: u32 =
512        read_reg((instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *const u32);
513    reg_val &= !FXMAC_NWCTRL_RXEN_MASK;
514    reg_val &= !FXMAC_NWCTRL_TXEN_MASK;
515    write_reg(
516        (instance_p.config.base_address + FXMAC_NWCTRL_OFFSET) as *mut u32,
517        reg_val,
518    );
519
520    // Mark as stopped
521    instance_p.is_started = 0;
522}
523
524/*
525 * Perform a graceful reset of the Ethernet MAC. Resets the DMA channels, the
526 * transmitter, and the receiver.
527 *
528 * Steps to reset
529 * - Stops transmit and receive channels
530 * - Stops DMA
531 * - Configure transmit and receive buffer size to default
532 * - Clear transmit and receive status register and counters
533 * - Clear all interrupt sources
534 * - Clear phy (if there is any previously detected) address
535 * - Clear MAC addresses (1-4) as well as Type IDs and hash value
536 *
537 */
538
539fn FXmacReset(instance_p: &mut FXmac) {
540    let mut mac_addr: [u8; 6] = [0; 6];
541
542    /* Stop the device and reset hardware */
543    FXmacStop(instance_p);
544
545    // Module identification number
546    // instance_p->moudle_id = 12
547    instance_p.moudle_id = (read_reg((FXMAC_IOBASE + FXMAC_REVISION_REG_OFFSET) as *const u32)
548        & FXMAC_IDENTIFICATION_MASK)
549        >> 16;
550    info!(
551        "FXmacReset, Got Moudle IDENTIFICATION: {}",
552        instance_p.moudle_id
553    );
554
555    instance_p.max_mtu_size = FXMAC_MTU;
556    instance_p.max_frame_size = FXMAC_MAX_FRAME_SIZE;
557    instance_p.config.max_queue_num = 16;
558    instance_p.config.dma_brust_length = 16;
559    instance_p.config.network_default_config = FXMAC_DEFAULT_OPTIONS;
560
561    instance_p.config.pclk_hz = FXMAC0_PCLK; // 50000000
562
563    let netctrl =
564        (FXMAC_NWCTRL_STATCLR_MASK & !FXMAC_NWCTRL_LOOPBACK_LOCAL_MASK) | FXMAC_NWCTRL_MDEN_MASK;
565    write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, netctrl);
566
567    FXmacConfigureCaps(instance_p);
568
569    // mdio clock division
570    let mut w_reg: u32 = FXmacClkDivGet(instance_p);
571    // DMA bus width, DMA位宽为128
572    w_reg |= FXmacDmaWidth(instance_p.moudle_id);
573    write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, w_reg);
574
575    FXmacDmaReset(instance_p);
576
577    // This register, when read provides details of the status of the receive path.
578    write_reg(
579        (FXMAC_IOBASE + FXMAC_RXSR_OFFSET) as *mut u32,
580        FXMAC_SR_ALL_MASK,
581    );
582
583    // write 1 ro the relavant bit location disable that particular interrupt
584    write_reg(
585        (FXMAC_IOBASE + FXMAC_IDR_OFFSET) as *mut u32,
586        FXMAC_IXR_ALL_MASK,
587    );
588
589    let reg_val: u32 = read_reg((FXMAC_IOBASE + FXMAC_ISR_OFFSET) as *const u32);
590    write_reg((FXMAC_IOBASE + FXMAC_ISR_OFFSET) as *mut u32, reg_val);
591
592    write_reg(
593        (FXMAC_IOBASE + FXMAC_TXSR_OFFSET) as *mut u32,
594        FXMAC_SR_ALL_MASK,
595    );
596
597    FXmacClearHash();
598
599    // set default mac address
600    for i in 0..4 {
601        FXmacSetMacAddress(&mac_addr, i);
602        FXmacGetMacAddress(&mut mac_addr, i);
603        FXmacSetTypeIdCheck(0, i);
604    }
605
606    /* clear all counters */
607    for i in 0..((FXMAC_LAST_OFFSET - FXMAC_OCTTXL_OFFSET) / 4) {
608        read_reg((FXMAC_IOBASE + FXMAC_OCTTXL_OFFSET + (i * 4)) as *mut u32);
609    }
610
611    /* Sync default options with hardware but leave receiver and
612     * transmitter disabled. They get enabled with FXmacStart() if
613     * FXMAC_TRANSMITTER_ENABLE_OPTION and FXMAC_RECEIVER_ENABLE_OPTION are set.
614     */
615    let options = instance_p.config.network_default_config
616        & !(FXMAC_TRANSMITTER_ENABLE_OPTION | FXMAC_RECEIVER_ENABLE_OPTION);
617    FXmacSetOptions(instance_p, options, 0);
618    let options = !instance_p.config.network_default_config;
619    FXmacClearOptions(instance_p, options, 0);
620}
621
622fn FXmacDmaReset(instance_p: &mut FXmac) {
623    let max_frame_size: u32 = instance_p.max_frame_size;
624
625    let mut dmacfg: u32 = 0;
626    //let max_queue_num = 16;
627    //let dma_brust_length = 16;
628
629    let mut rx_buf_size: u32 = max_frame_size / FXMAC_RX_BUF_UNIT;
630    rx_buf_size += if (max_frame_size % FXMAC_RX_BUF_UNIT) != 0 {
631        1
632    } else {
633        0
634    }; /* roundup */
635
636    // moudle_id=12
637    if (instance_p.moudle_id >= 2) {
638        for queue in 0..instance_p.config.max_queue_num {
639            dmacfg = 0;
640
641            // 设置发包/收包 buffer队列的基地址
642            FXmacSetQueuePtr(0, queue as u8, FXMAC_SEND);
643            FXmacSetQueuePtr(0, queue as u8, FXMAC_RECV);
644
645            if queue != 0 {
646                write_reg(
647                    (FXMAC_IOBASE + FXMAC_RXBUFQX_SIZE_OFFSET(queue as u64)) as *mut u32,
648                    rx_buf_size,
649                );
650            } else
651            /* queue is 0 */
652            {
653                dmacfg |= (FXMAC_DMACR_RXBUF_MASK & (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT));
654            }
655        }
656
657        dmacfg |= (instance_p.config.dma_brust_length & FXMAC_DMACR_BLENGTH_MASK);
658
659        dmacfg &= !FXMAC_DMACR_ENDIAN_MASK;
660        dmacfg &= !FXMAC_DMACR_SWAP_MANAGEMENT_MASK; /* 选择小端 */
661
662        dmacfg &= !FXMAC_DMACR_TCPCKSUM_MASK; /* close  transmitter checksum generation engine */
663
664        dmacfg &= !FXMAC_DMACR_ADDR_WIDTH_64;
665        dmacfg |= FXMAC_DMACR_RXSIZE_MASK | FXMAC_DMACR_TXSIZE_MASK;
666        /*
667            set this bit can enable auto discard rx frame when lack of receive source,
668            which avoid endless rx buffer not available error intrrupts.
669        */
670        dmacfg |= FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK; /* force_discard_on_rx_err */
671
672        dmacfg |= FXMAC_DMACR_ADDR_WIDTH_64; // Just for aarch64
673    } else {
674        FXmacSetQueuePtr(0, 0, FXMAC_SEND);
675        FXmacSetQueuePtr(0, 0, FXMAC_RECV);
676        dmacfg |= (FXMAC_DMACR_RXBUF_MASK & (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT));
677        dmacfg |= (instance_p.config.dma_brust_length & FXMAC_DMACR_BLENGTH_MASK);
678
679        dmacfg &= !FXMAC_DMACR_ENDIAN_MASK;
680        dmacfg &= !FXMAC_DMACR_SWAP_MANAGEMENT_MASK; /* 选择小端 */
681
682        dmacfg &= !FXMAC_DMACR_TCPCKSUM_MASK; /* close  transmitter checksum generation engine */
683
684        dmacfg &= !FXMAC_DMACR_ADDR_WIDTH_64;
685        dmacfg |= FXMAC_DMACR_RXSIZE_MASK | FXMAC_DMACR_TXSIZE_MASK;
686        /*
687            set this bit can enable auto discard rx frame when lack of receive source,
688            which avoid endless rx buffer not available error intrrupts.
689        */
690        dmacfg |= FXMAC_DMACR_ORCE_DISCARD_ON_ERR_MASK; /* force_discard_on_rx_err */
691        dmacfg |= FXMAC_DMACR_ADDR_WIDTH_64; // Just for aarch64
692    }
693
694    write_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *mut u32, dmacfg);
695}
696
697fn FXmacDmaWidth(moudle_id: u32) -> u32 {
698    if moudle_id < 2 {
699        return FXMAC_NWCFG_BUS_WIDTH_32_MASK;
700    }
701
702    let read_regs = read_reg((FXMAC_IOBASE + FXMAC_DESIGNCFG_DEBUG1_OFFSET) as *const u32);
703    match ((read_regs & FXMAC_DESIGNCFG_DEBUG1_BUS_WIDTH_MASK) >> 25) {
704        4 => {
705            info!("bus width is 128");
706            FXMAC_NWCFG_BUS_WIDTH_128_MASK
707        }
708        2 => {
709            info!("bus width is 64");
710            FXMAC_NWCFG_BUS_WIDTH_64_MASK
711        }
712        _ => {
713            info!("bus width is 32");
714            FXMAC_NWCFG_BUS_WIDTH_32_MASK
715        }
716    }
717}
718
719fn FxmacFeatureSetOptions(feature: u32, xmac_p: &mut FXmac) {
720    let mut options: u32 = 0;
721
722    if (feature & FXMAC_LWIP_PORT_CONFIG_JUMBO) != 0 {
723        info!("FXMAC_JUMBO_ENABLE_OPTION is ok");
724        options |= FXMAC_JUMBO_ENABLE_OPTION;
725    }
726
727    if (feature & FXMAC_LWIP_PORT_CONFIG_UNICAST_ADDRESS_FILITER) != 0 {
728        info!("FXMAC_UNICAST_OPTION is ok");
729        options |= FXMAC_UNICAST_OPTION;
730    }
731
732    if (feature & FXMAC_LWIP_PORT_CONFIG_MULTICAST_ADDRESS_FILITER) != 0 {
733        info!("FXMAC_MULTICAST_OPTION is ok");
734        options |= FXMAC_MULTICAST_OPTION;
735    }
736    /* enable copy all frames */
737    if (feature & FXMAC_LWIP_PORT_CONFIG_COPY_ALL_FRAMES) != 0 {
738        info!("FXMAC_PROMISC_OPTION is ok");
739        options |= FXMAC_PROMISC_OPTION;
740    }
741    /* close fcs check */
742    if (feature & FXMAC_LWIP_PORT_CONFIG_CLOSE_FCS_CHECK) != 0 {
743        info!("FXMAC_FCS_STRIP_OPTION is ok");
744        options |= FXMAC_FCS_STRIP_OPTION;
745    }
746
747    FXmacSetOptions(xmac_p, options, 0);
748}
749
750/// Sets the start address of the transmit/receive buffer queue.
751///
752/// # Arguments
753///
754/// * `queue_p` - Physical base address of the queue ring.
755/// * `queue_num` - Queue index to configure.
756/// * `direction` - [`FXMAC_SEND`] or [`FXMAC_RECV`].
757///
758/// # Note
759///
760/// The buffer queue address must be configured before calling [`FXmacStart`].
761pub fn FXmacSetQueuePtr(queue_p: u64, queue_num: u8, direction: u32) {
762    //assert!(instance_p.is_ready == FT_COMPONENT_IS_READY);
763    // If already started, then just return
764
765    let flag_queue_p = if queue_p == 0 { 1 } else { 0 };
766    let FXMAC_QUEUE_REGISTER_OFFSET =
767        |base_addr: u64, queue_id: u64| (base_addr + (queue_id - 1) * 4);
768
769    if queue_num == 0 {
770        if direction == FXMAC_SEND {
771            /* set base start address of TX buffer queue (tx buffer descriptor list) */
772            write_reg(
773                (FXMAC_IOBASE + FXMAC_TXQBASE_OFFSET) as *mut u32,
774                ((queue_p & ULONG64_LO_MASK) | flag_queue_p) as u32,
775            );
776        } else {
777            /* set base start address of RX buffer queue (rx buffer descriptor list) */
778            write_reg(
779                (FXMAC_IOBASE + FXMAC_RXQBASE_OFFSET) as *mut u32,
780                ((queue_p & ULONG64_LO_MASK) | flag_queue_p) as u32,
781            );
782        }
783    } else if direction == FXMAC_SEND {
784        write_reg(
785            (FXMAC_IOBASE + FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_TXQ1BASE_OFFSET, queue_num as u64))
786                as *mut u32,
787            ((queue_p & ULONG64_LO_MASK) | flag_queue_p) as u32,
788        );
789    } else {
790        write_reg(
791            (FXMAC_IOBASE + FXMAC_QUEUE_REGISTER_OFFSET(FXMAC_RXQ1BASE_OFFSET, queue_num as u64))
792                as *mut u32,
793            ((queue_p & ULONG64_LO_MASK) | flag_queue_p) as u32,
794        );
795    }
796
797    if direction == FXMAC_SEND
798    // Only for aarch64
799    {
800        /* Set the MSB of TX Queue start address */
801        write_reg(
802            (FXMAC_IOBASE + FXMAC_MSBBUF_TXQBASE_OFFSET) as *mut u32,
803            ((queue_p & ULONG64_HI_MASK) >> 32) as u32,
804        );
805    } else {
806        /* Set the MSB of RX Queue start address */
807        write_reg(
808            (FXMAC_IOBASE + FXMAC_MSBBUF_RXQBASE_OFFSET) as *mut u32,
809            ((queue_p & ULONG64_HI_MASK) >> 32) as u32,
810        );
811    }
812}
813
814fn FXmacConfigureCaps(instance_p: &mut FXmac) {
815    instance_p.caps = 0;
816    let read_regs = read_reg((FXMAC_IOBASE + FXMAC_DESIGNCFG_DEBUG1_OFFSET) as *const u32);
817    if (read_regs & FXMAC_DESIGNCFG_DEBUG1_BUS_IRQCOR_MASK) == 0 {
818        instance_p.caps |= FXMAC_CAPS_ISR_CLEAR_ON_WRITE;
819        info!(
820            "Design ConfigReg1: {:#x} Has FXMAC_CAPS_ISR_CLEAR_ON_WRITE feature",
821            read_regs
822        );
823    }
824}
825
826fn FXmacClkDivGet(instance_p: &mut FXmac) -> u32 {
827    // moudle_id=12
828    // let pclk_hz = 50000000;
829    let pclk_hz = instance_p.config.pclk_hz; // FXMAC0_PCLK;
830
831    if (pclk_hz <= 20000000) {
832        FXMAC_NWCFG_CLOCK_DIV8_MASK
833    } else if (pclk_hz <= 40000000) {
834        FXMAC_NWCFG_CLOCK_DIV16_MASK
835    } else if (pclk_hz <= 80000000) {
836        FXMAC_NWCFG_CLOCK_DIV32_MASK
837    } else if (instance_p.moudle_id >= 2) {
838        if (pclk_hz <= 120000000) {
839            FXMAC_NWCFG_CLOCK_DIV48_MASK
840        } else if (pclk_hz <= 160000000) {
841            FXMAC_NWCFG_CLOCK_DIV64_MASK
842        } else if (pclk_hz <= 240000000) {
843            FXMAC_NWCFG_CLOCK_DIV96_MASK
844        } else if (pclk_hz <= 320000000) {
845            FXMAC_NWCFG_CLOCK_DIV128_MASK
846        } else {
847            FXMAC_NWCFG_CLOCK_DIV224_MASK
848        }
849    } else {
850        FXMAC_NWCFG_CLOCK_DIV64_MASK
851    }
852}
853
854/**
855 * Set options for the driver/device. The driver should be stopped with
856 * FXmacStop() before changing options.
857 */
858fn FXmacSetOptions(instance_p: &mut FXmac, options: u32, queue_num: u32) -> u32 {
859    let mut reg: u32 = 0; /* Generic register contents */
860    let mut reg_netcfg: u32 = 0; /* Reflects original contents of NET_CONFIG */
861    let mut reg_new_netcfg: u32 = 0; /* Reflects new contents of NET_CONFIG */
862    let mut status: u32 = 0;
863
864    //let is_started = 0;
865
866    info!(
867        "FXmacSetOptions, is_started={}, options={}, queue_num={}, max_queue_num={}",
868        instance_p.is_started, options, queue_num, instance_p.config.max_queue_num
869    );
870
871    /* Be sure device has been stopped */
872    if instance_p.is_started == FT_COMPONENT_IS_STARTED {
873        status = 9; //FXMAC_ERR_MAC_IS_PROCESSING;
874        error!("FXMAC is processing when calling FXmacSetOptions function");
875    } else {
876        /* Many of these options will change the NET_CONFIG registers.
877         * To reduce the amount of IO to the device, group these options here
878         * and change them all at once.
879         */
880
881        /* Grab current register contents */
882        reg_netcfg = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
883
884        reg_new_netcfg = reg_netcfg;
885
886        /*
887         * It is configured to max 1536.
888         */
889        if (options & FXMAC_FRAME1536_OPTION) != 0 {
890            reg_new_netcfg |= FXMAC_NWCFG_1536RXEN_MASK;
891        }
892
893        /* Turn on VLAN packet only, only VLAN tagged will be accepted */
894        if (options & FXMAC_VLAN_OPTION) != 0 {
895            reg_new_netcfg |= FXMAC_NWCFG_NVLANDISC_MASK;
896        }
897
898        /* Turn on FCS stripping on receive packets */
899        if (options & FXMAC_FCS_STRIP_OPTION) != 0 {
900            reg_new_netcfg |= FXMAC_NWCFG_FCS_REMOVE_MASK;
901        }
902
903        /* Turn on length/type field checking on receive packets */
904        if (options & FXMAC_LENTYPE_ERR_OPTION) != 0 {
905            reg_new_netcfg |= FXMAC_NWCFG_LENGTH_FIELD_ERROR_FRAME_DISCARD_MASK;
906        }
907
908        /* Turn on flow control */
909        if (options & FXMAC_FLOW_CONTROL_OPTION) != 0 {
910            reg_new_netcfg |= FXMAC_NWCFG_PAUSE_ENABLE_MASK;
911        }
912
913        /* Turn on promiscuous frame filtering (all frames are received) */
914        if (options & FXMAC_PROMISC_OPTION) != 0 {
915            reg_new_netcfg |= FXMAC_NWCFG_COPYALLEN_MASK;
916        }
917
918        /* Allow broadcast address reception */
919        if (options & FXMAC_BROADCAST_OPTION) != 0 {
920            reg_new_netcfg &= !FXMAC_NWCFG_BCASTDI_MASK;
921        }
922
923        /* Allow multicast address filtering */
924        if (options & FXMAC_MULTICAST_OPTION) != 0 {
925            reg_new_netcfg |= FXMAC_NWCFG_MCASTHASHEN_MASK;
926        }
927
928        if (options & FXMAC_UNICAST_OPTION) != 0 {
929            reg_new_netcfg |= FXMAC_NWCFG_UCASTHASHEN_MASK;
930        }
931
932        if (options & FXMAC_TAIL_PTR_OPTION) != 0 {
933            write_reg((FXMAC_IOBASE + FXMAC_TAIL_ENABLE) as *mut u32, 0x80000001);
934        }
935
936        /* enable RX checksum offload */
937        if (options & FXMAC_RX_CHKSUM_ENABLE_OPTION) != 0 {
938            reg_new_netcfg |= FXMAC_NWCFG_RXCHKSUMEN_MASK;
939        }
940
941        /* Enable jumbo frames */
942        if (options & FXMAC_JUMBO_ENABLE_OPTION) != 0 {
943            instance_p.max_mtu_size = FXMAC_MTU_JUMBO;
944            instance_p.max_frame_size = FXMAC_MAX_FRAME_SIZE_JUMBO;
945
946            reg_new_netcfg |= FXMAC_NWCFG_JUMBO_MASK;
947
948            write_reg(
949                (FXMAC_IOBASE + FXMAC_JUMBOMAXLEN_OFFSET) as *mut u32,
950                FXMAC_MAX_FRAME_SIZE_JUMBO,
951            );
952
953            write_reg(
954                (FXMAC_IOBASE + FXMAC_TXQSEGALLOC_QLOWER_OFFSET) as *mut u32,
955                FXMAC_TXQSEGALLOC_QLOWER_JUMBO_MASK,
956            );
957
958            if queue_num == 0 {
959                let mut rx_buf_size: u32 = 0;
960                reg = read_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *const u32);
961
962                reg &= !FXMAC_DMACR_RXBUF_MASK;
963
964                rx_buf_size = instance_p.max_frame_size / FXMAC_RX_BUF_UNIT;
965                rx_buf_size += if (instance_p.max_frame_size % FXMAC_RX_BUF_UNIT) != 0 {
966                    1
967                } else {
968                    0
969                };
970
971                reg |= (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT) & FXMAC_DMACR_RXBUF_MASK;
972                write_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *mut u32, reg);
973            } else if queue_num < instance_p.config.max_queue_num {
974                let mut rx_buf_size: u32 = 0;
975                rx_buf_size = instance_p.max_frame_size / FXMAC_RX_BUF_UNIT;
976                rx_buf_size += if (instance_p.max_frame_size % FXMAC_RX_BUF_UNIT) != 0 {
977                    1
978                } else {
979                    0
980                };
981
982                write_reg(
983                    (FXMAC_IOBASE + FXMAC_RXBUFQX_SIZE_OFFSET(queue_num as u64)) as *mut u32,
984                    rx_buf_size & FXMAC_RXBUFQX_SIZE_MASK,
985                );
986            }
987        }
988
989        if (options & FXMAC_SGMII_ENABLE_OPTION) != 0 {
990            reg_new_netcfg |= (FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK | FXMAC_NWCFG_PCSSEL_MASK);
991        }
992
993        if (options & FXMAC_LOOPBACK_NO_MII_OPTION) != 0 {
994            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
995            reg |= FXMAC_NWCTRL_LOOPBACK_LOCAL_MASK;
996            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
997        }
998
999        if (options & FXMAC_LOOPBACK_USXGMII_OPTION) != 0 {
1000            write_reg((FXMAC_IOBASE + FXMAC_TEST_CONTROL_OFFSET) as *mut u32, 2);
1001        }
1002
1003        /* Officially change the NET_CONFIG registers if it needs to be
1004         * modified.
1005         */
1006        if (reg_netcfg != reg_new_netcfg) {
1007            write_reg(
1008                (FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32,
1009                reg_new_netcfg,
1010            );
1011        }
1012
1013        /* Enable TX checksum offload */
1014        if (options & FXMAC_TX_CHKSUM_ENABLE_OPTION) != 0 {
1015            reg = read_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *const u32);
1016            reg |= FXMAC_DMACR_TCPCKSUM_MASK;
1017            write_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *mut u32, reg);
1018        }
1019
1020        /* Enable transmitter */
1021        if (options & FXMAC_TRANSMITTER_ENABLE_OPTION) != 0 {
1022            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1023            reg |= FXMAC_NWCTRL_TXEN_MASK;
1024            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
1025        }
1026
1027        /* Enable receiver */
1028        if (options & FXMAC_RECEIVER_ENABLE_OPTION) != 0 {
1029            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1030            reg |= FXMAC_NWCTRL_RXEN_MASK;
1031
1032            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
1033        }
1034
1035        /* The remaining options not handled here are managed elsewhere in the
1036         * driver. No register modifications are needed at this time. Reflecting
1037         * the option in instance_p->options is good enough for now.
1038         */
1039
1040        /* Set options word to its new value */
1041        instance_p.options |= options;
1042
1043        status = 0; // FT_SUCCESS;
1044    }
1045
1046    status
1047}
1048
1049/// Clear options for the driver/device
1050fn FXmacClearOptions(instance_p: &mut FXmac, options: u32, queue_num: u32) -> u32 {
1051    let mut reg: u32 = 0; /* Generic */
1052    let mut reg_net_cfg: u32 = 0; /* Reflects original contents of NET_CONFIG */
1053    let mut reg_new_net_cfg: u32 = 0; /* Reflects new contents of NET_CONFIG */
1054    let mut status: u32 = 0;
1055
1056    //let is_started = 0;
1057    /* Be sure device has been stopped */
1058    if (instance_p.is_started == FT_COMPONENT_IS_STARTED) {
1059        status = 9; //FXMAC_ERR_MAC_IS_PROCESSING
1060        error!("FXMAC is processing when calling FXmacClearOptions function");
1061    } else {
1062        /* Many of these options will change the NET_CONFIG registers.
1063         * To reduce the amount of IO to the device, group these options here
1064         * and change them all at once.
1065         */
1066        /* Grab current register contents */
1067        reg_net_cfg = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1068        reg_new_net_cfg = reg_net_cfg;
1069        /* There is only RX configuration!?
1070         * It is configured in two different length, up to 1536 and 10240 bytes
1071         */
1072        if (options & FXMAC_FRAME1536_OPTION) != 0 {
1073            reg_new_net_cfg &= !FXMAC_NWCFG_1536RXEN_MASK;
1074        }
1075
1076        /* Turn off VLAN packet only */
1077        if (options & FXMAC_VLAN_OPTION) != 0 {
1078            reg_new_net_cfg &= !FXMAC_NWCFG_NVLANDISC_MASK;
1079        }
1080
1081        /* Turn off FCS stripping on receive packets */
1082        if (options & FXMAC_FCS_STRIP_OPTION) != 0 {
1083            reg_new_net_cfg &= !FXMAC_NWCFG_FCS_REMOVE_MASK;
1084        }
1085
1086        /* Turn off length/type field checking on receive packets */
1087        if (options & FXMAC_LENTYPE_ERR_OPTION) != 0 {
1088            reg_new_net_cfg &= !FXMAC_NWCFG_LENGTH_FIELD_ERROR_FRAME_DISCARD_MASK;
1089        }
1090
1091        /* Turn off flow control */
1092        if (options & FXMAC_FLOW_CONTROL_OPTION) != 0 {
1093            reg_new_net_cfg &= !FXMAC_NWCFG_PAUSE_ENABLE_MASK;
1094        }
1095
1096        /* Turn off promiscuous frame filtering (all frames are received) */
1097        if (options & FXMAC_PROMISC_OPTION) != 0 {
1098            reg_new_net_cfg &= !FXMAC_NWCFG_COPYALLEN_MASK;
1099        }
1100
1101        /* Disallow broadcast address filtering => broadcast reception */
1102        if (options & FXMAC_BROADCAST_OPTION) != 0 {
1103            reg_new_net_cfg |= FXMAC_NWCFG_BCASTDI_MASK;
1104        }
1105
1106        /* Disallow unicast address filtering */
1107        if (options & FXMAC_UNICAST_OPTION) != 0 {
1108            reg_new_net_cfg &= !FXMAC_NWCFG_UCASTHASHEN_MASK;
1109        }
1110
1111        /* Disallow multicast address filtering */
1112        if (options & FXMAC_MULTICAST_OPTION) != 0 {
1113            reg_new_net_cfg &= !FXMAC_NWCFG_MCASTHASHEN_MASK;
1114        }
1115
1116        if (options & FXMAC_TAIL_PTR_OPTION) != 0 {
1117            write_reg((FXMAC_IOBASE + FXMAC_TAIL_ENABLE) as *mut u32, 0);
1118        }
1119
1120        /* Disable RX checksum offload */
1121        if (options & FXMAC_RX_CHKSUM_ENABLE_OPTION) != 0 {
1122            reg_new_net_cfg &= !FXMAC_NWCFG_RXCHKSUMEN_MASK;
1123        }
1124
1125        /* Disable jumbo frames */
1126        if (options & FXMAC_JUMBO_ENABLE_OPTION) != 0
1127        /* 恢复之前buffer 容量 */
1128        {
1129            instance_p.max_mtu_size = FXMAC_MTU;
1130            instance_p.max_frame_size = FXMAC_MAX_FRAME_SIZE;
1131
1132            reg_new_net_cfg &= !FXMAC_NWCFG_JUMBO_MASK;
1133
1134            reg = read_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *const u32);
1135
1136            reg &= !FXMAC_DMACR_RXBUF_MASK;
1137
1138            if queue_num == 0 {
1139                let mut rx_buf_size: u32 = 0;
1140
1141                reg = read_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *const u32);
1142                reg &= !FXMAC_DMACR_RXBUF_MASK;
1143
1144                rx_buf_size = instance_p.max_frame_size / FXMAC_RX_BUF_UNIT;
1145                rx_buf_size += if instance_p.max_frame_size % FXMAC_RX_BUF_UNIT != 0 {
1146                    1
1147                } else {
1148                    0
1149                };
1150
1151                reg |= (rx_buf_size << FXMAC_DMACR_RXBUF_SHIFT) & FXMAC_DMACR_RXBUF_MASK;
1152
1153                write_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *mut u32, reg);
1154            } else if (queue_num < instance_p.config.max_queue_num) {
1155                let mut rx_buf_size: u32 = 0;
1156                rx_buf_size = instance_p.max_frame_size / FXMAC_RX_BUF_UNIT;
1157                rx_buf_size += if (instance_p.max_frame_size % FXMAC_RX_BUF_UNIT) != 0 {
1158                    1
1159                } else {
1160                    0
1161                };
1162
1163                write_reg(
1164                    (FXMAC_IOBASE + FXMAC_RXBUFQX_SIZE_OFFSET(queue_num as u64)) as *mut u32,
1165                    rx_buf_size & FXMAC_RXBUFQX_SIZE_MASK,
1166                );
1167            }
1168        }
1169
1170        if (options & FXMAC_SGMII_ENABLE_OPTION) != 0 {
1171            reg_new_net_cfg &= !(FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK | FXMAC_NWCFG_PCSSEL_MASK);
1172        }
1173
1174        if (options & FXMAC_LOOPBACK_NO_MII_OPTION) != 0 {
1175            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1176            reg &= !FXMAC_NWCTRL_LOOPBACK_LOCAL_MASK;
1177            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
1178        }
1179
1180        if (options & FXMAC_LOOPBACK_USXGMII_OPTION) != 0 {
1181            write_reg(
1182                (FXMAC_IOBASE + FXMAC_TEST_CONTROL_OFFSET) as *mut u32,
1183                read_reg((FXMAC_IOBASE + FXMAC_TEST_CONTROL_OFFSET) as *const u32) & !2,
1184            );
1185        }
1186
1187        /* Officially change the NET_CONFIG registers if it needs to be
1188         * modified.
1189         */
1190        if reg_net_cfg != reg_new_net_cfg {
1191            write_reg(
1192                (FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32,
1193                reg_new_net_cfg,
1194            );
1195        }
1196
1197        /* Disable TX checksum offload */
1198        if (options & FXMAC_TX_CHKSUM_ENABLE_OPTION) != 0 {
1199            reg = read_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *const u32);
1200            reg &= !FXMAC_DMACR_TCPCKSUM_MASK;
1201            write_reg((FXMAC_IOBASE + FXMAC_DMACR_OFFSET) as *mut u32, reg);
1202        }
1203
1204        /* Disable transmitter */
1205        if (options & FXMAC_TRANSMITTER_ENABLE_OPTION) != 0 {
1206            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1207            reg &= !FXMAC_NWCTRL_TXEN_MASK;
1208            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
1209        }
1210
1211        /* Disable receiver */
1212        if (options & FXMAC_RECEIVER_ENABLE_OPTION) != 0 {
1213            reg = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1214            reg &= !FXMAC_NWCTRL_RXEN_MASK;
1215            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, reg);
1216        }
1217
1218        /* The remaining options not handled here are managed elsewhere in the
1219         * driver. No register modifications are needed at this time. Reflecting
1220         * option in instance_p->options is good enough for now.
1221         */
1222
1223        /* Set options word to its new value */
1224        instance_p.options &= !options;
1225
1226        status = 0; // FT_SUCCESS
1227    }
1228    status
1229}
1230
1231///  Clear the Hash registers for the mac address pointed by address_ptr.
1232fn FXmacClearHash() {
1233    write_reg((FXMAC_IOBASE + FXMAC_HASHL_OFFSET) as *mut u32, 0);
1234
1235    /* write bits [63:32] in TOP */
1236    write_reg((FXMAC_IOBASE + FXMAC_HASHH_OFFSET) as *mut u32, 0);
1237}
1238
1239/// Sets the MAC address for the specified address slot.
1240///
1241/// The device must be stopped before calling this function.
1242///
1243/// # Arguments
1244///
1245/// * `address_ptr` - 6-byte MAC address.
1246/// * `index` - Address slot index (0..FXMAC_MAX_MAC_ADDR).
1247///
1248/// # Panics
1249///
1250/// Panics if `index` is out of range.
1251pub fn FXmacSetMacAddress(address_ptr: &[u8; 6], index: u8) -> u32 {
1252    let mut mac_addr: u32 = 0;
1253    let aptr = address_ptr;
1254    let index_loc: u8 = index;
1255    let mut status: u32 = 0;
1256    assert!(
1257        (index_loc < FXMAC_MAX_MAC_ADDR as u8),
1258        "index of Mac Address exceed {}",
1259        FXMAC_MAX_MAC_ADDR
1260    );
1261
1262    let is_started = 0;
1263    /* Be sure device has been stopped */
1264    if is_started == FT_COMPONENT_IS_STARTED {
1265        //status = FXMAC_ERR_MAC_IS_PROCESSING;
1266        status = 9;
1267        error!("FXMAC is processing when calling FXmacSetMacAddress function");
1268    } else {
1269        /* Set the MAC bits [31:0] in BOT */
1270        mac_addr = aptr[0] as u32
1271            | ((aptr[1] as u32) << 8)
1272            | ((aptr[2] as u32) << 16)
1273            | ((aptr[3] as u32) << 24);
1274        write_reg(
1275            (FXMAC_IOBASE + FXMAC_GEM_SA1B as u64 + (index_loc * 8) as u64) as *mut u32,
1276            mac_addr,
1277        );
1278
1279        /* There are reserved bits in TOP so don't affect them */
1280        mac_addr =
1281            read_reg((FXMAC_IOBASE + FXMAC_GEM_SA1T as u64 + (index_loc * 8) as u64) as *const u32);
1282        mac_addr &= !FXMAC_GEM_SAB_MASK;
1283
1284        /* Set MAC bits [47:32] in TOP */
1285        mac_addr |= aptr[4] as u32;
1286        mac_addr |= (aptr[5] as u32) << 8;
1287
1288        write_reg(
1289            (FXMAC_IOBASE + FXMAC_GEM_SA1T as u64 + (index_loc * 8) as u64) as *mut u32,
1290            mac_addr,
1291        );
1292
1293        status = 0; // FT_SUCCESS
1294    }
1295
1296    status
1297}
1298/// Reads a MAC address from the specified address slot.
1299///
1300/// # Arguments
1301///
1302/// * `address_ptr` - Output buffer for the MAC address.
1303/// * `index` - Address slot index (0..FXMAC_MAX_MAC_ADDR).
1304///
1305/// # Panics
1306///
1307/// Panics if `index` is out of range.
1308pub fn FXmacGetMacAddress(address_ptr: &mut [u8; 6], index: u8) {
1309    assert!((index as u32) < FXMAC_MAX_MAC_ADDR);
1310
1311    let mut reg_value: u32 =
1312        read_reg((FXMAC_IOBASE + FXMAC_GEM_SA1B as u64 + (index as u64 * 8)) as *const u32);
1313    address_ptr[0] = reg_value as u8;
1314    address_ptr[1] = (reg_value >> 8) as u8;
1315    address_ptr[2] = (reg_value >> 16) as u8;
1316    address_ptr[3] = (reg_value >> 24) as u8;
1317
1318    reg_value = read_reg((FXMAC_IOBASE + FXMAC_GEM_SA1T as u64 + (index as u64 * 8)) as *const u32);
1319    address_ptr[4] = (reg_value) as u8;
1320    address_ptr[5] = (reg_value >> 8) as u8;
1321}
1322
1323/// Sets a 48-bit MAC address entry in the hash table.
1324///
1325/// The device must be stopped before calling this function.
1326///
1327/// # Arguments
1328///
1329/// * `intance_p` - Mutable reference to the FXMAC instance.
1330/// * `mac_address` - The MAC address to hash.
1331///
1332/// The hash address register is 64 bits long and takes up two locations in
1333/// the memory map. The least significant bits are stored in hash register
1334/// bottom and the most significant bits in hash register top.
1335///
1336/// The unicast hash enable and the multicast hash enable bits in the network
1337/// configuration register enable the reception of hash matched frames. The
1338/// destination address is reduced to a 6 bit index into the 64 bit hash
1339/// register using the following hash function. The hash function is an XOR
1340/// of every sixth bit of the destination address.
1341pub fn FXmac_SetHash(intance_p: &mut FXmac, mac_address: &[u8; 6]) -> u32 {
1342    let mut HashAddr: u32 = 0;
1343    let mut Status: u32 = 0;
1344    debug!("Set MAC: {:x?} in hash table", mac_address);
1345
1346    // Check that the Ethernet address (MAC) is not 00:00:00:00:00:00
1347    assert!(!((mac_address[0] == 0) && (mac_address[5] == 0)));
1348    assert!(intance_p.is_ready == FT_COMPONENT_IS_READY);
1349
1350    /* Be sure device has been stopped */
1351    if (intance_p.is_started == FT_COMPONENT_IS_STARTED) {
1352        error!("FXmac_SetHash failed: FXMAC_ERR_MAC_IS_PROCESSING");
1353        Status = 9; // FXMAC_ERR_MAC_IS_PROCESSING
1354    } else {
1355        let Temp1: u8 = (mac_address[0]) & 0x3F;
1356        let Temp2: u8 = ((mac_address[0] >> 6) & 0x03) | ((mac_address[1] & 0x0F) << 2);
1357        let Temp3: u8 = ((mac_address[1] >> 4) & 0x0F) | ((mac_address[2] & 0x3) << 4);
1358        let Temp4: u8 = ((mac_address[2] >> 2) & 0x3F);
1359        let Temp5: u8 = mac_address[3] & 0x3F;
1360        let Temp6: u8 = ((mac_address[3] >> 6) & 0x03) | ((mac_address[4] & 0x0F) << 2);
1361        let Temp7: u8 = ((mac_address[4] >> 4) & 0x0F) | ((mac_address[5] & 0x03) << 4);
1362        let Temp8: u8 = ((mac_address[5] >> 2) & 0x3F);
1363
1364        let Result: u32 = (Temp1 as u32)
1365            ^ (Temp2 as u32)
1366            ^ (Temp3 as u32)
1367            ^ (Temp4 as u32)
1368            ^ (Temp5 as u32)
1369            ^ (Temp6 as u32)
1370            ^ (Temp7 as u32)
1371            ^ (Temp8 as u32);
1372
1373        if (Result >= FXMAC_MAX_HASH_BITS) {
1374            Status = 1; // FXMAC_ERR_INVALID_PARAM
1375        } else {
1376            if (Result < 32) {
1377                HashAddr =
1378                    read_reg((intance_p.config.base_address + FXMAC_HASHL_OFFSET) as *const u32);
1379                HashAddr |= 1 << Result;
1380                write_reg(
1381                    (intance_p.config.base_address + FXMAC_HASHL_OFFSET) as *mut u32,
1382                    HashAddr,
1383                );
1384            } else {
1385                HashAddr =
1386                    read_reg((intance_p.config.base_address + FXMAC_HASHH_OFFSET) as *const u32);
1387                HashAddr |= 1 << (Result - 32);
1388                write_reg(
1389                    (intance_p.config.base_address + FXMAC_HASHH_OFFSET) as *mut u32,
1390                    HashAddr,
1391                );
1392            }
1393            Status = 0;
1394        }
1395    }
1396
1397    Status
1398}
1399
1400/// Delete 48-bit MAC addresses in hash table.
1401/// The device must be stopped before calling this function.
1402pub fn FXmac_DeleteHash(intance_p: &mut FXmac, mac_address: &[u8; 6]) -> u32 {
1403    let mut HashAddr: u32 = 0;
1404    let mut Status: u32 = 0;
1405
1406    assert!(intance_p.is_ready == FT_COMPONENT_IS_READY);
1407
1408    /* Be sure device has been stopped */
1409    if (intance_p.is_started == FT_COMPONENT_IS_STARTED) {
1410        Status = 9; // (FXMAC_ERR_MAC_IS_PROCESSING);
1411    } else {
1412        let mut Temp1: u8 = (mac_address[0]) & 0x3F;
1413        let mut Temp2: u8 = ((mac_address[0] >> 6) & 0x03) | ((mac_address[1] & 0x0F) << 2);
1414        let mut Temp3: u8 = ((mac_address[1] >> 4) & 0x0F) | ((mac_address[2] & 0x03) << 4);
1415        let mut Temp4: u8 = ((mac_address[2] >> 2) & 0x3F);
1416        let mut Temp5: u8 = (mac_address[3]) & 0x3F;
1417        let mut Temp6: u8 = ((mac_address[3] >> 6) & 0x03) | ((mac_address[4] & 0x0F) << 2);
1418        let mut Temp7: u8 = ((mac_address[4] >> 4) & 0x0F) | ((mac_address[5] & 0x03) << 4);
1419        let mut Temp8: u8 = ((mac_address[5] >> 2) & 0x3F);
1420
1421        let Result: u32 = (Temp1 as u32)
1422            ^ (Temp2 as u32)
1423            ^ (Temp3 as u32)
1424            ^ (Temp4 as u32)
1425            ^ (Temp5 as u32)
1426            ^ (Temp6 as u32)
1427            ^ (Temp7 as u32)
1428            ^ (Temp8 as u32);
1429
1430        if Result >= FXMAC_MAX_HASH_BITS {
1431            Status = 1; //(FXMAC_ERR_INVALID_PARAM);
1432        } else {
1433            if Result < 32 {
1434                HashAddr =
1435                    read_reg((intance_p.config.base_address + FXMAC_HASHL_OFFSET) as *const u32);
1436                HashAddr &= !((1 << Result) as u32);
1437                write_reg(
1438                    (intance_p.config.base_address + FXMAC_HASHL_OFFSET) as *mut u32,
1439                    HashAddr,
1440                );
1441            } else {
1442                HashAddr =
1443                    read_reg((intance_p.config.base_address + FXMAC_HASHH_OFFSET) as *const u32);
1444                HashAddr &= !((1 << (Result - 32)) as u32);
1445                write_reg(
1446                    (intance_p.config.base_address + FXMAC_HASHH_OFFSET) as *mut u32,
1447                    HashAddr,
1448                );
1449            }
1450            Status = 0;
1451        }
1452    }
1453    Status
1454}
1455
1456/// Set the Type ID match for this driver/device.  The register is a 32-bit value.
1457/// The device must be stopped before calling this function.
1458fn FXmacSetTypeIdCheck(id_check: u32, index: u8) -> u32 {
1459    let mut status: u32 = 0;
1460    assert!(
1461        (index < FXMAC_MAX_TYPE_ID as u8),
1462        "index of Type ID exceed {}",
1463        FXMAC_MAX_TYPE_ID
1464    );
1465
1466    let is_started = 0;
1467    /* Be sure device has been stopped */
1468    if is_started == FT_COMPONENT_IS_STARTED {
1469        status = 9; //FXMAC_ERR_MAC_IS_PROCESSING
1470        error!("FXMAC is processing when calling FXmacSetTypeIdCheck function");
1471    } else {
1472        /* Set the ID bits in MATCHx register */
1473        write_reg(
1474            (FXMAC_IOBASE + FXMAC_MATCH1_OFFSET + (index * 4) as u64) as *mut u32,
1475            id_check,
1476        );
1477
1478        status = FT_SUCCESS;
1479    }
1480
1481    status
1482}
1483
1484/// FXmacSelectClk
1485/// Determine the driver clock configuration based on the media independent interface
1486/// FXMAC_CLK_TYPE_0
1487fn FXmacSelectClk(instance_p: &mut FXmac) {
1488    let speed: u32 = instance_p.config.speed;
1489    let FXMAC_WRITEREG32 = |base_address: u64, offset: u32, reg_value: u32| {
1490        write_reg((base_address + offset as u64) as *mut u32, reg_value)
1491    };
1492
1493    assert!(
1494        (speed == FXMAC_SPEED_10)
1495            || (speed == FXMAC_SPEED_100)
1496            || (speed == FXMAC_SPEED_1000)
1497            || (speed == FXMAC_SPEED_2500)
1498            || (speed == FXMAC_SPEED_10000)
1499    );
1500
1501    if (instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_USXGMII)
1502        || (instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_XGMII)
1503    {
1504        if speed == FXMAC_SPEED_10000 {
1505            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1506            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4); /*0x1c08*/
1507            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x1); /*0x1c0c*/
1508            FXMAC_WRITEREG32(
1509                instance_p.config.base_address,
1510                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1511                0x1,
1512            ); /*0x1c10*/
1513        } else if speed == FXMAC_SPEED_5000 {
1514            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1515            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x8); /*0x1c08*/
1516            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2); /*0x1c0c*/
1517            FXMAC_WRITEREG32(
1518                instance_p.config.base_address,
1519                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1520                0,
1521            ); /*0x1c10*/
1522        }
1523    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_5GBASER {
1524        if speed == FXMAC_SPEED_5000 {
1525            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1526            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x8); /*0x1c08*/
1527            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2); /*0x1c0c*/
1528            FXMAC_WRITEREG32(
1529                instance_p.config.base_address,
1530                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1531                0x0,
1532            ); /*0x1c10*/
1533        }
1534    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_2500BASEX {
1535        if speed == FXMAC_SPEED_25000 {
1536            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1537            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x1); /*0x1c08*/
1538            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2); /*0x1c0c*/
1539            FXMAC_WRITEREG32(
1540                instance_p.config.base_address,
1541                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1542                0x1,
1543            ); /*0x1c10*/
1544            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0); /*0x1c20*/
1545            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
1546            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1); /*0x1c28*/
1547            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1); /*0x1c2c*/
1548            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1); /*0x1c30*/
1549            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0); /*0x1c34*/
1550            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/
1551            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
1552            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
1553            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0);
1554            /*0x1c7c*/
1555        }
1556    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_SGMII {
1557        info!("FXMAC_PHY_INTERFACE_MODE_SGMII init");
1558        if speed == FXMAC_SPEED_2500 {
1559            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0);
1560            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x1);
1561            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x2);
1562            FXMAC_WRITEREG32(
1563                instance_p.config.base_address,
1564                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1565                0x1,
1566            );
1567            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0);
1568            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1);
1569            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1);
1570            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1);
1571            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1);
1572            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0);
1573            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/
1574            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
1575            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
1576            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0);
1577        /*0x1c7c*/
1578        } else if speed == FXMAC_SPEED_1000 {
1579            info!("sgmii FXMAC_SPEED_1000");
1580            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1581            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4); /*0x1c08*/
1582            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x8); /*0x1c0c*/
1583            FXMAC_WRITEREG32(
1584                instance_p.config.base_address,
1585                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1586                0x1,
1587            ); /*0x1c10*/
1588            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
1589            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x0); /*0x1c24*/
1590            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
1591            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1); /*0x1c2c*/
1592            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1); /*0x1c30*/
1593            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0); /*0x1c34*/
1594            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x0); /*0x1c70*/
1595            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
1596            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
1597            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x0);
1598        /*0x1c7c*/
1599        } else if (speed == FXMAC_SPEED_100) || (speed == FXMAC_SPEED_10) {
1600            info!("sgmii FXMAC_SPEED_{}", speed);
1601
1602            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_SRC_SEL_LN, 0x1); /*0x1c04*/
1603            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL0_LN, 0x4); /*0x1c08*/
1604            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_DIV_SEL1_LN, 0x8); /*0x1c0c*/
1605            FXMAC_WRITEREG32(
1606                instance_p.config.base_address,
1607                FXMAC_GEM_PMA_XCVR_POWER_STATE,
1608                0x1,
1609            ); /*0x1c10*/
1610            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
1611            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x0); /*0x1c24*/
1612            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x1); /*0x1c28*/
1613            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x1); /*0x1c2c*/
1614            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x1); /*0x1c30*/
1615            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x0); /*0x1c34*/
1616            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3_0, 0x1); /*0x1c70*/
1617            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL4_0, 0x0); /*0x1c74*/
1618            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL3_0, 0x0); /*0x1c78*/
1619            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL4_0, 0x1);
1620            /*0x1c7c*/
1621        }
1622    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_RGMII {
1623        info!("FXMAC_PHY_INTERFACE_MODE_RGMII init");
1624        if speed == FXMAC_SPEED_1000 {
1625            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_MII_SELECT, 0x1); /*0x1c18*/
1626            FXMAC_WRITEREG32(
1627                instance_p.config.base_address,
1628                FXMAC_GEM_SEL_MII_ON_RGMII,
1629                0x0,
1630            ); /*0x1c1c*/
1631            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
1632            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
1633            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
1634            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
1635            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
1636            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
1637            FXMAC_WRITEREG32(
1638                instance_p.config.base_address,
1639                FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
1640                0x0,
1641            ); /*0x1c38*/
1642            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
1643            FXMAC_WRITEREG32(
1644                instance_p.config.base_address,
1645                FXMAC_GEM_RGMII_TX_CLK_SEL0,
1646                0x1,
1647            ); /*0x1c80*/
1648            FXMAC_WRITEREG32(
1649                instance_p.config.base_address,
1650                FXMAC_GEM_RGMII_TX_CLK_SEL1,
1651                0x0,
1652            ); /*0x1c84*/
1653        } else if speed == FXMAC_SPEED_100 {
1654            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_MII_SELECT, 0x1); /*0x1c18*/
1655            FXMAC_WRITEREG32(
1656                instance_p.config.base_address,
1657                FXMAC_GEM_SEL_MII_ON_RGMII,
1658                0x0,
1659            ); /*0x1c1c*/
1660            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
1661            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
1662            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
1663            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
1664            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
1665            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
1666            FXMAC_WRITEREG32(
1667                instance_p.config.base_address,
1668                FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
1669                0x0,
1670            ); /*0x1c38*/
1671            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
1672            FXMAC_WRITEREG32(
1673                instance_p.config.base_address,
1674                FXMAC_GEM_RGMII_TX_CLK_SEL0,
1675                0x0,
1676            ); /*0x1c80*/
1677            FXMAC_WRITEREG32(
1678                instance_p.config.base_address,
1679                FXMAC_GEM_RGMII_TX_CLK_SEL1,
1680                0x0,
1681            ); /*0x1c84*/
1682        } else {
1683            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_MII_SELECT, 0x1); /*0x1c18*/
1684            FXMAC_WRITEREG32(
1685                instance_p.config.base_address,
1686                FXMAC_GEM_SEL_MII_ON_RGMII,
1687                0x0,
1688            ); /*0x1c1c*/
1689            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL0, 0x0); /*0x1c20*/
1690            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL1, 0x1); /*0x1c24*/
1691            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL2, 0x0); /*0x1c28*/
1692            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_TX_CLK_SEL3, 0x0); /*0x1c2c*/
1693            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL0, 0x0); /*0x1c30*/
1694            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL1, 0x1); /*0x1c34*/
1695            FXMAC_WRITEREG32(
1696                instance_p.config.base_address,
1697                FXMAC_GEM_CLK_250M_DIV10_DIV100_SEL,
1698                0x1,
1699            ); /*0x1c38*/
1700            FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1); /*0x1c48*/
1701            FXMAC_WRITEREG32(
1702                instance_p.config.base_address,
1703                FXMAC_GEM_RGMII_TX_CLK_SEL0,
1704                0x0,
1705            ); /*0x1c80*/
1706            FXMAC_WRITEREG32(
1707                instance_p.config.base_address,
1708                FXMAC_GEM_RGMII_TX_CLK_SEL1,
1709                0x0,
1710            ); /*0x1c84*/
1711        }
1712    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_RMII {
1713        FXMAC_WRITEREG32(instance_p.config.base_address, FXMAC_GEM_RX_CLK_SEL5, 0x1);
1714        /*0x1c48*/
1715    }
1716
1717    FXmacHighSpeedConfiguration(instance_p, speed);
1718}
1719
1720fn FXmacHighSpeedConfiguration(instance_p: &mut FXmac, speed: u32) {
1721    let mut reg_value: u32 = 0;
1722    let mut set_speed: i32 = 0;
1723    match speed {
1724        FXMAC_SPEED_25000 => {
1725            set_speed = 2;
1726        }
1727        FXMAC_SPEED_10000 => {
1728            set_speed = 4;
1729        }
1730        FXMAC_SPEED_5000 => {
1731            set_speed = 3;
1732        }
1733        FXMAC_SPEED_2500 => {
1734            set_speed = 2;
1735        }
1736        FXMAC_SPEED_1000 => {
1737            set_speed = 1;
1738        }
1739        _ => {
1740            set_speed = 0;
1741        }
1742    }
1743
1744    /*GEM_HSMAC(0x0050) provide rate to the external*/
1745    reg_value = read_reg((FXMAC_IOBASE + FXMAC_GEM_HSMAC as u64) as *const u32);
1746    reg_value &= !FXMAC_GEM_HSMACSPEED_MASK;
1747    reg_value |= (set_speed as u32) & FXMAC_GEM_HSMACSPEED_MASK;
1748    write_reg(
1749        (FXMAC_IOBASE + FXMAC_GEM_HSMAC as u64) as *mut u32,
1750        reg_value,
1751    );
1752
1753    reg_value = read_reg((FXMAC_IOBASE + FXMAC_GEM_HSMAC as u64) as *const u32);
1754
1755    info!("FXMAC_GEM_HSMAC is {:#x}", reg_value);
1756}
1757
1758/// FXmacInitInterface
1759/// Initialize the MAC controller configuration based on the PHY interface type
1760fn FXmacInitInterface(instance_p: &mut FXmac) {
1761    let mut config: u32 = 0;
1762    let mut control: u32 = 0;
1763
1764    info!(
1765        "FXmacInitInterface, PHY MODE:{:?}",
1766        instance_p.config.interface
1767    );
1768
1769    if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_XGMII {
1770        config = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1771        config &= !FXMAC_NWCFG_PCSSEL_MASK;
1772        write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, config);
1773
1774        control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1775        control |= FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
1776        write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1777
1778        instance_p.config.duplex = 1;
1779    } else if (instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_USXGMII)
1780        || (instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_5GBASER)
1781    {
1782        info!("usx interface is {:?}", instance_p.config.interface);
1783        /*  network_config */
1784        instance_p.config.duplex = 1;
1785        config = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1786        config |= FXMAC_NWCFG_PCSSEL_MASK;
1787        config &= !FXMAC_NWCFG_100_MASK;
1788        config &= !FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK;
1789        if (instance_p.config.duplex == 1) {
1790            info!("is duplex");
1791            config |= FXMAC_NWCFG_FDEN_MASK;
1792        }
1793
1794        write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, config);
1795
1796        /* network_control */
1797        control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1798        control |= FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
1799        write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1800
1801        /* High speed PCS control register */
1802        control = read_reg((FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *const u32);
1803
1804        if (instance_p.config.speed == FXMAC_SPEED_10000) {
1805            info!("is 10G");
1806            control |= FXMAC_GEM_USX_HS_MAC_SPEED_10G;
1807            control |= FXMAC_GEM_USX_SERDES_RATE_10G;
1808        } else if (instance_p.config.speed == FXMAC_SPEED_25000) {
1809            control |= FXMAC_GEM_USX_HS_MAC_SPEED_2_5G;
1810        } else if (instance_p.config.speed == FXMAC_SPEED_1000) {
1811            control |= FXMAC_GEM_USX_HS_MAC_SPEED_1G;
1812        } else if (instance_p.config.speed == FXMAC_SPEED_100) {
1813            control |= FXMAC_GEM_USX_HS_MAC_SPEED_100M;
1814        } else if (instance_p.config.speed == FXMAC_SPEED_5000) {
1815            control |= FXMAC_GEM_USX_HS_MAC_SPEED_5G;
1816            control |= FXMAC_GEM_USX_SERDES_RATE_5G;
1817        }
1818
1819        control &= !(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS);
1820        control |= FXMAC_GEM_USX_RX_SYNC_RESET;
1821        write_reg(
1822            (FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *mut u32,
1823            control,
1824        );
1825
1826        control = read_reg((FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *const u32);
1827        control &= !FXMAC_GEM_USX_RX_SYNC_RESET;
1828        control |= FXMAC_GEM_USX_TX_DATAPATH_EN;
1829        control |= FXMAC_GEM_USX_SIGNAL_OK;
1830
1831        write_reg(
1832            (FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *mut u32,
1833            control,
1834        );
1835    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_2500BASEX {
1836        /*  network_config */
1837        instance_p.config.duplex = 1;
1838        config = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1839        config |= FXMAC_NWCFG_PCSSEL_MASK | FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK;
1840        config &= !FXMAC_NWCFG_100_MASK;
1841
1842        if (instance_p.config.duplex == 1) {
1843            config |= FXMAC_NWCFG_FDEN_MASK;
1844        }
1845        write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, config);
1846
1847        /* network_control */
1848        control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1849        control &= !FXMAC_NWCTRL_ENABLE_HS_MAC_MASK;
1850        control |= FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK; /* Use high speed MAC */
1851        write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1852
1853        /* High speed PCS control register */
1854        control = read_reg((FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *const u32);
1855
1856        if (instance_p.config.speed == FXMAC_SPEED_25000) {
1857            control |= FXMAC_GEM_USX_HS_MAC_SPEED_2_5G;
1858        }
1859
1860        control &= !(FXMAC_GEM_USX_TX_SCR_BYPASS | FXMAC_GEM_USX_RX_SCR_BYPASS);
1861        control |= FXMAC_GEM_USX_RX_SYNC_RESET;
1862        write_reg(
1863            (FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *mut u32,
1864            control,
1865        );
1866
1867        control = read_reg((FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *const u32);
1868        control &= !FXMAC_GEM_USX_RX_SYNC_RESET;
1869        control |= FXMAC_GEM_USX_TX_DATAPATH_EN;
1870        control |= FXMAC_GEM_USX_SIGNAL_OK;
1871
1872        write_reg(
1873            (FXMAC_IOBASE + FXMAC_GEM_USX_CONTROL_OFFSET) as *mut u32,
1874            control,
1875        );
1876    } else if instance_p.config.interface == FXmacPhyInterface::FXMAC_PHY_INTERFACE_MODE_SGMII {
1877        config = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1878        config |= FXMAC_NWCFG_PCSSEL_MASK | FXMAC_NWCFG_SGMII_MODE_ENABLE_MASK;
1879
1880        config &= !(FXMAC_NWCFG_100_MASK
1881            | FXMAC_NWCFG_FDEN_MASK
1882            | FXMAC_NWCFG_LENGTH_FIELD_ERROR_FRAME_DISCARD_MASK);
1883
1884        if instance_p.moudle_id >= 2 {
1885            config &= !FXMAC_NWCFG_1000_MASK;
1886        }
1887
1888        if instance_p.config.duplex != 0 {
1889            config |= FXMAC_NWCFG_FDEN_MASK;
1890        }
1891
1892        if instance_p.config.speed == FXMAC_SPEED_100 {
1893            config |= FXMAC_NWCFG_100_MASK;
1894        } else if instance_p.config.speed == FXMAC_SPEED_1000 {
1895            config |= FXMAC_NWCFG_1000_MASK;
1896        }
1897
1898        write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, config);
1899
1900        if instance_p.config.speed == FXMAC_SPEED_2500 {
1901            control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1902            control |= FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK;
1903            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1904        } else {
1905            control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1906            control &= !FXMAC_NWCTRL_TWO_PT_FIVE_GIG_MASK;
1907            write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1908        }
1909
1910        control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1911        control &= !FXMAC_NWCTRL_ENABLE_HS_MAC_MASK;
1912        write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1913
1914        control = read_reg((FXMAC_IOBASE + FXMAC_PCS_CONTROL_OFFSET) as *const u32);
1915        control |= FXMAC_PCS_CONTROL_ENABLE_AUTO_NEG;
1916        write_reg(
1917            (FXMAC_IOBASE + FXMAC_PCS_CONTROL_OFFSET) as *mut u32,
1918            control,
1919        );
1920    } else {
1921        config = read_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *const u32);
1922
1923        info!("select rgmii");
1924
1925        config &= !FXMAC_NWCFG_PCSSEL_MASK;
1926        config &= !(FXMAC_NWCFG_100_MASK | FXMAC_NWCFG_FDEN_MASK);
1927
1928        if instance_p.moudle_id >= 2 {
1929            config &= !FXMAC_NWCFG_1000_MASK;
1930        }
1931
1932        if instance_p.config.duplex != 0 {
1933            config |= FXMAC_NWCFG_FDEN_MASK;
1934        }
1935
1936        if instance_p.config.speed == FXMAC_SPEED_100 {
1937            config |= FXMAC_NWCFG_100_MASK;
1938        } else if instance_p.config.speed == FXMAC_SPEED_1000 {
1939            config |= FXMAC_NWCFG_1000_MASK;
1940        }
1941
1942        write_reg((FXMAC_IOBASE + FXMAC_NWCFG_OFFSET) as *mut u32, config);
1943
1944        control = read_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *const u32);
1945        control &= !FXMAC_NWCTRL_ENABLE_HS_MAC_MASK; /* Use high speed MAC */
1946        write_reg((FXMAC_IOBASE + FXMAC_NWCTRL_OFFSET) as *mut u32, control);
1947    }
1948}