Merge branch 'master' into radar
authorChristian Lamparter <chunkeey@googlemail.com>
Sat, 26 Jan 2013 20:46:51 +0000 (21:46 +0100)
committerChristian Lamparter <chunkeey@googlemail.com>
Sat, 26 Jan 2013 20:46:51 +0000 (21:46 +0100)
autogen.sh
carlfw/Kconfig
carlfw/src/main.c
carlfw/src/uart.c
carlfw/src/wlan.c
carlfw/src/wlantx.c
include/linux/ieee80211.h
tools/lib/carlfw.c

index bb52416a2566a1c9bb7e7d27da16b24534ccee4d..0c4776dbc68549a3da4b1e21e211e97824f00bbb 100755 (executable)
@@ -9,7 +9,8 @@ case "$1" in
                cmake .
                make
                popd
-               config/conf Kconfig
+               shift 1
+               config/conf Kconfig "$@"
                cmake .
        ;;
 
@@ -43,7 +44,7 @@ case "$1" in
        ;;
 
        *)
-               $0 config
+               $0 config "$@"
                $0 compile
        ;;
 
index 9bce6f13d6b3791b93785568fd4786095855c9d7..4cec81cef2e7f424b9c90e768c8bff6aa945ad90 100644 (file)
@@ -200,7 +200,7 @@ config CARL9170FW_UNUSABLE
 config CARL9170FW_USB_MODESWITCH
        def_bool n
        prompt "USB 1.1 / 2.0 switching support"
-       depends on CARL9170FW_BROKEN_FEATURES
+       depends on CARL9170FW_BROKEN_FEATURES && CARL9170FW_USB_STANDARD_CMDS
        ---help---
         Mostly implemented, but untested and some serious
         doubts remain.
index b9e558d3bbedf7ee55eecddf60bd8884b777a141..50415fedbbb760e77ef29ec6fede2b9f1a907cb7 100644 (file)
@@ -85,10 +85,13 @@ static void handle_fw(void)
 
 static void tally_update(void)
 {
-       unsigned int boff, time, delta;
+       unsigned int time;
 
        time = get_clock_counter();
+#ifdef CONFIG_CARL9170FW_RADIO_FUNCTIONS
        if (fw.phy.state == CARL9170_PHY_ON) {
+               unsigned int boff, delta;
+
                delta = (time - fw.tally_clock);
 
                fw.tally.active += delta;
@@ -99,7 +102,7 @@ static void tally_update(void)
                if (boff & AR9170_MAC_BACKOFF_CCA)
                        fw.tally.cca += delta;
        }
-
+#endif /* CONFIG_CARL9170FW_RADIO_FUNCTIONS */
        fw.tally_clock = time;
        fw.counter++;
 }
index 58f64866bae04352e09239c9c14045df68e35e16..919e6835de633b6ae9ce70b96f93cfa6d239cde3 100644 (file)
@@ -33,7 +33,7 @@ void uart_putc(const char c)
        set(AR9170_UART_REG_TX_HOLDING, c);
 
        while (get(AR9170_UART_REG_LINE_STATUS) &
-              AR9170_UART_LINE_STS_TX_FIFO_ALMOST_EMPTY) {
+              AR9170_UART_LINE_STS_TX_FIFO_NEAR_EMPTY) {
                /*
                 * wait until the byte has made it
                 */
index 0f4dfeba074dfb53c898cb0bfb59887a7caca1d9..384d8d1118fafb89d994895ba2841ca66081fb04 100644 (file)
@@ -56,7 +56,7 @@ static void wlan_dump_queue(unsigned int qidx)
                entries++;
        }
 
