]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - drivers/net/wireless/ath9k/ath9k.h
Make ar9170 use common ath reg code
[mirror_ubuntu-artful-kernel.git] / drivers / net / wireless / ath9k / ath9k.h
index f5d099f0ab4c8c7422bc43f264ba98fc4e8849e9..c92d46fa9d5133713bc130b0dc9d16f3b1d01f5e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
  *
  * Permission to use, copy, modify, and/or distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -53,11 +53,7 @@ struct ath_node;
 
 #define A_MAX(a, b) ((a) > (b) ? (a) : (b))
 
-#define ASSERT(exp) do {                       \
-               if (unlikely(!(exp))) {         \
-                       BUG();                  \
-               }                               \
-       } while (0)
+#define ASSERT(exp) BUG_ON(!(exp))
 
 #define TSF_TO_TU(_h,_l) \
        ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
@@ -70,7 +66,6 @@ struct ath_config {
        u32 ath_aggr_prot;
        u16 txpowlimit;
        u8 cabqReadytime;
-       u8 swBeaconProcess;
 };
 
 /*************************/
@@ -78,13 +73,17 @@ struct ath_config {
 /*************************/
 
 #define ATH_TXBUF_RESET(_bf) do {                              \
-               (_bf)->bf_status = 0;                           \
+               (_bf)->bf_stale = false;                        \
                (_bf)->bf_lastbf = NULL;                        \
                (_bf)->bf_next = NULL;                          \
                memset(&((_bf)->bf_state), 0,                   \
                       sizeof(struct ath_buf_state));           \
        } while (0)
 
+#define ATH_RXBUF_RESET(_bf) do {              \
+               (_bf)->bf_stale = false;        \
+       } while (0)
+
 /**
  * enum buffer_type - Buffer type flags
  *
@@ -110,7 +109,7 @@ struct ath_buf_state {
        int bfs_seqno;
        int bfs_tidno;
        int bfs_retries;
-       u32 bf_type;
+       u8 bf_type;
        u32 bfs_keyix;
        enum ath9k_key_type bfs_keytype;
 };
@@ -134,26 +133,21 @@ struct ath_buf {
        struct ath_buf *bf_lastbf;      /* last buf of this unit (a frame or
                                           an aggregate) */
        struct ath_buf *bf_next;        /* next subframe in the aggregate */
-       void *bf_mpdu;                  /* enclosing frame structure */
+       struct sk_buff *bf_mpdu;        /* enclosing frame structure */
        struct ath_desc *bf_desc;       /* virtual addr of desc */
        dma_addr_t bf_daddr;            /* physical addr of desc */
        dma_addr_t bf_buf_addr;         /* physical addr of data buffer */
-       u32 bf_status;
+       bool bf_stale;
        u16 bf_flags;
        struct ath_buf_state bf_state;
        dma_addr_t bf_dmacontext;
 };
 
-#define ATH_RXBUF_RESET(_bf)    ((_bf)->bf_status = 0)
-#define ATH_BUFSTATUS_STALE     0x00000002
-
 struct ath_descdma {
-       const char *dd_name;
        struct ath_desc *dd_desc;
        dma_addr_t dd_desc_paddr;
        u32 dd_desc_len;
        struct ath_buf *dd_bufptr;
-       dma_addr_t dd_dmacontext;
 };
 
 int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
