Print this page
11493 aggr needs support for multiple pseudo rx groups
Portions contributed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Patrick Mooney <patrick.mooney@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>

@@ -54,10 +54,12 @@
  * Possible value of aggr_rseudo_rx_ring_t.arr_flags. Set when the ring entry
  * in the pseudo RX group is used.
  */
 #define MAC_PSEUDO_RING_INUSE   0x01
 
+#define MAX_GROUPS_PER_PORT     128
+
 /*
  * VLAN filters placed on the Rx pseudo group.
  */
 typedef struct aggr_vlan {
         list_node_t     av_link;

@@ -69,18 +71,27 @@
         uint8_t                         aua_addr[ETHERADDRL];
         struct aggr_unicst_addr_s       *aua_next;
 } aggr_unicst_addr_t;
 
 typedef struct aggr_pseudo_rx_ring_s {
-        mac_ring_handle_t       arr_rh; /* filled in by aggr_fill_ring() */
+        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 pseudo 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;
         aggr_pseudo_rx_ring_t   arg_rings[MAX_RINGS_PER_GROUP];
         uint_t                  arg_ring_cnt;

@@ -117,16 +128,17 @@
         uint32_t        lp_started : 1,
                         lp_tx_enabled : 1,
                         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;
+
         const mac_info_t *lp_mip;
         mac_notify_handle_t lp_mnh;
         uint_t          lp_tx_idx;              /* idx in group's tx array */
         uint64_t        lp_ifspeed;
         link_state_t    lp_link_state;

@@ -134,17 +146,23 @@
         uint64_t        lp_stat[MAC_NSTAT];
         uint64_t        lp_ether_stat[ETHER_NSTAT];
         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;
         /*
          * Handles of the pseudo TX rings. Each of them maps to

@@ -187,11 +205,11 @@
                         lg_vlan : 1,
                         lg_force : 1,
                         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;
         krwlock_t       lg_tx_lock;
         uint_t          lg_ntx_ports;

@@ -231,11 +249,13 @@
         mblk_t          *lg_lacp_head;
         mblk_t          *lg_lacp_tail;
         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;
         kcondvar_t      lg_tx_flowctl_cv;
         uint_t          lg_tx_blocked_cnt;

@@ -326,12 +346,10 @@
 extern uint64_t aggr_port_stat(aggr_port_t *, uint_t);
 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 *);
 extern void aggr_send_port_enable(aggr_port_t *);
 extern void aggr_send_port_disable(aggr_port_t *);

@@ -355,15 +373,15 @@
 
 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 *,
     uintptr_t, mac_ring_handle_t *);