1 /* 2 * Copyright (c) 2015-2016 Quantenna Communications, Inc. 3 * All rights reserved. 4 * 5 * This program is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU General Public License 7 * as published by the Free Software Foundation; either version 2 8 * of the License, or (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 */ 16 17 #ifndef _QTN_FMAC_SHM_IPC_H_ 18 #define _QTN_FMAC_SHM_IPC_H_ 19 20 #include <linux/workqueue.h> 21 #include <linux/completion.h> 22 #include <linux/mutex.h> 23 #include <linux/spinlock.h> 24 25 #include "shm_ipc_defs.h" 26 27 #define QTN_SHM_IPC_ACK_TIMEOUT (2 * HZ) 28 29 struct qtnf_shm_ipc_int { 30 void (*fn)(void *arg); 31 void *arg; 32 }; 33 34 struct qtnf_shm_ipc_rx_callback { 35 void (*fn)(void *arg, const u8 __iomem *buf, size_t len); 36 void *arg; 37 }; 38 39 enum qtnf_shm_ipc_direction { 40 QTNF_SHM_IPC_OUTBOUND = BIT(0), 41 QTNF_SHM_IPC_INBOUND = BIT(1), 42 }; 43 44 struct qtnf_shm_ipc { 45 struct qtnf_shm_ipc_region __iomem *shm_region; 46 enum qtnf_shm_ipc_direction direction; 47 size_t tx_packet_count; 48 size_t rx_packet_count; 49 50 size_t tx_timeout_count; 51 52 u8 waiting_for_ack; 53 54 struct qtnf_shm_ipc_int interrupt; 55 struct qtnf_shm_ipc_rx_callback rx_callback; 56 57 void (*irq_handler)(struct qtnf_shm_ipc *ipc); 58 59 struct workqueue_struct *workqueue; 60 struct work_struct irq_work; 61 struct completion tx_completion; 62 }; 63 64 int qtnf_shm_ipc_init(struct qtnf_shm_ipc *ipc, 65 enum qtnf_shm_ipc_direction direction, 66 struct qtnf_shm_ipc_region __iomem *shm_region, 67 struct workqueue_struct *workqueue, 68 const struct qtnf_shm_ipc_int *interrupt, 69 const struct qtnf_shm_ipc_rx_callback *rx_callback); 70 void qtnf_shm_ipc_free(struct qtnf_shm_ipc *ipc); 71 int qtnf_shm_ipc_send(struct qtnf_shm_ipc *ipc, const u8 *buf, size_t size); 72 73 static inline void qtnf_shm_ipc_irq_handler(struct qtnf_shm_ipc *ipc) 74 { 75 ipc->irq_handler(ipc); 76 } 77 78 #endif /* _QTN_FMAC_SHM_IPC_H_ */ 79