@@ -292,35 +286,12 @@ struct ath_atx_ac {
 struct ath_tx_control {
        struct ath_txq *txq;
        int if_id;
+       enum ath9k_internal_frame_type frame_type;
 };
 
-struct ath_xmit_status {
-       int retries;
-       int flags;
 #define ATH_TX_ERROR        0x01
 #define ATH_TX_XRETRY       0x02
 #define ATH_TX_BAR          0x04
-};
-
-/* All RSSI values are noise floor adjusted */
-struct ath_tx_stat {
-       int rssi;
-       int rssictl[ATH_MAX_ANTENNA];
-       int rssiextn[ATH_MAX_ANTENNA];
-       int rateieee;
-       int rateKbps;
-       int ratecode;
-       int flags;
-       u32 airtime;    /* time on air per final tx rate */
-};
-
-struct aggr_rifs_param {
-       int param_max_frames;
-       int param_max_len;
-       int param_rl;
-       int param_al;
-       struct ath_rc_series *param_rcs;
-};
 
 struct ath_node {
        struct ath_softc *an_sc;
@@ -369,14 +340,14 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
 void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
 void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
 int ath_tx_init(struct ath_softc *sc, int nbufs);
-int ath_tx_cleanup(struct ath_softc *sc);
+void ath_tx_cleanup(struct ath_softc *sc);
 struct ath_txq *ath_test_get_txq(struct ath_softc *sc, struct sk_buff *skb);
 int ath_txq_update(struct ath_softc *sc, int qnum,
                   struct ath9k_tx_queue_info *q);
-int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb,
+int ath_tx_start(struct ieee80211_hw *hw, struct sk_buff *skb,
                 struct ath_tx_control *txctl);
 void ath_tx_tasklet(struct ath_softc *sc);
-void ath_tx_cabq(struct ath_softc *sc, struct sk_buff *skb);
+void ath_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb);
 bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an, u8 tidno);
 int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
                      u16 tid, u16 *ssn);
@@ -387,22 +358,13 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid
 /* VIFs */
 /********/
 
-/*
- * Define the scheme that we select MAC address for multiple
- * BSS on the same radio. The very first VIF will just use the MAC
- * address from the EEPROM. For the next 3 VIFs, we set the
- * U/L bit (bit 1) in MAC address, and use the next two bits as the
- * index of the VIF.
- */
-
-#define ATH_SET_VIF_BSSID_MASK(bssid_mask) \
-       ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
-
 struct ath_vif {
        int av_bslot;
+       __le64 tsf_adjust; /* TSF adjustment for staggered beacons */
        enum nl80211_iftype av_opmode;
        struct ath_buf *av_bcbuf;
        struct ath_tx_control av_btxctl;
+       u8 bssid[ETH_ALEN]; /* current BSSID from config_interface */
 };
 
 /*******************/
