Merge branch 'for-linus' of git://git.infradead.org/~dedekind/ubi-2.6
[sfrench/cifs-2.6.git] / drivers / net / wireless / p54common.c
index 2c63cf0ad2cdb3cfe11936e40147fd89b390f0da..d191e055a788210e4a2b6343f4815b1bf120180d 100644 (file)
@@ -54,7 +54,7 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                u32 code = le32_to_cpu(bootrec->code);
                switch (code) {
                case BR_CODE_COMPONENT_ID:
-                       switch (be32_to_cpu(*bootrec->data)) {
+                       switch (be32_to_cpu(*(__be32 *)bootrec->data)) {
                        case FW_FMAC:
                                printk(KERN_INFO "p54: FreeMAC firmware\n");
                                break;
@@ -78,14 +78,14 @@ void p54_parse_firmware(struct ieee80211_hw *dev, const struct firmware *fw)
                                fw_version = (unsigned char*)bootrec->data;
                        break;
                case BR_CODE_DESCR:
-                       priv->rx_start = le32_to_cpu(bootrec->data[1]);
+                       priv->rx_start = le32_to_cpu(((__le32 *)bootrec->data)[1]);
                        /* FIXME add sanity checking */
-                       priv->rx_end = le32_to_cpu(bootrec->data[2]) - 0x3500;
+                       priv->rx_end = le32_to_cpu(((__le32 *)bootrec->data)[2]) - 0x3500;
                        break;
                case BR_CODE_EXPOSED_IF:
                        exp_if = (struct bootrec_exp_if *) bootrec->data;
                        for (i = 0; i < (len * sizeof(*exp_if) / 4); i++)
-                               if (exp_if[i].if_id == 0x1a)
+                               if (exp_if[i].if_id == cpu_to_le16(0x1a))
                                        priv->fw_var = le16_to_cpu(exp_if[i].variant);
                        break;
                case BR_CODE_DEPENDENT_IF:
@@ -166,18 +166,23 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
        struct p54_common *priv = dev->priv;
        struct eeprom_pda_wrap *wrap = NULL;
        struct pda_entry *entry;
-       int i = 0;
        unsigned int data_len, entry_len;
        void *tmp;
        int err;
+       u8 *end = (u8 *)eeprom + len;
 
        wrap = (struct eeprom_pda_wrap *) eeprom;
-       entry = (void *)wrap->data + wrap->len;
-       i += 2;
-       i += le16_to_cpu(entry->len)*2;
-       while (i < len) {
+       entry = (void *)wrap->data + le16_to_cpu(wrap->len);
+
+       /* verify that at least the entry length/code fits */
+       while ((u8 *)entry <= end - sizeof(*entry)) {
                entry_len = le16_to_cpu(entry->len);
                data_len = ((entry_len - 1) << 1);
+
+               /* abort if entry exceeds whole structure */
+               if ((u8 *)entry + sizeof(*entry) + data_len > end)
+                       break;
+
                switch (le16_to_cpu(entry->code)) {
                case PDR_MAC_ADDRESS:
                        SET_IEEE80211_PERM_ADDR(dev, entry->data);
@@ -249,13 +254,12 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
                        priv->version = *(u8 *)(entry->data + 1);
                        break;
                case PDR_END:
-                       i = len;
+                       /* make it overrun */
+                       entry_len = len;
                        break;
                }
 
                entry = (void *)entry + (entry_len + 1)*2;
-               i += 2;
-               i += entry_len*2;
        }
 
        if (!priv->iq_autocal || !priv->output_limit || !priv->curve_data) {
@@ -314,6 +318,7 @@ static void p54_rx_data(struct ieee80211_hw *dev, struct sk_buff *skb)
        rx_status.phymode = MODE_IEEE80211G;
        rx_status.antenna = hdr->antenna;
        rx_status.mactime = le64_to_cpu(hdr->timestamp);
+       rx_status.flag |= RX_FLAG_TSFT;
 
        skb_pull(skb, sizeof(*hdr));
        skb_trim(skb, le16_to_cpu(hdr->len));
@@ -374,7 +379,7 @@ static void p54_rx_frame_sent(struct ieee80211_hw *dev, struct sk_buff *skb)
                        if ((entry_hdr->magic1 & cpu_to_le16(0x4000)) != 0)
                                pad = entry_data->align[0];
 
-                       if (!status.control.flags & IEEE80211_TXCTL_NO_ACK) {
+                       if (!(status.control.flags & IEEE80211_TXCTL_NO_ACK)) {
                                if (!(payload->status & 0x01))
                                        status.flags |= IEEE80211_TX_STATUS_ACK;
                                else
@@ -577,7 +582,7 @@ static int p54_set_filter(struct ieee80211_hw *dev, u16 filter_type,
        struct p54_tx_control_filter *filter;
 
        hdr = kzalloc(sizeof(*hdr) + sizeof(*filter) +
-                     priv->tx_hdr_len, GFP_KERNEL);
+                     priv->tx_hdr_len, GFP_ATOMIC);
        if (!hdr)
                return -ENOMEM;
 
@@ -853,7 +858,8 @@ static int p54_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
        return ret;
 }
 
-static int p54_config_interface(struct ieee80211_hw *dev, int if_id,
+static int p54_config_interface(struct ieee80211_hw *dev,
+                               struct ieee80211_vif *vif,
                                struct ieee80211_if_conf *conf)
 {
        struct p54_common *priv = dev->priv;