Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Link Layer Control manager
0004  *
0005  * Copyright (C) 2012  Intel Corporation. All rights reserved.
0006  */
0007 
0008 #include <net/nfc/llc.h>
0009 
0010 #include "llc.h"
0011 
0012 static LIST_HEAD(llc_engines);
0013 
0014 int __init nfc_llc_init(void)
0015 {
0016     int r;
0017 
0018     r = nfc_llc_nop_register();
0019     if (r)
0020         goto exit;
0021 
0022     r = nfc_llc_shdlc_register();
0023     if (r)
0024         goto exit;
0025 
0026     return 0;
0027 
0028 exit:
0029     nfc_llc_exit();
0030     return r;
0031 }
0032 
0033 void nfc_llc_exit(void)
0034 {
0035     struct nfc_llc_engine *llc_engine, *n;
0036 
0037     list_for_each_entry_safe(llc_engine, n, &llc_engines, entry) {
0038         list_del(&llc_engine->entry);
0039         kfree(llc_engine->name);
0040         kfree(llc_engine);
0041     }
0042 }
0043 
0044 int nfc_llc_register(const char *name, const struct nfc_llc_ops *ops)
0045 {
0046     struct nfc_llc_engine *llc_engine;
0047 
0048     llc_engine = kzalloc(sizeof(struct nfc_llc_engine), GFP_KERNEL);
0049     if (llc_engine == NULL)
0050         return -ENOMEM;
0051 
0052     llc_engine->name = kstrdup(name, GFP_KERNEL);
0053     if (llc_engine->name == NULL) {
0054         kfree(llc_engine);
0055         return -ENOMEM;
0056     }
0057     llc_engine->ops = ops;
0058 
0059     INIT_LIST_HEAD(&llc_engine->entry);
0060     list_add_tail(&llc_engine->entry, &llc_engines);
0061 
0062     return 0;
0063 }
0064 
0065 static struct nfc_llc_engine *nfc_llc_name_to_engine(const char *name)
0066 {
0067     struct nfc_llc_engine *llc_engine;
0068 
0069     list_for_each_entry(llc_engine, &llc_engines, entry) {
0070         if (strcmp(llc_engine->name, name) == 0)
0071             return llc_engine;
0072     }
0073 
0074     return NULL;
0075 }
0076 
0077 void nfc_llc_unregister(const char *name)
0078 {
0079     struct nfc_llc_engine *llc_engine;
0080 
0081     llc_engine = nfc_llc_name_to_engine(name);
0082     if (llc_engine == NULL)
0083         return;
0084 
0085     list_del(&llc_engine->entry);
0086     kfree(llc_engine->name);
0087     kfree(llc_engine);
0088 }
0089 
0090 struct nfc_llc *nfc_llc_allocate(const char *name, struct nfc_hci_dev *hdev,
0091                  xmit_to_drv_t xmit_to_drv,
0092                  rcv_to_hci_t rcv_to_hci, int tx_headroom,
0093                  int tx_tailroom, llc_failure_t llc_failure)
0094 {
0095     struct nfc_llc_engine *llc_engine;
0096     struct nfc_llc *llc;
0097 
0098     llc_engine = nfc_llc_name_to_engine(name);
0099     if (llc_engine == NULL)
0100         return NULL;
0101 
0102     llc = kzalloc(sizeof(struct nfc_llc), GFP_KERNEL);
0103     if (llc == NULL)
0104         return NULL;
0105 
0106     llc->data = llc_engine->ops->init(hdev, xmit_to_drv, rcv_to_hci,
0107                       tx_headroom, tx_tailroom,
0108                       &llc->rx_headroom, &llc->rx_tailroom,
0109                       llc_failure);
0110     if (llc->data == NULL) {
0111         kfree(llc);
0112         return NULL;
0113     }
0114     llc->ops = llc_engine->ops;
0115 
0116     return llc;
0117 }
0118 
0119 void nfc_llc_free(struct nfc_llc *llc)
0120 {
0121     llc->ops->deinit(llc);
0122     kfree(llc);
0123 }
0124 
0125 int nfc_llc_start(struct nfc_llc *llc)
0126 {
0127     return llc->ops->start(llc);
0128 }
0129 EXPORT_SYMBOL(nfc_llc_start);
0130 
0131 int nfc_llc_stop(struct nfc_llc *llc)
0132 {
0133     return llc->ops->stop(llc);
0134 }
0135 EXPORT_SYMBOL(nfc_llc_stop);
0136 
0137 void nfc_llc_rcv_from_drv(struct nfc_llc *llc, struct sk_buff *skb)
0138 {
0139     llc->ops->rcv_from_drv(llc, skb);
0140 }
0141 
0142 int nfc_llc_xmit_from_hci(struct nfc_llc *llc, struct sk_buff *skb)
0143 {
0144     return llc->ops->xmit_from_hci(llc, skb);
0145 }
0146 
0147 void *nfc_llc_get_data(struct nfc_llc *llc)
0148 {
0149     return llc->data;
0150 }