-       desc = get_wlan_txq_addr(qidx);
+       desc = (struct dma_desc *)get_wlan_txq_addr(qidx);
 
        DBG("Queue: %d: te:%d td:%d h:%p c:%p t:%p",
            qidx, entries, queue_len(&fw.wlan.tx_queue[qidx]),
index 9f2f51b07ba54794010b3ce1a5a7654a6402a041..a421c4c0d65ddefdad4d4f2b8ac269f5c2518471 100644 (file)
 #include "linux/ieee80211.h"
 #include "wol.h"
 
-static void wlan_txunstuck(unsigned int queue)
+static void wlan_txunstuck(unsigned int qidx)
 {
-       set_wlan_txq_dma_addr(queue, ((uint32_t) fw.wlan.tx_queue[queue].head) | 1);
+       struct dma_queue *queue = &fw.wlan.tx_queue[qidx];
+       struct dma_desc *iter;
+
+       /*
+        * walk up to the last descriptor which hasn't been
+        * processed by the hardware before it bailed out
+        * due to a TX error.
+        * Note: if there was no more "pending" frame
+        * in the queue, it iter will be on the
+        *    queue->terminator (which is fine)
+        */
+       __for_each_desc_bits(iter, queue, AR9170_OWN_BITS_SW);
+
+       set_wlan_txq_dma_addr(qidx, ((uint32_t) iter) | 1);
+       wlan_trigger(BIT(qidx));
 }
 
 #ifdef CONFIG_CARL9170FW_DMA_QUEUE_BUMP
-static void wlan_txupdate(unsigned int queue)
+static void wlan_txupdate(unsigned int qidx)
 {
-       set_wlan_txq_dma_addr(queue, ((uint32_t) fw.wlan.tx_queue[queue].head));
+       struct dma_queue *queue = &fw.wlan.tx_queue[qidx];
+       struct dma_desc *iter;
+       /* comment in wlan_txunstuck applies here too. */
+       __for_each_desc_bits(iter, queue, AR9170_OWN_BITS_SW);
+
+       set_wlan_txq_dma_addr(qidx, ((uint32_t) iter));
+       wlan_trigger(BIT(qidx));
 }
 
 void wlan_dma_bump(unsigned int qidx)
@@ -258,9 +278,9 @@ static void __wlan_tx(struct dma_desc *desc)
 
        wlan_tx_ampdu(super);
 
-#ifdef CONFIG_CARL9170FW_DEBUG
+#if (defined CONFIG_CARL9170FW_DEBUG) && (defined CONFIG_CARL9170FW_RADIO_FUNCTIONS)
        BUG_ON(fw.phy.psm.state != CARL9170_PSM_WAKE);
-#endif /* CONFIG_CARL9170FW_DEBUG */
+#endif /* CONFIG_CARL9170FW_DEBUG && CONFIG_CARL9170FW_RADIO_FUNCTIONS */
 
        /* insert desc into the right queue */
        dma_put(&fw.wlan.tx_queue[super->s.queue], desc);
@@ -367,7 +387,7 @@ static bool wlan_tx_status(struct dma_queue *queue,
                                wlan_txunstuck(qidx);
 
                                /* abort cycle - this is necessary due to HW design */
-                               return false;
+                               goto out;
                        } else {
                                /* (HT-) BlockACK failure */
 
@@ -383,7 +403,7 @@ static bool wlan_tx_status(struct dma_queue *queue,
                                BUG_ON(dma_unlink_head(queue) != desc);
 #endif /* CONFIG_CARL9170FW_DEBUG */
                                dma_put(&fw.wlan.tx_retry, desc);
-                               return true;
+                               goto out;
                        }
                } else {
                        /* out of frame attempts - discard frame */
@@ -415,7 +435,7 @@ static bool wlan_tx_status(struct dma_queue *queue,
                if (fw.wlan.fw_desc_callback)
                        fw.wlan.fw_desc_callback(super, success);
 
-               return true;
+               goto out;
        }
 
        if (unlikely(super->s.cab))
@@ -430,7 +450,12 @@ static bool wlan_tx_status(struct dma_queue *queue,
        /* recycle freed descriptors */
        dma_reclaim(&fw.pta.down_queue, desc);
        down_trigger();
-       return true;
+out:
+       /*
+        * if we encounter a frame which run out of (normal)
+        * tx retries we have to stop too.
+        */
+       return !txfail;
 }
 
 void handle_wlan_tx_completion(void)
index 0ab6e2c968f86074a55397bd1926b404455300a0..acef0deaff5a8c32f846b1dbd7b552c023fcae73 100644 (file)
@@ -177,7 +177,7 @@ struct ieee80211_hdr {
        u8 addr3[6];
        __le16 seq_ctrl;
        u8 addr4[6];
-} __attribute__ ((packed));
+} __packed;
 
 struct ieee80211_hdr_3addr {
        __le16 frame_control;
@@ -186,7 +186,7 @@ struct ieee80211_hdr_3addr {
        u8 addr2[6];
        u8 addr3[6];
        __le16 seq_ctrl;
-} __attribute__ ((packed));
+} __packed;
 
 struct ieee80211_qos_hdr {
        __le16 frame_control;
@@ -196,7 +196,7 @@ struct ieee80211_qos_hdr {
        u8 addr3[6];
        __le16 seq_ctrl;
        __le16 qos_ctrl;
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
@@ -589,7 +589,7 @@ struct ieee80211s_hdr {
        __le32 seqnum;
        u8 eaddr1[6];
        u8 eaddr2[6];
-} __attribute__ ((packed));
+} __packed;
 
 /* Mesh flags */
 #define MESH_FLAGS_AE_A4       0x1
@@ -627,7 +627,7 @@ struct ieee80211_quiet_ie {
        u8 period;
        __le16 duration;
        __le16 offset;
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * struct ieee80211_msrment_ie
@@ -639,7 +639,7 @@ struct ieee80211_msrment_ie {
        u8 mode;
        u8 type;
        u8 request[0];
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * struct ieee80211_channel_sw_ie
@@ -650,7 +650,7 @@ struct ieee80211_channel_sw_ie {
        u8 mode;
        u8 new_ch_num;
        u8 count;
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * struct ieee80211_tim
@@ -663,7 +663,7 @@ struct ieee80211_tim_ie {
        u8 bitmap_ctrl;
        /* variable size: 1 - 251 bytes */
        u8 virtual_map[1];
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * struct ieee80211_meshconf_ie
@@ -678,7 +678,7 @@ struct ieee80211_meshconf_ie {
        u8 meshconf_auth;
        u8 meshconf_form;
        u8 meshconf_cap;
-} __attribute__ ((packed));
+} __packed;
 
 /**
  * enum mesh_config_capab_flags - Mesh Configuration IE capability field flags
@@ -708,12 +708,17 @@ struct ieee80211_rann_ie {
        __le32 rann_seq;
        __le32 rann_interval;
        __le32 rann_metric;
-} __attribute__ ((packed));
+} __packed;
 
 enum ieee80211_rann_flags {
        RANN_FLAG_IS_GATE = 1 << 0,
 };
 
+enum ieee80211_ht_chanwidth_values {
+       IEEE80211_HT_CHANWIDTH_20MHZ = 0,
+       IEEE80211_HT_CHANWIDTH_ANY = 1,
+};
+
 #define WLAN_SA_QUERY_TR_ID_LEN 2
 
 struct ieee80211_mgmt {
@@ -730,33 +735,33 @@ struct ieee80211_mgmt {
                        __le16 status_code;
                        /* possibly followed by Challenge text */
                        u8 variable[0];
-               } __attribute__ ((packed)) auth;
+               } __packed auth;
                struct {
                        __le16 reason_code;
-               } __attribute__ ((packed)) deauth;
+               } __packed deauth;
                struct {
                        __le16 capab_info;
                        __le16 listen_interval;
                        /* followed by SSID and Supported rates */
                        u8 variable[0];
-               } __attribute__ ((packed)) assoc_req;
+               } __packed assoc_req;
                struct {
                        __le16 capab_info;
                        __le16 status_code;
                        __le16 aid;
                        /* followed by Supported rates */
                        u8 variable[0];
-               } __attribute__ ((packed)) assoc_resp, reassoc_resp;
+               } __packed assoc_resp, reassoc_resp;
                struct {
                        __le16 capab_info;
                        __le16 listen_interval;
                        u8 current_ap[6];
                        /* followed by SSID and Supported rates */
                        u8 variable[0];
-               } __attribute__ ((packed)) reassoc_req;
+               } __packed reassoc_req;
                struct {
                        __le16 reason_code;
-               } __attribute__ ((packed)) disassoc;
+               } __packed disassoc;
                struct {
                        __le64 timestamp;
                        __le16 beacon_int;
@@ -764,11 +769,11 @@ struct ieee80211_mgmt {
                        /* followed by some of SSID, Supported rates,
                         * FH Params, DS Params, CF Params, IBSS Params, TIM */
                        u8 variable[0];
-               } __attribute__ ((packed)) beacon;
+               } __packed beacon;
                struct {
                        /* only variable items: SSID, Supported rates */
                        u8 variable[0];
-               } __attribute__ ((packed)) probe_req;
+               } __packed probe_req;
                struct {
                        __le64 timestamp;
                        __le16 beacon_int;
@@ -776,7 +781,7 @@ struct ieee80211_mgmt {
                        /* followed by some of SSID, Supported rates,
                         * FH Params, DS Params, CF Params, IBSS Params */
                        u8 variable[0];
-               } __attribute__ ((packed)) probe_resp;
+               } __packed probe_resp;
                struct {
                        u8 category;
                        union {
@@ -785,55 +790,59 @@ struct ieee80211_mgmt {
                                        u8 dialog_token;
                                        u8 status_code;
                                        u8 variable[0];
-                               } __attribute__ ((packed)) wme_action;
+                               } __packed wme_action;
                                struct{
                                        u8 action_code;
                                        u8 element_id;
                                        u8 length;
                                        struct ieee80211_channel_sw_ie sw_elem;
-                               } __attribute__((packed)) chan_switch;
+                               } __packed chan_switch;
                                struct{
                                        u8 action_code;
                                        u8 dialog_token;
                                        u8 element_id;
                                        u8 length;
                                        struct ieee80211_msrment_ie msr_elem;
-                               } __attribute__((packed)) measurement;
+                               } __packed measurement;
                                struct{
                                        u8 action_code;
                                        u8 dialog_token;
                                        __le16 capab;
                                        __le16 timeout;
                                        __le16 start_seq_num;
-                               } __attribute__((packed)) addba_req;
+                               } __packed addba_req;
                                struct{
                                        u8 action_code;
                                        u8 dialog_token;
                                        __le16 status;
                                        __le16 capab;
                                        __le16 timeout;
-                               } __attribute__((packed)) addba_resp;
+                               } __packed addba_resp;
                                struct{
                                        u8 action_code;
                                        __le16 params;
                                        __le16 reason_code;
-                               } __attribute__((packed)) delba;
+                               } __packed delba;
                                struct {
                                        u8 action_code;
                                        u8 variable[0];
-                               } __attribute__((packed)) self_prot;
+                               } __packed self_prot;
                                struct{
                                        u8 action_code;
                                        u8 variable[0];
-                               } __attribute__((packed)) mesh_action;
+                               } __packed mesh_action;
                                struct {
                                        u8 action;
                                        u8 trans_id[WLAN_SA_QUERY_TR_ID_LEN];
-                               } __attribute__ ((packed)) sa_query;
+                               } __packed sa_query;
                                struct {
                                        u8 action;
                                        u8 smps_control;
-                               } __attribute__ ((packed)) ht_smps;
+                               } __packed ht_smps;
+                               struct {
+                                       u8 action_code;
+                                       u8 chanwidth;
+                               } __packed ht_notify_cw;
                                struct {
                                        u8 action_code;
                                        u8 dialog_token;
@@ -841,9 +850,9 @@ struct ieee80211_mgmt {
                                        u8 variable[0];
                                } __packed tdls_discover_resp;
                        } u;
