162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * nop (passthrough) Link Layer Control
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2012  Intel Corporation. All rights reserved.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/types.h>
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include "llc.h"
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_cistruct llc_nop {
1362306a36Sopenharmony_ci	struct nfc_hci_dev *hdev;
1462306a36Sopenharmony_ci	xmit_to_drv_t xmit_to_drv;
1562306a36Sopenharmony_ci	rcv_to_hci_t rcv_to_hci;
1662306a36Sopenharmony_ci	int tx_headroom;
1762306a36Sopenharmony_ci	int tx_tailroom;
1862306a36Sopenharmony_ci	llc_failure_t llc_failure;
1962306a36Sopenharmony_ci};
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic void *llc_nop_init(struct nfc_hci_dev *hdev, xmit_to_drv_t xmit_to_drv,
2262306a36Sopenharmony_ci			  rcv_to_hci_t rcv_to_hci, int tx_headroom,
2362306a36Sopenharmony_ci			  int tx_tailroom, int *rx_headroom, int *rx_tailroom,
2462306a36Sopenharmony_ci			  llc_failure_t llc_failure)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	struct llc_nop *llc_nop;
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci	*rx_headroom = 0;
2962306a36Sopenharmony_ci	*rx_tailroom = 0;
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci	llc_nop = kzalloc(sizeof(struct llc_nop), GFP_KERNEL);
3262306a36Sopenharmony_ci	if (llc_nop == NULL)
3362306a36Sopenharmony_ci		return NULL;
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci	llc_nop->hdev = hdev;
3662306a36Sopenharmony_ci	llc_nop->xmit_to_drv = xmit_to_drv;
3762306a36Sopenharmony_ci	llc_nop->rcv_to_hci = rcv_to_hci;
3862306a36Sopenharmony_ci	llc_nop->tx_headroom = tx_headroom;
3962306a36Sopenharmony_ci	llc_nop->tx_tailroom = tx_tailroom;
4062306a36Sopenharmony_ci	llc_nop->llc_failure = llc_failure;
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci	return llc_nop;
4362306a36Sopenharmony_ci}
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_cistatic void llc_nop_deinit(struct nfc_llc *llc)
4662306a36Sopenharmony_ci{
4762306a36Sopenharmony_ci	kfree(nfc_llc_get_data(llc));
4862306a36Sopenharmony_ci}
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic int llc_nop_start(struct nfc_llc *llc)
5162306a36Sopenharmony_ci{
5262306a36Sopenharmony_ci	return 0;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic int llc_nop_stop(struct nfc_llc *llc)
5662306a36Sopenharmony_ci{
5762306a36Sopenharmony_ci	return 0;
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic void llc_nop_rcv_from_drv(struct nfc_llc *llc, struct sk_buff *skb)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	struct llc_nop *llc_nop = nfc_llc_get_data(llc);
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci	llc_nop->rcv_to_hci(llc_nop->hdev, skb);
6562306a36Sopenharmony_ci}
6662306a36Sopenharmony_ci
6762306a36Sopenharmony_cistatic int llc_nop_xmit_from_hci(struct nfc_llc *llc, struct sk_buff *skb)
6862306a36Sopenharmony_ci{
6962306a36Sopenharmony_ci	struct llc_nop *llc_nop = nfc_llc_get_data(llc);
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci	return llc_nop->xmit_to_drv(llc_nop->hdev, skb);
7262306a36Sopenharmony_ci}
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_cistatic const struct nfc_llc_ops llc_nop_ops = {
7562306a36Sopenharmony_ci	.init = llc_nop_init,
7662306a36Sopenharmony_ci	.deinit = llc_nop_deinit,
7762306a36Sopenharmony_ci	.start = llc_nop_start,
7862306a36Sopenharmony_ci	.stop = llc_nop_stop,
7962306a36Sopenharmony_ci	.rcv_from_drv = llc_nop_rcv_from_drv,
8062306a36Sopenharmony_ci	.xmit_from_hci = llc_nop_xmit_from_hci,
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ciint nfc_llc_nop_register(void)
8462306a36Sopenharmony_ci{
8562306a36Sopenharmony_ci	return nfc_llc_register(LLC_NOP_NAME, &llc_nop_ops);
8662306a36Sopenharmony_ci}
87