7be78d0279
The tool comes from https://github.com/jsoref Signed-off-by: Josh Soref <jsoref@gmail.com> Signed-off-by: Thomas Monjalon <thomas@monjalon.net>
632 lines
16 KiB
C
632 lines
16 KiB
C
/* SPDX-License-Identifier: BSD-3-Clause
|
|
* Copyright 2018-2019 NXP
|
|
*/
|
|
|
|
#include <arpa/inet.h>
|
|
|
|
#include "pfe_logs.h"
|
|
#include "pfe_mod.h"
|
|
|
|
#define PFE_MTU_RESET_MASK 0xC000FFFF
|
|
|
|
void *cbus_base_addr;
|
|
void *ddr_base_addr;
|
|
unsigned long ddr_phys_base_addr;
|
|
unsigned int ddr_size;
|
|
static struct pe_info pe[MAX_PE];
|
|
|
|
/* Initializes the PFE library.
|
|
* Must be called before using any of the library functions.
|
|
*
|
|
* @param[in] cbus_base CBUS virtual base address (as mapped in
|
|
* the host CPU address space)
|
|
* @param[in] ddr_base PFE DDR range virtual base address (as
|
|
* mapped in the host CPU address space)
|
|
* @param[in] ddr_phys_base PFE DDR range physical base address (as
|
|
* mapped in platform)
|
|
* @param[in] size PFE DDR range size (as defined by the host
|
|
* software)
|
|
*/
|
|
void
|
|
pfe_lib_init(void *cbus_base, void *ddr_base, unsigned long ddr_phys_base,
|
|
unsigned int size)
|
|
{
|
|
cbus_base_addr = cbus_base;
|
|
ddr_base_addr = ddr_base;
|
|
ddr_phys_base_addr = ddr_phys_base;
|
|
ddr_size = size;
|
|
|
|
pe[CLASS0_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(0);
|
|
pe[CLASS0_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(0);
|
|
pe[CLASS0_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS0_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS0_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS0_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[CLASS1_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(1);
|
|
pe[CLASS1_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(1);
|
|
pe[CLASS1_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS1_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS1_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS1_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[CLASS2_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(2);
|
|
pe[CLASS2_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(2);
|
|
pe[CLASS2_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS2_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS2_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS2_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[CLASS3_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(3);
|
|
pe[CLASS3_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(3);
|
|
pe[CLASS3_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS3_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS3_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS3_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[CLASS4_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(4);
|
|
pe[CLASS4_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(4);
|
|
pe[CLASS4_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS4_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS4_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS4_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[CLASS5_ID].dmem_base_addr = CLASS_DMEM_BASE_ADDR(5);
|
|
pe[CLASS5_ID].pmem_base_addr = CLASS_IMEM_BASE_ADDR(5);
|
|
pe[CLASS5_ID].pmem_size = CLASS_IMEM_SIZE;
|
|
pe[CLASS5_ID].mem_access_wdata = CLASS_MEM_ACCESS_WDATA;
|
|
pe[CLASS5_ID].mem_access_addr = CLASS_MEM_ACCESS_ADDR;
|
|
pe[CLASS5_ID].mem_access_rdata = CLASS_MEM_ACCESS_RDATA;
|
|
|
|
pe[TMU0_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(0);
|
|
pe[TMU0_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(0);
|
|
pe[TMU0_ID].pmem_size = TMU_IMEM_SIZE;
|
|
pe[TMU0_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
|
|
pe[TMU0_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
|
|
pe[TMU0_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
|
|
|
|
pe[TMU1_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(1);
|
|
pe[TMU1_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(1);
|
|
pe[TMU1_ID].pmem_size = TMU_IMEM_SIZE;
|
|
pe[TMU1_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
|
|
pe[TMU1_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
|
|
pe[TMU1_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
|
|
|
|
pe[TMU3_ID].dmem_base_addr = TMU_DMEM_BASE_ADDR(3);
|
|
pe[TMU3_ID].pmem_base_addr = TMU_IMEM_BASE_ADDR(3);
|
|
pe[TMU3_ID].pmem_size = TMU_IMEM_SIZE;
|
|
pe[TMU3_ID].mem_access_wdata = TMU_MEM_ACCESS_WDATA;
|
|
pe[TMU3_ID].mem_access_addr = TMU_MEM_ACCESS_ADDR;
|
|
pe[TMU3_ID].mem_access_rdata = TMU_MEM_ACCESS_RDATA;
|
|
|
|
#if !defined(CONFIG_FSL_PFE_UTIL_DISABLED)
|
|
pe[UTIL_ID].dmem_base_addr = UTIL_DMEM_BASE_ADDR;
|
|
pe[UTIL_ID].mem_access_wdata = UTIL_MEM_ACCESS_WDATA;
|
|
pe[UTIL_ID].mem_access_addr = UTIL_MEM_ACCESS_ADDR;
|
|
pe[UTIL_ID].mem_access_rdata = UTIL_MEM_ACCESS_RDATA;
|
|
#endif
|
|
}
|
|
|
|
/**************************** MTIP GEMAC ***************************/
|
|
|
|
/* Enable Rx Checksum Engine. With this enabled, Frame with bad IP,
|
|
* TCP or UDP checksums are discarded
|
|
*
|
|
* @param[in] base GEMAC base address.
|
|
*/
|
|
void
|
|
gemac_enable_rx_checksum_offload(__rte_unused void *base)
|
|
{
|
|
/*Do not find configuration to do this */
|
|
}
|
|
|
|
/* Disable Rx Checksum Engine.
|
|
*
|
|
* @param[in] base GEMAC base address.
|
|
*/
|
|
void
|
|
gemac_disable_rx_checksum_offload(__rte_unused void *base)
|
|
{
|
|
/*Do not find configuration to do this */
|
|
}
|
|
|
|
/* GEMAC set speed.
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] speed GEMAC speed (10, 100 or 1000 Mbps)
|
|
*/
|
|
void
|
|
gemac_set_speed(void *base, enum mac_speed gem_speed)
|
|
{
|
|
u32 ecr = readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_SPEED;
|
|
u32 rcr = readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_RMII_10T;
|
|
|
|
switch (gem_speed) {
|
|
case SPEED_10M:
|
|
rcr |= EMAC_RCNTRL_RMII_10T;
|
|
break;
|
|
|
|
case SPEED_1000M:
|
|
ecr |= EMAC_ECNTRL_SPEED;
|
|
break;
|
|
|
|
case SPEED_100M:
|
|
default:
|
|
/*It is in 100M mode */
|
|
break;
|
|
}
|
|
writel(ecr, (base + EMAC_ECNTRL_REG));
|
|
writel(rcr, (base + EMAC_RCNTRL_REG));
|
|
}
|
|
|
|
/* GEMAC set duplex.
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] duplex GEMAC duplex mode (Full, Half)
|
|
*/
|
|
void
|
|
gemac_set_duplex(void *base, int duplex)
|
|
{
|
|
if (duplex == DUPLEX_HALF) {
|
|
writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_FDEN, base
|
|
+ EMAC_TCNTRL_REG);
|
|
writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_DRT, (base
|
|
+ EMAC_RCNTRL_REG));
|
|
} else {
|
|
writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_FDEN, base
|
|
+ EMAC_TCNTRL_REG);
|
|
writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_DRT, (base
|
|
+ EMAC_RCNTRL_REG));
|
|
}
|
|
}
|
|
|
|
/* GEMAC set mode.
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] mode GEMAC operation mode (MII, RMII, RGMII, SGMII)
|
|
*/
|
|
void
|
|
gemac_set_mode(void *base, __rte_unused int mode)
|
|
{
|
|
u32 val = readl(base + EMAC_RCNTRL_REG);
|
|
|
|
/* Remove loopback */
|
|
val &= ~EMAC_RCNTRL_LOOP;
|
|
|
|
/*Enable flow control and MII mode*/
|
|
val |= (EMAC_RCNTRL_FCE | EMAC_RCNTRL_MII_MODE | EMAC_RCNTRL_CRC_FWD);
|
|
|
|
writel(val, base + EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC enable function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable(void *base)
|
|
{
|
|
writel(readl(base + EMAC_ECNTRL_REG) | EMAC_ECNTRL_ETHER_EN, base +
|
|
EMAC_ECNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC disable function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_disable(void *base)
|
|
{
|
|
writel(readl(base + EMAC_ECNTRL_REG) & ~EMAC_ECNTRL_ETHER_EN, base +
|
|
EMAC_ECNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC TX disable function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_tx_disable(void *base)
|
|
{
|
|
writel(readl(base + EMAC_TCNTRL_REG) | EMAC_TCNTRL_GTS, base +
|
|
EMAC_TCNTRL_REG);
|
|
}
|
|
|
|
void
|
|
gemac_tx_enable(void *base)
|
|
{
|
|
writel(readl(base + EMAC_TCNTRL_REG) & ~EMAC_TCNTRL_GTS, base +
|
|
EMAC_TCNTRL_REG);
|
|
}
|
|
|
|
/* Sets the hash register of the MAC.
|
|
* This register is used for matching unicast and multicast frames.
|
|
*
|
|
* @param[in] base GEMAC base address.
|
|
* @param[in] hash 64-bit hash to be configured.
|
|
*/
|
|
void
|
|
gemac_set_hash(void *base, struct pfe_mac_addr *hash)
|
|
{
|
|
writel(hash->bottom, base + EMAC_GALR);
|
|
writel(hash->top, base + EMAC_GAUR);
|
|
}
|
|
|
|
void
|
|
gemac_set_laddrN(void *base, struct pfe_mac_addr *address,
|
|
unsigned int entry_index)
|
|
{
|
|
if (entry_index < 1 || entry_index > EMAC_SPEC_ADDR_MAX)
|
|
return;
|
|
|
|
entry_index = entry_index - 1;
|
|
if (entry_index < 1) {
|
|
writel(htonl(address->bottom), base + EMAC_PHY_ADDR_LOW);
|
|
writel((htonl(address->top) | 0x8808), base +
|
|
EMAC_PHY_ADDR_HIGH);
|
|
} else {
|
|
writel(htonl(address->bottom), base + ((entry_index - 1) * 8)
|
|
+ EMAC_SMAC_0_0);
|
|
writel((htonl(address->top) | 0x8808), base + ((entry_index -
|
|
1) * 8) + EMAC_SMAC_0_1);
|
|
}
|
|
}
|
|
|
|
void
|
|
gemac_clear_laddrN(void *base, unsigned int entry_index)
|
|
{
|
|
if (entry_index < 1 || entry_index > EMAC_SPEC_ADDR_MAX)
|
|
return;
|
|
|
|
entry_index = entry_index - 1;
|
|
if (entry_index < 1) {
|
|
writel(0, base + EMAC_PHY_ADDR_LOW);
|
|
writel(0, base + EMAC_PHY_ADDR_HIGH);
|
|
} else {
|
|
writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_0);
|
|
writel(0, base + ((entry_index - 1) * 8) + EMAC_SMAC_0_1);
|
|
}
|
|
}
|
|
|
|
/* Set the loopback mode of the MAC. This can be either no loopback for
|
|
* normal operation, local loopback through MAC internal loopback module or PHY
|
|
* loopback for external loopback through a PHY. This asserts the external
|
|
* loop pin.
|
|
*
|
|
* @param[in] base GEMAC base address.
|
|
* @param[in] gem_loop Loopback mode to be enabled. LB_LOCAL - MAC
|
|
* Loopback,
|
|
* LB_EXT - PHY Loopback.
|
|
*/
|
|
void
|
|
gemac_set_loop(void *base, __rte_unused enum mac_loop gem_loop)
|
|
{
|
|
pr_info("%s()\n", __func__);
|
|
writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_LOOP, (base +
|
|
EMAC_RCNTRL_REG));
|
|
}
|
|
|
|
/* GEMAC allow frames
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_copy_all(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_PROM, (base +
|
|
EMAC_RCNTRL_REG));
|
|
}
|
|
|
|
/* GEMAC do not allow frames
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_disable_copy_all(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_PROM, (base +
|
|
EMAC_RCNTRL_REG));
|
|
}
|
|
|
|
/* GEMAC allow broadcast function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_allow_broadcast(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_BC_REJ, base +
|
|
EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC no broadcast function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_no_broadcast(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_BC_REJ, base +
|
|
EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC enable 1536 rx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_1536_rx(void *base)
|
|
{
|
|
/* Set 1536 as Maximum frame length */
|
|
writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK)
|
|
| (1536 << 16),
|
|
base + EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC set Max rx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
int
|
|
gemac_set_rx(void *base, int mtu)
|
|
{
|
|
if (mtu < HIF_RX_PKT_MIN_SIZE || mtu > JUMBO_FRAME_SIZE) {
|
|
PFE_PMD_ERR("Invalid or not support MTU size");
|
|
return -1;
|
|
}
|
|
|
|
if (pfe_svr == SVR_LS1012A_REV1 &&
|
|
mtu > (MAX_MTU_ON_REV1 + PFE_ETH_OVERHEAD)) {
|
|
PFE_PMD_ERR("Max supported MTU on Rev1 is %d", MAX_MTU_ON_REV1);
|
|
return -1;
|
|
}
|
|
|
|
writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK)
|
|
| (mtu << 16),
|
|
base + EMAC_RCNTRL_REG);
|
|
return 0;
|
|
}
|
|
|
|
/* GEMAC enable jumbo function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_rx_jmb(void *base)
|
|
{
|
|
if (pfe_svr == SVR_LS1012A_REV1) {
|
|
PFE_PMD_ERR("Jumbo not supported on Rev1");
|
|
return;
|
|
}
|
|
|
|
writel((readl(base + EMAC_RCNTRL_REG) & PFE_MTU_RESET_MASK) |
|
|
(JUMBO_FRAME_SIZE << 16), base + EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC enable stacked vlan function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_stacked_vlan(__rte_unused void *base)
|
|
{
|
|
/* MTIP doesn't support stacked vlan */
|
|
}
|
|
|
|
/* GEMAC enable pause rx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_pause_rx(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) | EMAC_RCNTRL_FCE,
|
|
base + EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC disable pause rx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_disable_pause_rx(void *base)
|
|
{
|
|
writel(readl(base + EMAC_RCNTRL_REG) & ~EMAC_RCNTRL_FCE,
|
|
base + EMAC_RCNTRL_REG);
|
|
}
|
|
|
|
/* GEMAC enable pause tx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_enable_pause_tx(void *base)
|
|
{
|
|
writel(EMAC_RX_SECTION_EMPTY_V, base + EMAC_RX_SECTION_EMPTY);
|
|
}
|
|
|
|
/* GEMAC disable pause tx function.
|
|
* @param[in] base GEMAC base address
|
|
*/
|
|
void
|
|
gemac_disable_pause_tx(void *base)
|
|
{
|
|
writel(0x0, base + EMAC_RX_SECTION_EMPTY);
|
|
}
|
|
|
|
/* GEMAC wol configuration
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] wol_conf WoL register configuration
|
|
*/
|
|
void
|
|
gemac_set_wol(void *base, u32 wol_conf)
|
|
{
|
|
u32 val = readl(base + EMAC_ECNTRL_REG);
|
|
|
|
if (wol_conf)
|
|
val |= (EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
|
|
else
|
|
val &= ~(EMAC_ECNTRL_MAGIC_ENA | EMAC_ECNTRL_SLEEP);
|
|
writel(val, base + EMAC_ECNTRL_REG);
|
|
}
|
|
|
|
/* Sets Gemac bus width to 64bit
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] width gemac bus width to be set possible values are 32/64/128
|
|
*/
|
|
void
|
|
gemac_set_bus_width(__rte_unused void *base, __rte_unused int width)
|
|
{
|
|
}
|
|
|
|
/* Sets Gemac configuration.
|
|
* @param[in] base GEMAC base address
|
|
* @param[in] cfg GEMAC configuration
|
|
*/
|
|
void
|
|
gemac_set_config(void *base, struct gemac_cfg *cfg)
|
|
{
|
|
/*GEMAC config taken from VLSI */
|
|
writel(0x00000004, base + EMAC_TFWR_STR_FWD);
|
|
writel(0x00000005, base + EMAC_RX_SECTION_FULL);
|
|
|
|
if (pfe_svr == SVR_LS1012A_REV1)
|
|
writel(0x00000768, base + EMAC_TRUNC_FL);
|
|
else
|
|
writel(0x00003fff, base + EMAC_TRUNC_FL);
|
|
|
|
writel(0x00000030, base + EMAC_TX_SECTION_EMPTY);
|
|
writel(0x00000000, base + EMAC_MIB_CTRL_STS_REG);
|
|
|
|
gemac_set_mode(base, cfg->mode);
|
|
|
|
gemac_set_speed(base, cfg->speed);
|
|
|
|
gemac_set_duplex(base, cfg->duplex);
|
|
}
|
|
|
|
/**************************** GPI ***************************/
|
|
|
|
/* Initializes a GPI block.
|
|
* @param[in] base GPI base address
|
|
* @param[in] cfg GPI configuration
|
|
*/
|
|
void
|
|
gpi_init(void *base, struct gpi_cfg *cfg)
|
|
{
|
|
gpi_reset(base);
|
|
|
|
gpi_disable(base);
|
|
|
|
gpi_set_config(base, cfg);
|
|
}
|
|
|
|
/* Resets a GPI block.
|
|
* @param[in] base GPI base address
|
|
*/
|
|
void
|
|
gpi_reset(void *base)
|
|
{
|
|
writel(CORE_SW_RESET, base + GPI_CTRL);
|
|
}
|
|
|
|
/* Enables a GPI block.
|
|
* @param[in] base GPI base address
|
|
*/
|
|
void
|
|
gpi_enable(void *base)
|
|
{
|
|
writel(CORE_ENABLE, base + GPI_CTRL);
|
|
}
|
|
|
|
/* Disables a GPI block.
|
|
* @param[in] base GPI base address
|
|
*/
|
|
void
|
|
gpi_disable(void *base)
|
|
{
|
|
writel(CORE_DISABLE, base + GPI_CTRL);
|
|
}
|
|
|
|
/* Sets the configuration of a GPI block.
|
|
* @param[in] base GPI base address
|
|
* @param[in] cfg GPI configuration
|
|
*/
|
|
void
|
|
gpi_set_config(void *base, struct gpi_cfg *cfg)
|
|
{
|
|
writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_ALLOC_CTRL), base
|
|
+ GPI_LMEM_ALLOC_ADDR);
|
|
writel(CBUS_VIRT_TO_PFE(BMU1_BASE_ADDR + BMU_FREE_CTRL), base
|
|
+ GPI_LMEM_FREE_ADDR);
|
|
writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_ALLOC_CTRL), base
|
|
+ GPI_DDR_ALLOC_ADDR);
|
|
writel(CBUS_VIRT_TO_PFE(BMU2_BASE_ADDR + BMU_FREE_CTRL), base
|
|
+ GPI_DDR_FREE_ADDR);
|
|
writel(CBUS_VIRT_TO_PFE(CLASS_INQ_PKTPTR), base + GPI_CLASS_ADDR);
|
|
writel(DDR_HDR_SIZE, base + GPI_DDR_DATA_OFFSET);
|
|
writel(LMEM_HDR_SIZE, base + GPI_LMEM_DATA_OFFSET);
|
|
writel(0, base + GPI_LMEM_SEC_BUF_DATA_OFFSET);
|
|
writel(0, base + GPI_DDR_SEC_BUF_DATA_OFFSET);
|
|
writel((DDR_HDR_SIZE << 16) | LMEM_HDR_SIZE, base + GPI_HDR_SIZE);
|
|
writel((DDR_BUF_SIZE << 16) | LMEM_BUF_SIZE, base + GPI_BUF_SIZE);
|
|
|
|
writel(((cfg->lmem_rtry_cnt << 16) | (GPI_DDR_BUF_EN << 1) |
|
|
GPI_LMEM_BUF_EN), base + GPI_RX_CONFIG);
|
|
writel(cfg->tmlf_txthres, base + GPI_TMLF_TX);
|
|
writel(cfg->aseq_len, base + GPI_DTX_ASEQ);
|
|
writel(1, base + GPI_TOE_CHKSUM_EN);
|
|
|
|
if (cfg->mtip_pause_reg) {
|
|
writel(cfg->mtip_pause_reg, base + GPI_CSR_MTIP_PAUSE_REG);
|
|
writel(EGPI_PAUSE_TIME, base + GPI_TX_PAUSE_TIME);
|
|
}
|
|
}
|
|
|
|
/**************************** HIF ***************************/
|
|
/* Initializes HIF copy block.
|
|
*
|
|
*/
|
|
void
|
|
hif_init(void)
|
|
{
|
|
/*Initialize HIF registers*/
|
|
writel((HIF_RX_POLL_CTRL_CYCLE << 16) | HIF_TX_POLL_CTRL_CYCLE,
|
|
HIF_POLL_CTRL);
|
|
}
|
|
|
|
/* Enable hif tx DMA and interrupt
|
|
*
|
|
*/
|
|
void
|
|
hif_tx_enable(void)
|
|
{
|
|
writel(HIF_CTRL_DMA_EN, HIF_TX_CTRL);
|
|
writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_TXPKT_INT_EN),
|
|
HIF_INT_ENABLE);
|
|
}
|
|
|
|
/* Disable hif tx DMA and interrupt
|
|
*
|
|
*/
|
|
void
|
|
hif_tx_disable(void)
|
|
{
|
|
u32 hif_int;
|
|
|
|
writel(0, HIF_TX_CTRL);
|
|
|
|
hif_int = readl(HIF_INT_ENABLE);
|
|
hif_int &= HIF_TXPKT_INT_EN;
|
|
writel(hif_int, HIF_INT_ENABLE);
|
|
}
|
|
|
|
/* Enable hif rx DMA and interrupt
|
|
*
|
|
*/
|
|
void
|
|
hif_rx_enable(void)
|
|
{
|
|
hif_rx_dma_start();
|
|
writel((readl(HIF_INT_ENABLE) | HIF_INT_EN | HIF_RXPKT_INT_EN),
|
|
HIF_INT_ENABLE);
|
|
}
|
|
|
|
/* Disable hif rx DMA and interrupt
|
|
*
|
|
*/
|
|
void
|
|
hif_rx_disable(void)
|
|
{
|
|
u32 hif_int;
|
|
|
|
writel(0, HIF_RX_CTRL);
|
|
|
|
hif_int = readl(HIF_INT_ENABLE);
|
|
hif_int &= HIF_RXPKT_INT_EN;
|
|
writel(hif_int, HIF_INT_ENABLE);
|
|
}
|