* [PATCH 1/5] net: cpsw: fix cpsw_slave_regs register offsets
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
@ 2020-05-04 7:50 ` Michael Grzeschik
2020-05-05 9:09 ` Michael Grzeschik
2020-05-04 7:50 ` [PATCH 2/5] net: cpsw: move generic setup code to probe Michael Grzeschik
` (4 subsequent siblings)
5 siblings, 1 reply; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-04 7:50 UTC (permalink / raw)
To: barebox
The cpsw_slave_regs struct also start with max_blks register, so here we
also have to skip the first two bytes like for .host_port_reg_ofs
---
drivers/net/cpsw.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index c3cc43cc5b..d745737aa3 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -1015,7 +1015,7 @@ static struct cpsw_data cpsw1_data = {
.cpdma_reg_ofs = 0x100,
.state_ram_ofs = 0x200,
.ale_reg_ofs = 0x600,
- .slave_ofs = 0x050,
+ .slave_ofs = 0x058,
.slave_size = 0x040,
.sliver_ofs = 0x700,
/* FIXME: mdio_reg_ofs and cppi_ram_ofs missing */
@@ -1026,7 +1026,7 @@ static struct cpsw_data cpsw2_data = {
.cpdma_reg_ofs = 0x800,
.state_ram_ofs = 0xa00,
.ale_reg_ofs = 0xd00,
- .slave_ofs = 0x200,
+ .slave_ofs = 0x208,
.slave_size = 0x100,
.sliver_ofs = 0xd80,
.mdio_reg_ofs = 0x1000,
--
2.26.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 1/5] net: cpsw: fix cpsw_slave_regs register offsets
2020-05-04 7:50 ` [PATCH 1/5] net: cpsw: fix cpsw_slave_regs register offsets Michael Grzeschik
@ 2020-05-05 9:09 ` Michael Grzeschik
0 siblings, 0 replies; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-05 9:09 UTC (permalink / raw)
To: barebox
[-- Attachment #1.1: Type: text/plain, Size: 1615 bytes --]
I forgot something.
On Mon, May 04, 2020 at 09:50:18AM +0200, Michael Grzeschik wrote:
>The cpsw_slave_regs struct also start with max_blks register, so here we
>also have to skip the first two bytes like for .host_port_reg_ofs
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
>---
> drivers/net/cpsw.c | 4 ++--
> 1 file changed, 2 insertions(+), 2 deletions(-)
>
>diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
>index c3cc43cc5b..d745737aa3 100644
>--- a/drivers/net/cpsw.c
>+++ b/drivers/net/cpsw.c
>@@ -1015,7 +1015,7 @@ static struct cpsw_data cpsw1_data = {
> .cpdma_reg_ofs = 0x100,
> .state_ram_ofs = 0x200,
> .ale_reg_ofs = 0x600,
>- .slave_ofs = 0x050,
>+ .slave_ofs = 0x058,
> .slave_size = 0x040,
> .sliver_ofs = 0x700,
> /* FIXME: mdio_reg_ofs and cppi_ram_ofs missing */
>@@ -1026,7 +1026,7 @@ static struct cpsw_data cpsw2_data = {
> .cpdma_reg_ofs = 0x800,
> .state_ram_ofs = 0xa00,
> .ale_reg_ofs = 0xd00,
>- .slave_ofs = 0x200,
>+ .slave_ofs = 0x208,
> .slave_size = 0x100,
> .sliver_ofs = 0xd80,
> .mdio_reg_ofs = 0x1000,
>--
>2.26.2
>
>
>_______________________________________________
>barebox mailing list
>barebox@lists.infradead.org
>http://lists.infradead.org/mailman/listinfo/barebox
>
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
[-- Attachment #1.2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
[-- Attachment #2: Type: text/plain, Size: 149 bytes --]
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/5] net: cpsw: move generic setup code to probe
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
2020-05-04 7:50 ` [PATCH 1/5] net: cpsw: fix cpsw_slave_regs register offsets Michael Grzeschik
@ 2020-05-04 7:50 ` Michael Grzeschik
2020-05-04 7:50 ` [PATCH 3/5] net: cpsw: cpsw_process should only handle rx channels for its own port Michael Grzeschik
` (3 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-04 7:50 UTC (permalink / raw)
To: barebox
All generic cpsw code can move to probe, so the controller is only reset
and configured once.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
drivers/net/cpsw.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index d745737aa3..55d7ad5f5b 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -801,7 +801,7 @@ static int cpsw_open(struct eth_device *edev)
{
struct cpsw_slave *slave = edev->priv;
struct cpsw_priv *priv = slave->cpsw;
- int i, ret;
+ int ret;
dev_dbg(&slave->dev, "* %s\n", __func__);
@@ -810,6 +810,16 @@ static int cpsw_open(struct eth_device *edev)
if (ret)
return ret;
+ cpsw_slave_init(slave, priv);
+
+ return 0;
+}
+
+static int cpsw_setup(struct device_d *dev)
+{
+ struct cpsw_priv *priv = dev->priv;
+ int i, ret;
+
/* soft reset the controller and initialize priv */
soft_reset(priv, &priv->regs->soft_reset);
@@ -834,9 +844,6 @@ static int cpsw_open(struct eth_device *edev)
cpsw_ale_add_ucast(priv, priv->mac_addr, priv->host_port,
ALE_SECURE);
cpsw_ale_add_mcast(priv, ethbdaddr, 1 << priv->host_port);
-
- cpsw_slave_init(slave, priv);
-
/* init descriptor pool */
for (i = 0; i < NUM_DESCS; i++) {
u32 val = (i == (NUM_DESCS - 1)) ? 0 : (u32)&priv->descs[i + 1];
@@ -875,7 +882,7 @@ static int cpsw_open(struct eth_device *edev)
ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
PKTSIZE);
if (ret < 0) {
- dev_err(&slave->dev, "error %d submitting rx desc\n", ret);
+ dev_err(dev, "error %d submitting rx desc\n", ret);
break;
}
}
@@ -1248,6 +1255,8 @@ static int cpsw_probe(struct device_d *dev)
dev->priv = priv;
+ cpsw_setup(dev);
+
return 0;
out:
free(priv->slaves);
--
2.26.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 3/5] net: cpsw: cpsw_process should only handle rx channels for its own port
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
2020-05-04 7:50 ` [PATCH 1/5] net: cpsw: fix cpsw_slave_regs register offsets Michael Grzeschik
2020-05-04 7:50 ` [PATCH 2/5] net: cpsw: move generic setup code to probe Michael Grzeschik
@ 2020-05-04 7:50 ` Michael Grzeschik
2020-05-04 7:50 ` [PATCH 4/5] net: cpsw: add vlan handling for dual_emac mode Michael Grzeschik
` (2 subsequent siblings)
5 siblings, 0 replies; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-04 7:50 UTC (permalink / raw)
To: barebox
The driver is currently processing the whole channel list, so it is
possible that it handles a channel of the wrong interface. We limit the
rx_chan handling for its desired port.
The cpsw_send is removing finished tx_chan transfers on each send, so this
has no directional limitation.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
drivers/net/cpsw.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 55d7ad5f5b..aabfc76ad6 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -52,6 +52,9 @@
#define CPDMA_DESC_EOP BIT(30)
#define CPDMA_DESC_OWNER BIT(29)
#define CPDMA_DESC_EOQ BIT(28)
+#define CPDMA_FROM_TO_PORT_SHIFT 16
+#define CPDMA_RX_SOURCE_PORT(__status__) \
+ (((__status__) >> CPDMA_FROM_TO_PORT_SHIFT) & 0x7)
#define SLIVER_SIZE 0x40
@@ -758,10 +761,11 @@ done:
return 0;
}
-static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
+static int cpdma_process(struct cpsw_slave *slave, struct cpdma_chan *chan,
void **buffer, int *len)
{
struct cpdma_desc *desc = chan->head;
+ struct cpsw_priv *priv = slave->cpsw;
u32 status;
if (!desc)
@@ -783,6 +787,14 @@ static int cpdma_process(struct cpsw_priv *priv, struct cpdma_chan *chan,
return -EBUSY;
}
+ /* cpsw_send is cleaning finished descriptors on next send
+ * so we only have to check for rx channel here
+ */
+ if (CPDMA_RX_SOURCE_PORT(status) != BIT(slave->slave_num) &&
+ chan == &priv->rx_chan) {
+ return -ENOMSG;
+ }
+
chan->head = (void *)readl(&desc->hw_next);
writel((u32)desc, chan->cp);
@@ -917,7 +929,7 @@ static int cpsw_send(struct eth_device *edev, void *packet, int length)
dev_dbg(&slave->dev, "* %s slave %d\n", __func__, slave->slave_num);
/* first reap completed packets */
- while (cpdma_process(priv, &priv->tx_chan, &buffer, &len) >= 0);
+ while (cpdma_process(slave, &priv->tx_chan, &buffer, &len) >= 0);
dev_dbg(&slave->dev, "%s: %i bytes @ 0x%p\n", __func__, length, packet);
@@ -935,7 +947,7 @@ static int cpsw_recv(struct eth_device *edev)
void *buffer;
int len;
- while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
+ while (cpdma_process(slave, &priv->rx_chan, &buffer, &len) >= 0) {
dma_sync_single_for_cpu((unsigned long)buffer, len,
DMA_FROM_DEVICE);
net_receive(edev, buffer, len);
--
2.26.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 4/5] net: cpsw: add vlan handling for dual_emac mode
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
` (2 preceding siblings ...)
2020-05-04 7:50 ` [PATCH 3/5] net: cpsw: cpsw_process should only handle rx channels for its own port Michael Grzeschik
@ 2020-05-04 7:50 ` Michael Grzeschik
2020-05-04 7:50 ` [PATCH 5/5] net: cpsw: make cpsw_send directional Michael Grzeschik
2020-05-05 10:22 ` [PATCH 0/5] net: cpsw: dual_emac mode Sascha Hauer
5 siblings, 0 replies; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-04 7:50 UTC (permalink / raw)
To: barebox
From TI am335x Reference Manual:
14.3.2.10.2 Dual Mac Mode
When operating in dual mac mode the intention is to transfer packets
between ports 0 and 1 and ports 0 and 2, but not between ports 1 and 2.
Each CPGMAC_SL appears as a single MAC with no bridging between MAC’s.
Each CPGMAC_SL has at least one unique (not the same) mac address.
Dual mac mode is configured as described below:
- Set the ale_vlan_aware bit in the ALE_Control register. This bit
configures the ALE to process in vlan aware mode.
With X can be Port 1 or Port 2:
- Configure the Port X to Port 0 VLAN.
Add a VLAN Table Entry with ports 0 and X as members (clear the flood
masks).
Add a VLAN/Unicast Address Table Entry with the PortX/0 VLAN and
a port number of 0.
- Select the dual mac mode on the port 0 FIFO by setting
tx_in_sel[1:0] = 01 in P0_Tx_In_Ctl.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
drivers/net/cpsw.c | 99 +++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 89 insertions(+), 10 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index aabfc76ad6..7cb530570f 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -164,10 +164,12 @@ enum cpsw_ale_port_state {
/* ALE unicast entry flags - passed into cpsw_ale_add_ucast() */
#define ALE_SECURE 1
#define ALE_BLOCKED 2
+#define ALE_VLAN 4
struct cpsw_slave {
struct cpsw_slave_regs *regs;
struct cpsw_sliver_regs *sliver;
+ int port_vlan;
int slave_num;
int phy_id;
phy_interface_t phy_if;
@@ -261,6 +263,7 @@ static inline void cpsw_ale_set_##name(u32 *ale_entry, u32 value) \
}
DEFINE_ALE_FIELD(entry_type, 60, 2)
+DEFINE_ALE_FIELD(vlan_id, 48, 12)
DEFINE_ALE_FIELD(mcast_state, 62, 2)
DEFINE_ALE_FIELD(port_mask, 66, 3)
DEFINE_ALE_FIELD(ucast_type, 62, 2)
@@ -268,6 +271,10 @@ DEFINE_ALE_FIELD(port_num, 66, 2)
DEFINE_ALE_FIELD(blocked, 65, 1)
DEFINE_ALE_FIELD(secure, 64, 1)
DEFINE_ALE_FIELD(mcast, 40, 1)
+DEFINE_ALE_FIELD(vlan_untag, 24, 3)
+DEFINE_ALE_FIELD(vlan_reg_mcast, 16, 3)
+DEFINE_ALE_FIELD(vlan_unreg_mcast, 8, 3)
+DEFINE_ALE_FIELD(vlan_member_list, 0, 3)
static char ethbdaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
@@ -312,6 +319,23 @@ static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry)
return idx;
}
+static int cpsw_ale_match_vlan(struct cpsw_priv *priv, u16 vid)
+{
+ u32 ale_entry[ALE_ENTRY_WORDS];
+ int type, idx;
+
+ for (idx = 0; idx < priv->ale_entries; idx++) {
+ cpsw_ale_read(priv, idx, ale_entry);
+ type = cpsw_ale_get_entry_type(ale_entry);
+ if (type != ALE_TYPE_VLAN)
+ continue;
+ if (cpsw_ale_get_vlan_id(ale_entry) == vid)
+ return idx;
+ }
+
+ return -ENOENT;
+}
+
static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr)
{
u32 ale_entry[ALE_ENTRY_WORDS];
@@ -376,13 +400,47 @@ static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
return -ENOENT;
}
+static int cpsw_ale_add_vlan(struct cpsw_priv *priv, u16 vid, int port_mask,
+ int untag, int reg_mcast, int unreg_mcast)
+{
+ u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
+ int idx;
+
+ idx = cpsw_ale_match_vlan(priv, vid);
+ if (idx >= 0)
+ cpsw_ale_read(priv, idx, ale_entry);
+
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
+ cpsw_ale_set_vlan_id(ale_entry, vid);
+ cpsw_ale_set_vlan_untag(ale_entry, untag);
+ cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast);
+ cpsw_ale_set_vlan_unreg_mcast(ale_entry, unreg_mcast);
+ cpsw_ale_set_vlan_member_list(ale_entry, port_mask);
+
+ if (idx < 0)
+ idx = cpsw_ale_match_free(priv);
+ if (idx < 0)
+ idx = cpsw_ale_find_ageable(priv);
+ if (idx < 0)
+ return -ENOMEM;
+
+ cpsw_ale_write(priv, idx, ale_entry);
+ return 0;
+}
+
static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
- int port, int flags)
+ int port, int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+ if (flags & ALE_VLAN) {
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
+ cpsw_ale_set_vlan_id(ale_entry, vid);
+ } else {
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+ }
+
cpsw_ale_set_addr(ale_entry, addr);
cpsw_ale_set_ucast_type(ale_entry, ALE_UCAST_PERSISTANT);
cpsw_ale_set_secure(ale_entry, (flags & ALE_SECURE) ? 1 : 0);
@@ -401,7 +459,8 @@ static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
return 0;
}
-static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask)
+static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask,
+ int flags, u16 vid, int mcast_state)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx, mask;
@@ -410,9 +469,14 @@ static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask)
if (idx >= 0)
cpsw_ale_read(priv, idx, ale_entry);
- cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+ if (flags & ALE_VLAN) {
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN_ADDR);
+ cpsw_ale_set_vlan_id(ale_entry, vid);
+ } else {
+ cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
+ }
cpsw_ale_set_addr(ale_entry, addr);
- cpsw_ale_set_mcast_state(ale_entry, ALE_MCAST_FWD_2);
+ cpsw_ale_set_mcast_state(ale_entry, mcast_state);
mask = cpsw_ale_get_port_mask(ale_entry);
port_mask |= mask;
@@ -676,6 +740,7 @@ static inline u32 cpsw_get_slave_port(struct cpsw_priv *priv, u32 slave_num)
static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
{
u32 slave_port;
+ u32 port_mask;
dev_dbg(&slave->dev, "* %s\n", __func__);
@@ -692,8 +757,22 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave_port = cpsw_get_slave_port(priv, slave->slave_num);
cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
+ port_mask = BIT(slave_port) | BIT(priv->host_port);
+
+ /* set port_vlan to host_vlan */
+ writel(BIT(slave->slave_num), &slave->regs->port_vlan);
+ slave->port_vlan = readl(&slave->regs->port_vlan);
+ slave->port_vlan &= 0xfff;
+
+ /* add dual emac default entries */
+ cpsw_ale_add_vlan(priv, slave->port_vlan, port_mask,
+ port_mask, port_mask, 0);
/* add broadcast address */
- cpsw_ale_add_mcast(priv, ethbdaddr, 1 << slave_port);
+ cpsw_ale_add_mcast(priv, ethbdaddr, BIT(priv->host_port), ALE_VLAN,
+ slave->port_vlan, 0);
+ cpsw_ale_add_ucast(priv, priv->mac_addr, priv->host_port,
+ ALE_SECURE | ALE_VLAN,
+ slave->port_vlan);
}
static struct cpdma_desc *cpdma_desc_alloc(struct cpsw_priv *priv)
@@ -839,7 +918,10 @@ static int cpsw_setup(struct device_d *dev)
cpsw_ale_enable(priv, 1);
cpsw_ale_clear(priv, 1);
cpsw_ale_bypass(priv, 0);
- cpsw_ale_vlan_aware(priv, 0); /* vlan unaware mode */
+ cpsw_ale_vlan_aware(priv, 1); /* vlan aware mode */
+
+ /* dual mac mode in fifo */
+ writel(BIT(16), &priv->host_port_regs->flow_thresh);
/* setup host port priority mapping */
writel(0x76543210, &priv->host_port_regs->cpdma_tx_pri_map);
@@ -853,9 +935,6 @@ static int cpsw_setup(struct device_d *dev)
cpsw_ale_port_state(priv, priv->host_port, ALE_PORT_STATE_FORWARD);
- cpsw_ale_add_ucast(priv, priv->mac_addr, priv->host_port,
- ALE_SECURE);
- cpsw_ale_add_mcast(priv, ethbdaddr, 1 << priv->host_port);
/* init descriptor pool */
for (i = 0; i < NUM_DESCS; i++) {
u32 val = (i == (NUM_DESCS - 1)) ? 0 : (u32)&priv->descs[i + 1];
--
2.26.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 5/5] net: cpsw: make cpsw_send directional
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
` (3 preceding siblings ...)
2020-05-04 7:50 ` [PATCH 4/5] net: cpsw: add vlan handling for dual_emac mode Michael Grzeschik
@ 2020-05-04 7:50 ` Michael Grzeschik
2020-05-05 10:22 ` [PATCH 0/5] net: cpsw: dual_emac mode Sascha Hauer
5 siblings, 0 replies; 8+ messages in thread
From: Michael Grzeschik @ 2020-05-04 7:50 UTC (permalink / raw)
To: barebox
For dual_emac mode, the driver needs to send on the individual
ports. We set the directional bits on each packet so the controller
knows where to send its.
From TI am335x Reference Manual:
14.3.2.10.2 Dual Mac Mode
- Packets from the host (port 0) to ports 1 and 2 should be directed.
Signed-off-by: Michael Grzeschik <m.grzeschik@pengutronix.de>
---
drivers/net/cpsw.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 7cb530570f..6e6e651768 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -52,6 +52,7 @@
#define CPDMA_DESC_EOP BIT(30)
#define CPDMA_DESC_OWNER BIT(29)
#define CPDMA_DESC_EOQ BIT(28)
+#define CPDMA_DESC_TO_PORT_EN BIT(20)
#define CPDMA_FROM_TO_PORT_SHIFT 16
#define CPDMA_RX_SOURCE_PORT(__status__) \
(((__status__) >> CPDMA_FROM_TO_PORT_SHIFT) & 0x7)
@@ -796,7 +797,7 @@ static void cpdma_desc_free(struct cpsw_priv *priv, struct cpdma_desc *desc)
}
static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
- void *buffer, int len)
+ void *buffer, int len, int port)
{
struct cpdma_desc *desc, *prev;
u32 mode;
@@ -810,6 +811,10 @@ static int cpdma_submit(struct cpsw_priv *priv, struct cpdma_chan *chan,
mode = CPDMA_DESC_OWNER | CPDMA_DESC_SOP | CPDMA_DESC_EOP;
+ if (port)
+ mode |= CPDMA_DESC_TO_PORT_EN |
+ (port << CPDMA_FROM_TO_PORT_SHIFT);
+
writel(0, &desc->hw_next);
writel((u32)buffer, &desc->hw_buffer);
writel(len, &desc->hw_len);
@@ -971,7 +976,7 @@ static int cpsw_setup(struct device_d *dev)
/* submit rx descs */
for (i = 0; i < PKTBUFSRX - 2; i++) {
ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
- PKTSIZE);
+ PKTSIZE, 0);
if (ret < 0) {
dev_err(dev, "error %d submitting rx desc\n", ret);
break;
@@ -1013,7 +1018,8 @@ static int cpsw_send(struct eth_device *edev, void *packet, int length)
dev_dbg(&slave->dev, "%s: %i bytes @ 0x%p\n", __func__, length, packet);
dma_sync_single_for_device((unsigned long)packet, length, DMA_TO_DEVICE);
- ret = cpdma_submit(priv, &priv->tx_chan, packet, length);
+ ret = cpdma_submit(priv, &priv->tx_chan, packet,
+ length, BIT(slave->slave_num));
dma_sync_single_for_cpu((unsigned long)packet, length, DMA_TO_DEVICE);
return ret;
@@ -1032,7 +1038,7 @@ static int cpsw_recv(struct eth_device *edev)
net_receive(edev, buffer, len);
dma_sync_single_for_device((unsigned long)buffer, len,
DMA_FROM_DEVICE);
- cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
+ cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE, 0);
}
return 0;
--
2.26.2
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 0/5] net: cpsw: dual_emac mode
2020-05-04 7:50 [PATCH 0/5] net: cpsw: dual_emac mode Michael Grzeschik
` (4 preceding siblings ...)
2020-05-04 7:50 ` [PATCH 5/5] net: cpsw: make cpsw_send directional Michael Grzeschik
@ 2020-05-05 10:22 ` Sascha Hauer
5 siblings, 0 replies; 8+ messages in thread
From: Sascha Hauer @ 2020-05-05 10:22 UTC (permalink / raw)
To: Michael Grzeschik; +Cc: barebox
On Mon, May 04, 2020 at 09:50:17AM +0200, Michael Grzeschik wrote:
> This series enables the dual_emac mode for cpsw controller.
> It enables both ports to be used individually.
>
> Michael Grzeschik (5):
> net: cpsw: fix cpsw_slave_regs register offsets
> net: cpsw: move generic setup code to probe
> net: cpsw: cpsw_process should only handle rx channels for its own
> port
> net: cpsw: add vlan handling for dual_emac mode
> net: cpsw: make cpsw_send directional
>
> drivers/net/cpsw.c | 154 ++++++++++++++++++++++++++++++++++++++-------
> 1 file changed, 130 insertions(+), 24 deletions(-)
Applied, thanks
Sascha
--
Pengutronix e.K. | |
Steuerwalder Str. 21 | http://www.pengutronix.de/ |
31137 Hildesheim, Germany | Phone: +49-5121-206917-0 |
Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 |
_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox
^ permalink raw reply [flat|nested] 8+ messages in thread