/*	       lac_hw.c   2.00.000 01JUN99 01:23  */

#include "sys.h"
#include "lac_options.h"
#include "lac_types.h"
#include "lac_defaults.h"
#include "lac_machines.h"
/******************************************************************************
 * LAC : LINK AGGREGATION CONTROL PROTOCOL : HARDWARE AGGREGATION CONTROL
 ******************************************************************************
 *
 * Note: These test versions of the multiplexer hardware functions do not
 * operate asynchronously, but set the multiplexer operational state, and
 * signal back to LACP state machines, before returning. A better test
 * implementations would set the administrative states (rx_on, tx_on)
 * immediately and return, and then set the operational states (rx_enabled,
 * tx_enabled) and signal the changes asynchronously after a random time delay.
 *
 * To avoid having to maintain a duplicate copy of the current state of the
 * hardware state within the mux control logic, that logic assumes that
 * signalling events to hs_control() is efficient if there is no work to be
 * done, and will result in an immediate appropriate return signal.
 */
/*---------------------------------------------------------------------------*/
static Boolean coupled_hw(Node *mux)
{
   return(False);
}
/*---------------------------------------------------------------------------*/
extern void hw_control(Lac_port *port, Lac_event event)
{
   Node *mac = &port->mac;
   Node *mux = &port->aport->mux;
   Node *n;
   Lac_event mux_event = Lac_null;

   switch (event)
   {
   case Lac_init:
      break;

   case Lac_attach:
      mac->next = mux->next;
      mux->next = mac;
      mac->user = mux;

      mux_event = Lac_attached;
      break;

   case Lac_detach:
      n = mux; while (n->next != mac) n = n->next;

      n->next   = mac->next;
      mac->next = mac;
      mac->user = NULL;

      mux_event = Lac_detached;
      break;

   case Lac_enable_collector:
      mux->rx_enabled = mux->rx_on = True;

      if (coupled_hw(mux))
         mux->tx_enabled = mux->tx_on = True;

      mux->rx_status_fn(mux, True, mac);
      mux_event = Lac_collector_on;
      break;

   case Lac_disable_collector:
      mux->rx_on =  mux->rx_enabled = False;

      if (coupled_hw(mux))
         mux->tx_on = mux->tx_enabled = False;

      mux->rx_status_fn(mux, False, mac);
      mux_event = Lac_collector_off;
      break;

   case Lac_enable_distributor:
      mux->tx_on = mux->tx_enabled = True;

      if (coupled_hw(mux))
         mux->rx_enabled = mux->rx_on = True;

      mux->tx_status_fn(mux, True, mac);
      mux_event = Lac_distributor_on;
      break;

   case Lac_disable_distributor:
      mux->tx_on = mux->tx_enabled = False;

      if (coupled_hw(mux))
         mux->rx_on = mux->rx_enabled = False;

      mux->tx_status_fn(mux, False, mac);
      mux_event = Lac_distributor_off;
      break;

   default:
      break;
   }
   if (mux_event != Lac_null)
      mux_control(port, mux_event);
}
/*---------------------------------------------------------------------------*/
