代码拉取完成,页面将自动刷新
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
* stmmac HW Interface Handling
*/
#include "common.h"
#include "stmmac.h"
#include "stmmac_ptp.h"
static u32 stmmac_get_id(struct stmmac_priv *priv, u32 id_reg)
{
u32 reg = readl(priv->ioaddr + id_reg);
if (!reg) {
dev_info(priv->device, "Version ID not available\n");
return 0x0;
}
dev_info(priv->device, "User ID: 0x%x, Synopsys ID: 0x%x\n",
(unsigned int)(reg & GENMASK(15, 8)) >> 8,
(unsigned int)(reg & GENMASK(7, 0)));
return reg & GENMASK(7, 0);
}
#ifdef CONFIG_STMMAC_FULL
static void stmmac_dwmac_mode_quirk(struct stmmac_priv *priv)
{
struct mac_device_info *mac = priv->hw;
if (priv->chain_mode) {
dev_info(priv->device, "Chain mode enabled\n");
priv->mode = STMMAC_CHAIN_MODE;
mac->mode = &chain_mode_ops;
} else {
dev_info(priv->device, "Ring mode enabled\n");
priv->mode = STMMAC_RING_MODE;
mac->mode = &ring_mode_ops;
}
}
static int stmmac_dwmac1_quirks(struct stmmac_priv *priv)
{
struct mac_device_info *mac = priv->hw;
if (priv->plat->enh_desc) {
dev_info(priv->device, "Enhanced/Alternate descriptors\n");
/* GMAC older than 3.50 has no extended descriptors */
if (priv->synopsys_id >= DWMAC_CORE_3_50) {
dev_info(priv->device, "Enabled extended descriptors\n");
priv->extend_desc = 1;
} else {
dev_warn(priv->device, "Extended descriptors not supported\n");
}
mac->desc = &enh_desc_ops;
} else {
dev_info(priv->device, "Normal descriptors\n");
mac->desc = &ndesc_ops;
}
stmmac_dwmac_mode_quirk(priv);
return 0;
}
static int stmmac_dwmac4_quirks(struct stmmac_priv *priv)
{
stmmac_dwmac_mode_quirk(priv);
return 0;
}
#endif
static const struct stmmac_hwif_entry {
bool gmac;
bool gmac4;
bool xgmac;
u32 min_id;
const struct stmmac_regs_off regs;
const void *desc;
const void *dma;
const void *mac;
#ifdef CONFIG_STMMAC_PTP
const void *hwtimestamp;
#endif
const void *mode;
const void *tc;
int (*setup)(struct stmmac_priv *priv);
int (*quirks)(struct stmmac_priv *priv);
} stmmac_hw[] = {
{
.gmac = false,
.gmac4 = true,
.xgmac = false,
.min_id = DWMAC_CORE_4_00,
.regs = {
.ptp_off = PTP_GMAC4_OFFSET,
.mmc_off = MMC_GMAC4_OFFSET,
},
.desc = &dwmac4_desc_ops,
.dma = &dwmac4_dma_ops,
.mac = &dwmac410_ops,
#ifdef CONFIG_STMMAC_PTP
.hwtimestamp = &stmmac_ptp,
#endif
.mode = &dwmac4_ring_mode_ops,
.tc = NULL,
.setup = dwmac4_setup,
.quirks = NULL,
},
};
int stmmac_hwif_init(struct stmmac_priv *priv)
{
/* ok3568是has_gmac4, 所以我们这边其他的无关配置都删除掉
* 在 stmmac_probe_config_dt 中设置的, 根据compatible属性
* if (of_device_is_compatible(np, "snps,dwmac-4.20a")) {
* plat->has_gmac4 = 1;
* plat->has_gmac = 0;
* }
*/
bool needs_xgmac = priv->plat->has_xgmac;
bool needs_gmac4 = priv->plat->has_gmac4;
bool needs_gmac = priv->plat->has_gmac;
const struct stmmac_hwif_entry *entry;
struct mac_device_info *mac;
bool needs_setup = true;
int i, ret;
u32 id;
if (needs_gmac4 || needs_xgmac)
id = stmmac_get_id(priv, GMAC4_VERSION);
/* Save ID for later use */
priv->synopsys_id = id;
/* 这边做成if else , 如果needs_gmac4 为0, 则返回错误 */
/* ptpaddr 和 mmcaddr 目前uk这边都不需要支持 */
priv->ptpaddr = priv->ioaddr +
(needs_gmac4 ? PTP_GMAC4_OFFSET : PTP_GMAC3_X_OFFSET);
priv->mmcaddr = priv->ioaddr +
(needs_gmac4 ? MMC_GMAC4_OFFSET : MMC_GMAC3_X_OFFSET);
/* Check for HW specific setup first */
if (priv->plat->setup) {
mac = priv->plat->setup(priv);
needs_setup = false;
} else {
mac = devm_kzalloc(priv->device, sizeof(*mac), GFP_KERNEL);
}
if (!mac)
return -ENOMEM;
/* Fallback to generic HW */
for (i = ARRAY_SIZE(stmmac_hw) - 1; i >= 0; i--) {
entry = &stmmac_hw[i];
if (needs_gmac ^ entry->gmac)
continue;
if (needs_gmac4 ^ entry->gmac4)
continue;
if (needs_xgmac ^ entry->xgmac)
continue;
/* Use synopsys_id var because some setups can override this */
/* priv->synopsys_id 是 0x51 */
if (priv->synopsys_id < entry->min_id)
continue;
/* Only use generic HW helpers if needed */
mac->desc = mac->desc ? : entry->desc;
mac->dma = mac->dma ? : entry->dma;
mac->mac = mac->mac ? : entry->mac;
#ifdef CONFIG_STMMAC_PTP
mac->ptp = mac->ptp ? : entry->hwtimestamp;
#endif
mac->mode = mac->mode ? : entry->mode;
mac->tc = mac->tc ? : entry->tc;
priv->hw = mac;
priv->ptpaddr = priv->ioaddr + entry->regs.ptp_off;
priv->mmcaddr = priv->ioaddr + entry->regs.mmc_off;
/* Entry found */
if (needs_setup) {
ret = entry->setup(priv);
if (ret)
return ret;
}
/* Save quirks, if needed for posterior use */
priv->hwif_quirks = entry->quirks;
return 0;
}
dev_err(priv->device, "Failed to find HW IF (id=0x%x, gmac=%d/%d)\n",
id, needs_gmac, needs_gmac4);
return -EINVAL;
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。