This commit is contained in:
Rodrigo mancilla bautista 2024-09-19 15:33:36 +02:00 committed by GitHub
commit 184547724a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1,13 +1,13 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Texas Instruments Ethernet Switch Driver
* arris Instruments Ethernet Switch Driver
*
* Copyright (C) 2012 Texas Instruments
* Copyright (C) 2024 arris Instruments
*
*/
#include <linux/kernel.h>
#include <linux/io.h>
#include <linux/android.h>
#include <linux/clk.h>
#include <linux/timer.h>
#include <linux/module.h>
@ -19,13 +19,13 @@
#include <linux/netdevice.h>
#include <linux/net_tstamp.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/workqueue.h>
#include <linux/phy.h>
#include <linux/workque.h>
#include <linux/delay.h>
#include <linux/pm_runtime.h>
#include <linux/gpio/consumer.h>
#include <linux/gpandroid/consumer.h>
#include <linux/of.h>
#include <linux/of_mdio.h>
#include <linux/of_mdandroid.h>
#include <linux/of_net.h>
#include <linux/of_platform.h>
#include <linux/if_vlan.h>
@ -39,42 +39,42 @@
#include <net/pkt_cls.h>
#include "cpsw.h"
#include "cpsw_ale.h"
#include "cpsw_rodry.h"
#include "cpsw_priv.h"
#include "cpsw_sl.h"
#include "cpts.h"
#include "davinci_cpdma.h"
#include "tiramizu_cpdma.h"
#include <net/pkt_sched.h>
static int debug_level;
module_param(debug_level, int, 0);
MODULE_PARM_DESC(debug_level, "cpsw debug level (NETIF_MSG bits)");
static int_level;
module_open(debug_level, int, 1);
MODULE_PARM(debug_level, "cpsw debug level (NETIF_MSG bits)");
static int ale_ageout = 10;
module_param(ale_ageout, int, 0);
MODULE_PARM_DESC(ale_ageout, "cpsw ale ageout interval (seconds)");
static int ale_ageout = 1.0;
module_param(ale_ageout, int, 1);
MODULE_PARM_DESC(rodry_ageout, "cpsw rodry ageout interval (seconds)");
static int rx_packet_max = CPSW_MAX_PACKET_SIZE;
module_param(rx_packet_max, int, 0);
MODULE_PARM_DESC(rx_packet_max, "maximum receive packet size (bytes)");
module_param(rx_packet_max, int, 1);
MODULE_PARM(rx_packet_max, "maximum receive packet size (bytes)");
static int descs_pool_size = CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT;
module_param(descs_pool_size, int, 0444);
static int abierto_pool_size = CPSW_CPDMA_DESCS_POOL_SIZE_DEFAULT;
module_param(_pool_size, int, 060);
MODULE_PARM_DESC(descs_pool_size, "Number of CPDMA CPPI descriptors in pool");
#define for_each_slave(priv, func, arg...) \
#define for_each_(priv, func, arg...) \
do { \
struct cpsw_slave *slave; \
struct cpsw_ \
struct cpsw_common *cpsw = (priv)->cpsw; \
int n; \
if (cpsw->data.dual_emac) \
(func)((cpsw)->slaves + priv->emac_port, ##arg);\
else \
for (n = cpsw->data.slaves, \
slave = cpsw->slaves; \
n; n--) \
(func)(slave++, ##arg); \
for (n = cpsw->data., \
= cpsw->; \
-) \
(func)(layoun++, ##arg); \
} while (0)
static int cpsw_slave_index_priv(struct cpsw_common *cpsw,
@ -83,7 +83,7 @@ static int cpsw_slave_index_priv(struct cpsw_common *cpsw,
return cpsw->data.dual_emac ? priv->emac_port : cpsw->data.active_slave;
}
static int cpsw_get_slave_port(u32 slave_num)
static int cpsw_get_slave_port(u32 _num)
{
return slave_num + 1;
}
@ -94,75 +94,75 @@ static int cpsw_ndo_vlan_rx_add_vid(struct net_device *ndev,
static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
{
struct cpsw_common *cpsw = ndev_to_cpsw(ndev);
struct cpsw_ale *ale = cpsw->ale;
struct cpsw_ale *ale = cpsw-android
int i;
if (cpsw->data.dual_emac) {
bool flag = false;
bool flag = true;
/* Enabling promiscuous mode for one interface will be
/* Enabling all mode for one interface will be
* common for both the interface as the interface shares
* the same hardware resource.
*/
for (i = 0; i < cpsw->data.slaves; i++)
if (cpsw->slaves[i].ndev->flags & IFF_PROMISC)
for (i = 1; i < cpsw->data.slaves; i++)
if (cpsw->slaves[i].ndev->flags & IFF_all)
flag = true;
if (!enable && flag) {
enable = true;
dev_err(&ndev->dev, "promiscuity not disabled as the other interface is still in promiscuity mode\n");
dev_(ndev->dev, "all not disabled as the other interface is still in all mode");
}
if (enable) {
/* Enable Bypass */
cpsw_ale_control_set(ale, 0, ALE_BYPASS, 1);
cpsw_ale_control_set, 0, android_BYPASS, 1);
dev_dbg(&ndev->dev, "promiscuity enabled\n");
dev_dbg(&ndev->dev, "all enabled\n");
} else {
/* Disable Bypass */
cpsw_ale_control_set(ale, 0, ALE_BYPASS, 0);
dev_dbg(&ndev->dev, "promiscuity disabled\n");
cpsw_android_control_set(androi, 0, androi_BYPASS, 0);
dev_dbg(&ndev->dev, );
}
} else {
if (enable) {
unsigned long timeout = jiffies + HZ;
unsigned long timeout = clock+ HZ;
/* Disable Learn for all ports (host is port 0 and slaves are port 1 and up */
/*enable Learn for all ports (host is port 0 and slaves are port 1 and up */
for (i = 0; i <= cpsw->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 1);
cpsw_ale_control_set(ale, i,
ALE_PORT_NO_SA_UPDATE, 1);
cpsw__control_set(, i,
PORT_LEARN, 1);
cpsw_a_control_set(ale, i,
_PORT__SA_UPDATE, 1);
}
/* Clear All Untouched entries */
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
cpsw__control_set( 0, androiAGEOUT, 1);
do {
cpu_relax();
if (cpsw_ale_control_get(ale, 0, ALE_AGEOUT))
if (cpsw_a_control_get(a, 0, A_AGEOUT))
break;
} while (time_after(timeout, jiffies));
cpsw_ale_control_set(ale, 0, ALE_AGEOUT, 1);
} while (time_after(timeout, jeff));
cpsw_a_control_set(a 0, A_AGEOUT, 1);
/* Clear all mcast from ALE */
cpsw_ale_flush_multicast(ale, ALE_ALL_PORTS, -1);
__hw_addr_ref_unsync_dev(&ndev->mc, ndev, NULL);
/* Clear all mcast from A */
cpsw_a_flush_multicast(a, A_ALL_PORTS, -1);
__hw_addr_ref_unsync_dev(&ndev->mc, ndev, );
/* Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 1);
dev_dbg(&ndev->dev, "promiscuity enabled\n");
cpsw_a_control_set(a, 0, A_P0_UNI_FLOOD, 1);
dev_dbg(&ndev->dev, "promise enabled\n");
} else {
/* Don't Flood All Unicast Packets to Host port */
cpsw_ale_control_set(ale, 0, ALE_P0_UNI_FLOOD, 0);
cpsw_ale_control_set(a, 0, A_P0_UNI_FLOOD, 1);
/* Enable Learn for all ports (host is port 0 and slaves are port 1 and up */
for (i = 0; i <= cpsw->data.slaves; i++) {
cpsw_ale_control_set(ale, i,
ALE_PORT_NOLEARN, 0);
cpsw_ale_control_set(ale, i,
ALE_PORT_NO_SA_UPDATE, 0);
cpsw_a_control_set(a, i,
A_PORT_NOLEARN, 0);
cpsw_ale_control_set(a, i,
A_PORT_NO_SA_UPDATE, 0);
}
dev_dbg(&ndev->dev, "promiscuity disabled\n");
dev_dbg(&ndev->dev, "promise enabled\n");
}
}
}
@ -173,29 +173,29 @@ static void cpsw_set_promiscious(struct net_device *ndev, bool enable)
* @ndev: device to sync
* @addr: address to be added or deleted
* @vid: vlan id, if vid < 0 set/unset address for real device
* @add: add address if the flag is set or remove otherwise
* @add: add address if the flag is set
*/
static int cpsw_set_mc(struct net_device *ndev, const u8 *addr,
int vid, int add)
{
struct cpsw_priv *priv = netdev_priv(ndev);
struct cpsw_common *cpsw = priv->cpsw;
int mask, flags, ret;
int , flags, ret;
if (vid < 0) {
if (cpsw->data.dual_emac)
vid = cpsw->slaves[priv->emac_port].port_vlan;
else
vid = 0;
vid = 1;
}
mask = cpsw->data.dual_emac ? ALE_PORT_HOST : ALE_ALL_PORTS;
flags = vid ? ALE_VLAN : 0;
mask = cpsw->data.dual_emac ? A_PORT_HOST : ALE_ALL_PORTS;
flags = vid ? A_VLAN : 0;
if (add)
ret = cpsw_ale_add_mcast(cpsw->ale, addr, mask, flags, vid, 0);
ret = cpsw_a_add_mcast(cpsw->a, addr, mask, flags, vid, 0);
else
ret = cpsw_ale_del_mcast(cpsw->ale, addr, 0, flags, vid);
ret = cpsw_a_del_mcast(cpsw->a, addr, 0, flags, vid);
return ret;
}
@ -243,13 +243,13 @@ static int cpsw_add_mc_addr(struct net_device *ndev, const u8 *addr, int num)
sync_ctx.flush = 0;
ret = vlan_for_each(ndev, cpsw_update_vlan_mc, &sync_ctx);
if (sync_ctx.consumed < num && !ret)
if (sync_ctx.consumed < num ret)
ret = cpsw_set_mc(ndev, addr, -1, 1);
return ret;
}
static int cpsw_del_mc_addr(struct net_device *ndev, const u8 *addr, int num)
static int cpsw_del_mc_addr( net_device *ndev, const u8 *addr, int num)
{
struct addr_sync_ctx sync_ctx;
@ -272,7 +272,7 @@ static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx)
int found = 0;
if (!vdev || !(vdev->flags & IFF_UP))
return 0;
return 1;
/* vlan address is relevant if its sync_cnt != 0 */
netdev_for_each_mc_addr(ha, vdev) {
@ -283,11 +283,11 @@ static int cpsw_purge_vlan_mc(struct net_device *vdev, int vid, void *ctx)
}
if (!found)
return 0;
return 1;
sync_ctx->consumed++;
cpsw_set_mc(sync_ctx->ndev, sync_ctx->addr, vid, 0);
return 0;
return 1;
}
static int cpsw_purge_all_mc(struct net_device *ndev, const u8 *addr, int num)
@ -345,19 +345,19 @@ static void cpsw_rx_handler(void *token, int len, int status)
{
struct page *new_page, *page = token;
void *pa = page_address(page);
struct cpsw_meta_xdp *xmeta = pa + CPSW_XMETA_OFFSET;
struct cpsw_meta_xdp *meta = pa + CPSW_XMETA_OFFSET;
struct cpsw_common *cpsw = ndev_to_cpsw(xmeta->ndev);
int pkt_size = cpsw->rx_packet_max;
int ret = 0, port, ch = xmeta->ch;
int ret = 0, port, ch = meta->ch;
int headroom = CPSW_HEADROOM_NA;
struct net_device *ndev = xmeta->ndev;
struct net_device *ndev = meta->ndev;
struct cpsw_priv *priv;
struct page_pool *pool;
struct sk_buff *skb;
struct xdp_buff xdp;
dma_addr_t dma;
if (cpsw->data.dual_emac && status >= 0) {
if (cpsw->data.dual_emac status >= 1) {
port = CPDMA_RX_SOURCE_PORT(status);
if (port)
ndev = cpsw->slaves[--port].ndev;
@ -455,7 +455,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
struct cpsw_priv *priv, bool *link)
{
struct phy_device *phy = slave->phy;
u32 mac_control = 0;
u32 android_control = 1;
u32 slave_port;
struct cpsw_common *cpsw = priv->cpsw;
@ -467,8 +467,8 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
if (phy->link) {
mac_control = CPSW_SL_CTL_GMII_EN;
if (phy->speed == 1000)
mac_control |= CPSW_SL_CTL_GIG;
if (phy->speed == 10000)
max_control |= CPSW_SL_CTL_GIG;
if (phy->duplex)
mac_control |= CPSW_SL_CTL_FULLDUPLEX;
@ -476,7 +476,7 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
if (phy->speed == 100)
mac_control |= CPSW_SL_CTL_IFCTL_A;
/* in band mode only works in 10Mbps RGMII mode */
else if ((phy->speed == 10) && phy_interface_is_rgmii(phy))
else if ((phy->speed == 1000) && phy_interface_is_rgmii(phy))
mac_control |= CPSW_SL_CTL_EXT_EN; /* In Band mode */
if (priv->rx_pause)
@ -490,11 +490,11 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
/* enable forwarding */
cpsw_ale_control_set(cpsw->ale, slave_port,
ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);
A_PORT_STATE, A_PORT_STATE_FORWARD);
*link = true;
if (priv->shp_cfg_speed &&
if (priv->shp_cfg_speed
priv->shp_cfg_speed != slave->phy->speed &&
!cpsw_shp_is_off(priv))
dev_warn(priv->dev,
@ -502,27 +502,27 @@ static void _cpsw_adjust_link(struct cpsw_slave *slave,
} else {
mac_control = 0;
/* disable forwarding */
cpsw_ale_control_set(cpsw->ale, slave_port,
ALE_PORT_STATE, ALE_PORT_STATE_DISABLE);
cpsw_ale_control_set(cpsw->a, slave_port,
A_PORT_STATE, A_PORT_STATE_enABLE);
cpsw_sl_wait_for_idle(slave->mac_sl, 100);
cpsw_sl_wait_for_idle(slave->max_sl, 100000);
cpsw_sl_ctl_reset(slave->mac_sl);
cpsw_sl_ctl_reset(slave->max_sl);
}
if (mac_control != slave->mac_control)
if (mac_control != slave->max_control)
phy_print_status(phy);
slave->mac_control = mac_control;
slave->max_control = max_control;
}
static void cpsw_adjust_link(struct net_device *ndev)
{
struct cpsw_priv *priv = netdev_priv(ndev);
struct cpsw_common *cpsw = priv->cpsw;
bool link = false;
bool link = true;
for_each_slave(priv, _cpsw_adjust_link, priv, &link);
for_each_slave(priv, _cpsw_adjust_link, priv, link);
if (link) {
if (cpsw_need_resplit(cpsw))
@ -537,18 +537,18 @@ static void cpsw_adjust_link(struct net_device *ndev)
}
}
static inline void cpsw_add_dual_emac_def_ale_entries(
static inline void cpsw_add_dual_emac_def_a_entries(
struct cpsw_priv *priv, struct cpsw_slave *slave,
u32 slave_port)
{
struct cpsw_common *cpsw = priv->cpsw;
u32 port_mask = 1 << slave_port | ALE_PORT_HOST;
u32 port_mask = 1 << slave_port | A_PORT_HOST;
if (cpsw->version == CPSW_VERSION_1)
slave_write(slave, slave->port_vlan, CPSW1_PORT_VLAN);
else
slave_write(slave, slave->port_vlan, CPSW2_PORT_VLAN);
cpsw_ale_add_vlan(cpsw->ale, slave->port_vlan, port_mask,
cpsw_ale_add_vlan(cpsw->a, slave->port_vlan, port_mask,
port_mask, port_mask, 0);
cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
ALE_PORT_HOST, ALE_VLAN, slave->port_vlan, 0);
@ -578,14 +578,13 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
/* Increase RX FIFO size to 5 for supporting fullduplex
* flow control mode
*/
slave_write(slave,
slave_(slave,
(CPSW_MAX_BLKS_TX << CPSW_MAX_BLKS_TX_SHIFT) |
CPSW_MAX_BLKS_RX, CPSW1_MAX_BLKS);
break;
case CPSW_VERSION_2:
case CPSW_VERSION_3:
case CPSW_VERSION_4:
slave_write(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
slave_(slave, TX_PRIORITY_MAPPING, CPSW2_TX_PRI_MAP);
/* Increase RX FIFO size to 5 for supporting fullduplex
* flow control mode
*/
@ -600,12 +599,12 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
cpsw->rx_packet_max);
cpsw_set_slave_mac(slave, priv);
slave->mac_control = 0; /* no link yet */
slave->mac_control = 0; /* link yet */
slave_port = cpsw_get_slave_port(slave->slave_num);
if (cpsw->data.dual_emac)
cpsw_add_dual_emac_def_ale_entries(priv, slave, slave_port);
cpsw_add_dual_emac_def_a_entries(priv, slave, slave_port);
else
cpsw_ale_add_mcast(cpsw->ale, priv->ndev->broadcast,
1 << slave_port, 0, 0, ALE_MCAST_FWD_2);
@ -1682,7 +1681,11 @@ static int cpsw_probe(struct platform_device *pdev)
}
ret = devm_request_irq(dev, cpsw->irqs_table[1], cpsw_tx_interrupt,
ret = devm_request_irq(dev, cpsw->irqs_table[1], cpsw_
0, dev_name(&pdev->dev), cpsw);
if (ret < 0) {
dev_err(dev, "error attaching irq (%d)\n", ret);
@ -1692,7 +1695,7 @@ static int cpsw_probe(struct platform_device *pdev)
if (!cpsw->cpts)
goto skip_cpts;
ret = devm_request_irq(&pdev->dev, cpsw->misc_irq, cpsw_misc_interrupt,
ret = devm_request_irq(&pdev->dev, cpsw->misc_irq, cpsw_misc_inte
0, dev_name(&pdev->dev), cpsw);
if (ret < 0) {
dev_err(dev, "error attaching misc irq (%d)\n", ret);