wlcore: Propagate errors from wl1271_read
authorIdo Yariv <ido@wizery.com>
Mon, 18 Jun 2012 09:31:16 +0000 (12:31 +0300)
committerLuciano Coelho <coelho@ti.com>
Fri, 22 Jun 2012 07:46:34 +0000 (10:46 +0300)
Propagate errors from wl1271_read and request for recovery when
appropriate.
Also rename prefixes of wlcore functions which their prototypes had to
be changed.

Signed-off-by: Ido Yariv <ido@wizery.com>
Signed-off-by: Luciano Coelho <coelho@ti.com>
12 files changed:
drivers/net/wireless/ti/wl12xx/main.c
drivers/net/wireless/ti/wlcore/boot.c
drivers/net/wireless/ti/wlcore/cmd.c
drivers/net/wireless/ti/wlcore/event.c
drivers/net/wireless/ti/wlcore/hw_ops.h
drivers/net/wireless/ti/wlcore/io.h
drivers/net/wireless/ti/wlcore/main.c
drivers/net/wireless/ti/wlcore/rx.c
drivers/net/wireless/ti/wlcore/rx.h
drivers/net/wireless/ti/wlcore/tx.c
drivers/net/wireless/ti/wlcore/tx.h
drivers/net/wireless/ti/wlcore/wlcore.h

index 0d2fdca2aa32bf04fa8c18bce83d06ecbf57d9b2..916cee76b37f15f2c7cf9eaf11c9944910537414 100644 (file)
@@ -1162,13 +1162,13 @@ static u32 wl12xx_get_rx_packet_len(struct wl1271 *wl, void *rx_data,
        return data_len - sizeof(*desc) - desc->pad_len;
 }
 
-static void wl12xx_tx_delayed_compl(struct wl1271 *wl)
+static int wl12xx_tx_delayed_compl(struct wl1271 *wl)
 {
        if (wl->fw_status_1->tx_results_counter ==
            (wl->tx_results_count & 0xff))
-               return;
+               return 0;
 
-       wl1271_tx_complete(wl);
+       return wlcore_tx_complete(wl);
 }
 
 static int wl12xx_hw_init(struct wl1271 *wl)
index 0fda500c01c95f6dd9e92b9eafa7850647bbda18..d7abc505f2a3c22747b2990634731b974905eca5 100644 (file)
@@ -87,7 +87,9 @@ static int wlcore_boot_static_data(struct wl1271 *wl)
                goto out;
        }
 
-       wl1271_read(wl, wl->cmd_box_addr, static_data, len, false);
+       ret = wlcore_read(wl, wl->cmd_box_addr, static_data, len, false);
+       if (ret < 0)
+               goto out_free;
 
        ret = wlcore_boot_parse_fw_ver(wl, static_data);
        if (ret < 0)
index 885364ca43446ac9b8dd46642d597d26ec85a6b2..69f27d1fdcdf858e9e1cec482f3cb7aed1c00df3 100644 (file)
@@ -95,7 +95,10 @@ int wl1271_cmd_send(struct wl1271 *wl, u16 id, void *buf, size_t len,
        /* read back the status code of the command */
        if (res_len == 0)
                res_len = sizeof(struct wl1271_cmd_header);
-       wl1271_read(wl, wl->cmd_box_addr, cmd, res_len, false);
+
+       ret = wlcore_read(wl, wl->cmd_box_addr, cmd, res_len, false);
+       if (ret < 0)
+               goto fail;
 
        status = le16_to_cpu(cmd->status);
        if (status != CMD_STATUS_SUCCESS) {
@@ -141,11 +144,18 @@ static int wl1271_cmd_wait_for_event_or_timeout(struct wl1271 *wl, u32 mask)
                msleep(1);
 
                /* read from both event fields */
-               wl1271_read(wl, wl->mbox_ptr[0], events_vector,
-                           sizeof(*events_vector), false);
+               ret = wlcore_read(wl, wl->mbox_ptr[0], events_vector,
+                                 sizeof(*events_vector), false);
+               if (ret < 0)
+                       goto out;
+
                event = *events_vector & mask;
-               wl1271_read(wl, wl->mbox_ptr[1], events_vector,
-                           sizeof(*events_vector), false);
+
+               ret = wlcore_read(wl, wl->mbox_ptr[1], events_vector,
+                                 sizeof(*events_vector), false);
+               if (ret < 0)
+                       goto out;
+
                event |= *events_vector & mask;
        } while (!event);
 
index c976f04098655b08ad4812ddcbeadc6be0de79e6..858ac33f5980c33c125783aff9ccf21e6987b5ac 100644 (file)
@@ -301,8 +301,10 @@ int wl1271_event_handle(struct wl1271 *wl, u8 mbox_num)
                return -EINVAL;
 
        /* first we read the mbox descriptor */
-       wl1271_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
-                   sizeof(*wl->mbox), false);
+       ret = wlcore_read(wl, wl->mbox_ptr[mbox_num], wl->mbox,
+                         sizeof(*wl->mbox), false);
+       if (ret < 0)
+               return ret;
 
        /* process the descriptor */
        ret = wl1271_event_process(wl);
