summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/strplumb.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/strplumb.c')
-rw-r--r--usr/src/uts/common/io/strplumb.c275
1 files changed, 14 insertions, 261 deletions
diff --git a/usr/src/uts/common/io/strplumb.c b/usr/src/uts/common/io/strplumb.c
index 644d83c352..6f20d98a5a 100644
--- a/usr/src/uts/common/io/strplumb.c
+++ b/usr/src/uts/common/io/strplumb.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -626,12 +626,8 @@ done:
static uchar_t boot_macaddr[16];
static int boot_maclen;
-static uchar_t *getmacaddr(dev_info_t *dip, int *maclen);
+static uchar_t *getmacaddr(dev_info_t *dip, size_t *maclenp);
static int matchmac(dev_info_t *dip, void *arg);
-int dl_attach(ldi_handle_t lh, int unit);
-int dl_bind(ldi_handle_t lh, uint_t sap, uint_t max_conn,
- uint_t service, uint_t conn_mgmt);
-int dl_phys_addr(ldi_handle_t lh, struct ether_addr *eaddr);
#endif /* !_OBP */
@@ -705,7 +701,7 @@ matchmac(dev_info_t *dip, void *arg)
char **devpathp = (char **)arg;
char *model_str;
uchar_t *macaddr;
- int maclen;
+ size_t maclen;
/* XXX Should use "device-type" per IEEE 1275 */
if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
@@ -750,40 +746,15 @@ matchmac(dev_info_t *dip, void *arg)
}
static uchar_t *
-getmacaddr_gldv3(char *drv, int inst, int *maclenp)
-{
- char ifname[16];
- mac_handle_t mh;
- uchar_t *macaddr;
-
- (void) snprintf(ifname, sizeof (ifname), "%s%d", drv, inst);
- if (mac_open(ifname, &mh) < 0) {
- return (NULL);
- }
- *maclenp = sizeof (struct ether_addr);
- macaddr = kmem_alloc(*maclenp, KM_SLEEP);
- mac_unicst_get(mh, macaddr);
- mac_close(mh);
-
- return (macaddr);
-}
-
-static uchar_t *
-getmacaddr(dev_info_t *dip, int *maclenp)
+getmacaddr(dev_info_t *dip, size_t *maclenp)
{
int rc, ppa;
ldi_ident_t li;
ldi_handle_t lh;
- char *drv_name = (char *)ddi_driver_name(dip);
+ const char *drv_name = ddi_driver_name(dip);
char *clonepath;
uchar_t *macaddr = NULL;
- /* a simpler way to get mac address for GLDv3 drivers */
- if (GLDV3_DRV(ddi_name_to_major(drv_name))) {
- return (getmacaddr_gldv3(drv_name, ddi_get_instance(dip),
- maclenp));
- }
-
if (rc = ldi_ident_from_mod(&modlinkage, &li)) {
cmn_err(CE_WARN,
"getmacaddr: ldi_ident_from_mod failed: %d\n", rc);
@@ -806,245 +777,27 @@ getmacaddr(dev_info_t *dip, int *maclenp)
kmem_free(clonepath, MAXPATHLEN);
ppa = i_ddi_devi_get_ppa(dip);
- if ((dl_attach(lh, ppa) != 0) ||
- (dl_bind(lh, ETHERTYPE_IP, 0, DL_CLDLS, 0) != 0)) {
+ if ((dl_attach(lh, ppa, NULL) != 0) ||
+ (dl_bind(lh, ETHERTYPE_IP, NULL) != 0)) {
(void) ldi_close(lh, FREAD|FWRITE, CRED());
cmn_err(CE_WARN,
"getmacaddr: dl_attach/bind(%s%d) failed: %d\n",
drv_name, ppa, rc);
return (NULL);
}
- *maclenp = sizeof (struct ether_addr);
- macaddr = kmem_alloc(*maclenp, KM_SLEEP);
- if (dl_phys_addr(lh, (struct ether_addr *)macaddr) != 0) {
- kmem_free(macaddr, *maclenp);
+
+ *maclenp = ETHERADDRL;
+ macaddr = kmem_alloc(ETHERADDRL, KM_SLEEP);
+ if (dl_phys_addr(lh, macaddr, maclenp, NULL) != 0 ||
+ *maclenp != ETHERADDRL) {
+ kmem_free(macaddr, ETHERADDRL);
macaddr = NULL;
*maclenp = 0;
cmn_err(CE_WARN,
- "getmacaddr: dl_macaddr(%s%d) failed: %d\n",
+ "getmacaddr: dl_phys_addr(%s%d) failed: %d\n",
drv_name, ppa, rc);
}
(void) ldi_close(lh, FREAD|FWRITE, CRED());
return (macaddr);
}
-
#endif /* !_OBP */
-
-int
-dl_attach(ldi_handle_t lh, int unit)
-{
- dl_attach_req_t *attach_req;
- union DL_primitives *dl_prim;
- mblk_t *mp;
- int error;
-
- if ((mp = allocb(sizeof (dl_attach_req_t), BPRI_MED)) == NULL) {
- cmn_err(CE_WARN, "dl_attach: allocb failed");
- return (ENOSR);
- }
- mp->b_datap->db_type = M_PROTO;
- mp->b_wptr += sizeof (dl_attach_req_t);
-
- attach_req = (dl_attach_req_t *)mp->b_rptr;
- attach_req->dl_primitive = DL_ATTACH_REQ;
- attach_req->dl_ppa = unit;
-
- (void) ldi_putmsg(lh, mp);
- if ((error = ldi_getmsg(lh, &mp, (timestruc_t *)NULL)) != 0) {
- cmn_err(CE_NOTE, "!dl_attach: ldi_getmsg failed: %d", error);
- return (error);
- }
-
- dl_prim = (union DL_primitives *)mp->b_rptr;
- switch (dl_prim->dl_primitive) {
- case DL_OK_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_ok_ack_t)) {
- cmn_err(CE_NOTE,
- "!dl_attach: DL_OK_ACK protocol error");
- break;
- }
- if (((dl_ok_ack_t *)dl_prim)->dl_correct_primitive !=
- DL_ATTACH_REQ) {
- cmn_err(CE_NOTE, "!dl_attach: DL_OK_ACK rtnd prim %u",
- ((dl_ok_ack_t *)dl_prim)->dl_correct_primitive);
- break;
- }
- freemsg(mp);
- return (0);
-
- case DL_ERROR_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) {
- cmn_err(CE_NOTE,
- "!dl_attach: DL_ERROR_ACK protocol error");
- break;
- }
- break;
-
- default:
- cmn_err(CE_NOTE, "!dl_attach: bad ACK header %u",
- dl_prim->dl_primitive);
- break;
- }
-
- /*
- * Error return only.
- */
- freemsg(mp);
- return (-1);
-}
-
-int
-dl_bind(ldi_handle_t lh, uint_t sap, uint_t max_conn, uint_t service,
- uint_t conn_mgmt)
-{
- dl_bind_req_t *bind_req;
- union DL_primitives *dl_prim;
- mblk_t *mp;
- int error;
-
- if ((mp = allocb(sizeof (dl_bind_req_t), BPRI_MED)) == NULL) {
- cmn_err(CE_WARN, "dl_bind: allocb failed");
- return (ENOSR);
- }
- mp->b_datap->db_type = M_PROTO;
-
- bind_req = (dl_bind_req_t *)mp->b_wptr;
- mp->b_wptr += sizeof (dl_bind_req_t);
- bind_req->dl_primitive = DL_BIND_REQ;
- bind_req->dl_sap = sap;
- bind_req->dl_max_conind = max_conn;
- bind_req->dl_service_mode = service;
- bind_req->dl_conn_mgmt = conn_mgmt;
- bind_req->dl_xidtest_flg = 0;
-
- (void) ldi_putmsg(lh, mp);
- if ((error = ldi_getmsg(lh, &mp, (timestruc_t *)NULL)) != 0) {
- cmn_err(CE_NOTE, "!dl_bind: ldi_getmsg failed: %d", error);
- return (error);
- }
-
- dl_prim = (union DL_primitives *)mp->b_rptr;
- switch (dl_prim->dl_primitive) {
- case DL_BIND_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_bind_ack_t)) {
- cmn_err(CE_NOTE,
- "!dl_bind: DL_BIND_ACK protocol error");
- break;
- }
- if (((dl_bind_ack_t *)dl_prim)->dl_sap != sap) {
- cmn_err(CE_NOTE, "!dl_bind: DL_BIND_ACK bad sap %u",
- ((dl_bind_ack_t *)dl_prim)->dl_sap);
- break;
- }
- freemsg(mp);
- return (0);
-
- case DL_ERROR_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) {
- cmn_err(CE_NOTE,
- "!dl_bind: DL_ERROR_ACK protocol error");
- break;
- }
- break;
-
- default:
- cmn_err(CE_NOTE, "!dl_bind: bad ACK header %u",
- dl_prim->dl_primitive);
- break;
- }
-
- /*
- * Error return only.
- */
- freemsg(mp);
- return (-1);
-}
-
-int
-dl_phys_addr(ldi_handle_t lh, struct ether_addr *eaddr)
-{
- dl_phys_addr_req_t *phys_addr_req;
- dl_phys_addr_ack_t *phys_addr_ack;
- union DL_primitives *dl_prim;
- mblk_t *mp;
- int error;
- uchar_t *addrp;
- timestruc_t tv;
-
- if ((mp = allocb(sizeof (dl_phys_addr_req_t), BPRI_MED)) ==
- (mblk_t *)NULL) {
- cmn_err(CE_WARN, "dl_phys_addr: allocb failed");
- return (ENOSR);
- }
- mp->b_datap->db_type = M_PROTO;
- mp->b_wptr += sizeof (dl_phys_addr_req_t);
-
- phys_addr_req = (dl_phys_addr_req_t *)mp->b_rptr;
- phys_addr_req->dl_primitive = DL_PHYS_ADDR_REQ;
- phys_addr_req->dl_addr_type = DL_CURR_PHYS_ADDR;
-
- /*
- * In case some provider doesn't implement or nack the
- * request just wait for 15 seconds.
- */
- tv.tv_sec = 15;
- tv.tv_nsec = 0;
-
- (void) ldi_putmsg(lh, mp);
- error = ldi_getmsg(lh, &mp, &tv);
- if (error == ETIME) {
- cmn_err(CE_NOTE, "!dl_phys_addr: timed out");
- return (-1);
- } else if (error != 0) {
- cmn_err(CE_NOTE, "!dl_phys_addr: ldi_getmsg failed: %d", error);
- return (error);
- }
-
- dl_prim = (union DL_primitives *)mp->b_rptr;
- switch (dl_prim->dl_primitive) {
- case DL_PHYS_ADDR_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_phys_addr_ack_t)) {
- cmn_err(CE_NOTE, "!dl_phys_addr: "
- "DL_PHYS_ADDR_ACK protocol error");
- break;
- }
- phys_addr_ack = &dl_prim->physaddr_ack;
- if (phys_addr_ack->dl_addr_length != sizeof (*eaddr)) {
- cmn_err(CE_NOTE,
- "!dl_phys_addr: DL_PHYS_ADDR_ACK bad len %u",
- phys_addr_ack->dl_addr_length);
- break;
- }
- if (phys_addr_ack->dl_addr_length +
- phys_addr_ack->dl_addr_offset > (mp->b_wptr-mp->b_rptr)) {
- cmn_err(CE_NOTE,
- "!dl_phys_addr: DL_PHYS_ADDR_ACK bad len %u",
- phys_addr_ack->dl_addr_length);
- break;
- }
- addrp = mp->b_rptr + phys_addr_ack->dl_addr_offset;
- bcopy(addrp, eaddr, sizeof (*eaddr));
- freemsg(mp);
- return (0);
-
- case DL_ERROR_ACK:
- if ((mp->b_wptr-mp->b_rptr) < sizeof (dl_error_ack_t)) {
- cmn_err(CE_NOTE,
- "!dl_phys_addr: DL_ERROR_ACK protocol error");
- break;
- }
-
- break;
-
- default:
- cmn_err(CE_NOTE, "!dl_phys_addr: bad ACK header %u",
- dl_prim->dl_primitive);
- break;
- }
-
- /*
- * Error return only.
- */
- freemsg(mp);
- return (-1);
-}