diff options
| author | Chas Williams <chas@cmf.nrl.navy.mil> | 2006-09-29 20:11:47 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2006-09-29 20:11:47 -0400 |
| commit | 1fa9961d631fcde21cc42678157129c6fae7fe6d (patch) | |
| tree | c9cfa49762b2d0aa33d9fc2e309b3d088f8c51f7 | |
| parent | d44f77466cfdc6f1d1e3870e176afedab7f46a42 (diff) | |
[ATM]: [lec] indent, comment and whitespace cleanup [continued]
Signed-off-by: Chas Williams <chas@cmf.nrl.navy.mil>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | net/atm/lec.c | 1783 |
1 files changed, 899 insertions, 884 deletions
diff --git a/net/atm/lec.c b/net/atm/lec.c index 543960c86fa8..d2b44e91badf 100644 --- a/net/atm/lec.c +++ b/net/atm/lec.c | |||
| @@ -1418,7 +1418,6 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, | |||
| 1418 | * | 1418 | * |
| 1419 | * lec_arpc.c was added here when making | 1419 | * lec_arpc.c was added here when making |
| 1420 | * lane client modular. October 1997 | 1420 | * lane client modular. October 1997 |
| 1421 | * | ||
| 1422 | */ | 1421 | */ |
| 1423 | 1422 | ||
| 1424 | #include <linux/types.h> | 1423 | #include <linux/types.h> |
| @@ -1429,7 +1428,6 @@ static void lane2_associate_ind(struct net_device *dev, u8 *mac_addr, | |||
| 1429 | #include <linux/inetdevice.h> | 1428 | #include <linux/inetdevice.h> |
| 1430 | #include <net/route.h> | 1429 | #include <net/route.h> |
| 1431 | 1430 | ||
| 1432 | |||
| 1433 | #if 0 | 1431 | #if 0 |
| 1434 | #define DPRINTK(format,args...) | 1432 | #define DPRINTK(format,args...) |
| 1435 | /* | 1433 | /* |
| @@ -1452,296 +1450,294 @@ static void lec_arp_expire_arp(unsigned long data); | |||
| 1452 | /* | 1450 | /* |
| 1453 | * Initialization of arp-cache | 1451 | * Initialization of arp-cache |
| 1454 | */ | 1452 | */ |
| 1455 | static void | 1453 | static void lec_arp_init(struct lec_priv *priv) |
| 1456 | lec_arp_init(struct lec_priv *priv) | ||
| 1457 | { | 1454 | { |
| 1458 | unsigned short i; | 1455 | unsigned short i; |
| 1459 | 1456 | ||
| 1460 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 1457 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 1461 | priv->lec_arp_tables[i] = NULL; | 1458 | priv->lec_arp_tables[i] = NULL; |
| 1462 | } | 1459 | } |
| 1463 | spin_lock_init(&priv->lec_arp_lock); | 1460 | spin_lock_init(&priv->lec_arp_lock); |
| 1464 | init_timer(&priv->lec_arp_timer); | 1461 | init_timer(&priv->lec_arp_timer); |
| 1465 | priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; | 1462 | priv->lec_arp_timer.expires = jiffies + LEC_ARP_REFRESH_INTERVAL; |
| 1466 | priv->lec_arp_timer.data = (unsigned long)priv; | 1463 | priv->lec_arp_timer.data = (unsigned long)priv; |
| 1467 | priv->lec_arp_timer.function = lec_arp_check_expire; | 1464 | priv->lec_arp_timer.function = lec_arp_check_expire; |
| 1468 | add_timer(&priv->lec_arp_timer); | 1465 | add_timer(&priv->lec_arp_timer); |
| 1469 | } | 1466 | } |
| 1470 | 1467 | ||
| 1471 | static void | 1468 | static void lec_arp_clear_vccs(struct lec_arp_table *entry) |
| 1472 | lec_arp_clear_vccs(struct lec_arp_table *entry) | ||
| 1473 | { | 1469 | { |
| 1474 | if (entry->vcc) { | 1470 | if (entry->vcc) { |
| 1475 | struct atm_vcc *vcc = entry->vcc; | 1471 | struct atm_vcc *vcc = entry->vcc; |
| 1476 | struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); | 1472 | struct lec_vcc_priv *vpriv = LEC_VCC_PRIV(vcc); |
| 1477 | struct net_device *dev = (struct net_device*) vcc->proto_data; | 1473 | struct net_device *dev = (struct net_device *)vcc->proto_data; |
| 1478 | 1474 | ||
| 1479 | vcc->pop = vpriv->old_pop; | 1475 | vcc->pop = vpriv->old_pop; |
| 1480 | if (vpriv->xoff) | 1476 | if (vpriv->xoff) |
| 1481 | netif_wake_queue(dev); | 1477 | netif_wake_queue(dev); |
| 1482 | kfree(vpriv); | 1478 | kfree(vpriv); |
| 1483 | vcc->user_back = NULL; | 1479 | vcc->user_back = NULL; |
| 1484 | vcc->push = entry->old_push; | 1480 | vcc->push = entry->old_push; |
| 1485 | vcc_release_async(vcc, -EPIPE); | 1481 | vcc_release_async(vcc, -EPIPE); |
| 1486 | vcc = NULL; | 1482 | vcc = NULL; |
| 1487 | } | 1483 | } |
| 1488 | if (entry->recv_vcc) { | 1484 | if (entry->recv_vcc) { |
| 1489 | entry->recv_vcc->push = entry->old_recv_push; | 1485 | entry->recv_vcc->push = entry->old_recv_push; |
| 1490 | vcc_release_async(entry->recv_vcc, -EPIPE); | 1486 | vcc_release_async(entry->recv_vcc, -EPIPE); |
| 1491 | entry->recv_vcc = NULL; | 1487 | entry->recv_vcc = NULL; |
| 1492 | } | 1488 | } |
| 1493 | } | 1489 | } |
| 1494 | 1490 | ||
| 1495 | /* | 1491 | /* |
| 1496 | * Insert entry to lec_arp_table | 1492 | * Insert entry to lec_arp_table |
| 1497 | * LANE2: Add to the end of the list to satisfy 8.1.13 | 1493 | * LANE2: Add to the end of the list to satisfy 8.1.13 |
| 1498 | */ | 1494 | */ |
| 1499 | static inline void | 1495 | static inline void |
| 1500 | lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add) | 1496 | lec_arp_add(struct lec_priv *priv, struct lec_arp_table *to_add) |
| 1501 | { | 1497 | { |
| 1502 | unsigned short place; | 1498 | unsigned short place; |
| 1503 | struct lec_arp_table *tmp; | 1499 | struct lec_arp_table *tmp; |
| 1504 | 1500 | ||
| 1505 | place = HASH(to_add->mac_addr[ETH_ALEN-1]); | 1501 | place = HASH(to_add->mac_addr[ETH_ALEN - 1]); |
| 1506 | tmp = priv->lec_arp_tables[place]; | 1502 | tmp = priv->lec_arp_tables[place]; |
| 1507 | to_add->next = NULL; | 1503 | to_add->next = NULL; |
| 1508 | if (tmp == NULL) | 1504 | if (tmp == NULL) |
| 1509 | priv->lec_arp_tables[place] = to_add; | 1505 | priv->lec_arp_tables[place] = to_add; |
| 1510 | 1506 | ||
| 1511 | else { /* add to the end */ | 1507 | else { /* add to the end */ |
| 1512 | while (tmp->next) | 1508 | while (tmp->next) |
| 1513 | tmp = tmp->next; | 1509 | tmp = tmp->next; |
| 1514 | tmp->next = to_add; | 1510 | tmp->next = to_add; |
| 1515 | } | 1511 | } |
| 1516 | 1512 | ||
| 1517 | DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", | 1513 | DPRINTK("LEC_ARP: Added entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", |
| 1518 | 0xff&to_add->mac_addr[0], 0xff&to_add->mac_addr[1], | 1514 | 0xff & to_add->mac_addr[0], 0xff & to_add->mac_addr[1], |
| 1519 | 0xff&to_add->mac_addr[2], 0xff&to_add->mac_addr[3], | 1515 | 0xff & to_add->mac_addr[2], 0xff & to_add->mac_addr[3], |
| 1520 | 0xff&to_add->mac_addr[4], 0xff&to_add->mac_addr[5]); | 1516 | 0xff & to_add->mac_addr[4], 0xff & to_add->mac_addr[5]); |
| 1521 | } | 1517 | } |
| 1522 | 1518 | ||
| 1523 | /* | 1519 | /* |
| 1524 | * Remove entry from lec_arp_table | 1520 | * Remove entry from lec_arp_table |
| 1525 | */ | 1521 | */ |
| 1526 | static int | 1522 | static int |
| 1527 | lec_arp_remove(struct lec_priv *priv, | 1523 | lec_arp_remove(struct lec_priv *priv, struct lec_arp_table *to_remove) |
| 1528 | struct lec_arp_table *to_remove) | ||
| 1529 | { | 1524 | { |
| 1530 | unsigned short place; | 1525 | unsigned short place; |
| 1531 | struct lec_arp_table *tmp; | 1526 | struct lec_arp_table *tmp; |
| 1532 | int remove_vcc=1; | 1527 | int remove_vcc = 1; |
| 1533 | 1528 | ||
| 1534 | if (!to_remove) { | 1529 | if (!to_remove) { |
| 1535 | return -1; | 1530 | return -1; |
| 1536 | } | 1531 | } |
| 1537 | place = HASH(to_remove->mac_addr[ETH_ALEN-1]); | 1532 | place = HASH(to_remove->mac_addr[ETH_ALEN - 1]); |
| 1538 | tmp = priv->lec_arp_tables[place]; | 1533 | tmp = priv->lec_arp_tables[place]; |
| 1539 | if (tmp == to_remove) { | 1534 | if (tmp == to_remove) { |
| 1540 | priv->lec_arp_tables[place] = tmp->next; | 1535 | priv->lec_arp_tables[place] = tmp->next; |
| 1541 | } else { | 1536 | } else { |
| 1542 | while(tmp && tmp->next != to_remove) { | 1537 | while (tmp && tmp->next != to_remove) { |
| 1543 | tmp = tmp->next; | 1538 | tmp = tmp->next; |
| 1544 | } | 1539 | } |
| 1545 | if (!tmp) {/* Entry was not found */ | 1540 | if (!tmp) { /* Entry was not found */ |
| 1546 | return -1; | 1541 | return -1; |
| 1547 | } | 1542 | } |
| 1548 | } | 1543 | } |
| 1549 | tmp->next = to_remove->next; | 1544 | tmp->next = to_remove->next; |
| 1550 | del_timer(&to_remove->timer); | 1545 | del_timer(&to_remove->timer); |
| 1551 | 1546 | ||
| 1552 | /* If this is the only MAC connected to this VCC, also tear down | 1547 | /* If this is the only MAC connected to this VCC, also tear down |
| 1553 | the VCC */ | 1548 | the VCC */ |
| 1554 | if (to_remove->status >= ESI_FLUSH_PENDING) { | 1549 | if (to_remove->status >= ESI_FLUSH_PENDING) { |
| 1555 | /* | 1550 | /* |
| 1556 | * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT | 1551 | * ESI_FLUSH_PENDING, ESI_FORWARD_DIRECT |
| 1557 | */ | 1552 | */ |
| 1558 | for(place = 0; place < LEC_ARP_TABLE_SIZE; place++) { | 1553 | for (place = 0; place < LEC_ARP_TABLE_SIZE; place++) { |
| 1559 | for(tmp = priv->lec_arp_tables[place]; tmp != NULL; tmp = tmp->next) { | 1554 | for (tmp = priv->lec_arp_tables[place]; tmp != NULL; |
| 1560 | if (memcmp(tmp->atm_addr, to_remove->atm_addr, | 1555 | tmp = tmp->next) { |
| 1561 | ATM_ESA_LEN)==0) { | 1556 | if (memcmp |
| 1562 | remove_vcc=0; | 1557 | (tmp->atm_addr, to_remove->atm_addr, |
| 1563 | break; | 1558 | ATM_ESA_LEN) == 0) { |
| 1564 | } | 1559 | remove_vcc = 0; |
| 1565 | } | 1560 | break; |
| 1566 | } | 1561 | } |
| 1567 | if (remove_vcc) | 1562 | } |
| 1568 | lec_arp_clear_vccs(to_remove); | 1563 | } |
| 1569 | } | 1564 | if (remove_vcc) |
| 1570 | skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */ | 1565 | lec_arp_clear_vccs(to_remove); |
| 1571 | 1566 | } | |
| 1572 | DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", | 1567 | skb_queue_purge(&to_remove->tx_wait); /* FIXME: good place for this? */ |
| 1573 | 0xff&to_remove->mac_addr[0], 0xff&to_remove->mac_addr[1], | 1568 | |
| 1574 | 0xff&to_remove->mac_addr[2], 0xff&to_remove->mac_addr[3], | 1569 | DPRINTK("LEC_ARP: Removed entry:%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", |
| 1575 | 0xff&to_remove->mac_addr[4], 0xff&to_remove->mac_addr[5]); | 1570 | 0xff & to_remove->mac_addr[0], 0xff & to_remove->mac_addr[1], |
| 1576 | return 0; | 1571 | 0xff & to_remove->mac_addr[2], 0xff & to_remove->mac_addr[3], |
| 1572 | 0xff & to_remove->mac_addr[4], 0xff & to_remove->mac_addr[5]); | ||
| 1573 | return 0; | ||
| 1577 | } | 1574 | } |
| 1578 | 1575 | ||
| 1579 | #if DEBUG_ARP_TABLE | 1576 | #if DEBUG_ARP_TABLE |
| 1580 | static char* | 1577 | static char *get_status_string(unsigned char st) |
| 1581 | get_status_string(unsigned char st) | ||
| 1582 | { | 1578 | { |
| 1583 | switch(st) { | 1579 | switch (st) { |
| 1584 | case ESI_UNKNOWN: | 1580 | case ESI_UNKNOWN: |
| 1585 | return "ESI_UNKNOWN"; | 1581 | return "ESI_UNKNOWN"; |
| 1586 | case ESI_ARP_PENDING: | 1582 | case ESI_ARP_PENDING: |
| 1587 | return "ESI_ARP_PENDING"; | 1583 | return "ESI_ARP_PENDING"; |
| 1588 | case ESI_VC_PENDING: | 1584 | case ESI_VC_PENDING: |
| 1589 | return "ESI_VC_PENDING"; | 1585 | return "ESI_VC_PENDING"; |
| 1590 | case ESI_FLUSH_PENDING: | 1586 | case ESI_FLUSH_PENDING: |
| 1591 | return "ESI_FLUSH_PENDING"; | 1587 | return "ESI_FLUSH_PENDING"; |
| 1592 | case ESI_FORWARD_DIRECT: | 1588 | case ESI_FORWARD_DIRECT: |
| 1593 | return "ESI_FORWARD_DIRECT"; | 1589 | return "ESI_FORWARD_DIRECT"; |
| 1594 | default: | 1590 | default: |
| 1595 | return "<UNKNOWN>"; | 1591 | return "<UNKNOWN>"; |
| 1596 | } | 1592 | } |
| 1597 | } | 1593 | } |
| 1598 | #endif | 1594 | #endif |
| 1599 | 1595 | ||
| 1600 | static void | 1596 | static void dump_arp_table(struct lec_priv *priv) |
| 1601 | dump_arp_table(struct lec_priv *priv) | ||
| 1602 | { | 1597 | { |
| 1603 | #if DEBUG_ARP_TABLE | 1598 | #if DEBUG_ARP_TABLE |
| 1604 | int i,j, offset; | 1599 | int i, j, offset; |
| 1605 | struct lec_arp_table *rulla; | 1600 | struct lec_arp_table *rulla; |
| 1606 | char buf[1024]; | 1601 | char buf[1024]; |
| 1607 | struct lec_arp_table **lec_arp_tables = | 1602 | struct lec_arp_table **lec_arp_tables = |
| 1608 | (struct lec_arp_table **)priv->lec_arp_tables; | 1603 | (struct lec_arp_table **)priv->lec_arp_tables; |
| 1609 | struct lec_arp_table *lec_arp_empty_ones = | 1604 | struct lec_arp_table *lec_arp_empty_ones = |
| 1610 | (struct lec_arp_table *)priv->lec_arp_empty_ones; | 1605 | (struct lec_arp_table *)priv->lec_arp_empty_ones; |
| 1611 | struct lec_arp_table *lec_no_forward = | 1606 | struct lec_arp_table *lec_no_forward = |
| 1612 | (struct lec_arp_table *)priv->lec_no_forward; | 1607 | (struct lec_arp_table *)priv->lec_no_forward; |
| 1613 | struct lec_arp_table *mcast_fwds = priv->mcast_fwds; | 1608 | struct lec_arp_table *mcast_fwds = priv->mcast_fwds; |
| 1614 | 1609 | ||
| 1615 | 1610 | printk("Dump %p:\n", priv); | |
| 1616 | printk("Dump %p:\n",priv); | 1611 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 1617 | for (i=0;i<LEC_ARP_TABLE_SIZE;i++) { | 1612 | rulla = lec_arp_tables[i]; |
| 1618 | rulla = lec_arp_tables[i]; | 1613 | offset = 0; |
| 1619 | offset = 0; | 1614 | offset += sprintf(buf, "%d: %p\n", i, rulla); |
| 1620 | offset += sprintf(buf,"%d: %p\n",i, rulla); | 1615 | while (rulla) { |
| 1621 | while (rulla) { | 1616 | offset += sprintf(buf + offset, "Mac:"); |
| 1622 | offset += sprintf(buf+offset,"Mac:"); | 1617 | for (j = 0; j < ETH_ALEN; j++) { |
| 1623 | for(j=0;j<ETH_ALEN;j++) { | 1618 | offset += sprintf(buf + offset, |
| 1624 | offset+=sprintf(buf+offset, | 1619 | "%2.2x ", |
| 1625 | "%2.2x ", | 1620 | rulla->mac_addr[j] & 0xff); |
| 1626 | rulla->mac_addr[j]&0xff); | 1621 | } |
| 1627 | } | 1622 | offset += sprintf(buf + offset, "Atm:"); |
| 1628 | offset +=sprintf(buf+offset,"Atm:"); | 1623 | for (j = 0; j < ATM_ESA_LEN; j++) { |
| 1629 | for(j=0;j<ATM_ESA_LEN;j++) { | 1624 | offset += sprintf(buf + offset, |
| 1630 | offset+=sprintf(buf+offset, | 1625 | "%2.2x ", |
| 1631 | "%2.2x ", | 1626 | rulla->atm_addr[j] & 0xff); |
| 1632 | rulla->atm_addr[j]&0xff); | 1627 | } |
| 1633 | } | 1628 | offset += sprintf(buf + offset, |
| 1634 | offset+=sprintf(buf+offset, | 1629 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", |
| 1635 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", | 1630 | rulla->vcc ? rulla->vcc->vpi : 0, |
| 1636 | rulla->vcc?rulla->vcc->vpi:0, | 1631 | rulla->vcc ? rulla->vcc->vci : 0, |
| 1637 | rulla->vcc?rulla->vcc->vci:0, | 1632 | rulla->recv_vcc ? rulla->recv_vcc-> |
| 1638 | rulla->recv_vcc?rulla->recv_vcc->vpi:0, | 1633 | vpi : 0, |
| 1639 | rulla->recv_vcc?rulla->recv_vcc->vci:0, | 1634 | rulla->recv_vcc ? rulla->recv_vcc-> |
| 1640 | rulla->last_used, | 1635 | vci : 0, rulla->last_used, |
| 1641 | rulla->timestamp, rulla->no_tries); | 1636 | rulla->timestamp, rulla->no_tries); |
| 1642 | offset+=sprintf(buf+offset, | 1637 | offset += |
| 1643 | "Flags:%x, Packets_flooded:%x, Status: %s ", | 1638 | sprintf(buf + offset, |
| 1644 | rulla->flags, rulla->packets_flooded, | 1639 | "Flags:%x, Packets_flooded:%x, Status: %s ", |
| 1645 | get_status_string(rulla->status)); | 1640 | rulla->flags, rulla->packets_flooded, |
| 1646 | offset+=sprintf(buf+offset,"->%p\n",rulla->next); | 1641 | get_status_string(rulla->status)); |
| 1647 | rulla = rulla->next; | 1642 | offset += sprintf(buf + offset, "->%p\n", rulla->next); |
| 1648 | } | 1643 | rulla = rulla->next; |
| 1649 | printk("%s",buf); | 1644 | } |
| 1650 | } | 1645 | printk("%s", buf); |
| 1651 | rulla = lec_no_forward; | 1646 | } |
| 1652 | if (rulla) | 1647 | rulla = lec_no_forward; |
| 1653 | printk("No forward\n"); | 1648 | if (rulla) |
| 1654 | while(rulla) { | 1649 | printk("No forward\n"); |
| 1655 | offset=0; | 1650 | while (rulla) { |
| 1656 | offset += sprintf(buf+offset,"Mac:"); | 1651 | offset = 0; |
| 1657 | for(j=0;j<ETH_ALEN;j++) { | 1652 | offset += sprintf(buf + offset, "Mac:"); |
| 1658 | offset+=sprintf(buf+offset,"%2.2x ", | 1653 | for (j = 0; j < ETH_ALEN; j++) { |
| 1659 | rulla->mac_addr[j]&0xff); | 1654 | offset += sprintf(buf + offset, "%2.2x ", |
| 1660 | } | 1655 | rulla->mac_addr[j] & 0xff); |
| 1661 | offset +=sprintf(buf+offset,"Atm:"); | 1656 | } |
| 1662 | for(j=0;j<ATM_ESA_LEN;j++) { | 1657 | offset += sprintf(buf + offset, "Atm:"); |
| 1663 | offset+=sprintf(buf+offset,"%2.2x ", | 1658 | for (j = 0; j < ATM_ESA_LEN; j++) { |
| 1664 | rulla->atm_addr[j]&0xff); | 1659 | offset += sprintf(buf + offset, "%2.2x ", |
| 1665 | } | 1660 | rulla->atm_addr[j] & 0xff); |
| 1666 | offset+=sprintf(buf+offset, | 1661 | } |
| 1667 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", | 1662 | offset += sprintf(buf + offset, |
| 1668 | rulla->vcc?rulla->vcc->vpi:0, | 1663 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", |
| 1669 | rulla->vcc?rulla->vcc->vci:0, | 1664 | rulla->vcc ? rulla->vcc->vpi : 0, |
| 1670 | rulla->recv_vcc?rulla->recv_vcc->vpi:0, | 1665 | rulla->vcc ? rulla->vcc->vci : 0, |
| 1671 | rulla->recv_vcc?rulla->recv_vcc->vci:0, | 1666 | rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, |
| 1672 | rulla->last_used, | 1667 | rulla->recv_vcc ? rulla->recv_vcc->vci : 0, |
| 1673 | rulla->timestamp, rulla->no_tries); | 1668 | rulla->last_used, |
| 1674 | offset+=sprintf(buf+offset, | 1669 | rulla->timestamp, rulla->no_tries); |
| 1675 | "Flags:%x, Packets_flooded:%x, Status: %s ", | 1670 | offset += sprintf(buf + offset, |
| 1676 | rulla->flags, rulla->packets_flooded, | 1671 | "Flags:%x, Packets_flooded:%x, Status: %s ", |
| 1677 | get_status_string(rulla->status)); | 1672 | rulla->flags, rulla->packets_flooded, |
| 1678 | offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); | 1673 | get_status_string(rulla->status)); |
| 1679 | rulla = rulla->next; | 1674 | offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next); |
| 1680 | printk("%s",buf); | 1675 | rulla = rulla->next; |
| 1681 | } | 1676 | printk("%s", buf); |
| 1682 | rulla = lec_arp_empty_ones; | 1677 | } |
| 1683 | if (rulla) | 1678 | rulla = lec_arp_empty_ones; |
| 1684 | printk("Empty ones\n"); | 1679 | if (rulla) |
| 1685 | while(rulla) { | 1680 | printk("Empty ones\n"); |
| 1686 | offset=0; | 1681 | while (rulla) { |
| 1687 | offset += sprintf(buf+offset,"Mac:"); | 1682 | offset = 0; |
| 1688 | for(j=0;j<ETH_ALEN;j++) { | 1683 | offset += sprintf(buf + offset, "Mac:"); |
| 1689 | offset+=sprintf(buf+offset,"%2.2x ", | 1684 | for (j = 0; j < ETH_ALEN; j++) { |
| 1690 | rulla->mac_addr[j]&0xff); | 1685 | offset += sprintf(buf + offset, "%2.2x ", |
| 1691 | } | 1686 | rulla->mac_addr[j] & 0xff); |
| 1692 | offset +=sprintf(buf+offset,"Atm:"); | 1687 | } |
| 1693 | for(j=0;j<ATM_ESA_LEN;j++) { | 1688 | offset += sprintf(buf + offset, "Atm:"); |
| 1694 | offset+=sprintf(buf+offset,"%2.2x ", | 1689 | for (j = 0; j < ATM_ESA_LEN; j++) { |
| 1695 | rulla->atm_addr[j]&0xff); | 1690 | offset += sprintf(buf + offset, "%2.2x ", |
| 1696 | } | 1691 | rulla->atm_addr[j] & 0xff); |
| 1697 | offset+=sprintf(buf+offset, | 1692 | } |
| 1698 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", | 1693 | offset += sprintf(buf + offset, |
| 1699 | rulla->vcc?rulla->vcc->vpi:0, | 1694 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", |
| 1700 | rulla->vcc?rulla->vcc->vci:0, | 1695 | rulla->vcc ? rulla->vcc->vpi : 0, |
| 1701 | rulla->recv_vcc?rulla->recv_vcc->vpi:0, | 1696 | rulla->vcc ? rulla->vcc->vci : 0, |
| 1702 | rulla->recv_vcc?rulla->recv_vcc->vci:0, | 1697 | rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, |
| 1703 | rulla->last_used, | 1698 | rulla->recv_vcc ? rulla->recv_vcc->vci : 0, |
| 1704 | rulla->timestamp, rulla->no_tries); | 1699 | rulla->last_used, |
| 1705 | offset+=sprintf(buf+offset, | 1700 | rulla->timestamp, rulla->no_tries); |
| 1706 | "Flags:%x, Packets_flooded:%x, Status: %s ", | 1701 | offset += sprintf(buf + offset, |
| 1707 | rulla->flags, rulla->packets_flooded, | 1702 | "Flags:%x, Packets_flooded:%x, Status: %s ", |
| 1708 | get_status_string(rulla->status)); | 1703 | rulla->flags, rulla->packets_flooded, |
| 1709 | offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); | 1704 | get_status_string(rulla->status)); |
| 1710 | rulla = rulla->next; | 1705 | offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next); |
| 1711 | printk("%s",buf); | 1706 | rulla = rulla->next; |
| 1712 | } | 1707 | printk("%s", buf); |
| 1713 | 1708 | } | |
| 1714 | rulla = mcast_fwds; | 1709 | |
| 1715 | if (rulla) | 1710 | rulla = mcast_fwds; |
| 1716 | printk("Multicast Forward VCCs\n"); | 1711 | if (rulla) |
| 1717 | while(rulla) { | 1712 | printk("Multicast Forward VCCs\n"); |
| 1718 | offset=0; | 1713 | while (rulla) { |
| 1719 | offset += sprintf(buf+offset,"Mac:"); | 1714 | offset = 0; |
| 1720 | for(j=0;j<ETH_ALEN;j++) { | 1715 | offset += sprintf(buf + offset, "Mac:"); |
| 1721 | offset+=sprintf(buf+offset,"%2.2x ", | 1716 | for (j = 0; j < ETH_ALEN; j++) { |
| 1722 | rulla->mac_addr[j]&0xff); | 1717 | offset += sprintf(buf + offset, "%2.2x ", |
| 1723 | } | 1718 | rulla->mac_addr[j] & 0xff); |
| 1724 | offset +=sprintf(buf+offset,"Atm:"); | 1719 | } |
| 1725 | for(j=0;j<ATM_ESA_LEN;j++) { | 1720 | offset += sprintf(buf + offset, "Atm:"); |
| 1726 | offset+=sprintf(buf+offset,"%2.2x ", | 1721 | for (j = 0; j < ATM_ESA_LEN; j++) { |
| 1727 | rulla->atm_addr[j]&0xff); | 1722 | offset += sprintf(buf + offset, "%2.2x ", |
| 1728 | } | 1723 | rulla->atm_addr[j] & 0xff); |
| 1729 | offset+=sprintf(buf+offset, | 1724 | } |
| 1730 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", | 1725 | offset += sprintf(buf + offset, |
| 1731 | rulla->vcc?rulla->vcc->vpi:0, | 1726 | "Vcc vpi:%d vci:%d, Recv_vcc vpi:%d vci:%d Last_used:%lx, Timestamp:%lx, No_tries:%d ", |
| 1732 | rulla->vcc?rulla->vcc->vci:0, | 1727 | rulla->vcc ? rulla->vcc->vpi : 0, |
| 1733 | rulla->recv_vcc?rulla->recv_vcc->vpi:0, | 1728 | rulla->vcc ? rulla->vcc->vci : 0, |
| 1734 | rulla->recv_vcc?rulla->recv_vcc->vci:0, | 1729 | rulla->recv_vcc ? rulla->recv_vcc->vpi : 0, |
| 1735 | rulla->last_used, | 1730 | rulla->recv_vcc ? rulla->recv_vcc->vci : 0, |
| 1736 | rulla->timestamp, rulla->no_tries); | 1731 | rulla->last_used, |
| 1737 | offset+=sprintf(buf+offset, | 1732 | rulla->timestamp, rulla->no_tries); |
| 1738 | "Flags:%x, Packets_flooded:%x, Status: %s ", | 1733 | offset += sprintf(buf + offset, |
| 1739 | rulla->flags, rulla->packets_flooded, | 1734 | "Flags:%x, Packets_flooded:%x, Status: %s ", |
| 1740 | get_status_string(rulla->status)); | 1735 | rulla->flags, rulla->packets_flooded, |
| 1741 | offset+=sprintf(buf+offset,"->%lx\n",(long)rulla->next); | 1736 | get_status_string(rulla->status)); |
| 1742 | rulla = rulla->next; | 1737 | offset += sprintf(buf + offset, "->%lx\n", (long)rulla->next); |
| 1743 | printk("%s",buf); | 1738 | rulla = rulla->next; |
| 1744 | } | 1739 | printk("%s", buf); |
| 1740 | } | ||
| 1745 | 1741 | ||
| 1746 | #endif | 1742 | #endif |
| 1747 | } | 1743 | } |
| @@ -1749,177 +1745,168 @@ dump_arp_table(struct lec_priv *priv) | |||
| 1749 | /* | 1745 | /* |
| 1750 | * Destruction of arp-cache | 1746 | * Destruction of arp-cache |
| 1751 | */ | 1747 | */ |
| 1752 | static void | 1748 | static void lec_arp_destroy(struct lec_priv *priv) |
| 1753 | lec_arp_destroy(struct lec_priv *priv) | ||
| 1754 | { | 1749 | { |
| 1755 | unsigned long flags; | 1750 | unsigned long flags; |
| 1756 | struct lec_arp_table *entry, *next; | 1751 | struct lec_arp_table *entry, *next; |
| 1757 | int i; | 1752 | int i; |
| 1753 | |||
| 1754 | del_timer_sync(&priv->lec_arp_timer); | ||
| 1758 | 1755 | ||
| 1759 | del_timer_sync(&priv->lec_arp_timer); | 1756 | /* |
| 1760 | 1757 | * Remove all entries | |
| 1761 | /* | 1758 | */ |
| 1762 | * Remove all entries | ||
| 1763 | */ | ||
| 1764 | 1759 | ||
| 1765 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 1760 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 1766 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 1761 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 1767 | for(entry = priv->lec_arp_tables[i]; entry != NULL; entry=next) { | 1762 | for (entry = priv->lec_arp_tables[i]; entry != NULL; |
| 1768 | next = entry->next; | 1763 | entry = next) { |
| 1769 | lec_arp_remove(priv, entry); | 1764 | next = entry->next; |
| 1770 | kfree(entry); | 1765 | lec_arp_remove(priv, entry); |
| 1771 | } | 1766 | kfree(entry); |
| 1772 | } | 1767 | } |
| 1773 | entry = priv->lec_arp_empty_ones; | 1768 | } |
| 1774 | while(entry) { | 1769 | entry = priv->lec_arp_empty_ones; |
| 1775 | next = entry->next; | 1770 | while (entry) { |
| 1776 | del_timer_sync(&entry->timer); | 1771 | next = entry->next; |
| 1777 | lec_arp_clear_vccs(entry); | 1772 | del_timer_sync(&entry->timer); |
| 1778 | kfree(entry); | 1773 | lec_arp_clear_vccs(entry); |
| 1779 | entry = next; | 1774 | kfree(entry); |
| 1780 | } | 1775 | entry = next; |
| 1781 | priv->lec_arp_empty_ones = NULL; | 1776 | } |
| 1782 | entry = priv->lec_no_forward; | 1777 | priv->lec_arp_empty_ones = NULL; |
| 1783 | while(entry) { | 1778 | entry = priv->lec_no_forward; |
| 1784 | next = entry->next; | 1779 | while (entry) { |
| 1785 | del_timer_sync(&entry->timer); | 1780 | next = entry->next; |
| 1786 | lec_arp_clear_vccs(entry); | 1781 | del_timer_sync(&entry->timer); |
| 1787 | kfree(entry); | 1782 | lec_arp_clear_vccs(entry); |
| 1788 | entry = next; | 1783 | kfree(entry); |
| 1789 | } | 1784 | entry = next; |
| 1790 | priv->lec_no_forward = NULL; | 1785 | } |
| 1791 | entry = priv->mcast_fwds; | 1786 | priv->lec_no_forward = NULL; |
| 1792 | while(entry) { | 1787 | entry = priv->mcast_fwds; |
| 1793 | next = entry->next; | 1788 | while (entry) { |
| 1794 | /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ | 1789 | next = entry->next; |
| 1795 | lec_arp_clear_vccs(entry); | 1790 | /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ |
| 1796 | kfree(entry); | 1791 | lec_arp_clear_vccs(entry); |
| 1797 | entry = next; | 1792 | kfree(entry); |
| 1798 | } | 1793 | entry = next; |
| 1799 | priv->mcast_fwds = NULL; | 1794 | } |
| 1800 | priv->mcast_vcc = NULL; | 1795 | priv->mcast_fwds = NULL; |
| 1801 | memset(priv->lec_arp_tables, 0, | 1796 | priv->mcast_vcc = NULL; |
| 1802 | sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE); | 1797 | memset(priv->lec_arp_tables, 0, |
| 1798 | sizeof(struct lec_arp_table *) * LEC_ARP_TABLE_SIZE); | ||
| 1803 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 1799 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 1804 | } | 1800 | } |
| 1805 | 1801 | ||
| 1806 | |||
| 1807 | /* | 1802 | /* |
| 1808 | * Find entry by mac_address | 1803 | * Find entry by mac_address |
| 1809 | */ | 1804 | */ |
| 1810 | static struct lec_arp_table* | 1805 | static struct lec_arp_table *lec_arp_find(struct lec_priv *priv, |
| 1811 | lec_arp_find(struct lec_priv *priv, | 1806 | unsigned char *mac_addr) |
| 1812 | unsigned char *mac_addr) | ||
| 1813 | { | 1807 | { |
| 1814 | unsigned short place; | 1808 | unsigned short place; |
| 1815 | struct lec_arp_table *to_return; | 1809 | struct lec_arp_table *to_return; |
| 1816 | 1810 | ||
| 1817 | DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", | 1811 | DPRINTK("LEC_ARP: lec_arp_find :%2.2x %2.2x %2.2x %2.2x %2.2x %2.2x\n", |
| 1818 | mac_addr[0]&0xff, mac_addr[1]&0xff, mac_addr[2]&0xff, | 1812 | mac_addr[0] & 0xff, mac_addr[1] & 0xff, mac_addr[2] & 0xff, |
| 1819 | mac_addr[3]&0xff, mac_addr[4]&0xff, mac_addr[5]&0xff); | 1813 | mac_addr[3] & 0xff, mac_addr[4] & 0xff, mac_addr[5] & 0xff); |
| 1820 | place = HASH(mac_addr[ETH_ALEN-1]); | 1814 | place = HASH(mac_addr[ETH_ALEN - 1]); |
| 1821 | 1815 | ||
| 1822 | to_return = priv->lec_arp_tables[place]; | 1816 | to_return = priv->lec_arp_tables[place]; |
| 1823 | while(to_return) { | 1817 | while (to_return) { |
| 1824 | if (!compare_ether_addr(mac_addr, to_return->mac_addr)) { | 1818 | if (!compare_ether_addr(mac_addr, to_return->mac_addr)) { |
| 1825 | return to_return; | 1819 | return to_return; |
| 1826 | } | 1820 | } |
| 1827 | to_return = to_return->next; | 1821 | to_return = to_return->next; |
| 1828 | } | 1822 | } |
| 1829 | return NULL; | 1823 | return NULL; |
| 1830 | } | 1824 | } |
| 1831 | 1825 | ||
| 1832 | static struct lec_arp_table* | 1826 | static struct lec_arp_table *make_entry(struct lec_priv *priv, |
| 1833 | make_entry(struct lec_priv *priv, unsigned char *mac_addr) | 1827 | unsigned char *mac_addr) |
| 1834 | { | 1828 | { |
| 1835 | struct lec_arp_table *to_return; | 1829 | struct lec_arp_table *to_return; |
| 1836 | 1830 | ||
| 1837 | to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); | 1831 | to_return = kzalloc(sizeof(struct lec_arp_table), GFP_ATOMIC); |
| 1838 | if (!to_return) { | 1832 | if (!to_return) { |
| 1839 | printk("LEC: Arp entry kmalloc failed\n"); | 1833 | printk("LEC: Arp entry kmalloc failed\n"); |
| 1840 | return NULL; | 1834 | return NULL; |
| 1841 | } | 1835 | } |
| 1842 | memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); | 1836 | memcpy(to_return->mac_addr, mac_addr, ETH_ALEN); |
| 1843 | init_timer(&to_return->timer); | 1837 | init_timer(&to_return->timer); |
| 1844 | to_return->timer.function = lec_arp_expire_arp; | 1838 | to_return->timer.function = lec_arp_expire_arp; |
| 1845 | to_return->timer.data = (unsigned long) to_return; | 1839 | to_return->timer.data = (unsigned long)to_return; |
| 1846 | to_return->last_used = jiffies; | 1840 | to_return->last_used = jiffies; |
| 1847 | to_return->priv = priv; | 1841 | to_return->priv = priv; |
| 1848 | skb_queue_head_init(&to_return->tx_wait); | 1842 | skb_queue_head_init(&to_return->tx_wait); |
| 1849 | return to_return; | 1843 | return to_return; |
| 1850 | } | 1844 | } |
| 1851 | 1845 | ||
| 1852 | /* | 1846 | /* Arp sent timer expired */ |
| 1853 | * | 1847 | static void lec_arp_expire_arp(unsigned long data) |
| 1854 | * Arp sent timer expired | ||
| 1855 | * | ||
| 1856 | */ | ||
| 1857 | static void | ||
| 1858 | lec_arp_expire_arp(unsigned long data) | ||
| 1859 | { | 1848 | { |
| 1860 | struct lec_arp_table *entry; | 1849 | struct lec_arp_table *entry; |
| 1861 | 1850 | ||
| 1862 | entry = (struct lec_arp_table *)data; | 1851 | entry = (struct lec_arp_table *)data; |
| 1863 | 1852 | ||
| 1864 | DPRINTK("lec_arp_expire_arp\n"); | 1853 | DPRINTK("lec_arp_expire_arp\n"); |
| 1865 | if (entry->status == ESI_ARP_PENDING) { | 1854 | if (entry->status == ESI_ARP_PENDING) { |
| 1866 | if (entry->no_tries <= entry->priv->max_retry_count) { | 1855 | if (entry->no_tries <= entry->priv->max_retry_count) { |
| 1867 | if (entry->is_rdesc) | 1856 | if (entry->is_rdesc) |
| 1868 | send_to_lecd(entry->priv, l_rdesc_arp_xmt, entry->mac_addr, NULL, NULL); | 1857 | send_to_lecd(entry->priv, l_rdesc_arp_xmt, |
| 1869 | else | 1858 | entry->mac_addr, NULL, NULL); |
| 1870 | send_to_lecd(entry->priv, l_arp_xmt, entry->mac_addr, NULL, NULL); | 1859 | else |
| 1871 | entry->no_tries++; | 1860 | send_to_lecd(entry->priv, l_arp_xmt, |
| 1872 | } | 1861 | entry->mac_addr, NULL, NULL); |
| 1873 | mod_timer(&entry->timer, jiffies + (1*HZ)); | 1862 | entry->no_tries++; |
| 1874 | } | 1863 | } |
| 1864 | mod_timer(&entry->timer, jiffies + (1 * HZ)); | ||
| 1865 | } | ||
| 1875 | } | 1866 | } |
| 1876 | 1867 | ||
| 1877 | /* | 1868 | /* Unknown/unused vcc expire, remove associated entry */ |
| 1878 | * | 1869 | static void lec_arp_expire_vcc(unsigned long data) |
| 1879 | * Unknown/unused vcc expire, remove associated entry | ||
| 1880 | * | ||
| 1881 | */ | ||
| 1882 | static void | ||
| 1883 | lec_arp_expire_vcc(unsigned long data) | ||
| 1884 | { | 1870 | { |
| 1885 | unsigned long flags; | 1871 | unsigned long flags; |
| 1886 | struct lec_arp_table *to_remove = (struct lec_arp_table*)data; | 1872 | struct lec_arp_table *to_remove = (struct lec_arp_table *)data; |
| 1887 | struct lec_priv *priv = (struct lec_priv *)to_remove->priv; | 1873 | struct lec_priv *priv = (struct lec_priv *)to_remove->priv; |
| 1888 | struct lec_arp_table *entry = NULL; | 1874 | struct lec_arp_table *entry = NULL; |
| 1889 | 1875 | ||
| 1890 | del_timer(&to_remove->timer); | 1876 | del_timer(&to_remove->timer); |
| 1891 | 1877 | ||
| 1892 | DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n", | 1878 | DPRINTK("LEC_ARP %p %p: lec_arp_expire_vcc vpi:%d vci:%d\n", |
| 1893 | to_remove, priv, | 1879 | to_remove, priv, |
| 1894 | to_remove->vcc?to_remove->recv_vcc->vpi:0, | 1880 | to_remove->vcc ? to_remove->recv_vcc->vpi : 0, |
| 1895 | to_remove->vcc?to_remove->recv_vcc->vci:0); | 1881 | to_remove->vcc ? to_remove->recv_vcc->vci : 0); |
| 1896 | DPRINTK("eo:%p nf:%p\n",priv->lec_arp_empty_ones,priv->lec_no_forward); | 1882 | DPRINTK("eo:%p nf:%p\n", priv->lec_arp_empty_ones, |
| 1883 | priv->lec_no_forward); | ||
| 1897 | 1884 | ||
| 1898 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 1885 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 1899 | if (to_remove == priv->lec_arp_empty_ones) | 1886 | if (to_remove == priv->lec_arp_empty_ones) |
| 1900 | priv->lec_arp_empty_ones = to_remove->next; | 1887 | priv->lec_arp_empty_ones = to_remove->next; |
| 1901 | else { | 1888 | else { |
| 1902 | entry = priv->lec_arp_empty_ones; | 1889 | entry = priv->lec_arp_empty_ones; |
| 1903 | while (entry && entry->next != to_remove) | 1890 | while (entry && entry->next != to_remove) |
| 1904 | entry = entry->next; | 1891 | entry = entry->next; |
| 1905 | if (entry) | 1892 | if (entry) |
| 1906 | entry->next = to_remove->next; | 1893 | entry->next = to_remove->next; |
| 1907 | } | 1894 | } |
| 1908 | if (!entry) { | 1895 | if (!entry) { |
| 1909 | if (to_remove == priv->lec_no_forward) { | 1896 | if (to_remove == priv->lec_no_forward) { |
| 1910 | priv->lec_no_forward = to_remove->next; | 1897 | priv->lec_no_forward = to_remove->next; |
| 1911 | } else { | 1898 | } else { |
| 1912 | entry = priv->lec_no_forward; | 1899 | entry = priv->lec_no_forward; |
| 1913 | while (entry && entry->next != to_remove) | 1900 | while (entry && entry->next != to_remove) |
| 1914 | entry = entry->next; | 1901 | entry = entry->next; |
| 1915 | if (entry) | 1902 | if (entry) |
| 1916 | entry->next = to_remove->next; | 1903 | entry->next = to_remove->next; |
| 1917 | } | 1904 | } |
| 1918 | } | 1905 | } |
| 1919 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 1906 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 1920 | 1907 | ||
| 1921 | lec_arp_clear_vccs(to_remove); | 1908 | lec_arp_clear_vccs(to_remove); |
| 1922 | kfree(to_remove); | 1909 | kfree(to_remove); |
| 1923 | } | 1910 | } |
| 1924 | 1911 | ||
| 1925 | /* | 1912 | /* |
| @@ -1938,64 +1925,68 @@ lec_arp_expire_vcc(unsigned long data) | |||
| 1938 | * to ESI_FORWARD_DIRECT. This causes the flush period to end | 1925 | * to ESI_FORWARD_DIRECT. This causes the flush period to end |
| 1939 | * regardless of the progress of the flush protocol. | 1926 | * regardless of the progress of the flush protocol. |
| 1940 | */ | 1927 | */ |
| 1941 | static void | 1928 | static void lec_arp_check_expire(unsigned long data) |
| 1942 | lec_arp_check_expire(unsigned long data) | ||
| 1943 | { | 1929 | { |
| 1944 | unsigned long flags; | 1930 | unsigned long flags; |
| 1945 | struct lec_priv *priv = (struct lec_priv *)data; | 1931 | struct lec_priv *priv = (struct lec_priv *)data; |
| 1946 | struct lec_arp_table *entry, *next; | 1932 | struct lec_arp_table *entry, *next; |
| 1947 | unsigned long now; | 1933 | unsigned long now; |
| 1948 | unsigned long time_to_check; | 1934 | unsigned long time_to_check; |
| 1949 | int i; | 1935 | int i; |
| 1950 | 1936 | ||
| 1951 | DPRINTK("lec_arp_check_expire %p\n",priv); | 1937 | DPRINTK("lec_arp_check_expire %p\n", priv); |
| 1952 | DPRINTK("expire: eo:%p nf:%p\n",priv->lec_arp_empty_ones, | 1938 | DPRINTK("expire: eo:%p nf:%p\n", priv->lec_arp_empty_ones, |
| 1953 | priv->lec_no_forward); | 1939 | priv->lec_no_forward); |
| 1954 | now = jiffies; | 1940 | now = jiffies; |
| 1955 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 1941 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 1956 | for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 1942 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 1957 | for(entry = priv->lec_arp_tables[i]; entry != NULL; ) { | 1943 | for (entry = priv->lec_arp_tables[i]; entry != NULL;) { |
| 1958 | if ((entry->flags) & LEC_REMOTE_FLAG && | 1944 | if ((entry->flags) & LEC_REMOTE_FLAG && |
| 1959 | priv->topology_change) | 1945 | priv->topology_change) |
| 1960 | time_to_check = priv->forward_delay_time; | 1946 | time_to_check = priv->forward_delay_time; |
| 1961 | else | 1947 | else |
| 1962 | time_to_check = priv->aging_time; | 1948 | time_to_check = priv->aging_time; |
| 1963 | 1949 | ||
| 1964 | DPRINTK("About to expire: %lx - %lx > %lx\n", | 1950 | DPRINTK("About to expire: %lx - %lx > %lx\n", |
| 1965 | now,entry->last_used, time_to_check); | 1951 | now, entry->last_used, time_to_check); |
| 1966 | if( time_after(now, entry->last_used+ | 1952 | if (time_after(now, entry->last_used + time_to_check) |
| 1967 | time_to_check) && | 1953 | && !(entry->flags & LEC_PERMANENT_FLAG) |
| 1968 | !(entry->flags & LEC_PERMANENT_FLAG) && | 1954 | && !(entry->mac_addr[0] & 0x01)) { /* LANE2: 7.1.20 */ |
| 1969 | !(entry->mac_addr[0] & 0x01) ) { /* LANE2: 7.1.20 */ | ||
| 1970 | /* Remove entry */ | 1955 | /* Remove entry */ |
| 1971 | DPRINTK("LEC:Entry timed out\n"); | 1956 | DPRINTK("LEC:Entry timed out\n"); |
| 1972 | next = entry->next; | 1957 | next = entry->next; |
| 1973 | lec_arp_remove(priv, entry); | 1958 | lec_arp_remove(priv, entry); |
| 1974 | kfree(entry); | 1959 | kfree(entry); |
| 1975 | entry = next; | 1960 | entry = next; |
| 1976 | } else { | 1961 | } else { |
| 1977 | /* Something else */ | 1962 | /* Something else */ |
| 1978 | if ((entry->status == ESI_VC_PENDING || | 1963 | if ((entry->status == ESI_VC_PENDING || |
| 1979 | entry->status == ESI_ARP_PENDING) | 1964 | entry->status == ESI_ARP_PENDING) |
| 1980 | && time_after_eq(now, | 1965 | && time_after_eq(now, |
| 1981 | entry->timestamp + | 1966 | entry->timestamp + |
| 1982 | priv->max_unknown_frame_time)) { | 1967 | priv-> |
| 1968 | max_unknown_frame_time)) { | ||
| 1983 | entry->timestamp = jiffies; | 1969 | entry->timestamp = jiffies; |
| 1984 | entry->packets_flooded = 0; | 1970 | entry->packets_flooded = 0; |
| 1985 | if (entry->status == ESI_VC_PENDING) | 1971 | if (entry->status == ESI_VC_PENDING) |
| 1986 | send_to_lecd(priv, l_svc_setup, entry->mac_addr, entry->atm_addr, NULL); | 1972 | send_to_lecd(priv, l_svc_setup, |
| 1973 | entry->mac_addr, | ||
| 1974 | entry->atm_addr, | ||
| 1975 | NULL); | ||
| 1987 | } | 1976 | } |
| 1988 | if (entry->status == ESI_FLUSH_PENDING | 1977 | if (entry->status == ESI_FLUSH_PENDING |
| 1989 | && | 1978 | && |
| 1990 | time_after_eq(now, entry->timestamp+ | 1979 | time_after_eq(now, entry->timestamp + |
| 1991 | priv->path_switching_delay)) { | 1980 | priv->path_switching_delay)) { |
| 1992 | struct sk_buff *skb; | 1981 | struct sk_buff *skb; |
| 1993 | 1982 | ||
| 1994 | while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) | 1983 | while ((skb = |
| 1995 | lec_send(entry->vcc, skb, entry->priv); | 1984 | skb_dequeue(&entry->tx_wait)) != |
| 1985 | NULL) | ||
| 1986 | lec_send(entry->vcc, skb, | ||
| 1987 | entry->priv); | ||
| 1996 | entry->last_used = jiffies; | 1988 | entry->last_used = jiffies; |
| 1997 | entry->status = | 1989 | entry->status = ESI_FORWARD_DIRECT; |
| 1998 | ESI_FORWARD_DIRECT; | ||
| 1999 | } | 1990 | } |
| 2000 | entry = entry->next; | 1991 | entry = entry->next; |
| 2001 | } | 1992 | } |
| @@ -2003,93 +1994,101 @@ lec_arp_check_expire(unsigned long data) | |||
| 2003 | } | 1994 | } |
| 2004 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 1995 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2005 | 1996 | ||
| 2006 | mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL); | 1997 | mod_timer(&priv->lec_arp_timer, jiffies + LEC_ARP_REFRESH_INTERVAL); |
| 2007 | } | 1998 | } |
| 1999 | |||
| 2008 | /* | 2000 | /* |
| 2009 | * Try to find vcc where mac_address is attached. | 2001 | * Try to find vcc where mac_address is attached. |
| 2010 | * | 2002 | * |
| 2011 | */ | 2003 | */ |
| 2012 | static struct atm_vcc* | 2004 | static struct atm_vcc *lec_arp_resolve(struct lec_priv *priv, |
| 2013 | lec_arp_resolve(struct lec_priv *priv, unsigned char *mac_to_find, | 2005 | unsigned char *mac_to_find, int is_rdesc, |
| 2014 | int is_rdesc, struct lec_arp_table **ret_entry) | 2006 | struct lec_arp_table **ret_entry) |
| 2015 | { | 2007 | { |
| 2016 | unsigned long flags; | 2008 | unsigned long flags; |
| 2017 | struct lec_arp_table *entry; | 2009 | struct lec_arp_table *entry; |
| 2018 | struct atm_vcc *found; | 2010 | struct atm_vcc *found; |
| 2019 | 2011 | ||
| 2020 | if (mac_to_find[0] & 0x01) { | 2012 | if (mac_to_find[0] & 0x01) { |
| 2021 | switch (priv->lane_version) { | 2013 | switch (priv->lane_version) { |
| 2022 | case 1: | 2014 | case 1: |
| 2023 | return priv->mcast_vcc; | 2015 | return priv->mcast_vcc; |
| 2024 | break; | 2016 | break; |
| 2025 | case 2: /* LANE2 wants arp for multicast addresses */ | 2017 | case 2: /* LANE2 wants arp for multicast addresses */ |
| 2026 | if (!compare_ether_addr(mac_to_find, bus_mac)) | 2018 | if (!compare_ether_addr(mac_to_find, bus_mac)) |
| 2027 | return priv->mcast_vcc; | 2019 | return priv->mcast_vcc; |
| 2028 | break; | 2020 | break; |
| 2029 | default: | 2021 | default: |
| 2030 | break; | 2022 | break; |
| 2031 | } | 2023 | } |
| 2032 | } | 2024 | } |
| 2033 | 2025 | ||
| 2034 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2026 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2035 | entry = lec_arp_find(priv, mac_to_find); | 2027 | entry = lec_arp_find(priv, mac_to_find); |
| 2036 | 2028 | ||
| 2037 | if (entry) { | 2029 | if (entry) { |
| 2038 | if (entry->status == ESI_FORWARD_DIRECT) { | 2030 | if (entry->status == ESI_FORWARD_DIRECT) { |
| 2039 | /* Connection Ok */ | 2031 | /* Connection Ok */ |
| 2040 | entry->last_used = jiffies; | 2032 | entry->last_used = jiffies; |
| 2041 | *ret_entry = entry; | 2033 | *ret_entry = entry; |
| 2042 | found = entry->vcc; | 2034 | found = entry->vcc; |
| 2043 | goto out; | 2035 | goto out; |
| 2044 | } | 2036 | } |
| 2045 | /* If the LE_ARP cache entry is still pending, reset count to 0 | 2037 | /* |
| 2038 | * If the LE_ARP cache entry is still pending, reset count to 0 | ||
| 2046 | * so another LE_ARP request can be made for this frame. | 2039 | * so another LE_ARP request can be made for this frame. |
| 2047 | */ | 2040 | */ |
| 2048 | if (entry->status == ESI_ARP_PENDING) { | 2041 | if (entry->status == ESI_ARP_PENDING) { |
| 2049 | entry->no_tries = 0; | 2042 | entry->no_tries = 0; |
| 2050 | } | 2043 | } |
| 2051 | /* Data direct VC not yet set up, check to see if the unknown | 2044 | /* |
| 2052 | frame count is greater than the limit. If the limit has | 2045 | * Data direct VC not yet set up, check to see if the unknown |
| 2053 | not been reached, allow the caller to send packet to | 2046 | * frame count is greater than the limit. If the limit has |
| 2054 | BUS. */ | 2047 | * not been reached, allow the caller to send packet to |
| 2055 | if (entry->status != ESI_FLUSH_PENDING && | 2048 | * BUS. |
| 2056 | entry->packets_flooded<priv->maximum_unknown_frame_count) { | 2049 | */ |
| 2057 | entry->packets_flooded++; | 2050 | if (entry->status != ESI_FLUSH_PENDING && |
| 2058 | DPRINTK("LEC_ARP: Flooding..\n"); | 2051 | entry->packets_flooded < |
| 2059 | found = priv->mcast_vcc; | 2052 | priv->maximum_unknown_frame_count) { |
| 2053 | entry->packets_flooded++; | ||
| 2054 | DPRINTK("LEC_ARP: Flooding..\n"); | ||
| 2055 | found = priv->mcast_vcc; | ||
| 2060 | goto out; | 2056 | goto out; |
| 2061 | } | 2057 | } |
| 2062 | /* We got here because entry->status == ESI_FLUSH_PENDING | 2058 | /* |
| 2059 | * We got here because entry->status == ESI_FLUSH_PENDING | ||
| 2063 | * or BUS flood limit was reached for an entry which is | 2060 | * or BUS flood limit was reached for an entry which is |
| 2064 | * in ESI_ARP_PENDING or ESI_VC_PENDING state. | 2061 | * in ESI_ARP_PENDING or ESI_VC_PENDING state. |
| 2065 | */ | 2062 | */ |
| 2066 | *ret_entry = entry; | 2063 | *ret_entry = entry; |
| 2067 | DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, entry->vcc); | 2064 | DPRINTK("lec: entry->status %d entry->vcc %p\n", entry->status, |
| 2068 | found = NULL; | 2065 | entry->vcc); |
| 2069 | } else { | 2066 | found = NULL; |
| 2070 | /* No matching entry was found */ | 2067 | } else { |
| 2071 | entry = make_entry(priv, mac_to_find); | 2068 | /* No matching entry was found */ |
| 2072 | DPRINTK("LEC_ARP: Making entry\n"); | 2069 | entry = make_entry(priv, mac_to_find); |
| 2073 | if (!entry) { | 2070 | DPRINTK("LEC_ARP: Making entry\n"); |
| 2074 | found = priv->mcast_vcc; | 2071 | if (!entry) { |
| 2072 | found = priv->mcast_vcc; | ||
| 2075 | goto out; | 2073 | goto out; |
| 2076 | } | 2074 | } |
| 2077 | lec_arp_add(priv, entry); | 2075 | lec_arp_add(priv, entry); |
| 2078 | /* We want arp-request(s) to be sent */ | 2076 | /* We want arp-request(s) to be sent */ |
| 2079 | entry->packets_flooded =1; | 2077 | entry->packets_flooded = 1; |
| 2080 | entry->status = ESI_ARP_PENDING; | 2078 | entry->status = ESI_ARP_PENDING; |
| 2081 | entry->no_tries = 1; | 2079 | entry->no_tries = 1; |
| 2082 | entry->last_used = entry->timestamp = jiffies; | 2080 | entry->last_used = entry->timestamp = jiffies; |
| 2083 | entry->is_rdesc = is_rdesc; | 2081 | entry->is_rdesc = is_rdesc; |
| 2084 | if (entry->is_rdesc) | 2082 | if (entry->is_rdesc) |
| 2085 | send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, NULL); | 2083 | send_to_lecd(priv, l_rdesc_arp_xmt, mac_to_find, NULL, |
| 2086 | else | 2084 | NULL); |
| 2087 | send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL); | 2085 | else |
| 2088 | entry->timer.expires = jiffies + (1*HZ); | 2086 | send_to_lecd(priv, l_arp_xmt, mac_to_find, NULL, NULL); |
| 2089 | entry->timer.function = lec_arp_expire_arp; | 2087 | entry->timer.expires = jiffies + (1 * HZ); |
| 2090 | add_timer(&entry->timer); | 2088 | entry->timer.function = lec_arp_expire_arp; |
| 2091 | found = priv->mcast_vcc; | 2089 | add_timer(&entry->timer); |
| 2092 | } | 2090 | found = priv->mcast_vcc; |
| 2091 | } | ||
| 2093 | 2092 | ||
| 2094 | out: | 2093 | out: |
| 2095 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2094 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| @@ -2097,30 +2096,31 @@ out: | |||
| 2097 | } | 2096 | } |
| 2098 | 2097 | ||
| 2099 | static int | 2098 | static int |
| 2100 | lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, | 2099 | lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, |
| 2101 | unsigned long permanent) | 2100 | unsigned long permanent) |
| 2102 | { | 2101 | { |
| 2103 | unsigned long flags; | 2102 | unsigned long flags; |
| 2104 | struct lec_arp_table *entry, *next; | 2103 | struct lec_arp_table *entry, *next; |
| 2105 | int i; | 2104 | int i; |
| 2106 | 2105 | ||
| 2107 | DPRINTK("lec_addr_delete\n"); | 2106 | DPRINTK("lec_addr_delete\n"); |
| 2108 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2107 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2109 | for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 2108 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 2110 | for(entry = priv->lec_arp_tables[i]; entry != NULL; entry = next) { | 2109 | for (entry = priv->lec_arp_tables[i]; entry != NULL; |
| 2111 | next = entry->next; | 2110 | entry = next) { |
| 2112 | if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) | 2111 | next = entry->next; |
| 2113 | && (permanent || | 2112 | if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN) |
| 2114 | !(entry->flags & LEC_PERMANENT_FLAG))) { | 2113 | && (permanent || |
| 2114 | !(entry->flags & LEC_PERMANENT_FLAG))) { | ||
| 2115 | lec_arp_remove(priv, entry); | 2115 | lec_arp_remove(priv, entry); |
| 2116 | kfree(entry); | 2116 | kfree(entry); |
| 2117 | } | 2117 | } |
| 2118 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2118 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2119 | return 0; | 2119 | return 0; |
| 2120 | } | 2120 | } |
| 2121 | } | 2121 | } |
| 2122 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2122 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2123 | return -1; | 2123 | return -1; |
| 2124 | } | 2124 | } |
| 2125 | 2125 | ||
| 2126 | /* | 2126 | /* |
| @@ -2128,109 +2128,109 @@ lec_addr_delete(struct lec_priv *priv, unsigned char *atm_addr, | |||
| 2128 | */ | 2128 | */ |
| 2129 | static void | 2129 | static void |
| 2130 | lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, | 2130 | lec_arp_update(struct lec_priv *priv, unsigned char *mac_addr, |
| 2131 | unsigned char *atm_addr, unsigned long remoteflag, | 2131 | unsigned char *atm_addr, unsigned long remoteflag, |
| 2132 | unsigned int targetless_le_arp) | 2132 | unsigned int targetless_le_arp) |
| 2133 | { | 2133 | { |
| 2134 | unsigned long flags; | 2134 | unsigned long flags; |
| 2135 | struct lec_arp_table *entry, *tmp; | 2135 | struct lec_arp_table *entry, *tmp; |
| 2136 | int i; | 2136 | int i; |
| 2137 | 2137 | ||
| 2138 | DPRINTK("lec:%s", (targetless_le_arp) ? "targetless ": " "); | 2138 | DPRINTK("lec:%s", (targetless_le_arp) ? "targetless " : " "); |
| 2139 | DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", | 2139 | DPRINTK("lec_arp_update mac:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", |
| 2140 | mac_addr[0],mac_addr[1],mac_addr[2],mac_addr[3], | 2140 | mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], |
| 2141 | mac_addr[4],mac_addr[5]); | 2141 | mac_addr[4], mac_addr[5]); |
| 2142 | 2142 | ||
| 2143 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2143 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2144 | entry = lec_arp_find(priv, mac_addr); | 2144 | entry = lec_arp_find(priv, mac_addr); |
| 2145 | if (entry == NULL && targetless_le_arp) | 2145 | if (entry == NULL && targetless_le_arp) |
| 2146 | goto out; /* LANE2: ignore targetless LE_ARPs for which | 2146 | goto out; /* |
| 2147 | * we have no entry in the cache. 7.1.30 | 2147 | * LANE2: ignore targetless LE_ARPs for which |
| 2148 | */ | 2148 | * we have no entry in the cache. 7.1.30 |
| 2149 | if (priv->lec_arp_empty_ones) { | 2149 | */ |
| 2150 | entry = priv->lec_arp_empty_ones; | 2150 | if (priv->lec_arp_empty_ones) { |
| 2151 | if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) { | 2151 | entry = priv->lec_arp_empty_ones; |
| 2152 | priv->lec_arp_empty_ones = entry->next; | 2152 | if (!memcmp(entry->atm_addr, atm_addr, ATM_ESA_LEN)) { |
| 2153 | } else { | 2153 | priv->lec_arp_empty_ones = entry->next; |
| 2154 | while(entry->next && memcmp(entry->next->atm_addr, | 2154 | } else { |
| 2155 | atm_addr, ATM_ESA_LEN)) | 2155 | while (entry->next && memcmp(entry->next->atm_addr, |
| 2156 | entry = entry->next; | 2156 | atm_addr, ATM_ESA_LEN)) |
| 2157 | if (entry->next) { | 2157 | entry = entry->next; |
| 2158 | tmp = entry; | 2158 | if (entry->next) { |
| 2159 | entry = entry->next; | 2159 | tmp = entry; |
| 2160 | tmp->next = entry->next; | 2160 | entry = entry->next; |
| 2161 | } else | 2161 | tmp->next = entry->next; |
| 2162 | entry = NULL; | 2162 | } else |
| 2163 | 2163 | entry = NULL; | |
| 2164 | } | 2164 | |
| 2165 | if (entry) { | 2165 | } |
| 2166 | del_timer(&entry->timer); | 2166 | if (entry) { |
| 2167 | tmp = lec_arp_find(priv, mac_addr); | 2167 | del_timer(&entry->timer); |
| 2168 | if (tmp) { | 2168 | tmp = lec_arp_find(priv, mac_addr); |
| 2169 | del_timer(&tmp->timer); | 2169 | if (tmp) { |
| 2170 | tmp->status = ESI_FORWARD_DIRECT; | 2170 | del_timer(&tmp->timer); |
| 2171 | memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN); | 2171 | tmp->status = ESI_FORWARD_DIRECT; |
| 2172 | tmp->vcc = entry->vcc; | 2172 | memcpy(tmp->atm_addr, atm_addr, ATM_ESA_LEN); |
| 2173 | tmp->old_push = entry->old_push; | 2173 | tmp->vcc = entry->vcc; |
| 2174 | tmp->last_used = jiffies; | 2174 | tmp->old_push = entry->old_push; |
| 2175 | del_timer(&entry->timer); | 2175 | tmp->last_used = jiffies; |
| 2176 | kfree(entry); | 2176 | del_timer(&entry->timer); |
| 2177 | entry=tmp; | 2177 | kfree(entry); |
| 2178 | } else { | 2178 | entry = tmp; |
| 2179 | entry->status = ESI_FORWARD_DIRECT; | 2179 | } else { |
| 2180 | memcpy(entry->mac_addr, mac_addr, ETH_ALEN); | 2180 | entry->status = ESI_FORWARD_DIRECT; |
| 2181 | entry->last_used = jiffies; | 2181 | memcpy(entry->mac_addr, mac_addr, ETH_ALEN); |
| 2182 | lec_arp_add(priv, entry); | 2182 | entry->last_used = jiffies; |
| 2183 | } | 2183 | lec_arp_add(priv, entry); |
| 2184 | if (remoteflag) | 2184 | } |
| 2185 | entry->flags|=LEC_REMOTE_FLAG; | 2185 | if (remoteflag) |
| 2186 | else | 2186 | entry->flags |= LEC_REMOTE_FLAG; |
| 2187 | entry->flags&=~LEC_REMOTE_FLAG; | 2187 | else |
| 2188 | DPRINTK("After update\n"); | 2188 | entry->flags &= ~LEC_REMOTE_FLAG; |
| 2189 | dump_arp_table(priv); | 2189 | DPRINTK("After update\n"); |
| 2190 | goto out; | 2190 | dump_arp_table(priv); |
| 2191 | } | ||
| 2192 | } | ||
| 2193 | entry = lec_arp_find(priv, mac_addr); | ||
| 2194 | if (!entry) { | ||
| 2195 | entry = make_entry(priv, mac_addr); | ||
| 2196 | if (!entry) | ||
| 2197 | goto out; | 2191 | goto out; |
| 2198 | entry->status = ESI_UNKNOWN; | 2192 | } |
| 2199 | lec_arp_add(priv, entry); | 2193 | } |
| 2200 | /* Temporary, changes before end of function */ | 2194 | entry = lec_arp_find(priv, mac_addr); |
| 2201 | } | 2195 | if (!entry) { |
| 2202 | memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); | 2196 | entry = make_entry(priv, mac_addr); |
| 2203 | del_timer(&entry->timer); | 2197 | if (!entry) |
| 2204 | for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 2198 | goto out; |
| 2205 | for(tmp = priv->lec_arp_tables[i]; tmp; tmp=tmp->next) { | 2199 | entry->status = ESI_UNKNOWN; |
| 2206 | if (entry != tmp && | 2200 | lec_arp_add(priv, entry); |
| 2207 | !memcmp(tmp->atm_addr, atm_addr, | 2201 | /* Temporary, changes before end of function */ |
| 2208 | ATM_ESA_LEN)) { | 2202 | } |
| 2209 | /* Vcc to this host exists */ | 2203 | memcpy(entry->atm_addr, atm_addr, ATM_ESA_LEN); |
| 2210 | if (tmp->status > ESI_VC_PENDING) { | 2204 | del_timer(&entry->timer); |
| 2211 | /* | 2205 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 2212 | * ESI_FLUSH_PENDING, | 2206 | for (tmp = priv->lec_arp_tables[i]; tmp; tmp = tmp->next) { |
| 2213 | * ESI_FORWARD_DIRECT | 2207 | if (entry != tmp && |
| 2214 | */ | 2208 | !memcmp(tmp->atm_addr, atm_addr, ATM_ESA_LEN)) { |
| 2215 | entry->vcc = tmp->vcc; | 2209 | /* Vcc to this host exists */ |
| 2216 | entry->old_push=tmp->old_push; | 2210 | if (tmp->status > ESI_VC_PENDING) { |
| 2217 | } | 2211 | /* |
| 2218 | entry->status=tmp->status; | 2212 | * ESI_FLUSH_PENDING, |
| 2219 | break; | 2213 | * ESI_FORWARD_DIRECT |
| 2220 | } | 2214 | */ |
| 2221 | } | 2215 | entry->vcc = tmp->vcc; |
| 2222 | } | 2216 | entry->old_push = tmp->old_push; |
| 2223 | if (remoteflag) | 2217 | } |
| 2224 | entry->flags|=LEC_REMOTE_FLAG; | 2218 | entry->status = tmp->status; |
| 2225 | else | 2219 | break; |
| 2226 | entry->flags&=~LEC_REMOTE_FLAG; | 2220 | } |
| 2227 | if (entry->status == ESI_ARP_PENDING || | 2221 | } |
| 2228 | entry->status == ESI_UNKNOWN) { | 2222 | } |
| 2229 | entry->status = ESI_VC_PENDING; | 2223 | if (remoteflag) |
| 2230 | send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, NULL); | 2224 | entry->flags |= LEC_REMOTE_FLAG; |
| 2231 | } | 2225 | else |
| 2232 | DPRINTK("After update2\n"); | 2226 | entry->flags &= ~LEC_REMOTE_FLAG; |
| 2233 | dump_arp_table(priv); | 2227 | if (entry->status == ESI_ARP_PENDING || entry->status == ESI_UNKNOWN) { |
| 2228 | entry->status = ESI_VC_PENDING; | ||
| 2229 | send_to_lecd(priv, l_svc_setup, entry->mac_addr, atm_addr, | ||
| 2230 | NULL); | ||
| 2231 | } | ||
| 2232 | DPRINTK("After update2\n"); | ||
| 2233 | dump_arp_table(priv); | ||
| 2234 | out: | 2234 | out: |
| 2235 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2235 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2236 | } | 2236 | } |
| @@ -2240,299 +2240,312 @@ out: | |||
| 2240 | */ | 2240 | */ |
| 2241 | static void | 2241 | static void |
| 2242 | lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, | 2242 | lec_vcc_added(struct lec_priv *priv, struct atmlec_ioc *ioc_data, |
| 2243 | struct atm_vcc *vcc, | 2243 | struct atm_vcc *vcc, |
| 2244 | void (*old_push)(struct atm_vcc *vcc, struct sk_buff *skb)) | 2244 | void (*old_push) (struct atm_vcc *vcc, struct sk_buff *skb)) |
| 2245 | { | 2245 | { |
| 2246 | unsigned long flags; | 2246 | unsigned long flags; |
| 2247 | struct lec_arp_table *entry; | 2247 | struct lec_arp_table *entry; |
| 2248 | int i, found_entry=0; | 2248 | int i, found_entry = 0; |
| 2249 | 2249 | ||
| 2250 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2250 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2251 | if (ioc_data->receive == 2) { | 2251 | if (ioc_data->receive == 2) { |
| 2252 | /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ | 2252 | /* Vcc for Multicast Forward. No timer, LANEv2 7.1.20 and 2.3.5.3 */ |
| 2253 | 2253 | ||
| 2254 | DPRINTK("LEC_ARP: Attaching mcast forward\n"); | 2254 | DPRINTK("LEC_ARP: Attaching mcast forward\n"); |
| 2255 | #if 0 | 2255 | #if 0 |
| 2256 | entry = lec_arp_find(priv, bus_mac); | 2256 | entry = lec_arp_find(priv, bus_mac); |
| 2257 | if (!entry) { | 2257 | if (!entry) { |
| 2258 | printk("LEC_ARP: Multicast entry not found!\n"); | 2258 | printk("LEC_ARP: Multicast entry not found!\n"); |
| 2259 | goto out; | 2259 | goto out; |
| 2260 | } | 2260 | } |
| 2261 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); | 2261 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
| 2262 | entry->recv_vcc = vcc; | 2262 | entry->recv_vcc = vcc; |
| 2263 | entry->old_recv_push = old_push; | 2263 | entry->old_recv_push = old_push; |
| 2264 | #endif | 2264 | #endif |
| 2265 | entry = make_entry(priv, bus_mac); | 2265 | entry = make_entry(priv, bus_mac); |
| 2266 | if (entry == NULL) | 2266 | if (entry == NULL) |
| 2267 | goto out; | 2267 | goto out; |
| 2268 | del_timer(&entry->timer); | 2268 | del_timer(&entry->timer); |
| 2269 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); | 2269 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
| 2270 | entry->recv_vcc = vcc; | 2270 | entry->recv_vcc = vcc; |
| 2271 | entry->old_recv_push = old_push; | 2271 | entry->old_recv_push = old_push; |
| 2272 | entry->next = priv->mcast_fwds; | 2272 | entry->next = priv->mcast_fwds; |
| 2273 | priv->mcast_fwds = entry; | 2273 | priv->mcast_fwds = entry; |
| 2274 | goto out; | 2274 | goto out; |
| 2275 | } else if (ioc_data->receive == 1) { | 2275 | } else if (ioc_data->receive == 1) { |
| 2276 | /* Vcc which we don't want to make default vcc, attach it | 2276 | /* |
| 2277 | anyway. */ | 2277 | * Vcc which we don't want to make default vcc, |
| 2278 | DPRINTK("LEC_ARP:Attaching data direct, not default :%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", | 2278 | * attach it anyway. |
| 2279 | ioc_data->atm_addr[0],ioc_data->atm_addr[1], | 2279 | */ |
| 2280 | ioc_data->atm_addr[2],ioc_data->atm_addr[3], | 2280 | DPRINTK |
| 2281 | ioc_data->atm_addr[4],ioc_data->atm_addr[5], | 2281 | ("LEC_ARP:Attaching data direct, not default: " |
| 2282 | ioc_data->atm_addr[6],ioc_data->atm_addr[7], | 2282 | "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", |
| 2283 | ioc_data->atm_addr[8],ioc_data->atm_addr[9], | 2283 | ioc_data->atm_addr[0], ioc_data->atm_addr[1], |
| 2284 | ioc_data->atm_addr[10],ioc_data->atm_addr[11], | 2284 | ioc_data->atm_addr[2], ioc_data->atm_addr[3], |
| 2285 | ioc_data->atm_addr[12],ioc_data->atm_addr[13], | 2285 | ioc_data->atm_addr[4], ioc_data->atm_addr[5], |
| 2286 | ioc_data->atm_addr[14],ioc_data->atm_addr[15], | 2286 | ioc_data->atm_addr[6], ioc_data->atm_addr[7], |
| 2287 | ioc_data->atm_addr[16],ioc_data->atm_addr[17], | 2287 | ioc_data->atm_addr[8], ioc_data->atm_addr[9], |
| 2288 | ioc_data->atm_addr[18],ioc_data->atm_addr[19]); | 2288 | ioc_data->atm_addr[10], ioc_data->atm_addr[11], |
| 2289 | entry = make_entry(priv, bus_mac); | 2289 | ioc_data->atm_addr[12], ioc_data->atm_addr[13], |
| 2290 | if (entry == NULL) | 2290 | ioc_data->atm_addr[14], ioc_data->atm_addr[15], |
| 2291 | ioc_data->atm_addr[16], ioc_data->atm_addr[17], | ||
| 2292 | ioc_data->atm_addr[18], ioc_data->atm_addr[19]); | ||
| 2293 | entry = make_entry(priv, bus_mac); | ||
| 2294 | if (entry == NULL) | ||
| 2291 | goto out; | 2295 | goto out; |
| 2292 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); | 2296 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
| 2293 | memset(entry->mac_addr, 0, ETH_ALEN); | 2297 | memset(entry->mac_addr, 0, ETH_ALEN); |
| 2294 | entry->recv_vcc = vcc; | 2298 | entry->recv_vcc = vcc; |
| 2295 | entry->old_recv_push = old_push; | 2299 | entry->old_recv_push = old_push; |
| 2296 | entry->status = ESI_UNKNOWN; | 2300 | entry->status = ESI_UNKNOWN; |
| 2297 | entry->timer.expires = jiffies + priv->vcc_timeout_period; | 2301 | entry->timer.expires = jiffies + priv->vcc_timeout_period; |
| 2298 | entry->timer.function = lec_arp_expire_vcc; | 2302 | entry->timer.function = lec_arp_expire_vcc; |
| 2299 | add_timer(&entry->timer); | 2303 | add_timer(&entry->timer); |
| 2300 | entry->next = priv->lec_no_forward; | 2304 | entry->next = priv->lec_no_forward; |
| 2301 | priv->lec_no_forward = entry; | 2305 | priv->lec_no_forward = entry; |
| 2302 | dump_arp_table(priv); | 2306 | dump_arp_table(priv); |
| 2303 | goto out; | 2307 | goto out; |
| 2304 | } | 2308 | } |
| 2305 | DPRINTK("LEC_ARP:Attaching data direct, default:%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", | 2309 | DPRINTK |
| 2306 | ioc_data->atm_addr[0],ioc_data->atm_addr[1], | 2310 | ("LEC_ARP:Attaching data direct, default: " |
| 2307 | ioc_data->atm_addr[2],ioc_data->atm_addr[3], | 2311 | "%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n", |
| 2308 | ioc_data->atm_addr[4],ioc_data->atm_addr[5], | 2312 | ioc_data->atm_addr[0], ioc_data->atm_addr[1], |
| 2309 | ioc_data->atm_addr[6],ioc_data->atm_addr[7], | 2313 | ioc_data->atm_addr[2], ioc_data->atm_addr[3], |
| 2310 | ioc_data->atm_addr[8],ioc_data->atm_addr[9], | 2314 | ioc_data->atm_addr[4], ioc_data->atm_addr[5], |
| 2311 | ioc_data->atm_addr[10],ioc_data->atm_addr[11], | 2315 | ioc_data->atm_addr[6], ioc_data->atm_addr[7], |
| 2312 | ioc_data->atm_addr[12],ioc_data->atm_addr[13], | 2316 | ioc_data->atm_addr[8], ioc_data->atm_addr[9], |
| 2313 | ioc_data->atm_addr[14],ioc_data->atm_addr[15], | 2317 | ioc_data->atm_addr[10], ioc_data->atm_addr[11], |
| 2314 | ioc_data->atm_addr[16],ioc_data->atm_addr[17], | 2318 | ioc_data->atm_addr[12], ioc_data->atm_addr[13], |
| 2315 | ioc_data->atm_addr[18],ioc_data->atm_addr[19]); | 2319 | ioc_data->atm_addr[14], ioc_data->atm_addr[15], |
| 2316 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | 2320 | ioc_data->atm_addr[16], ioc_data->atm_addr[17], |
| 2317 | for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) { | 2321 | ioc_data->atm_addr[18], ioc_data->atm_addr[19]); |
| 2318 | if (memcmp(ioc_data->atm_addr, entry->atm_addr, | 2322 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 2319 | ATM_ESA_LEN)==0) { | 2323 | for (entry = priv->lec_arp_tables[i]; entry; |
| 2320 | DPRINTK("LEC_ARP: Attaching data direct\n"); | 2324 | entry = entry->next) { |
| 2321 | DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n", | 2325 | if (memcmp |
| 2322 | entry->vcc?entry->vcc->vci:0, | 2326 | (ioc_data->atm_addr, entry->atm_addr, |
| 2323 | entry->recv_vcc?entry->recv_vcc->vci:0); | 2327 | ATM_ESA_LEN) == 0) { |
| 2324 | found_entry=1; | 2328 | DPRINTK("LEC_ARP: Attaching data direct\n"); |
| 2325 | del_timer(&entry->timer); | 2329 | DPRINTK("Currently -> Vcc: %d, Rvcc:%d\n", |
| 2326 | entry->vcc = vcc; | 2330 | entry->vcc ? entry->vcc->vci : 0, |
| 2327 | entry->old_push = old_push; | 2331 | entry->recv_vcc ? entry->recv_vcc-> |
| 2328 | if (entry->status == ESI_VC_PENDING) { | 2332 | vci : 0); |
| 2329 | if(priv->maximum_unknown_frame_count | 2333 | found_entry = 1; |
| 2330 | ==0) | 2334 | del_timer(&entry->timer); |
| 2331 | entry->status = | 2335 | entry->vcc = vcc; |
| 2332 | ESI_FORWARD_DIRECT; | 2336 | entry->old_push = old_push; |
| 2333 | else { | 2337 | if (entry->status == ESI_VC_PENDING) { |
| 2334 | entry->timestamp = jiffies; | 2338 | if (priv->maximum_unknown_frame_count |
| 2335 | entry->status = | 2339 | == 0) |
| 2336 | ESI_FLUSH_PENDING; | 2340 | entry->status = |
| 2341 | ESI_FORWARD_DIRECT; | ||
| 2342 | else { | ||
| 2343 | entry->timestamp = jiffies; | ||
| 2344 | entry->status = | ||
| 2345 | ESI_FLUSH_PENDING; | ||
| 2337 | #if 0 | 2346 | #if 0 |
| 2338 | send_to_lecd(priv,l_flush_xmt, | 2347 | send_to_lecd(priv, l_flush_xmt, |
| 2339 | NULL, | 2348 | NULL, |
| 2340 | entry->atm_addr, | 2349 | entry->atm_addr, |
| 2341 | NULL); | 2350 | NULL); |
| 2342 | #endif | 2351 | #endif |
| 2343 | } | 2352 | } |
| 2344 | } else { | 2353 | } else { |
| 2345 | /* They were forming a connection | 2354 | /* |
| 2346 | to us, and we to them. Our | 2355 | * They were forming a connection |
| 2347 | ATM address is numerically lower | 2356 | * to us, and we to them. Our |
| 2348 | than theirs, so we make connection | 2357 | * ATM address is numerically lower |
| 2349 | we formed into default VCC (8.1.11). | 2358 | * than theirs, so we make connection |
| 2350 | Connection they made gets torn | 2359 | * we formed into default VCC (8.1.11). |
| 2351 | down. This might confuse some | 2360 | * Connection they made gets torn |
| 2352 | clients. Can be changed if | 2361 | * down. This might confuse some |
| 2353 | someone reports trouble... */ | 2362 | * clients. Can be changed if |
| 2354 | ; | 2363 | * someone reports trouble... |
| 2355 | } | 2364 | */ |
| 2356 | } | 2365 | ; |
| 2357 | } | 2366 | } |
| 2358 | } | 2367 | } |
| 2359 | if (found_entry) { | 2368 | } |
| 2360 | DPRINTK("After vcc was added\n"); | 2369 | } |
| 2361 | dump_arp_table(priv); | 2370 | if (found_entry) { |
| 2371 | DPRINTK("After vcc was added\n"); | ||
| 2372 | dump_arp_table(priv); | ||
| 2362 | goto out; | 2373 | goto out; |
| 2363 | } | 2374 | } |
| 2364 | /* Not found, snatch address from first data packet that arrives from | 2375 | /* |
| 2365 | this vcc */ | 2376 | * Not found, snatch address from first data packet that arrives |
| 2366 | entry = make_entry(priv, bus_mac); | 2377 | * from this vcc |
| 2367 | if (!entry) | 2378 | */ |
| 2379 | entry = make_entry(priv, bus_mac); | ||
| 2380 | if (!entry) | ||
| 2368 | goto out; | 2381 | goto out; |
| 2369 | entry->vcc = vcc; | 2382 | entry->vcc = vcc; |
| 2370 | entry->old_push = old_push; | 2383 | entry->old_push = old_push; |
| 2371 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); | 2384 | memcpy(entry->atm_addr, ioc_data->atm_addr, ATM_ESA_LEN); |
| 2372 | memset(entry->mac_addr, 0, ETH_ALEN); | 2385 | memset(entry->mac_addr, 0, ETH_ALEN); |
| 2373 | entry->status = ESI_UNKNOWN; | 2386 | entry->status = ESI_UNKNOWN; |
| 2374 | entry->next = priv->lec_arp_empty_ones; | 2387 | entry->next = priv->lec_arp_empty_ones; |
| 2375 | priv->lec_arp_empty_ones = entry; | 2388 | priv->lec_arp_empty_ones = entry; |
| 2376 | entry->timer.expires = jiffies + priv->vcc_timeout_period; | 2389 | entry->timer.expires = jiffies + priv->vcc_timeout_period; |
| 2377 | entry->timer.function = lec_arp_expire_vcc; | 2390 | entry->timer.function = lec_arp_expire_vcc; |
| 2378 | add_timer(&entry->timer); | 2391 | add_timer(&entry->timer); |
| 2379 | DPRINTK("After vcc was added\n"); | 2392 | DPRINTK("After vcc was added\n"); |
| 2380 | dump_arp_table(priv); | 2393 | dump_arp_table(priv); |
| 2381 | out: | 2394 | out: |
| 2382 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2395 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2383 | } | 2396 | } |
| 2384 | 2397 | ||
| 2385 | static void | 2398 | static void lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) |
| 2386 | lec_flush_complete(struct lec_priv *priv, unsigned long tran_id) | ||
| 2387 | { | 2399 | { |
| 2388 | unsigned long flags; | 2400 | unsigned long flags; |
| 2389 | struct lec_arp_table *entry; | 2401 | struct lec_arp_table *entry; |
| 2390 | int i; | 2402 | int i; |
| 2391 | |||
| 2392 | DPRINTK("LEC:lec_flush_complete %lx\n",tran_id); | ||
| 2393 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | ||
| 2394 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | ||
| 2395 | for (entry = priv->lec_arp_tables[i]; entry; entry=entry->next) { | ||
| 2396 | if (entry->flush_tran_id == tran_id && | ||
| 2397 | entry->status == ESI_FLUSH_PENDING) { | ||
| 2398 | struct sk_buff *skb; | ||
| 2399 | 2403 | ||
| 2400 | while ((skb = skb_dequeue(&entry->tx_wait)) != NULL) | 2404 | DPRINTK("LEC:lec_flush_complete %lx\n", tran_id); |
| 2405 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | ||
| 2406 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { | ||
| 2407 | for (entry = priv->lec_arp_tables[i]; entry; | ||
| 2408 | entry = entry->next) { | ||
| 2409 | if (entry->flush_tran_id == tran_id | ||
| 2410 | && entry->status == ESI_FLUSH_PENDING) { | ||
| 2411 | struct sk_buff *skb; | ||
| 2412 | |||
| 2413 | while ((skb = | ||
| 2414 | skb_dequeue(&entry->tx_wait)) != NULL) | ||
| 2401 | lec_send(entry->vcc, skb, entry->priv); | 2415 | lec_send(entry->vcc, skb, entry->priv); |
| 2402 | entry->status = ESI_FORWARD_DIRECT; | 2416 | entry->status = ESI_FORWARD_DIRECT; |
| 2403 | DPRINTK("LEC_ARP: Flushed\n"); | 2417 | DPRINTK("LEC_ARP: Flushed\n"); |
| 2404 | } | 2418 | } |
| 2405 | } | 2419 | } |
| 2406 | } | 2420 | } |
| 2407 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2421 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2408 | dump_arp_table(priv); | 2422 | dump_arp_table(priv); |
| 2409 | } | 2423 | } |
| 2410 | 2424 | ||
| 2411 | static void | 2425 | static void |
| 2412 | lec_set_flush_tran_id(struct lec_priv *priv, | 2426 | lec_set_flush_tran_id(struct lec_priv *priv, |
| 2413 | unsigned char *atm_addr, unsigned long tran_id) | 2427 | unsigned char *atm_addr, unsigned long tran_id) |
| 2414 | { | 2428 | { |
| 2415 | unsigned long flags; | 2429 | unsigned long flags; |
| 2416 | struct lec_arp_table *entry; | 2430 | struct lec_arp_table *entry; |
| 2417 | int i; | 2431 | int i; |
| 2418 | 2432 | ||
| 2419 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2433 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2420 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) | 2434 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) |
| 2421 | for(entry = priv->lec_arp_tables[i]; entry; entry=entry->next) | 2435 | for (entry = priv->lec_arp_tables[i]; entry; |
| 2422 | if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { | 2436 | entry = entry->next) |
| 2423 | entry->flush_tran_id = tran_id; | 2437 | if (!memcmp(atm_addr, entry->atm_addr, ATM_ESA_LEN)) { |
| 2424 | DPRINTK("Set flush transaction id to %lx for %p\n",tran_id,entry); | 2438 | entry->flush_tran_id = tran_id; |
| 2425 | } | 2439 | DPRINTK |
| 2440 | ("Set flush transaction id to %lx for %p\n", | ||
| 2441 | tran_id, entry); | ||
| 2442 | } | ||
| 2426 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2443 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2427 | } | 2444 | } |
| 2428 | 2445 | ||
| 2429 | static int | 2446 | static int lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) |
| 2430 | lec_mcast_make(struct lec_priv *priv, struct atm_vcc *vcc) | ||
| 2431 | { | 2447 | { |
| 2432 | unsigned long flags; | 2448 | unsigned long flags; |
| 2433 | unsigned char mac_addr[] = { | 2449 | unsigned char mac_addr[] = { |
| 2434 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; | 2450 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
| 2435 | struct lec_arp_table *to_add; | 2451 | }; |
| 2452 | struct lec_arp_table *to_add; | ||
| 2436 | struct lec_vcc_priv *vpriv; | 2453 | struct lec_vcc_priv *vpriv; |
| 2437 | int err = 0; | 2454 | int err = 0; |
| 2438 | 2455 | ||
| 2439 | if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL))) | 2456 | if (!(vpriv = kmalloc(sizeof(struct lec_vcc_priv), GFP_KERNEL))) |
| 2440 | return -ENOMEM; | 2457 | return -ENOMEM; |
| 2441 | vpriv->xoff = 0; | 2458 | vpriv->xoff = 0; |
| 2442 | vpriv->old_pop = vcc->pop; | 2459 | vpriv->old_pop = vcc->pop; |
| 2443 | vcc->user_back = vpriv; | 2460 | vcc->user_back = vpriv; |
| 2444 | vcc->pop = lec_pop; | 2461 | vcc->pop = lec_pop; |
| 2445 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2462 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2446 | to_add = make_entry(priv, mac_addr); | 2463 | to_add = make_entry(priv, mac_addr); |
| 2447 | if (!to_add) { | 2464 | if (!to_add) { |
| 2448 | vcc->pop = vpriv->old_pop; | 2465 | vcc->pop = vpriv->old_pop; |
| 2449 | kfree(vpriv); | 2466 | kfree(vpriv); |
| 2450 | err = -ENOMEM; | 2467 | err = -ENOMEM; |
| 2451 | goto out; | 2468 | goto out; |
| 2452 | } | 2469 | } |
| 2453 | memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN); | 2470 | memcpy(to_add->atm_addr, vcc->remote.sas_addr.prv, ATM_ESA_LEN); |
| 2454 | to_add->status = ESI_FORWARD_DIRECT; | 2471 | to_add->status = ESI_FORWARD_DIRECT; |
| 2455 | to_add->flags |= LEC_PERMANENT_FLAG; | 2472 | to_add->flags |= LEC_PERMANENT_FLAG; |
| 2456 | to_add->vcc = vcc; | 2473 | to_add->vcc = vcc; |
| 2457 | to_add->old_push = vcc->push; | 2474 | to_add->old_push = vcc->push; |
| 2458 | vcc->push = lec_push; | 2475 | vcc->push = lec_push; |
| 2459 | priv->mcast_vcc = vcc; | 2476 | priv->mcast_vcc = vcc; |
| 2460 | lec_arp_add(priv, to_add); | 2477 | lec_arp_add(priv, to_add); |
| 2461 | out: | 2478 | out: |
| 2462 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2479 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2463 | return err; | 2480 | return err; |
| 2464 | } | 2481 | } |
| 2465 | 2482 | ||
| 2466 | static void | 2483 | static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) |
| 2467 | lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) | ||
| 2468 | { | 2484 | { |
| 2469 | unsigned long flags; | 2485 | unsigned long flags; |
| 2470 | struct lec_arp_table *entry, *next; | 2486 | struct lec_arp_table *entry, *next; |
| 2471 | int i; | 2487 | int i; |
| 2472 | 2488 | ||
| 2473 | DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n",vcc->vpi,vcc->vci); | 2489 | DPRINTK("LEC_ARP: lec_vcc_close vpi:%d vci:%d\n", vcc->vpi, vcc->vci); |
| 2474 | dump_arp_table(priv); | 2490 | dump_arp_table(priv); |
| 2475 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2491 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2476 | for(i=0;i<LEC_ARP_TABLE_SIZE;i++) { | 2492 | for (i = 0; i < LEC_ARP_TABLE_SIZE; i++) { |
| 2477 | for(entry = priv->lec_arp_tables[i];entry; entry=next) { | 2493 | for (entry = priv->lec_arp_tables[i]; entry; entry = next) { |
| 2478 | next = entry->next; | 2494 | next = entry->next; |
| 2479 | if (vcc == entry->vcc) { | 2495 | if (vcc == entry->vcc) { |
| 2480 | lec_arp_remove(priv, entry); | 2496 | lec_arp_remove(priv, entry); |
| 2481 | kfree(entry); | 2497 | kfree(entry); |
| 2482 | if (priv->mcast_vcc == vcc) { | 2498 | if (priv->mcast_vcc == vcc) { |
| 2483 | priv->mcast_vcc = NULL; | 2499 | priv->mcast_vcc = NULL; |
| 2484 | } | 2500 | } |
| 2485 | } | 2501 | } |
| 2486 | } | 2502 | } |
| 2487 | } | 2503 | } |
| 2488 | 2504 | ||
| 2489 | entry = priv->lec_arp_empty_ones; | 2505 | entry = priv->lec_arp_empty_ones; |
| 2490 | priv->lec_arp_empty_ones = NULL; | 2506 | priv->lec_arp_empty_ones = NULL; |
| 2491 | while (entry != NULL) { | 2507 | while (entry != NULL) { |
| 2492 | next = entry->next; | 2508 | next = entry->next; |
| 2493 | if (entry->vcc == vcc) { /* leave it out from the list */ | 2509 | if (entry->vcc == vcc) { /* leave it out from the list */ |
| 2494 | lec_arp_clear_vccs(entry); | 2510 | lec_arp_clear_vccs(entry); |
| 2495 | del_timer(&entry->timer); | 2511 | del_timer(&entry->timer); |
| 2496 | kfree(entry); | 2512 | kfree(entry); |
| 2497 | } | 2513 | } else { /* put it back to the list */ |
| 2498 | else { /* put it back to the list */ | 2514 | entry->next = priv->lec_arp_empty_ones; |
| 2499 | entry->next = priv->lec_arp_empty_ones; | 2515 | priv->lec_arp_empty_ones = entry; |
| 2500 | priv->lec_arp_empty_ones = entry; | 2516 | } |
| 2501 | } | 2517 | entry = next; |
| 2502 | entry = next; | 2518 | } |
| 2503 | } | 2519 | |
| 2504 | 2520 | entry = priv->lec_no_forward; | |
| 2505 | entry = priv->lec_no_forward; | 2521 | priv->lec_no_forward = NULL; |
| 2506 | priv->lec_no_forward = NULL; | 2522 | while (entry != NULL) { |
| 2507 | while (entry != NULL) { | 2523 | next = entry->next; |
| 2508 | next = entry->next; | 2524 | if (entry->recv_vcc == vcc) { |
| 2509 | if (entry->recv_vcc == vcc) { | 2525 | lec_arp_clear_vccs(entry); |
| 2510 | lec_arp_clear_vccs(entry); | 2526 | del_timer(&entry->timer); |
| 2511 | del_timer(&entry->timer); | 2527 | kfree(entry); |
| 2512 | kfree(entry); | 2528 | } else { |
| 2513 | } | 2529 | entry->next = priv->lec_no_forward; |
| 2514 | else { | 2530 | priv->lec_no_forward = entry; |
| 2515 | entry->next = priv->lec_no_forward; | 2531 | } |
| 2516 | priv->lec_no_forward = entry; | 2532 | entry = next; |
| 2517 | } | 2533 | } |
| 2518 | entry = next; | 2534 | |
| 2519 | } | 2535 | entry = priv->mcast_fwds; |
| 2520 | 2536 | priv->mcast_fwds = NULL; | |
| 2521 | entry = priv->mcast_fwds; | 2537 | while (entry != NULL) { |
| 2522 | priv->mcast_fwds = NULL; | 2538 | next = entry->next; |
| 2523 | while (entry != NULL) { | 2539 | if (entry->recv_vcc == vcc) { |
| 2524 | next = entry->next; | 2540 | lec_arp_clear_vccs(entry); |
| 2525 | if (entry->recv_vcc == vcc) { | 2541 | /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ |
| 2526 | lec_arp_clear_vccs(entry); | 2542 | kfree(entry); |
| 2527 | /* No timer, LANEv2 7.1.20 and 2.3.5.3 */ | 2543 | } else { |
| 2528 | kfree(entry); | 2544 | entry->next = priv->mcast_fwds; |
| 2529 | } | 2545 | priv->mcast_fwds = entry; |
| 2530 | else { | 2546 | } |
| 2531 | entry->next = priv->mcast_fwds; | 2547 | entry = next; |
| 2532 | priv->mcast_fwds = entry; | 2548 | } |
| 2533 | } | ||
| 2534 | entry = next; | ||
| 2535 | } | ||
| 2536 | 2549 | ||
| 2537 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2550 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2538 | dump_arp_table(priv); | 2551 | dump_arp_table(priv); |
| @@ -2540,57 +2553,59 @@ lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc) | |||
| 2540 | 2553 | ||
| 2541 | static void | 2554 | static void |
| 2542 | lec_arp_check_empties(struct lec_priv *priv, | 2555 | lec_arp_check_empties(struct lec_priv *priv, |
| 2543 | struct atm_vcc *vcc, struct sk_buff *skb) | 2556 | struct atm_vcc *vcc, struct sk_buff *skb) |
| 2544 | { | 2557 | { |
| 2545 | unsigned long flags; | 2558 | unsigned long flags; |
| 2546 | struct lec_arp_table *entry, *prev; | 2559 | struct lec_arp_table *entry, *prev; |
| 2547 | struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; | 2560 | struct lecdatahdr_8023 *hdr = (struct lecdatahdr_8023 *)skb->data; |
| 2548 | unsigned char *src; | 2561 | unsigned char *src; |
| 2549 | #ifdef CONFIG_TR | 2562 | #ifdef CONFIG_TR |
| 2550 | struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; | 2563 | struct lecdatahdr_8025 *tr_hdr = (struct lecdatahdr_8025 *)skb->data; |
| 2551 | 2564 | ||
| 2552 | if (priv->is_trdev) src = tr_hdr->h_source; | 2565 | if (priv->is_trdev) |
| 2553 | else | 2566 | src = tr_hdr->h_source; |
| 2567 | else | ||
| 2554 | #endif | 2568 | #endif |
| 2555 | src = hdr->h_source; | 2569 | src = hdr->h_source; |
| 2556 | 2570 | ||
| 2557 | spin_lock_irqsave(&priv->lec_arp_lock, flags); | 2571 | spin_lock_irqsave(&priv->lec_arp_lock, flags); |
| 2558 | entry = priv->lec_arp_empty_ones; | 2572 | entry = priv->lec_arp_empty_ones; |
| 2559 | if (vcc == entry->vcc) { | 2573 | if (vcc == entry->vcc) { |
| 2560 | del_timer(&entry->timer); | 2574 | del_timer(&entry->timer); |
| 2561 | memcpy(entry->mac_addr, src, ETH_ALEN); | 2575 | memcpy(entry->mac_addr, src, ETH_ALEN); |
| 2562 | entry->status = ESI_FORWARD_DIRECT; | 2576 | entry->status = ESI_FORWARD_DIRECT; |
| 2563 | entry->last_used = jiffies; | 2577 | entry->last_used = jiffies; |
| 2564 | priv->lec_arp_empty_ones = entry->next; | 2578 | priv->lec_arp_empty_ones = entry->next; |
| 2565 | /* We might have got an entry */ | 2579 | /* We might have got an entry */ |
| 2566 | if ((prev = lec_arp_find(priv,src))) { | 2580 | if ((prev = lec_arp_find(priv, src))) { |
| 2567 | lec_arp_remove(priv, prev); | 2581 | lec_arp_remove(priv, prev); |
| 2568 | kfree(prev); | 2582 | kfree(prev); |
| 2569 | } | 2583 | } |
| 2570 | lec_arp_add(priv, entry); | 2584 | lec_arp_add(priv, entry); |
| 2571 | goto out; | 2585 | goto out; |
| 2572 | } | 2586 | } |
| 2573 | prev = entry; | 2587 | prev = entry; |
| 2574 | entry = entry->next; | 2588 | entry = entry->next; |
| 2575 | while (entry && entry->vcc != vcc) { | 2589 | while (entry && entry->vcc != vcc) { |
| 2576 | prev= entry; | 2590 | prev = entry; |
| 2577 | entry = entry->next; | 2591 | entry = entry->next; |
| 2578 | } | 2592 | } |
| 2579 | if (!entry) { | 2593 | if (!entry) { |
| 2580 | DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n"); | 2594 | DPRINTK("LEC_ARP: Arp_check_empties: entry not found!\n"); |
| 2581 | goto out; | 2595 | goto out; |
| 2582 | } | 2596 | } |
| 2583 | del_timer(&entry->timer); | 2597 | del_timer(&entry->timer); |
| 2584 | memcpy(entry->mac_addr, src, ETH_ALEN); | 2598 | memcpy(entry->mac_addr, src, ETH_ALEN); |
| 2585 | entry->status = ESI_FORWARD_DIRECT; | 2599 | entry->status = ESI_FORWARD_DIRECT; |
| 2586 | entry->last_used = jiffies; | 2600 | entry->last_used = jiffies; |
| 2587 | prev->next = entry->next; | 2601 | prev->next = entry->next; |
| 2588 | if ((prev = lec_arp_find(priv, src))) { | 2602 | if ((prev = lec_arp_find(priv, src))) { |
| 2589 | lec_arp_remove(priv, prev); | 2603 | lec_arp_remove(priv, prev); |
| 2590 | kfree(prev); | 2604 | kfree(prev); |
| 2591 | } | 2605 | } |
| 2592 | lec_arp_add(priv, entry); | 2606 | lec_arp_add(priv, entry); |
| 2593 | out: | 2607 | out: |
| 2594 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); | 2608 | spin_unlock_irqrestore(&priv->lec_arp_lock, flags); |
| 2595 | } | 2609 | } |
| 2610 | |||
| 2596 | MODULE_LICENSE("GPL"); | 2611 | MODULE_LICENSE("GPL"); |