index 9e7787ba961062cf75eaffaf4b68461471d5e671..f44d586048ab441cb0d32b987e3b6eedb2b7abd4 100644 (file)
@@ -81,10 +81,12 @@ wlcore_hw_get_rx_packet_len(struct wl1271 *wl, void *rx_data, u32 data_len)
        return wl->ops->get_rx_packet_len(wl, rx_data, data_len);
 }
 
-static inline void wlcore_hw_tx_delayed_compl(struct wl1271 *wl)
+static inline int wlcore_hw_tx_delayed_compl(struct wl1271 *wl)
 {
        if (wl->ops->tx_delayed_compl)
-               wl->ops->tx_delayed_compl(wl);
+               return wl->ops->tx_delayed_compl(wl);
+
+       return 0;
 }
 
 static inline void wlcore_hw_tx_immediate_compl(struct wl1271 *wl)
index 2713ce11e21b2c310426c78dcd37a18dc5b4966b..d114bb42a9248c6ff3b905415edfeb3bab2c9318 100644 (file)
@@ -92,14 +92,14 @@ static inline void wl1271_raw_write32(struct wl1271 *wl, int addr, u32 val)
                             sizeof(wl->buffer_32), false);
 }
 
-static inline void wl1271_read(struct wl1271 *wl, int addr, void *buf,
-                              size_t len, bool fixed)
+static inline int wlcore_read(struct wl1271 *wl, int addr, void *buf,
+                             size_t len, bool fixed)
 {
        int physical;
 
        physical = wlcore_translate_addr(wl, addr);
 
-       wlcore_raw_read(wl, physical, buf, len, fixed);
+       return wlcore_raw_read(wl, physical, buf, len, fixed);
 }
 
 static inline void wl1271_write(struct wl1271 *wl, int addr, void *buf,
@@ -118,10 +118,10 @@ static inline void wlcore_write_data(struct wl1271 *wl, int reg, void *buf,
        wl1271_write(wl, wl->rtable[reg], buf, len, fixed);
 }
 
-static inline void wlcore_read_data(struct wl1271 *wl, int reg, void *buf,
+static inline int wlcore_read_data(struct wl1271 *wl, int reg, void *buf,
                                    size_t len, bool fixed)
 {
-       wl1271_read(wl, wl->rtable[reg], buf, len, fixed);
+       return wlcore_read(wl, wl->rtable[reg], buf, len, fixed);
 }
 
 static inline void wl1271_read_hwaddr(struct wl1271 *wl, int hwaddr,
index 085cd17fa07436dd77eeff8f5103efcfb985b735..deb22f8e193d062b4c1b442644cdf0c9004a891c 100644 (file)
@@ -572,7 +572,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
                if (likely(intr & WL1271_ACX_INTR_DATA)) {
                        wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_DATA");
 
-                       wl12xx_rx(wl, wl->fw_status_1);
+                       ret = wlcore_rx(wl, wl->fw_status_1);
+                       if (ret < 0) {
+                               wl12xx_queue_recovery_work(wl);
+                               goto out;
+                       }
 
                        /* Check if any tx blocks were freed */
                        spin_lock_irqsave(&wl->wl_lock, flags);
@@ -589,7 +593,11 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
                        }
 
                        /* check for tx results */
-                       wlcore_hw_tx_delayed_compl(wl);
+                       ret = wlcore_hw_tx_delayed_compl(wl);
+                       if (ret < 0) {
+                               wl12xx_queue_recovery_work(wl);
+                               goto out;
+                       }
 
                        /* Make sure the deferred queues don't get too long */
                        defer_count = skb_queue_len(&wl->deferred_tx_queue) +
@@ -600,12 +608,20 @@ static irqreturn_t wl1271_irq(int irq, void *cookie)
 
                if (intr & WL1271_ACX_INTR_EVENT_A) {
                        wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_A");
-                       wl1271_event_handle(wl, 0);
+                       ret = wl1271_event_handle(wl, 0);
+                       if (ret < 0) {
+                               wl12xx_queue_recovery_work(wl);
+                               goto out;
+                       }
                }
 
                if (intr & WL1271_ACX_INTR_EVENT_B) {
                        wl1271_debug(DEBUG_IRQ, "WL1271_ACX_INTR_EVENT_B");
-                       wl1271_event_handle(wl, 1);
+                       ret = wl1271_event_handle(wl, 1);
+                       if (ret < 0) {
+                               wl12xx_queue_recovery_work(wl);
+                               goto out;
+                       }
                }
 
                if (intr & WL1271_ACX_INTR_INIT_COMPLETE)
index a1db4e032409ffd2bc87f53859f8a7b7f1e10cd8..59d0956c5d09d9ed00ed0423a936ececa134d9fa 100644 (file)
@@ -200,7 +200,7 @@ static int wl1271_rx_handle_data(struct wl1271 *wl, u8 *data, u32 length,
        return is_data;
 }
 
-void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
+int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
 {
        unsigned long active_hlids[BITS_TO_LONGS(WL12XX_MAX_LINKS)] = {0};
        u32 buf_size;
@@ -211,6 +211,7 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
        u32 pkt_offset, des;
        u8 hlid;
        enum wl_rx_buf_align rx_align;
+       int ret = 0;
 
        while (drv_rx_counter != fw_rx_counter) {
                buf_size = 0;
@@ -235,8 +236,11 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
                /* Read all available packets at once */
                des = le32_to_cpu(status->rx_pkt_descs[drv_rx_counter]);
                wlcore_hw_prepare_read(wl, des, buf_size);
-               wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
-                                buf_size, true);
+
+               ret = wlcore_read_data(wl, REG_SLV_MEM_DATA, wl->aggr_buf,
+                                      buf_size, true);
+               if (ret < 0)
+                       goto out;
 
                /* Split data into separate packets */
                pkt_offset = 0;
@@ -278,6 +282,9 @@ void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status)
                               wl->rx_counter);
 
        wl12xx_rearm_rx_streaming(wl, active_hlids);
+
+out:
+       return ret;
 }
 
 #ifdef CONFIG_PM
index 4324a427e8353b59355ad8bc254def7f83a5eb06..79f7839a06e27e74bd786308d58d3f2b007bc80a 100644 (file)
@@ -143,7 +143,7 @@ struct wl1271_rx_descriptor {
        u8  reserved;
 } __packed;
 
-void wl12xx_rx(struct wl1271 *wl, struct wl_fw_status_1 *status);
+int wlcore_rx(struct wl1271 *wl, struct wl_fw_status_1 *status);
 u8 wl1271_rate_to_idx(int rate, enum ieee80211_band band);
 int wl1271_rx_filter_enable(struct wl1271 *wl,
                            int index, bool enable,
index 8ee82b9f93f4cf48a75a7cadfbddcf62a38cfd94..fc890cba8d3981b648b052d5cb411c7eb52957bf 100644 (file)
@@ -881,16 +881,20 @@ static void wl1271_tx_complete_packet(struct wl1271 *wl,
 }
 
 /* Called upon reception of a TX complete interrupt */
-void wl1271_tx_complete(struct wl1271 *wl)
+int wlcore_tx_complete(struct wl1271 *wl)
 {
        struct wl1271_acx_mem_map *memmap =
                (struct wl1271_acx_mem_map *)wl->target_mem_map;
        u32 count, fw_counter;
        u32 i;
+       int ret;
 
        /* read the tx results from the chipset */
-       wl1271_read(wl, le32_to_cpu(memmap->tx_result),
-                   wl->tx_res_if, sizeof(*wl->tx_res_if), false);
+       ret = wlcore_read(wl, le32_to_cpu(memmap->tx_result),
+                         wl->tx_res_if, sizeof(*wl->tx_res_if), false);
+       if (ret < 0)
+               goto out;
+
        fw_counter = le32_to_cpu(wl->tx_res_if->tx_result_fw_counter);
 
        /* write host counter to chipset (to ack) */
@@ -916,8 +920,11 @@ void wl1271_tx_complete(struct wl1271 *wl)
 
                wl->tx_results_count++;
        }
+
+out:
+       return ret;
 }
-EXPORT_SYMBOL(wl1271_tx_complete);
+EXPORT_SYMBOL(wlcore_tx_complete);
 
 void wl1271_tx_reset_link_queues(struct wl1271 *wl, u8 hlid)
 {
index fa4be1b911352671219f6b9c082532c94357acc9..10540944a80cb555ae9da353a41b2583bc5a19d1 100644 (file)
@@ -235,7 +235,7 @@ static inline int wl1271_tx_total_queue_count(struct wl1271 *wl)
 
 void wl1271_tx_work(struct work_struct *work);
 void wl1271_tx_work_locked(struct wl1271 *wl);
-void wl1271_tx_complete(struct wl1271 *wl);
+int wlcore_tx_complete(struct wl1271 *wl);
 void wl12xx_tx_reset_wlvif(struct wl1271 *wl, struct wl12xx_vif *wlvif);
 void wl12xx_tx_reset(struct wl1271 *wl);
 void wl1271_tx_flush(struct wl1271 *wl);
index 205d8ad2b761daaa9ee4ba2fb8df6f315afddf52..fd37307ebb93affe199be47e7f6fec6e3fbeb66e 100644 (file)
@@ -56,7 +56,7 @@ struct wlcore_ops {
        void (*prepare_read)(struct wl1271 *wl, u32 rx_desc, u32 len);
        u32 (*get_rx_packet_len)(struct wl1271 *wl, void *rx_data,
                                 u32 data_len);
-       void (*tx_delayed_compl)(struct wl1271 *wl);
+       int (*tx_delayed_compl)(struct wl1271 *wl);
        void (*tx_immediate_compl)(struct wl1271 *wl);
        int (*hw_init)(struct wl1271 *wl);
        int (*init_vif)(struct wl1271 *wl, struct wl12xx_vif *wlvif);