Squashed backup commit (no shallow-clone history issues) of xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2 branch, upstream commit 9eece662e) plus all fixes applied to get everpal_defconfig building clean against a modern (GCC 15.2.0) toolchain -- see the previous commit message on the lineage-23.2 branch (also in this repo history is not available here since this is a squashed snapshot; full incremental history lives in the local DL380 checkout and the upstream GitHub remote). Upstream: https://github.com/xiaomi-mt6833-dev/kernel_xiaomi_mt6833 (lineage-23.2)
548 lines
14 KiB
C
548 lines
14 KiB
C
/*
|
|
* Copyright (c) 2019 MediaTek Inc.
|
|
* Author: Zhiyong Tao <zhiyong.tao@mediatek.com>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*/
|
|
|
|
#include "star.h"
|
|
|
|
#ifdef CONFIG_ARM64
|
|
uintptr_t tx_skb_reserve[TX_DESC_NUM];
|
|
uintptr_t rx_skb_reserve[RX_DESC_NUM];
|
|
#endif
|
|
|
|
u16 star_mdc_mdio_read(star_dev *dev, u32 phy_addr, u32 phy_reg)
|
|
{
|
|
u16 data;
|
|
u32 phy_ctl;
|
|
void __iomem *base = dev->base;
|
|
|
|
/* Clear previous read/write OK status (write 1 clear) */
|
|
star_set_reg(STAR_PHY_CTRL0(base), STAR_PHY_CTRL0_RWOK);
|
|
phy_ctl = (phy_addr & STAR_PHY_CTRL0_PA_MASK)
|
|
<< STAR_PHY_CTRL0_PA_OFFSET |
|
|
(phy_reg & STAR_PHY_CTRL0_PREG_MASK)
|
|
<< STAR_PHY_CTRL0_PREG_OFFSET |
|
|
STAR_PHY_CTRL0_RDCMD;
|
|
star_mb();
|
|
star_set_reg(STAR_PHY_CTRL0(base), phy_ctl);
|
|
star_mb();
|
|
|
|
STAR_POLLING_TIMEOUT(star_is_set_bit(STAR_PHY_CTRL0(base),
|
|
STAR_PHY_CTRL0_RWOK));
|
|
star_mb();
|
|
data = (u16)star_get_bit_mask(STAR_PHY_CTRL0(base),
|
|
STAR_PHY_CTRL0_RWDATA_MASK,
|
|
STAR_PHY_CTRL0_RWDATA_OFFSET);
|
|
|
|
return data;
|
|
}
|
|
|
|
void star_mdc_mdio_write(star_dev *dev, u32 phy_addr, u32 phy_reg, u16 value)
|
|
{
|
|
u32 phy_ctl;
|
|
void __iomem *base = dev->base;
|
|
|
|
/* Clear previous read/write OK status (write 1 clear) */
|
|
star_set_reg(STAR_PHY_CTRL0(base), STAR_PHY_CTRL0_RWOK);
|
|
phy_ctl = ((value & STAR_PHY_CTRL0_RWDATA_MASK)
|
|
<< STAR_PHY_CTRL0_RWDATA_OFFSET) |
|
|
((phy_addr & STAR_PHY_CTRL0_PA_MASK)
|
|
<< STAR_PHY_CTRL0_PA_OFFSET) |
|
|
((phy_reg & STAR_PHY_CTRL0_PREG_MASK)
|
|
<< STAR_PHY_CTRL0_PREG_OFFSET) |
|
|
STAR_PHY_CTRL0_WTCMD;
|
|
star_mb();
|
|
star_set_reg(STAR_PHY_CTRL0(base), phy_ctl);
|
|
star_mb();
|
|
STAR_POLLING_TIMEOUT(star_is_set_bit(STAR_PHY_CTRL0(base),
|
|
STAR_PHY_CTRL0_RWOK));
|
|
}
|
|
|
|
static void desc_tx_init(tx_desc *tx_desc, u32 is_eor)
|
|
{
|
|
tx_desc->buffer = 0;
|
|
tx_desc->ctrl_len = TX_COWN | (is_eor ? TX_EOR : 0);
|
|
tx_desc->vtag = 0;
|
|
tx_desc->reserve = 0;
|
|
}
|
|
|
|
static void desc_rx_init(rx_desc *rx_desc, u32 is_eor)
|
|
{
|
|
rx_desc->buffer = 0;
|
|
rx_desc->ctrl_len = RX_COWN | (is_eor ? RX_EOR : 0);
|
|
rx_desc->vtag = 0;
|
|
rx_desc->reserve = 0;
|
|
}
|
|
|
|
u32 desc_tx_empty(tx_desc *tx_desc)
|
|
{
|
|
return (((tx_desc)->buffer == 0) &&
|
|
(((tx_desc)->ctrl_len & ~TX_EOR) == TX_COWN) &&
|
|
((tx_desc)->vtag == 0) &&
|
|
((tx_desc)->reserve == 0));
|
|
}
|
|
|
|
u32 desc_rx_empty(rx_desc *rx_desc)
|
|
{
|
|
return (((rx_desc)->buffer == 0) &&
|
|
(((rx_desc)->ctrl_len & ~RX_EOR) == RX_COWN) &&
|
|
((rx_desc)->vtag == 0) &&
|
|
((rx_desc)->reserve == 0));
|
|
}
|
|
|
|
static void desc_tx_take(tx_desc *tx_desc)
|
|
{
|
|
if (desc_tx_dma(tx_desc))
|
|
tx_desc->ctrl_len |= TX_COWN;
|
|
}
|
|
|
|
static void desc_rx_take(rx_desc *rx_desc)
|
|
{
|
|
if (desc_rx_dma(rx_desc))
|
|
rx_desc->ctrl_len |= RX_COWN;
|
|
}
|
|
|
|
int star_dma_init(star_dev *dev, uintptr_t desc_viraddr,
|
|
dma_addr_t desc_dmaaddrdr)
|
|
{
|
|
int i;
|
|
void __iomem *base = dev->base;
|
|
|
|
STAR_PR_DEBUG("%s virAddr=0x%lx\n", __func__, desc_viraddr);
|
|
dev->tx_ring_size = TX_DESC_NUM;
|
|
dev->rx_ring_size = RX_DESC_NUM;
|
|
|
|
dev->tx_desc = (tx_desc *)desc_viraddr;
|
|
dev->rx_desc = (rx_desc *)dev->tx_desc + dev->tx_ring_size;
|
|
|
|
for (i = 0; i < dev->tx_ring_size; i++)
|
|
desc_tx_init(dev->tx_desc + i, i == dev->tx_ring_size - 1);
|
|
for (i = 0; i < dev->rx_ring_size; i++)
|
|
desc_rx_init(dev->rx_desc + i, i == dev->rx_ring_size - 1);
|
|
|
|
dev->tx_head = 0;
|
|
dev->tx_tail = 0;
|
|
dev->rx_head = 0;
|
|
dev->rx_tail = 0;
|
|
dev->tx_num = 0;
|
|
dev->rx_num = 0;
|
|
|
|
/* Set Tx/Rx descriptor address */
|
|
star_set_reg(STAR_TX_BASE_ADDR(base), (u32)desc_dmaaddrdr);
|
|
star_set_reg(STAR_TX_DPTR(base), (u32)desc_dmaaddrdr);
|
|
star_set_reg(STAR_RX_BASE_ADDR(base),
|
|
(u32)desc_dmaaddrdr + sizeof(tx_desc) * dev->tx_ring_size);
|
|
star_set_reg(STAR_RX_DPTR(base),
|
|
(u32)desc_dmaaddrdr + sizeof(tx_desc) * dev->tx_ring_size);
|
|
|
|
star_intr_disable(dev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int star_dma_tx_set(star_dev *dev, u32 buffer, u32 length, uintptr_t ext_buf)
|
|
{
|
|
int is_tx_last;
|
|
int desc_idx = dev->tx_head;
|
|
tx_desc *tx_desc = dev->tx_desc + desc_idx;
|
|
u32 len = (((length < 60) ? 60 : length) & TX_LEN_MASK)
|
|
<< TX_LEN_OFFSET;
|
|
|
|
/* Error checking */
|
|
if (dev->tx_num == dev->tx_ring_size)
|
|
goto err;
|
|
/* descriptor is not empty - cannot set */
|
|
if (!desc_tx_empty(tx_desc))
|
|
goto err;
|
|
|
|
tx_desc->buffer = buffer;
|
|
tx_desc->ctrl_len |= len | TX_FS | TX_LS | TX_INT;
|
|
#ifdef CONFIG_ARM64
|
|
tx_skb_reserve[desc_idx] = ext_buf;
|
|
#else
|
|
tx_desc->reserve = ext_buf;
|
|
#endif
|
|
/* star memory barrier */
|
|
wmb();
|
|
/* Set HW own */
|
|
tx_desc->ctrl_len &= ~TX_COWN;
|
|
|
|
dev->tx_num++;
|
|
is_tx_last = desc_tx_last(tx_desc);
|
|
dev->tx_head = is_tx_last ? 0 : desc_idx + 1;
|
|
|
|
return desc_idx;
|
|
err:
|
|
return -1;
|
|
}
|
|
|
|
int star_dma_tx_get(star_dev *dev, u32 *buffer,
|
|
u32 *ctrl_len, uintptr_t *ext_buf)
|
|
{
|
|
int is_tx_last;
|
|
int desc_idx = dev->tx_tail;
|
|
tx_desc *tx_desc = dev->tx_desc + desc_idx;
|
|
|
|
if (dev->tx_num == 0)
|
|
goto err;
|
|
if (desc_tx_dma(tx_desc))
|
|
goto err;
|
|
if (desc_tx_empty(tx_desc))
|
|
goto err;
|
|
|
|
if (buffer != 0)
|
|
*buffer = tx_desc->buffer;
|
|
if (ctrl_len != 0)
|
|
*ctrl_len = tx_desc->ctrl_len;
|
|
|
|
#ifdef CONFIG_ARM64
|
|
if (ext_buf != 0)
|
|
*ext_buf = tx_skb_reserve[desc_idx];
|
|
#else
|
|
if (ext_buf != 0)
|
|
*ext_buf = tx_desc->reserve;
|
|
#endif
|
|
/* add star memory barrier */
|
|
rmb();
|
|
|
|
desc_tx_init(tx_desc, desc_tx_last(tx_desc));
|
|
dev->tx_num--;
|
|
is_tx_last = desc_tx_last(tx_desc);
|
|
dev->tx_tail = is_tx_last ? 0 : desc_idx + 1;
|
|
|
|
return desc_idx;
|
|
err:
|
|
return -1;
|
|
}
|
|
|
|
int star_dma_rx_set(star_dev *dev, u32 buffer, u32 length, uintptr_t ext_buf)
|
|
{
|
|
int desc_idx = dev->rx_head;
|
|
rx_desc *rx_desc = dev->rx_desc + desc_idx;
|
|
int is_rx_last;
|
|
|
|
/* Error checking */
|
|
if (dev->rx_num == dev->rx_ring_size)
|
|
goto err;
|
|
/* descriptor is not empty - cannot set */
|
|
if (!desc_rx_empty(rx_desc))
|
|
goto err;
|
|
|
|
rx_desc->buffer = buffer;
|
|
rx_desc->ctrl_len |= ((length & RX_LEN_MASK) << RX_LEN_OFFSET);
|
|
#ifdef CONFIG_ARM64
|
|
rx_skb_reserve[desc_idx] = ext_buf;
|
|
#else
|
|
rx_desc->reserve = ext_buf;
|
|
#endif
|
|
/* star memory barrier */
|
|
wmb();
|
|
/* Set HW own */
|
|
rx_desc->ctrl_len &= ~RX_COWN;
|
|
|
|
dev->rx_num++;
|
|
is_rx_last = desc_rx_last(rx_desc);
|
|
dev->rx_head = is_rx_last ? 0 : desc_idx + 1;
|
|
|
|
return desc_idx;
|
|
err:
|
|
return -1;
|
|
}
|
|
|
|
int star_dma_rx_get(star_dev *dev, u32 *buffer,
|
|
u32 *ctrl_len, uintptr_t *ext_buf)
|
|
{
|
|
int is_rx_last;
|
|
int desc_idx = dev->rx_tail;
|
|
rx_desc *rx_desc = dev->rx_desc + desc_idx;
|
|
|
|
/* Error checking */
|
|
/* No buffer can be got */
|
|
if (dev->rx_num == 0)
|
|
goto err;
|
|
/* descriptor is owned by DMA - cannot get */
|
|
if (desc_rx_dma(rx_desc))
|
|
goto err;
|
|
/* descriptor is empty - cannot get */
|
|
if (desc_rx_empty(rx_desc))
|
|
goto err;
|
|
|
|
if (buffer != 0)
|
|
*buffer = rx_desc->buffer;
|
|
if (ctrl_len != 0)
|
|
*ctrl_len = rx_desc->ctrl_len;
|
|
#ifdef CONFIG_ARM64
|
|
if (ext_buf != 0)
|
|
*ext_buf = rx_skb_reserve[desc_idx];
|
|
#else
|
|
if (ext_buf != 0)
|
|
*ext_buf = rx_desc->reserve;
|
|
#endif
|
|
/* star memory barrier */
|
|
rmb();
|
|
|
|
desc_rx_init(rx_desc, desc_rx_last(rx_desc));
|
|
dev->rx_num--;
|
|
is_rx_last = desc_rx_last(rx_desc);
|
|
dev->rx_tail = is_rx_last ? 0 : desc_idx + 1;
|
|
|
|
return desc_idx;
|
|
err:
|
|
return -1;
|
|
}
|
|
|
|
void star_dma_tx_stop(star_dev *dev)
|
|
{
|
|
int i;
|
|
|
|
star_dma_tx_disable(dev);
|
|
for (i = 0; i < dev->tx_ring_size; i++)
|
|
desc_tx_take(dev->tx_desc + i);
|
|
}
|
|
|
|
void star_dma_rx_stop(star_dev *dev)
|
|
{
|
|
int i;
|
|
|
|
star_dma_rx_disable(dev);
|
|
for (i = 0; i < dev->rx_ring_size; i++)
|
|
desc_rx_take(dev->rx_desc + i);
|
|
}
|
|
|
|
int star_mac_init(star_dev *dev, u8 mac_addr[6])
|
|
{
|
|
void __iomem *base = dev->base;
|
|
|
|
STAR_PR_DEBUG("MAC Initialization\n");
|
|
|
|
/* Set Mac Address */
|
|
star_set_reg(star_my_mac_h(base),
|
|
mac_addr[0] << 8 | mac_addr[1] << 0);
|
|
star_set_reg(star_my_mac_l(base),
|
|
mac_addr[2] << 24 | mac_addr[3] << 16 |
|
|
mac_addr[4] << 8 | mac_addr[5] << 0);
|
|
|
|
/* Set Mac Configuration */
|
|
star_set_reg(STAR_MAC_CFG(base),
|
|
STAR_MAC_CFG_CRCSTRIP |
|
|
STAR_MAC_CFG_MAXLEN_1522 |
|
|
/* 12 byte IPG */
|
|
(0x1f & STAR_MAC_CFG_IPG_MASK) << STAR_MAC_CFG_IPG_OFFSET);
|
|
|
|
/* Init Flow Control register */
|
|
star_set_reg(STAR_FC_CFG(base),
|
|
STAR_FC_CFG_SEND_PAUSE_TH_DEF |
|
|
STAR_FC_CFG_UCPAUSEDIS |
|
|
STAR_FC_CFG_BPEN);
|
|
|
|
/* Init SEND_PAUSE_RLS */
|
|
star_set_reg(star_extend_cfg(base), STAR_EXTEND_CFG_SEND_PAUSE_RLS_DEF);
|
|
|
|
/* Init MIB counter (reset to 0) */
|
|
star_mib_init(dev);
|
|
|
|
/* Enable Hash Table BIST */
|
|
star_set_bit(star_hash_ctrl(base), STAR_HASH_CTRL_HASHEN);
|
|
|
|
/* Reset Hash Table (All reset to 0) */
|
|
star_reset_hash_table(dev);
|
|
star_clear_bit(STAR_ARL_CFG(base), STAR_ARL_CFG_MISCMODE);
|
|
star_clear_bit(STAR_ARL_CFG(base), STAR_ARL_CFG_HASHALG_CRCDA);
|
|
|
|
/*Recv VLAN tag in RX packet */
|
|
star_clear_bit(STAR_MAC_CFG(base), STAR_MAC_CFG_VLANSTRIP);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void star_mib_reset(star_dev *dev)
|
|
{
|
|
void __iomem *base = dev->base;
|
|
|
|
star_get_reg(STAR_MIB_RXOKPKT(base));
|
|
star_get_reg(STAR_MIB_RXOKBYTE(base));
|
|
star_get_reg(STAR_MIB_RXRUNT(base));
|
|
star_get_reg(STAR_MIB_RXOVERSIZE(base));
|
|
star_get_reg(STAR_MIB_RXNOBUFDROP(base));
|
|
star_get_reg(STAR_MIB_RXCRCERR(base));
|
|
star_get_reg(STAR_MIB_RXARLDROP(base));
|
|
star_get_reg(STAR_MIB_RXVLANDROP(base));
|
|
star_get_reg(STAR_MIB_RXCKSERR(base));
|
|
star_get_reg(STAR_MIB_RXPAUSE(base));
|
|
star_get_reg(STAR_MIB_TXOKPKT(base));
|
|
star_get_reg(STAR_MIB_TXOKBYTE(base));
|
|
star_get_reg(STAR_MIB_TXPAUSECOL(base));
|
|
}
|
|
|
|
int star_mib_init(star_dev *dev)
|
|
{
|
|
star_mib_reset(dev);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int star_phyctrl_init(star_dev *dev, u32 enable, u32 phy_addr)
|
|
{
|
|
u32 data;
|
|
void __iomem *base = dev->base;
|
|
|
|
data = STAR_PHY_CTRL1_FORCETXFC |
|
|
STAR_PHY_CTRL1_FORCERXFC |
|
|
STAR_PHY_CTRL1_FORCEFULL |
|
|
STAR_PHY_CTRL1_FORCESPD_100M |
|
|
STAR_PHY_CTRL1_ANEN;
|
|
|
|
STAR_PR_DEBUG("PHY Control Initialization\n");
|
|
/* Enable/Disable PHY auto-polling */
|
|
if (enable)
|
|
star_set_reg(STAR_PHY_CTRL1(base),
|
|
data | STAR_PHY_CTRL1_APEN |
|
|
(phy_addr &
|
|
STAR_PHY_CTRL1_phy_addr_MASK)
|
|
<< STAR_PHY_CTRL1_phy_addr_OFFSET);
|
|
else
|
|
star_set_reg(STAR_PHY_CTRL1(base), data | STAR_PHY_CTRL1_APDIS);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void star_set_hashbit(star_dev *dev, u32 addr, u32 value)
|
|
{
|
|
u32 data;
|
|
void __iomem *base = dev->base;
|
|
|
|
STAR_POLLING_TIMEOUT(star_is_set_bit(star_hash_ctrl(base),
|
|
STAR_HASH_CTRL_HTBISTDONE));
|
|
STAR_POLLING_TIMEOUT(star_is_set_bit(star_hash_ctrl(base),
|
|
STAR_HASH_CTRL_HTBISTOK));
|
|
STAR_POLLING_TIMEOUT(!star_is_set_bit(star_hash_ctrl(base),
|
|
STAR_HASH_CTRL_START));
|
|
|
|
data = (STAR_HASH_CTRL_HASHEN |
|
|
STAR_HASH_CTRL_ACCESSWT | STAR_HASH_CTRL_START |
|
|
(value ? STAR_HASH_CTRL_HBITDATA : 0) |
|
|
(addr & STAR_HASH_CTRL_HBITADDR_MASK)
|
|
<< STAR_HASH_CTRL_HBITADDR_OFFSET);
|
|
star_set_reg(star_hash_ctrl(base), data);
|
|
STAR_POLLING_TIMEOUT(!star_is_set_bit(star_hash_ctrl(base),
|
|
STAR_HASH_CTRL_START));
|
|
}
|
|
|
|
int star_hw_init(star_dev *dev)
|
|
{
|
|
star_set_reg(ETHSYS_CONFIG(dev->base),
|
|
SWC_MII_MODE | EXT_MDC_MODE | MII_PAD_OE);
|
|
star_set_reg(MAC_CLOCK_CONFIG(dev->base),
|
|
(star_get_reg(MAC_CLOCK_CONFIG(dev->base)) &
|
|
(~(0xff << 0))) | MDC_CLK_DIV_10);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void star_link_status_change(star_dev *dev)
|
|
{
|
|
u32 val, speed;
|
|
|
|
val = star_get_reg(STAR_PHY_CTRL1(dev->base));
|
|
if (dev->link_up != ((val & STAR_PHY_CTRL1_STA_LINK) ? 1UL : 0UL)) {
|
|
dev->link_up = (val & STAR_PHY_CTRL1_STA_LINK) ? 1UL : 0UL;
|
|
STAR_PR_INFO("Link status: %s\n",
|
|
dev->link_up ? "Up" : "Down");
|
|
if (dev->link_up == 1UL) {
|
|
speed = ((val >> STAR_PHY_CTRL1_STA_SPD_OFFSET) &
|
|
STAR_PHY_CTRL1_STA_SPD_MASK);
|
|
STAR_PR_INFO("%s Duplex - %s Mbps mode\n",
|
|
(val & STAR_PHY_CTRL1_STA_FULL) ?
|
|
"Full" : "Half",
|
|
!speed ? "10" : (speed == 1 ? "100" :
|
|
(speed == 2 ? "1000" : "unknown")));
|
|
STAR_PR_INFO(
|
|
"TX flow control:%s, RX flow control:%s\n",
|
|
(val & STAR_PHY_CTRL1_STA_TXFC) ? "On" : "Off",
|
|
(val & STAR_PHY_CTRL1_STA_RXFC) ? "On" : "Off");
|
|
} else if (dev->link_up == 0UL) {
|
|
netif_carrier_off(((star_private *)dev->star_prv)->dev);
|
|
}
|
|
}
|
|
|
|
if (dev->link_up)
|
|
netif_carrier_on(((star_private *)dev->star_prv)->dev);
|
|
}
|
|
|
|
void star_nic_pdset(star_dev *dev, bool flag)
|
|
{
|
|
#define MAX_NICPDRDY_RETRY 10000
|
|
u32 data, retry = 0;
|
|
|
|
data = star_get_reg(STAR_MAC_CFG(dev->base));
|
|
if (flag) {
|
|
data |= STAR_MAC_CFG_NICPD;
|
|
star_set_reg(STAR_MAC_CFG(dev->base), data);
|
|
/* wait until NIC_PD_READY and clear it */
|
|
do {
|
|
data = star_get_reg(STAR_MAC_CFG(dev->base));
|
|
if (data & STAR_MAC_CFG_NICPDRDY) {
|
|
/* clear NIC_PD_READY */
|
|
data |= STAR_MAC_CFG_NICPDRDY;
|
|
star_set_reg(STAR_MAC_CFG(dev->base), data);
|
|
break;
|
|
}
|
|
} while (retry++ < MAX_NICPDRDY_RETRY);
|
|
if (retry >= MAX_NICPDRDY_RETRY)
|
|
STAR_PR_ERR("timeout MAX_NICPDRDY_RETRY(%d)\n",
|
|
MAX_NICPDRDY_RETRY);
|
|
} else {
|
|
data &= ~STAR_MAC_CFG_NICPD;
|
|
star_set_reg(STAR_MAC_CFG(dev->base), data);
|
|
}
|
|
}
|
|
|
|
void star_config_wol(star_dev *star_dev, bool enable)
|
|
{
|
|
STAR_PR_INFO("[%s]%s wol\n", __func__,
|
|
enable ? "enable" : "disable");
|
|
if (enable) {
|
|
star_set_reg(star_int_sta(star_dev->base),
|
|
star_get_reg(star_int_sta(star_dev->base)));
|
|
star_set_bit(STAR_MAC_CFG(star_dev->base), STAR_MAC_CFG_WOLEN);
|
|
star_mb();
|
|
star_clear_bit(star_int_mask(star_dev->base),
|
|
STAR_INT_STA_MAGICPKT);
|
|
} else {
|
|
star_clear_bit(STAR_MAC_CFG(star_dev->base),
|
|
STAR_MAC_CFG_WOLEN);
|
|
star_mb();
|
|
star_set_bit(star_int_mask(star_dev->base),
|
|
STAR_INT_STA_MAGICPKT);
|
|
}
|
|
}
|
|
|
|
void star_switch_to_rmii_mode(star_dev *star_dev)
|
|
{
|
|
u32 reg_val;
|
|
|
|
reg_val = star_get_reg(star_dev->pericfg_base + 0x10);
|
|
reg_val &= ~(0xf << 0);
|
|
/* select RMII mode */
|
|
reg_val |= (0x1 << 0);
|
|
star_set_reg(star_dev->pericfg_base + 0x10, reg_val);
|
|
|
|
#ifdef STAR_USE_TX_CLOCK
|
|
reg_val = star_get_reg(star_dev->pericfg_base + 0x10);
|
|
reg_val &= ~(0x1 << 8);
|
|
/* select tx clock */
|
|
reg_val |= (0x1 << 8);
|
|
star_set_reg(star_dev->pericfg_base + 0x10, reg_val);
|
|
#endif
|
|
}
|
|
|