linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c
<<
>>
Prefs
   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_post_delif(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_post_delif(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
  73void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr)
  74{
  75        if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC)
  76                brcmf_proto_bcdc_detach_pre_delif(drvr);
  77}
  78