Commit 3def5542 authored by Chas Williams's avatar Chas Williams Committed by Hideaki Yoshifuji

[ATM]: Remove cli from lec.c

parent f130c141
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <net/arp.h> #include <net/arp.h>
#include <net/dst.h> #include <net/dst.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/spinlock.h>
/* TokenRing if needed */ /* TokenRing if needed */
#ifdef CONFIG_TR #ifdef CONFIG_TR
...@@ -55,6 +56,7 @@ extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br, ...@@ -55,6 +56,7 @@ extern struct net_bridge_fdb_entry *(*br_fdb_get_hook)(struct net_bridge *br,
unsigned char *addr); unsigned char *addr);
extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent); extern void (*br_fdb_put_hook)(struct net_bridge_fdb_entry *ent);
static spinlock_t lec_arp_spinlock = SPIN_LOCK_UNLOCKED;
#define DUMP_PACKETS 0 /* 0 = None, #define DUMP_PACKETS 0 /* 0 = None,
* 1 = 30 first bytes * 1 = 30 first bytes
...@@ -1044,15 +1046,15 @@ void dump_arp_table(struct lec_priv *priv); ...@@ -1044,15 +1046,15 @@ void dump_arp_table(struct lec_priv *priv);
#define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1)) #define HASH(ch) (ch & (LEC_ARP_TABLE_SIZE -1))
static __inline__ void static __inline__ void
lec_arp_lock(struct lec_priv *priv) lec_arp_get(struct lec_priv *priv)
{ {
atomic_inc(&priv->lec_arp_lock_var); atomic_inc(&priv->lec_arp_users);
} }
static __inline__ void static __inline__ void
lec_arp_unlock(struct lec_priv *priv) lec_arp_put(struct lec_priv *priv)
{ {
atomic_dec(&priv->lec_arp_lock_var); atomic_dec(&priv->lec_arp_users);
} }
/* /*
...@@ -1103,33 +1105,33 @@ lec_arp_clear_vccs(struct lec_arp_table *entry) ...@@ -1103,33 +1105,33 @@ lec_arp_clear_vccs(struct lec_arp_table *entry)
* LANE2: Add to the end of the list to satisfy 8.1.13 * LANE2: Add to the end of the list to satisfy 8.1.13
*/ */
static __inline__ void static __inline__ void
lec_arp_put(struct lec_arp_table **lec_arp_tables, lec_arp_add(struct lec_arp_table **lec_arp_tables,
struct lec_arp_table *to_put) struct lec_arp_table *to_add)
{ {
unsigned short place;
unsigned long flags; unsigned long flags;
unsigned short place;
struct lec_arp_table *tmp; struct lec_arp_table *tmp;
save_flags(flags); spin_lock_irqsave(&lec_arp_spinlock, flags);
cli();
place = HASH(to_put->mac_addr[ETH_ALEN-1]); place = HASH(to_add->mac_addr[ETH_ALEN-1]);
tmp = lec_arp_tables[place]; tmp = lec_arp_tables[place];
to_put->next = NULL; to_add->next = NULL;
if (tmp == NULL) if (tmp == NULL)
lec_arp_tables[place] = to_put; lec_arp_tables[place] = to_add;
else { /* add to the end */ else { /* add to the end */
while (tmp->next) while (tmp->next)
tmp = tmp->next; tmp = tmp->next;
tmp->next = to_put; tmp->next = to_add;
} }
restore_flags(flags); spin_unlock_irqrestore(&lec_arp_spinlock, flags);
DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
0xff&to_put->mac_addr[0], 0xff&to_put->mac_addr[1], 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1],
0xff&to_put->mac_addr[2], 0xff&to_put->mac_addr[3], 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3],
0xff&to_put->mac_addr[4], 0xff&to_put->mac_addr[5]); 0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]);
} }
/* /*
...@@ -1139,16 +1141,15 @@ static __inline__ int ...@@ -1139,16 +1141,15 @@ static __inline__ int
lec_arp_remove(struct lec_arp_table **lec_arp_tables, lec_arp_remove(struct lec_arp_table **lec_arp_tables,
struct lec_arp_table *to_remove) struct lec_arp_table *to_remove)
{ {
unsigned long flags;
unsigned short place; unsigned short place;
struct lec_arp_table *tmp; struct lec_arp_table *tmp;
unsigned long flags;
int remove_vcc=1; int remove_vcc=1;
save_flags(flags); spin_lock_irqsave(&lec_arp_spinlock, flags);
cli();
if (!to_remove) { if (!to_remove) {
restore_flags(flags); spin_unlock_irqrestore(&lec_arp_spinlock, flags);
return -1; return -1;
} }
place = HASH(to_remove->mac_addr[ETH_ALEN-1]); place = HASH(to_remove->mac_addr[ETH_ALEN-1]);
...@@ -1160,7 +1161,7 @@ lec_arp_remove(struct lec_arp_table **lec_arp_tables, ...@@ -1160,7 +1161,7 @@ lec_arp_remove(struct lec_arp_table **lec_arp_tables,
tmp = tmp->next; tmp = tmp->next;
} }
if (!tmp) {/* Entry was not found */ if (!tmp) {/* Entry was not found */
restore_flags(flags); spin_unlock_irqrestore(&lec_arp_spinlock, flags);
return -1; return -1;
} }
} }
...@@ -1186,7 +1187,9 @@ lec_arp_remove(struct lec_arp_table **lec_arp_tables, ...@@ -1186,7 +1187,9 @@ lec_arp_remove(struct lec_arp_table **lec_arp_tables,
lec_arp_clear_vccs(to_remove); lec_arp_clear_vccs(to_remove);
} }
skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */ skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */
restore_flags(flags);
spin_unlock_irqrestore(&lec_arp_spinlock, flags);
DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1], 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1],
0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3], 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3],
...@@ -1371,12 +1374,8 @@ void ...@@ -1371,12 +1374,8 @@ void
lec_arp_destroy(struct lec_priv *priv) lec_arp_destroy(struct lec_priv *priv)
{ {
struct lec_arp_table *entry, *next; struct lec_arp_table *entry, *next;
unsigned long flags;
int i; int i;
save_flags(flags);
cli();
del_timer(&priv->lec_arp_timer); del_timer(&priv->lec_arp_timer);
/* /*
...@@ -1419,7 +1418,6 @@ lec_arp_destroy(struct lec_priv *priv) ...@@ -1419,7 +1418,6 @@ lec_arp_destroy(struct lec_priv *priv)
priv->mcast_vcc = NULL; priv->mcast_vcc = NULL;
memset(priv->lec_arp_tables, 0, memset(priv->lec_arp_tables, 0,
sizeof(struct lec_arp_table*)*LEC_ARP_TABLE_SIZE); sizeof(struct lec_arp_table*)*LEC_ARP_TABLE_SIZE);
restore_flags(flags);
} }
...@@ -1436,18 +1434,18 @@ lec_arp_find(struct lec_priv *priv, ...@@ -1436,18 +1434,18 @@ lec_arp_find(struct lec_priv *priv,
DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n",
mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff, mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff,
mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff); mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff);
lec_arp_lock(priv); lec_arp_get(priv);
place = HASH(mac_addr[ETH_ALEN-1]); place = HASH(mac_addr[ETH_ALEN-1]);
to_return = priv->lec_arp_tables[place]; to_return = priv->lec_arp_tables[place];
while(to_return) { while(to_return) {
if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) { if (memcmp(mac_addr, to_return->mac_addr, ETH_ALEN) == 0) {
lec_arp_unlock(priv); lec_arp_put(priv);
return to_return; return to_return;
} }
to_return = to_return->next; to_return = to_return->next;
} }
lec_arp_unlock(priv); lec_arp_put(priv);
return NULL; return NULL;
} }
...@@ -1574,11 +1572,11 @@ lec_arp_check_expire(unsigned long data) ...@@ -1574,11 +1572,11 @@ lec_arp_check_expire(unsigned long data)
del_timer(&priv->lec_arp_timer); del_timer(&priv->lec_arp_timer);
DPRINTK("lec_arp_check_expire %p,%d\n",priv, DPRINTK("lec_arp_check_expire %p,%d\n",priv,
priv->lec_arp_lock_var.counter); atomic_read(&priv->lec_arp_users));
DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones, DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones,
priv->lec_no_forward); priv->lec_no_forward);
if (!priv->lec_arp_lock_var.counter) { if (!atomic_read(&priv->lec_arp_users)) {
lec_arp_lock(priv); lec_arp_get(priv);
now = jiffies; now = jiffies;
for(i=0;i<LEC_ARP_TABLE_SIZE;i++) { for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
for(entry = lec_arp_tables[i];entry != NULL;) { for(entry = lec_arp_tables[i];entry != NULL;) {
...@@ -1624,7 +1622,7 @@ lec_arp_check_expire(unsigned long data) ...@@ -1624,7 +1622,7 @@ lec_arp_check_expire(unsigned long data)
} }
} }
} }
lec_arp_unlock(priv); lec_arp_put(priv);
} }
priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL;
add_timer(&priv->lec_arp_timer); add_timer(&priv->lec_arp_timer);
...@@ -1686,7 +1684,7 @@ lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc, ...@@ -1686,7 +1684,7 @@ lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, int is_rdesc,
if (!entry) { if (!entry) {
return priv->mcast_vcc; return priv->mcast_vcc;
} }
lec_arp_put(priv->lec_arp_tables, entry); lec_arp_add(priv->lec_arp_tables, entry);
/* We want arp-request(s) to be sent */ /* We want arp-request(s) to be sent */
entry->packets_flooded =1; entry->packets_flooded =1;
entry->status = ESI_ARP_PENDING; entry->status = ESI_ARP_PENDING;
...@@ -1711,7 +1709,7 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, ...@@ -1711,7 +1709,7 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
struct lec_arp_table *entry, *next; struct lec_arp_table *entry, *next;
int i; int i;
lec_arp_lock(priv); lec_arp_get(priv);
DPRINTK("lec_addr_delete\n"); DPRINTK("lec_addr_delete\n");
for(i=0;i<LEC_ARP_TABLE_SIZE;i++) { for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
for(entry=priv->lec_arp_tables[i];entry != NULL; entry=next) { for(entry=priv->lec_arp_tables[i];entry != NULL; entry=next) {
...@@ -1722,11 +1720,11 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, ...@@ -1722,11 +1720,11 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr,
lec_arp_remove(priv->lec_arp_tables, entry); lec_arp_remove(priv->lec_arp_tables, entry);
kfree(entry); kfree(entry);
} }
lec_arp_unlock(priv); lec_arp_put(priv);
return 0; return 0;
} }
} }
lec_arp_unlock(priv); lec_arp_put(priv);
return -1; return -1;
} }
...@@ -1751,7 +1749,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, ...@@ -1751,7 +1749,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
return; /* LANE2: ignore targetless LE_ARPs for which return; /* LANE2: ignore targetless LE_ARPs for which
* we have no entry in the cache. 7.1.30 * we have no entry in the cache. 7.1.30
*/ */
lec_arp_lock(priv); lec_arp_get(priv);
if (priv->lec_arp_empty_ones) { if (priv->lec_arp_empty_ones) {
entry = priv->lec_arp_empty_ones; entry = priv->lec_arp_empty_ones;
if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) { if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) {
...@@ -1785,13 +1783,13 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, ...@@ -1785,13 +1783,13 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
entry->status = ESI_FORWARD_DIRECT; entry->status = ESI_FORWARD_DIRECT;
memcpy(entry->mac_addr, mac_addr, ETH_ALEN); memcpy(entry->mac_addr, mac_addr, ETH_ALEN);
entry->last_used = jiffies; entry->last_used = jiffies;
lec_arp_put(priv->lec_arp_tables, entry); lec_arp_add(priv->lec_arp_tables, entry);
} }
if (remoteflag) if (remoteflag)
entry->flags|=LEC_REMOTE_FLAG; entry->flags|=LEC_REMOTE_FLAG;
else else
entry->flags&=~LEC_REMOTE_FLAG; entry->flags&=~LEC_REMOTE_FLAG;
lec_arp_unlock(priv); lec_arp_put(priv);
DPRINTK("After update\n"); DPRINTK("After update\n");
dump_arp_table(priv); dump_arp_table(priv);
return; return;
...@@ -1801,11 +1799,11 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, ...@@ -1801,11 +1799,11 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
if (!entry) { if (!entry) {
entry = make_entry(priv, mac_addr); entry = make_entry(priv, mac_addr);
if (!entry) { if (!entry) {
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
entry->status = ESI_UNKNOWN; entry->status = ESI_UNKNOWN;
lec_arp_put(priv->lec_arp_tables, entry); lec_arp_add(priv->lec_arp_tables, entry);
/* Temporary, changes before end of function */ /* Temporary, changes before end of function */
} }
memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN);
...@@ -1840,7 +1838,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, ...@@ -1840,7 +1838,7 @@ lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr,
} }
DPRINTK("After update2\n"); DPRINTK("After update2\n");
dump_arp_table(priv); dump_arp_table(priv);
lec_arp_unlock(priv); lec_arp_put(priv);
} }
/* /*
...@@ -1854,7 +1852,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1854,7 +1852,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
struct lec_arp_table *entry; struct lec_arp_table *entry;
int i, found_entry=0; int i, found_entry=0;
lec_arp_lock(priv); lec_arp_get(priv);
if (ioc_data->receive == 2) { if (ioc_data->receive == 2) {
/* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */
...@@ -1863,7 +1861,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1863,7 +1861,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
entry = lec_arp_find(priv, bus_mac); entry = lec_arp_find(priv, bus_mac);
if (!entry) { if (!entry) {
printk("LEC_ARP: Multicast entry not found!\n"); printk("LEC_ARP: Multicast entry not found!\n");
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
...@@ -1872,7 +1870,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1872,7 +1870,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
#endif #endif
entry = make_entry(priv, bus_mac); entry = make_entry(priv, bus_mac);
if (entry == NULL) { if (entry == NULL) {
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
del_timer(&entry->timer); del_timer(&entry->timer);
...@@ -1881,7 +1879,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1881,7 +1879,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
entry->old_recv_push = old_push; entry->old_recv_push = old_push;
entry->next = priv->mcast_fwds; entry->next = priv->mcast_fwds;
priv->mcast_fwds = entry; priv->mcast_fwds = entry;
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} else if (ioc_data->receive == 1) { } else if (ioc_data->receive == 1) {
/* Vcc which we don't want to make default vcc, attach it /* Vcc which we don't want to make default vcc, attach it
...@@ -1899,7 +1897,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1899,7 +1897,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
ioc_data->atm_addr[18],ioc_data->atm_addr[19]); ioc_data->atm_addr[18],ioc_data->atm_addr[19]);
entry = make_entry(priv, bus_mac); entry = make_entry(priv, bus_mac);
if (entry == NULL) { if (entry == NULL) {
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN);
...@@ -1912,7 +1910,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1912,7 +1910,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
add_timer(&entry->timer); add_timer(&entry->timer);
entry->next = priv->lec_no_forward; entry->next = priv->lec_no_forward;
priv->lec_no_forward = entry; priv->lec_no_forward = entry;
lec_arp_unlock(priv); lec_arp_put(priv);
dump_arp_table(priv); dump_arp_table(priv);
return; return;
} }
...@@ -1971,7 +1969,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1971,7 +1969,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
} }
} }
if (found_entry) { if (found_entry) {
lec_arp_unlock(priv); lec_arp_put(priv);
DPRINTK("After vcc was added\n"); DPRINTK("After vcc was added\n");
dump_arp_table(priv); dump_arp_table(priv);
return; return;
...@@ -1980,7 +1978,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1980,7 +1978,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
this vcc */ this vcc */
entry = make_entry(priv, bus_mac); entry = make_entry(priv, bus_mac);
if (!entry) { if (!entry) {
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
entry->vcc = vcc; entry->vcc = vcc;
...@@ -1993,7 +1991,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, ...@@ -1993,7 +1991,7 @@ lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data,
entry->timer.expires = jiffies + priv->vcc_timeout_period; entry->timer.expires = jiffies + priv->vcc_timeout_period;
entry->timer.function = lec_arp_expire_vcc; entry->timer.function = lec_arp_expire_vcc;
add_timer(&entry->timer); add_timer(&entry->timer);
lec_arp_unlock(priv); lec_arp_put(priv);
DPRINTK("After vcc was added\n"); DPRINTK("After vcc was added\n");
dump_arp_table(priv); dump_arp_table(priv);
} }
...@@ -2039,10 +2037,10 @@ lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) ...@@ -2039,10 +2037,10 @@ lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
struct lec_arp_table *to_add; struct lec_arp_table *to_add;
lec_arp_lock(priv); lec_arp_get(priv);
to_add = make_entry(priv, mac_addr); to_add = make_entry(priv, mac_addr);
if (!to_add) { if (!to_add) {
lec_arp_unlock(priv); lec_arp_put(priv);
return -ENOMEM; return -ENOMEM;
} }
memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN); memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN);
...@@ -2052,8 +2050,8 @@ lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) ...@@ -2052,8 +2050,8 @@ lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc)
to_add->old_push = vcc->push; to_add->old_push = vcc->push;
vcc->push = lec_push; vcc->push = lec_push;
priv->mcast_vcc = vcc; priv->mcast_vcc = vcc;
lec_arp_put(priv->lec_arp_tables, to_add); lec_arp_add(priv->lec_arp_tables, to_add);
lec_arp_unlock(priv); lec_arp_put(priv);
return 0; return 0;
} }
...@@ -2065,7 +2063,7 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) ...@@ -2065,7 +2063,7 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci); DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci);
dump_arp_table(priv); dump_arp_table(priv);
lec_arp_lock(priv); lec_arp_get(priv);
for(i=0;i<LEC_ARP_TABLE_SIZE;i++) { for(i=0;i<LEC_ARP_TABLE_SIZE;i++) {
for(entry = priv->lec_arp_tables[i];entry; entry=next) { for(entry = priv->lec_arp_tables[i];entry; entry=next) {
next = entry->next; next = entry->next;
...@@ -2127,7 +2125,7 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) ...@@ -2127,7 +2125,7 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc)
entry = next; entry = next;
} }
lec_arp_unlock(priv); lec_arp_put(priv);
dump_arp_table(priv); dump_arp_table(priv);
} }
...@@ -2135,9 +2133,9 @@ void ...@@ -2135,9 +2133,9 @@ void
lec_arp_check_empties(struct lec_priv *priv, lec_arp_check_empties(struct lec_priv *priv,
struct atm_vcc *vcc, struct sk_buff *skb) struct atm_vcc *vcc, struct sk_buff *skb)
{ {
unsigned long flags;
struct lec_arp_table *entry, *prev; struct lec_arp_table *entry, *prev;
struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data;
unsigned long flags;
unsigned char *src; unsigned char *src;
#ifdef CONFIG_TR #ifdef CONFIG_TR
struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data;
...@@ -2147,26 +2145,26 @@ lec_arp_check_empties(struct lec_priv *priv, ...@@ -2147,26 +2145,26 @@ lec_arp_check_empties(struct lec_priv *priv,
#endif #endif
src = hdr->h_source; src = hdr->h_source;
lec_arp_lock(priv); lec_arp_get(priv);
entry = priv->lec_arp_empty_ones; entry = priv->lec_arp_empty_ones;
if (vcc == entry->vcc) { if (vcc == entry->vcc) {
save_flags(flags); spin_lock_irqsave(&lec_arp_spinlock, flags);
cli();
del_timer(&entry->timer); del_timer(&entry->timer);
memcpy(entry->mac_addr, src, ETH_ALEN); memcpy(entry->mac_addr, src, ETH_ALEN);
entry->status = ESI_FORWARD_DIRECT; entry->status = ESI_FORWARD_DIRECT;
entry->last_used = jiffies; entry->last_used = jiffies;
priv->lec_arp_empty_ones = entry->next; priv->lec_arp_empty_ones = entry->next;
restore_flags(flags); spin_unlock_irqrestore(&lec_arp_spinlock, flags);
/* We might have got an entry */ /* We might have got an entry */
if ((prev=lec_arp_find(priv,src))) { if ((prev=lec_arp_find(priv,src))) {
lec_arp_remove(priv->lec_arp_tables, prev); lec_arp_remove(priv->lec_arp_tables, prev);
kfree(prev); kfree(prev);
} }
lec_arp_put(priv->lec_arp_tables, entry); lec_arp_add(priv->lec_arp_tables, entry);
lec_arp_unlock(priv); lec_arp_put(priv);
return; return;
} }
spin_lock_irqsave(&lec_arp_spinlock, flags);
prev = entry; prev = entry;
entry = entry->next; entry = entry->next;
while (entry && entry->vcc != vcc) { while (entry && entry->vcc != vcc) {
...@@ -2175,22 +2173,21 @@ lec_arp_check_empties(struct lec_priv *priv, ...@@ -2175,22 +2173,21 @@ lec_arp_check_empties(struct lec_priv *priv,
} }
if (!entry) { if (!entry) {
DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n"); DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n");
lec_arp_unlock(priv); lec_arp_put(priv);
spin_unlock_irqrestore(&lec_arp_spinlock, flags);
return; return;
} }
save_flags(flags);
cli();
del_timer(&entry->timer); del_timer(&entry->timer);
memcpy(entry->mac_addr, src, ETH_ALEN); memcpy(entry->mac_addr, src, ETH_ALEN);
entry->status = ESI_FORWARD_DIRECT; entry->status = ESI_FORWARD_DIRECT;
entry->last_used = jiffies; entry->last_used = jiffies;
prev->next = entry->next; prev->next = entry->next;
restore_flags(flags); spin_unlock_irqrestore(&lec_arp_spinlock, flags);
if ((prev = lec_arp_find(priv, src))) { if ((prev = lec_arp_find(priv, src))) {
lec_arp_remove(priv->lec_arp_tables,prev); lec_arp_remove(priv->lec_arp_tables,prev);
kfree(prev); kfree(prev);
} }
lec_arp_put(priv->lec_arp_tables,entry); lec_arp_add(priv->lec_arp_tables,entry);
lec_arp_unlock(priv); lec_arp_put(priv);
} }
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -98,7 +98,7 @@ struct lec_priv { ...@@ -98,7 +98,7 @@ struct lec_priv {
establishes multiple Multicast Forward VCCs to us. This list establishes multiple Multicast Forward VCCs to us. This list
collects all those VCCs. LANEv1 client has only one item in this collects all those VCCs. LANEv1 client has only one item in this
list. These entries are not aged out. */ list. These entries are not aged out. */
atomic_t lec_arp_lock_var; atomic_t lec_arp_users;
struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */ struct atm_vcc *mcast_vcc; /* Default Multicast Send VCC */
struct atm_vcc *lecd; struct atm_vcc *lecd;
struct timer_list lec_arp_timer; struct timer_list lec_arp_timer;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment