mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-27 11:06:41 -05:00
Merge branch 'net-bcmasp-add-v3-0-and-remove-v2-0'
Justin Chen says: ==================== net: bcmasp: Add v3.0 and remove v2.0 asp-v2.0 had one supported SoC that never saw the light of day. Given that it was the first iteration of the HW, it ended up with some one off HW design decisions that were changed in futher iterations of the HW. We remove support to simplify the code and make it easier to add future revisions. Add support for asp-v3.0. asp-v3.0 reduces the feature set for cost savings. We reduce the number of channel/network filters. And also remove some features and statistics. ==================== Link: https://patch.msgid.link/20250422233645.1931036-1-justin.chen@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
$id: http://devicetree.org/schemas/net/brcm,asp-v2.0.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Broadcom ASP 2.0 Ethernet controller
|
||||
title: Broadcom ASP Ethernet controller
|
||||
|
||||
maintainers:
|
||||
- Justin Chen <justin.chen@broadcom.com>
|
||||
@@ -15,6 +15,10 @@ description: Broadcom Ethernet controller first introduced with 72165
|
||||
properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm74110-asp
|
||||
- const: brcm,asp-v3.0
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm74165b0-asp
|
||||
@@ -23,10 +27,6 @@ properties:
|
||||
- enum:
|
||||
- brcm,bcm74165-asp
|
||||
- const: brcm,asp-v2.1
|
||||
- items:
|
||||
- enum:
|
||||
- brcm,bcm72165-asp
|
||||
- const: brcm,asp-v2.0
|
||||
|
||||
"#address-cells":
|
||||
const: 1
|
||||
@@ -39,11 +39,9 @@ properties:
|
||||
ranges: true
|
||||
|
||||
interrupts:
|
||||
minItems: 1
|
||||
items:
|
||||
- description: RX/TX interrupt
|
||||
- description: Port 0 Wake-on-LAN
|
||||
- description: Port 1 Wake-on-LAN
|
||||
- description: Wake-on-LAN interrupt
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
@@ -106,16 +104,17 @@ examples:
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
ethernet@9c00000 {
|
||||
compatible = "brcm,bcm72165-asp", "brcm,asp-v2.0";
|
||||
compatible = "brcm,bcm74165-asp", "brcm,asp-v2.1";
|
||||
reg = <0x9c00000 0x1fff14>;
|
||||
interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-extended = <&intc GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<&aon_pm_l2_intc 14>;
|
||||
ranges = <0x0 0x9c00000 0x1fff14>;
|
||||
clocks = <&scmi 14>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
mdio@c614 {
|
||||
compatible = "brcm,asp-v2.0-mdio";
|
||||
compatible = "brcm,asp-v2.1-mdio";
|
||||
reg = <0xc614 0x8>;
|
||||
reg-names = "mdio";
|
||||
#address-cells = <1>;
|
||||
@@ -127,7 +126,7 @@ examples:
|
||||
};
|
||||
|
||||
mdio@ce14 {
|
||||
compatible = "brcm,asp-v2.0-mdio";
|
||||
compatible = "brcm,asp-v2.1-mdio";
|
||||
reg = <0xce14 0x8>;
|
||||
reg-names = "mdio";
|
||||
#address-cells = <1>;
|
||||
|
||||
@@ -22,9 +22,9 @@ properties:
|
||||
- brcm,genet-mdio-v3
|
||||
- brcm,genet-mdio-v4
|
||||
- brcm,genet-mdio-v5
|
||||
- brcm,asp-v2.0-mdio
|
||||
- brcm,asp-v2.1-mdio
|
||||
- brcm,asp-v2.2-mdio
|
||||
- brcm,asp-v3.0-mdio
|
||||
- brcm,unimac-mdio
|
||||
- brcm,bcm6846-mdio
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ void bcmasp_flush_rx_port(struct bcmasp_intf *intf)
|
||||
return;
|
||||
}
|
||||
|
||||
rx_ctrl_core_wl(priv, mask, priv->hw_info->rx_ctrl_flush);
|
||||
rx_ctrl_core_wl(priv, mask, ASP_RX_CTRL_FLUSH);
|
||||
}
|
||||
|
||||
static void bcmasp_netfilt_hw_en_wake(struct bcmasp_priv *priv,
|
||||
@@ -518,7 +518,7 @@ void bcmasp_netfilt_suspend(struct bcmasp_intf *intf)
|
||||
int ret, i;
|
||||
|
||||
/* Write all filters to HW */
|
||||
for (i = 0; i < NUM_NET_FILTERS; i++) {
|
||||
for (i = 0; i < priv->num_net_filters; i++) {
|
||||
/* If the filter does not match the port, skip programming. */
|
||||
if (!priv->net_filters[i].claimed ||
|
||||
priv->net_filters[i].port != intf->port)
|
||||
@@ -551,7 +551,7 @@ int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
int j = 0, i;
|
||||
|
||||
for (i = 0; i < NUM_NET_FILTERS; i++) {
|
||||
for (i = 0; i < priv->num_net_filters; i++) {
|
||||
if (!priv->net_filters[i].claimed ||
|
||||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
@@ -577,7 +577,7 @@ int bcmasp_netfilt_get_active(struct bcmasp_intf *intf)
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
int cnt = 0, i;
|
||||
|
||||
for (i = 0; i < NUM_NET_FILTERS; i++) {
|
||||
for (i = 0; i < priv->num_net_filters; i++) {
|
||||
if (!priv->net_filters[i].claimed ||
|
||||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
@@ -602,7 +602,7 @@ bool bcmasp_netfilt_check_dup(struct bcmasp_intf *intf,
|
||||
size_t fs_size = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_NET_FILTERS; i++) {
|
||||
for (i = 0; i < priv->num_net_filters; i++) {
|
||||
if (!priv->net_filters[i].claimed ||
|
||||
priv->net_filters[i].port != intf->port)
|
||||
continue;
|
||||
@@ -670,7 +670,7 @@ struct bcmasp_net_filter *bcmasp_netfilt_get_init(struct bcmasp_intf *intf,
|
||||
int i, open_index = -1;
|
||||
|
||||
/* Check whether we exceed the filter table capacity */
|
||||
if (loc != RX_CLS_LOC_ANY && loc >= NUM_NET_FILTERS)
|
||||
if (loc != RX_CLS_LOC_ANY && loc >= priv->num_net_filters)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* If the filter location is busy (already claimed) and we are initializing
|
||||
@@ -686,7 +686,7 @@ struct bcmasp_net_filter *bcmasp_netfilt_get_init(struct bcmasp_intf *intf,
|
||||
/* Initialize the loop index based on the desired location or from 0 */
|
||||
i = loc == RX_CLS_LOC_ANY ? 0 : loc;
|
||||
|
||||
for ( ; i < NUM_NET_FILTERS; i++) {
|
||||
for ( ; i < priv->num_net_filters; i++) {
|
||||
/* Found matching network filter */
|
||||
if (!init &&
|
||||
priv->net_filters[i].claimed &&
|
||||
@@ -779,7 +779,7 @@ static void bcmasp_en_mda_filter(struct bcmasp_intf *intf, bool en,
|
||||
priv->mda_filters[i].en = en;
|
||||
priv->mda_filters[i].port = intf->port;
|
||||
|
||||
rx_filter_core_wl(priv, ((intf->channel + 8) |
|
||||
rx_filter_core_wl(priv, ((intf->channel + priv->tx_chan_offset) |
|
||||
(en << ASP_RX_FILTER_MDA_CFG_EN_SHIFT) |
|
||||
ASP_RX_FILTER_MDA_CFG_UMC_SEL(intf->port)),
|
||||
ASP_RX_FILTER_MDA_CFG(i));
|
||||
@@ -865,7 +865,7 @@ void bcmasp_disable_all_filters(struct bcmasp_intf *intf)
|
||||
res_count = bcmasp_total_res_mda_cnt(intf->parent);
|
||||
|
||||
/* Disable all filters held by this port */
|
||||
for (i = res_count; i < NUM_MDA_FILTERS; i++) {
|
||||
for (i = res_count; i < priv->num_mda_filters; i++) {
|
||||
if (priv->mda_filters[i].en &&
|
||||
priv->mda_filters[i].port == intf->port)
|
||||
bcmasp_en_mda_filter(intf, 0, i);
|
||||
@@ -909,7 +909,7 @@ int bcmasp_set_en_mda_filter(struct bcmasp_intf *intf, unsigned char *addr,
|
||||
|
||||
res_count = bcmasp_total_res_mda_cnt(intf->parent);
|
||||
|
||||
for (i = res_count; i < NUM_MDA_FILTERS; i++) {
|
||||
for (i = res_count; i < priv->num_mda_filters; i++) {
|
||||
/* If filter not enabled or belongs to another port skip */
|
||||
if (!priv->mda_filters[i].en ||
|
||||
priv->mda_filters[i].port != intf->port)
|
||||
@@ -924,7 +924,7 @@ int bcmasp_set_en_mda_filter(struct bcmasp_intf *intf, unsigned char *addr,
|
||||
}
|
||||
|
||||
/* Create new filter if possible */
|
||||
for (i = res_count; i < NUM_MDA_FILTERS; i++) {
|
||||
for (i = res_count; i < priv->num_mda_filters; i++) {
|
||||
if (priv->mda_filters[i].en)
|
||||
continue;
|
||||
|
||||
@@ -944,12 +944,12 @@ static void bcmasp_core_init_filters(struct bcmasp_priv *priv)
|
||||
/* Disable all filters and reset software view since the HW
|
||||
* can lose context while in deep sleep suspend states
|
||||
*/
|
||||
for (i = 0; i < NUM_MDA_FILTERS; i++) {
|
||||
for (i = 0; i < priv->num_mda_filters; i++) {
|
||||
rx_filter_core_wl(priv, 0x0, ASP_RX_FILTER_MDA_CFG(i));
|
||||
priv->mda_filters[i].en = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < NUM_NET_FILTERS; i++)
|
||||
for (i = 0; i < priv->num_net_filters; i++)
|
||||
rx_filter_core_wl(priv, 0x0, ASP_RX_FILTER_NET_CFG(i));
|
||||
|
||||
/* Top level filter enable bit should be enabled at all times, set
|
||||
@@ -966,18 +966,8 @@ static void bcmasp_core_init_filters(struct bcmasp_priv *priv)
|
||||
/* ASP core initialization */
|
||||
static void bcmasp_core_init(struct bcmasp_priv *priv)
|
||||
{
|
||||
tx_analytics_core_wl(priv, 0x0, ASP_TX_ANALYTICS_CTRL);
|
||||
rx_analytics_core_wl(priv, 0x4, ASP_RX_ANALYTICS_CTRL);
|
||||
|
||||
rx_edpkt_core_wl(priv, (ASP_EDPKT_HDR_SZ_128 << ASP_EDPKT_HDR_SZ_SHIFT),
|
||||
ASP_EDPKT_HDR_CFG);
|
||||
rx_edpkt_core_wl(priv,
|
||||
(ASP_EDPKT_ENDI_BT_SWP_WD << ASP_EDPKT_ENDI_DESC_SHIFT),
|
||||
ASP_EDPKT_ENDI);
|
||||
|
||||
rx_edpkt_core_wl(priv, 0x1b, ASP_EDPKT_BURST_BUF_PSCAL_TOUT);
|
||||
rx_edpkt_core_wl(priv, 0x3e8, ASP_EDPKT_BURST_BUF_WRITE_TOUT);
|
||||
rx_edpkt_core_wl(priv, 0x3e8, ASP_EDPKT_BURST_BUF_READ_TOUT);
|
||||
|
||||
rx_edpkt_core_wl(priv, ASP_EDPKT_ENABLE_EN, ASP_EDPKT_ENABLE);
|
||||
|
||||
@@ -1020,6 +1010,18 @@ static void bcmasp_core_clock_select_one(struct bcmasp_priv *priv, bool slow)
|
||||
ctrl_core_wl(priv, reg, ASP_CTRL_CORE_CLOCK_SELECT);
|
||||
}
|
||||
|
||||
static void bcmasp_core_clock_select_one_ctrl2(struct bcmasp_priv *priv, bool slow)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
reg = ctrl2_core_rl(priv, ASP_CTRL2_CORE_CLOCK_SELECT);
|
||||
if (slow)
|
||||
reg &= ~ASP_CTRL2_CORE_CLOCK_SELECT_MAIN;
|
||||
else
|
||||
reg |= ASP_CTRL2_CORE_CLOCK_SELECT_MAIN;
|
||||
ctrl2_core_wl(priv, reg, ASP_CTRL2_CORE_CLOCK_SELECT);
|
||||
}
|
||||
|
||||
static void bcmasp_core_clock_set_ll(struct bcmasp_priv *priv, u32 clr, u32 set)
|
||||
{
|
||||
u32 reg;
|
||||
@@ -1108,7 +1110,7 @@ static int bcmasp_get_and_request_irq(struct bcmasp_priv *priv, int i)
|
||||
return irq;
|
||||
}
|
||||
|
||||
static void bcmasp_init_wol_shared(struct bcmasp_priv *priv)
|
||||
static void bcmasp_init_wol(struct bcmasp_priv *priv)
|
||||
{
|
||||
struct platform_device *pdev = priv->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -1125,7 +1127,7 @@ static void bcmasp_init_wol_shared(struct bcmasp_priv *priv)
|
||||
device_set_wakeup_capable(&pdev->dev, 1);
|
||||
}
|
||||
|
||||
static void bcmasp_enable_wol_shared(struct bcmasp_intf *intf, bool en)
|
||||
void bcmasp_enable_wol(struct bcmasp_intf *intf, bool en)
|
||||
{
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
struct device *dev = &priv->pdev->dev;
|
||||
@@ -1154,54 +1156,12 @@ static void bcmasp_enable_wol_shared(struct bcmasp_intf *intf, bool en)
|
||||
}
|
||||
}
|
||||
|
||||
static void bcmasp_wol_irq_destroy_shared(struct bcmasp_priv *priv)
|
||||
static void bcmasp_wol_irq_destroy(struct bcmasp_priv *priv)
|
||||
{
|
||||
if (priv->wol_irq > 0)
|
||||
free_irq(priv->wol_irq, priv);
|
||||
}
|
||||
|
||||
static void bcmasp_init_wol_per_intf(struct bcmasp_priv *priv)
|
||||
{
|
||||
struct platform_device *pdev = priv->pdev;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct bcmasp_intf *intf;
|
||||
int irq;
|
||||
|
||||
list_for_each_entry(intf, &priv->intfs, list) {
|
||||
irq = bcmasp_get_and_request_irq(priv, intf->port + 1);
|
||||
if (irq < 0) {
|
||||
dev_warn(dev, "Failed to init WoL irq(port %d): %d\n",
|
||||
intf->port, irq);
|
||||
continue;
|
||||
}
|
||||
|
||||
intf->wol_irq = irq;
|
||||
intf->wol_irq_enabled = false;
|
||||
device_set_wakeup_capable(&pdev->dev, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static void bcmasp_enable_wol_per_intf(struct bcmasp_intf *intf, bool en)
|
||||
{
|
||||
struct device *dev = &intf->parent->pdev->dev;
|
||||
|
||||
if (en ^ intf->wol_irq_enabled)
|
||||
irq_set_irq_wake(intf->wol_irq, en);
|
||||
|
||||
intf->wol_irq_enabled = en;
|
||||
device_set_wakeup_enable(dev, en);
|
||||
}
|
||||
|
||||
static void bcmasp_wol_irq_destroy_per_intf(struct bcmasp_priv *priv)
|
||||
{
|
||||
struct bcmasp_intf *intf;
|
||||
|
||||
list_for_each_entry(intf, &priv->intfs, list) {
|
||||
if (intf->wol_irq > 0)
|
||||
free_irq(intf->wol_irq, priv);
|
||||
}
|
||||
}
|
||||
|
||||
static void bcmasp_eee_fixup(struct bcmasp_intf *intf, bool en)
|
||||
{
|
||||
u32 reg, phy_lpi_overwrite;
|
||||
@@ -1220,70 +1180,53 @@ static void bcmasp_eee_fixup(struct bcmasp_intf *intf, bool en)
|
||||
usleep_range(50, 100);
|
||||
}
|
||||
|
||||
static struct bcmasp_hw_info v20_hw_info = {
|
||||
.rx_ctrl_flush = ASP_RX_CTRL_FLUSH,
|
||||
.umac2fb = UMAC2FB_OFFSET,
|
||||
.rx_ctrl_fb_out_frame_count = ASP_RX_CTRL_FB_OUT_FRAME_COUNT,
|
||||
.rx_ctrl_fb_filt_out_frame_count = ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT,
|
||||
.rx_ctrl_fb_rx_fifo_depth = ASP_RX_CTRL_FB_RX_FIFO_DEPTH,
|
||||
};
|
||||
|
||||
static const struct bcmasp_plat_data v20_plat_data = {
|
||||
.init_wol = bcmasp_init_wol_per_intf,
|
||||
.enable_wol = bcmasp_enable_wol_per_intf,
|
||||
.destroy_wol = bcmasp_wol_irq_destroy_per_intf,
|
||||
.core_clock_select = bcmasp_core_clock_select_one,
|
||||
.hw_info = &v20_hw_info,
|
||||
};
|
||||
|
||||
static struct bcmasp_hw_info v21_hw_info = {
|
||||
.rx_ctrl_flush = ASP_RX_CTRL_FLUSH_2_1,
|
||||
.umac2fb = UMAC2FB_OFFSET_2_1,
|
||||
.rx_ctrl_fb_out_frame_count = ASP_RX_CTRL_FB_OUT_FRAME_COUNT_2_1,
|
||||
.rx_ctrl_fb_filt_out_frame_count =
|
||||
ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT_2_1,
|
||||
.rx_ctrl_fb_rx_fifo_depth = ASP_RX_CTRL_FB_RX_FIFO_DEPTH_2_1,
|
||||
};
|
||||
|
||||
static const struct bcmasp_plat_data v21_plat_data = {
|
||||
.init_wol = bcmasp_init_wol_shared,
|
||||
.enable_wol = bcmasp_enable_wol_shared,
|
||||
.destroy_wol = bcmasp_wol_irq_destroy_shared,
|
||||
.core_clock_select = bcmasp_core_clock_select_one,
|
||||
.hw_info = &v21_hw_info,
|
||||
.num_mda_filters = 32,
|
||||
.num_net_filters = 32,
|
||||
.tx_chan_offset = 8,
|
||||
.rx_ctrl_offset = 0x0,
|
||||
};
|
||||
|
||||
static const struct bcmasp_plat_data v22_plat_data = {
|
||||
.init_wol = bcmasp_init_wol_shared,
|
||||
.enable_wol = bcmasp_enable_wol_shared,
|
||||
.destroy_wol = bcmasp_wol_irq_destroy_shared,
|
||||
.core_clock_select = bcmasp_core_clock_select_many,
|
||||
.hw_info = &v21_hw_info,
|
||||
.eee_fixup = bcmasp_eee_fixup,
|
||||
.num_mda_filters = 32,
|
||||
.num_net_filters = 32,
|
||||
.tx_chan_offset = 8,
|
||||
.rx_ctrl_offset = 0x0,
|
||||
};
|
||||
|
||||
static const struct bcmasp_plat_data v30_plat_data = {
|
||||
.core_clock_select = bcmasp_core_clock_select_one_ctrl2,
|
||||
.num_mda_filters = 20,
|
||||
.num_net_filters = 16,
|
||||
.tx_chan_offset = 0,
|
||||
.rx_ctrl_offset = 0x10000,
|
||||
};
|
||||
|
||||
static void bcmasp_set_pdata(struct bcmasp_priv *priv, const struct bcmasp_plat_data *pdata)
|
||||
{
|
||||
priv->init_wol = pdata->init_wol;
|
||||
priv->enable_wol = pdata->enable_wol;
|
||||
priv->destroy_wol = pdata->destroy_wol;
|
||||
priv->core_clock_select = pdata->core_clock_select;
|
||||
priv->eee_fixup = pdata->eee_fixup;
|
||||
priv->hw_info = pdata->hw_info;
|
||||
priv->num_mda_filters = pdata->num_mda_filters;
|
||||
priv->num_net_filters = pdata->num_net_filters;
|
||||
priv->tx_chan_offset = pdata->tx_chan_offset;
|
||||
priv->rx_ctrl_offset = pdata->rx_ctrl_offset;
|
||||
}
|
||||
|
||||
static const struct of_device_id bcmasp_of_match[] = {
|
||||
{ .compatible = "brcm,asp-v2.0", .data = &v20_plat_data },
|
||||
{ .compatible = "brcm,asp-v2.1", .data = &v21_plat_data },
|
||||
{ .compatible = "brcm,asp-v2.2", .data = &v22_plat_data },
|
||||
{ .compatible = "brcm,asp-v3.0", .data = &v30_plat_data },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcmasp_of_match);
|
||||
|
||||
static const struct of_device_id bcmasp_mdio_of_match[] = {
|
||||
{ .compatible = "brcm,asp-v2.2-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.1-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.0-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.2-mdio", },
|
||||
{ .compatible = "brcm,asp-v3.0-mdio", },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bcmasp_mdio_of_match);
|
||||
@@ -1365,6 +1308,17 @@ static int bcmasp_probe(struct platform_device *pdev)
|
||||
* how many interfaces come up.
|
||||
*/
|
||||
bcmasp_core_init(priv);
|
||||
|
||||
priv->mda_filters = devm_kcalloc(dev, priv->num_mda_filters,
|
||||
sizeof(*priv->mda_filters), GFP_KERNEL);
|
||||
if (!priv->mda_filters)
|
||||
return -ENOMEM;
|
||||
|
||||
priv->net_filters = devm_kcalloc(dev, priv->num_net_filters,
|
||||
sizeof(*priv->net_filters), GFP_KERNEL);
|
||||
if (!priv->net_filters)
|
||||
return -ENOMEM;
|
||||
|
||||
bcmasp_core_init_filters(priv);
|
||||
|
||||
ports_node = of_find_node_by_name(dev->of_node, "ethernet-ports");
|
||||
@@ -1387,7 +1341,7 @@ static int bcmasp_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
/* Check and enable WoL */
|
||||
priv->init_wol(priv);
|
||||
bcmasp_init_wol(priv);
|
||||
|
||||
/* Drop the clock reference count now and let ndo_open()/ndo_close()
|
||||
* manage it for us from now on.
|
||||
@@ -1404,7 +1358,7 @@ static int bcmasp_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
netdev_err(intf->ndev,
|
||||
"failed to register net_device: %d\n", ret);
|
||||
priv->destroy_wol(priv);
|
||||
bcmasp_wol_irq_destroy(priv);
|
||||
bcmasp_remove_intfs(priv);
|
||||
goto of_put_exit;
|
||||
}
|
||||
@@ -1425,7 +1379,7 @@ static void bcmasp_remove(struct platform_device *pdev)
|
||||
if (!priv)
|
||||
return;
|
||||
|
||||
priv->destroy_wol(priv);
|
||||
bcmasp_wol_irq_destroy(priv);
|
||||
bcmasp_remove_intfs(priv);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,22 +53,15 @@
|
||||
#define ASP_RX_CTRL_FB_0_FRAME_COUNT 0x14
|
||||
#define ASP_RX_CTRL_FB_1_FRAME_COUNT 0x18
|
||||
#define ASP_RX_CTRL_FB_8_FRAME_COUNT 0x1c
|
||||
/* asp2.1 diverges offsets here */
|
||||
/* ASP2.0 */
|
||||
#define ASP_RX_CTRL_FB_OUT_FRAME_COUNT 0x20
|
||||
#define ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT 0x24
|
||||
#define ASP_RX_CTRL_FLUSH 0x28
|
||||
#define ASP_CTRL_UMAC0_FLUSH_MASK (BIT(0) | BIT(12))
|
||||
#define ASP_CTRL_UMAC1_FLUSH_MASK (BIT(1) | BIT(13))
|
||||
#define ASP_CTRL_SPB_FLUSH_MASK (BIT(8) | BIT(20))
|
||||
#define ASP_RX_CTRL_FB_RX_FIFO_DEPTH 0x30
|
||||
/* ASP2.1 */
|
||||
#define ASP_RX_CTRL_FB_9_FRAME_COUNT_2_1 0x20
|
||||
#define ASP_RX_CTRL_FB_10_FRAME_COUNT_2_1 0x24
|
||||
#define ASP_RX_CTRL_FB_OUT_FRAME_COUNT_2_1 0x28
|
||||
#define ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT_2_1 0x2c
|
||||
#define ASP_RX_CTRL_FLUSH_2_1 0x30
|
||||
#define ASP_RX_CTRL_FB_RX_FIFO_DEPTH_2_1 0x38
|
||||
#define ASP_RX_CTRL_FB_9_FRAME_COUNT 0x20
|
||||
#define ASP_RX_CTRL_FB_10_FRAME_COUNT 0x24
|
||||
#define ASP_RX_CTRL_FB_OUT_FRAME_COUNT 0x28
|
||||
#define ASP_RX_CTRL_FB_FILT_OUT_FRAME_COUNT 0x2c
|
||||
#define ASP_RX_CTRL_FLUSH 0x30
|
||||
#define ASP_CTRL_UMAC0_FLUSH_MASK (BIT(0) | BIT(12))
|
||||
#define ASP_CTRL_UMAC1_FLUSH_MASK (BIT(1) | BIT(13))
|
||||
#define ASP_CTRL_SPB_FLUSH_MASK (BIT(8) | BIT(20))
|
||||
#define ASP_RX_CTRL_FB_RX_FIFO_DEPTH 0x38
|
||||
|
||||
#define ASP_RX_FILTER_OFFSET 0x80000
|
||||
#define ASP_RX_FILTER_BLK_CTRL 0x0
|
||||
@@ -345,9 +338,6 @@ struct bcmasp_intf {
|
||||
|
||||
u32 wolopts;
|
||||
u8 sopass[SOPASS_MAX];
|
||||
/* Used if per intf wol irq */
|
||||
int wol_irq;
|
||||
unsigned int wol_irq_enabled:1;
|
||||
};
|
||||
|
||||
#define NUM_NET_FILTERS 32
|
||||
@@ -370,21 +360,13 @@ struct bcmasp_mda_filter {
|
||||
u8 mask[ETH_ALEN];
|
||||
};
|
||||
|
||||
struct bcmasp_hw_info {
|
||||
u32 rx_ctrl_flush;
|
||||
u32 umac2fb;
|
||||
u32 rx_ctrl_fb_out_frame_count;
|
||||
u32 rx_ctrl_fb_filt_out_frame_count;
|
||||
u32 rx_ctrl_fb_rx_fifo_depth;
|
||||
};
|
||||
|
||||
struct bcmasp_plat_data {
|
||||
void (*init_wol)(struct bcmasp_priv *priv);
|
||||
void (*enable_wol)(struct bcmasp_intf *intf, bool en);
|
||||
void (*destroy_wol)(struct bcmasp_priv *priv);
|
||||
void (*core_clock_select)(struct bcmasp_priv *priv, bool slow);
|
||||
void (*eee_fixup)(struct bcmasp_intf *priv, bool en);
|
||||
struct bcmasp_hw_info *hw_info;
|
||||
unsigned int num_mda_filters;
|
||||
unsigned int num_net_filters;
|
||||
unsigned int tx_chan_offset;
|
||||
unsigned int rx_ctrl_offset;
|
||||
};
|
||||
|
||||
struct bcmasp_priv {
|
||||
@@ -399,18 +381,18 @@ struct bcmasp_priv {
|
||||
int wol_irq;
|
||||
unsigned long wol_irq_enabled_mask;
|
||||
|
||||
void (*init_wol)(struct bcmasp_priv *priv);
|
||||
void (*enable_wol)(struct bcmasp_intf *intf, bool en);
|
||||
void (*destroy_wol)(struct bcmasp_priv *priv);
|
||||
void (*core_clock_select)(struct bcmasp_priv *priv, bool slow);
|
||||
void (*eee_fixup)(struct bcmasp_intf *intf, bool en);
|
||||
unsigned int num_mda_filters;
|
||||
unsigned int num_net_filters;
|
||||
unsigned int tx_chan_offset;
|
||||
unsigned int rx_ctrl_offset;
|
||||
|
||||
void __iomem *base;
|
||||
struct bcmasp_hw_info *hw_info;
|
||||
|
||||
struct list_head intfs;
|
||||
|
||||
struct bcmasp_mda_filter mda_filters[NUM_MDA_FILTERS];
|
||||
struct bcmasp_mda_filter *mda_filters;
|
||||
|
||||
/* MAC destination address filters lock */
|
||||
spinlock_t mda_lock;
|
||||
@@ -418,7 +400,7 @@ struct bcmasp_priv {
|
||||
/* Protects accesses to ASP_CTRL_CLOCK_CTRL */
|
||||
spinlock_t clk_lock;
|
||||
|
||||
struct bcmasp_net_filter net_filters[NUM_NET_FILTERS];
|
||||
struct bcmasp_net_filter *net_filters;
|
||||
|
||||
/* Network filter lock */
|
||||
struct mutex net_lock;
|
||||
@@ -508,8 +490,8 @@ BCMASP_FP_IO_MACRO_Q(rx_edpkt_cfg);
|
||||
#define PKT_OFFLOAD_EPKT_IP(x) ((x) << 21)
|
||||
#define PKT_OFFLOAD_EPKT_TP(x) ((x) << 19)
|
||||
#define PKT_OFFLOAD_EPKT_LEN(x) ((x) << 16)
|
||||
#define PKT_OFFLOAD_EPKT_CSUM_L3 BIT(15)
|
||||
#define PKT_OFFLOAD_EPKT_CSUM_L2 BIT(14)
|
||||
#define PKT_OFFLOAD_EPKT_CSUM_L4 BIT(15)
|
||||
#define PKT_OFFLOAD_EPKT_CSUM_L3 BIT(14)
|
||||
#define PKT_OFFLOAD_EPKT_ID(x) ((x) << 12)
|
||||
#define PKT_OFFLOAD_EPKT_SEQ(x) ((x) << 10)
|
||||
#define PKT_OFFLOAD_EPKT_TS(x) ((x) << 8)
|
||||
@@ -541,12 +523,27 @@ BCMASP_CORE_IO_MACRO(intr2, ASP_INTR2_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(wakeup_intr2, ASP_WAKEUP_INTR2_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(tx_analytics, ASP_TX_ANALYTICS_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(rx_analytics, ASP_RX_ANALYTICS_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(rx_ctrl, ASP_RX_CTRL_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(rx_filter, ASP_RX_FILTER_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(rx_edpkt, ASP_EDPKT_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(ctrl, ASP_CTRL_OFFSET);
|
||||
BCMASP_CORE_IO_MACRO(ctrl2, ASP_CTRL2_OFFSET);
|
||||
|
||||
#define BCMASP_CORE_IO_MACRO_OFFSET(name, offset) \
|
||||
static inline u32 name##_core_rl(struct bcmasp_priv *priv, \
|
||||
u32 off) \
|
||||
{ \
|
||||
u32 reg = readl_relaxed(priv->base + priv->name##_offset + \
|
||||
(offset) + off); \
|
||||
return reg; \
|
||||
} \
|
||||
static inline void name##_core_wl(struct bcmasp_priv *priv, \
|
||||
u32 val, u32 off) \
|
||||
{ \
|
||||
writel_relaxed(val, priv->base + priv->name##_offset + \
|
||||
(offset) + off); \
|
||||
}
|
||||
BCMASP_CORE_IO_MACRO_OFFSET(rx_ctrl, ASP_RX_CTRL_OFFSET);
|
||||
|
||||
struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
|
||||
struct device_node *ndev_dn, int i);
|
||||
|
||||
@@ -599,4 +596,5 @@ int bcmasp_netfilt_get_all_active(struct bcmasp_intf *intf, u32 *rule_locs,
|
||||
|
||||
void bcmasp_netfilt_suspend(struct bcmasp_intf *intf);
|
||||
|
||||
void bcmasp_enable_wol(struct bcmasp_intf *intf, bool en);
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
#include "bcmasp_intf_defs.h"
|
||||
|
||||
enum bcmasp_stat_type {
|
||||
BCMASP_STAT_RX_EDPKT,
|
||||
BCMASP_STAT_RX_CTRL,
|
||||
BCMASP_STAT_RX_CTRL_PER_INTF,
|
||||
BCMASP_STAT_SOFT,
|
||||
@@ -33,8 +32,6 @@ struct bcmasp_stats {
|
||||
.reg_offset = offset, \
|
||||
}
|
||||
|
||||
#define STAT_BCMASP_RX_EDPKT(str, offset) \
|
||||
STAT_BCMASP_OFFSET(str, BCMASP_STAT_RX_EDPKT, offset)
|
||||
#define STAT_BCMASP_RX_CTRL(str, offset) \
|
||||
STAT_BCMASP_OFFSET(str, BCMASP_STAT_RX_CTRL, offset)
|
||||
#define STAT_BCMASP_RX_CTRL_PER_INTF(str, offset) \
|
||||
@@ -42,11 +39,6 @@ struct bcmasp_stats {
|
||||
|
||||
/* Must match the order of struct bcmasp_mib_counters */
|
||||
static const struct bcmasp_stats bcmasp_gstrings_stats[] = {
|
||||
/* EDPKT counters */
|
||||
STAT_BCMASP_RX_EDPKT("RX Time Stamp", ASP_EDPKT_RX_TS_COUNTER),
|
||||
STAT_BCMASP_RX_EDPKT("RX PKT Count", ASP_EDPKT_RX_PKT_CNT),
|
||||
STAT_BCMASP_RX_EDPKT("RX PKT Buffered", ASP_EDPKT_HDR_EXTR_CNT),
|
||||
STAT_BCMASP_RX_EDPKT("RX PKT Pushed to DRAM", ASP_EDPKT_HDR_OUT_CNT),
|
||||
/* ASP RX control */
|
||||
STAT_BCMASP_RX_CTRL_PER_INTF("Frames From Unimac",
|
||||
ASP_RX_CTRL_UMAC_0_FRAME_COUNT),
|
||||
@@ -71,23 +63,6 @@ static const struct bcmasp_stats bcmasp_gstrings_stats[] = {
|
||||
|
||||
#define BCMASP_STATS_LEN ARRAY_SIZE(bcmasp_gstrings_stats)
|
||||
|
||||
static u16 bcmasp_stat_fixup_offset(struct bcmasp_intf *intf,
|
||||
const struct bcmasp_stats *s)
|
||||
{
|
||||
struct bcmasp_priv *priv = intf->parent;
|
||||
|
||||
if (!strcmp("Frames Out(Buffer)", s->stat_string))
|
||||
return priv->hw_info->rx_ctrl_fb_out_frame_count;
|
||||
|
||||
if (!strcmp("Frames Out(Filters)", s->stat_string))
|
||||
return priv->hw_info->rx_ctrl_fb_filt_out_frame_count;
|
||||
|
||||
if (!strcmp("RX Buffer FIFO Depth", s->stat_string))
|
||||
return priv->hw_info->rx_ctrl_fb_rx_fifo_depth;
|
||||
|
||||
return s->reg_offset;
|
||||
}
|
||||
|
||||
static int bcmasp_get_sset_count(struct net_device *dev, int string_set)
|
||||
{
|
||||
switch (string_set) {
|
||||
@@ -126,13 +101,10 @@ static void bcmasp_update_mib_counters(struct bcmasp_intf *intf)
|
||||
char *p;
|
||||
|
||||
s = &bcmasp_gstrings_stats[i];
|
||||
offset = bcmasp_stat_fixup_offset(intf, s);
|
||||
offset = s->reg_offset;
|
||||
switch (s->type) {
|
||||
case BCMASP_STAT_SOFT:
|
||||
continue;
|
||||
case BCMASP_STAT_RX_EDPKT:
|
||||
val = rx_edpkt_core_rl(intf->parent, offset);
|
||||
break;
|
||||
case BCMASP_STAT_RX_CTRL:
|
||||
val = rx_ctrl_core_rl(intf->parent, offset);
|
||||
break;
|
||||
@@ -215,7 +187,7 @@ static int bcmasp_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
|
||||
memcpy(intf->sopass, wol->sopass, sizeof(wol->sopass));
|
||||
|
||||
mutex_lock(&priv->wol_lock);
|
||||
priv->enable_wol(intf, !!intf->wolopts);
|
||||
bcmasp_enable_wol(intf, !!intf->wolopts);
|
||||
mutex_unlock(&priv->wol_lock);
|
||||
|
||||
return 0;
|
||||
@@ -289,7 +261,7 @@ static int bcmasp_flow_get(struct bcmasp_intf *intf, struct ethtool_rxnfc *cmd)
|
||||
|
||||
memcpy(&cmd->fs, &nfilter->fs, sizeof(nfilter->fs));
|
||||
|
||||
cmd->data = NUM_NET_FILTERS;
|
||||
cmd->data = intf->parent->num_net_filters;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -336,7 +308,7 @@ static int bcmasp_get_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd,
|
||||
break;
|
||||
case ETHTOOL_GRXCLSRLALL:
|
||||
err = bcmasp_netfilt_get_all_active(intf, rule_locs, &cmd->rule_cnt);
|
||||
cmd->data = NUM_NET_FILTERS;
|
||||
cmd->data = intf->parent->num_net_filters;
|
||||
break;
|
||||
default:
|
||||
err = -EOPNOTSUPP;
|
||||
|
||||
@@ -180,14 +180,14 @@ static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
|
||||
case htons(ETH_P_IP):
|
||||
header |= PKT_OFFLOAD_HDR_SIZE_2((ip_hdrlen(skb) >> 8) & 0xf);
|
||||
header2 |= PKT_OFFLOAD_HDR2_SIZE_2(ip_hdrlen(skb) & 0xff);
|
||||
epkt |= PKT_OFFLOAD_EPKT_IP(0) | PKT_OFFLOAD_EPKT_CSUM_L2;
|
||||
epkt |= PKT_OFFLOAD_EPKT_IP(0);
|
||||
ip_proto = ip_hdr(skb)->protocol;
|
||||
header_cnt += 2;
|
||||
break;
|
||||
case htons(ETH_P_IPV6):
|
||||
header |= PKT_OFFLOAD_HDR_SIZE_2((IP6_HLEN >> 8) & 0xf);
|
||||
header2 |= PKT_OFFLOAD_HDR2_SIZE_2(IP6_HLEN & 0xff);
|
||||
epkt |= PKT_OFFLOAD_EPKT_IP(1) | PKT_OFFLOAD_EPKT_CSUM_L2;
|
||||
epkt |= PKT_OFFLOAD_EPKT_IP(1);
|
||||
ip_proto = ipv6_hdr(skb)->nexthdr;
|
||||
header_cnt += 2;
|
||||
break;
|
||||
@@ -198,12 +198,12 @@ static struct sk_buff *bcmasp_csum_offload(struct net_device *dev,
|
||||
switch (ip_proto) {
|
||||
case IPPROTO_TCP:
|
||||
header2 |= PKT_OFFLOAD_HDR2_SIZE_3(tcp_hdrlen(skb));
|
||||
epkt |= PKT_OFFLOAD_EPKT_TP(0) | PKT_OFFLOAD_EPKT_CSUM_L3;
|
||||
epkt |= PKT_OFFLOAD_EPKT_TP(0) | PKT_OFFLOAD_EPKT_CSUM_L4;
|
||||
header_cnt++;
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
header2 |= PKT_OFFLOAD_HDR2_SIZE_3(UDP_HLEN);
|
||||
epkt |= PKT_OFFLOAD_EPKT_TP(1) | PKT_OFFLOAD_EPKT_CSUM_L3;
|
||||
epkt |= PKT_OFFLOAD_EPKT_TP(1) | PKT_OFFLOAD_EPKT_CSUM_L4;
|
||||
header_cnt++;
|
||||
break;
|
||||
default:
|
||||
@@ -818,9 +818,7 @@ static void bcmasp_init_tx(struct bcmasp_intf *intf)
|
||||
/* Tx SPB */
|
||||
tx_spb_ctrl_wl(intf, ((intf->channel + 8) << TX_SPB_CTRL_XF_BID_SHIFT),
|
||||
TX_SPB_CTRL_XF_CTRL2);
|
||||
tx_pause_ctrl_wl(intf, (1 << (intf->channel + 8)), TX_PAUSE_MAP_VECTOR);
|
||||
tx_spb_top_wl(intf, 0x1e, TX_SPB_TOP_BLKOUT);
|
||||
tx_spb_top_wl(intf, 0x0, TX_SPB_TOP_SPRE_BW_CTRL);
|
||||
|
||||
tx_spb_dma_wq(intf, intf->tx_spb_dma_addr, TX_SPB_DMA_READ);
|
||||
tx_spb_dma_wq(intf, intf->tx_spb_dma_addr, TX_SPB_DMA_BASE);
|
||||
@@ -1185,7 +1183,7 @@ static void bcmasp_map_res(struct bcmasp_priv *priv, struct bcmasp_intf *intf)
|
||||
{
|
||||
/* Per port */
|
||||
intf->res.umac = priv->base + UMC_OFFSET(intf);
|
||||
intf->res.umac2fb = priv->base + (priv->hw_info->umac2fb +
|
||||
intf->res.umac2fb = priv->base + (UMAC2FB_OFFSET + priv->rx_ctrl_offset +
|
||||
(intf->port * 0x4));
|
||||
intf->res.rgmii = priv->base + RGMII_OFFSET(intf);
|
||||
|
||||
@@ -1200,7 +1198,6 @@ static void bcmasp_map_res(struct bcmasp_priv *priv, struct bcmasp_intf *intf)
|
||||
intf->rx_edpkt_cfg = priv->base + RX_EDPKT_CFG_OFFSET(intf);
|
||||
}
|
||||
|
||||
#define MAX_IRQ_STR_LEN 64
|
||||
struct bcmasp_intf *bcmasp_interface_create(struct bcmasp_priv *priv,
|
||||
struct device_node *ndev_dn, int i)
|
||||
{
|
||||
|
||||
@@ -118,8 +118,7 @@
|
||||
#define UMC_PSW_MS 0x624
|
||||
#define UMC_PSW_LS 0x628
|
||||
|
||||
#define UMAC2FB_OFFSET_2_1 0x9f044
|
||||
#define UMAC2FB_OFFSET 0x9f03c
|
||||
#define UMAC2FB_OFFSET 0x9f044
|
||||
#define UMAC2FB_CFG 0x0
|
||||
#define UMAC2FB_CFG_OPUT_EN BIT(0)
|
||||
#define UMAC2FB_CFG_VLAN_EN BIT(1)
|
||||
|
||||
@@ -334,9 +334,9 @@ static SIMPLE_DEV_PM_OPS(unimac_mdio_pm_ops,
|
||||
NULL, unimac_mdio_resume);
|
||||
|
||||
static const struct of_device_id unimac_mdio_ids[] = {
|
||||
{ .compatible = "brcm,asp-v3.0-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.2-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.1-mdio", },
|
||||
{ .compatible = "brcm,asp-v2.0-mdio", },
|
||||
{ .compatible = "brcm,bcm6846-mdio", },
|
||||
{ .compatible = "brcm,genet-mdio-v5", },
|
||||
{ .compatible = "brcm,genet-mdio-v4", },
|
||||
|
||||
Reference in New Issue
Block a user