aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIgal Chernobelsky <igalc@ti.com>2013-09-09 05:24:38 -0400
committerLuciano Coelho <luciano.coelho@intel.com>2013-10-23 02:47:42 -0400
commitc83cb8031bdd7923c7c5ea87accede4a5fc3282a (patch)
tree11e9538026d0ad340673301663b0cf9f0bc4776e
parent9d8146d4e1ddb967ac6acff8c820c1ae38dfa2fc (diff)
wlcore/wl18xx/wl12xx: FW log params per chip arch
FW memory block size and FW log end marker parameters are added to wl structure and are initialized per chip architecture. convert_hwaddr hw operation is added to convert chip dependent FW internal address. Copy from FW log is also simplified to copy the entire memory block as FW logger utility is repsponsible for parsing of FW log content. Signed-off-by: Igal Chernobelsky <igalc@ti.com> Signed-off-by: Eliad Peller <eliad@wizery.com> Signed-off-by: Luciano Coelho <luciano.coelho@intel.com>
-rw-r--r--drivers/net/wireless/ti/wl12xx/main.c9
-rw-r--r--drivers/net/wireless/ti/wl18xx/main.c9
-rw-r--r--drivers/net/wireless/ti/wlcore/hw_ops.h9
-rw-r--r--drivers/net/wireless/ti/wlcore/io.h4
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c44
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore.h7
-rw-r--r--drivers/net/wireless/ti/wlcore/wlcore_i.h2
7 files changed, 61 insertions, 23 deletions
diff --git a/drivers/net/wireless/ti/wl12xx/main.c b/drivers/net/wireless/ti/wl12xx/main.c
index d4d15de66e7a..be7129ba16ad 100644
--- a/drivers/net/wireless/ti/wl12xx/main.c
+++ b/drivers/net/wireless/ti/wl12xx/main.c
@@ -717,6 +717,9 @@ static int wl12xx_identify_chip(struct wl1271 *wl)
717 goto out; 717 goto out;
718 } 718 }
719 719
720 wl->fw_mem_block_size = 256;
721 wl->fwlog_end = 0x2000000;
722
720 /* common settings */ 723 /* common settings */
721 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY; 724 wl->scan_templ_id_2_4 = CMD_TEMPL_APP_PROBE_REQ_2_4_LEGACY;
722 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY; 725 wl->scan_templ_id_5 = CMD_TEMPL_APP_PROBE_REQ_5_LEGACY;
@@ -1649,6 +1652,11 @@ static bool wl12xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1649 return true; 1652 return true;
1650} 1653}
1651 1654
1655static u32 wl12xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1656{
1657 return hwaddr << 5;
1658}
1659
1652static int wl12xx_setup(struct wl1271 *wl); 1660static int wl12xx_setup(struct wl1271 *wl);
1653 1661
1654static struct wlcore_ops wl12xx_ops = { 1662static struct wlcore_ops wl12xx_ops = {
@@ -1685,6 +1693,7 @@ static struct wlcore_ops wl12xx_ops = {
1685 .channel_switch = wl12xx_cmd_channel_switch, 1693 .channel_switch = wl12xx_cmd_channel_switch,
1686 .pre_pkt_send = NULL, 1694 .pre_pkt_send = NULL,
1687 .set_peer_cap = wl12xx_set_peer_cap, 1695 .set_peer_cap = wl12xx_set_peer_cap,
1696 .convert_hwaddr = wl12xx_convert_hwaddr,
1688 .lnk_high_prio = wl12xx_lnk_high_prio, 1697 .lnk_high_prio = wl12xx_lnk_high_prio,
1689 .lnk_low_prio = wl12xx_lnk_low_prio, 1698 .lnk_low_prio = wl12xx_lnk_low_prio,
1690}; 1699};
diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c
index 447387512dde..ec37b16585df 100644
--- a/drivers/net/wireless/ti/wl18xx/main.c
+++ b/drivers/net/wireless/ti/wl18xx/main.c
@@ -686,6 +686,9 @@ static int wl18xx_identify_chip(struct wl1271 *wl)
686 goto out; 686 goto out;
687 } 687 }
688 688
689 wl->fw_mem_block_size = 272;
690 wl->fwlog_end = 0x40000000;
691
689 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4; 692 wl->scan_templ_id_2_4 = CMD_TEMPL_CFG_PROBE_REQ_2_4;
690 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5; 693 wl->scan_templ_id_5 = CMD_TEMPL_CFG_PROBE_REQ_5;
691 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC; 694 wl->sched_scan_templ_id_2_4 = CMD_TEMPL_PROBE_REQ_2_4_PERIODIC;
@@ -1605,6 +1608,11 @@ static bool wl18xx_lnk_low_prio(struct wl1271 *wl, u8 hlid,
1605 return lnk->allocated_pkts < thold; 1608 return lnk->allocated_pkts < thold;
1606} 1609}
1607 1610
1611static u32 wl18xx_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
1612{
1613 return hwaddr & ~0x80000000;
1614}
1615
1608static int wl18xx_setup(struct wl1271 *wl); 1616static int wl18xx_setup(struct wl1271 *wl);
1609 1617
1610static struct wlcore_ops wl18xx_ops = { 1618static struct wlcore_ops wl18xx_ops = {
@@ -1642,6 +1650,7 @@ static struct wlcore_ops wl18xx_ops = {
1642 .pre_pkt_send = wl18xx_pre_pkt_send, 1650 .pre_pkt_send = wl18xx_pre_pkt_send,
1643 .sta_rc_update = wl18xx_sta_rc_update, 1651 .sta_rc_update = wl18xx_sta_rc_update,
1644 .set_peer_cap = wl18xx_set_peer_cap, 1652 .set_peer_cap = wl18xx_set_peer_cap,
1653 .convert_hwaddr = wl18xx_convert_hwaddr,
1645 .lnk_high_prio = wl18xx_lnk_high_prio, 1654 .lnk_high_prio = wl18xx_lnk_high_prio,
1646 .lnk_low_prio = wl18xx_lnk_low_prio, 1655 .lnk_low_prio = wl18xx_lnk_low_prio,
1647}; 1656};
diff --git a/drivers/net/wireless/ti/wlcore/hw_ops.h b/drivers/net/wireless/ti/wlcore/hw_ops.h
index 7fd260c02a0a..51f8d634d32f 100644
--- a/drivers/net/wireless/ti/wlcore/hw_ops.h
+++ b/drivers/net/wireless/ti/wlcore/hw_ops.h
@@ -222,6 +222,15 @@ wlcore_hw_set_peer_cap(struct wl1271 *wl,
222 return 0; 222 return 0;
223} 223}
224 224
225static inline u32
226wlcore_hw_convert_hwaddr(struct wl1271 *wl, u32 hwaddr)
227{
228 if (!wl->ops->convert_hwaddr)
229 BUG_ON(1);
230
231 return wl->ops->convert_hwaddr(wl, hwaddr);
232}
233
225static inline bool 234static inline bool
226wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid, 235wlcore_hw_lnk_high_prio(struct wl1271 *wl, u8 hlid,
227 struct wl1271_link *lnk) 236 struct wl1271_link *lnk)
diff --git a/drivers/net/wireless/ti/wlcore/io.h b/drivers/net/wireless/ti/wlcore/io.h
index af7d9f9b3b4d..07e3d6a049ad 100644
--- a/drivers/net/wireless/ti/wlcore/io.h
+++ b/drivers/net/wireless/ti/wlcore/io.h
@@ -165,8 +165,8 @@ static inline int __must_check wlcore_read_hwaddr(struct wl1271 *wl, int hwaddr,
165 int physical; 165 int physical;
166 int addr; 166 int addr;
167 167
168 /* Addresses are stored internally as addresses to 32 bytes blocks */ 168 /* Convert from FW internal address which is chip arch dependent */
169 addr = hwaddr << 5; 169 addr = wl->ops->convert_hwaddr(wl, hwaddr);
170 170
171 physical = wlcore_translate_addr(wl, addr); 171 physical = wlcore_translate_addr(wl, addr);
172 172
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index 9a07f4f67885..a742860349df 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -800,19 +800,10 @@ void wl12xx_queue_recovery_work(struct wl1271 *wl)
800 800
801size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen) 801size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
802{ 802{
803 size_t len = 0; 803 size_t len;
804
805 /* The FW log is a length-value list, find where the log end */
806 while (len < maxlen) {
807 if (memblock[len] == 0)
808 break;
809 if (len + memblock[len] + 1 > maxlen)
810 break;
811 len += memblock[len] + 1;
812 }
813 804
814 /* Make sure we have enough room */ 805 /* Make sure we have enough room */
815 len = min(len, (size_t)(PAGE_SIZE - wl->fwlog_size)); 806 len = min(maxlen, (size_t)(PAGE_SIZE - wl->fwlog_size));
816 807
817 /* Fill the FW log file, consumed by the sysfs fwlog entry */ 808 /* Fill the FW log file, consumed by the sysfs fwlog entry */
818 memcpy(wl->fwlog + wl->fwlog_size, memblock, len); 809 memcpy(wl->fwlog + wl->fwlog_size, memblock, len);
@@ -821,10 +812,9 @@ size_t wl12xx_copy_fwlog(struct wl1271 *wl, u8 *memblock, size_t maxlen)
821 return len; 812 return len;
822} 813}
823 814
824#define WLCORE_FW_LOG_END 0x2000000
825
826static void wl12xx_read_fwlog_panic(struct wl1271 *wl) 815static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
827{ 816{
817 struct wlcore_partition_set part, old_part;
828 u32 addr; 818 u32 addr;
829 u32 offset; 819 u32 offset;
830 u32 end_of_log; 820 u32 end_of_log;
@@ -837,7 +827,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
837 827
838 wl1271_info("Reading FW panic log"); 828 wl1271_info("Reading FW panic log");
839 829
840 block = kmalloc(WL12XX_HW_BLOCK_SIZE, GFP_KERNEL); 830 block = kmalloc(wl->fw_mem_block_size, GFP_KERNEL);
841 if (!block) 831 if (!block)
842 return; 832 return;
843 833
@@ -863,17 +853,31 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
863 853
864 if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) { 854 if (wl->conf.fwlog.mode == WL12XX_FWLOG_CONTINUOUS) {
865 offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor); 855 offset = sizeof(addr) + sizeof(struct wl1271_rx_descriptor);
866 end_of_log = WLCORE_FW_LOG_END; 856 end_of_log = wl->fwlog_end;
867 } else { 857 } else {
868 offset = sizeof(addr); 858 offset = sizeof(addr);
869 end_of_log = addr; 859 end_of_log = addr;
870 } 860 }
871 861
862 old_part = wl->curr_part;
863 memset(&part, 0, sizeof(part));
864
872 /* Traverse the memory blocks linked list */ 865 /* Traverse the memory blocks linked list */
873 do { 866 do {
874 memset(block, 0, WL12XX_HW_BLOCK_SIZE); 867 part.mem.start = wlcore_hw_convert_hwaddr(wl, addr);
875 ret = wlcore_read_hwaddr(wl, addr, block, WL12XX_HW_BLOCK_SIZE, 868 part.mem.size = PAGE_SIZE;
876 false); 869
870 ret = wlcore_set_partition(wl, &part);
871 if (ret < 0) {
872 wl1271_error("%s: set_partition start=0x%X size=%d",
873 __func__, part.mem.start, part.mem.size);
874 goto out;
875 }
876
877 memset(block, 0, wl->fw_mem_block_size);
878 ret = wlcore_read_hwaddr(wl, addr, block,
879 wl->fw_mem_block_size, false);
880
877 if (ret < 0) 881 if (ret < 0)
878 goto out; 882 goto out;
879 883
@@ -884,8 +888,9 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
884 * on demand mode and is equal to 0x2000000 in continuous mode. 888 * on demand mode and is equal to 0x2000000 in continuous mode.
885 */ 889 */
886 addr = le32_to_cpup((__le32 *)block); 890 addr = le32_to_cpup((__le32 *)block);
891
887 if (!wl12xx_copy_fwlog(wl, block + offset, 892 if (!wl12xx_copy_fwlog(wl, block + offset,
888 WL12XX_HW_BLOCK_SIZE - offset)) 893 wl->fw_mem_block_size - offset))
889 break; 894 break;
890 } while (addr && (addr != end_of_log)); 895 } while (addr && (addr != end_of_log));
891 896
@@ -893,6 +898,7 @@ static void wl12xx_read_fwlog_panic(struct wl1271 *wl)
893 898
894out: 899out:
895 kfree(block); 900 kfree(block);
901 wlcore_set_partition(wl, &old_part);
896} 902}
897 903
898static void wlcore_print_recovery(struct wl1271 *wl) 904static void wlcore_print_recovery(struct wl1271 *wl)
diff --git a/drivers/net/wireless/ti/wlcore/wlcore.h b/drivers/net/wireless/ti/wlcore/wlcore.h
index f9272229d73d..06efc12a39e5 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore.h
@@ -110,6 +110,7 @@ struct wlcore_ops {
110 struct ieee80211_sta_ht_cap *ht_cap, 110 struct ieee80211_sta_ht_cap *ht_cap,
111 bool allow_ht_operation, 111 bool allow_ht_operation,
112 u32 rate_set, u8 hlid); 112 u32 rate_set, u8 hlid);
113 u32 (*convert_hwaddr)(struct wl1271 *wl, u32 hwaddr);
113 bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid, 114 bool (*lnk_high_prio)(struct wl1271 *wl, u8 hlid,
114 struct wl1271_link *lnk); 115 struct wl1271_link *lnk);
115 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid, 116 bool (*lnk_low_prio)(struct wl1271 *wl, u8 hlid,
@@ -290,6 +291,12 @@ struct wl1271 {
290 /* Number of valid bytes in the FW log buffer */ 291 /* Number of valid bytes in the FW log buffer */
291 ssize_t fwlog_size; 292 ssize_t fwlog_size;
292 293
294 /* FW log end marker */
295 u32 fwlog_end;
296
297 /* FW memory block size */
298 u32 fw_mem_block_size;
299
293 /* Sysfs FW log entry readers wait queue */ 300 /* Sysfs FW log entry readers wait queue */
294 wait_queue_head_t fwlog_waitq; 301 wait_queue_head_t fwlog_waitq;
295 302
diff --git a/drivers/net/wireless/ti/wlcore/wlcore_i.h b/drivers/net/wireless/ti/wlcore/wlcore_i.h
index 2a50e089b0e7..ce7261ce8b59 100644
--- a/drivers/net/wireless/ti/wlcore/wlcore_i.h
+++ b/drivers/net/wireless/ti/wlcore/wlcore_i.h
@@ -550,6 +550,4 @@ void wl1271_rx_filter_flatten_fields(struct wl12xx_rx_filter *filter,
550#define HW_HT_RATES_OFFSET 16 550#define HW_HT_RATES_OFFSET 16
551#define HW_MIMO_RATES_OFFSET 24 551#define HW_MIMO_RATES_OFFSET 24
552 552
553#define WL12XX_HW_BLOCK_SIZE 256
554
555#endif /* __WLCORE_I_H__ */ 553#endif /* __WLCORE_I_H__ */