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 *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 u8 rx_data[QTN_IPC_MAX_DATA_SZ] __aligned(sizeof(u32)); 55 56 struct qtnf_shm_ipc_int interrupt; 57 struct qtnf_shm_ipc_rx_callback rx_callback; 58 59 void (*irq_handler)(struct qtnf_shm_ipc *ipc); 60 61 struct workqueue_struct *workqueue; 62 struct work_struct irq_work; 63 struct completion tx_completion; 64 }; 65 66 int qtnf_shm_ipc_init(struct qtnf_shm_ipc *ipc, 67 enum qtnf_shm_ipc_direction direction, 68 struct qtnf_shm_ipc_region __iomem *shm_region, 69 struct workqueue_struct *workqueue, 70 const struct qtnf_shm_ipc_int *interrupt, 71 const struct qtnf_shm_ipc_rx_callback *rx_callback); 72 void qtnf_shm_ipc_free(struct qtnf_shm_ipc *ipc); 73 int qtnf_shm_ipc_send(struct qtnf_shm_ipc *ipc, const u8 *buf, size_t size); 74 75 static inline void qtnf_shm_ipc_irq_handler(struct qtnf_shm_ipc *ipc) 76 { 77 ipc->irq_handler(ipc); 78 } 79 80 #endif /* _QTN_FMAC_SHM_IPC_H_ */ 81