@@ -415,7 +377,7 @@ struct ath_vif {
  * number of beacon intervals, the game's up.
  */
 #define BSTUCK_THRESH                  (9 * ATH_BCBUF)
-#define        ATH_BCBUF                       1
+#define        ATH_BCBUF                       4
 #define ATH_DEFAULT_BINTVAL            100 /* TU */
 #define ATH_DEFAULT_BMISS_LIMIT        10
 #define IEEE80211_MS_TO_TU(x)           (((x) * 1000) / 1024)
@@ -426,11 +388,6 @@ struct ath_beacon_config {
        u16 dtim_period;
        u16 bmiss_timeout;
        u8 dtim_count;
-       u8 tim_offset;
-       union {
-               u64 last_tsf;
-               u8 last_tstamp[8];
-       } u; /* last received beacon/probe response timestamp of this BSS. */
 };
 
 struct ath_beacon {
@@ -444,7 +401,8 @@ struct ath_beacon {
        u32 bmisscnt;
        u32 ast_be_xmit;
        u64 bc_tstamp;
-       int bslot[ATH_BCBUF];
+       struct ieee80211_vif *bslot[ATH_BCBUF];
+       struct ath_wiphy *bslot_aphy[ATH_BCBUF];
        int slottime;
        int slotupdate;
        struct ath9k_tx_queue_info beacon_qi;
@@ -454,11 +412,10 @@ struct ath_beacon {
 };
 
 void ath_beacon_tasklet(unsigned long data);
-void ath_beacon_config(struct ath_softc *sc, int if_id);
+void ath_beacon_config(struct ath_softc *sc, struct ieee80211_vif *vif);
 int ath_beaconq_setup(struct ath_hw *ah);
-int ath_beacon_alloc(struct ath_softc *sc, int if_id);
+int ath_beacon_alloc(struct ath_wiphy *aphy, struct ieee80211_vif *vif);
 void ath_beacon_return(struct ath_softc *sc, struct ath_vif *avp);
-void ath_beacon_sync(struct ath_softc *sc, int if_id);
 
 /*******/
 /* ANI */
@@ -538,27 +495,26 @@ struct ath_rfkill {
  */
 #define        ATH_KEYMAX              128     /* max key cache size we handle */
 
-#define ATH_IF_ID_ANY          0xff
 #define ATH_TXPOWER_MAX         100     /* .5 dBm units */
 #define ATH_RSSI_DUMMY_MARKER   0x127
 #define ATH_RATE_DUMMY_MARKER   0
 
-#define SC_OP_INVALID          BIT(0)
-#define SC_OP_BEACONS          BIT(1)
-#define SC_OP_RXAGGR           BIT(2)
-#define SC_OP_TXAGGR           BIT(3)
-#define SC_OP_CHAINMASK_UPDATE BIT(4)
-#define SC_OP_FULL_RESET       BIT(5)
-#define SC_OP_PREAMBLE_SHORT   BIT(6)
-#define SC_OP_PROTECT_ENABLE   BIT(7)
-#define SC_OP_RXFLUSH          BIT(8)
-#define SC_OP_LED_ASSOCIATED   BIT(9)
-#define SC_OP_RFKILL_REGISTERED        BIT(10)
-#define SC_OP_RFKILL_SW_BLOCKED        BIT(11)
-#define SC_OP_RFKILL_HW_BLOCKED        BIT(12)
-#define SC_OP_WAIT_FOR_BEACON  BIT(13)
-#define SC_OP_LED_ON           BIT(14)
-#define SC_OP_SCANNING         BIT(15)
+#define SC_OP_INVALID           BIT(0)
+#define SC_OP_BEACONS           BIT(1)
+#define SC_OP_RXAGGR            BIT(2)
+#define SC_OP_TXAGGR            BIT(3)
+#define SC_OP_FULL_RESET        BIT(4)
+#define SC_OP_PREAMBLE_SHORT    BIT(5)
+#define SC_OP_PROTECT_ENABLE    BIT(6)
+#define SC_OP_RXFLUSH           BIT(7)
+#define SC_OP_LED_ASSOCIATED    BIT(8)
+#define SC_OP_RFKILL_REGISTERED BIT(9)
+#define SC_OP_RFKILL_SW_BLOCKED BIT(10)
+#define SC_OP_RFKILL_HW_BLOCKED BIT(11)
+#define SC_OP_WAIT_FOR_BEACON   BIT(12)
+#define SC_OP_LED_ON            BIT(13)
+#define SC_OP_SCANNING          BIT(14)
+#define SC_OP_TSF_RESET         BIT(15)
 
 struct ath_bus_ops {
        void            (*read_cachesize)(struct ath_softc *sc, int *csz);
@@ -566,15 +522,34 @@ struct ath_bus_ops {
        bool            (*eeprom_read)(struct ath_hw *ah, u32 off, u16 *data);
 };
 
+struct ath_wiphy;
+
 struct ath_softc {
        struct ieee80211_hw *hw;
        struct device *dev;
+
+       spinlock_t wiphy_lock; /* spinlock to protect ath_wiphy data */
+       struct ath_wiphy *pri_wiphy;
+       struct ath_wiphy **sec_wiphy; /* secondary wiphys (virtual radios); may
+                                      * have NULL entries */
+       int num_sec_wiphy; /* number of sec_wiphy pointers in the array */
+       int chan_idx;
+       int chan_is_ht;
+       struct ath_wiphy *next_wiphy;
+       struct work_struct chan_work;
+       int wiphy_select_failures;
+       unsigned long wiphy_select_first_fail;
+       struct delayed_work wiphy_work;
+       unsigned long wiphy_scheduler_int;
+       int wiphy_scheduler_index;
+
        struct tasklet_struct intr_tq;
        struct tasklet_struct bcon_tasklet;
        struct ath_hw *sc_ah;
        void __iomem *mem;
        int irq;
        spinlock_t sc_resetlock;
+       spinlock_t sc_serial_rw;
        struct mutex mutex;
 
        u8 curbssid[ETH_ALEN];
@@ -600,7 +575,6 @@ struct ath_softc {
        struct ath_rx rx;
        struct ath_tx tx;
        struct ath_beacon beacon;
-       struct ieee80211_vif *vifs[ATH_BCBUF];
        struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
        struct ath_rate_table *hw_rate_table[ATH9K_MODE_MAX];
        struct ath_rate_table *cur_rate_table;
@@ -625,6 +599,20 @@ struct ath_softc {
        struct ath_bus_ops *bus_ops;
 };
 
+struct ath_wiphy {
+       struct ath_softc *sc; /* shared for all virtual wiphys */
+       struct ieee80211_hw *hw;
+       enum ath_wiphy_state {
+               ATH_WIPHY_INACTIVE,
+               ATH_WIPHY_ACTIVE,
+               ATH_WIPHY_PAUSING,
+               ATH_WIPHY_PAUSED,
+               ATH_WIPHY_SCAN,
+       } state;
+       int chan_idx;
+       int chan_is_ht;
+};
+
 int ath_reset(struct ath_softc *sc, bool retry_tx);
 int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
 int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
@@ -648,6 +636,14 @@ int ath_attach(u16 devid, struct ath_softc *sc);
 void ath_detach(struct ath_softc *sc);
 const char *ath_mac_bb_name(u32 mac_bb_version);
 const char *ath_rf_name(u16 rf_version);
+void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
+void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                          struct ath9k_channel *ichan);
+void ath_update_chainmask(struct ath_softc *sc, int is_ht);
+int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
+                   struct ath9k_channel *hchan);
+void ath_radio_enable(struct ath_softc *sc);
+void ath_radio_disable(struct ath_softc *sc);
 
 #ifdef CONFIG_PCI
 int ath_pci_init(void);
@@ -683,4 +679,52 @@ static inline void ath9k_ps_restore(struct ath_softc *sc)
                                          sc->sc_ah->restore_mode);
 }
 
+
+void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
+int ath9k_wiphy_add(struct ath_softc *sc);
+int ath9k_wiphy_del(struct ath_wiphy *aphy);
+void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb);
+int ath9k_wiphy_pause(struct ath_wiphy *aphy);
+int ath9k_wiphy_unpause(struct ath_wiphy *aphy);
+int ath9k_wiphy_select(struct ath_wiphy *aphy);
+void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int);
+void ath9k_wiphy_chan_work(struct work_struct *work);
+bool ath9k_wiphy_started(struct ath_softc *sc);
+void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
+                                 struct ath_wiphy *selected);
+bool ath9k_wiphy_scanning(struct ath_softc *sc);
+void ath9k_wiphy_work(struct work_struct *work);
+
+/*
+ * Read and write, they both share the same lock. We do this to serialize
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
+ * as the FIFO on these devices can only accept sanely 2 requests. After
+ * that the device goes bananas. Serializing the reads/writes prevents this
+ * from happening.
+ */
+
+static inline void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val)
+{
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               iowrite32(val, ah->ah_sc->mem + reg_offset);
+}
+
+static inline unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset)
+{
+       u32 val;
+       if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
+               unsigned long flags;
+               spin_lock_irqsave(&ah->ah_sc->sc_serial_rw, flags);
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+               spin_unlock_irqrestore(&ah->ah_sc->sc_serial_rw, flags);
+       } else
+               val = ioread32(ah->ah_sc->mem + reg_offset);
+       return val;
+}
+
 #endif /* ATH9K_H */