215 lines
5.8 KiB
C
215 lines
5.8 KiB
C
/**
|
|
* aicwf_txrxif.h
|
|
*
|
|
* bus function declarations
|
|
*
|
|
* Copyright (C) AICSemi 2018-2020
|
|
*/
|
|
|
|
#ifndef _AICWF_TXRXIF_H_
|
|
#define _AICWF_TXRXIF_H_
|
|
|
|
#include <linux/skbuff.h>
|
|
#include <linux/sched.h>
|
|
#include "aicsdio.h"
|
|
|
|
#define CMD_BUF_MAX 1536
|
|
#define TXPKT_BLOCKSIZE 512
|
|
#define MAX_AGGR_TXPKT_LEN (1536*4)
|
|
#define CMD_TX_TIMEOUT 5000
|
|
#define TX_ALIGNMENT 4
|
|
|
|
#define RX_HWHRD_LEN 60 //58->60 word allined
|
|
#define CCMP_OR_WEP_INFO 8
|
|
#define MAX_RXQLEN 2000
|
|
#define RX_ALIGNMENT 4
|
|
|
|
#define DEBUG_ERROR_LEVEL 0
|
|
#define DEBUG_DEBUG_LEVEL 1
|
|
#define DEBUG_INFO_LEVEL 2
|
|
|
|
#define DBG_LEVEL DEBUG_DEBUG_LEVEL
|
|
|
|
#define txrx_err(fmt, ...) pr_err("aicbsp: txrx_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
|
#define sdio_err(fmt, ...) pr_err("aicbsp: sdio_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
|
#define usb_err(fmt, ...) pr_err("aicbsp: usb_err:<%s,%d>: " fmt, __func__, __LINE__, ##__VA_ARGS__)
|
|
#if DBG_LEVEL >= DEBUG_DEBUG_LEVEL
|
|
#define sdio_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
|
#define usb_dbg(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
|
#else
|
|
#define sdio_dbg(fmt, ...)
|
|
#define usb_dbg(fmt, ...)
|
|
#endif
|
|
#if DBG_LEVEL >= DEBUG_INFO_LEVEL
|
|
#define sdio_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
|
#define usb_info(fmt, ...) printk("aicbsp: " fmt, ##__VA_ARGS__)
|
|
#else
|
|
#define sdio_info(fmt, ...)
|
|
#define usb_info(fmt, ...)
|
|
#endif
|
|
|
|
enum aicwf_bus_state {
|
|
BUS_DOWN_ST,
|
|
BUS_UP_ST
|
|
};
|
|
|
|
struct aicwf_bus_ops {
|
|
int (*start) (struct device *dev);
|
|
void (*stop) (struct device *dev);
|
|
int (*txdata) (struct device *dev, struct sk_buff *skb);
|
|
int (*txmsg) (struct device *dev, u8 *msg, uint len);
|
|
};
|
|
|
|
struct frame_queue {
|
|
u16 num_prio;
|
|
u16 hi_prio;
|
|
u16 qmax; /* max number of queued frames */
|
|
u16 qcnt;
|
|
struct sk_buff_head queuelist[8];
|
|
};
|
|
|
|
struct aicwf_bus {
|
|
union {
|
|
struct aic_sdio_dev *sdio;
|
|
struct aic_usb_dev *usb;
|
|
} bus_priv;
|
|
struct device *dev;
|
|
struct aicwf_bus_ops *ops;
|
|
enum aicwf_bus_state state;
|
|
u8 *cmd_buf;
|
|
struct completion bustx_trgg;
|
|
struct completion busrx_trgg;
|
|
struct task_struct *bustx_thread;
|
|
struct task_struct *busrx_thread;
|
|
};
|
|
|
|
struct aicwf_tx_priv {
|
|
#ifdef AICWF_SDIO_SUPPORT
|
|
struct aic_sdio_dev *sdiodev;
|
|
int fw_avail_bufcnt;
|
|
//for cmd tx
|
|
u8 *cmd_buf;
|
|
uint cmd_len;
|
|
bool cmd_txstate;
|
|
bool cmd_tx_succ;
|
|
struct semaphore cmd_txsema;
|
|
wait_queue_head_t cmd_txdone_wait;
|
|
//for data tx
|
|
atomic_t tx_pktcnt;
|
|
|
|
struct frame_queue txq;
|
|
spinlock_t txqlock;
|
|
struct semaphore txctl_sema;
|
|
#endif
|
|
#ifdef AICWF_USB_SUPPORT
|
|
struct aic_usb_dev *usbdev;
|
|
#endif
|
|
struct sk_buff *aggr_buf;
|
|
atomic_t aggr_count;
|
|
u8 *head;
|
|
u8 *tail;
|
|
};
|
|
|
|
|
|
#define MAX_REORD_RXFRAME 250
|
|
#define REORDER_UPDATE_TIME 50
|
|
#define AICWF_REORDER_WINSIZE 64
|
|
#define SN_LESS(a, b) (((a-b)&0x800) != 0)
|
|
#define SN_EQUAL(a, b) (a == b)
|
|
|
|
struct reord_ctrl {
|
|
struct aicwf_rx_priv *rx_priv;
|
|
u8 enable;
|
|
u16 ind_sn;
|
|
u8 wsize_b;
|
|
spinlock_t reord_list_lock;
|
|
struct list_head reord_list;
|
|
struct timer_list reord_timer;
|
|
struct work_struct reord_timer_work;
|
|
};
|
|
|
|
struct reord_ctrl_info {
|
|
u8 mac_addr[6];
|
|
struct reord_ctrl preorder_ctrl[8];
|
|
struct list_head list;
|
|
};
|
|
|
|
struct recv_msdu {
|
|
struct sk_buff *pkt;
|
|
u8 tid;
|
|
u16 seq_num;
|
|
uint len;
|
|
u8 *rx_data;
|
|
//for pending rx reorder list
|
|
struct list_head reord_pending_list;
|
|
//for total frame list, when rxframe from busif, dequeue, when submit frame to net, enqueue
|
|
struct list_head rxframe_list;
|
|
struct reord_ctrl *preorder_ctrl;
|
|
};
|
|
|
|
struct aicwf_rx_priv {
|
|
struct aic_sdio_dev *sdiodev;
|
|
void *rwnx_vif;
|
|
atomic_t rx_cnt;
|
|
u32 data_len;
|
|
spinlock_t rxqlock;
|
|
struct frame_queue rxq;
|
|
|
|
spinlock_t freeq_lock;
|
|
struct list_head rxframes_freequeue;
|
|
struct list_head stas_reord_list;
|
|
spinlock_t stas_reord_lock;
|
|
struct recv_msdu *recv_frames;
|
|
};
|
|
|
|
static inline int aicwf_bus_start(struct aicwf_bus *bus)
|
|
{
|
|
return bus->ops->start(bus->dev);
|
|
}
|
|
|
|
static inline void aicwf_bus_stop(struct aicwf_bus *bus)
|
|
{
|
|
bus->ops->stop(bus->dev);
|
|
}
|
|
|
|
static inline int aicwf_bus_txdata(struct aicwf_bus *bus, struct sk_buff *skb)
|
|
{
|
|
return bus->ops->txdata(bus->dev, skb);
|
|
}
|
|
|
|
static inline int aicwf_bus_txmsg(struct aicwf_bus *bus, u8 *msg, uint len)
|
|
{
|
|
return bus->ops->txmsg(bus->dev, msg, len);
|
|
}
|
|
|
|
static inline void aicwf_sched_timeout(u32 millisec)
|
|
{
|
|
ulong timeout = 0, expires = 0;
|
|
expires = jiffies + msecs_to_jiffies(millisec);
|
|
timeout = millisec;
|
|
|
|
while (timeout) {
|
|
timeout = schedule_timeout(timeout);
|
|
if (time_after(jiffies, expires))
|
|
break;
|
|
}
|
|
}
|
|
|
|
int aicwf_bus_init(uint bus_hdrlen, struct device *dev);
|
|
void aicwf_bus_deinit(struct device *dev);
|
|
void aicwf_tx_deinit(struct aicwf_tx_priv *tx_priv);
|
|
void aicwf_rx_deinit(struct aicwf_rx_priv *rx_priv);
|
|
struct aicwf_tx_priv *aicwf_tx_init(void *arg);
|
|
struct aicwf_rx_priv *aicwf_rx_init(void *arg);
|
|
void aicwf_frame_queue_init(struct frame_queue *pq, int num_prio, int max_len);
|
|
void aicwf_frame_queue_flush(struct frame_queue *pq);
|
|
bool aicwf_frame_enq(struct device *dev, struct frame_queue *q, struct sk_buff *pkt, int prio);
|
|
bool aicwf_rxframe_enqueue(struct device *dev, struct frame_queue *q, struct sk_buff *pkt);
|
|
bool aicwf_is_framequeue_empty(struct frame_queue *pq);
|
|
void aicwf_frame_tx(void *dev, struct sk_buff *skb);
|
|
void aicwf_dev_skb_free(struct sk_buff *skb);
|
|
struct sk_buff *aicwf_frame_dequeue(struct frame_queue *pq);
|
|
struct sk_buff *aicwf_frame_queue_peek_tail(struct frame_queue *pq, int *prio_out);
|
|
|
|
#endif /* _AICWF_TXRXIF_H_ */
|