xref: /freebsd/sys/contrib/dev/broadcom/brcm80211/brcmfmac/proto.c (revision b4c3e9b5b09c829b4135aff738bd2893ed052377)
1*b4c3e9b5SBjoern A. Zeeb // SPDX-License-Identifier: ISC
2*b4c3e9b5SBjoern A. Zeeb /*
3*b4c3e9b5SBjoern A. Zeeb  * Copyright (c) 2013 Broadcom Corporation
4*b4c3e9b5SBjoern A. Zeeb  */
5*b4c3e9b5SBjoern A. Zeeb 
6*b4c3e9b5SBjoern A. Zeeb 
7*b4c3e9b5SBjoern A. Zeeb  #include <linux/types.h>
8*b4c3e9b5SBjoern A. Zeeb #include <linux/slab.h>
9*b4c3e9b5SBjoern A. Zeeb #include <linux/netdevice.h>
10*b4c3e9b5SBjoern A. Zeeb 
11*b4c3e9b5SBjoern A. Zeeb #include <brcmu_wifi.h>
12*b4c3e9b5SBjoern A. Zeeb #include "core.h"
13*b4c3e9b5SBjoern A. Zeeb #include "bus.h"
14*b4c3e9b5SBjoern A. Zeeb #include "debug.h"
15*b4c3e9b5SBjoern A. Zeeb #include "proto.h"
16*b4c3e9b5SBjoern A. Zeeb #include "bcdc.h"
17*b4c3e9b5SBjoern A. Zeeb #include "msgbuf.h"
18*b4c3e9b5SBjoern A. Zeeb 
19*b4c3e9b5SBjoern A. Zeeb 
brcmf_proto_attach(struct brcmf_pub * drvr)20*b4c3e9b5SBjoern A. Zeeb int brcmf_proto_attach(struct brcmf_pub *drvr)
21*b4c3e9b5SBjoern A. Zeeb {
22*b4c3e9b5SBjoern A. Zeeb 	struct brcmf_proto *proto;
23*b4c3e9b5SBjoern A. Zeeb 
24*b4c3e9b5SBjoern A. Zeeb 	brcmf_dbg(TRACE, "Enter\n");
25*b4c3e9b5SBjoern A. Zeeb 
26*b4c3e9b5SBjoern A. Zeeb 	proto = kzalloc(sizeof(*proto), GFP_ATOMIC);
27*b4c3e9b5SBjoern A. Zeeb 	if (!proto)
28*b4c3e9b5SBjoern A. Zeeb 		goto fail;
29*b4c3e9b5SBjoern A. Zeeb 
30*b4c3e9b5SBjoern A. Zeeb 	drvr->proto = proto;
31*b4c3e9b5SBjoern A. Zeeb 
32*b4c3e9b5SBjoern A. Zeeb 	if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) {
33*b4c3e9b5SBjoern A. Zeeb 		if (brcmf_proto_bcdc_attach(drvr))
34*b4c3e9b5SBjoern A. Zeeb 			goto fail;
35*b4c3e9b5SBjoern A. Zeeb 	} else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) {
36*b4c3e9b5SBjoern A. Zeeb 		if (brcmf_proto_msgbuf_attach(drvr))
37*b4c3e9b5SBjoern A. Zeeb 			goto fail;
38*b4c3e9b5SBjoern A. Zeeb 	} else {
39*b4c3e9b5SBjoern A. Zeeb 		bphy_err(drvr, "Unsupported proto type %d\n",
40*b4c3e9b5SBjoern A. Zeeb 			 drvr->bus_if->proto_type);
41*b4c3e9b5SBjoern A. Zeeb 		goto fail;
42*b4c3e9b5SBjoern A. Zeeb 	}
43*b4c3e9b5SBjoern A. Zeeb 	if (!proto->tx_queue_data || (proto->hdrpull == NULL) ||
44*b4c3e9b5SBjoern A. Zeeb 	    (proto->query_dcmd == NULL) || (proto->set_dcmd == NULL) ||
45*b4c3e9b5SBjoern A. Zeeb 	    (proto->configure_addr_mode == NULL) ||
46*b4c3e9b5SBjoern A. Zeeb 	    (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) ||
47*b4c3e9b5SBjoern A. Zeeb 	    (proto->debugfs_create == NULL)) {
48*b4c3e9b5SBjoern A. Zeeb 		bphy_err(drvr, "Not all proto handlers have been installed\n");
49*b4c3e9b5SBjoern A. Zeeb 		goto fail;
50*b4c3e9b5SBjoern A. Zeeb 	}
51*b4c3e9b5SBjoern A. Zeeb 	return 0;
52*b4c3e9b5SBjoern A. Zeeb 
53*b4c3e9b5SBjoern A. Zeeb fail:
54*b4c3e9b5SBjoern A. Zeeb 	kfree(proto);
55*b4c3e9b5SBjoern A. Zeeb 	drvr->proto = NULL;
56*b4c3e9b5SBjoern A. Zeeb 	return -ENOMEM;
57*b4c3e9b5SBjoern A. Zeeb }
58*b4c3e9b5SBjoern A. Zeeb 
brcmf_proto_detach(struct brcmf_pub * drvr)59*b4c3e9b5SBjoern A. Zeeb void brcmf_proto_detach(struct brcmf_pub *drvr)
60*b4c3e9b5SBjoern A. Zeeb {
61*b4c3e9b5SBjoern A. Zeeb 	brcmf_dbg(TRACE, "Enter\n");
62*b4c3e9b5SBjoern A. Zeeb 
63*b4c3e9b5SBjoern A. Zeeb 	if (drvr->proto) {
64*b4c3e9b5SBjoern A. Zeeb 		if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
65*b4c3e9b5SBjoern A. Zeeb 			brcmf_proto_bcdc_detach(drvr);
66*b4c3e9b5SBjoern A. Zeeb 		else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF)
67*b4c3e9b5SBjoern A. Zeeb 			brcmf_proto_msgbuf_detach(drvr);
68*b4c3e9b5SBjoern A. Zeeb 		kfree(drvr->proto);
69*b4c3e9b5SBjoern A. Zeeb 		drvr->proto = NULL;
70*b4c3e9b5SBjoern A. Zeeb 	}
71*b4c3e9b5SBjoern A. Zeeb }
72