Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 352105
b: refs/heads/master
c: e11b220
h: refs/heads/master
i:
  352103: 158ed73
v: v3
  • Loading branch information
Mugunthan V N authored and David S. Miller committed Feb 6, 2013
1 parent 0a2582d commit 9397e10
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 23 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ca99ca14c95ae49fb4c9cd3abf5f84d11a7e8a61
refs/heads/master: e11b220f336c654db876027d40953acef90b0cae
8 changes: 4 additions & 4 deletions trunk/drivers/net/ethernet/ti/cpsw.c
Original file line number Diff line number Diff line change
Expand Up @@ -345,7 +345,7 @@ static void cpsw_ndo_set_rx_mode(struct net_device *ndev)
/* program multicast address list into ALE register */
netdev_for_each_mc_addr(ha, ndev) {
cpsw_ale_add_mcast(priv->ale, (u8 *)ha->addr,
ALE_ALL_PORTS << priv->host_port, 0, 0);
ALE_ALL_PORTS << priv->host_port, 0, 0, 0);
}
}
}
Expand Down Expand Up @@ -592,7 +592,7 @@ static void cpsw_slave_open(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave_port = cpsw_get_slave_port(priv, slave->slave_num);

cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
1 << slave_port, 0, ALE_MCAST_FWD_2);
1 << slave_port, 0, 0, ALE_MCAST_FWD_2);

slave->phy = phy_connect(priv->ndev, slave->data->phy_id,
&cpsw_adjust_link, slave->data->phy_if);
Expand Down Expand Up @@ -624,9 +624,9 @@ static void cpsw_init_host_port(struct cpsw_priv *priv)
cpsw_ale_control_set(priv->ale, priv->host_port,
ALE_PORT_STATE, ALE_PORT_STATE_FORWARD);

cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port, 0);
cpsw_ale_add_ucast(priv->ale, priv->mac_addr, priv->host_port, 0, 0);
cpsw_ale_add_mcast(priv->ale, priv->ndev->broadcast,
1 << priv->host_port, 0, ALE_MCAST_FWD_2);
1 << priv->host_port, 0, 0, ALE_MCAST_FWD_2);
}

static int cpsw_ndo_open(struct net_device *ndev)
Expand Down
107 changes: 95 additions & 12 deletions trunk/drivers/net/ethernet/ti/cpsw_ale.c
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ static int cpsw_ale_write(struct cpsw_ale *ale, int idx, u32 *ale_entry)
return idx;
}

static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr)
int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int type, idx;
Expand All @@ -160,13 +160,31 @@ static int cpsw_ale_match_addr(struct cpsw_ale *ale, u8 *addr)
type = cpsw_ale_get_entry_type(ale_entry);
if (type != ALE_TYPE_ADDR && type != ALE_TYPE_VLAN_ADDR)
continue;
if (cpsw_ale_get_vlan_id(ale_entry) != vid)
continue;
cpsw_ale_get_addr(ale_entry, entry_addr);
if (memcmp(entry_addr, addr, 6) == 0)
return idx;
}
return -ENOENT;
}

int cpsw_ale_match_vlan(struct cpsw_ale *ale, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int type, idx;

for (idx = 0; idx < ale->params.ale_entries; idx++) {
cpsw_ale_read(ale, 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_free(struct cpsw_ale *ale)
{
u32 ale_entry[ALE_ENTRY_WORDS];
Expand Down Expand Up @@ -274,19 +292,32 @@ int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask)
return 0;
}

int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags)
static inline void cpsw_ale_set_vlan_entry_type(u32 *ale_entry,
int flags, u16 vid)
{
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);
}
}

int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, 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);
cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);

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);
cpsw_ale_set_blocked(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
cpsw_ale_set_port_num(ale_entry, port);

idx = cpsw_ale_match_addr(ale, addr);
idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
if (idx < 0)
idx = cpsw_ale_match_free(ale);
if (idx < 0)
Expand All @@ -298,12 +329,13 @@ int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags)
return 0;
}

int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port)
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;

