Print this page
cstyle sort of updates
7127 remove -Wno-missing-braces from Makefile.uts
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/softmac/softmac_dev.c
+++ new/usr/src/uts/common/io/softmac/softmac_dev.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 #include <sys/types.h>
28 28 #include <inet/common.h>
29 29 #include <sys/stropts.h>
30 30 #include <sys/modctl.h>
31 31 #include <sys/dld.h>
32 32 #include <sys/softmac_impl.h>
33 33
34 34 dev_info_t *softmac_dip = NULL;
35 35 static kmem_cache_t *softmac_upper_cachep;
36 36
37 37 /*
38 38 * This function is a generic open(9E) entry point into the softmac for
39 39 * both the softmac module and the softmac driver.
40 40 */
41 41 static int softmac_cmn_open(queue_t *, dev_t *, int, int, cred_t *);
42 42
43 43 /*
44 44 * The following softmac_mod_xxx() functions are (9E) entry point functions for
45 45 * the softmac module.
46 46 */
47 47 static int softmac_mod_close(queue_t *);
48 48 static void softmac_mod_rput(queue_t *, mblk_t *);
49 49 static void softmac_mod_wput(queue_t *, mblk_t *);
50 50 static void softmac_mod_wsrv(queue_t *);
51 51
52 52 /*
53 53 * The following softmac_drv_xxx() functions are (9E) entry point functions for
54 54 * the softmac driver.
55 55 */
56 56 static int softmac_drv_open(queue_t *, dev_t *, int, int, cred_t *);
57 57 static int softmac_drv_close(queue_t *);
58 58 static void softmac_drv_wput(queue_t *, mblk_t *);
59 59 static void softmac_drv_wsrv(queue_t *);
60 60
61 61 static int softmac_attach(dev_info_t *, ddi_attach_cmd_t);
62 62 static int softmac_detach(dev_info_t *, ddi_detach_cmd_t);
63 63 static int softmac_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
64 64
65 65 static struct module_info softmac_modinfo = {
66 66 0,
67 67 SOFTMAC_DEV_NAME,
68 68 0,
69 69 INFPSZ,
70 70 65536,
71 71 1024
72 72 };
73 73
74 74 /*
75 75 * hi-water mark is 1 because of the flow control mechanism implemented in
76 76 * dld. Refer to the comments in dld_str.c for details.
77 77 */
78 78 static struct module_info softmac_dld_modinfo = {
79 79 0,
80 80 SOFTMAC_DEV_NAME,
81 81 0,
82 82 INFPSZ,
83 83 1,
84 84 0
85 85 };
86 86
87 87 static struct qinit softmac_urinit = {
88 88 (pfi_t)softmac_mod_rput, /* qi_putp */
89 89 (pfi_t)NULL, /* qi_srvp */
90 90 softmac_cmn_open, /* qi_qopen */
91 91 softmac_mod_close, /* qi_qclose */
92 92 NULL, /* qi_qadmin */
93 93 &softmac_modinfo /* qi_minfo */
94 94 };
95 95
96 96 static struct qinit softmac_uwinit = {
97 97 (pfi_t)softmac_mod_wput, /* qi_putp */
98 98 (pfi_t)softmac_mod_wsrv, /* qi_srvp */
99 99 NULL, /* qi_qopen */
100 100 NULL, /* qi_qclose */
101 101 NULL, /* qi_qadmin */
102 102 &softmac_modinfo /* qi_minfo */
103 103 };
104 104
105 105 static struct streamtab softmac_tab = {
106 106 &softmac_urinit, /* st_rdinit */
107 107 &softmac_uwinit /* st_wrinit */
108 108 };
109 109
110 110 DDI_DEFINE_STREAM_OPS(softmac_ops, nulldev, nulldev, softmac_attach,
111 111 softmac_detach, nodev, softmac_info, D_MP, &softmac_tab,
112 112 ddi_quiesce_not_supported);
113 113
114 114 static struct qinit softmac_dld_r_qinit = {
115 115 NULL, NULL, softmac_drv_open, softmac_drv_close, NULL,
116 116 &softmac_dld_modinfo
117 117 };
118 118
119 119 static struct qinit softmac_dld_w_qinit = {
120 120 (pfi_t)softmac_drv_wput, (pfi_t)softmac_drv_wsrv, NULL, NULL, NULL,
121 121 &softmac_dld_modinfo
122 122 };
123 123
124 124 static struct fmodsw softmac_fmodsw = {
125 125 SOFTMAC_DEV_NAME,
126 126 &softmac_tab,
127 127 D_MP
128 128 };
129 129
130 130 static struct modldrv softmac_modldrv = {
131 131 &mod_driverops,
132 132 "softmac driver",
133 133 &softmac_ops
↓ open down ↓ |
133 lines elided |
↑ open up ↑ |
134 134 };
135 135
136 136 static struct modlstrmod softmac_modlstrmod = {
137 137 &mod_strmodops,
138 138 "softmac module",
139 139 &softmac_fmodsw
140 140 };
141 141
142 142 static struct modlinkage softmac_modlinkage = {
143 143 MODREV_1,
144 - &softmac_modlstrmod,
145 - &softmac_modldrv,
146 - NULL
144 + { &softmac_modlstrmod,
145 + &softmac_modldrv,
146 + NULL }
147 147 };
148 148
149 149 static void softmac_dedicated_rx(void *, mac_resource_handle_t, mblk_t *,
150 150 mac_header_info_t *);
151 151
152 152 /*ARGSUSED*/
153 153 static int
154 154 softmac_upper_constructor(void *buf, void *arg, int kmflag)
155 155 {
156 156 softmac_upper_t *sup = buf;
157 157
158 158 bzero(buf, sizeof (softmac_upper_t));
159 159
160 160 mutex_init(&sup->su_mutex, NULL, MUTEX_DEFAULT, NULL);
161 161 cv_init(&sup->su_cv, NULL, CV_DEFAULT, NULL);
162 162 mutex_init(&sup->su_disp_mutex, NULL, MUTEX_DEFAULT, NULL);
163 163 cv_init(&sup->su_disp_cv, NULL, CV_DEFAULT, NULL);
164 164 list_create(&sup->su_req_list, sizeof (softmac_switch_req_t),
165 165 offsetof(softmac_switch_req_t, ssq_req_list_node));
166 166 return (0);
167 167 }
168 168
169 169 /*ARGSUSED*/
170 170 static void
171 171 softmac_upper_destructor(void *buf, void *arg)
172 172 {
173 173 softmac_upper_t *sup = buf;
174 174
175 175 ASSERT(sup->su_slp == NULL);
176 176 ASSERT(sup->su_pending_head == NULL && sup->su_pending_tail == NULL);
177 177 ASSERT(!sup->su_dlpi_pending);
178 178 ASSERT(!sup->su_active);
179 179 ASSERT(!sup->su_closing);
180 180 ASSERT(sup->su_tx_flow_mp == NULL);
181 181 ASSERT(sup->su_tx_inprocess == 0);
182 182 ASSERT(sup->su_mode == SOFTMAC_UNKNOWN);
183 183 ASSERT(!sup->su_tx_busy);
184 184 ASSERT(!sup->su_bound);
185 185 ASSERT(!sup->su_taskq_scheduled);
186 186 ASSERT(sup->su_tx_notify_func == NULL);
187 187 ASSERT(sup->su_tx_notify_arg == NULL);
188 188 ASSERT(list_is_empty(&sup->su_req_list));
189 189
190 190 list_destroy(&sup->su_req_list);
191 191 mutex_destroy(&sup->su_mutex);
192 192 cv_destroy(&sup->su_cv);
193 193 mutex_destroy(&sup->su_disp_mutex);
194 194 cv_destroy(&sup->su_disp_cv);
195 195 }
196 196
197 197 int
198 198 _init(void)
199 199 {
200 200 int err;
201 201
202 202 mac_init_ops(NULL, SOFTMAC_DEV_NAME);
203 203 softmac_init();
204 204
205 205 softmac_upper_cachep = kmem_cache_create("softmac_upper_cache",
206 206 sizeof (softmac_upper_t), 0, softmac_upper_constructor,
207 207 softmac_upper_destructor, NULL, NULL, NULL, 0);
208 208 ASSERT(softmac_upper_cachep != NULL);
209 209
210 210 if ((err = mod_install(&softmac_modlinkage)) != 0) {
211 211 softmac_fini();
212 212 return (err);
213 213 }
214 214
215 215 return (0);
216 216 }
217 217
218 218 int
219 219 _fini(void)
220 220 {
221 221 int err;
222 222
223 223 if (softmac_busy())
224 224 return (EBUSY);
225 225
226 226 if ((err = mod_remove(&softmac_modlinkage)) != 0)
227 227 return (err);
228 228
229 229 kmem_cache_destroy(softmac_upper_cachep);
230 230 softmac_fini();
231 231
232 232 return (0);
233 233 }
234 234
235 235 int
236 236 _info(struct modinfo *modinfop)
237 237 {
238 238 return (mod_info(&softmac_modlinkage, modinfop));
239 239 }
240 240
241 241 static int
242 242 softmac_cmn_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
243 243 {
244 244 softmac_lower_t *slp;
245 245 /*
246 246 * This is a self-cloning driver so that each queue should only
247 247 * get opened once.
248 248 */
249 249 if (rq->q_ptr != NULL)
250 250 return (EBUSY);
251 251
252 252 if (sflag == MODOPEN) {
253 253 /*
254 254 * This is the softmac module pushed over an underlying
255 255 * legacy device. Initialize the lower structure.
256 256 */
257 257 if ((slp = kmem_zalloc(sizeof (*slp), KM_NOSLEEP)) == NULL)
258 258 return (ENOMEM);
259 259
260 260 slp->sl_wq = WR(rq);
261 261 cv_init(&slp->sl_cv, NULL, CV_DRIVER, NULL);
262 262 mutex_init(&slp->sl_mutex, NULL, MUTEX_DRIVER, NULL);
263 263 slp->sl_pending_prim = DL_PRIM_INVAL;
264 264 rq->q_ptr = WR(rq)->q_ptr = slp;
265 265 qprocson(rq);
266 266 return (0);
267 267 }
268 268
269 269 /*
270 270 * Regular device open of a softmac DLPI node. We modify
271 271 * the queues' q_qinfo pointer such that all future STREAMS
272 272 * operations will go through another set of entry points
273 273 */
274 274 rq->q_qinfo = &softmac_dld_r_qinit;
275 275 WR(rq)->q_qinfo = &softmac_dld_w_qinit;
276 276 return (softmac_drv_open(rq, devp, flag, sflag, credp));
277 277 }
278 278
279 279 static int
280 280 softmac_mod_close(queue_t *rq)
281 281 {
282 282 softmac_lower_t *slp = rq->q_ptr;
283 283
284 284 /*
285 285 * Call the appropriate delete routine depending on whether this is
286 286 * a module or device.
287 287 */
288 288 ASSERT(WR(rq)->q_next != NULL);
289 289
290 290 qprocsoff(rq);
291 291
292 292 slp->sl_softmac = NULL;
293 293 slp->sl_lh = NULL;
294 294
295 295 ASSERT(slp->sl_ack_mp == NULL);
296 296 ASSERT(slp->sl_pending_prim == DL_PRIM_INVAL);
297 297 ASSERT(slp->sl_pending_ioctl == B_FALSE);
298 298
299 299 cv_destroy(&slp->sl_cv);
300 300 mutex_destroy(&slp->sl_mutex);
301 301
302 302 kmem_free(slp, sizeof (*slp));
303 303 return (0);
304 304 }
305 305
306 306 static void
307 307 softmac_mod_rput(queue_t *rq, mblk_t *mp)
308 308 {
309 309 softmac_lower_t *slp = rq->q_ptr;
310 310 softmac_lower_rxinfo_t *rxinfo;
311 311 union DL_primitives *dlp;
312 312
313 313 /*
314 314 * This is the softmac module.
315 315 */
316 316 ASSERT(WR(rq)->q_next != NULL);
317 317 ASSERT((mp->b_next == NULL) && (mp->b_prev == NULL));
318 318
319 319 switch (DB_TYPE(mp)) {
320 320 case M_DATA: {
321 321
322 322 /*
323 323 * If sl_rxinfo is non-NULL. This is dedicated-lower-stream
324 324 * created for fastpath. Directly call the rx callback.
325 325 */
326 326 if ((rxinfo = slp->sl_rxinfo) != NULL) {
327 327 rxinfo->slr_rx(rxinfo->slr_arg, NULL, mp, NULL);
328 328 break;
329 329 }
330 330
331 331 /*
332 332 * A shared-lower-stream. Some driver starts to send up
333 333 * packets even it not in the DL_IDLE state, where
334 334 * sl_softmac is not set yet. Drop the packet in this case.
335 335 */
336 336 if (slp->sl_softmac == NULL) {
337 337 freemsg(mp);
338 338 return;
339 339 }
340 340
341 341 /*
342 342 * If this message is looped back from the legacy devices,
343 343 * drop it as the Nemo framework will be responsible for
344 344 * looping it back by the mac_txloop() function.
345 345 */
346 346 if (mp->b_flag & MSGNOLOOP) {
347 347 freemsg(mp);
348 348 return;
349 349 }
350 350
351 351 /*
352 352 * This is the most common case.
353 353 */
354 354 if (DB_REF(mp) == 1) {
355 355 ASSERT(slp->sl_softmac != NULL);
356 356 mac_rx(slp->sl_softmac->smac_mh, NULL, mp);
357 357 return;
358 358 } else {
359 359 softmac_rput_process_data(slp, mp);
360 360 }
361 361 break;
362 362 }
363 363 case M_PROTO:
364 364 case M_PCPROTO:
365 365 if (MBLKL(mp) < sizeof (dlp->dl_primitive)) {
366 366 freemsg(mp);
367 367 break;
368 368 }
369 369 dlp = (union DL_primitives *)mp->b_rptr;
370 370 if (dlp->dl_primitive == DL_UNITDATA_IND) {
371 371
372 372 if ((rxinfo = slp->sl_rxinfo) != NULL) {
373 373 softmac_dedicated_rx(slp->sl_sup, NULL, mp,
374 374 NULL);
375 375 break;
376 376 }
377 377
378 378 cmn_err(CE_WARN, "got unexpected %s message",
379 379 dl_primstr(DL_UNITDATA_IND));
380 380 freemsg(mp);
381 381 break;
382 382 }
383 383 /*FALLTHROUGH*/
384 384 default:
385 385 softmac_rput_process_notdata(rq, slp->sl_sup, mp);
386 386 break;
387 387 }
388 388 }
389 389
390 390 static void
391 391 softmac_mod_wput(queue_t *wq, mblk_t *mp)
392 392 {
393 393 /*
394 394 * This is the softmac module
395 395 */
396 396 ASSERT(wq->q_next != NULL);
397 397
398 398 switch (DB_TYPE(mp)) {
399 399 case M_IOCTL: {
400 400 struct iocblk *ioc = (struct iocblk *)mp->b_rptr;
401 401
402 402 switch (ioc->ioc_cmd) {
403 403 case SMAC_IOC_START: {
404 404 softmac_lower_t *slp = wq->q_ptr;
405 405 smac_ioc_start_t *arg;
406 406
407 407 if (ioc->ioc_count != sizeof (*arg)) {
408 408 miocnak(wq, mp, 0, EINVAL);
409 409 break;
410 410 }
411 411
412 412 /*
413 413 * Assign the devname and perstream handle of the
414 414 * specific lower stream and return it as a part
415 415 * of the ioctl.
416 416 */
417 417 arg = (smac_ioc_start_t *)mp->b_cont->b_rptr;
418 418 arg->si_slp = slp;
419 419 miocack(wq, mp, sizeof (*arg), 0);
420 420 break;
421 421 }
422 422 default:
423 423 miocnak(wq, mp, 0, EINVAL);
424 424 break;
425 425 }
426 426 break;
427 427 }
428 428 default:
429 429 freemsg(mp);
430 430 break;
431 431 }
432 432 }
433 433
434 434 static void
435 435 softmac_mod_wsrv(queue_t *wq)
436 436 {
437 437 softmac_lower_t *slp = wq->q_ptr;
438 438
439 439 /*
440 440 * This is the softmac module
441 441 */
442 442 ASSERT(wq->q_next != NULL);
443 443
444 444 /*
445 445 * Inform that the tx resource is available; mac_tx_update() will
446 446 * inform all the upper streams sharing this lower stream.
447 447 */
448 448 if (slp->sl_sup != NULL)
449 449 qenable(slp->sl_sup->su_wq);
450 450 else if (slp->sl_softmac != NULL)
451 451 mac_tx_update(slp->sl_softmac->smac_mh);
452 452 }
453 453
454 454 static int
455 455 softmac_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
456 456 {
457 457 ASSERT(ddi_get_instance(dip) == 0);
458 458
459 459 if (cmd != DDI_ATTACH)
460 460 return (DDI_FAILURE);
461 461
462 462 softmac_dip = dip;
463 463
464 464 return (DDI_SUCCESS);
465 465 }
466 466
467 467 /* ARGSUSED */
468 468 static int
469 469 softmac_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
470 470 {
471 471 if (cmd != DDI_DETACH)
472 472 return (DDI_FAILURE);
473 473
474 474 softmac_dip = NULL;
475 475 return (DDI_SUCCESS);
476 476 }
477 477
478 478 /* ARGSUSED */
479 479 static int
480 480 softmac_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
481 481 {
482 482 switch (infocmd) {
483 483 case DDI_INFO_DEVT2DEVINFO:
484 484 if (softmac_dip != NULL) {
485 485 *result = softmac_dip;
486 486 return (DDI_SUCCESS);
487 487 }
488 488 break;
489 489
490 490 case DDI_INFO_DEVT2INSTANCE:
491 491 *result = NULL;
492 492 return (DDI_SUCCESS);
493 493
494 494 }
495 495
496 496 return (DDI_FAILURE);
497 497 }
498 498
499 499 /*ARGSUSED*/
500 500 static void
501 501 softmac_dedicated_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
502 502 mac_header_info_t *mhip)
503 503 {
504 504 queue_t *rq = ((softmac_upper_t *)arg)->su_rq;
505 505
506 506 if (canputnext(rq))
507 507 putnext(rq, mp);
508 508 else
509 509 freemsg(mp);
510 510 }
511 511
512 512 /*ARGSUSED*/
513 513 static int
514 514 softmac_drv_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
515 515 {
516 516 softmac_upper_t *sup = NULL;
517 517 softmac_t *softmac;
518 518 int err = 0;
519 519
520 520 /*
521 521 * This is a softmac device created for a legacy device, find the
522 522 * associated softmac and initialize the softmac_upper_t structure.
523 523 */
524 524 if ((err = softmac_hold(*devp, &softmac)) != 0)
525 525 return (err);
526 526
527 527 sup = kmem_cache_alloc(softmac_upper_cachep, KM_NOSLEEP);
528 528 if (sup == NULL) {
529 529 err = ENOMEM;
530 530 goto fail;
531 531 }
532 532
533 533 ASSERT(list_is_empty(&sup->su_req_list));
534 534
535 535 if ((sup->su_tx_flow_mp = allocb(1, BPRI_HI)) == NULL) {
536 536 err = ENOMEM;
537 537 goto fail;
538 538 }
539 539
540 540 sup->su_rq = rq;
541 541 sup->su_wq = WR(rq);
542 542 sup->su_softmac = softmac;
543 543 sup->su_mode = SOFTMAC_UNKNOWN;
544 544
545 545 sup->su_rxinfo.slr_arg = sup;
546 546 sup->su_rxinfo.slr_rx = softmac_dedicated_rx;
547 547 sup->su_direct_rxinfo.slr_arg = sup;
548 548 sup->su_direct_rxinfo.slr_rx = softmac_dedicated_rx;
549 549
550 550 if ((err = dld_str_open(rq, devp, sup)) != 0) {
551 551 freeb(sup->su_tx_flow_mp);
552 552 sup->su_tx_flow_mp = NULL;
553 553 goto fail;
554 554 }
555 555
556 556 return (0);
557 557
558 558 fail:
559 559 if (sup != NULL)
560 560 kmem_cache_free(softmac_upper_cachep, sup);
561 561 softmac_rele(softmac);
562 562 return (err);
563 563 }
564 564
565 565 static int
566 566 softmac_drv_close(queue_t *rq)
567 567 {
568 568 softmac_upper_t *sup = dld_str_private(rq);
569 569 softmac_t *softmac = sup->su_softmac;
570 570
571 571 ASSERT(WR(rq)->q_next == NULL);
572 572
573 573 qprocsoff(rq);
574 574
575 575 ASSERT(sup->su_tx_inprocess == 0);
576 576
577 577 /*
578 578 * Wait until the pending request are processed by the worker thread.
579 579 */
580 580 mutex_enter(&sup->su_disp_mutex);
581 581 sup->su_closing = B_TRUE;
582 582 while (sup->su_dlpi_pending)
583 583 cv_wait(&sup->su_disp_cv, &sup->su_disp_mutex);
584 584 mutex_exit(&sup->su_disp_mutex);
585 585
586 586 softmac_upperstream_close(sup);
587 587
588 588 if (sup->su_tx_flow_mp != NULL) {
589 589 freeb(sup->su_tx_flow_mp);
590 590 sup->su_tx_flow_mp = NULL;
591 591 }
592 592
593 593 if (sup->su_active) {
594 594 mutex_enter(&softmac->smac_active_mutex);
595 595 softmac->smac_nactive--;
596 596 mutex_exit(&softmac->smac_active_mutex);
597 597 sup->su_active = B_FALSE;
598 598 }
599 599
600 600 sup->su_bound = B_FALSE;
601 601 sup->su_softmac = NULL;
602 602 sup->su_closing = B_FALSE;
603 603
604 604 kmem_cache_free(softmac_upper_cachep, sup);
605 605
606 606 softmac_rele(softmac);
607 607 return (dld_str_close(rq));
608 608 }
609 609
610 610 static void
611 611 softmac_drv_wput(queue_t *wq, mblk_t *mp)
612 612 {
613 613 softmac_upper_t *sup = dld_str_private(wq);
614 614 t_uscalar_t prim;
615 615
616 616 ASSERT(wq->q_next == NULL);
617 617
618 618 switch (DB_TYPE(mp)) {
619 619 case M_DATA:
620 620 case M_MULTIDATA:
621 621 softmac_wput_data(sup, mp);
622 622 break;
623 623 case M_PROTO:
624 624 case M_PCPROTO:
625 625
626 626 if (MBLKL(mp) < sizeof (t_uscalar_t)) {
627 627 freemsg(mp);
628 628 return;
629 629 }
630 630
631 631 prim = ((union DL_primitives *)mp->b_rptr)->dl_primitive;
632 632 if (prim == DL_UNITDATA_REQ) {
633 633 softmac_wput_data(sup, mp);
634 634 return;
635 635 }
636 636
637 637 softmac_wput_nondata(sup, mp);
638 638 break;
639 639 default:
640 640 softmac_wput_nondata(sup, mp);
641 641 break;
642 642 }
643 643 }
644 644
645 645 static void
646 646 softmac_drv_wsrv(queue_t *wq)
647 647 {
648 648 softmac_upper_t *sup = dld_str_private(wq);
649 649
650 650 ASSERT(wq->q_next == NULL);
651 651
652 652 mutex_enter(&sup->su_mutex);
653 653 if (sup->su_mode != SOFTMAC_FASTPATH) {
654 654 /*
655 655 * Bump su_tx_inprocess so that su_mode won't change.
656 656 */
657 657 sup->su_tx_inprocess++;
658 658 mutex_exit(&sup->su_mutex);
659 659 dld_wsrv(wq);
660 660 mutex_enter(&sup->su_mutex);
661 661 if (--sup->su_tx_inprocess == 0)
662 662 cv_signal(&sup->su_cv);
663 663 } else if (sup->su_tx_busy && SOFTMAC_CANPUTNEXT(sup->su_slp->sl_wq)) {
664 664 /*
665 665 * The flow-conctol of the dedicated-lower-stream is
666 666 * relieved. If DLD_CAPAB_DIRECT is enabled, call tx_notify
667 667 * callback to relieve the flow-control of the specific client,
668 668 * otherwise relieve the flow-control of all the upper-stream
669 669 * using the traditional STREAM mechanism.
670 670 */
671 671 if (sup->su_tx_notify_func != NULL) {
672 672 sup->su_tx_inprocess++;
673 673 mutex_exit(&sup->su_mutex);
674 674 sup->su_tx_notify_func(sup->su_tx_notify_arg,
675 675 (mac_tx_cookie_t)sup);
676 676 mutex_enter(&sup->su_mutex);
677 677 if (--sup->su_tx_inprocess == 0)
678 678 cv_signal(&sup->su_cv);
679 679 }
680 680 ASSERT(sup->su_tx_flow_mp == NULL);
681 681 VERIFY((sup->su_tx_flow_mp = getq(wq)) != NULL);
682 682 sup->su_tx_busy = B_FALSE;
683 683 }
684 684 mutex_exit(&sup->su_mutex);
685 685 }
↓ open down ↓ |
529 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX