xref: /linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c (revision 976e3645923bdd2fe7893aae33fd7a21098bfb28)
1daeccac2SArend van Spriel // SPDX-License-Identifier: ISC
205491d2cSKalle Valo /*
305491d2cSKalle Valo  * Copyright (c) 2013 Broadcom Corporation
405491d2cSKalle Valo  */
505491d2cSKalle Valo 
605491d2cSKalle Valo 
705491d2cSKalle Valo  #include <linux/types.h>
805491d2cSKalle Valo #include <linux/slab.h>
905491d2cSKalle Valo #include <linux/netdevice.h>
1005491d2cSKalle Valo 
1105491d2cSKalle Valo #include <brcmu_wifi.h>
1205491d2cSKalle Valo #include "core.h"
1305491d2cSKalle Valo #include "bus.h"
1405491d2cSKalle Valo #include "debug.h"
1505491d2cSKalle Valo #include "proto.h"
1605491d2cSKalle Valo #include "bcdc.h"
1705491d2cSKalle Valo #include "msgbuf.h"
1805491d2cSKalle Valo 
1905491d2cSKalle Valo 
brcmf_proto_attach(struct brcmf_pub * drvr)2005491d2cSKalle Valo int brcmf_proto_attach(struct brcmf_pub *drvr)
2105491d2cSKalle Valo {
2205491d2cSKalle Valo 	struct brcmf_proto *proto;
2305491d2cSKalle Valo 
2405491d2cSKalle Valo 	brcmf_dbg(TRACE, "Enter\n");
2505491d2cSKalle Valo 
2605491d2cSKalle Valo 	proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
2705491d2cSKalle Valo 	if (!proto)
2805491d2cSKalle Valo 		goto fail;
2905491d2cSKalle Valo 
3005491d2cSKalle Valo 	drvr->proto = proto;
3105491d2cSKalle Valo 
3205491d2cSKalle Valo 	if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) {
3305491d2cSKalle Valo 		if (brcmf_proto_bcdc_attach(drvr))
3405491d2cSKalle Valo 			goto fail;
3505491d2cSKalle Valo 	} else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) {
3605491d2cSKalle Valo 		if (brcmf_proto_msgbuf_attach(drvr))
3705491d2cSKalle Valo 			goto fail;
3805491d2cSKalle Valo 	} else {
39dcb1471bSRafał Miłecki 		bphy_err(drvr, "Unsupported proto type %d\n",
4005491d2cSKalle Valo 			 drvr->bus_if->proto_type);
4105491d2cSKalle Valo 		goto fail;
4205491d2cSKalle Valo 	}
43b073ac1fSRafał Miłecki 	if (!proto->tx_queue_data || (proto->hdrpull == NULL) ||
4405491d2cSKalle Valo 	    (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) ||
4505491d2cSKalle Valo 	    (proto->configure_addr_mode == NULL) ||
4634789d0cSArend Van Spriel 	    (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) ||
4734789d0cSArend Van Spriel 	    (proto->debugfs_create == NULL)) {
48dcb1471bSRafał Miłecki 		bphy_err(drvr, "Not all proto handlers have been installed\n");
4905491d2cSKalle Valo 		goto fail;
5005491d2cSKalle Valo 	}
5105491d2cSKalle Valo 	return 0;
5205491d2cSKalle Valo 
5305491d2cSKalle Valo fail:
5405491d2cSKalle Valo 	kfree(proto);
5505491d2cSKalle Valo 	drvr->proto = NULL;
5605491d2cSKalle Valo 	return -ENOMEM;
5705491d2cSKalle Valo }
5805491d2cSKalle Valo 
brcmf_proto_detach(struct brcmf_pub * drvr)59*a84a60ccSArend van Spriel void brcmf_proto_detach(struct brcmf_pub *drvr)
6005491d2cSKalle Valo {
6105491d2cSKalle Valo 	brcmf_dbg(TRACE, "Enter\n");
6205491d2cSKalle Valo 
6305491d2cSKalle Valo 	if (drvr->proto) {
6405491d2cSKalle Valo 		if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
65*a84a60ccSArend van Spriel 			brcmf_proto_bcdc_detach(drvr);
6605491d2cSKalle Valo 		else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF)
6705491d2cSKalle Valo 			brcmf_proto_msgbuf_detach(drvr);
6805491d2cSKalle Valo 		kfree(drvr->proto);
6905491d2cSKalle Valo 		drvr->proto = NULL;
7005491d2cSKalle Valo 	}
7105491d2cSKalle Valo }
72