File Index
Files and directories
Sign in
FILE

llc.c

File preview with syntax highlighting.

linux-6.19.14/net/nfc/hci/llc.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Link Layer Control manager
  4 *
  5 * Copyright (C) 2012  Intel Corporation. All rights reserved.
  6 */
  7
  8#include <net/nfc/llc.h>
  9
 10#include "llc.h"
 11
 12static LIST_HEAD(llc_engines);
 13
 14int __init nfc_llc_init(void)
 15{
 16	int r;
 17
 18	r = nfc_llc_nop_register();
 19	if (r)
 20		goto exit;
 21
 22	r = nfc_llc_shdlc_register();
 23	if (r)
 24		goto exit;
 25
 26	return 0;
 27
 28exit:
 29	nfc_llc_exit();
 30	return r;
 31}
 32
 33static void nfc_llc_del_engine(struct nfc_llc_engine *llc_engine)
 34{
 35	list_del(&llc_engine->entry);
 36	kfree_const(llc_engine->name);
 37	kfree(llc_engine);
 38}
 39
 40void nfc_llc_exit(void)
 41{
 42	struct nfc_llc_engine *llc_engine, *n;
 43
 44	list_for_each_entry_safe(llc_engine, n, &llc_engines, entry)
 45		nfc_llc_del_engine(llc_engine);
 46}
 47
 48int nfc_llc_register(const char *name, const struct nfc_llc_ops *ops)
 49{
 50	struct nfc_llc_engine *llc_engine;
 51
 52	llc_engine = kzalloc(sizeof(struct nfc_llc_engine), GFP_KERNEL);
 53	if (llc_engine == NULL)
 54		return -ENOMEM;
 55
 56	llc_engine->name = kstrdup_const(name, GFP_KERNEL);
 57	if (llc_engine->name == NULL) {
 58		kfree(llc_engine);
 59		return -ENOMEM;
 60	}
 61	llc_engine->ops = ops;
 62
 63	INIT_LIST_HEAD(&llc_engine->entry);
 64	list_add_tail(&llc_engine->entry, &llc_engines);
 65
 66	return 0;
 67}
 68
 69static struct nfc_llc_engine *nfc_llc_name_to_engine(const char *name)
 70{
 71	struct nfc_llc_engine *llc_engine;
 72
 73	list_for_each_entry(llc_engine, &llc_engines, entry) {
 74		if (strcmp(llc_engine->name, name) == 0)
 75			return llc_engine;
 76	}
 77
 78	return NULL;
 79}
 80
 81struct nfc_llc *nfc_llc_allocate(const char *name, struct nfc_hci_dev *hdev,
 82				 xmit_to_drv_t xmit_to_drv,
 83				 rcv_to_hci_t rcv_to_hci, int tx_headroom,
 84				 int tx_tailroom, llc_failure_t llc_failure)
 85{
 86	struct nfc_llc_engine *llc_engine;
 87	struct nfc_llc *llc;
 88
 89	llc_engine = nfc_llc_name_to_engine(name);
 90	if (llc_engine == NULL)
 91		return NULL;
 92
 93	llc = kzalloc(sizeof(struct nfc_llc), GFP_KERNEL);
 94	if (llc == NULL)
 95		return NULL;
 96
 97	llc->data = llc_engine->ops->init(hdev, xmit_to_drv, rcv_to_hci,
 98					  tx_headroom, tx_tailroom,
 99					  &llc->rx_headroom, &llc->rx_tailroom,
100					  llc_failure);
101	if (llc->data == NULL) {
102		kfree(llc);
103		return NULL;
104	}
105	llc->ops = llc_engine->ops;
106
107	return llc;
108}
109
110void nfc_llc_free(struct nfc_llc *llc)
111{
112	llc->ops->deinit(llc);
113	kfree(llc);
114}
115
116int nfc_llc_start(struct nfc_llc *llc)
117{
118	return llc->ops->start(llc);
119}
120EXPORT_SYMBOL(nfc_llc_start);
121
122int nfc_llc_stop(struct nfc_llc *llc)
123{
124	return llc->ops->stop(llc);
125}
126EXPORT_SYMBOL(nfc_llc_stop);
127
128void nfc_llc_rcv_from_drv(struct nfc_llc *llc, struct sk_buff *skb)
129{
130	llc->ops->rcv_from_drv(llc, skb);
131}
132
133int nfc_llc_xmit_from_hci(struct nfc_llc *llc, struct sk_buff *skb)
134{
135	return llc->ops->xmit_from_hci(llc, skb);
136}
137
138void *nfc_llc_get_data(struct nfc_llc *llc)
139{
140	return llc->data;
141}
~/ Read-only file preview.