idx = cpsw_ale_match_addr(ale, addr);
idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
if (idx < 0)
return -ENOENT;

Expand All @@ -313,18 +345,19 @@ int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port)
}

int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int super, int mcast_state)
int flags, u16 vid, int mcast_state)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx, mask;

idx = cpsw_ale_match_addr(ale, addr);
idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
if (idx >= 0)
cpsw_ale_read(ale, idx, ale_entry);

cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_ADDR);
cpsw_ale_set_vlan_entry_type(ale_entry, flags, vid);

cpsw_ale_set_addr(ale_entry, addr);
cpsw_ale_set_super(ale_entry, super);
cpsw_ale_set_super(ale_entry, (flags & ALE_BLOCKED) ? 1 : 0);
cpsw_ale_set_mcast_state(ale_entry, mcast_state);

mask = cpsw_ale_get_port_mask(ale_entry);
Expand All @@ -342,12 +375,13 @@ int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
return 0;
}

int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask)
int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int flags, u16 vid)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;

idx = cpsw_ale_match_addr(ale, addr);
idx = cpsw_ale_match_addr(ale, addr, (flags & ALE_VLAN) ? vid : 0);
if (idx < 0)
return -EINVAL;

Expand All @@ -362,6 +396,55 @@ int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask)
return 0;
}

int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
int reg_mcast, int unreg_mcast)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;

idx = cpsw_ale_match_vlan(ale, vid);
if (idx >= 0)
cpsw_ale_read(ale, 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_force(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);

if (idx < 0)
idx = cpsw_ale_match_free(ale);
if (idx < 0)
idx = cpsw_ale_find_ageable(ale);
if (idx < 0)
return -ENOMEM;

cpsw_ale_write(ale, idx, ale_entry);
return 0;
}

int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port_mask)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx;

idx = cpsw_ale_match_vlan(ale, vid);
if (idx < 0)
return -ENOENT;

cpsw_ale_read(ale, idx, ale_entry);

if (port_mask)
cpsw_ale_set_vlan_member_list(ale_entry, port_mask);
else
cpsw_ale_set_entry_type(ale_entry, ALE_TYPE_FREE);

cpsw_ale_write(ale, idx, ale_entry);
return 0;
}

struct ale_control_info {
const char *name;
int offset, port_offset;
Expand Down
20 changes: 14 additions & 6 deletions trunk/drivers/net/ethernet/ti/cpsw_ale.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,10 @@ 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_SECURE BIT(0)
#define ALE_BLOCKED BIT(1)
#define ALE_SUPER BIT(2)
#define ALE_VLAN BIT(3)

#define ALE_MCAST_FWD 0
#define ALE_MCAST_BLOCK_LEARN_FWD 1
Expand All @@ -81,11 +83,17 @@ void cpsw_ale_stop(struct cpsw_ale *ale);
int cpsw_ale_set_ageout(struct cpsw_ale *ale, int ageout);
int cpsw_ale_flush(struct cpsw_ale *ale, int port_mask);
int cpsw_ale_flush_multicast(struct cpsw_ale *ale, int port_mask);
int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port, int flags);
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port);
int cpsw_ale_add_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int flags, u16 vid);
int cpsw_ale_del_ucast(struct cpsw_ale *ale, u8 *addr, int port,
int flags, u16 vid);
int cpsw_ale_add_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int super, int mcast_state);
int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask);
int flags, u16 vid, int mcast_state);
int cpsw_ale_del_mcast(struct cpsw_ale *ale, u8 *addr, int port_mask,
int flags, u16 vid);
int cpsw_ale_add_vlan(struct cpsw_ale *ale, u16 vid, int port, int untag,
int reg_mcast, int unreg_mcast);
int cpsw_ale_del_vlan(struct cpsw_ale *ale, u16 vid, int port);

int cpsw_ale_control_get(struct cpsw_ale *ale, int port, int control);
int cpsw_ale_control_set(struct cpsw_ale *ale, int port,
Expand Down

0 comments on commit 9397e10

Please sign in to comment.