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