Changeset 5cb7096 in rtems


Ignore:
Timestamp:
Jun 6, 2009, 12:49:41 AM (10 years ago)
Author:
Till Straumann <strauman@…>
Branches:
4.10, 4.11, master
Children:
f4812a03
Parents:
c30fcf52
Message:

2009-06-05 Till Straumann <strauman@…>

  • network/tsec.c, network/if_tsec_pub.h: implemented multicast support.
Location:
c/src/lib/libbsp/powerpc/mvme3100
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/powerpc/mvme3100/ChangeLog

    rc30fcf52 r5cb7096  
     12009-06-05      Till Straumann <strauman@slac.stanford.edu>
     2
     3        * network/tsec.c, network/if_tsec_pub.h:
     4        implemented multicast support.
     5
    162009-04-28      Chris Johns <chrisj@rtems.org>
    27
  • c/src/lib/libbsp/powerpc/mvme3100/network/if_tsec_pub.h

    rc30fcf52 r5cb7096  
    174174 * 'enaddr'             pointer to six bytes with MAC address. Read
    175175 *                              from the device if NULL.
     176 * NOTE:        multicast filter is cleared by this routine.
    176177 */
    177178void
    178179BSP_tsec_init_hw(struct tsec_private *mp, int promisc, unsigned char *enaddr);
     180
     181/*
     182 * Clear multicast hash filter. No multicast frames are accepted
     183 * after executing this routine (unless the hardware was initialized
     184 * in 'promiscuous' mode).
     185 */
     186void
     187BSP_tsec_mcast_filter_clear(struct tsec_private *mp);
     188
     189/*
     190 * Program multicast filter to accept all multicast frames.
     191 */
     192void
     193BSP_tsec_mcast_filter_accept_all(struct tsec_private *mp);
     194
     195/*
     196 * Add a MAC address to the multicast filter.
     197 * Existing entries are not changed but note that
     198 * the filter is imperfect, i.e., multiple MAC addresses
     199 * may alias to a single filter entry. Hence software
     200 * filtering must still be performed.
     201 *
     202 * NOTE: Deletion of an address is not possible. This is
     203 *       usually accomplished by a higher-level driver
     204 *       maintaining a list/database of multicast addresses
     205 *       and going through a sequence:
     206 *
     207 *         BSP_tsec_mcast_filter_clear()
     208 *         forall mcast addresses do
     209 *            BSP_tsec_mcast_filter_accept_add()
     210 */
     211void
     212BSP_tsec_mcast_filter_accept_add(struct tsec_private *mp, unsigned char *enaddr);
    179213
    180214/*
  • c/src/lib/libbsp/powerpc/mvme3100/network/tsec.c

    rc30fcf52 r5cb7096  
    5151#include <inttypes.h>
    5252#include <stdio.h>
     53#include <errno.h>
    5354#include <assert.h>
    5455#include <bsp.h>
     
    113114static uint32_t
    114115phy_ack_irq(struct tsec_private *mp);
     116
     117static void
     118tsec_update_mcast(struct ifnet *ifp);
    115119
    116120#if defined(PARANOIA) || defined(DEBUG)
     
    13401344        for ( i=0; i<8*4; i+=4 ) {
    13411345                fec_wr( b, TSEC_IADDR0 + i, 0 );
    1342                 fec_wr( b, TSEC_GADDR0 + i, 0 );
    1343         }
     1346        }
     1347
     1348        BSP_tsec_mcast_filter_clear(mp);
    13441349
    13451350        BSP_tsec_reset_stats(mp);
     
    13951400        /* globally reenable */
    13961401        rtems_interrupt_enable( l );
     1402}
     1403
     1404static uint8_t
     1405hash_accept(struct tsec_private *mp, uint32_t tble, const uint8_t *enaddr)
     1406{
     1407uint8_t s;
     1408
     1409        s = ether_crc32_le(enaddr, ETHER_ADDR_LEN);
     1410
     1411        /* bit-reverse */
     1412    s = ((s&0x0f) << 4) | ((s&0xf0) >> 4);
     1413    s = ((s&0x33) << 2) | ((s&0xcc) >> 2);
     1414    s = ((s&0x55) << 1) | ((s&0xaa) >> 1);
     1415
     1416        fec_wr( mp->base, tble + (s >> (5-2)), (1 << (31 - (s & 31))) );
     1417}
     1418
     1419void
     1420BSP_tsec_mcast_filter_clear(struct tsec_private *mp)
     1421{
     1422int i;
     1423        for ( i=0; i<8*4; i+=4 ) {
     1424                fec_wr( mp->base, TSEC_GADDR0 + i, 0 );
     1425        }
     1426}
     1427
     1428void
     1429BSP_tsec_mcast_filter_accept_all(struct tsec_private *mp)
     1430{
     1431int i;
     1432        for ( i=0; i<8*4; i+=4 ) {
     1433                fec_wr( mp->base, TSEC_GADDR0 + i, 0xffffffff );
     1434        }
     1435}
     1436
     1437void
     1438BSP_tsec_mcast_filter_accept_add(struct tsec_private *mp, uint8_t *enaddr)
     1439{
     1440static const uint8_t bcst={0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
     1441        if ( ! (enaddr[0] & 0x01) ) {
     1442                /* not a multicast address; ignore */
     1443                return;
     1444        }
     1445        if ( 0 == memcmp( enaddr, bcst, sizeof(bcst) ) ) {
     1446                /* broadcast; ignore */
     1447                return;
     1448        }
     1449        hash_accept(mp, TSEC_GADDR0, enaddr);
    13971450}
    13981451
     
    23112364struct ifnet            *ifp = &sc->arpcom.ac_if;
    23122365        BSP_tsec_init_hw(&sc->pvt, ifp->if_flags & IFF_PROMISC, sc->arpcom.ac_enaddr);
     2366
     2367        tsec_update_mcast(ifp);
    23132368        ifp->if_flags |= IFF_RUNNING;
    23142369        sc->arpcom.ac_if.if_timer = 0;
     
    23472402        tsec_init(sc);
    23482403        tsec_start(ifp);
     2404}
     2405
     2406static void
     2407tsec_update_mcast(struct ifnet *ifp)
     2408{
     2409struct tsec_softc *sc = ifp->if_softc;
     2410struct ether_multi     *enm;
     2411struct ether_multistep step;
     2412
     2413        if ( IFF_ALLMULTI & ifp->if_flags ) {
     2414                BSP_tsec_mcast_filter_accept_all( &sc->pvt );
     2415        } else {
     2416                BSP_tsec_mcast_filter_clear( &sc->pvt );
     2417
     2418                ETHER_FIRST_MULTI(step, (struct arpcom *)ifp, enm);
     2419
     2420                while ( enm ) {
     2421                        if ( memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) )
     2422                                assert( !"Should never get here; IFF_ALLMULTI should be set!" );
     2423
     2424                        BSP_tsec_mcast_filter_accept_add(&sc->pvt, enm->enm_addrlo);
     2425
     2426                        ETHER_NEXT_MULTI(step, enm);
     2427                }
     2428        }
    23492429}
    23502430
     
    23962476                break;
    23972477 
    2398 /*
    2399  * TODO
    2400  *
    2401  *              case SIOCADDMULTI:
    2402  *              case SIOCDELMULTI:
    2403  *
    2404  *              break;
    2405  */
    2406 
     2478                case SIOCADDMULTI:
     2479                case SIOCDELMULTI:
     2480                        error = (cmd == SIOCADDMULTI)
     2481                                ? ether_addmulti(ifr, &sc->arpcom)
     2482                                    : ether_delmulti(ifr, &sc->arpcom);
     2483
     2484                        if (error == ENETRESET) {
     2485                                if (ifp->if_flags & IFF_RUNNING) {
     2486                                        tsec_update_mcast(ifp);
     2487                                }
     2488                                error = 0;
     2489                        }
     2490                break;
    24072491
    24082492                case SIO_RTEMS_SHOW_STATS:
     
    25712655
    25722656                sc->bsd.oif_flags               = /* ... */
    2573                 ifp->if_flags                   = IFF_BROADCAST | IFF_SIMPLEX;
     2657                ifp->if_flags                   = IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX;
    25742658
    25752659                /*
Note: See TracChangeset for help on using the changeset viewer.