Skip to content

Commit

Permalink
net: ethernet: ti: cpsw: allow untagged traffic on host port
Browse files Browse the repository at this point in the history
Now untagged vlan traffic is not support on Host P0 port. This patch adds
in ALE context bitmap of VLANs for which Host P0 port bit set in Force
Untagged Packet Egress bitmask in VLANs ALE entries, and adds corresponding
check in VLAN incapsulation header parsing function cpsw_rx_vlan_encap().

Signed-off-by: Grygorii Strashko <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
grygoriyS authored and davem330 committed Nov 20, 2019
1 parent 7fe579d commit 4b41d34
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 10 deletions.
17 changes: 8 additions & 9 deletions drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,17 +428,16 @@ static void cpsw_rx_vlan_encap(struct sk_buff *skb)
/* Ignore vid 0 and pass packet as is */
if (!vid)
return;
/* Ignore default vlans in dual mac mode */
if (cpsw->data.dual_emac &&
vid == cpsw->slaves[priv->emac_port].port_vlan)
return;

prio = (rx_vlan_encap_hdr >>
CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT) &
CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK;
/* Untag P0 packets if set for vlan */
if (!cpsw_ale_get_vlan_p0_untag(cpsw->ale, vid)) {
prio = (rx_vlan_encap_hdr >>
CPSW_RX_VLAN_ENCAP_HDR_PRIO_SHIFT) &
CPSW_RX_VLAN_ENCAP_HDR_PRIO_MSK;

vtag = (prio << VLAN_PRIO_SHIFT) | vid;
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vtag);
vtag = (prio << VLAN_PRIO_SHIFT) | vid;
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q), vtag);
}

/* strip vlan tag for VLAN-tagged packet */
if (pkt_type == CPSW_RX_VLAN_ENCAP_HDR_PKT_VLAN_TAG) {
Expand Down
23 changes: 22 additions & 1 deletion drivers/net/ethernet/ti/cpsw_ale.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
* Copyright (C) 2012 Texas Instruments
*
*/
#include <linux/bitmap.h>
#include <linux/if_vlan.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
Expand Down Expand Up @@ -415,6 +417,17 @@ static void cpsw_ale_set_vlan_mcast(struct cpsw_ale *ale, u32 *ale_entry,
writel(unreg_mcast, ale->params.ale_regs + ALE_VLAN_MASK_MUX(idx));
}

static void cpsw_ale_set_vlan_untag(struct cpsw_ale *ale, u32 *ale_entry,
u16 vid, int untag_mask)
{
cpsw_ale_set_vlan_untag_force(ale_entry,
untag_mask, ale->vlan_field_bits);
if (untag_mask & ALE_PORT_HOST)
bitmap_set(ale->p0_untag_vid_mask, vid, 1);
else
bitmap_clear(ale->p0_untag_vid_mask, vid, 1);
}

int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
int reg_mcast, int unreg_mcast)
{
Expand All @@ -427,8 +440,8 @@ int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,

cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_VLAN);
cpsw_ale_set_vlan_id(ale_entry, vid);
cpsw_ale_set_vlan_untag(ale, ale_entry, vid, untag);

cpsw_ale_set_vlan_untag_force(ale_entry, untag, ale->vlan_field_bits);
if (!ale->params.nu_switch_ale) {
cpsw_ale_set_vlan_reg_mcast(ale_entry, reg_mcast,
ale->vlan_field_bits);
Expand Down Expand Up @@ -460,6 +473,7 @@ int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
return -ENOENT;

cpsw_ale_read(ale, idx, ale_entry);
cpsw_ale_set_vlan_untag(ale, ale_entry, vid, 0);

if (port_mask)
cpsw_ale_set_vlan_member_list(ale_entry, port_mask,
Expand Down Expand Up @@ -792,6 +806,13 @@ struct cpsw_ale *cpsw_ale_create(struct cpsw_ale_params *params)
if (!ale)
return NULL;

ale->p0_untag_vid_mask =
devm_kmalloc_array(params->dev, BITS_TO_LONGS(VLAN_N_VID),
sizeof(unsigned long),
GFP_KERNEL);
if (!ale->p0_untag_vid_mask)
return ERR_PTR(-ENOMEM);

ale->params = *params;
ale->ageout = ale->params.ale_ageout * HZ;

Expand Down
5 changes: 5 additions & 0 deletions drivers/net/ethernet/ti/cpsw_ale.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ struct cpsw_ale {
u32 port_mask_bits;
u32 port_num_bits;
u32 vlan_field_bits;
unsigned long *p0_untag_vid_mask;
};

enum cpsw_ale_control {
Expand Down Expand Up @@ -115,4 +116,8 @@ int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
int control, int value);
void cpsw_ale_dump(struct cpsw_ale *ale, u32 *data);

static inline int cpsw_ale_get_vlan_p0_untag(struct cpsw_ale *ale, u16 vid)
{
return test_bit(vid, ale->p0_untag_vid_mask);
}
#endif

0 comments on commit 4b41d34

Please sign in to comment.