#include <sys/sysmacros.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/strsun.h>
#include <sys/strsubr.h>
#include <sys/byteorder.h>
#include <sys/aggr.h>
#include <sys/aggr_impl.h>
static void
aggr_mac_rx(mac_handle_t lg_mh, mac_resource_handle_t mrh, mblk_t *mp)
{
if (mrh == NULL) {
mac_rx(lg_mh, mrh, mp);
} else {
aggr_pseudo_rx_ring_t *ring = (aggr_pseudo_rx_ring_t *)mrh;
mac_rx_ring(lg_mh, ring->arr_rh, mp, ring->arr_gen);
}
}
void
aggr_recv_lacp(aggr_port_t *port, mac_resource_handle_t mrh, mblk_t *mp)
{
aggr_grp_t *grp = port->lp_grp;
if (grp->lg_promisc) {
mblk_t *nmp = copymsg(mp);
if (nmp != NULL)
aggr_mac_rx(grp->lg_mh, mrh, nmp);
}
aggr_lacp_rx_enqueue(port, mp);
}
static void
aggr_recv_path_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
boolean_t loopback)
{
aggr_port_t *port = (aggr_port_t *)arg;
aggr_grp_t *grp = port->lp_grp;
if (grp->lg_lacp_mode == AGGR_LACP_OFF) {
aggr_mac_rx(grp->lg_mh, mrh, mp);
} else {
mblk_t *cmp, *last, *head;
struct ether_header *ehp;
uint16_t sap;
last = NULL;
head = cmp = mp;
while (cmp != NULL) {
if (MBLKL(cmp) < sizeof (struct ether_header)) {
if (head == cmp) {
head = cmp->b_next;
cmp->b_next = NULL;
freemsg(cmp);
cmp = head;
} else {
last->b_next = NULL;
if (port->lp_collector_enabled) {
aggr_mac_rx(grp->lg_mh, mrh,
head);
} else {
freemsgchain(head);
}
head = cmp->b_next;
cmp->b_next = NULL;
freemsg(cmp);
cmp = head;
last = NULL;
}
continue;
}
ehp = (struct ether_header *)cmp->b_rptr;
sap = ntohs(ehp->ether_type);
if (sap == ETHERTYPE_SLOW) {
if (head == cmp) {
ASSERT(last == NULL);
head = cmp->b_next;
cmp->b_next = NULL;
aggr_recv_lacp(port, mrh, cmp);
cmp = head;
} else {
ASSERT(last != NULL);
last->b_next = NULL;
if (port->lp_collector_enabled) {
aggr_mac_rx(grp->lg_mh, mrh,
head);
} else {
freemsgchain(head);
}
head = cmp->b_next;
cmp->b_next = NULL;
aggr_recv_lacp(port, mrh, cmp);
cmp = head;
last = NULL;
}
} else {
last = cmp;
cmp = cmp->b_next;
}
}
if (head != NULL) {
if (port->lp_collector_enabled)
aggr_mac_rx(grp->lg_mh, mrh, head);
else
freemsgchain(head);
}
}
}
void
aggr_recv_cb(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
boolean_t loopback)
{
aggr_recv_path_cb(arg, mrh, mp, loopback);
}