-               } __attribute__ ((packed)) action;
+               } __packed action;
        } u;
-} __attribute__ ((packed));
+} __packed;
 
 /* Supported Rates value encodings in 802.11n-2009 7.3.2.2 */
 #define BSS_MEMBERSHIP_SELECTOR_HT_PHY 127
@@ -859,7 +868,7 @@ struct ieee80211_mmie {
        __le16 key_id;
        u8 sequence_number[6];
        u8 mic[8];
-} __attribute__ ((packed));
+} __packed;
 
 struct ieee80211_vendor_ie {
        u8 element_id;
@@ -874,20 +883,20 @@ struct ieee80211_rts {
        __le16 duration;
        u8 ra[6];
        u8 ta[6];
-} __attribute__ ((packed));
+} __packed;
 
 struct ieee80211_cts {
        __le16 frame_control;
        __le16 duration;
        u8 ra[6];
-} __attribute__ ((packed));
+} __packed;
 
 struct ieee80211_pspoll {
        __le16 frame_control;
        __le16 aid;
        u8 bssid[6];
        u8 ta[6];
-} __attribute__ ((packed));
+} __packed;
 
 /* TDLS */
 
@@ -980,7 +989,7 @@ struct ieee80211_bar {
        __u8 ta[6];
        __le16 control;
        __le16 start_seq_num;
-} __attribute__((packed)) __aligned(4);
+} __packed __aligned(4);
 
 /* 802.11 BA(R) control masks */
 #define IEEE80211_BAR_CTRL_ACK_POLICY_NORMAL   0x0000
