15895Syz147064 /* 25895Syz147064 * CDDL HEADER START 35895Syz147064 * 45895Syz147064 * The contents of this file are subject to the terms of the 55895Syz147064 * Common Development and Distribution License (the "License"). 65895Syz147064 * You may not use this file except in compliance with the License. 75895Syz147064 * 85895Syz147064 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 95895Syz147064 * or http://www.opensolaris.org/os/licensing. 105895Syz147064 * See the License for the specific language governing permissions 115895Syz147064 * and limitations under the License. 125895Syz147064 * 135895Syz147064 * When distributing Covered Code, include this CDDL HEADER in each 145895Syz147064 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 155895Syz147064 * If applicable, add the following below this CDDL HEADER, with the 165895Syz147064 * fields enclosed by brackets "[]" replaced with your own identifying 175895Syz147064 * information: Portions Copyright [yyyy] [name of copyright owner] 185895Syz147064 * 195895Syz147064 * CDDL HEADER END 205895Syz147064 */ 215895Syz147064 /* 225895Syz147064 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 235895Syz147064 * Use is subject to license terms. 245895Syz147064 */ 255895Syz147064 265895Syz147064 #include <sys/stropts.h> 27*8275SEric Cheng #include <sys/strsubr.h> 28*8275SEric Cheng #include <sys/callb.h> 295895Syz147064 #include <sys/softmac_impl.h> 305895Syz147064 315895Syz147064 int 325895Syz147064 softmac_send_notify_req(softmac_lower_t *slp, uint32_t notifications) 335895Syz147064 { 345895Syz147064 mblk_t *reqmp; 355895Syz147064 365895Syz147064 /* 375895Syz147064 * create notify req message and send it down 385895Syz147064 */ 395895Syz147064 reqmp = mexchange(NULL, NULL, DL_NOTIFY_REQ_SIZE, M_PROTO, 405895Syz147064 DL_NOTIFY_REQ); 415895Syz147064 if (reqmp == NULL) 425895Syz147064 return (ENOMEM); 435895Syz147064 445895Syz147064 ((dl_notify_req_t *)reqmp->b_rptr)->dl_notifications = notifications; 455895Syz147064 465895Syz147064 return (softmac_proto_tx(slp, reqmp, NULL)); 475895Syz147064 } 485895Syz147064 495895Syz147064 int 505895Syz147064 softmac_send_bind_req(softmac_lower_t *slp, uint_t sap) 515895Syz147064 { 525895Syz147064 dl_bind_req_t *bind; 535895Syz147064 mblk_t *reqmp; 545895Syz147064 555895Syz147064 /* 565895Syz147064 * create bind req message and send it down 575895Syz147064 */ 585895Syz147064 reqmp = mexchange(NULL, NULL, DL_BIND_REQ_SIZE, M_PROTO, DL_BIND_REQ); 595895Syz147064 if (reqmp == NULL) 605895Syz147064 return (ENOMEM); 615895Syz147064 625895Syz147064 bind = (dl_bind_req_t *)reqmp->b_rptr; 635895Syz147064 bind->dl_sap = sap; 645895Syz147064 bind->dl_conn_mgmt = 0; 655895Syz147064 bind->dl_max_conind = 0; 665895Syz147064 bind->dl_xidtest_flg = 0; 675895Syz147064 bind->dl_service_mode = DL_CLDLS; 685895Syz147064 695895Syz147064 return (softmac_proto_tx(slp, reqmp, NULL)); 705895Syz147064 } 715895Syz147064 725895Syz147064 int 735895Syz147064 softmac_send_promisc_req(softmac_lower_t *slp, t_uscalar_t level, boolean_t on) 745895Syz147064 { 755895Syz147064 mblk_t *reqmp; 765895Syz147064 size_t size; 775895Syz147064 t_uscalar_t dl_prim; 785895Syz147064 795895Syz147064 /* 805895Syz147064 * create promisc message and send it down 815895Syz147064 */ 825895Syz147064 if (on) { 835895Syz147064 dl_prim = DL_PROMISCON_REQ; 845895Syz147064 size = DL_PROMISCON_REQ_SIZE; 855895Syz147064 } else { 865895Syz147064 dl_prim = DL_PROMISCOFF_REQ; 875895Syz147064 size = DL_PROMISCOFF_REQ_SIZE; 885895Syz147064 } 895895Syz147064 905895Syz147064 reqmp = mexchange(NULL, NULL, size, M_PROTO, dl_prim); 915895Syz147064 if (reqmp == NULL) 925895Syz147064 return (ENOMEM); 935895Syz147064 945895Syz147064 if (on) 955895Syz147064 ((dl_promiscon_req_t *)reqmp->b_rptr)->dl_level = level; 965895Syz147064 else 975895Syz147064 ((dl_promiscoff_req_t *)reqmp->b_rptr)->dl_level = level; 985895Syz147064 995895Syz147064 return (softmac_proto_tx(slp, reqmp, NULL)); 1005895Syz147064 } 1015895Syz147064 1025895Syz147064 int 1035895Syz147064 softmac_m_promisc(void *arg, boolean_t on) 1045895Syz147064 { 1055895Syz147064 softmac_t *softmac = arg; 1065895Syz147064 softmac_lower_t *slp = softmac->smac_lower; 1075895Syz147064 1085895Syz147064 ASSERT(slp != NULL); 1095895Syz147064 return (softmac_send_promisc_req(slp, DL_PROMISC_PHYS, on)); 1105895Syz147064 } 1115895Syz147064 1125895Syz147064 int 1135895Syz147064 softmac_m_multicst(void *arg, boolean_t add, const uint8_t *mca) 1145895Syz147064 { 1155895Syz147064 softmac_t *softmac = arg; 1165895Syz147064 softmac_lower_t *slp; 1175895Syz147064 dl_enabmulti_req_t *enabmulti; 1185895Syz147064 dl_disabmulti_req_t *disabmulti; 1195895Syz147064 mblk_t *reqmp; 1205895Syz147064 t_uscalar_t dl_prim; 1215895Syz147064 uint32_t size, addr_length; 1225895Syz147064 1235895Syz147064 /* 1245895Syz147064 * create multicst message and send it down 1255895Syz147064 */ 1265895Syz147064 addr_length = softmac->smac_addrlen; 1275895Syz147064 if (add) { 1285895Syz147064 size = sizeof (dl_enabmulti_req_t) + addr_length; 1295895Syz147064 dl_prim = DL_ENABMULTI_REQ; 1305895Syz147064 } else { 1315895Syz147064 size = sizeof (dl_disabmulti_req_t) + addr_length; 1325895Syz147064 dl_prim = DL_DISABMULTI_REQ; 1335895Syz147064 } 1345895Syz147064 1355895Syz147064 reqmp = mexchange(NULL, NULL, size, M_PROTO, dl_prim); 1365895Syz147064 if (reqmp == NULL) 1375895Syz147064 return (ENOMEM); 1385895Syz147064 1395895Syz147064 if (add) { 1405895Syz147064 enabmulti = (dl_enabmulti_req_t *)reqmp->b_rptr; 1415895Syz147064 enabmulti->dl_addr_offset = sizeof (dl_enabmulti_req_t); 1425895Syz147064 enabmulti->dl_addr_length = addr_length; 1435895Syz147064 (void) memcpy(&enabmulti[1], mca, addr_length); 1445895Syz147064 } else { 1455895Syz147064 disabmulti = (dl_disabmulti_req_t *)reqmp->b_rptr; 1465895Syz147064 disabmulti->dl_addr_offset = sizeof (dl_disabmulti_req_t); 1475895Syz147064 disabmulti->dl_addr_length = addr_length; 1485895Syz147064 (void) memcpy(&disabmulti[1], mca, addr_length); 1495895Syz147064 } 1505895Syz147064 1515895Syz147064 slp = softmac->smac_lower; 1525895Syz147064 ASSERT(slp != NULL); 1535895Syz147064 return (softmac_proto_tx(slp, reqmp, NULL)); 1545895Syz147064 } 1555895Syz147064 1565895Syz147064 int 1575895Syz147064 softmac_m_unicst(void *arg, const uint8_t *macaddr) 1585895Syz147064 { 1595895Syz147064 softmac_t *softmac = arg; 1605895Syz147064 softmac_lower_t *slp; 1615895Syz147064 dl_set_phys_addr_req_t *phyaddr; 1625895Syz147064 mblk_t *reqmp; 1635895Syz147064 size_t size; 1645895Syz147064 1655895Syz147064 /* 1665895Syz147064 * create set_phys_addr message and send it down 1675895Syz147064 */ 1685895Syz147064 size = DL_SET_PHYS_ADDR_REQ_SIZE + softmac->smac_addrlen; 1695895Syz147064 reqmp = mexchange(NULL, NULL, size, M_PROTO, DL_SET_PHYS_ADDR_REQ); 1705895Syz147064 if (reqmp == NULL) 1715895Syz147064 return (ENOMEM); 1725895Syz147064 1735895Syz147064 phyaddr = (dl_set_phys_addr_req_t *)reqmp->b_rptr; 1745895Syz147064 phyaddr->dl_addr_offset = sizeof (dl_set_phys_addr_req_t); 1755895Syz147064 phyaddr->dl_addr_length = softmac->smac_addrlen; 1765895Syz147064 (void) memcpy(&phyaddr[1], macaddr, softmac->smac_addrlen); 1775895Syz147064 1785895Syz147064 slp = softmac->smac_lower; 1795895Syz147064 ASSERT(slp != NULL); 1805895Syz147064 return (softmac_proto_tx(slp, reqmp, NULL)); 1815895Syz147064 } 1825895Syz147064 1835895Syz147064 void 1845895Syz147064 softmac_m_ioctl(void *arg, queue_t *wq, mblk_t *mp) 1855895Syz147064 { 1865895Syz147064 softmac_lower_t *slp = ((softmac_t *)arg)->smac_lower; 1875895Syz147064 mblk_t *ackmp; 1885895Syz147064 1895895Syz147064 ASSERT(slp != NULL); 1905895Syz147064 softmac_ioctl_tx(slp, mp, &ackmp); 1915895Syz147064 qreply(wq, ackmp); 1925895Syz147064 } 1935895Syz147064 1945895Syz147064 static void 195*8275SEric Cheng softmac_process_notify_ind(softmac_t *softmac, mblk_t *mp) 1965895Syz147064 { 1975895Syz147064 dl_notify_ind_t *dlnip = (dl_notify_ind_t *)mp->b_rptr; 1985895Syz147064 uint_t addroff, addrlen; 1995895Syz147064 2005895Syz147064 ASSERT(dlnip->dl_primitive == DL_NOTIFY_IND); 2015895Syz147064 2025895Syz147064 switch (dlnip->dl_notification) { 2035895Syz147064 case DL_NOTE_PHYS_ADDR: 2045895Syz147064 if (dlnip->dl_data != DL_CURR_PHYS_ADDR) 2055895Syz147064 break; 2065895Syz147064 2075895Syz147064 addroff = dlnip->dl_addr_offset; 2085895Syz147064 addrlen = dlnip->dl_addr_length - softmac->smac_saplen; 2095895Syz147064 if (addroff == 0 || addrlen != softmac->smac_addrlen || 2105895Syz147064 !MBLKIN(mp, addroff, addrlen)) { 2115895Syz147064 cmn_err(CE_NOTE, "softmac: got malformed " 2125895Syz147064 "DL_NOTIFY_IND; length/offset %d/%d", 2135895Syz147064 addrlen, addroff); 2145895Syz147064 break; 2155895Syz147064 } 2165895Syz147064 2175895Syz147064 mac_unicst_update(softmac->smac_mh, mp->b_rptr + addroff); 2185895Syz147064 break; 2195895Syz147064 2205895Syz147064 case DL_NOTE_LINK_UP: 2215895Syz147064 mac_link_update(softmac->smac_mh, LINK_STATE_UP); 2225895Syz147064 break; 2235895Syz147064 2245895Syz147064 case DL_NOTE_LINK_DOWN: 2255895Syz147064 mac_link_update(softmac->smac_mh, LINK_STATE_DOWN); 2265895Syz147064 break; 2275895Syz147064 } 2285895Syz147064 2295895Syz147064 freemsg(mp); 2305895Syz147064 } 2315895Syz147064 232*8275SEric Cheng void 233*8275SEric Cheng softmac_notify_thread(void *arg) 234*8275SEric Cheng { 235*8275SEric Cheng softmac_t *softmac = arg; 236*8275SEric Cheng callb_cpr_t cprinfo; 237*8275SEric Cheng 238*8275SEric Cheng CALLB_CPR_INIT(&cprinfo, &softmac->smac_mutex, callb_generic_cpr, 239*8275SEric Cheng "softmac_notify_thread"); 240*8275SEric Cheng 241*8275SEric Cheng mutex_enter(&softmac->smac_mutex); 242*8275SEric Cheng 243*8275SEric Cheng /* 244*8275SEric Cheng * Quit the thread if smac_mh is unregistered. 245*8275SEric Cheng */ 246*8275SEric Cheng while (softmac->smac_mh != NULL && 247*8275SEric Cheng !(softmac->smac_flags & SOFTMAC_NOTIFY_QUIT)) { 248*8275SEric Cheng mblk_t *mp, *nextmp; 249*8275SEric Cheng 250*8275SEric Cheng if ((mp = softmac->smac_notify_head) == NULL) { 251*8275SEric Cheng CALLB_CPR_SAFE_BEGIN(&cprinfo); 252*8275SEric Cheng cv_wait(&softmac->smac_cv, &softmac->smac_mutex); 253*8275SEric Cheng CALLB_CPR_SAFE_END(&cprinfo, &softmac->smac_mutex); 254*8275SEric Cheng continue; 255*8275SEric Cheng } 256*8275SEric Cheng 257*8275SEric Cheng softmac->smac_notify_head = softmac->smac_notify_tail = NULL; 258*8275SEric Cheng mutex_exit(&softmac->smac_mutex); 259*8275SEric Cheng 260*8275SEric Cheng while (mp != NULL) { 261*8275SEric Cheng nextmp = mp->b_next; 262*8275SEric Cheng mp->b_next = NULL; 263*8275SEric Cheng softmac_process_notify_ind(softmac, mp); 264*8275SEric Cheng mp = nextmp; 265*8275SEric Cheng } 266*8275SEric Cheng mutex_enter(&softmac->smac_mutex); 267*8275SEric Cheng } 268*8275SEric Cheng 269*8275SEric Cheng /* 270*8275SEric Cheng * The softmac is being destroyed, simply free all of the DL_NOTIFY_IND 271*8275SEric Cheng * messages left in the queue which did not have the chance to be 272*8275SEric Cheng * processed. 273*8275SEric Cheng */ 274*8275SEric Cheng freemsgchain(softmac->smac_notify_head); 275*8275SEric Cheng softmac->smac_notify_head = softmac->smac_notify_tail = NULL; 276*8275SEric Cheng softmac->smac_notify_thread = NULL; 277*8275SEric Cheng cv_broadcast(&softmac->smac_cv); 278*8275SEric Cheng CALLB_CPR_EXIT(&cprinfo); 279*8275SEric Cheng thread_exit(); 280*8275SEric Cheng } 281*8275SEric Cheng 282*8275SEric Cheng static void 283*8275SEric Cheng softmac_enqueue_notify_ind(queue_t *rq, mblk_t *mp) 284*8275SEric Cheng { 285*8275SEric Cheng softmac_lower_t *slp = rq->q_ptr; 286*8275SEric Cheng softmac_t *softmac = slp->sl_softmac; 287*8275SEric Cheng 288*8275SEric Cheng mutex_enter(&softmac->smac_mutex); 289*8275SEric Cheng if (softmac->smac_notify_tail == NULL) { 290*8275SEric Cheng softmac->smac_notify_head = softmac->smac_notify_tail = mp; 291*8275SEric Cheng } else { 292*8275SEric Cheng softmac->smac_notify_tail->b_next = mp; 293*8275SEric Cheng softmac->smac_notify_tail = mp; 294*8275SEric Cheng } 295*8275SEric Cheng cv_broadcast(&softmac->smac_cv); 296*8275SEric Cheng mutex_exit(&softmac->smac_mutex); 297*8275SEric Cheng } 298*8275SEric Cheng 2995895Syz147064 static void 3005895Syz147064 softmac_process_dlpi(softmac_lower_t *slp, mblk_t *mp, uint_t minlen, 3015895Syz147064 t_uscalar_t reqprim) 3025895Syz147064 { 3035895Syz147064 const char *ackname; 3045895Syz147064 3055895Syz147064 ackname = dl_primstr(((union DL_primitives *)mp->b_rptr)->dl_primitive); 3065895Syz147064 3075895Syz147064 if (MBLKL(mp) < minlen) { 3085895Syz147064 cmn_err(CE_WARN, "softmac: got short %s", ackname); 3095895Syz147064 freemsg(mp); 3105895Syz147064 return; 3115895Syz147064 } 3125895Syz147064 3135895Syz147064 mutex_enter(&slp->sl_mutex); 3145895Syz147064 if (slp->sl_pending_prim != reqprim) { 3155895Syz147064 cmn_err(CE_NOTE, "softmac: got unexpected %s", ackname); 3165895Syz147064 mutex_exit(&slp->sl_mutex); 3175895Syz147064 freemsg(mp); 3185895Syz147064 return; 3195895Syz147064 } 3205895Syz147064 3215895Syz147064 slp->sl_pending_prim = DL_PRIM_INVAL; 3225895Syz147064 slp->sl_ack_mp = mp; 3235895Syz147064 cv_signal(&slp->sl_cv); 3245895Syz147064 mutex_exit(&slp->sl_mutex); 3255895Syz147064 } 3265895Syz147064 3275895Syz147064 void 3285895Syz147064 softmac_rput_process_proto(queue_t *rq, mblk_t *mp) 3295895Syz147064 { 3305895Syz147064 softmac_lower_t *slp = rq->q_ptr; 3315895Syz147064 union DL_primitives *dlp = (union DL_primitives *)mp->b_rptr; 3325895Syz147064 ssize_t len = MBLKL(mp); 3335895Syz147064 const char *primstr; 3345895Syz147064 3355895Syz147064 if (len < sizeof (t_uscalar_t)) { 3365895Syz147064 cmn_err(CE_WARN, "softmac: got runt DLPI message"); 3375895Syz147064 goto exit; 3385895Syz147064 } 3395895Syz147064 3405895Syz147064 primstr = dl_primstr(dlp->dl_primitive); 3415895Syz147064 3425895Syz147064 switch (dlp->dl_primitive) { 3435895Syz147064 case DL_OK_ACK: 3445895Syz147064 if (len < DL_OK_ACK_SIZE) 3455895Syz147064 goto runt; 3465895Syz147064 3475895Syz147064 softmac_process_dlpi(slp, mp, DL_OK_ACK_SIZE, 3485895Syz147064 dlp->ok_ack.dl_correct_primitive); 3495895Syz147064 return; 3505895Syz147064 3515895Syz147064 case DL_ERROR_ACK: 3525895Syz147064 if (len < DL_ERROR_ACK_SIZE) 3535895Syz147064 goto runt; 3545895Syz147064 3555895Syz147064 softmac_process_dlpi(slp, mp, DL_ERROR_ACK_SIZE, 3565895Syz147064 dlp->error_ack.dl_error_primitive); 3575895Syz147064 return; 3585895Syz147064 3595895Syz147064 case DL_NOTIFY_IND: 3605895Syz147064 if (len < DL_NOTIFY_IND_SIZE) 3615895Syz147064 goto runt; 3625895Syz147064 363*8275SEric Cheng /* 364*8275SEric Cheng * Enqueue all the DL_NOTIFY_IND messages and process them 365*8275SEric Cheng * in another separate thread to avoid deadlock. Here is an 366*8275SEric Cheng * example of the deadlock scenario: 367*8275SEric Cheng * 368*8275SEric Cheng * Thread A: mac_promisc_set()->softmac_m_promisc() 369*8275SEric Cheng * 370*8275SEric Cheng * The softmac driver waits for the ACK of the 371*8275SEric Cheng * DL_PROMISC_PHYS request with the MAC perimeter; 372*8275SEric Cheng * 373*8275SEric Cheng * Thread B: 374*8275SEric Cheng * 375*8275SEric Cheng * The driver handles the DL_PROMISC_PHYS request. Before 376*8275SEric Cheng * it sends back the ACK, it could first send a 377*8275SEric Cheng * DL_NOTE_PROMISC_ON_PHYS notification. 378*8275SEric Cheng * 379*8275SEric Cheng * Since DL_NOTIFY_IND could eventually cause softmac to call 380*8275SEric Cheng * mac_xxx_update(), which requires MAC perimeter, this would 381*8275SEric Cheng * cause deadlock between the two threads. Enqueuing the 382*8275SEric Cheng * DL_NOTIFY_IND message and defer its processing would 383*8275SEric Cheng * avoid the potential deadlock. 384*8275SEric Cheng */ 385*8275SEric Cheng softmac_enqueue_notify_ind(rq, mp); 3865895Syz147064 return; 3875895Syz147064 3885895Syz147064 case DL_NOTIFY_ACK: 3895895Syz147064 softmac_process_dlpi(slp, mp, DL_NOTIFY_ACK_SIZE, 3905895Syz147064 DL_NOTIFY_REQ); 3915895Syz147064 return; 3925895Syz147064 3935895Syz147064 case DL_CAPABILITY_ACK: 3945895Syz147064 softmac_process_dlpi(slp, mp, DL_CAPABILITY_ACK_SIZE, 3955895Syz147064 DL_CAPABILITY_REQ); 3965895Syz147064 return; 3975895Syz147064 3985895Syz147064 case DL_BIND_ACK: 3995895Syz147064 softmac_process_dlpi(slp, mp, DL_BIND_ACK_SIZE, DL_BIND_REQ); 4005895Syz147064 return; 4015895Syz147064 4025895Syz147064 case DL_CONTROL_ACK: 4035895Syz147064 softmac_process_dlpi(slp, mp, DL_CONTROL_ACK_SIZE, 4045895Syz147064 DL_CONTROL_REQ); 4055895Syz147064 return; 4065895Syz147064 4075895Syz147064 case DL_UNITDATA_IND: 4085895Syz147064 case DL_PHYS_ADDR_ACK: 4095895Syz147064 /* 4105895Syz147064 * a. Because the stream is in DLIOCRAW mode, 4115895Syz147064 * DL_UNITDATA_IND messages are not expected. 4125895Syz147064 * b. The lower stream should not receive DL_PHYS_ADDR_REQ, 4135895Syz147064 * so DL_PHYS_ADDR_ACK messages are also unexpected. 4145895Syz147064 */ 4155895Syz147064 default: 4165895Syz147064 cmn_err(CE_WARN, "softmac: got unexpected %s", primstr); 4175895Syz147064 break; 4185895Syz147064 } 4195895Syz147064 exit: 4205895Syz147064 freemsg(mp); 4215895Syz147064 return; 4225895Syz147064 runt: 4235895Syz147064 cmn_err(CE_WARN, "softmac: got runt %s", primstr); 4245895Syz147064 freemsg(mp); 4255895Syz147064 } 4265895Syz147064 4275895Syz147064 void 4285895Syz147064 softmac_rput_process_notdata(queue_t *rq, mblk_t *mp) 4295895Syz147064 { 4305895Syz147064 softmac_lower_t *slp = rq->q_ptr; 4315895Syz147064 4325895Syz147064 switch (DB_TYPE(mp)) { 4335895Syz147064 case M_PROTO: 4345895Syz147064 case M_PCPROTO: 4355895Syz147064 softmac_rput_process_proto(rq, mp); 4365895Syz147064 break; 4375895Syz147064 4385895Syz147064 case M_FLUSH: 4395895Syz147064 if (*mp->b_rptr & FLUSHR) 4405895Syz147064 flushq(rq, FLUSHDATA); 4415895Syz147064 if (*mp->b_rptr & FLUSHW) 4425895Syz147064 flushq(OTHERQ(rq), FLUSHDATA); 4435895Syz147064 putnext(rq, mp); 4445895Syz147064 break; 4455895Syz147064 4465895Syz147064 case M_IOCACK: 4475895Syz147064 case M_IOCNAK: 4485895Syz147064 case M_COPYIN: 4495895Syz147064 case M_COPYOUT: 4505895Syz147064 mutex_enter(&slp->sl_mutex); 4515895Syz147064 if (!slp->sl_pending_ioctl) { 4525895Syz147064 mutex_exit(&slp->sl_mutex); 4535895Syz147064 cmn_err(CE_NOTE, "softmac: got unexpected mblk " 4545895Syz147064 "type 0x%x", DB_TYPE(mp)); 4555895Syz147064 freemsg(mp); 4565895Syz147064 break; 4575895Syz147064 } 4585895Syz147064 4595895Syz147064 slp->sl_pending_ioctl = B_FALSE; 4605895Syz147064 slp->sl_ack_mp = mp; 4615895Syz147064 cv_broadcast(&slp->sl_cv); 4625895Syz147064 mutex_exit(&slp->sl_mutex); 4635895Syz147064 return; 4645895Syz147064 4655895Syz147064 default: 4665895Syz147064 cmn_err(CE_NOTE, "softmac: got unsupported mblk type 0x%x", 4675895Syz147064 DB_TYPE(mp)); 4685895Syz147064 freemsg(mp); 4695895Syz147064 break; 4705895Syz147064 } 4715895Syz147064 } 472