summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/sys
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/sys')
-rw-r--r--usr/src/uts/common/sys/aggr_impl.h56
-rw-r--r--usr/src/uts/common/sys/mac_client_priv.h13
-rw-r--r--usr/src/uts/common/sys/mac_impl.h13
-rw-r--r--usr/src/uts/common/sys/mac_provider.h54
4 files changed, 110 insertions, 26 deletions
diff --git a/usr/src/uts/common/sys/aggr_impl.h b/usr/src/uts/common/sys/aggr_impl.h
index 415e176ef3..bd31c60604 100644
--- a/usr/src/uts/common/sys/aggr_impl.h
+++ b/usr/src/uts/common/sys/aggr_impl.h
@@ -56,6 +56,8 @@ extern "C" {
*/
#define MAC_PSEUDO_RING_INUSE 0x01
+#define MAX_GROUPS_PER_PORT 128
+
/*
* VLAN filters placed on the Rx pseudo group.
*/
@@ -71,14 +73,23 @@ typedef struct aggr_unicst_addr_s {
} aggr_unicst_addr_t;
typedef struct aggr_pseudo_rx_ring_s {
- mac_ring_handle_t arr_rh; /* filled in by aggr_fill_ring() */
- struct aggr_port_s *arr_port;
- mac_ring_handle_t arr_hw_rh;
- uint_t arr_flags;
- uint64_t arr_gen;
+ mac_ring_handle_t arr_rh; /* set by aggr_fill_ring() */
+ struct aggr_port_s *arr_port;
+ struct aggr_pseudo_rx_group_s *arr_grp;
+ mac_ring_handle_t arr_hw_rh;
+ uint_t arr_flags;
+ uint64_t arr_gen;
} aggr_pseudo_rx_ring_t;
+/*
+ * An aggr pseudo group abstracts the underlying ports' HW groups. For
+ * example, if each port has 8 groups (mac_group_t), then the aggr
+ * will create 8 psuedo groups. Each pseudo group represents a
+ * collection of HW groups: one group from each port. If you have
+ * three ports then the pseudo group stands in for three HW groups.
+ */
typedef struct aggr_pseudo_rx_group_s {
+ uint_t arg_index;
struct aggr_grp_s *arg_grp; /* filled in by aggr_fill_group() */
mac_group_handle_t arg_gh; /* filled in by aggr_fill_group() */
aggr_unicst_addr_t *arg_macaddr;
@@ -119,12 +130,13 @@ typedef struct aggr_port_s {
lp_collector_enabled : 1,
lp_promisc_on : 1,
lp_no_link_update : 1,
- lp_rx_grp_added : 1,
lp_tx_grp_added : 1,
lp_closing : 1,
- lp_pad_bits : 24;
+ lp_pad_bits : 25;
mac_handle_t lp_mh;
- mac_client_handle_t lp_mch;
+
+ mac_client_handle_t lp_mch;
+
const mac_info_t *lp_mip;
mac_notify_handle_t lp_mnh;
uint_t lp_tx_idx; /* idx in group's tx array */
@@ -136,13 +148,19 @@ typedef struct aggr_port_s {
aggr_lacp_port_t lp_lacp; /* LACP state */
lacp_stats_t lp_lacp_stats;
uint32_t lp_margin;
- mac_promisc_handle_t lp_mphp;
+
mac_unicast_handle_t lp_mah;
/* List of non-primary addresses that requires promiscous mode set */
aggr_unicst_addr_t *lp_prom_addr;
- /* handle of the underlying HW RX group */
- mac_group_handle_t lp_hwgh;
+
+ /*
+ * References to the underlying HW Rx groups of this port.
+ * Used by aggr to program HW classification for the pseudo
+ * groups.
+ */
+ mac_group_handle_t lp_hwghs[MAX_GROUPS_PER_PORT];
+
int lp_tx_ring_cnt;
/* handles of the underlying HW TX rings */
mac_ring_handle_t *lp_tx_rings;
@@ -189,7 +207,7 @@ typedef struct aggr_grp_s {
lg_lso : 1,
lg_pad_bits : 8;
aggr_port_t *lg_ports; /* list of configured ports */
- aggr_port_t *lg_mac_addr_port;
+ aggr_port_t *lg_mac_addr_port; /* using address of this port */
mac_handle_t lg_mh;
zoneid_t lg_zoneid;
uint_t lg_nattached_ports;
@@ -233,7 +251,9 @@ typedef struct aggr_grp_s {
kthread_t *lg_lacp_rx_thread;
boolean_t lg_lacp_done;
- aggr_pseudo_rx_group_t lg_rx_group;
+ uint_t lg_rx_group_count;
+ aggr_pseudo_rx_group_t lg_rx_groups[MAX_GROUPS_PER_PORT];
+
aggr_pseudo_tx_group_t lg_tx_group;
kmutex_t lg_tx_flowctl_lock;
@@ -328,8 +348,6 @@ extern boolean_t aggr_port_notify_link(aggr_grp_t *, aggr_port_t *);
extern void aggr_port_init_callbacks(aggr_port_t *);
extern void aggr_recv_cb(void *, mac_resource_handle_t, mblk_t *, boolean_t);
-extern void aggr_recv_promisc_cb(void *, mac_resource_handle_t, mblk_t *,
- boolean_t);
extern void aggr_tx_ring_update(void *, uintptr_t);
extern void aggr_tx_notify_thread(void *);
@@ -357,11 +375,11 @@ extern void aggr_grp_port_hold(aggr_port_t *);
extern void aggr_grp_port_rele(aggr_port_t *);
extern void aggr_grp_port_wait(aggr_grp_t *);
-extern int aggr_port_addmac(aggr_port_t *, const uint8_t *);
-extern void aggr_port_remmac(aggr_port_t *, const uint8_t *);
+extern int aggr_port_addmac(aggr_port_t *, uint_t, const uint8_t *);
+extern void aggr_port_remmac(aggr_port_t *, uint_t, const uint8_t *);
-extern int aggr_port_addvlan(aggr_port_t *, uint16_t);
-extern int aggr_port_remvlan(aggr_port_t *, uint16_t);
+extern int aggr_port_addvlan(aggr_port_t *, uint_t, uint16_t);
+extern int aggr_port_remvlan(aggr_port_t *, uint_t, uint16_t);
extern mblk_t *aggr_ring_tx(void *, mblk_t *);
extern mblk_t *aggr_find_tx_ring(void *, mblk_t *,
diff --git a/usr/src/uts/common/sys/mac_client_priv.h b/usr/src/uts/common/sys/mac_client_priv.h
index 98325feb17..01cb27644c 100644
--- a/usr/src/uts/common/sys/mac_client_priv.h
+++ b/usr/src/uts/common/sys/mac_client_priv.h
@@ -121,9 +121,17 @@ extern void mac_tx_client_quiesce(mac_client_handle_t);
extern void mac_tx_client_condemn(mac_client_handle_t);
extern void mac_tx_client_restart(mac_client_handle_t);
extern void mac_srs_perm_quiesce(mac_client_handle_t, boolean_t);
+extern uint_t mac_hwrings_idx_get(mac_handle_t, uint_t, mac_group_handle_t *,
+ mac_ring_handle_t *, mac_ring_type_t);
extern int mac_hwrings_get(mac_client_handle_t, mac_group_handle_t *,
mac_ring_handle_t *, mac_ring_type_t);
extern uint_t mac_hwring_getinfo(mac_ring_handle_t);
+extern void mac_hwring_set_passthru(mac_ring_handle_t, mac_rx_t, void *,
+ mac_resource_handle_t);
+extern void mac_hwring_clear_passthru(mac_ring_handle_t);
+extern void mac_client_set_flow_cb(mac_client_handle_t, mac_rx_t, void *);
+extern void mac_client_clear_flow_cb(mac_client_handle_t);
+
extern void mac_hwring_setup(mac_ring_handle_t, mac_resource_handle_t,
mac_ring_handle_t);
extern void mac_hwring_teardown(mac_ring_handle_t);
@@ -131,6 +139,8 @@ extern int mac_hwring_disable_intr(mac_ring_handle_t);
extern int mac_hwring_enable_intr(mac_ring_handle_t);
extern int mac_hwring_start(mac_ring_handle_t);
extern void mac_hwring_stop(mac_ring_handle_t);
+extern int mac_hwring_activate(mac_ring_handle_t);
+extern void mac_hwring_quiesce(mac_ring_handle_t);
extern mblk_t *mac_hwring_poll(mac_ring_handle_t, int);
extern mblk_t *mac_hwring_tx(mac_ring_handle_t, mblk_t *);
extern int mac_hwring_getstat(mac_ring_handle_t, uint_t, uint64_t *);
@@ -149,6 +159,9 @@ extern int mac_hwgroup_remvlan(mac_group_handle_t, uint16_t);
extern boolean_t mac_has_hw_vlan(mac_handle_t);
+extern uint_t mac_get_num_rx_groups(mac_handle_t);
+extern int mac_set_promisc(mac_handle_t, boolean_t);
+
extern void mac_set_upper_mac(mac_client_handle_t, mac_handle_t,
mac_resource_props_t *);
diff --git a/usr/src/uts/common/sys/mac_impl.h b/usr/src/uts/common/sys/mac_impl.h
index b62fca5c46..17aebffc38 100644
--- a/usr/src/uts/common/sys/mac_impl.h
+++ b/usr/src/uts/common/sys/mac_impl.h
@@ -208,9 +208,18 @@ struct mac_ring_s {
mac_ring_t *mr_next; /* next ring in the chain */
mac_group_handle_t mr_gh; /* reference to group */
- mac_classify_type_t mr_classify_type; /* HW vs SW */
+ mac_classify_type_t mr_classify_type;
struct mac_soft_ring_set_s *mr_srs; /* associated SRS */
- mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */
+ mac_ring_handle_t mr_prh; /* associated pseudo ring hdl */
+
+ /*
+ * Ring passthru callback and arguments. See the
+ * MAC_PASSTHRU_CLASSIFIER comment in mac_provider.h.
+ */
+ mac_rx_t mr_pt_fn;
+ void *mr_pt_arg1;
+ mac_resource_handle_t mr_pt_arg2;
+
uint_t mr_refcnt; /* Ring references */
/* ring generation no. to guard against drivers using stale rings */
uint64_t mr_gen_num;
diff --git a/usr/src/uts/common/sys/mac_provider.h b/usr/src/uts/common/sys/mac_provider.h
index f5c91e7933..2dea3a4758 100644
--- a/usr/src/uts/common/sys/mac_provider.h
+++ b/usr/src/uts/common/sys/mac_provider.h
@@ -243,16 +243,59 @@ typedef struct mac_callbacks_s {
/*
* Virtualization Capabilities
*/
+
/*
- * The ordering of entries below is important. MAC_HW_CLASSIFIER
- * is the cutoff below which are entries which don't depend on
- * H/W. MAC_HW_CLASSIFIER and entries after that are cases where
- * H/W has been updated through add/modify/delete APIs.
+ * The type of ring classification. This is used by MAC to determine
+ * what, if any, processing it has to do upon receiving traffic on a
+ * particular Rx ring.
+ *
+ * MAC_NO_CLASSIFIER
+ *
+ * No classification has been set. No traffic should cross an Rx
+ * ring in this state.
+ *
+ * MAC_SW_CLASSIFIER
+ *
+ * The driver delivers traffic for multiple clients to this ring.
+ * All traffic must be software classified by MAC to guarantee
+ * delivery to the correct client. This classification type may
+ * be chosen for several reasons.
+ *
+ * o The driver provides only one group and there are multiple
+ * clients using the MAC.
+ *
+ * o The driver provides some hardware filtering but not enough
+ * to fully classify the traffic. E.g., a VLAN VNIC requires L2
+ * unicast address filtering as well as VLAN filtering, but
+ * some drivers may only support the former.
+ *
+ * o The ring belongs to the default group. The default group
+ * acts as a spillover for all clients that can't reserve an
+ * exclusive group. It also handles multicast traffic for all
+ * clients. For these reasons, the default group's rings are
+ * always software classified.
+ *
+ * MAC_HW_CLASSIFIER
+ *
+ * The driver delivers traffic for a single MAC client across
+ * this ring. With this guarantee, MAC can simply pass the
+ * traffic up the stack or even allow polling of the ring.
+ *
+ * MAC_PASSTHRU_CLASSIFIER
+ *
+ * The ring is in "passthru" mode. In this mode we bypass all of
+ * the typical MAC processing and pass the traffic directly to
+ * the mr_pt_fn callback, see mac_rx_common(). This is used in
+ * cases where there is another module acting as MAC provider on
+ * behalf of the driver. E.g., link aggregations use this mode to
+ * take full control of the port's rings; allowing it to enforce
+ * LACP protocols and aggregate rings across discrete drivers.
*/
typedef enum {
MAC_NO_CLASSIFIER = 0,
MAC_SW_CLASSIFIER,
- MAC_HW_CLASSIFIER
+ MAC_HW_CLASSIFIER,
+ MAC_PASSTHRU_CLASSIFIER
} mac_classify_type_t;
typedef void (*mac_rx_func_t)(void *, mac_resource_handle_t, mblk_t *,
@@ -365,6 +408,7 @@ typedef struct mac_ring_info_s {
mac_ring_poll_t poll;
} mrfunion;
mac_ring_stat_t mri_stat;
+
/*
* mri_flags will have some bits set to indicate some special
* property/feature of a ring like serialization needed for a