@@ -1004,7 +1013,7 @@ struct ieee80211_ba {
 
        __le16 start_seq_num;
        u8 bitmap[8];
-} __attribute__((packed));
+} __packed;
 
 #define IEEE80211_HT_MCS_MASK_LEN              10
 
@@ -1022,7 +1031,7 @@ struct ieee80211_mcs_info {
        __le16 rx_highest;
        u8 tx_params;
        u8 reserved[3];
-} __attribute__((packed));
+} __packed;
 
 /* 802.11n HT capability MSC set */
 #define IEEE80211_HT_MCS_RX_HIGHEST_MASK       0x3ff
@@ -1061,7 +1070,7 @@ struct ieee80211_ht_cap {
        __le16 extended_ht_cap_info;
        __le32 tx_BF_cap_info;
        u8 antenna_selection_info;
-} __attribute__ ((packed));
+} __packed;
 
 /* 802.11n HT capabilities masks (for cap_info) */
 #define IEEE80211_HT_CAP_LDPC_CODING           0x0001
@@ -1132,7 +1141,7 @@ struct ieee80211_ht_operation {
        __le16 operation_mode;
        __le16 stbc_param;
        u8 basic_set[16];
-} __attribute__ ((packed));
+} __packed;
 
 /* for ht_param */
 #define IEEE80211_HT_PARAM_CHA_SEC_OFFSET              0x03
