d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER START
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * The contents of this file are subject to the terms of the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Common Development and Distribution License (the "License").
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You may not use this file except in compliance with the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * or http://www.opensolaris.org/os/licensing.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * See the License for the specific language governing permissions
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * and limitations under the License.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * When distributing Covered Code, include this CDDL HEADER in each
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * If applicable, add the following below this CDDL HEADER, with the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * fields enclosed by brackets "[]" replaced with your own identifying
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * information: Portions Copyright [yyyy] [name of copyright owner]
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * CDDL HEADER END
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Use is subject to license terms.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/types.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <inet/common.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/stropts.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/modctl.h>
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou#include <sys/dld.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz#include <sys/softmac_impl.h>
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzdev_info_t *softmac_dip = NULL;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic kmem_cache_t *softmac_upper_cachep;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * This function is a generic open(9E) entry point into the softmac for
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * both the softmac module and the softmac driver.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int softmac_cmn_open(queue_t *, dev_t *, int, int, cred_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * The following softmac_mod_xxx() functions are (9E) entry point functions for
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * the softmac module.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int softmac_mod_close(queue_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void softmac_mod_rput(queue_t *, mblk_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void softmac_mod_wput(queue_t *, mblk_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void softmac_mod_wsrv(queue_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * The following softmac_drv_xxx() functions are (9E) entry point functions for
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * the softmac driver.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int softmac_drv_open(queue_t *, dev_t *, int, int, cred_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int softmac_drv_close(queue_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void softmac_drv_wput(queue_t *, mblk_t *);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void softmac_drv_wsrv(queue_t *);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int softmac_attach(dev_info_t *, ddi_attach_cmd_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int softmac_detach(dev_info_t *, ddi_detach_cmd_t);
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int softmac_info(dev_info_t *, ddi_info_cmd_t, void *, void **);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct module_info softmac_modinfo = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz SOFTMAC_DEV_NAME,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz INFPSZ,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 65536,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 1024
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * hi-water mark is 1 because of the flow control mechanism implemented in
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * dld. Refer to the comments in dld_str.c for details.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct module_info softmac_dld_modinfo = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz SOFTMAC_DEV_NAME,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz INFPSZ,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz 0
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct qinit softmac_urinit = {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou (pfi_t)softmac_mod_rput, /* qi_putp */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou (pfi_t)NULL, /* qi_srvp */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_cmn_open, /* qi_qopen */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_mod_close, /* qi_qclose */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou NULL, /* qi_qadmin */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou &softmac_modinfo /* qi_minfo */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct qinit softmac_uwinit = {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou (pfi_t)softmac_mod_wput, /* qi_putp */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou (pfi_t)softmac_mod_wsrv, /* qi_srvp */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou NULL, /* qi_qopen */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou NULL, /* qi_qclose */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou NULL, /* qi_qadmin */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou &softmac_modinfo /* qi_minfo */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct streamtab softmac_tab = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_urinit, /* st_rdinit */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_uwinit /* st_wrinit */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzDDI_DEFINE_STREAM_OPS(softmac_ops, nulldev, nulldev, softmac_attach,
193974072f41a843678abf5f61979c748687e66bSherry Moore softmac_detach, nodev, softmac_info, D_MP, &softmac_tab,
193974072f41a843678abf5f61979c748687e66bSherry Moore ddi_quiesce_not_supported);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct qinit softmac_dld_r_qinit = {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou NULL, NULL, softmac_drv_open, softmac_drv_close, NULL,
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou &softmac_dld_modinfo
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct qinit softmac_dld_w_qinit = {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou (pfi_t)softmac_drv_wput, (pfi_t)softmac_drv_wsrv, NULL, NULL, NULL,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_dld_modinfo
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct fmodsw softmac_fmodsw = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz SOFTMAC_DEV_NAME,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_tab,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz D_MP
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct modldrv softmac_modldrv = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &mod_driverops,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "softmac driver",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_ops
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct modlstrmod softmac_modlstrmod = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &mod_strmodops,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz "softmac module",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_fmodsw
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic struct modlinkage softmac_modlinkage = {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz MODREV_1,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_modlstrmod,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz &softmac_modldrv,
d62bc4badc1c1f1549c961cfb8b420e650e1272byz NULL
d62bc4badc1c1f1549c961cfb8b420e650e1272byz};
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmarkstatic void softmac_dedicated_rx(void *, mac_resource_handle_t, mblk_t *,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark mac_header_info_t *);
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*ARGSUSED*/
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_upper_constructor(void *buf, void *arg, int kmflag)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = buf;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou bzero(buf, sizeof (softmac_upper_t));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_init(&sup->su_mutex, NULL, MUTEX_DEFAULT, NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_init(&sup->su_cv, NULL, CV_DEFAULT, NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_init(&sup->su_disp_mutex, NULL, MUTEX_DEFAULT, NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_init(&sup->su_disp_cv, NULL, CV_DEFAULT, NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou list_create(&sup->su_req_list, sizeof (softmac_switch_req_t),
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou offsetof(softmac_switch_req_t, ssq_req_list_node));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (0);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*ARGSUSED*/
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_upper_destructor(void *buf, void *arg)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = buf;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_slp == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_pending_head == NULL && sup->su_pending_tail == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_dlpi_pending);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_active);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_closing);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_tx_flow_mp == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_tx_inprocess == 0);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_mode == SOFTMAC_UNKNOWN);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_tx_busy);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_bound);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(!sup->su_taskq_scheduled);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou ASSERT(sup->su_tx_notify_func == NULL);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou ASSERT(sup->su_tx_notify_arg == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(list_is_empty(&sup->su_req_list));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou list_destroy(&sup->su_req_list);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_destroy(&sup->su_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_destroy(&sup->su_cv);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_destroy(&sup->su_disp_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_destroy(&sup->su_disp_cv);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
d62bc4badc1c1f1549c961cfb8b420e650e1272byz_init(void)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
ee94b1c37a34b758315666dcd0bc7c46d1aea15cSebastien Roy mac_init_ops(NULL, SOFTMAC_DEV_NAME);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_init();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_cachep = kmem_cache_create("softmac_upper_cache",
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sizeof (softmac_upper_t), 0, softmac_upper_constructor,
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_destructor, NULL, NULL, NULL, 0);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(softmac_upper_cachep != NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((err = mod_install(&softmac_modlinkage)) != 0) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_fini();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
d62bc4badc1c1f1549c961cfb8b420e650e1272byz_fini(void)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz int err;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (softmac_busy())
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (EBUSY);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((err = mod_remove(&softmac_modlinkage)) != 0)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (err);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou kmem_cache_destroy(softmac_upper_cachep);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_fini();
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzint
d62bc4badc1c1f1549c961cfb8b420e650e1272byz_info(struct modinfo *modinfop)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (mod_info(&softmac_modlinkage, modinfop));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_cmn_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_lower_t *slp;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is a self-cloning driver so that each queue should only
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * get opened once.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (rq->q_ptr != NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (EBUSY);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (sflag == MODOPEN) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is the softmac module pushed over an underlying
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * legacy device. Initialize the lower structure.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if ((slp = kmem_zalloc(sizeof (*slp), KM_NOSLEEP)) == NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (ENOMEM);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz slp->sl_wq = WR(rq);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cv_init(&slp->sl_cv, NULL, CV_DRIVER, NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mutex_init(&slp->sl_mutex, NULL, MUTEX_DRIVER, NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz slp->sl_pending_prim = DL_PRIM_INVAL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rq->q_ptr = WR(rq)->q_ptr = slp;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz qprocson(rq);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Regular device open of a softmac DLPI node. We modify
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * the queues' q_qinfo pointer such that all future STREAMS
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * operations will go through another set of entry points
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz rq->q_qinfo = &softmac_dld_r_qinit;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz WR(rq)->q_qinfo = &softmac_dld_w_qinit;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (softmac_drv_open(rq, devp, flag, sflag, credp));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_mod_close(queue_t *rq)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_lower_t *slp = rq->q_ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Call the appropriate delete routine depending on whether this is
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * a module or device.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(WR(rq)->q_next != NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz qprocsoff(rq);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz slp->sl_softmac = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz slp->sl_lh = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(slp->sl_ack_mp == NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(slp->sl_pending_prim == DL_PRIM_INVAL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(slp->sl_pending_ioctl == B_FALSE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cv_destroy(&slp->sl_cv);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mutex_destroy(&slp->sl_mutex);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz kmem_free(slp, sizeof (*slp));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_mod_rput(queue_t *rq, mblk_t *mp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_lower_t *slp = rq->q_ptr;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_lower_rxinfo_t *rxinfo;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou union DL_primitives *dlp;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is the softmac module.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(WR(rq)->q_next != NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT((mp->b_next == NULL) && (mp->b_prev == NULL));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz switch (DB_TYPE(mp)) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou case M_DATA: {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * If sl_rxinfo is non-NULL. This is dedicated-lower-stream
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * created for fastpath. Directly call the rx callback.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if ((rxinfo = slp->sl_rxinfo) != NULL) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou rxinfo->slr_rx(rxinfo->slr_arg, NULL, mp, NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * A shared-lower-stream. Some driver starts to send up
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * packets even it not in the DL_IDLE state, where
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * sl_softmac is not set yet. Drop the packet in this case.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (slp->sl_softmac == NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz freemsg(mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng /*
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * If this message is looped back from the legacy devices,
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * drop it as the Nemo framework will be responsible for
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng * looping it back by the mac_txloop() function.
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng */
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng if (mp->b_flag & MSGNOLOOP) {
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng freemsg(mp);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng return;
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng }
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is the most common case.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (DB_REF(mp) == 1) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(slp->sl_softmac != NULL);
da14cebe459d3275048785f25bd869cb09b5307fEric Cheng mac_rx(slp->sl_softmac->smac_mh, NULL, mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz } else {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_rput_process_data(slp, mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case M_PROTO:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case M_PCPROTO:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (MBLKL(mp) < sizeof (dlp->dl_primitive)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz freemsg(mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dlp = (union DL_primitives *)mp->b_rptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (dlp->dl_primitive == DL_UNITDATA_IND) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if ((rxinfo = slp->sl_rxinfo) != NULL) {
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark softmac_dedicated_rx(slp->sl_sup, NULL, mp,
bd670b35a010421b6e1a5536c34453a827007c81Erik Nordmark NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
d62bc4badc1c1f1549c961cfb8b420e650e1272byz cmn_err(CE_WARN, "got unexpected %s message",
d62bc4badc1c1f1549c961cfb8b420e650e1272byz dl_primstr(DL_UNITDATA_IND));
d62bc4badc1c1f1549c961cfb8b420e650e1272byz freemsg(mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*FALLTHROUGH*/
d62bc4badc1c1f1549c961cfb8b420e650e1272byz default:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_rput_process_notdata(rq, slp->sl_sup, mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_mod_wput(queue_t *wq, mblk_t *mp)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is the softmac module
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(wq->q_next != NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz switch (DB_TYPE(mp)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case M_IOCTL: {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz struct iocblk *ioc = (struct iocblk *)mp->b_rptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz switch (ioc->ioc_cmd) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case SMAC_IOC_START: {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_lower_t *slp = wq->q_ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz smac_ioc_start_t *arg;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (ioc->ioc_count != sizeof (*arg)) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz miocnak(wq, mp, 0, EINVAL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Assign the devname and perstream handle of the
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * specific lower stream and return it as a part
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * of the ioctl.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz arg = (smac_ioc_start_t *)mp->b_cont->b_rptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz arg->si_slp = slp;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz miocack(wq, mp, sizeof (*arg), 0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz default:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz miocnak(wq, mp, 0, EINVAL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz default:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz freemsg(mp);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_mod_wsrv(queue_t *wq)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_lower_t *slp = wq->q_ptr;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * This is the softmac module
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(wq->q_next != NULL);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz /*
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * Inform that the tx resource is available; mac_tx_update() will
d62bc4badc1c1f1549c961cfb8b420e650e1272byz * inform all the upper streams sharing this lower stream.
d62bc4badc1c1f1549c961cfb8b420e650e1272byz */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (slp->sl_sup != NULL)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou qenable(slp->sl_sup->su_wq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou else if (slp->sl_softmac != NULL)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz mac_tx_update(slp->sl_softmac->smac_mh);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzsoftmac_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz ASSERT(ddi_get_instance(dip) == 0);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (cmd != DDI_ATTACH)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_dip = dip;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* ARGSUSED */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzsoftmac_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (cmd != DDI_DETACH)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz softmac_dip = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz/* ARGSUSED */
d62bc4badc1c1f1549c961cfb8b420e650e1272byzstatic int
d62bc4badc1c1f1549c961cfb8b420e650e1272byzsoftmac_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
d62bc4badc1c1f1549c961cfb8b420e650e1272byz{
d62bc4badc1c1f1549c961cfb8b420e650e1272byz switch (infocmd) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case DDI_INFO_DEVT2DEVINFO:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz if (softmac_dip != NULL) {
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *result = softmac_dip;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz break;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz case DDI_INFO_DEVT2INSTANCE:
d62bc4badc1c1f1549c961cfb8b420e650e1272byz *result = NULL;
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_SUCCESS);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz }
d62bc4badc1c1f1549c961cfb8b420e650e1272byz
d62bc4badc1c1f1549c961cfb8b420e650e1272byz return (DDI_FAILURE);
d62bc4badc1c1f1549c961cfb8b420e650e1272byz}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*ARGSUSED*/
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_dedicated_rx(void *arg, mac_resource_handle_t mrh, mblk_t *mp,
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mac_header_info_t *mhip)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou queue_t *rq = ((softmac_upper_t *)arg)->su_rq;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (canputnext(rq))
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou putnext(rq, mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou else
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou freemsg(mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou/*ARGSUSED*/
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_drv_open(queue_t *rq, dev_t *devp, int flag, int sflag, cred_t *credp)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = NULL;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_t *softmac;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou int err = 0;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * This is a softmac device created for a legacy device, find the
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * associated softmac and initialize the softmac_upper_t structure.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if ((err = softmac_hold(*devp, &softmac)) != 0)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (err);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup = kmem_cache_alloc(softmac_upper_cachep, KM_NOSLEEP);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (sup == NULL) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou err = ENOMEM;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou goto fail;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(list_is_empty(&sup->su_req_list));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if ((sup->su_tx_flow_mp = allocb(1, BPRI_HI)) == NULL) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou err = ENOMEM;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou goto fail;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_rq = rq;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_wq = WR(rq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_softmac = softmac;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_mode = SOFTMAC_UNKNOWN;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_rxinfo.slr_arg = sup;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_rxinfo.slr_rx = softmac_dedicated_rx;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_direct_rxinfo.slr_arg = sup;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_direct_rxinfo.slr_rx = softmac_dedicated_rx;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if ((err = dld_str_open(rq, devp, sup)) != 0) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou freeb(sup->su_tx_flow_mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_tx_flow_mp = NULL;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou goto fail;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (0);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoufail:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (sup != NULL)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou kmem_cache_free(softmac_upper_cachep, sup);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_rele(softmac);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (err);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic int
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_drv_close(queue_t *rq)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = dld_str_private(rq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_t *softmac = sup->su_softmac;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(WR(rq)->q_next == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou qprocsoff(rq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(sup->su_tx_inprocess == 0);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * Wait until the pending request are processed by the worker thread.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_enter(&sup->su_disp_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_closing = B_TRUE;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou while (sup->su_dlpi_pending)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_wait(&sup->su_disp_cv, &sup->su_disp_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_exit(&sup->su_disp_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upperstream_close(sup);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (sup->su_tx_flow_mp != NULL) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou freeb(sup->su_tx_flow_mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_tx_flow_mp = NULL;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (sup->su_active) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_enter(&softmac->smac_active_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac->smac_nactive--;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_exit(&softmac->smac_active_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_active = B_FALSE;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_bound = B_FALSE;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_softmac = NULL;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_closing = B_FALSE;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou kmem_cache_free(softmac_upper_cachep, sup);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_rele(softmac);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return (dld_str_close(rq));
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_drv_wput(queue_t *wq, mblk_t *mp)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = dld_str_private(wq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou t_uscalar_t prim;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(wq->q_next == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou switch (DB_TYPE(mp)) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou case M_DATA:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou case M_MULTIDATA:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_wput_data(sup, mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou case M_PROTO:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou case M_PCPROTO:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (MBLKL(mp) < sizeof (t_uscalar_t)) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou freemsg(mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou prim = ((union DL_primitives *)mp->b_rptr)->dl_primitive;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (prim == DL_UNITDATA_REQ) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_wput_data(sup, mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou return;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_wput_nondata(sup, mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou default:
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_wput_nondata(sup, mp);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou break;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhoustatic void
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhousoftmac_drv_wsrv(queue_t *wq)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou{
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou softmac_upper_t *sup = dld_str_private(wq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou ASSERT(wq->q_next == NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_enter(&sup->su_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (sup->su_mode != SOFTMAC_FASTPATH) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * Bump su_tx_inprocess so that su_mode won't change.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_tx_inprocess++;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_exit(&sup->su_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou dld_wsrv(wq);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_enter(&sup->su_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou if (--sup->su_tx_inprocess == 0)
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou cv_signal(&sup->su_cv);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou } else if (sup->su_tx_busy && SOFTMAC_CANPUTNEXT(sup->su_slp->sl_wq)) {
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou /*
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou * The flow-conctol of the dedicated-lower-stream is
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou * relieved. If DLD_CAPAB_DIRECT is enabled, call tx_notify
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou * callback to relieve the flow-control of the specific client,
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou * otherwise relieve the flow-control of all the upper-stream
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou * using the traditional STREAM mechanism.
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou */
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou if (sup->su_tx_notify_func != NULL) {
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou sup->su_tx_inprocess++;
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou mutex_exit(&sup->su_mutex);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou sup->su_tx_notify_func(sup->su_tx_notify_arg,
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou (mac_tx_cookie_t)sup);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou mutex_enter(&sup->su_mutex);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou if (--sup->su_tx_inprocess == 0)
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou cv_signal(&sup->su_cv);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou }
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou ASSERT(sup->su_tx_flow_mp == NULL);
79eeb64527c881659e23b60088c32ae3736a7a2cCathy Zhou VERIFY((sup->su_tx_flow_mp = getq(wq)) != NULL);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou sup->su_tx_busy = B_FALSE;
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou }
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou mutex_exit(&sup->su_mutex);
5d460eafffba936e81c4dd5ebe0f59b238f09121Cathy Zhou}