gk7205v200-uboot/drivers/net/femac/ctrl.c

184 lines
3.8 KiB
C
Raw Permalink Normal View History

2025-08-07 17:13:54 +08:00
/*
* Copyright (c) Hunan Goke,Chengdu Goke,Shandong Goke. 2021. All rights reserved.
*/
#define BSPETH_FEMAC
#include "bspeth.h"
#include "ctrl.h"
static inline u32 _bspeth_irq_enable(struct bspeth_netdev_local *ld, u32 irqs)
{
u32 old = bspeth_readl(ld, GLB_RW_IRQ_ENA);
bspeth_writel(ld, old | irqs, GLB_RW_IRQ_ENA);
return old;
}
static inline u32 _bspeth_irq_disable(struct bspeth_netdev_local *ld, u32 irqs)
{
u32 old = bspeth_readl(ld, GLB_RW_IRQ_ENA);
bspeth_writel(ld, old & (~irqs), GLB_RW_IRQ_ENA);
return old;
}
static inline u32 _bspeth_read_irqstatus(struct bspeth_netdev_local *ld)
{
u32 status;
status = bspeth_readl(ld, GLB_RO_IRQ_STAT);
return status;
}
static inline int _test_xmit_queue_ready(struct bspeth_netdev_local *ld)
{
return bspeth_readl_bits(ld, ud_reg_name(GLB_RO_QUEUE_STAT),
BITS_XMITQ_RDY);
}
static inline int _test_recv_queue_ready(struct bspeth_netdev_local *ld)
{
return bspeth_readl_bits(ld, ud_reg_name(GLB_RO_QUEUE_STAT),
BITS_RECVQ_RDY);
}
u32 bspeth_irq_enable(struct bspeth_netdev_local *ld, u32 irqs)
{
u32 old;
local_lock(ld);
old = _bspeth_irq_enable(ld, irqs);
local_unlock(ld);
return old;
}
u32 bspeth_irq_disable(struct bspeth_netdev_local *ld, u32 irqs)
{
u32 old;
local_lock(ld);
old = _bspeth_irq_disable(ld, irqs);
local_unlock(ld);
return old;
}
u32 bspeth_read_irqstatus(struct bspeth_netdev_local *ld)
{
u32 status;
local_lock(ld);
status = _bspeth_read_irqstatus(ld);
local_unlock(ld);
return status;
}
u32 bspeth_read_raw_irqstatus(struct bspeth_netdev_local *ld)
{
u32 status;
local_lock(ld);
status = bspeth_readl(ld, GLB_RO_IRQ_STAT);
local_unlock(ld);
return status;
}
u32 bspeth_clear_irqstatus(struct bspeth_netdev_local *ld, u32 irqs)
{
u32 status;
local_lock(ld);
bspeth_writel(ld, irqs, GLB_RW_IRQ_RAW);
status = _bspeth_read_irqstatus(ld);
local_unlock(ld);
return status;
}
u32 bspeth_set_endian_mode(struct bspeth_netdev_local *ld, u32 mode)
{
u32 old;
local_lock(ld);
old = bspeth_readl_bits(ld, GLB_ENDIAN_MOD, BITS_ENDIAN);
bspeth_writel_bits(ld, mode, GLB_ENDIAN_MOD, BITS_ENDIAN);
local_unlock(ld);
return old;
}
void hw_xmitq_setfd(struct bspeth_netdev_local *ld, struct bspeth_frame_desc fd)
{
bspeth_writel(ld, fd.frm_addr, ud_reg_name(GLB_EQ_ADDR));
bspeth_writel_bits(ld, fd.frm_len, ud_reg_name(GLB_EQFRM_LEN), BITS_TXINQ_LEN);
}
u32 bspeth_readl(struct bspeth_netdev_local *ld, u32 ofs)
{
u32 reg = _readl((uintptr_t)(ld->iobase_phys + ofs));
bspeth_trace(BSPETH_TRACE_ETH, "_readl(0x%08X) = 0x%08X",
(u32)(ld->iobase_phys + ofs), reg);
return reg;
}
void bspeth_writel(struct bspeth_netdev_local *ld, u32 v, u32 ofs)
{
_writel(v, (uintptr_t)(ld->iobase_phys + ofs));
bspeth_trace(BSPETH_TRACE_ETH, "_writel(0x%08X) = 0x%08X",
(u32)(ld->iobase_phys + ofs), v);
}
u32 bspeth_readl_bits(struct bspeth_netdev_local *ld, u32 ofs, u32 bits_desc)
{
u32 _bits_desc = bits_desc;
u32 _shift = _bits_desc >> 16; /* shift 16 bit */
u32 _mask = ((1 << (_bits_desc & 0x1F)) - 1) << _shift;
u32 reg = (bspeth_readl(ld, ofs) & _mask) >> _shift;
return reg;
}
void bspeth_writel_bits(struct bspeth_netdev_local *ld, u32 v, u32 ofs, u32 bits_desc)
{
u32 _bits_desc = bits_desc;
u32 _shift = _bits_desc >> 16; /* shift 16 bit */
u32 _reg = bspeth_readl(ld, ofs);
u32 _mask = ((1 << (_bits_desc & 0x1F)) - 1) << _shift;
bspeth_writel(ld, (_reg & (~_mask)) | ((v << _shift) & _mask), ofs);
}
void bspeth_trace(int level, const char *fmt, ...)
{
if (level >= BSPETH_TRACE_LEVEL) {
va_list args;
va_start(args, fmt);
printf("bspeth_trace:");
printf(fmt, args);
printf("\n");
va_end(args);
}
}
void bspeth_error(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
printf("bspeth:");
printf(fmt, args);
printf("\n");
va_end(args);
}
void bspeth_assert(bool cond)
{
if (!cond)
printf("Assert:bspeth:%s:%d\n", __FILE__, __LINE__);
}