summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/digiPiper/pipermain.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/digiPiper/pipermain.h')
-rw-r--r--drivers/net/wireless/digiPiper/pipermain.h381
1 files changed, 381 insertions, 0 deletions
diff --git a/drivers/net/wireless/digiPiper/pipermain.h b/drivers/net/wireless/digiPiper/pipermain.h
new file mode 100644
index 000000000000..dba31309e081
--- /dev/null
+++ b/drivers/net/wireless/digiPiper/pipermain.h
@@ -0,0 +1,381 @@
+#ifndef __PIPER_H_
+#define __PIPER_H_
+
+#include <linux/completion.h>
+#include <linux/if_ether.h>
+#include <linux/spinlock.h>
+#include <net/mac80211.h>
+#include <linux/i2c.h>
+#include "mac.h"
+
+
+// #define WANT_DEBUG
+#ifdef WANT_DEBUG
+#define digi_dbg(fmt, arg...) \
+ printk(KERN_ERR PIPER_DRIVER_NAME ": %s - " fmt, __func__, ##arg)
+#else
+#define digi_dbg(fmt, arg...) \
+ do { } while (0)
+#endif
+
+#define ERROR(x) printk(KERN_ALERT x)
+
+/* Debug levels */
+#define DSILENT 0xffff
+#define DERROR 0xfff0
+#define DWARNING 0xffe0
+#define DNORMAL 0xffd0
+#define DVERBOSE 0xffc0
+#define DVVERBOSE 0xffb0
+#define DALL 0xffa0
+
+
+#define PIPER_DRIVER_NAME "piper"
+#define DRV_VERS "0.1"
+
+/* Useful defines for AES */
+#define PIPER_EXTIV_SIZE 8 /* IV and extended IV size */
+#define MIC_SIZE 8 /* Message integrity check size */
+#define ICV_SIZE 4
+#define DATA_SIZE 28 /* Data frame header+FCS size */
+#define CCMP_SIZE (PIPER_EXTIV_SIZE + MIC_SIZE) /* Total CCMP size */
+#define EXPANDED_KEY_LENGTH (176) /* length of expanded AES key */
+#define PIPER_MAX_KEYS (4)
+#define AES_BLOB_LENGTH (48) /* length of AES IV and headers */
+
+/* Calibration constants */
+#define WCD_MAGIC "WCALDATA"
+#define WCD_MAX_CAL_POINTS (8)
+#define WCD_CHANNELS_BG (14)
+#define WCD_CHANNELS_A (35)
+#define WCD_B_CURVE_INDEX (0)
+#define WCD_G_CURVE_INDEX (1)
+
+/*
+ * Set this #define to receive frames in the ISR. This may improve
+ * performance under heavy load at the expense of interrupt latency.
+ */
+#define WANT_TO_RECEIVE_FRAMES_IN_ISR (0)
+
+
+typedef u64 u48;
+
+/*
+ * This enum lists the possible LED states.
+ */
+enum led_states {
+ led_shutdown,
+ led_adhoc,
+ led_not_associated,
+ led_associated
+};
+
+/* Available leds */
+enum wireless_led {
+ STATUS_LED,
+ ACTIVITY_LED,
+};
+
+#define WCD_HW_REV_MASK 0xf000
+#define WCD_HW_REV_PROTOTYPE 0x0000
+#define WCD_HW_REV_PILOT 0x1000
+#define WCD_HW_REV_A 0x2000
+#define WCD_PLATFORM_MASK 0x0ff0
+#define WCD_CCW9P_PLATFORM 0x0010
+#define WCD_CCW9M_PLATFORM 0x0020
+
+
+typedef struct nv_wcd_header {
+ char magic_string[8]; /* WCALDATA */
+ char ver_major; /* Major version in ascii */
+ char ver_minor; /* Minor version in ascii */
+ u16 hw_platform; /* Hardware Platform used for calibration */
+ u8 numcalpoints; /* Number of points per curve */
+ u8 padding[107]; /* Reserved for future use */
+ u32 wcd_len; /* Total length of the data section */
+ u32 wcd_crc; /* Data section crc32 */
+} nv_wcd_header_t;
+
+typedef struct wcd_point {
+ s16 out_power; /* Output Power */
+ u16 adc_val; /* Measured ADC val */
+ u8 power_index; /* Airoha Power Index */
+ u8 reserved[3]; /* For future use */
+} wcd_point_t;
+
+typedef struct wcd_curve {
+ u8 max_adc_value; /* maximum allowed ADC value for this curve */
+ u8 reserved[3]; /* Resered for future use */
+ /* Calibration curve points */
+ wcd_point_t points[WCD_MAX_CAL_POINTS];
+} wcd_curve_t;
+
+typedef struct wcd_data {
+ nv_wcd_header_t header;
+ wcd_curve_t cal_curves_bg[WCD_CHANNELS_BG][2];
+ wcd_curve_t cal_curves_a[WCD_CHANNELS_A];
+} wcd_data_t;
+
+typedef enum {
+ op_write,
+ op_or,
+ op_and
+} reg_op_t;
+
+enum antenna_select {
+ ANTENNA_BOTH = 0,
+ ANTENNA_1,
+ ANTENNA_2,
+};
+
+typedef struct {
+ bool loaded;
+ bool enabled;
+ bool weSentLastOne;
+} piperBeaconInfo_t;
+
+typedef enum {
+ RECEIVED_ACK,
+ TX_COMPLETE,
+ OUT_OF_RETRIES,
+ TX_NOT_DONE
+} tx_result_t;
+
+
+/* Structure that holds the information we need to support H/W AES encryption */
+struct piperKeyInfo {
+ bool valid; /* indicates if this record is valid */
+ u8 addr[ETH_ALEN]; /* MAC address associated with key */
+ u32 expandedKey[EXPANDED_KEY_LENGTH / sizeof(u32)];
+ u48 txPn; /* packet number for transmit */
+ u48 rxPn; /* expected receive packet number */
+};
+
+/* rf */
+struct digi_rf_ops {
+ const char *name;
+ void (*init) (struct ieee80211_hw *, int);
+ int (*stop) (struct ieee80211_hw *);
+ int (*set_chan) (struct ieee80211_hw *, int chan);
+ int (*set_chan_no_rx) (struct ieee80211_hw *, int chan);
+ int (*set_pwr) (struct ieee80211_hw *, uint8_t val);
+ void (*set_pwr_index) (struct ieee80211_hw *, unsigned int val);
+ void (*power_on) (struct ieee80211_hw *, bool want_power_on);
+ void (*getOfdmBrs) (int channel, u64 brsBitMask, unsigned int *ofdm,
+ unsigned int *psk);
+ enum ieee80211_band (*getBand) (int);
+ int (*getFrequency) (int);
+ void (*set_hw_info)(struct ieee80211_hw *, int channel, u16 hw_platform);
+ const struct ieee80211_rate *(*getRate) (unsigned int);
+ int channelChangeTime;
+ s8 maxSignal;
+ struct ieee80211_supported_band *bands;
+ u8 n_bands;
+};
+
+struct piper_stats {
+ u32 rx_overruns;
+ u32 tx_complete_count;
+ u32 tx_start_count;
+ u32 tx_total_tetries;
+ u32 tx_retry_count[IEEE80211_TX_MAX_RATES];
+ u32 tx_retry_index;
+ struct ieee80211_tx_queue_stats tx_queue;
+ struct ieee80211_low_level_stats ll_stats;
+ spinlock_t lock;
+};
+
+enum piper_ps_mode {
+ PS_MODE_LOW_POWER,
+ PS_MODE_FULL_POWER
+};
+
+enum piper_ps_state {
+ PS_STATE_WAIT_FOR_BEACON,
+ PS_STATE_WAIT_FOR_STOP_TRANSMIT_EVENT,
+ PS_STATE_WAIT_FOR_TRANSMITTER_DONE,
+ PS_STATE_WAIT_FOR_WAKEUP_ALARM,
+ PS_STATE_WAIT_FOR_TRANSMITTER_DONE_EVENT
+};
+
+struct piper_priv;
+
+struct piper_ps {
+ u32 beacon_int;
+ u16 aid;
+ volatile unsigned int scan_timer;
+ unsigned int sleep_time;
+ struct timer_list timer;
+ enum piper_ps_mode mode;
+ enum piper_ps_state state;
+ unsigned int this_event;
+ spinlock_t lock;
+ volatile bool power_management;
+ volatile bool poweredDown;
+ volatile bool rxTaskletRunning;
+ volatile bool allowTransmits;
+ volatile bool stopped_tx_queues;
+ volatile unsigned int frames_pending;
+};
+
+typedef void (*tx_skb_return_cb_t)(struct ieee80211_hw *hw,
+ struct sk_buff *skb);
+
+struct piper_queue {
+ struct sk_buff *skb;
+ tx_skb_return_cb_t skb_return_cb;
+};
+
+#define PIPER_TX_QUEUE_SIZE (16)
+#define NEXT_TX_QUEUE_INDEX(x) ((x+1) & 0xf)
+
+struct piper_priv {
+ const char *drv_name;
+ char debug_cmd[32];
+ u32 version;
+ struct piper_pdata *pdata;
+ struct ieee80211_hw *hw;
+ struct ieee80211_key_conf txKeyInfo;
+ struct ieee80211_cts ctsFrame;
+ struct ieee80211_rts rtsFrame;
+ struct ieee80211_rate *calibrationTxRate;
+ struct piper_stats pstats;
+ struct tasklet_struct rx_tasklet;
+ struct tasklet_struct tx_tasklet;
+ spinlock_t tx_tasklet_lock;
+ bool tx_tasklet_running;
+ spinlock_t tx_queue_lock;
+ struct piper_queue tx_queue[PIPER_TX_QUEUE_SIZE];
+ unsigned int tx_queue_head;
+ unsigned int tx_queue_tail;
+ unsigned int tx_queue_count;
+ bool expectingAck;
+ struct timer_list tx_timer;
+ struct timer_list led_timer;
+ enum led_states led_state;
+ struct piper_ps ps;
+ bool power_save_was_on_when_suspended;
+ struct access_ops *ac;
+ spinlock_t aesLock;
+ struct digi_rf_ops *rf;
+ void *__iomem vbase;
+ int irq;
+ tx_result_t tx_result;
+ int tx_signal_strength;
+
+ /* Function callbacks */
+ int (*init_hw) (struct piper_priv *, enum ieee80211_band);
+ int (*deinit_hw) (struct piper_priv *);
+ void (*set_irq_mask_bit) (struct piper_priv *, u32);
+ void (*clear_irq_mask_bit) (struct piper_priv *, u32);
+ u16(*get_next_beacon_backoff) (void);
+ int (*load_beacon) (struct piper_priv *, u8 *, u32);
+ int (*rand) (void);
+ void (*tx_calib_cb) (struct piper_priv *);
+ int (*set_antenna) (struct piper_priv *, enum antenna_select);
+ int (*set_tracking_constant) (struct piper_priv * piperp,
+ unsigned megahertz);
+ void (*adjust_max_agc) (struct piper_priv * piperp, unsigned int rssi,
+ _80211HeaderType * header);
+
+ /* General settings */
+ enum nl80211_iftype if_type;
+ bool areWeAssociated;
+ bool is_radio_on;
+ bool use_short_preamble;
+ int channel;
+ int tx_power;
+ u8 bssid[ETH_ALEN];
+ bool tx_cts;
+ bool tx_rts;
+ enum antenna_select antenna;
+ int power_duty;
+
+ /* AES stuff */
+ bool use_hw_aes;
+ u32 aes_key_count;
+ struct piperKeyInfo key[PIPER_MAX_KEYS];
+ u32 tx_aes_key;
+ u32 tx_aes_blob[AES_BLOB_LENGTH / sizeof(u32)];
+
+ /* IBSS */
+ piperBeaconInfo_t beacon;
+};
+
+struct access_ops {
+ spinlock_t reg_lock;
+ int (*wr_reg) (struct piper_priv *, u8 reg, u32 val, reg_op_t op);
+ u32(*rd_reg) (struct piper_priv *, u8 reg);
+ int (*wr_fifo) (struct piper_priv *, u8 addr, u8 * buf, int len);
+ int (*rd_fifo) (struct piper_priv *, u8 addr, u8 * buf, int len);
+};
+
+struct piper_pdata {
+ u8 macaddr[6];
+ int rst_gpio;
+ int irq_gpio;
+ int status_led_gpio;
+ int rf_transceiver;
+ wcd_data_t wcd;
+ int i2c_adapter_num;
+ struct piper_priv *piperp;
+
+ /* Platform callbacks */
+ void (*reset) (struct piper_priv *, int);
+ int (*init) (struct piper_priv *);
+ int (*late_init) (struct piper_priv *);
+ void (*set_led) (struct piper_priv *, enum wireless_led, int);
+ void (*early_resume) (struct piper_priv *);
+};
+
+/* main */
+int piper_alloc_hw(struct piper_priv **priv, size_t priv_sz);
+void piper_free_hw(struct piper_priv *priv);
+int piper_register_hw(struct piper_priv *priv, struct device *dev,
+ struct digi_rf_ops *rf);
+void piper_unregister_hw(struct piper_priv *priv);
+irqreturn_t piper_irq_handler(int irq, void *dev_id);
+void packet_tx_done(struct piper_priv *piperp,
+ tx_result_t result, int singalstrength);
+void piper_rx_tasklet(unsigned long context);
+void piper_tx_tasklet(unsigned long context);
+bool piper_prepare_aes_datablob(struct piper_priv *digi,
+ unsigned int keyIndex, u8 * aesBlob,
+ u8 * frame, u32 length, bool isTransmit);
+void piper_load_mac_firmware(struct piper_priv *piperp);
+void piper_load_dsp_firmware(struct piper_priv *piperp);
+int piper_spike_suppression(struct piper_priv *piperp, bool retry);
+void piper_reset_mac(struct piper_priv *piperp);
+void piper_set_macaddr(struct piper_priv *piperp);
+int piper_hw_tx_private(struct ieee80211_hw *hw, struct sk_buff *skb, tx_skb_return_cb_t fn);
+void piper_empty_tx_queue(struct piper_priv *piperp);
+int piper_tx_enqueue(struct piper_priv *piperp, struct sk_buff *skb, tx_skb_return_cb_t skb_return_cb);
+struct sk_buff *piper_tx_getqueue(struct piper_priv *piperp);
+bool piper_tx_queue_half_full(struct piper_priv *piperp);
+void piper_set_macaddr(struct piper_priv *piperp);
+void piper_MacEnterActiveMode(struct piper_priv *piperp, bool want_spike_suppression);
+int piper_MacEnterSleepMode(struct piper_priv *piperp, bool force);
+void piper_sendNullDataFrame(struct piper_priv *piperp, bool isPowerSaveOn);
+void piper_ps_rx_task_exiting(struct piper_priv *piperp);
+void piper_ps_scan_event(struct piper_priv *piperp);
+
+/*
+ * Defines for debugging function dumpRegisters
+ */
+#define MAIN_REGS (1)
+#define MAC_REGS (2)
+#define RF_REGS (4)
+#define FRAME_BUFFER_REGS (8)
+#define CTRL_STATUS_REGS (0x10)
+#define FIFO_REGS (0x20)
+#define IRQ_REGS (0x40)
+#define ALL_REGS (0xf)
+
+void digiWifiDumpRegisters(struct piper_priv *digi, unsigned int regs);
+void digiWifiDumpSkb(struct sk_buff *skb);
+
+extern void digiWifiDumpWordsAdd(unsigned int word);
+extern void digiWifiDumpWordsDump(void);
+extern void digiWifiDumpWordsReset(void);
+
+#endif /* __PIPER_H_ */