@@ -1341,16 +1350,21 @@ struct ieee80211_vht_operation {
 #define WLAN_CAPABILITY_SPECTRUM_MGMT  (1<<8)
 #define WLAN_CAPABILITY_QOS            (1<<9)
 #define WLAN_CAPABILITY_SHORT_SLOT_TIME        (1<<10)
+#define WLAN_CAPABILITY_APSD           (1<<11)
+#define WLAN_CAPABILITY_RADIO_MEASURE  (1<<12)
 #define WLAN_CAPABILITY_DSSS_OFDM      (1<<13)
+#define WLAN_CAPABILITY_DEL_BACK       (1<<14)
+#define WLAN_CAPABILITY_IMM_BACK       (1<<15)
 
 /* DMG (60gHz) 802.11ad */
 /* type - bits 0..1 */
+#define WLAN_CAPABILITY_DMG_TYPE_MASK          (3<<0)
 #define WLAN_CAPABILITY_DMG_TYPE_IBSS          (1<<0) /* Tx by: STA */
 #define WLAN_CAPABILITY_DMG_TYPE_PBSS          (2<<0) /* Tx by: PCP */
 #define WLAN_CAPABILITY_DMG_TYPE_AP            (3<<0) /* Tx by: AP */
 
 #define WLAN_CAPABILITY_DMG_CBAP_ONLY          (1<<2)
-#define WLAN_CAPABILITY_DMG_CBAP_SOURCE        (1<<3)
+#define WLAN_CAPABILITY_DMG_CBAP_SOURCE                (1<<3)
 #define WLAN_CAPABILITY_DMG_PRIVACY            (1<<4)
 #define WLAN_CAPABILITY_DMG_ECPAC              (1<<5)
 
@@ -1864,14 +1878,14 @@ struct ieee80211_country_ie_triplet {
                        u8 first_channel;
                        u8 num_channels;
                        s8 max_power;
-               } __attribute__ ((packed)) chans;
+               } __packed chans;
                struct {
                        u8 reg_extension_id;
                        u8 reg_class;
                        u8 coverage_class;
-               } __attribute__ ((packed)) ext;
+               } __packed ext;
        };
-} __attribute__ ((packed));
+} __packed;
 
 enum ieee80211_timeout_interval_type {
        WLAN_TIMEOUT_REASSOC_DEADLINE = 1 /* 802.11r */,
index ce61afb244913f1c892a878d5f6b90ac60bc287a..79a7467ad3f5e0e0f547f5263d8215b91b1d560d 100644 (file)
@@ -186,10 +186,15 @@ static void *__carlfw_find_desc(struct carlfw_file *file,
                                unsigned int len,
                                uint8_t compatible_revision)
 {
-       int scan = file->len, found = 0;
+       int scan, found = 0;
        struct carl9170fw_desc_head *tmp = NULL;
 
-       while (scan >= 0) {
+       /*
+        * Note: the last desc also has atleast a full desc_head.
+        * There's no reason for looking beyond that point.
+        */
+       scan = (file->len - 1) - (sizeof(*tmp) - CARL9170FW_MAGIC_SIZE);
+       while (scan > 0) {
                if (file->data[scan] == descid[CARL9170FW_MAGIC_SIZE - found - 1])
                        found++;
                else
@@ -202,10 +207,13 @@ static void *__carlfw_find_desc(struct carlfw_file *file,
        }
 
        if (found == CARL9170FW_MAGIC_SIZE) {
+               u16 tmp_desc_len;
+
                tmp = (void *) &file->data[scan];
+               tmp_desc_len = le16_to_cpu(tmp->length);
 
                if (!CHECK_HDR_VERSION(tmp, compatible_revision) &&
-                   (le16_to_cpu(tmp->length) >= len))
+                   (scan + tmp_desc_len <= file->len) && (tmp_desc_len >= len))
                        return tmp;
        }