summaryrefslogtreecommitdiff
path: root/usr/src/uts
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts')
-rw-r--r--usr/src/uts/common/io/aggr/aggr_grp.c13
-rw-r--r--usr/src/uts/common/io/bge/bge_chip2.c29
-rw-r--r--usr/src/uts/common/io/bge/bge_impl.h22
-rw-r--r--usr/src/uts/common/io/bge/bge_kstats.c27
-rw-r--r--usr/src/uts/common/io/bge/bge_main2.c516
-rw-r--r--usr/src/uts/common/io/bge/bge_ndd.c73
-rw-r--r--usr/src/uts/common/io/bge/bge_recv2.c8
-rw-r--r--usr/src/uts/common/io/dld/dld_drv.c74
-rw-r--r--usr/src/uts/common/io/dld/dld_proto.c12
-rw-r--r--usr/src/uts/common/io/dld/dld_str.c41
-rw-r--r--usr/src/uts/common/io/gld.c42
-rw-r--r--usr/src/uts/common/io/ipw/ipw2100.c1
-rw-r--r--usr/src/uts/common/io/ipw/ipw2100_impl.h7
-rw-r--r--usr/src/uts/common/io/mac/mac.c72
-rw-r--r--usr/src/uts/common/io/nge/nge_kstats.c25
-rw-r--r--usr/src/uts/common/io/strplumb.c1
-rw-r--r--usr/src/uts/common/io/vnic/vnic_dev.c5
-rw-r--r--usr/src/uts/common/sys/dld.h64
-rw-r--r--usr/src/uts/common/sys/mac.h31
-rw-r--r--usr/src/uts/common/sys/mac_impl.h2
-rw-r--r--usr/src/uts/common/xen/io/xnbo.c9
-rw-r--r--usr/src/uts/intel/mac/Makefile8
-rw-r--r--usr/src/uts/sparc/mac/Makefile8
-rw-r--r--usr/src/uts/sun/io/hme.c4
24 files changed, 905 insertions, 189 deletions
diff --git a/usr/src/uts/common/io/aggr/aggr_grp.c b/usr/src/uts/common/io/aggr/aggr_grp.c
index 65105e298e..2668c23790 100644
--- a/usr/src/uts/common/io/aggr/aggr_grp.c
+++ b/usr/src/uts/common/io/aggr/aggr_grp.c
@@ -1520,9 +1520,11 @@ aggr_grp_max_sdu(aggr_grp_t *grp)
ASSERT(grp->lg_ports != NULL);
for (port = grp->lg_ports; port != NULL; port = port->lp_next) {
- const mac_info_t *port_mi = mac_info(port->lp_mh);
- if (max_sdu > port_mi->mi_sdu_max)
- max_sdu = port_mi->mi_sdu_max;
+ uint_t port_sdu_max;
+
+ mac_sdu_get(port->lp_mh, NULL, &port_sdu_max);
+ if (max_sdu > port_sdu_max)
+ max_sdu = port_sdu_max;
}
return (max_sdu);
@@ -1536,9 +1538,10 @@ aggr_grp_max_sdu(aggr_grp_t *grp)
static boolean_t
aggr_grp_sdu_check(aggr_grp_t *grp, aggr_port_t *port)
{
- const mac_info_t *port_mi = mac_info(port->lp_mh);
+ uint_t port_sdu_max;
- return (port_mi->mi_sdu_max >= grp->lg_max_sdu);
+ mac_sdu_get(port->lp_mh, NULL, &port_sdu_max);
+ return (port_sdu_max >= grp->lg_max_sdu);
}
/*
diff --git a/usr/src/uts/common/io/bge/bge_chip2.c b/usr/src/uts/common/io/bge/bge_chip2.c
index 1f29ac14a9..f4a46a15da 100644
--- a/usr/src/uts/common/io/bge/bge_chip2.c
+++ b/usr/src/uts/common/io/bge/bge_chip2.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1934,8 +1934,6 @@ bge_chip_id_init(bge_t *bgep)
int err;
uint_t i;
- ASSERT(bgep->bge_chip_state == BGE_CHIP_INITIAL);
-
sys_ok = dev_ok = B_FALSE;
cidp = &bgep->chipid;
@@ -1963,6 +1961,8 @@ bge_chip_id_init(bge_t *bgep)
cidp->mbuf_lo_water_rdma = bge_mbuf_lo_water_rdma;
cidp->mbuf_lo_water_rmac = bge_mbuf_lo_water_rmac;
cidp->mbuf_hi_water = bge_mbuf_hi_water;
+ cidp->rx_ticks_norm = bge_rx_ticks_norm;
+ cidp->rx_count_norm = bge_rx_count_norm;
if (cidp->rx_rings == 0 || cidp->rx_rings > BGE_RECV_RINGS_MAX)
cidp->rx_rings = BGE_RECV_RINGS_DEFAULT;
@@ -2649,10 +2649,10 @@ bge_chip_enable_engine(bge_t *bgep, bge_regno_t regno, uint32_t morebits)
* Reprogram the Ethernet, Transmit, and Receive MAC
* modes to match the param_* variables
*/
-static void bge_sync_mac_modes(bge_t *bgep);
+void bge_sync_mac_modes(bge_t *bgep);
#pragma no_inline(bge_sync_mac_modes)
-static void
+void
bge_sync_mac_modes(bge_t *bgep)
{
uint32_t macmode;
@@ -2741,7 +2741,7 @@ bge_chip_sync(bge_t *bgep)
int retval = DDI_SUCCESS;
BGE_TRACE(("bge_chip_sync($%p)",
- (void *)bgep));
+ (void *)bgep));
ASSERT(mutex_owned(bgep->genlock));
@@ -2945,7 +2945,9 @@ bge_chip_stop(bge_t *bgep, boolean_t fault)
if (fault) {
if (bgep->bge_chip_state != BGE_CHIP_FAULT) {
bgep->bge_chip_state = BGE_CHIP_FAULT;
- ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_LOST);
+ if (!bgep->manual_reset)
+ ddi_fm_service_impact(bgep->devinfo,
+ DDI_SERVICE_LOST);
if (bgep->bge_dma_error) {
/*
* need to free buffers in case the fault was
@@ -3926,10 +3928,10 @@ bge_status_sync(bge_t *bgep, uint64_t bits, uint64_t *flags)
return (retval);
}
-static void bge_wake_factotum(bge_t *bgep);
+void bge_wake_factotum(bge_t *bgep);
#pragma inline(bge_wake_factotum)
-static void
+void
bge_wake_factotum(bge_t *bgep)
{
mutex_enter(bgep->softintrlock);
@@ -4464,8 +4466,10 @@ bge_chip_factotum(caddr_t arg)
bgep->asf_status = ASF_STAT_RUN;
}
#endif
- ddi_fm_service_impact(bgep->devinfo,
- DDI_SERVICE_RESTORED);
+ if (!bgep->manual_reset) {
+ ddi_fm_service_impact(bgep->devinfo,
+ DDI_SERVICE_RESTORED);
+ }
}
}
break;
@@ -4507,6 +4511,9 @@ bge_chip_factotum(caddr_t arg)
*/
if (linkchg)
mac_link_update(bgep->mh, bgep->link_state);
+ if (bgep->manual_reset) {
+ bgep->manual_reset = B_FALSE;
+ }
return (result);
}
diff --git a/usr/src/uts/common/io/bge/bge_impl.h b/usr/src/uts/common/io/bge/bge_impl.h
index 8b2bbaebc7..2da4240765 100644
--- a/usr/src/uts/common/io/bge/bge_impl.h
+++ b/usr/src/uts/common/io/bge/bge_impl.h
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -63,6 +63,7 @@ extern "C" {
#include <sys/pattr.h>
#include <sys/disp.h>
+#include <sys/cmn_err.h>
#include <sys/ddi.h>
#include <sys/sunddi.h>
@@ -616,6 +617,9 @@ typedef struct {
uint64_t hw_mac_addr; /* from chip register */
bge_mac_addr_t vendor_addr; /* transform of same */
boolean_t msi_enabled; /* default to true */
+
+ uint32_t rx_ticks_norm;
+ uint32_t rx_count_norm;
} chip_id_t;
#define CHIP_FLAG_SUPPORTED 0x80
@@ -696,7 +700,6 @@ enum {
PARAM_LINK_RX_PAUSE,
PARAM_LINK_TX_PAUSE,
- PARAM_LOOP_MODE,
PARAM_MSI_CNT,
PARAM_DRAIN_MAX,
@@ -916,6 +919,7 @@ typedef struct bge {
boolean_t send_hw_tcp_csum;
boolean_t recv_hw_tcp_csum;
boolean_t promisc;
+ boolean_t manual_reset;
/*
* Miscellaneous operating variables (not synchronised)
@@ -960,6 +964,17 @@ typedef struct bge {
uint32_t asf_status;
timeout_id_t asf_timeout_id;
#endif
+ uint32_t param_en_pause:1,
+ param_en_asym_pause:1,
+ param_en_1000hdx:1,
+ param_en_1000fdx:1,
+ param_en_100fdx:1,
+ param_en_100hdx:1,
+ param_en_10fdx:1,
+ param_en_10hdx:1,
+ param_pad_to_32:24;
+
+ uint32_t param_loop_mode;
} bge_t;
/*
@@ -1009,7 +1024,6 @@ typedef struct bge {
#define param_link_rx_pause nd_params[PARAM_LINK_RX_PAUSE].ndp_val
#define param_link_tx_pause nd_params[PARAM_LINK_TX_PAUSE].ndp_val
-#define param_loop_mode nd_params[PARAM_LOOP_MODE].ndp_val
#define param_msi_cnt nd_params[PARAM_MSI_CNT].ndp_val
#define param_drain_max nd_params[PARAM_DRAIN_MAX].ndp_val
@@ -1220,6 +1234,7 @@ void bge_chip_cyclic(void *arg);
enum ioc_reply bge_chip_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp,
struct iocblk *iocp);
uint_t bge_intr(caddr_t arg1, caddr_t arg2);
+void bge_sync_mac_modes(bge_t *);
extern uint32_t bge_rx_ticks_norm;
extern uint32_t bge_tx_ticks_norm;
extern uint32_t bge_rx_count_norm;
@@ -1260,6 +1275,7 @@ int bge_alloc_bufs(bge_t *bgep);
void bge_free_bufs(bge_t *bgep);
void bge_intr_enable(bge_t *bgep);
void bge_intr_disable(bge_t *bgep);
+int bge_reprogram(bge_t *);
/* bge_phys.c */
int bge_phys_init(bge_t *bgep);
diff --git a/usr/src/uts/common/io/bge/bge_kstats.c b/usr/src/uts/common/io/bge/bge_kstats.c
index 98141d92ce..32af1a2b13 100644
--- a/usr/src/uts/common/io/bge/bge_kstats.c
+++ b/usr/src/uts/common/io/bge/bge_kstats.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -600,31 +600,6 @@ bge_setup_named_kstat(bge_t *bgep, int instance, char *name,
return (ksp);
}
-/*
- * Create kstats corresponding to NDD parameters
- */
-static kstat_t *
-bge_setup_params_kstat(bge_t *bgep, int instance, char *name,
- int (*update)(kstat_t *, int))
-{
- kstat_t *ksp;
- kstat_named_t *knp;
- int i;
-
- ksp = kstat_create(BGE_DRIVER_NAME, instance, name, "net",
- KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT);
- if (ksp != NULL) {
- ksp->ks_private = bgep;
- ksp->ks_update = update;
- for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
- kstat_named_init(knp, bgep->nd_params[i].ndp_name+1,
- KSTAT_DATA_UINT64);
- kstat_install(ksp);
- }
-
- return (ksp);
-}
-
void
bge_init_kstats(bge_t *bgep, int instance)
{
diff --git a/usr/src/uts/common/io/bge/bge_main2.c b/usr/src/uts/common/io/bge/bge_main2.c
index f80a750652..7a13f85e50 100644
--- a/usr/src/uts/common/io/bge/bge_main2.c
+++ b/usr/src/uts/common/io/bge/bge_main2.c
@@ -28,6 +28,7 @@
#include "bge_impl.h"
#include <sys/sdt.h>
+#include <sys/dld.h>
/*
* This is the string displayed by modinfo, etc.
@@ -127,8 +128,17 @@ static int bge_m_unicst_add(void *, mac_multi_addr_t *);
static int bge_m_unicst_remove(void *, mac_addr_slot_t);
static int bge_m_unicst_modify(void *, mac_multi_addr_t *);
static int bge_m_unicst_get(void *, mac_multi_addr_t *);
-
-#define BGE_M_CALLBACK_FLAGS (MC_RESOURCES | MC_IOCTL | MC_GETCAPAB)
+static int bge_m_setprop(void *, const char *, mac_prop_id_t,
+ uint_t, const void *);
+static int bge_m_getprop(void *, const char *, mac_prop_id_t,
+ uint_t, void *);
+static int bge_set_priv_prop(bge_t *, const char *, uint_t,
+ const void *);
+static int bge_get_priv_prop(bge_t *, const char *, uint_t,
+ void *);
+
+#define BGE_M_CALLBACK_FLAGS\
+ (MC_RESOURCES | MC_IOCTL | MC_GETCAPAB | MC_SETPROP | MC_GETPROP)
static mac_callbacks_t bge_m_callbacks = {
BGE_M_CALLBACK_FLAGS,
@@ -141,7 +151,11 @@ static mac_callbacks_t bge_m_callbacks = {
bge_m_tx,
bge_m_resources,
bge_m_ioctl,
- bge_m_getcapab
+ bge_m_getcapab,
+ NULL,
+ NULL,
+ bge_m_setprop,
+ bge_m_getprop
};
/*
@@ -834,6 +848,439 @@ bge_m_unicst_get(void *arg, mac_multi_addr_t *maddr)
return (0);
}
+extern void bge_wake_factotum(bge_t *);
+
+static boolean_t
+bge_param_locked(mac_prop_id_t pr_num)
+{
+ /*
+ * All adv_* parameters are locked (read-only) while
+ * the device is in any sort of loopback mode ...
+ */
+ switch (pr_num) {
+ case DLD_PROP_ADV_1000FDX_CAP:
+ case DLD_PROP_EN_1000FDX_CAP:
+ case DLD_PROP_ADV_1000HDX_CAP:
+ case DLD_PROP_EN_1000HDX_CAP:
+ case DLD_PROP_ADV_100FDX_CAP:
+ case DLD_PROP_EN_100FDX_CAP:
+ case DLD_PROP_ADV_100HDX_CAP:
+ case DLD_PROP_EN_100HDX_CAP:
+ case DLD_PROP_ADV_10FDX_CAP:
+ case DLD_PROP_EN_10FDX_CAP:
+ case DLD_PROP_ADV_10HDX_CAP:
+ case DLD_PROP_EN_10HDX_CAP:
+ case DLD_PROP_AUTONEG:
+ case DLD_PROP_FLOWCTRL:
+ return (B_TRUE);
+ }
+ return (B_FALSE);
+}
+/*
+ * callback functions for set/get of properties
+ */
+static int
+bge_m_setprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
+ uint_t pr_valsize, const void *pr_val)
+{
+ bge_t *bgep = barg;
+ int err = 0;
+ uint64_t cur_mtu, new_mtu;
+ uint_t maxsdu;
+ link_flowctrl_t fl;
+
+ mutex_enter(bgep->genlock);
+ if (bgep->param_loop_mode != BGE_LOOP_NONE &&
+ bge_param_locked(pr_num)) {
+ /*
+ * All adv_* parameters are locked (read-only)
+ * while the device is in any sort of loopback mode.
+ */
+ mutex_exit(bgep->genlock);
+ return (EBUSY);
+ }
+ switch (pr_num) {
+ case DLD_PROP_EN_1000FDX_CAP:
+ bgep->param_en_1000fdx = *(uint8_t *)pr_val;
+ bgep->param_adv_1000fdx = *(uint8_t *)pr_val;
+ goto reprogram;
+ case DLD_PROP_EN_1000HDX_CAP:
+ bgep->param_en_1000hdx = *(uint8_t *)pr_val;
+ bgep->param_adv_1000hdx = *(uint8_t *)pr_val;
+ goto reprogram;
+ case DLD_PROP_EN_100FDX_CAP:
+ bgep->param_en_100fdx = *(uint8_t *)pr_val;
+ bgep->param_adv_100fdx = *(uint8_t *)pr_val;
+ goto reprogram;
+ case DLD_PROP_EN_100HDX_CAP:
+ bgep->param_en_100hdx = *(uint8_t *)pr_val;
+ bgep->param_adv_100hdx = *(uint8_t *)pr_val;
+ goto reprogram;
+ case DLD_PROP_EN_10FDX_CAP:
+ bgep->param_en_10fdx = *(uint8_t *)pr_val;
+ bgep->param_adv_10fdx = *(uint8_t *)pr_val;
+ goto reprogram;
+ case DLD_PROP_EN_10HDX_CAP:
+ bgep->param_en_10hdx = *(uint8_t *)pr_val;
+ bgep->param_adv_10hdx = *(uint8_t *)pr_val;
+reprogram:
+ if (err == 0 && bge_reprogram(bgep) == IOC_INVAL)
+ err = EINVAL;
+ break;
+ case DLD_PROP_ADV_1000FDX_CAP:
+ case DLD_PROP_ADV_1000HDX_CAP:
+ case DLD_PROP_ADV_100FDX_CAP:
+ case DLD_PROP_ADV_100HDX_CAP:
+ case DLD_PROP_ADV_10FDX_CAP:
+ case DLD_PROP_ADV_10HDX_CAP:
+ case DLD_PROP_STATUS:
+ case DLD_PROP_SPEED:
+ case DLD_PROP_DUPLEX:
+ err = EINVAL; /* read-only prop. Can't set this */
+ break;
+ case DLD_PROP_AUTONEG:
+ bgep->param_adv_autoneg = *(uint8_t *)pr_val;
+ if (bge_reprogram(bgep) == IOC_INVAL)
+ err = EINVAL;
+ break;
+ case DLD_PROP_DEFMTU:
+ cur_mtu = bgep->chipid.default_mtu;
+ bcopy(pr_val, &new_mtu, sizeof (new_mtu));
+ if (new_mtu == cur_mtu) {
+ err = 0;
+ break;
+ }
+ if (new_mtu < BGE_DEFAULT_MTU ||
+ new_mtu > BGE_MAXIMUM_MTU) {
+ err = EINVAL;
+ break;
+ }
+ if ((new_mtu > BGE_DEFAULT_MTU) &&
+ (bgep->chipid.flags & CHIP_FLAG_NO_JUMBO)) {
+ err = EINVAL;
+ break;
+ }
+ if (bgep->bge_mac_state == BGE_MAC_STARTED) {
+ err = EBUSY;
+ break;
+ }
+ bgep->chipid.default_mtu = new_mtu;
+ if (bge_chip_id_init(bgep)) {
+ err = EINVAL;
+ break;
+ }
+ maxsdu = bgep->chipid.ethmax_size -
+ sizeof (struct ether_header);
+ err = mac_maxsdu_update(bgep->mh, maxsdu);
+ if (err == 0) {
+ bgep->bge_dma_error = B_TRUE;
+ bgep->manual_reset = B_TRUE;
+ bge_chip_stop(bgep, B_TRUE);
+ bge_wake_factotum(bgep);
+ err = 0;
+ }
+ break;
+ case DLD_PROP_FLOWCTRL:
+ bcopy(pr_val, &fl, sizeof (fl));
+ switch (fl) {
+ default:
+ err = EINVAL;
+ break;
+ case LINK_FLOWCTRL_NONE:
+ bgep->param_adv_pause = 0;
+ bgep->param_adv_asym_pause = 0;
+
+ bgep->param_link_rx_pause = B_FALSE;
+ bgep->param_link_tx_pause = B_FALSE;
+ break;
+ case LINK_FLOWCTRL_RX:
+ if (!((bgep->param_lp_pause == 0) &&
+ (bgep->param_lp_asym_pause == 1))) {
+ err = EINVAL;
+ break;
+ }
+ bgep->param_adv_pause = 1;
+ bgep->param_adv_asym_pause = 1;
+
+ bgep->param_link_rx_pause = B_TRUE;
+ bgep->param_link_tx_pause = B_FALSE;
+ break;
+ case LINK_FLOWCTRL_TX:
+ if (!((bgep->param_lp_pause == 1) &&
+ (bgep->param_lp_asym_pause == 1))) {
+ err = EINVAL;
+ break;
+ }
+ bgep->param_adv_pause = 0;
+ bgep->param_adv_asym_pause = 1;
+
+ bgep->param_link_rx_pause = B_FALSE;
+ bgep->param_link_tx_pause = B_TRUE;
+ break;
+ case LINK_FLOWCTRL_BI:
+ if (bgep->param_lp_pause != 1) {
+ err = EINVAL;
+ break;
+ }
+ bgep->param_adv_pause = 1;
+
+ bgep->param_link_rx_pause = B_TRUE;
+ bgep->param_link_tx_pause = B_TRUE;
+ break;
+ }
+
+ if (err == 0) {
+ if (bge_reprogram(bgep) == IOC_INVAL)
+ err = EINVAL;
+ }
+
+ break;
+ default:
+ err = bge_set_priv_prop(bgep, pr_name, pr_valsize,
+ pr_val);
+ break;
+ }
+ mutex_exit(bgep->genlock);
+ return (err);
+}
+static int
+bge_m_getprop(void *barg, const char *pr_name, mac_prop_id_t pr_num,
+ uint_t pr_valsize, void *pr_val)
+{
+ bge_t *bgep = barg;
+ int err = 0;
+ link_flowctrl_t fl;
+
+ bzero(pr_val, pr_valsize);
+ switch (pr_num) {
+ case DLD_PROP_DUPLEX:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_link_duplex;
+ break;
+ case DLD_PROP_SPEED:
+ if (pr_valsize < sizeof (uint_t))
+ return (EINVAL);
+ bcopy(&(bgep->param_link_speed), pr_val,
+ sizeof (bgep->param_link_speed));
+ break;
+ case DLD_PROP_STATUS:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_link_up;
+ break;
+ case DLD_PROP_AUTONEG:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_autoneg;
+ break;
+ case DLD_PROP_DEFMTU: {
+ uint64_t tmp = 0;
+
+ if (pr_valsize < sizeof (uint64_t))
+ return (EINVAL);
+ tmp = bgep->chipid.default_mtu;
+ bcopy(&tmp, pr_val, sizeof (tmp));
+ break;
+ }
+ case DLD_PROP_FLOWCTRL:
+ if (pr_valsize < sizeof (link_flowctrl_t))
+ return (EINVAL);
+ if (bgep->param_link_rx_pause &&
+ !bgep->param_link_tx_pause)
+ fl = LINK_FLOWCTRL_RX;
+
+ if (!bgep->param_link_rx_pause &&
+ !bgep->param_link_tx_pause)
+ fl = LINK_FLOWCTRL_NONE;
+
+ if (!bgep->param_link_rx_pause &&
+ bgep->param_link_tx_pause)
+ fl = LINK_FLOWCTRL_TX;
+
+ if (bgep->param_link_rx_pause &&
+ bgep->param_link_tx_pause)
+ fl = LINK_FLOWCTRL_BI;
+ bcopy(&fl, pr_val, sizeof (fl));
+ break;
+ case DLD_PROP_ADV_1000FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_1000fdx;
+ break;
+ case DLD_PROP_EN_1000FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_1000fdx;
+ break;
+ case DLD_PROP_ADV_1000HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_1000hdx;
+ break;
+ case DLD_PROP_EN_1000HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_1000hdx;
+ break;
+ case DLD_PROP_ADV_100FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_100fdx;
+ break;
+ case DLD_PROP_EN_100FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_100fdx;
+ break;
+ case DLD_PROP_ADV_100HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_100hdx;
+ break;
+ case DLD_PROP_EN_100HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_100hdx;
+ break;
+ case DLD_PROP_ADV_10FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_10fdx;
+ break;
+ case DLD_PROP_EN_10FDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_10fdx;
+ break;
+ case DLD_PROP_ADV_10HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_adv_10hdx;
+ break;
+ case DLD_PROP_EN_10HDX_CAP:
+ if (pr_valsize < sizeof (uint8_t))
+ return (EINVAL);
+ *(uint8_t *)pr_val = bgep->param_en_10hdx;
+ break;
+ default:
+ err = bge_get_priv_prop(bgep, pr_name, pr_valsize,
+ pr_val);
+ return (err);
+ }
+ return (0);
+}
+
+/* ARGSUSED */
+static int
+bge_set_priv_prop(bge_t *bgep, const char *pr_name, uint_t pr_valsize,
+ const void *pr_val)
+{
+ int err = 0;
+ long result;
+
+ if (strcmp(pr_name, "_drain_max") == 0) {
+
+ /*
+ * on the Tx side, we need to update the h/w register for
+ * real packet transmission per packet. The drain_max parameter
+ * is used to reduce the register access. This parameter
+ * controls the max number of packets that we will hold before
+ * updating the bge h/w to trigger h/w transmit. The bge
+ * chipset usually has a max of 512 Tx descriptors, thus
+ * the upper bound on drain_max is 512.
+ */
+ if (pr_val == NULL) {
+ err = EINVAL;
+ return (err);
+ }
+ (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
+ if (result > 512 || result < 1)
+ err = EINVAL;
+ else {
+ bgep->param_drain_max = (uint32_t)result;
+ if (bge_reprogram(bgep) == IOC_INVAL)
+ err = EINVAL;
+ }
+ return (err);
+ }
+ if (strcmp(pr_name, "_msi_cnt") == 0) {
+
+ if (pr_val == NULL) {
+ err = EINVAL;
+ return (err);
+ }
+ (void) ddi_strtol(pr_val, (char **)NULL, 0, &result);
+ if (result > 7 || result < 0)
+ err = EINVAL;
+ else {
+ bgep->param_msi_cnt = (uint32_t)result;
+ if (bge_reprogram(bgep) == IOC_INVAL)
+ err = EINVAL;
+ }
+ return (err);
+ }
+ if (strcmp(pr_name, "_intr_coalesce_blank_time") == 0) {
+ if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0) {
+ return (EINVAL);
+ }
+
+ bgep->chipid.rx_ticks_norm = result;
+ return (0);
+ }
+
+ if (strcmp(pr_name, "_intr_coalesce_pkt_cnt") == 0) {
+ if (ddi_strtol(pr_val, (char **)NULL, 0, &result) != 0)
+ return (EINVAL);
+
+ bgep->chipid.rx_count_norm = result;
+ return (0);
+ }
+ return (EINVAL);
+}
+
+static int
+bge_get_priv_prop(bge_t *bge, const char *pr_name, uint_t pr_valsize,
+ void *pr_val)
+{
+ char valstr[MAXNAMELEN];
+ int err = EINVAL;
+ uint_t strsize;
+
+
+ if (strcmp(pr_name, "_drain_max") == 0) {
+ (void) sprintf(valstr, "%d", bge->param_drain_max);
+ err = 0;
+ goto done;
+ }
+ if (strcmp(pr_name, "_msi_cnt") == 0) {
+ (void) sprintf(valstr, "%d", bge->param_msi_cnt);
+ err = 0;
+ goto done;
+ }
+
+ if (strcmp(pr_name, "_intr_coalesce_blank_time") == 0) {
+ (void) sprintf(valstr, "%d", bge->chipid.rx_ticks_norm);
+ err = 0;
+ goto done;
+ }
+
+ if (strcmp(pr_name, "_intr_coalesce_pkt_cnt") == 0) {
+ (void) sprintf(valstr, "%d", bge->chipid.rx_count_norm);
+ err = 0;
+ goto done;
+ }
+
+done:
+ strsize = (uint_t)strlen(valstr);
+ if (pr_valsize < strsize) {
+ err = ENOBUFS;
+ } else {
+ (void) strlcpy(pr_val, valstr, pr_valsize);
+ }
+ return (err);
+}
+
/*
* Compute the index of the required bit in the multicast hash map.
* This must mirror the way the hardware actually does it!
@@ -1262,22 +1709,8 @@ bge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
switch (status) {
case IOC_RESTART_REPLY:
case IOC_RESTART_ACK:
- if (bge_phys_update(bgep) != DDI_SUCCESS) {
- ddi_fm_service_impact(bgep->devinfo,
- DDI_SERVICE_DEGRADED);
- status = IOC_INVAL;
- }
-#ifdef BGE_IPMI_ASF
- if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
-#else
- if (bge_chip_sync(bgep) == DDI_FAILURE) {
-#endif
- ddi_fm_service_impact(bgep->devinfo,
- DDI_SERVICE_DEGRADED);
+ if (bge_reprogram(bgep) == IOC_INVAL)
status = IOC_INVAL;
- }
- if (bgep->intr_type == DDI_INTR_TYPE_MSI)
- bge_chip_msi_trig(bgep);
break;
}
@@ -1331,15 +1764,13 @@ bge_m_ioctl(void *arg, queue_t *wq, mblk_t *mp)
}
static void
-bge_m_resources(void *arg)
+bge_resources_add(bge_t *bgep, time_t time, uint_t pkt_cnt)
{
- bge_t *bgep = arg;
+
recv_ring_t *rrp;
mac_rx_fifo_t mrf;
int ring;
- mutex_enter(bgep->genlock);
-
/*
* Register Rx rings as resources and save mac
* resource id for future reference
@@ -1347,15 +1778,25 @@ bge_m_resources(void *arg)
mrf.mrf_type = MAC_RX_FIFO;
mrf.mrf_blank = bge_chip_blank;
mrf.mrf_arg = (void *)bgep;
- mrf.mrf_normal_blank_time = bge_rx_ticks_norm;
- mrf.mrf_normal_pkt_count = bge_rx_count_norm;
+ mrf.mrf_normal_blank_time = time;
+ mrf.mrf_normal_pkt_count = pkt_cnt;
for (ring = 0; ring < bgep->chipid.rx_rings; ring++) {
rrp = &bgep->recv[ring];
rrp->handle = mac_resource_add(bgep->mh,
(mac_resource_t *)&mrf);
}
+}
+static void
+bge_m_resources(void *arg)
+{
+ bge_t *bgep = arg;
+
+ mutex_enter(bgep->genlock);
+
+ bge_resources_add(bgep, bgep->chipid.rx_ticks_norm,
+ bgep->chipid.rx_count_norm);
mutex_exit(bgep->genlock);
}
@@ -2520,6 +2961,9 @@ bge_attach(dev_info_t *devinfo, ddi_attach_cmd_t cmd)
ddi_set_driver_private(devinfo, bgep);
bgep->bge_guard = BGE_GUARD;
bgep->devinfo = devinfo;
+ bgep->param_drain_max = 64;
+ bgep->param_msi_cnt = 0;
+ bgep->param_loop_mode = 0;
/*
* Initialize more fields in BGE private data
@@ -3241,3 +3685,27 @@ bge_intr_disable(bge_t *bgep)
}
}
}
+
+int
+bge_reprogram(bge_t *bgep)
+{
+ int status = 0;
+
+ ASSERT(mutex_owned(bgep->genlock));
+
+ if (bge_phys_update(bgep) != DDI_SUCCESS) {
+ ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+ status = IOC_INVAL;
+ }
+#ifdef BGE_IPMI_ASF
+ if (bge_chip_sync(bgep, B_TRUE) == DDI_FAILURE) {
+#else
+ if (bge_chip_sync(bgep) == DDI_FAILURE) {
+#endif
+ ddi_fm_service_impact(bgep->devinfo, DDI_SERVICE_DEGRADED);
+ status = IOC_INVAL;
+ }
+ if (bgep->intr_type == DDI_INTR_TYPE_MSI)
+ bge_chip_msi_trig(bgep);
+ return (status);
+}
diff --git a/usr/src/uts/common/io/bge/bge_ndd.c b/usr/src/uts/common/io/bge/bge_ndd.c
index ca993b64f7..280f3b6bcb 100644
--- a/usr/src/uts/common/io/bge/bge_ndd.c
+++ b/usr/src/uts/common/io/bge/bge_ndd.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -30,7 +30,6 @@
#define BGE_DBG BGE_DBG_NDD /* debug flag for this code */
-
/*
* Property names
*/
@@ -112,15 +111,6 @@ static const nd_param_t nd_template[] = {
{ PARAM_LINK_RX_PAUSE, 0, 1, 0, "-link_rx_pause" },
{ PARAM_LINK_TX_PAUSE, 0, 1, 0, "-link_tx_pause" },
-/* Loopback status */
-{ PARAM_LOOP_MODE, 0, 5, 0, "-loop_mode" },
-
-/* MSI count */
-{ PARAM_MSI_CNT, 0, 7, 0, "+msi_cnt" },
-
-/* Performance tuning */
-{ PARAM_DRAIN_MAX, 1, 512, 64, "+drain_max" },
-
/* Terminator */
{ PARAM_COUNT, 0, 0, 0, NULL }
};
@@ -146,6 +136,27 @@ bge_param_get(queue_t *q, mblk_t *mp, caddr_t cp, cred_t *credp)
}
/*
+ * synchronize the adv* and en* parameters.
+ *
+ * See comments in <sys/dld.h> for details of the *_en_*
+ * parameters. The usage of ndd for setting adv parameters will
+ * synchronize all the en parameters with the bge parameters,
+ * implicitly disabling any settings made via dladm.
+ */
+static void
+bge_param_sync(bge_t *bgep)
+{
+ bgep->param_en_pause = bgep->param_adv_pause;
+ bgep->param_en_asym_pause = bgep->param_adv_asym_pause;
+ bgep->param_en_1000fdx = bgep->param_adv_1000fdx;
+ bgep->param_en_1000hdx = bgep->param_adv_1000hdx;
+ bgep->param_en_100fdx = bgep->param_adv_100fdx;
+ bgep->param_en_100hdx = bgep->param_adv_100hdx;
+ bgep->param_en_10fdx = bgep->param_adv_10fdx;
+ bgep->param_en_10hdx = bgep->param_adv_10hdx;
+}
+
+/*
* Validates the request to set a BGE parameter to a specific value.
* If the request is OK, the parameter is set. Also the <info> field
* is incremented to show that the parameter was touched, even though
@@ -251,7 +262,7 @@ bge_param_register(bge_t *bgep)
nd_fail:
BGE_DEBUG(("bge_param_register: FAILED at index %d [info %d]",
- tmplp-nd_template, tmplp->ndp_info));
+ tmplp-nd_template, tmplp->ndp_info));
nd_free(nddpp);
return (DDI_FAILURE);
}
@@ -280,8 +291,8 @@ bge_nd_init(bge_t *bgep)
*/
if (BGE_PROP_EXISTS(bgep->devinfo, supported_net)) {
if (ddi_prop_lookup_string_array(DDI_DEV_T_ANY, bgep->devinfo,
- DDI_PROP_DONTPASS, supported_net,
- &options, &noptions) == DDI_PROP_SUCCESS) {
+ DDI_PROP_DONTPASS, supported_net,
+ &options, &noptions) == DDI_PROP_SUCCESS) {
bgep->param_adv_autoneg = 0;
bgep->param_adv_1000fdx = 0;
@@ -342,7 +353,7 @@ bge_nd_init(bge_t *bgep)
speed = BGE_PROP_GET_INT(dip, transfer_speed_propname);
bge_log(bgep, "%s property is %d",
- transfer_speed_propname, speed);
+ transfer_speed_propname, speed);
switch (speed) {
case 1000:
@@ -401,9 +412,9 @@ bge_nd_init(bge_t *bgep)
speed = BGE_PROP_GET_INT(dip, speed_propname);
duplex = BGE_PROP_GET_INT(dip, duplex_propname);
bge_log(bgep, "%s property is %d",
- speed_propname, speed);
+ speed_propname, speed);
bge_log(bgep, "%s property is %d",
- duplex_propname, duplex);
+ duplex_propname, duplex);
switch (speed) {
case 1000:
@@ -446,15 +457,17 @@ bge_nd_init(bge_t *bgep)
}
BGE_DEBUG(("bge_nd_init: autoneg %d"
- "pause %d asym_pause %d "
- "1000fdx %d 1000hdx %d "
- "100fdx %d 100hdx %d "
- "10fdx %d 10hdx %d ",
- bgep->param_adv_autoneg,
- bgep->param_adv_pause, bgep->param_adv_asym_pause,
- bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
- bgep->param_adv_100fdx, bgep->param_adv_100hdx,
- bgep->param_adv_10fdx, bgep->param_adv_10hdx));
+ "pause %d asym_pause %d "
+ "1000fdx %d 1000hdx %d "
+ "100fdx %d 100hdx %d "
+ "10fdx %d 10hdx %d ",
+ bgep->param_adv_autoneg,
+ bgep->param_adv_pause, bgep->param_adv_asym_pause,
+ bgep->param_adv_1000fdx, bgep->param_adv_1000hdx,
+ bgep->param_adv_100fdx, bgep->param_adv_100hdx,
+ bgep->param_adv_10fdx, bgep->param_adv_10hdx));
+
+ bge_param_sync(bgep);
return (0);
}
@@ -468,7 +481,7 @@ bge_nd_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
int cmd;
BGE_TRACE(("bge_nd_ioctl($%p, $%p, $%p, $%p)",
- (void *)bgep, (void *)wq, (void *)mp, (void *)iocp));
+ (void *)bgep, (void *)wq, (void *)mp, (void *)iocp));
ASSERT(mutex_owned(bgep->genlock));
@@ -513,6 +526,8 @@ bge_nd_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
info = ndp->ndp_info;
ok = nd_getset(wq, bgep->nd_data_p, mp);
+ bge_param_sync(bgep);
+
/*
* If nd_getset() returns B_FALSE, the command was
* not valid (e.g. unknown name), so we just tell
@@ -526,8 +541,8 @@ bge_nd_ioctl(bge_t *bgep, queue_t *wq, mblk_t *mp, struct iocblk *iocp)
* So, we also drop out in that case ...
*/
BGE_DEBUG(("bge_nd_ioctl: set %s err %d autoneg %d info %d/%d",
- ok ? "OK" : "FAIL", iocp->ioc_error,
- ndp->ndp_val, info, ndp->ndp_info));
+ ok ? "OK" : "FAIL", iocp->ioc_error,
+ ndp->ndp_val, info, ndp->ndp_info));
if (!ok)
return (IOC_INVAL);
if (iocp->ioc_error)
diff --git a/usr/src/uts/common/io/bge/bge_recv2.c b/usr/src/uts/common/io/bge/bge_recv2.c
index 78a5913ae2..06282b461b 100644
--- a/usr/src/uts/common/io/bge/bge_recv2.c
+++ b/usr/src/uts/common/io/bge/bge_recv2.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -211,8 +211,8 @@ bge_receive_packet(bge_t *bgep, bge_rbd_t *hw_rbd_p)
ehp->ether_tpid = ntohs(ETHERTYPE_VLAN);
ehp->ether_tci = ntohs(hw_rbd.vlan_tci);
bcopy(((uchar_t *)(DMA_VPTR(srbdp->pbuf))) + 2 * ETHERADDRL,
- dp + 2 * ETHERADDRL + VLAN_TAGSZ,
- len - 2 * ETHERADDRL);
+ dp + 2 * ETHERADDRL + VLAN_TAGSZ,
+ len - 2 * ETHERADDRL);
} else {
#endif
mp->b_rptr = dp = mp->b_rptr + BGE_HEADROOM;
@@ -312,7 +312,7 @@ bge_receive_ring(bge_t *bgep, recv_ring_t *rrp)
slot = rrp->rx_next;
while ((slot != *rrp->prod_index_p) && /* Note: volatile */
- (recv_cnt < BGE_MAXPKT_RCVED)) {
+ (recv_cnt < BGE_MAXPKT_RCVED)) {
if ((mp = bge_receive_packet(bgep, &hw_rbd_p[slot])) != NULL) {
*tail = mp;
tail = &mp->b_next;
diff --git a/usr/src/uts/common/io/dld/dld_drv.c b/usr/src/uts/common/io/dld/dld_drv.c
index 2b394c051d..e09b6eff13 100644
--- a/usr/src/uts/common/io/dld/dld_drv.c
+++ b/usr/src/uts/common/io/dld/dld_drv.c
@@ -431,8 +431,8 @@ drv_ioc_attr(dld_ctl_str_t *ctls, mblk_t *mp)
dls_devnet_rele_tmp(dlh);
goto failed;
}
+ mac_sdu_get(dvp->dv_dlp->dl_mh, NULL, &diap->dia_max_sdu);
- diap->dia_max_sdu = dvp->dv_dlp->dl_mip->mi_sdu_max;
dls_vlan_rele(dvp);
dls_devnet_rele_tmp(dlh);
@@ -507,6 +507,72 @@ failed:
}
/*
+ * DLDIOCSETPROP
+ */
+static void
+drv_ioc_prop_common(dld_ctl_str_t *ctls, mblk_t *mp, boolean_t set)
+{
+ int err = EINVAL, dsize;
+ queue_t *q = ctls->cs_wq;
+ dld_ioc_prop_t *dipp;
+ dls_dl_handle_t dlh;
+ dls_vlan_t *dvp;
+ datalink_id_t linkid;
+ mac_prop_t macprop;
+
+ if ((err = miocpullup(mp, sizeof (dld_ioc_prop_t))) != 0)
+ goto done;
+ dipp = (dld_ioc_prop_t *)mp->b_cont->b_rptr;
+
+ dsize = sizeof (dld_ioc_prop_t) + dipp->pr_valsize - 1;
+ if ((err = miocpullup(mp, dsize)) != 0)
+ goto done;
+ dipp = (dld_ioc_prop_t *)mp->b_cont->b_rptr;
+
+ if ((err = dls_mgmt_get_linkid(dipp->pr_linkname, &linkid)) != 0)
+ goto done;
+
+ if ((err = dls_devnet_hold_tmp(linkid, &dlh)) != 0)
+ goto done;
+
+ if ((err = dls_vlan_hold(dls_devnet_mac(dlh),
+ dls_devnet_vid(dlh), &dvp, B_FALSE, B_FALSE)) != 0) {
+ dls_devnet_rele_tmp(dlh);
+ goto done;
+ }
+
+ macprop.mp_name = dipp->pr_name;
+ macprop.mp_id = dipp->pr_num;
+
+ if (set)
+ err = mac_set_prop(dvp->dv_dlp->dl_mh, &macprop,
+ dipp->pr_val, dipp->pr_valsize);
+ else
+ err = mac_get_prop(dvp->dv_dlp->dl_mh, &macprop,
+ dipp->pr_val, dipp->pr_valsize);
+
+ dls_vlan_rele(dvp);
+ dls_devnet_rele_tmp(dlh);
+done:
+ if (err == 0)
+ miocack(q, mp, dsize, 0);
+ else
+ miocnak(q, mp, 0, err);
+}
+
+static void
+drv_ioc_setprop(dld_ctl_str_t *ctls, mblk_t *mp)
+{
+ drv_ioc_prop_common(ctls, mp, B_TRUE);
+}
+
+static void
+drv_ioc_getprop(dld_ctl_str_t *ctls, mblk_t *mp)
+{
+ drv_ioc_prop_common(ctls, mp, B_FALSE);
+}
+
+/*
* DLDIOC_CREATE_VLAN
*/
static void
@@ -900,6 +966,12 @@ drv_ioc(dld_ctl_str_t *ctls, mblk_t *mp)
case DLDIOC_SECOBJ_UNSET:
drv_ioc_secobj_unset(ctls, mp);
return;
+ case DLDIOCSETPROP:
+ drv_ioc_setprop(ctls, mp);
+ return;
+ case DLDIOCGETPROP:
+ drv_ioc_getprop(ctls, mp);
+ return;
case DLDIOC_CREATE_VLAN:
drv_ioc_create_vlan(ctls, mp);
return;
diff --git a/usr/src/uts/common/io/dld/dld_proto.c b/usr/src/uts/common/io/dld/dld_proto.c
index 78543294d4..f572c3c322 100644
--- a/usr/src/uts/common/io/dld/dld_proto.c
+++ b/usr/src/uts/common/io/dld/dld_proto.c
@@ -238,6 +238,8 @@ proto_info_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp)
minfop = &minfo;
} else {
minfop = (mac_info_t *)dsp->ds_mip;
+ /* We can only get the sdu if we're attached. */
+ mac_sdu_get(dsp->ds_mh, &dlp->dl_min_sdu, &dlp->dl_max_sdu);
}
/*
@@ -255,12 +257,6 @@ proto_info_req(dld_str_t *dsp, union DL_primitives *udlp, mblk_t *mp)
sap_length = sizeof (uint16_t);
dlp->dl_sap_length = NEG(sap_length);
- /*
- * Set the minimum and maximum payload sizes.
- */
- dlp->dl_min_sdu = minfop->mi_sdu_min;
- dlp->dl_max_sdu = minfop->mi_sdu_max;
-
addr_length = minfop->mi_addr_length;
/*
@@ -1322,6 +1318,7 @@ dld_wput_proto_data(dld_str_t *dsp, mblk_t *mp)
mblk_t *bp, *payload;
uint32_t start, stuff, end, value, flags;
t_uscalar_t dl_err;
+ uint_t max_sdu;
if (MBLKL(mp) < sizeof (dl_unitdata_req_t) || mp->b_cont == NULL) {
dl_err = DL_BADPRIM;
@@ -1358,7 +1355,8 @@ dld_wput_proto_data(dld_str_t *dsp, mblk_t *mp)
size += MBLKL(bp);
}
- if (size > dsp->ds_mip->mi_sdu_max)
+ mac_sdu_get(dsp->ds_mh, NULL, &max_sdu);
+ if (size > max_sdu)
goto baddata;
/*
diff --git a/usr/src/uts/common/io/dld/dld_str.c b/usr/src/uts/common/io/dld/dld_str.c
index f89e4a5f94..bb39729813 100644
--- a/usr/src/uts/common/io/dld/dld_str.c
+++ b/usr/src/uts/common/io/dld/dld_str.c
@@ -1008,6 +1008,7 @@ str_mdata_raw_put(dld_str_t *dsp, mblk_t *mp)
size_t size;
mac_header_info_t mhi;
uint_t pri, vid;
+ uint_t max_sdu;
/*
* Certain MAC type plugins provide an illusion for raw DLPI
@@ -1042,12 +1043,13 @@ str_mdata_raw_put(dld_str_t *dsp, mblk_t *mp)
if (dls_header_info(dsp->ds_dc, mp, &mhi) != 0)
goto discard;
+ mac_sdu_get(dsp->ds_mh, NULL, &max_sdu);
/*
* If LSO is enabled, check the size against lso_max. Otherwise,
- * compare the packet size with sdu_max.
+ * compare the packet size with max_sdu.
*/
- if (size > (dsp->ds_lso ? dsp->ds_lso_max : dsp->ds_mip->mi_sdu_max)
- + mhi.mhi_hdrsize)
+ max_sdu = dsp->ds_lso ? dsp->ds_lso_max : max_sdu;
+ if (size > max_sdu + mhi.mhi_hdrsize)
goto discard;
if (is_ethernet) {
@@ -1473,6 +1475,31 @@ dld_str_rx_unitdata(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
}
/*
+ * DL_NOTIFY_IND: DL_NOTE_SDU_SIZE
+ */
+static void
+str_notify_sdu_size(dld_str_t *dsp, uint_t max_sdu)
+{
+ mblk_t *mp;
+ dl_notify_ind_t *dlip;
+
+ if (!(dsp->ds_notifications & DL_NOTE_SDU_SIZE))
+ return;
+
+ if ((mp = mexchange(dsp->ds_wq, NULL, sizeof (dl_notify_ind_t),
+ M_PROTO, 0)) == NULL)
+ return;
+
+ bzero(mp->b_rptr, sizeof (dl_notify_ind_t));
+ dlip = (dl_notify_ind_t *)mp->b_rptr;
+ dlip->dl_primitive = DL_NOTIFY_IND;
+ dlip->dl_notification = DL_NOTE_SDU_SIZE;
+ dlip->dl_data = max_sdu;
+
+ qreply(dsp->ds_wq, mp);
+}
+
+/*
* Generate DL_NOTIFY_IND messages to notify the DLPI consumer of the
* current state of the interface.
*/
@@ -1857,12 +1884,20 @@ str_notify(void *arg, mac_notify_type_t type)
str_notify_capab_reneg(dsp);
break;
+ case MAC_NOTE_SDU_SIZE: {
+ uint_t max_sdu;
+ mac_sdu_get(dsp->ds_mh, NULL, &max_sdu);
+ str_notify_sdu_size(dsp, max_sdu);
+ break;
+ }
+
case MAC_NOTE_FASTPATH_FLUSH:
str_notify_fastpath_flush(dsp);
break;
case MAC_NOTE_MARGIN:
break;
+
default:
ASSERT(B_FALSE);
break;
diff --git a/usr/src/uts/common/io/gld.c b/usr/src/uts/common/io/gld.c
index d14b0eff00..0aa1ae890a 100644
--- a/usr/src/uts/common/io/gld.c
+++ b/usr/src/uts/common/io/gld.c
@@ -204,7 +204,7 @@ extern void gld_sr_dump(gld_mac_info_t *);
* Allocate and zero-out "number" structures each of type "structure" in
* kernel memory.
*/
-#define GETSTRUCT(structure, number) \
+#define GLD_GETSTRUCT(structure, number) \
(kmem_zalloc((uint_t)(sizeof (structure) * (number)), KM_NOSLEEP))
#define abs(a) ((a) < 0 ? -(a) : a)
@@ -574,7 +574,7 @@ gld_register(dev_info_t *devinfo, char *devname, gld_mac_info_t *macinfo)
*/
if (glddev == NULL) {
/* first occurrence of this device name (major number) */
- glddev = GETSTRUCT(glddev_t, 1);
+ glddev = GLD_GETSTRUCT(glddev_t, 1);
if (glddev == NULL) {
mutex_exit(&gld_device_list.gld_devlock);
return (DDI_FAILURE);
@@ -584,9 +584,9 @@ gld_register(dev_info_t *devinfo, char *devname, gld_mac_info_t *macinfo)
glddev->gld_major = major;
glddev->gld_nextminor = GLD_MIN_CLONE_MINOR;
glddev->gld_mac_next = glddev->gld_mac_prev =
- (gld_mac_info_t *)&glddev->gld_mac_next;
+ (gld_mac_info_t *)&glddev->gld_mac_next;
glddev->gld_str_next = glddev->gld_str_prev =
- (gld_t *)&glddev->gld_str_next;
+ (gld_t *)&glddev->gld_str_next;
mutex_init(&glddev->gld_devlock, NULL, MUTEX_DRIVER, NULL);
/* allow increase of number of supported multicast addrs */
@@ -806,9 +806,9 @@ late_failure:
ddi_remove_minor_node(devinfo, NULL);
GLDM_LOCK_DESTROY(macinfo);
if (mac_pvt->curr_macaddr != NULL)
- kmem_free(mac_pvt->curr_macaddr, macinfo->gldm_addrlen);
+ kmem_free(mac_pvt->curr_macaddr, macinfo->gldm_addrlen);
if (mac_pvt->statistics != NULL)
- kmem_free(mac_pvt->statistics, sizeof (struct gld_stats));
+ kmem_free(mac_pvt->statistics, sizeof (struct gld_stats));
kmem_free(macinfo->gldm_mac_pvt, sizeof (gld_mac_pvt_t));
macinfo->gldm_mac_pvt = NULL;
@@ -3243,13 +3243,13 @@ gld_addudind(gld_t *gld, mblk_t *mp, pktinfo_t *pktinfo, boolean_t tagged)
dludindp->dl_primitive = DL_UNITDATA_IND;
dludindp->dl_src_addr_length =
dludindp->dl_dest_addr_length = macinfo->gldm_addrlen +
- abs(macinfo->gldm_saplen);
+ abs(macinfo->gldm_saplen);
dludindp->dl_dest_addr_offset = sizeof (dl_unitdata_ind_t);
dludindp->dl_src_addr_offset = dludindp->dl_dest_addr_offset +
- dludindp->dl_dest_addr_length;
+ dludindp->dl_dest_addr_length;
dludindp->dl_group_address = (pktinfo->isMulticast ||
- pktinfo->isBroadcast);
+ pktinfo->isBroadcast);
nmp->b_wptr = nmp->b_rptr + dludindp->dl_dest_addr_offset;
@@ -4001,14 +4001,14 @@ gld_notify_req(queue_t *q, mblk_t *mp)
#ifdef GLD_DEBUG
if (gld_debug & GLDTRACE)
cmn_err(CE_NOTE, "gld_notify_req(%p %p)",
- (void *)q, (void *)mp);
+ (void *)q, (void *)mp);
#endif
if (gld->gld_state == DL_UNATTACHED) {
#ifdef GLD_DEBUG
if (gld_debug & GLDERRS)
cmn_err(CE_NOTE, "gld_notify_req: wrong state (%d)",
- gld->gld_state);
+ gld->gld_state);
#endif
return (DL_OUTSTATE);
}
@@ -4205,7 +4205,7 @@ gld_bind(queue_t *q, mblk_t *mp)
#ifdef GLD_DEBUG
if (gld_debug & GLDERRS)
cmn_err(CE_NOTE, "gld_bind: bound or not attached (%d)",
- gld->gld_state);
+ gld->gld_state);
#endif
return (DL_OUTSTATE);
}
@@ -4285,7 +4285,7 @@ gld_unbind(queue_t *q, mblk_t *mp)
#ifdef GLD_DEBUG
if (gld_debug & GLDERRS)
cmn_err(CE_NOTE, "gld_unbind: wrong state (%d)",
- gld->gld_state);
+ gld->gld_state);
#endif
return (DL_OUTSTATE);
}
@@ -4516,7 +4516,7 @@ gld_unitdata(queue_t *q, mblk_t *mp)
#ifdef GLD_DEBUG
if (gld_debug & GLDERRS)
cmn_err(CE_NOTE, "gld_unitdata: wrong state (%d)",
- gld->gld_state);
+ gld->gld_state);
#endif
dluderrorind(q, mp, mp->b_rptr + dlp->dl_dest_addr_offset,
dlp->dl_dest_addr_length, DL_OUTSTATE, 0);
@@ -4539,7 +4539,7 @@ gld_unitdata(queue_t *q, mblk_t *mp)
#ifdef GLD_DEBUG
if (gld_debug & GLDERRS)
cmn_err(CE_NOTE, "gld_unitdata: bad msglen (%d)",
- (int)msglen);
+ (int)msglen);
#endif
dluderrorind(q, mp, mp->b_rptr + dlp->dl_dest_addr_offset,
dlp->dl_dest_addr_length, DL_BADDATA, 0);
@@ -4886,8 +4886,8 @@ gld_enable_multi(queue_t *q, mblk_t *mp)
/* does this address appear in current table? */
if (gld->gld_mcast == NULL) {
/* no mcast addresses -- allocate table */
- gld->gld_mcast = GETSTRUCT(gld_mcast_t *,
- glddev->gld_multisize);
+ gld->gld_mcast = GLD_GETSTRUCT(gld_mcast_t *,
+ glddev->gld_multisize);
if (gld->gld_mcast == NULL) {
GLDM_UNLOCK(macinfo);
dlerrorack(q, mp, DL_ENABMULTI_REQ, DL_SYSERR, ENOSR);
@@ -4898,7 +4898,7 @@ gld_enable_multi(queue_t *q, mblk_t *mp)
for (i = 0; i < gld->gld_multicnt; i++) {
if (gld->gld_mcast[i] &&
mac_eq(gld->gld_mcast[i]->gldm_addr,
- maddr, macinfo->gldm_addrlen)) {
+ maddr, macinfo->gldm_addrlen)) {
/* this is a match -- just succeed */
ASSERT(gld->gld_mcast[i]->gldm_refcnt);
GLDM_UNLOCK(macinfo);
@@ -4913,8 +4913,8 @@ gld_enable_multi(queue_t *q, mblk_t *mp)
*/
mcast = NULL;
if (mac_pvt->mcast_table == NULL) {
- mac_pvt->mcast_table = GETSTRUCT(gld_mcast_t,
- glddev->gld_multisize);
+ mac_pvt->mcast_table = GLD_GETSTRUCT(gld_mcast_t,
+ glddev->gld_multisize);
if (mac_pvt->mcast_table == NULL) {
GLDM_UNLOCK(macinfo);
dlerrorack(q, mp, DL_ENABMULTI_REQ, DL_SYSERR, ENOSR);
@@ -5685,7 +5685,7 @@ nextminor:
;
}
cmn_err(CE_WARN, "GLD ran out of minor numbers for %s",
- device->gld_name);
+ device->gld_name);
return (0);
}
diff --git a/usr/src/uts/common/io/ipw/ipw2100.c b/usr/src/uts/common/io/ipw/ipw2100.c
index 34fcc32a6e..10e5c7f65c 100644
--- a/usr/src/uts/common/io/ipw/ipw2100.c
+++ b/usr/src/uts/common/io/ipw/ipw2100.c
@@ -51,6 +51,7 @@
#include <sys/devops.h>
#include <sys/dlpi.h>
#include <sys/mac.h>
+#include <net/if.h>
#include <sys/mac_wifi.h>
#include <sys/varargs.h>
#include <sys/policy.h>
diff --git a/usr/src/uts/common/io/ipw/ipw2100_impl.h b/usr/src/uts/common/io/ipw/ipw2100_impl.h
index b0800d8e80..269ed55eb5 100644
--- a/usr/src/uts/common/io/ipw/ipw2100_impl.h
+++ b/usr/src/uts/common/io/ipw/ipw2100_impl.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -166,12 +166,7 @@ struct ipw2100_softc {
kcondvar_t sc_scan_cv; /* used for active scan */
kthread_t *sc_mf_thread;
uint32_t sc_mfthread_switch; /* 0/1 indicate off/on */
-
int if_flags;
-#define IFF_DEBUG (0x0004)
-#define IFF_PROMISC (0x0100)
-#define IFF_SIMPLEX (0x0800)
-
};
/*
diff --git a/usr/src/uts/common/io/mac/mac.c b/usr/src/uts/common/io/mac/mac.c
index d12bfdf021..3bc71547de 100644
--- a/usr/src/uts/common/io/mac/mac.c
+++ b/usr/src/uts/common/io/mac/mac.c
@@ -53,6 +53,7 @@
#include <sys/cpuvar.h>
#include <sys/atomic.h>
#include <sys/sdt.h>
+#include <inet/nd.h>
#define IMPL_HASHSZ 67 /* prime */
@@ -1004,6 +1005,17 @@ mac_promisc_get(mac_handle_t mh, mac_promisc_type_t ptype)
}
void
+mac_sdu_get(mac_handle_t mh, uint_t *min_sdu, uint_t *max_sdu)
+{
+ mac_impl_t *mip = (mac_impl_t *)mh;
+
+ if (min_sdu != NULL)
+ *min_sdu = mip->mi_sdu_min;
+ if (max_sdu != NULL)
+ *max_sdu = mip->mi_sdu_max;
+}
+
+void
mac_resources(mac_handle_t mh)
{
mac_impl_t *mip = (mac_impl_t *)mh;
@@ -1020,7 +1032,20 @@ void
mac_ioctl(mac_handle_t mh, queue_t *wq, mblk_t *bp)
{
mac_impl_t *mip = (mac_impl_t *)mh;
+ int cmd;
+ if (mip->mi_callbacks->mc_callbacks & (MC_SETPROP|MC_GETPROP)) {
+ cmd = ((struct iocblk *)bp->b_rptr)->ioc_cmd;
+ if (cmd == ND_SET || cmd == ND_GET) {
+ /*
+ * ndd ioctls are Obsolete
+ */
+ cmn_err(CE_WARN,
+ "The ndd commands are obsolete and may be removed "
+ "in a future release of Solaris. "
+ "Use dladm(1M) to manage driver tunables\n");
+ }
+ }
/*
* Call the driver to handle the ioctl. The driver may not support
* any ioctls, in which case we reply with a NAK on its behalf.
@@ -1511,10 +1536,10 @@ mac_register(mac_register_t *mregp, mac_handle_t *mhp)
mip->mi_margin = mregp->m_margin;
mip->mi_info.mi_media = mtype->mt_type;
mip->mi_info.mi_nativemedia = mtype->mt_nativetype;
- mip->mi_info.mi_sdu_min = mregp->m_min_sdu;
if (mregp->m_max_sdu <= mregp->m_min_sdu)
goto fail;
- mip->mi_info.mi_sdu_max = mregp->m_max_sdu;
+ mip->mi_sdu_min = mregp->m_min_sdu;
+ mip->mi_sdu_max = mregp->m_max_sdu;
mip->mi_info.mi_addr_length = mip->mi_type->mt_addr_length;
/*
* If the media supports a broadcast address, cache a pointer to it
@@ -1667,6 +1692,9 @@ mac_register(mac_register_t *mregp, mac_handle_t *mhp)
goto fail;
}
+ DTRACE_PROBE2(mac__register, struct devnames *, dnp,
+ (mac_impl_t *), mip);
+
/*
* Mark the MAC to be ready for open.
*/
@@ -2817,3 +2845,43 @@ done:
mutex_exit(&i_mactype_lock);
return (err);
}
+
+int
+mac_set_prop(mac_handle_t mh, mac_prop_t *macprop, void *val, uint_t valsize)
+{
+ int err = ENOTSUP;
+ mac_impl_t *mip = (mac_impl_t *)mh;
+
+ if (mip->mi_callbacks->mc_callbacks & MC_SETPROP) {
+ err = mip->mi_callbacks->mc_setprop(mip->mi_driver,
+ macprop->mp_name, macprop->mp_id, valsize, val);
+ }
+ return (err);
+}
+
+int
+mac_get_prop(mac_handle_t mh, mac_prop_t *macprop, void *val, uint_t valsize)
+{
+ int err = ENOTSUP;
+ mac_impl_t *mip = (mac_impl_t *)mh;
+
+ if (mip->mi_callbacks->mc_callbacks & MC_GETPROP) {
+ err = mip->mi_callbacks->mc_getprop(mip->mi_driver,
+ macprop->mp_name, macprop->mp_id, valsize, val);
+ }
+ return (err);
+}
+
+int
+mac_maxsdu_update(mac_handle_t mh, uint_t sdu_max)
+{
+ mac_impl_t *mip = (mac_impl_t *)mh;
+
+ if (sdu_max <= mip->mi_sdu_min)
+ return (EINVAL);
+ mip->mi_sdu_max = sdu_max;
+
+ /* Send a MAC_NOTE_SDU_SIZE notification. */
+ i_mac_notify(mip, MAC_NOTE_SDU_SIZE);
+ return (0);
+}
diff --git a/usr/src/uts/common/io/nge/nge_kstats.c b/usr/src/uts/common/io/nge/nge_kstats.c
index 66350d6125..28069a836b 100644
--- a/usr/src/uts/common/io/nge/nge_kstats.c
+++ b/usr/src/uts/common/io/nge/nge_kstats.c
@@ -243,31 +243,6 @@ nge_setup_named_kstat(nge_t *ngep, int instance, char *name,
return (ksp);
}
-/*
- * Create kstats corresponding to NDD parameters
- */
-static kstat_t *
-nge_setup_params_kstat(nge_t *ngep, int instance, char *name,
- int (*update)(kstat_t *, int))
-{
- kstat_t *ksp;
- kstat_named_t *knp;
- int i;
-
- ksp = kstat_create(NGE_DRIVER_NAME, instance, name, "net",
- KSTAT_TYPE_NAMED, PARAM_COUNT, KSTAT_FLAG_PERSISTENT);
- if (ksp != NULL) {
- ksp->ks_private = ngep;
- ksp->ks_update = update;
- for (knp = ksp->ks_data, i = 0; i < PARAM_COUNT; ++knp, ++i)
- kstat_named_init(knp, ngep->nd_params[i].ndp_name+1,
- KSTAT_DATA_UINT64);
- kstat_install(ksp);
- }
-
- return (ksp);
-}
-
void
nge_init_kstats(nge_t *ngep, int instance)
{
diff --git a/usr/src/uts/common/io/strplumb.c b/usr/src/uts/common/io/strplumb.c
index 6f20d98a5a..4eaf8e20ac 100644
--- a/usr/src/uts/common/io/strplumb.c
+++ b/usr/src/uts/common/io/strplumb.c
@@ -71,6 +71,7 @@
#include <sys/ddi_implfuncs.h>
#include <sys/dld.h>
+#include <sys/mac.h>
/*
* Debug Macros
diff --git a/usr/src/uts/common/io/vnic/vnic_dev.c b/usr/src/uts/common/io/vnic/vnic_dev.c
index 676bcc1e6f..7d98003a17 100644
--- a/usr/src/uts/common/io/vnic/vnic_dev.c
+++ b/usr/src/uts/common/io/vnic/vnic_dev.c
@@ -729,7 +729,6 @@ vnic_dev_create(datalink_id_t vnic_id, datalink_id_t linkid, int mac_len,
mac_register_t *mac;
int err;
vnic_mac_t *vnic_mac;
- const mac_info_t *lower_mac_info;
mac_multi_addr_t maddr;
mac_txinfo_t tx_info;
@@ -796,9 +795,7 @@ vnic_dev_create(datalink_id_t vnic_id, datalink_id_t linkid, int mac_len,
mac->m_src_addr = vnic->vn_addr;
mac->m_callbacks = &vnic_m_callbacks;
- lower_mac_info = mac_info(vnic_mac->va_mh);
- mac->m_min_sdu = lower_mac_info->mi_sdu_min;
- mac->m_max_sdu = lower_mac_info->mi_sdu_max;
+ mac_sdu_get(vnic_mac->va_mh, &mac->m_min_sdu, &mac->m_max_sdu);
/*
* As the current margin size of the underlying mac is used to
diff --git a/usr/src/uts/common/sys/dld.h b/usr/src/uts/common/sys/dld.h
index 8cc70e52f9..ad3530c1a3 100644
--- a/usr/src/uts/common/sys/dld.h
+++ b/usr/src/uts/common/sys/dld.h
@@ -34,11 +34,11 @@
#include <sys/types.h>
#include <sys/stream.h>
-#include <sys/mac.h>
-#include <sys/dls.h>
#include <sys/conf.h>
#include <sys/sad.h>
#include <net/if.h>
+#include <sys/ddi.h>
+#include <sys/sunddi.h>
#ifdef __cplusplus
extern "C" {
@@ -94,6 +94,8 @@ extern "C" {
#define DLDIOC_ATTR (DLDIOC | 0x03)
+typedef uint32_t datalink_id_t;
+
typedef struct dld_ioc_attr {
datalink_id_t dia_linkid;
uint_t dia_max_sdu;
@@ -109,6 +111,8 @@ typedef struct dld_ioc_vlan_attr {
} dld_ioc_vlan_attr_t;
#define DLDIOC_PHYS_ATTR (DLDIOC | 0x05)
+#define DLPI_LINKNAME_MAX 32
+
typedef struct dld_ioc_phys_attr {
datalink_id_t dip_linkid;
/*
@@ -223,7 +227,63 @@ struct dlautopush {
char dap_aplist[MAXAPUSH][FMNAMESZ+1];
};
+/*
+ * Encodings for public properties.
+ * A most significant bit value of 1 indicates private property, intended
+ * to allow private property implementations to use internal encodings
+ * if desired.
+ *
+ * Note that there are 2 sets of parameters: the *_EN_*
+ * values are those that the Administrator configures for autonegotiation.
+ * The _ADV_* values are those that are currently exposed over the wire.
+ */
+typedef enum {
+ DLD_PROP_DUPLEX = 0x00000001,
+ DLD_PROP_SPEED,
+ DLD_PROP_STATUS,
+ DLD_PROP_AUTONEG,
+ DLD_PROP_EN_AUTONEG,
+ DLD_PROP_DEFMTU,
+ DLD_PROP_NDD_LEGACY,
+ DLD_PROP_FLOWCTRL,
+ DLD_PROP_ADV_1000FDX_CAP,
+ DLD_PROP_EN_1000FDX_CAP,
+ DLD_PROP_ADV_1000HDX_CAP,
+ DLD_PROP_EN_1000HDX_CAP,
+ DLD_PROP_ADV_100FDX_CAP,
+ DLD_PROP_EN_100FDX_CAP,
+ DLD_PROP_ADV_100HDX_CAP,
+ DLD_PROP_EN_100HDX_CAP,
+ DLD_PROP_ADV_10FDX_CAP,
+ DLD_PROP_EN_10FDX_CAP,
+ DLD_PROP_ADV_10HDX_CAP,
+ DLD_PROP_EN_10HDX_CAP,
+ DLD_PROP_PRIVATE = -1
+} dld_prop_id_t;
+
+/*
+ * to figure out r/w status of legacy ndd props.
+ */
+#define DLD_NDD_READ 0x01
+#define DLD_NDD_WRITE 0x10
+
+#define DLDIOCSETPROP (DLDIOC | 0x14)
+#define DLDIOCGETPROP (DLDIOC | 0x15)
+#define DLD_LINKPROP_NAME_MAX 256
+#define DLD_PROP_VERSION 1
+
+typedef struct dld_ioc_prop_s {
+ int pr_version;
+ uint_t pr_flags; /* private to libdladm */
+ char pr_linkname[DLPI_LINKNAME_MAX]; /* interface name */
+ dld_prop_id_t pr_num;
+ char pr_name[DLD_LINKPROP_NAME_MAX];
+ uint_t pr_valsize; /* sizeof pr_val */
+ char pr_val[1];
+} dld_ioc_prop_t;
+
#ifdef _KERNEL
+typedef dld_prop_id_t mac_prop_id_t;
int dld_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
int dld_open(queue_t *, dev_t *, int, int, cred_t *);
int dld_close(queue_t *);
diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h
index 4fd83059c4..b83f5cb981 100644
--- a/usr/src/uts/common/sys/mac.h
+++ b/usr/src/uts/common/sys/mac.h
@@ -32,6 +32,7 @@
#include <sys/ddi.h>
#include <sys/sunddi.h>
#include <sys/stream.h>
+#include <sys/dld.h>
/*
* MAC Services Module
@@ -84,11 +85,17 @@ typedef enum {
LINK_DUPLEX_FULL
} link_duplex_t;
-typedef uint32_t datalink_id_t;
#define DATALINK_INVALID_LINKID 0
#define DATALINK_ALL_LINKID 0
#define DATALINK_MAX_LINKID 0xffffffff
+typedef enum {
+ LINK_FLOWCTRL_NONE = 0,
+ LINK_FLOWCTRL_RX,
+ LINK_FLOWCTRL_TX,
+ LINK_FLOWCTRL_BI
+} link_flowctrl_t;
+
/*
* Maximum MAC address length
*/
@@ -177,8 +184,6 @@ enum mac_driver_stat {
typedef struct mac_info_s {
uint_t mi_media;
uint_t mi_nativemedia;
- uint_t mi_sdu_min;
- uint_t mi_sdu_max;
uint_t mi_addr_length;
uint8_t *mi_unicst_addr;
uint8_t *mi_brdcst_addr;
@@ -292,6 +297,10 @@ typedef mblk_t *(*mac_tx_t)(void *, mblk_t *);
typedef boolean_t (*mac_getcapab_t)(void *, mac_capab_t, void *);
typedef int (*mac_open_t)(void *);
typedef void (*mac_close_t)(void *);
+typedef int (*mac_set_prop_t)(void *, const char *, mac_prop_id_t,
+ uint_t, const void *);
+typedef int (*mac_get_prop_t)(void *, const char *, mac_prop_id_t,
+ uint_t, void *);
/*
* Drivers must set all of these callbacks except for mc_resources,
@@ -315,6 +324,8 @@ typedef struct mac_callbacks_s {
mac_getcapab_t mc_getcapab; /* Get capability information */
mac_open_t mc_open; /* Open the device */
mac_close_t mc_close; /* Close the device */
+ mac_set_prop_t mc_setprop;
+ mac_get_prop_t mc_getprop;
} mac_callbacks_t;
/*
@@ -328,6 +339,8 @@ typedef struct mac_callbacks_s {
#define MC_GETCAPAB 0x004
#define MC_OPEN 0x008
#define MC_CLOSE 0x010
+#define MC_SETPROP 0x020
+#define MC_GETPROP 0x040
#define MAC_MAX_MINOR 1000
@@ -367,6 +380,7 @@ typedef enum {
MAC_NOTE_RESOURCE,
MAC_NOTE_DEVPROMISC,
MAC_NOTE_FASTPATH_FLUSH,
+ MAC_NOTE_SDU_SIZE,
MAC_NOTE_VNIC,
MAC_NOTE_MARGIN,
MAC_NNOTE /* must be the last entry */
@@ -534,6 +548,11 @@ typedef struct mactype_register_s {
size_t mtr_statcount;
} mactype_register_t;
+typedef struct mac_prop_s {
+ mac_prop_id_t mp_id;
+ char *mp_name;
+} mac_prop_t;
+
/*
* Client interface functions.
*/
@@ -560,6 +579,7 @@ extern boolean_t mac_unicst_verify(mac_handle_t,
extern int mac_unicst_set(mac_handle_t, const uint8_t *);
extern void mac_unicst_get(mac_handle_t, uint8_t *);
extern void mac_dest_get(mac_handle_t, uint8_t *);
+extern void mac_sdu_get(mac_handle_t, uint_t *, uint_t *);
extern void mac_resources(mac_handle_t);
extern void mac_ioctl(mac_handle_t, queue_t *, mblk_t *);
extern const mac_txinfo_t *mac_tx_get(mac_handle_t);
@@ -626,6 +646,7 @@ extern void mac_tx_update(mac_handle_t);
extern void mac_resource_update(mac_handle_t);
extern mac_resource_handle_t mac_resource_add(mac_handle_t,
mac_resource_t *);
+extern int mac_maxsdu_update(mac_handle_t, uint_t);
extern int mac_pdata_update(mac_handle_t, void *,
size_t);
extern void mac_multicst_refresh(mac_handle_t,
@@ -650,6 +671,10 @@ extern mactype_register_t *mactype_alloc(uint_t);
extern void mactype_free(mactype_register_t *);
extern int mactype_register(mactype_register_t *);
extern int mactype_unregister(const char *);
+extern int mac_set_prop(mac_handle_t, mac_prop_t *,
+ void *, uint_t);
+extern int mac_get_prop(mac_handle_t, mac_prop_t *,
+ void *, uint_t);
#endif /* _KERNEL */
diff --git a/usr/src/uts/common/sys/mac_impl.h b/usr/src/uts/common/sys/mac_impl.h
index c0acfc5c37..6e39232224 100644
--- a/usr/src/uts/common/sys/mac_impl.h
+++ b/usr/src/uts/common/sys/mac_impl.h
@@ -152,6 +152,8 @@ typedef struct mac_impl_s {
uint_t mi_devpromisc;
uint8_t mi_addr[MAXMACADDRLEN];
uint8_t mi_dstaddr[MAXMACADDRLEN];
+ uint_t mi_sdu_min;
+ uint_t mi_sdu_max;
mac_multicst_addr_t *mi_mmap;
krwlock_t mi_notify_lock;
diff --git a/usr/src/uts/common/xen/io/xnbo.c b/usr/src/uts/common/xen/io/xnbo.c
index 91714e9117..833cf96576 100644
--- a/usr/src/uts/common/xen/io/xnbo.c
+++ b/usr/src/uts/common/xen/io/xnbo.c
@@ -245,6 +245,7 @@ xnbo_open_mac(xnb_t *xnbp, char *mac)
const mac_info_t *mi;
char *xsname;
void (*rx_fn)(void *, mac_resource_handle_t, mblk_t *);
+ uint_t max_sdu;
xsname = xvdi_get_xsname(xnbp->xnb_devinfo);
@@ -271,9 +272,11 @@ xnbo_open_mac(xnb_t *xnbp, char *mac)
xnbo_close_mac(xnbop);
return (B_FALSE);
}
- if (mi->mi_sdu_max > XNBMAXPKT) {
- cmn_err(CE_WARN, "xnbo_open_mac: "
- "mac device SDU too big (%d)", mi->mi_sdu_max);
+
+ mac_sdu_get(xnbop->o_mh, NULL, &max_sdu);
+ if (max_sdu > XNBMAXPKT) {
+ cmn_err(CE_WARN, "xnbo_open_mac: mac device SDU too big (%d)",
+ max_sdu);
xnbo_close_mac(xnbop);
return (B_FALSE);
}
diff --git a/usr/src/uts/intel/mac/Makefile b/usr/src/uts/intel/mac/Makefile
index 8e34b910a9..12bd648ee0 100644
--- a/usr/src/uts/intel/mac/Makefile
+++ b/usr/src/uts/intel/mac/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -54,6 +53,7 @@ include $(UTSBASE)/intel/Makefile.intel
ALL_TARGET = $(BINARY)
LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
+LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
#
# Overrides.
diff --git a/usr/src/uts/sparc/mac/Makefile b/usr/src/uts/sparc/mac/Makefile
index ecf5b2cfa2..d343e0bc74 100644
--- a/usr/src/uts/sparc/mac/Makefile
+++ b/usr/src/uts/sparc/mac/Makefile
@@ -2,9 +2,8 @@
# CDDL HEADER START
#
# The contents of this file are subject to the terms of the
-# Common Development and Distribution License, Version 1.0 only
-# (the "License"). You may not use this file except in compliance
-# with the License.
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
#
# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
# or http://www.opensolaris.org/os/licensing.
@@ -20,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
#ident "%Z%%M% %I% %E% SMI"
@@ -55,6 +54,7 @@ include $(UTSBASE)/sparc/Makefile.sparc
ALL_TARGET = $(BINARY)
LINT_TARGET = $(MODULE).lint
INSTALL_TARGET = $(BINARY) $(ROOTMODULE)
+LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN
#
# Overrides.
diff --git a/usr/src/uts/sun/io/hme.c b/usr/src/uts/sun/io/hme.c
index f57bcd697b..b5d91a728a 100644
--- a/usr/src/uts/sun/io/hme.c
+++ b/usr/src/uts/sun/io/hme.c
@@ -2341,7 +2341,7 @@ _info(struct modinfo *modinfop)
* Allocate and zero-out "number" structures
* each of type "structure" in kernel memory.
*/
-#define GETSTRUCT(structure, number) \
+#define HME_GETSTRUCT(structure, number) \
((structure *)kmem_zalloc(\
(size_t)(sizeof (structure) * (number)), KM_SLEEP))
@@ -2763,7 +2763,7 @@ hmeattach(dev_info_t *dip, ddi_attach_cmd_t cmd)
/*
* Allocate soft device data structure
*/
- hmep = GETSTRUCT(struct hme, 1);
+ hmep = HME_GETSTRUCT(struct hme, 1);
/*
* Might as well set up elements of data structure