diff options
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi')
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/Kconfig | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/Makefile | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/bus.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/cfg80211.c | 17 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.c | 14 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/commands.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/debug.h | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/debugfs.c | 123 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/hal.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/hal.h | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/iwm.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/main.c | 9 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/rx.c | 79 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/sdio.c | 19 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/trace.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/trace.h | 283 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/tx.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwmc3200wifi/umac.h | 2 |
18 files changed, 428 insertions, 180 deletions
diff --git a/drivers/net/wireless/iwmc3200wifi/Kconfig b/drivers/net/wireless/iwmc3200wifi/Kconfig index b9d34a766964..03f998d098c5 100644 --- a/drivers/net/wireless/iwmc3200wifi/Kconfig +++ b/drivers/net/wireless/iwmc3200wifi/Kconfig | |||
@@ -17,7 +17,7 @@ config IWM | |||
17 | config IWM_DEBUG | 17 | config IWM_DEBUG |
18 | bool "Enable full debugging output in iwmc3200wifi" | 18 | bool "Enable full debugging output in iwmc3200wifi" |
19 | depends on IWM && DEBUG_FS | 19 | depends on IWM && DEBUG_FS |
20 | ---help--- | 20 | help |
21 | This option will enable debug tracing and setting for iwm | 21 | This option will enable debug tracing and setting for iwm |
22 | 22 | ||
23 | You can set the debug level and module through debugfs. By | 23 | You can set the debug level and module through debugfs. By |
@@ -30,3 +30,10 @@ config IWM_DEBUG | |||
30 | Or, if you want the full debug, for all modules: | 30 | Or, if you want the full debug, for all modules: |
31 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level | 31 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/level |
32 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules | 32 | echo 0xff > /sys/kernel/debug/iwm/phyN/debug/modules |
33 | |||
34 | config IWM_TRACING | ||
35 | bool "Enable event tracing for iwmc3200wifi" | ||
36 | depends on IWM && EVENT_TRACING | ||
37 | help | ||
38 | Say Y here to trace all the commands and responses between | ||
39 | the driver and firmware (including TX/RX frames) with ftrace. | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/Makefile b/drivers/net/wireless/iwmc3200wifi/Makefile index d34291b652d3..cdc7e07ba113 100644 --- a/drivers/net/wireless/iwmc3200wifi/Makefile +++ b/drivers/net/wireless/iwmc3200wifi/Makefile | |||
@@ -3,3 +3,8 @@ iwmc3200wifi-objs += main.o netdev.o rx.o tx.o sdio.o hal.o fw.o | |||
3 | iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o | 3 | iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o |
4 | 4 | ||
5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o | 5 | iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o |
6 | iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o | ||
7 | |||
8 | CFLAGS_trace.o := -I$(src) | ||
9 | |||
10 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/bus.h b/drivers/net/wireless/iwmc3200wifi/bus.h index 836663eec257..62edd5888a7b 100644 --- a/drivers/net/wireless/iwmc3200wifi/bus.h +++ b/drivers/net/wireless/iwmc3200wifi/bus.h | |||
@@ -31,7 +31,7 @@ struct iwm_if_ops { | |||
31 | int (*disable)(struct iwm_priv *iwm); | 31 | int (*disable)(struct iwm_priv *iwm); |
32 | int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); | 32 | int (*send_chunk)(struct iwm_priv *iwm, u8* buf, int count); |
33 | 33 | ||
34 | int (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); | 34 | void (*debugfs_init)(struct iwm_priv *iwm, struct dentry *parent_dir); |
35 | void (*debugfs_exit)(struct iwm_priv *iwm); | 35 | void (*debugfs_exit)(struct iwm_priv *iwm); |
36 | 36 | ||
37 | const char *umac_name; | 37 | const char *umac_name; |
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c index a1d45cce0ebc..902e95f70f6e 100644 --- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c +++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c | |||
@@ -264,7 +264,7 @@ static int iwm_cfg80211_get_station(struct wiphy *wiphy, | |||
264 | int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) | 264 | int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) |
265 | { | 265 | { |
266 | struct wiphy *wiphy = iwm_to_wiphy(iwm); | 266 | struct wiphy *wiphy = iwm_to_wiphy(iwm); |
267 | struct iwm_bss_info *bss, *next; | 267 | struct iwm_bss_info *bss; |
268 | struct iwm_umac_notif_bss_info *umac_bss; | 268 | struct iwm_umac_notif_bss_info *umac_bss; |
269 | struct ieee80211_mgmt *mgmt; | 269 | struct ieee80211_mgmt *mgmt; |
270 | struct ieee80211_channel *channel; | 270 | struct ieee80211_channel *channel; |
@@ -272,7 +272,7 @@ int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) | |||
272 | s32 signal; | 272 | s32 signal; |
273 | int freq; | 273 | int freq; |
274 | 274 | ||
275 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) { | 275 | list_for_each_entry(bss, &iwm->bss_list, node) { |
276 | umac_bss = bss->bss; | 276 | umac_bss = bss->bss; |
277 | mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); | 277 | mgmt = (struct ieee80211_mgmt *)(umac_bss->frame_buf); |
278 | 278 | ||
@@ -726,23 +726,26 @@ static int iwm_cfg80211_set_power_mgmt(struct wiphy *wiphy, | |||
726 | CFG_POWER_INDEX, iwm->conf.power_index); | 726 | CFG_POWER_INDEX, iwm->conf.power_index); |
727 | } | 727 | } |
728 | 728 | ||
729 | int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, | 729 | static int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, |
730 | struct cfg80211_pmksa *pmksa) | 730 | struct net_device *netdev, |
731 | struct cfg80211_pmksa *pmksa) | ||
731 | { | 732 | { |
732 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 733 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
733 | 734 | ||
734 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); | 735 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_ADD); |
735 | } | 736 | } |
736 | 737 | ||
737 | int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, | 738 | static int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, |
738 | struct cfg80211_pmksa *pmksa) | 739 | struct net_device *netdev, |
740 | struct cfg80211_pmksa *pmksa) | ||
739 | { | 741 | { |
740 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 742 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
741 | 743 | ||
742 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); | 744 | return iwm_send_pmkid_update(iwm, pmksa, IWM_CMD_PMKID_DEL); |
743 | } | 745 | } |
744 | 746 | ||
745 | int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) | 747 | static int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, |
748 | struct net_device *netdev) | ||
746 | { | 749 | { |
747 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); | 750 | struct iwm_priv *iwm = wiphy_to_iwm(wiphy); |
748 | struct cfg80211_pmksa pmksa; | 751 | struct cfg80211_pmksa pmksa; |
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c index 42df7262f9f7..330c7d9cf101 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.c +++ b/drivers/net/wireless/iwmc3200wifi/commands.c | |||
@@ -507,7 +507,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address, | |||
507 | return ret; | 507 | return ret; |
508 | } | 508 | } |
509 | 509 | ||
510 | /* When succeding, the send_target routine returns the seq number */ | 510 | /* When succeeding, the send_target routine returns the seq number */ |
511 | seq_num = ret; | 511 | seq_num = ret; |
512 | 512 | ||
513 | ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, | 513 | ret = wait_event_interruptible_timeout(iwm->nonwifi_queue, |
@@ -782,10 +782,9 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm) | |||
782 | return 0; | 782 | return 0; |
783 | } | 783 | } |
784 | 784 | ||
785 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | 785 | int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm) |
786 | { | 786 | { |
787 | struct iwm_umac_invalidate_profile invalid; | 787 | struct iwm_umac_invalidate_profile invalid; |
788 | int ret; | ||
789 | 788 | ||
790 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; | 789 | invalid.hdr.oid = UMAC_WIFI_IF_CMD_INVALIDATE_PROFILE; |
791 | invalid.hdr.buf_size = | 790 | invalid.hdr.buf_size = |
@@ -794,7 +793,14 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | |||
794 | 793 | ||
795 | invalid.reason = WLAN_REASON_UNSPECIFIED; | 794 | invalid.reason = WLAN_REASON_UNSPECIFIED; |
796 | 795 | ||
797 | ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); | 796 | return iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); |
797 | } | ||
798 | |||
799 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) | ||
800 | { | ||
801 | int ret; | ||
802 | |||
803 | ret = __iwm_invalidate_mlme_profile(iwm); | ||
798 | if (ret) | 804 | if (ret) |
799 | return ret; | 805 | return ret; |
800 | 806 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.h b/drivers/net/wireless/iwmc3200wifi/commands.h index 3dfd9f0e9003..7e16bcf59978 100644 --- a/drivers/net/wireless/iwmc3200wifi/commands.h +++ b/drivers/net/wireless/iwmc3200wifi/commands.h | |||
@@ -488,6 +488,7 @@ int iwm_umac_set_config_var(struct iwm_priv *iwm, u16 key, | |||
488 | void *payload, u16 payload_size); | 488 | void *payload, u16 payload_size); |
489 | int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); | 489 | int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); |
490 | int iwm_send_mlme_profile(struct iwm_priv *iwm); | 490 | int iwm_send_mlme_profile(struct iwm_priv *iwm); |
491 | int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm); | ||
491 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); | 492 | int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); |
492 | int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); | 493 | int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); |
493 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); | 494 | int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); |
diff --git a/drivers/net/wireless/iwmc3200wifi/debug.h b/drivers/net/wireless/iwmc3200wifi/debug.h index e35c9b693d1f..a0c13a49ab3c 100644 --- a/drivers/net/wireless/iwmc3200wifi/debug.h +++ b/drivers/net/wireless/iwmc3200wifi/debug.h | |||
@@ -113,13 +113,10 @@ struct iwm_debugfs { | |||
113 | }; | 113 | }; |
114 | 114 | ||
115 | #ifdef CONFIG_IWM_DEBUG | 115 | #ifdef CONFIG_IWM_DEBUG |
116 | int iwm_debugfs_init(struct iwm_priv *iwm); | 116 | void iwm_debugfs_init(struct iwm_priv *iwm); |
117 | void iwm_debugfs_exit(struct iwm_priv *iwm); | 117 | void iwm_debugfs_exit(struct iwm_priv *iwm); |
118 | #else | 118 | #else |
119 | static inline int iwm_debugfs_init(struct iwm_priv *iwm) | 119 | static inline void iwm_debugfs_init(struct iwm_priv *iwm) {} |
120 | { | ||
121 | return 0; | ||
122 | } | ||
123 | static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} | 120 | static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} |
124 | #endif | 121 | #endif |
125 | 122 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/debugfs.c b/drivers/net/wireless/iwmc3200wifi/debugfs.c index cbb81befdb55..53b0b7711f02 100644 --- a/drivers/net/wireless/iwmc3200wifi/debugfs.c +++ b/drivers/net/wireless/iwmc3200wifi/debugfs.c | |||
@@ -48,12 +48,11 @@ static struct { | |||
48 | 48 | ||
49 | #define add_dbg_module(dbg, name, id, initlevel) \ | 49 | #define add_dbg_module(dbg, name, id, initlevel) \ |
50 | do { \ | 50 | do { \ |
51 | struct dentry *d; \ | ||
52 | dbg.dbg_module[id] = (initlevel); \ | 51 | dbg.dbg_module[id] = (initlevel); \ |
53 | d = debugfs_create_x8(name, 0600, dbg.dbgdir, \ | 52 | dbg.dbg_module_dentries[id] = \ |
54 | &(dbg.dbg_module[id])); \ | 53 | debugfs_create_x8(name, 0600, \ |
55 | if (!IS_ERR(d)) \ | 54 | dbg.dbgdir, \ |
56 | dbg.dbg_module_dentries[id] = d; \ | 55 | &(dbg.dbg_module[id])); \ |
57 | } while (0) | 56 | } while (0) |
58 | 57 | ||
59 | static int iwm_debugfs_u32_read(void *data, u64 *val) | 58 | static int iwm_debugfs_u32_read(void *data, u64 *val) |
@@ -266,7 +265,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
266 | size_t count, loff_t *ppos) | 265 | size_t count, loff_t *ppos) |
267 | { | 266 | { |
268 | struct iwm_priv *iwm = filp->private_data; | 267 | struct iwm_priv *iwm = filp->private_data; |
269 | struct iwm_rx_ticket_node *ticket, *next; | 268 | struct iwm_rx_ticket_node *ticket; |
270 | char *buf; | 269 | char *buf; |
271 | int buf_len = 4096, i; | 270 | int buf_len = 4096, i; |
272 | size_t len = 0; | 271 | size_t len = 0; |
@@ -281,7 +280,8 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
281 | if (!buf) | 280 | if (!buf) |
282 | return -ENOMEM; | 281 | return -ENOMEM; |
283 | 282 | ||
284 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { | 283 | spin_lock(&iwm->ticket_lock); |
284 | list_for_each_entry(ticket, &iwm->rx_tickets, node) { | ||
285 | len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", | 285 | len += snprintf(buf + len, buf_len - len, "Ticket #%d\n", |
286 | ticket->ticket->id); | 286 | ticket->ticket->id); |
287 | len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", | 287 | len += snprintf(buf + len, buf_len - len, "\taction: 0x%x\n", |
@@ -289,14 +289,17 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
289 | len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", | 289 | len += snprintf(buf + len, buf_len - len, "\tflags: 0x%x\n", |
290 | ticket->ticket->flags); | 290 | ticket->ticket->flags); |
291 | } | 291 | } |
292 | spin_unlock(&iwm->ticket_lock); | ||
292 | 293 | ||
293 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | 294 | for (i = 0; i < IWM_RX_ID_HASH; i++) { |
294 | struct iwm_rx_packet *packet, *nxt; | 295 | struct iwm_rx_packet *packet; |
295 | struct list_head *pkt_list = &iwm->rx_packets[i]; | 296 | struct list_head *pkt_list = &iwm->rx_packets[i]; |
297 | |||
296 | if (!list_empty(pkt_list)) { | 298 | if (!list_empty(pkt_list)) { |
297 | len += snprintf(buf + len, buf_len - len, | 299 | len += snprintf(buf + len, buf_len - len, |
298 | "Packet hash #%d\n", i); | 300 | "Packet hash #%d\n", i); |
299 | list_for_each_entry_safe(packet, nxt, pkt_list, node) { | 301 | spin_lock(&iwm->packet_lock[i]); |
302 | list_for_each_entry(packet, pkt_list, node) { | ||
300 | len += snprintf(buf + len, buf_len - len, | 303 | len += snprintf(buf + len, buf_len - len, |
301 | "\tPacket id: %d\n", | 304 | "\tPacket id: %d\n", |
302 | packet->id); | 305 | packet->id); |
@@ -304,6 +307,7 @@ static ssize_t iwm_debugfs_rx_ticket_read(struct file *filp, | |||
304 | "\tPacket length: %lu\n", | 307 | "\tPacket length: %lu\n", |
305 | packet->pkt_size); | 308 | packet->pkt_size); |
306 | } | 309 | } |
310 | spin_unlock(&iwm->packet_lock[i]); | ||
307 | } | 311 | } |
308 | } | 312 | } |
309 | 313 | ||
@@ -418,89 +422,29 @@ static const struct file_operations iwm_debugfs_fw_err_fops = { | |||
418 | .read = iwm_debugfs_fw_err_read, | 422 | .read = iwm_debugfs_fw_err_read, |
419 | }; | 423 | }; |
420 | 424 | ||
421 | int iwm_debugfs_init(struct iwm_priv *iwm) | 425 | void iwm_debugfs_init(struct iwm_priv *iwm) |
422 | { | 426 | { |
423 | int i, result; | 427 | int i; |
424 | char devdir[16]; | ||
425 | 428 | ||
426 | iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); | 429 | iwm->dbg.rootdir = debugfs_create_dir(KBUILD_MODNAME, NULL); |
427 | result = PTR_ERR(iwm->dbg.rootdir); | 430 | iwm->dbg.devdir = debugfs_create_dir(wiphy_name(iwm_to_wiphy(iwm)), |
428 | if (!result || IS_ERR(iwm->dbg.rootdir)) { | 431 | iwm->dbg.rootdir); |
429 | if (result == -ENODEV) { | ||
430 | IWM_ERR(iwm, "DebugFS (CONFIG_DEBUG_FS) not " | ||
431 | "enabled in kernel config\n"); | ||
432 | result = 0; /* No debugfs support */ | ||
433 | } | ||
434 | IWM_ERR(iwm, "Couldn't create rootdir: %d\n", result); | ||
435 | goto error; | ||
436 | } | ||
437 | |||
438 | snprintf(devdir, sizeof(devdir), "%s", wiphy_name(iwm_to_wiphy(iwm))); | ||
439 | |||
440 | iwm->dbg.devdir = debugfs_create_dir(devdir, iwm->dbg.rootdir); | ||
441 | result = PTR_ERR(iwm->dbg.devdir); | ||
442 | if (IS_ERR(iwm->dbg.devdir) && (result != -ENODEV)) { | ||
443 | IWM_ERR(iwm, "Couldn't create devdir: %d\n", result); | ||
444 | goto error; | ||
445 | } | ||
446 | |||
447 | iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); | 432 | iwm->dbg.dbgdir = debugfs_create_dir("debug", iwm->dbg.devdir); |
448 | result = PTR_ERR(iwm->dbg.dbgdir); | ||
449 | if (IS_ERR(iwm->dbg.dbgdir) && (result != -ENODEV)) { | ||
450 | IWM_ERR(iwm, "Couldn't create dbgdir: %d\n", result); | ||
451 | goto error; | ||
452 | } | ||
453 | |||
454 | iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); | 433 | iwm->dbg.rxdir = debugfs_create_dir("rx", iwm->dbg.devdir); |
455 | result = PTR_ERR(iwm->dbg.rxdir); | ||
456 | if (IS_ERR(iwm->dbg.rxdir) && (result != -ENODEV)) { | ||
457 | IWM_ERR(iwm, "Couldn't create rx dir: %d\n", result); | ||
458 | goto error; | ||
459 | } | ||
460 | |||
461 | iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); | 434 | iwm->dbg.txdir = debugfs_create_dir("tx", iwm->dbg.devdir); |
462 | result = PTR_ERR(iwm->dbg.txdir); | ||
463 | if (IS_ERR(iwm->dbg.txdir) && (result != -ENODEV)) { | ||
464 | IWM_ERR(iwm, "Couldn't create tx dir: %d\n", result); | ||
465 | goto error; | ||
466 | } | ||
467 | |||
468 | iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); | 435 | iwm->dbg.busdir = debugfs_create_dir("bus", iwm->dbg.devdir); |
469 | result = PTR_ERR(iwm->dbg.busdir); | 436 | if (iwm->bus_ops->debugfs_init) |
470 | if (IS_ERR(iwm->dbg.busdir) && (result != -ENODEV)) { | 437 | iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); |
471 | IWM_ERR(iwm, "Couldn't create bus dir: %d\n", result); | ||
472 | goto error; | ||
473 | } | ||
474 | |||
475 | if (iwm->bus_ops->debugfs_init) { | ||
476 | result = iwm->bus_ops->debugfs_init(iwm, iwm->dbg.busdir); | ||
477 | if (result < 0) { | ||
478 | IWM_ERR(iwm, "Couldn't create bus entry: %d\n", result); | ||
479 | goto error; | ||
480 | } | ||
481 | } | ||
482 | |||
483 | 438 | ||
484 | iwm->dbg.dbg_level = IWM_DL_NONE; | 439 | iwm->dbg.dbg_level = IWM_DL_NONE; |
485 | iwm->dbg.dbg_level_dentry = | 440 | iwm->dbg.dbg_level_dentry = |
486 | debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, | 441 | debugfs_create_file("level", 0200, iwm->dbg.dbgdir, iwm, |
487 | &fops_iwm_dbg_level); | 442 | &fops_iwm_dbg_level); |
488 | result = PTR_ERR(iwm->dbg.dbg_level_dentry); | ||
489 | if (IS_ERR(iwm->dbg.dbg_level_dentry) && (result != -ENODEV)) { | ||
490 | IWM_ERR(iwm, "Couldn't create dbg_level: %d\n", result); | ||
491 | goto error; | ||
492 | } | ||
493 | |||
494 | 443 | ||
495 | iwm->dbg.dbg_modules = IWM_DM_DEFAULT; | 444 | iwm->dbg.dbg_modules = IWM_DM_DEFAULT; |
496 | iwm->dbg.dbg_modules_dentry = | 445 | iwm->dbg.dbg_modules_dentry = |
497 | debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, | 446 | debugfs_create_file("modules", 0200, iwm->dbg.dbgdir, iwm, |
498 | &fops_iwm_dbg_modules); | 447 | &fops_iwm_dbg_modules); |
499 | result = PTR_ERR(iwm->dbg.dbg_modules_dentry); | ||
500 | if (IS_ERR(iwm->dbg.dbg_modules_dentry) && (result != -ENODEV)) { | ||
501 | IWM_ERR(iwm, "Couldn't create dbg_modules: %d\n", result); | ||
502 | goto error; | ||
503 | } | ||
504 | 448 | ||
505 | for (i = 0; i < __IWM_DM_NR; i++) | 449 | for (i = 0; i < __IWM_DM_NR; i++) |
506 | add_dbg_module(iwm->dbg, iwm_debug_module[i].name, | 450 | add_dbg_module(iwm->dbg, iwm_debug_module[i].name, |
@@ -509,44 +453,15 @@ int iwm_debugfs_init(struct iwm_priv *iwm) | |||
509 | iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, | 453 | iwm->dbg.txq_dentry = debugfs_create_file("queues", 0200, |
510 | iwm->dbg.txdir, iwm, | 454 | iwm->dbg.txdir, iwm, |
511 | &iwm_debugfs_txq_fops); | 455 | &iwm_debugfs_txq_fops); |
512 | result = PTR_ERR(iwm->dbg.txq_dentry); | ||
513 | if (IS_ERR(iwm->dbg.txq_dentry) && (result != -ENODEV)) { | ||
514 | IWM_ERR(iwm, "Couldn't create tx queue: %d\n", result); | ||
515 | goto error; | ||
516 | } | ||
517 | |||
518 | iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, | 456 | iwm->dbg.tx_credit_dentry = debugfs_create_file("credits", 0200, |
519 | iwm->dbg.txdir, iwm, | 457 | iwm->dbg.txdir, iwm, |
520 | &iwm_debugfs_tx_credit_fops); | 458 | &iwm_debugfs_tx_credit_fops); |
521 | result = PTR_ERR(iwm->dbg.tx_credit_dentry); | ||
522 | if (IS_ERR(iwm->dbg.tx_credit_dentry) && (result != -ENODEV)) { | ||
523 | IWM_ERR(iwm, "Couldn't create tx credit: %d\n", result); | ||
524 | goto error; | ||
525 | } | ||
526 | |||
527 | iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, | 459 | iwm->dbg.rx_ticket_dentry = debugfs_create_file("tickets", 0200, |
528 | iwm->dbg.rxdir, iwm, | 460 | iwm->dbg.rxdir, iwm, |
529 | &iwm_debugfs_rx_ticket_fops); | 461 | &iwm_debugfs_rx_ticket_fops); |
530 | result = PTR_ERR(iwm->dbg.rx_ticket_dentry); | ||
531 | if (IS_ERR(iwm->dbg.rx_ticket_dentry) && (result != -ENODEV)) { | ||
532 | IWM_ERR(iwm, "Couldn't create rx ticket: %d\n", result); | ||
533 | goto error; | ||
534 | } | ||
535 | |||
536 | iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, | 462 | iwm->dbg.fw_err_dentry = debugfs_create_file("last_fw_err", 0200, |
537 | iwm->dbg.dbgdir, iwm, | 463 | iwm->dbg.dbgdir, iwm, |
538 | &iwm_debugfs_fw_err_fops); | 464 | &iwm_debugfs_fw_err_fops); |
539 | result = PTR_ERR(iwm->dbg.fw_err_dentry); | ||
540 | if (IS_ERR(iwm->dbg.fw_err_dentry) && (result != -ENODEV)) { | ||
541 | IWM_ERR(iwm, "Couldn't create last FW err: %d\n", result); | ||
542 | goto error; | ||
543 | } | ||
544 | |||
545 | |||
546 | return 0; | ||
547 | |||
548 | error: | ||
549 | return result; | ||
550 | } | 465 | } |
551 | 466 | ||
552 | void iwm_debugfs_exit(struct iwm_priv *iwm) | 467 | void iwm_debugfs_exit(struct iwm_priv *iwm) |
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c index 229de990379c..9531b18cf72a 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.c +++ b/drivers/net/wireless/iwmc3200wifi/hal.c | |||
@@ -105,6 +105,7 @@ | |||
105 | #include "hal.h" | 105 | #include "hal.h" |
106 | #include "umac.h" | 106 | #include "umac.h" |
107 | #include "debug.h" | 107 | #include "debug.h" |
108 | #include "trace.h" | ||
108 | 109 | ||
109 | static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, | 110 | static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, |
110 | struct iwm_nonwifi_cmd *cmd, | 111 | struct iwm_nonwifi_cmd *cmd, |
@@ -207,9 +208,9 @@ void iwm_cmd_flush(struct iwm_priv *iwm) | |||
207 | 208 | ||
208 | struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) | 209 | struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) |
209 | { | 210 | { |
210 | struct iwm_wifi_cmd *cmd, *next; | 211 | struct iwm_wifi_cmd *cmd; |
211 | 212 | ||
212 | list_for_each_entry_safe(cmd, next, &iwm->wifi_pending_cmd, pending) | 213 | list_for_each_entry(cmd, &iwm->wifi_pending_cmd, pending) |
213 | if (cmd->seq_num == seq_num) { | 214 | if (cmd->seq_num == seq_num) { |
214 | list_del(&cmd->pending); | 215 | list_del(&cmd->pending); |
215 | return cmd; | 216 | return cmd; |
@@ -218,12 +219,12 @@ struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) | |||
218 | return NULL; | 219 | return NULL; |
219 | } | 220 | } |
220 | 221 | ||
221 | struct iwm_nonwifi_cmd * | 222 | struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, |
222 | iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm, u8 seq_num, u8 cmd_opcode) | 223 | u8 seq_num, u8 cmd_opcode) |
223 | { | 224 | { |
224 | struct iwm_nonwifi_cmd *cmd, *next; | 225 | struct iwm_nonwifi_cmd *cmd; |
225 | 226 | ||
226 | list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) | 227 | list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending) |
227 | if ((cmd->seq_num == seq_num) && | 228 | if ((cmd->seq_num == seq_num) && |
228 | (cmd->udma_cmd.opcode == cmd_opcode) && | 229 | (cmd->udma_cmd.opcode == cmd_opcode) && |
229 | (cmd->resp_received)) { | 230 | (cmd->resp_received)) { |
@@ -277,6 +278,7 @@ static int iwm_send_udma_nonwifi_cmd(struct iwm_priv *iwm, | |||
277 | udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, | 278 | udma_cmd->handle_by_hw, cmd->seq_num, udma_cmd->addr, |
278 | udma_cmd->op1_sz, udma_cmd->op2); | 279 | udma_cmd->op1_sz, udma_cmd->op2); |
279 | 280 | ||
281 | trace_iwm_tx_nonwifi_cmd(iwm, udma_hdr); | ||
280 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); | 282 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); |
281 | } | 283 | } |
282 | 284 | ||
@@ -363,6 +365,7 @@ static int iwm_send_udma_wifi_cmd(struct iwm_priv *iwm, | |||
363 | return ret; | 365 | return ret; |
364 | } | 366 | } |
365 | 367 | ||
368 | trace_iwm_tx_wifi_cmd(iwm, umac_hdr); | ||
366 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); | 369 | return iwm_bus_send_chunk(iwm, buf->start, buf->len); |
367 | } | 370 | } |
368 | 371 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.h b/drivers/net/wireless/iwmc3200wifi/hal.h index 0adfdc85765d..c20936d9b6b7 100644 --- a/drivers/net/wireless/iwmc3200wifi/hal.h +++ b/drivers/net/wireless/iwmc3200wifi/hal.h | |||
@@ -75,7 +75,8 @@ do { \ | |||
75 | 75 | ||
76 | 76 | ||
77 | /* UDMA IN OP CODE -- cmd bits [3:0] */ | 77 | /* UDMA IN OP CODE -- cmd bits [3:0] */ |
78 | #define UDMA_IN_OPCODE_MASK 0xF | 78 | #define UDMA_HDI_IN_NW_CMD_OPCODE_POS 0 |
79 | #define UDMA_HDI_IN_NW_CMD_OPCODE_SEED 0xF | ||
79 | 80 | ||
80 | #define UDMA_IN_OPCODE_GENERAL_RESP 0x0 | 81 | #define UDMA_IN_OPCODE_GENERAL_RESP 0x0 |
81 | #define UDMA_IN_OPCODE_READ_RESP 0x1 | 82 | #define UDMA_IN_OPCODE_READ_RESP 0x1 |
@@ -130,7 +131,7 @@ do { \ | |||
130 | #define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ | 131 | #define IWM_MAX_WIFI_CMD_BUFF_SIZE (IWM_SDIO_FW_MAX_CHUNK_SIZE - \ |
131 | IWM_MAX_WIFI_HEADERS_SIZE) | 132 | IWM_MAX_WIFI_HEADERS_SIZE) |
132 | 133 | ||
133 | #define IWM_HAL_CONCATENATE_BUF_SIZE 8192 | 134 | #define IWM_HAL_CONCATENATE_BUF_SIZE (32 * 1024) |
134 | 135 | ||
135 | struct iwm_wifi_cmd_buff { | 136 | struct iwm_wifi_cmd_buff { |
136 | u16 len; | 137 | u16 len; |
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h index 79ffa3b98d73..13266c3842f8 100644 --- a/drivers/net/wireless/iwmc3200wifi/iwm.h +++ b/drivers/net/wireless/iwmc3200wifi/iwm.h | |||
@@ -48,6 +48,7 @@ | |||
48 | #include "umac.h" | 48 | #include "umac.h" |
49 | #include "lmac.h" | 49 | #include "lmac.h" |
50 | #include "eeprom.h" | 50 | #include "eeprom.h" |
51 | #include "trace.h" | ||
51 | 52 | ||
52 | #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" | 53 | #define IWM_COPYRIGHT "Copyright(c) 2009 Intel Corporation" |
53 | #define IWM_AUTHOR "<ilw@linux.intel.com>" | 54 | #define IWM_AUTHOR "<ilw@linux.intel.com>" |
@@ -268,7 +269,9 @@ struct iwm_priv { | |||
268 | 269 | ||
269 | struct sk_buff_head rx_list; | 270 | struct sk_buff_head rx_list; |
270 | struct list_head rx_tickets; | 271 | struct list_head rx_tickets; |
272 | spinlock_t ticket_lock; | ||
271 | struct list_head rx_packets[IWM_RX_ID_HASH]; | 273 | struct list_head rx_packets[IWM_RX_ID_HASH]; |
274 | spinlock_t packet_lock[IWM_RX_ID_HASH]; | ||
272 | struct workqueue_struct *rx_wq; | 275 | struct workqueue_struct *rx_wq; |
273 | struct work_struct rx_worker; | 276 | struct work_struct rx_worker; |
274 | 277 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c index 23856d359e12..362002735b12 100644 --- a/drivers/net/wireless/iwmc3200wifi/main.c +++ b/drivers/net/wireless/iwmc3200wifi/main.c | |||
@@ -277,8 +277,11 @@ int iwm_priv_init(struct iwm_priv *iwm) | |||
277 | 277 | ||
278 | skb_queue_head_init(&iwm->rx_list); | 278 | skb_queue_head_init(&iwm->rx_list); |
279 | INIT_LIST_HEAD(&iwm->rx_tickets); | 279 | INIT_LIST_HEAD(&iwm->rx_tickets); |
280 | for (i = 0; i < IWM_RX_ID_HASH; i++) | 280 | spin_lock_init(&iwm->ticket_lock); |
281 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | ||
281 | INIT_LIST_HEAD(&iwm->rx_packets[i]); | 282 | INIT_LIST_HEAD(&iwm->rx_packets[i]); |
283 | spin_lock_init(&iwm->packet_lock[i]); | ||
284 | } | ||
282 | 285 | ||
283 | INIT_WORK(&iwm->rx_worker, iwm_rx_worker); | 286 | INIT_WORK(&iwm->rx_worker, iwm_rx_worker); |
284 | 287 | ||
@@ -424,9 +427,9 @@ int iwm_notif_send(struct iwm_priv *iwm, struct iwm_wifi_cmd *cmd, | |||
424 | static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, | 427 | static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, |
425 | u8 source) | 428 | u8 source) |
426 | { | 429 | { |
427 | struct iwm_notif *notif, *next; | 430 | struct iwm_notif *notif; |
428 | 431 | ||
429 | list_for_each_entry_safe(notif, next, &iwm->pending_notif, pending) { | 432 | list_for_each_entry(notif, &iwm->pending_notif, pending) { |
430 | if ((notif->cmd_id == cmd) && (notif->src == source)) { | 433 | if ((notif->cmd_id == cmd) && (notif->src == source)) { |
431 | list_del(¬if->pending); | 434 | list_del(¬if->pending); |
432 | return notif; | 435 | return notif; |
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c index 3257d4fad835..e1184deca559 100644 --- a/drivers/net/wireless/iwmc3200wifi/rx.c +++ b/drivers/net/wireless/iwmc3200wifi/rx.c | |||
@@ -343,15 +343,17 @@ static void iwm_rx_ticket_node_free(struct iwm_rx_ticket_node *ticket_node) | |||
343 | static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) | 343 | static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) |
344 | { | 344 | { |
345 | u8 id_hash = IWM_RX_ID_GET_HASH(id); | 345 | u8 id_hash = IWM_RX_ID_GET_HASH(id); |
346 | struct list_head *packet_list; | 346 | struct iwm_rx_packet *packet; |
347 | struct iwm_rx_packet *packet, *next; | ||
348 | |||
349 | packet_list = &iwm->rx_packets[id_hash]; | ||
350 | 347 | ||
351 | list_for_each_entry_safe(packet, next, packet_list, node) | 348 | spin_lock(&iwm->packet_lock[id_hash]); |
352 | if (packet->id == id) | 349 | list_for_each_entry(packet, &iwm->rx_packets[id_hash], node) |
350 | if (packet->id == id) { | ||
351 | list_del(&packet->node); | ||
352 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
353 | return packet; | 353 | return packet; |
354 | } | ||
354 | 355 | ||
356 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
355 | return NULL; | 357 | return NULL; |
356 | } | 358 | } |
357 | 359 | ||
@@ -389,18 +391,22 @@ void iwm_rx_free(struct iwm_priv *iwm) | |||
389 | struct iwm_rx_packet *packet, *np; | 391 | struct iwm_rx_packet *packet, *np; |
390 | int i; | 392 | int i; |
391 | 393 | ||
394 | spin_lock(&iwm->ticket_lock); | ||
392 | list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { | 395 | list_for_each_entry_safe(ticket, nt, &iwm->rx_tickets, node) { |
393 | list_del(&ticket->node); | 396 | list_del(&ticket->node); |
394 | iwm_rx_ticket_node_free(ticket); | 397 | iwm_rx_ticket_node_free(ticket); |
395 | } | 398 | } |
399 | spin_unlock(&iwm->ticket_lock); | ||
396 | 400 | ||
397 | for (i = 0; i < IWM_RX_ID_HASH; i++) { | 401 | for (i = 0; i < IWM_RX_ID_HASH; i++) { |
402 | spin_lock(&iwm->packet_lock[i]); | ||
398 | list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], | 403 | list_for_each_entry_safe(packet, np, &iwm->rx_packets[i], |
399 | node) { | 404 | node) { |
400 | list_del(&packet->node); | 405 | list_del(&packet->node); |
401 | kfree_skb(packet->skb); | 406 | kfree_skb(packet->skb); |
402 | kfree(packet); | 407 | kfree(packet); |
403 | } | 408 | } |
409 | spin_unlock(&iwm->packet_lock[i]); | ||
404 | } | 410 | } |
405 | } | 411 | } |
406 | 412 | ||
@@ -425,10 +431,13 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf, | |||
425 | return PTR_ERR(ticket_node); | 431 | return PTR_ERR(ticket_node); |
426 | 432 | ||
427 | IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n", | 433 | IWM_DBG_RX(iwm, DBG, "TICKET %s(%d)\n", |
428 | ticket->action == IWM_RX_TICKET_RELEASE ? | 434 | __le16_to_cpu(ticket->action) == |
435 | IWM_RX_TICKET_RELEASE ? | ||
429 | "RELEASE" : "DROP", | 436 | "RELEASE" : "DROP", |
430 | ticket->id); | 437 | ticket->id); |
438 | spin_lock(&iwm->ticket_lock); | ||
431 | list_add_tail(&ticket_node->node, &iwm->rx_tickets); | 439 | list_add_tail(&ticket_node->node, &iwm->rx_tickets); |
440 | spin_unlock(&iwm->ticket_lock); | ||
432 | 441 | ||
433 | /* | 442 | /* |
434 | * We received an Rx ticket, most likely there's | 443 | * We received an Rx ticket, most likely there's |
@@ -461,6 +470,7 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf, | |||
461 | struct iwm_rx_packet *packet; | 470 | struct iwm_rx_packet *packet; |
462 | u16 id, buf_offset; | 471 | u16 id, buf_offset; |
463 | u32 packet_size; | 472 | u32 packet_size; |
473 | u8 id_hash; | ||
464 | 474 | ||
465 | IWM_DBG_RX(iwm, DBG, "\n"); | 475 | IWM_DBG_RX(iwm, DBG, "\n"); |
466 | 476 | ||
@@ -478,7 +488,10 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf, | |||
478 | if (IS_ERR(packet)) | 488 | if (IS_ERR(packet)) |
479 | return PTR_ERR(packet); | 489 | return PTR_ERR(packet); |
480 | 490 | ||
481 | list_add_tail(&packet->node, &iwm->rx_packets[IWM_RX_ID_GET_HASH(id)]); | 491 | id_hash = IWM_RX_ID_GET_HASH(id); |
492 | spin_lock(&iwm->packet_lock[id_hash]); | ||
493 | list_add_tail(&packet->node, &iwm->rx_packets[id_hash]); | ||
494 | spin_unlock(&iwm->packet_lock[id_hash]); | ||
482 | 495 | ||
483 | /* We might (unlikely) have received the packet _after_ the ticket */ | 496 | /* We might (unlikely) have received the packet _after_ the ticket */ |
484 | queue_work(iwm->rx_wq, &iwm->rx_worker); | 497 | queue_work(iwm->rx_wq, &iwm->rx_worker); |
@@ -519,6 +532,8 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
519 | unsigned long buf_size, | 532 | unsigned long buf_size, |
520 | struct iwm_wifi_cmd *cmd) | 533 | struct iwm_wifi_cmd *cmd) |
521 | { | 534 | { |
535 | struct wiphy *wiphy = iwm_to_wiphy(iwm); | ||
536 | struct ieee80211_channel *chan; | ||
522 | struct iwm_umac_notif_assoc_complete *complete = | 537 | struct iwm_umac_notif_assoc_complete *complete = |
523 | (struct iwm_umac_notif_assoc_complete *)buf; | 538 | (struct iwm_umac_notif_assoc_complete *)buf; |
524 | 539 | ||
@@ -527,6 +542,18 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
527 | 542 | ||
528 | switch (le32_to_cpu(complete->status)) { | 543 | switch (le32_to_cpu(complete->status)) { |
529 | case UMAC_ASSOC_COMPLETE_SUCCESS: | 544 | case UMAC_ASSOC_COMPLETE_SUCCESS: |
545 | chan = ieee80211_get_channel(wiphy, | ||
546 | ieee80211_channel_to_frequency(complete->channel)); | ||
547 | if (!chan || chan->flags & IEEE80211_CHAN_DISABLED) { | ||
548 | /* Associated to a unallowed channel, disassociate. */ | ||
549 | __iwm_invalidate_mlme_profile(iwm); | ||
550 | IWM_WARN(iwm, "Couldn't associate with %pM due to " | ||
551 | "channel %d is disabled. Check your local " | ||
552 | "regulatory setting.\n", | ||
553 | complete->bssid, complete->channel); | ||
554 | goto failure; | ||
555 | } | ||
556 | |||
530 | set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); | 557 | set_bit(IWM_STATUS_ASSOCIATED, &iwm->status); |
531 | memcpy(iwm->bssid, complete->bssid, ETH_ALEN); | 558 | memcpy(iwm->bssid, complete->bssid, ETH_ALEN); |
532 | iwm->channel = complete->channel; | 559 | iwm->channel = complete->channel; |
@@ -563,6 +590,7 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf, | |||
563 | GFP_KERNEL); | 590 | GFP_KERNEL); |
564 | break; | 591 | break; |
565 | case UMAC_ASSOC_COMPLETE_FAILURE: | 592 | case UMAC_ASSOC_COMPLETE_FAILURE: |
593 | failure: | ||
566 | clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); | 594 | clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); |
567 | memset(iwm->bssid, 0, ETH_ALEN); | 595 | memset(iwm->bssid, 0, ETH_ALEN); |
568 | iwm->channel = 0; | 596 | iwm->channel = 0; |
@@ -757,7 +785,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, | |||
757 | (struct iwm_umac_notif_bss_info *)buf; | 785 | (struct iwm_umac_notif_bss_info *)buf; |
758 | struct ieee80211_channel *channel; | 786 | struct ieee80211_channel *channel; |
759 | struct ieee80211_supported_band *band; | 787 | struct ieee80211_supported_band *band; |
760 | struct iwm_bss_info *bss, *next; | 788 | struct iwm_bss_info *bss; |
761 | s32 signal; | 789 | s32 signal; |
762 | int freq; | 790 | int freq; |
763 | u16 frame_len = le16_to_cpu(umac_bss->frame_len); | 791 | u16 frame_len = le16_to_cpu(umac_bss->frame_len); |
@@ -776,7 +804,7 @@ static int iwm_mlme_update_bss_table(struct iwm_priv *iwm, u8 *buf, | |||
776 | IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); | 804 | IWM_DBG_MLME(iwm, DBG, "\tRSSI: %d\n", umac_bss->rssi); |
777 | IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); | 805 | IWM_DBG_MLME(iwm, DBG, "\tFrame Length: %d\n", frame_len); |
778 | 806 | ||
779 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) | 807 | list_for_each_entry(bss, &iwm->bss_list, node) |
780 | if (bss->bss->table_idx == umac_bss->table_idx) | 808 | if (bss->bss->table_idx == umac_bss->table_idx) |
781 | break; | 809 | break; |
782 | 810 | ||
@@ -843,16 +871,15 @@ static int iwm_mlme_remove_bss(struct iwm_priv *iwm, u8 *buf, | |||
843 | int i; | 871 | int i; |
844 | 872 | ||
845 | for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { | 873 | for (i = 0; i < le32_to_cpu(bss_rm->count); i++) { |
846 | table_idx = (le16_to_cpu(bss_rm->entries[i]) | 874 | table_idx = le16_to_cpu(bss_rm->entries[i]) & |
847 | & IWM_BSS_REMOVE_INDEX_MSK); | 875 | IWM_BSS_REMOVE_INDEX_MSK; |
848 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) | 876 | list_for_each_entry_safe(bss, next, &iwm->bss_list, node) |
849 | if (bss->bss->table_idx == cpu_to_le16(table_idx)) { | 877 | if (bss->bss->table_idx == cpu_to_le16(table_idx)) { |
850 | struct ieee80211_mgmt *mgmt; | 878 | struct ieee80211_mgmt *mgmt; |
851 | 879 | ||
852 | mgmt = (struct ieee80211_mgmt *) | 880 | mgmt = (struct ieee80211_mgmt *) |
853 | (bss->bss->frame_buf); | 881 | (bss->bss->frame_buf); |
854 | IWM_DBG_MLME(iwm, ERR, | 882 | IWM_DBG_MLME(iwm, ERR, "BSS removed: %pM\n", |
855 | "BSS removed: %pM\n", | ||
856 | mgmt->bssid); | 883 | mgmt->bssid); |
857 | list_del(&bss->node); | 884 | list_del(&bss->node); |
858 | kfree(bss->bss); | 885 | kfree(bss->bss); |
@@ -1224,18 +1251,24 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf, | |||
1224 | u8 source, cmd_id; | 1251 | u8 source, cmd_id; |
1225 | u16 seq_num; | 1252 | u16 seq_num; |
1226 | u32 count; | 1253 | u32 count; |
1227 | u8 resp; | ||
1228 | 1254 | ||
1229 | wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; | 1255 | wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; |
1230 | cmd_id = wifi_hdr->sw_hdr.cmd.cmd; | 1256 | cmd_id = wifi_hdr->sw_hdr.cmd.cmd; |
1231 | |||
1232 | source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | 1257 | source = GET_VAL32(wifi_hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); |
1233 | if (source >= IWM_SRC_NUM) { | 1258 | if (source >= IWM_SRC_NUM) { |
1234 | IWM_CRIT(iwm, "invalid source %d\n", source); | 1259 | IWM_CRIT(iwm, "invalid source %d\n", source); |
1235 | return -EINVAL; | 1260 | return -EINVAL; |
1236 | } | 1261 | } |
1237 | 1262 | ||
1238 | count = (GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT)); | 1263 | if (cmd_id == REPLY_RX_MPDU_CMD) |
1264 | trace_iwm_rx_packet(iwm, buf, buf_size); | ||
1265 | else if ((cmd_id == UMAC_NOTIFY_OPCODE_RX_TICKET) && | ||
1266 | (source == UMAC_HDI_IN_SOURCE_FW)) | ||
1267 | trace_iwm_rx_ticket(iwm, buf, buf_size); | ||
1268 | else | ||
1269 | trace_iwm_rx_wifi_cmd(iwm, wifi_hdr); | ||
1270 | |||
1271 | count = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT); | ||
1239 | count += sizeof(struct iwm_umac_wifi_in_hdr) - | 1272 | count += sizeof(struct iwm_umac_wifi_in_hdr) - |
1240 | sizeof(struct iwm_dev_cmd_hdr); | 1273 | sizeof(struct iwm_dev_cmd_hdr); |
1241 | if (count > buf_size) { | 1274 | if (count > buf_size) { |
@@ -1243,8 +1276,6 @@ static int iwm_rx_handle_wifi(struct iwm_priv *iwm, u8 *buf, | |||
1243 | return -EINVAL; | 1276 | return -EINVAL; |
1244 | } | 1277 | } |
1245 | 1278 | ||
1246 | resp = GET_VAL32(wifi_hdr->sw_hdr.meta_data, UMAC_FW_CMD_STATUS); | ||
1247 | |||
1248 | seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); | 1279 | seq_num = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); |
1249 | 1280 | ||
1250 | IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", | 1281 | IWM_DBG_RX(iwm, DBG, "CMD:0x%x, source: 0x%x, seqnum: %d\n", |
@@ -1317,8 +1348,9 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf, | |||
1317 | { | 1348 | { |
1318 | u8 seq_num; | 1349 | u8 seq_num; |
1319 | struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; | 1350 | struct iwm_udma_in_hdr *hdr = (struct iwm_udma_in_hdr *)buf; |
1320 | struct iwm_nonwifi_cmd *cmd, *next; | 1351 | struct iwm_nonwifi_cmd *cmd; |
1321 | 1352 | ||
1353 | trace_iwm_rx_nonwifi_cmd(iwm, buf, buf_size); | ||
1322 | seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); | 1354 | seq_num = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); |
1323 | 1355 | ||
1324 | /* | 1356 | /* |
@@ -1329,7 +1361,7 @@ static int iwm_rx_handle_nonwifi(struct iwm_priv *iwm, u8 *buf, | |||
1329 | * That means we only support synchronised non wifi command response | 1361 | * That means we only support synchronised non wifi command response |
1330 | * schemes. | 1362 | * schemes. |
1331 | */ | 1363 | */ |
1332 | list_for_each_entry_safe(cmd, next, &iwm->nonwifi_pending_cmd, pending) | 1364 | list_for_each_entry(cmd, &iwm->nonwifi_pending_cmd, pending) |
1333 | if (cmd->seq_num == seq_num) { | 1365 | if (cmd->seq_num == seq_num) { |
1334 | cmd->resp_received = 1; | 1366 | cmd->resp_received = 1; |
1335 | cmd->buf.len = buf_size; | 1367 | cmd->buf.len = buf_size; |
@@ -1648,6 +1680,7 @@ void iwm_rx_worker(struct work_struct *work) | |||
1648 | * We stop whenever a ticket is missing its packet, as we're | 1680 | * We stop whenever a ticket is missing its packet, as we're |
1649 | * supposed to send the packets in order. | 1681 | * supposed to send the packets in order. |
1650 | */ | 1682 | */ |
1683 | spin_lock(&iwm->ticket_lock); | ||
1651 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { | 1684 | list_for_each_entry_safe(ticket, next, &iwm->rx_tickets, node) { |
1652 | struct iwm_rx_packet *packet = | 1685 | struct iwm_rx_packet *packet = |
1653 | iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); | 1686 | iwm_rx_packet_get(iwm, le16_to_cpu(ticket->ticket->id)); |
@@ -1656,12 +1689,12 @@ void iwm_rx_worker(struct work_struct *work) | |||
1656 | IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " | 1689 | IWM_DBG_RX(iwm, DBG, "Skip rx_work: Wait for ticket %d " |
1657 | "to be handled first\n", | 1690 | "to be handled first\n", |
1658 | le16_to_cpu(ticket->ticket->id)); | 1691 | le16_to_cpu(ticket->ticket->id)); |
1659 | return; | 1692 | break; |
1660 | } | 1693 | } |
1661 | 1694 | ||
1662 | list_del(&ticket->node); | 1695 | list_del(&ticket->node); |
1663 | list_del(&packet->node); | ||
1664 | iwm_rx_process_packet(iwm, packet, ticket); | 1696 | iwm_rx_process_packet(iwm, packet, ticket); |
1665 | } | 1697 | } |
1698 | spin_unlock(&iwm->ticket_lock); | ||
1666 | } | 1699 | } |
1667 | 1700 | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/sdio.c b/drivers/net/wireless/iwmc3200wifi/sdio.c index 1eafd6dec3fd..edcb52330cf5 100644 --- a/drivers/net/wireless/iwmc3200wifi/sdio.c +++ b/drivers/net/wireless/iwmc3200wifi/sdio.c | |||
@@ -366,21 +366,13 @@ static const struct file_operations iwm_debugfs_sdio_fops = { | |||
366 | .read = iwm_debugfs_sdio_read, | 366 | .read = iwm_debugfs_sdio_read, |
367 | }; | 367 | }; |
368 | 368 | ||
369 | static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) | 369 | static void if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) |
370 | { | 370 | { |
371 | int result; | ||
372 | struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); | 371 | struct iwm_sdio_priv *hw = iwm_to_if_sdio(iwm); |
373 | 372 | ||
374 | hw->cccr_dentry = debugfs_create_file("cccr", 0200, | 373 | hw->cccr_dentry = debugfs_create_file("cccr", 0200, |
375 | parent_dir, iwm, | 374 | parent_dir, iwm, |
376 | &iwm_debugfs_sdio_fops); | 375 | &iwm_debugfs_sdio_fops); |
377 | result = PTR_ERR(hw->cccr_dentry); | ||
378 | if (IS_ERR(hw->cccr_dentry) && (result != -ENODEV)) { | ||
379 | IWM_ERR(iwm, "Couldn't create CCCR entry: %d\n", result); | ||
380 | return result; | ||
381 | } | ||
382 | |||
383 | return 0; | ||
384 | } | 376 | } |
385 | 377 | ||
386 | static void if_sdio_debugfs_exit(struct iwm_priv *iwm) | 378 | static void if_sdio_debugfs_exit(struct iwm_priv *iwm) |
@@ -440,11 +432,7 @@ static int iwm_sdio_probe(struct sdio_func *func, | |||
440 | hw = iwm_private(iwm); | 432 | hw = iwm_private(iwm); |
441 | hw->iwm = iwm; | 433 | hw->iwm = iwm; |
442 | 434 | ||
443 | ret = iwm_debugfs_init(iwm); | 435 | iwm_debugfs_init(iwm); |
444 | if (ret < 0) { | ||
445 | IWM_ERR(iwm, "Debugfs registration failed\n"); | ||
446 | goto if_free; | ||
447 | } | ||
448 | 436 | ||
449 | sdio_set_drvdata(func, hw); | 437 | sdio_set_drvdata(func, hw); |
450 | 438 | ||
@@ -473,7 +461,6 @@ static int iwm_sdio_probe(struct sdio_func *func, | |||
473 | destroy_workqueue(hw->isr_wq); | 461 | destroy_workqueue(hw->isr_wq); |
474 | debugfs_exit: | 462 | debugfs_exit: |
475 | iwm_debugfs_exit(iwm); | 463 | iwm_debugfs_exit(iwm); |
476 | if_free: | ||
477 | iwm_if_free(iwm); | 464 | iwm_if_free(iwm); |
478 | return ret; | 465 | return ret; |
479 | } | 466 | } |
@@ -492,8 +479,6 @@ static void iwm_sdio_remove(struct sdio_func *func) | |||
492 | sdio_set_drvdata(func, NULL); | 479 | sdio_set_drvdata(func, NULL); |
493 | 480 | ||
494 | dev_info(dev, "IWM SDIO remove\n"); | 481 | dev_info(dev, "IWM SDIO remove\n"); |
495 | |||
496 | return; | ||
497 | } | 482 | } |
498 | 483 | ||
499 | static const struct sdio_device_id iwm_sdio_ids[] = { | 484 | static const struct sdio_device_id iwm_sdio_ids[] = { |
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.c b/drivers/net/wireless/iwmc3200wifi/trace.c new file mode 100644 index 000000000000..904d36f22311 --- /dev/null +++ b/drivers/net/wireless/iwmc3200wifi/trace.c | |||
@@ -0,0 +1,3 @@ | |||
1 | #include "iwm.h" | ||
2 | #define CREATE_TRACE_POINTS | ||
3 | #include "trace.h" | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/trace.h b/drivers/net/wireless/iwmc3200wifi/trace.h new file mode 100644 index 000000000000..abb4805fa8df --- /dev/null +++ b/drivers/net/wireless/iwmc3200wifi/trace.h | |||
@@ -0,0 +1,283 @@ | |||
1 | #if !defined(__IWM_TRACE_H__) || defined(TRACE_HEADER_MULTI_READ) | ||
2 | #define __IWM_TRACE_H__ | ||
3 | |||
4 | #include <linux/tracepoint.h> | ||
5 | |||
6 | #if !defined(CONFIG_IWM_TRACING) | ||
7 | #undef TRACE_EVENT | ||
8 | #define TRACE_EVENT(name, proto, ...) \ | ||
9 | static inline void trace_ ## name(proto) {} | ||
10 | #endif | ||
11 | |||
12 | #undef TRACE_SYSTEM | ||
13 | #define TRACE_SYSTEM iwm | ||
14 | |||
15 | #define IWM_ENTRY __array(char, ndev_name, 16) | ||
16 | #define IWM_ASSIGN strlcpy(__entry->ndev_name, iwm_to_ndev(iwm)->name, 16) | ||
17 | #define IWM_PR_FMT "%s" | ||
18 | #define IWM_PR_ARG __entry->ndev_name | ||
19 | |||
20 | TRACE_EVENT(iwm_tx_nonwifi_cmd, | ||
21 | TP_PROTO(struct iwm_priv *iwm, struct iwm_udma_out_nonwifi_hdr *hdr), | ||
22 | |||
23 | TP_ARGS(iwm, hdr), | ||
24 | |||
25 | TP_STRUCT__entry( | ||
26 | IWM_ENTRY | ||
27 | __field(u8, opcode) | ||
28 | __field(u8, resp) | ||
29 | __field(u8, eot) | ||
30 | __field(u8, hw) | ||
31 | __field(u16, seq) | ||
32 | __field(u32, addr) | ||
33 | __field(u32, op1) | ||
34 | __field(u32, op2) | ||
35 | ), | ||
36 | |||
37 | TP_fast_assign( | ||
38 | IWM_ASSIGN; | ||
39 | __entry->opcode = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_OPCODE); | ||
40 | __entry->resp = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_RESP); | ||
41 | __entry->eot = GET_VAL32(hdr->cmd, UMAC_HDI_OUT_CMD_EOT); | ||
42 | __entry->hw = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_NW_CMD_HANDLE_BY_HW); | ||
43 | __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_OUT_CMD_NON_WIFI_HW_SEQ_NUM); | ||
44 | __entry->addr = le32_to_cpu(hdr->addr); | ||
45 | __entry->op1 = le32_to_cpu(hdr->op1_sz); | ||
46 | __entry->op2 = le32_to_cpu(hdr->op2); | ||
47 | ), | ||
48 | |||
49 | TP_printk( | ||
50 | IWM_PR_FMT " Tx TARGET CMD: opcode 0x%x, resp %d, eot %d, " | ||
51 | "hw %d, seq 0x%x, addr 0x%x, op1 0x%x, op2 0x%x", | ||
52 | IWM_PR_ARG, __entry->opcode, __entry->resp, __entry->eot, | ||
53 | __entry->hw, __entry->seq, __entry->addr, __entry->op1, | ||
54 | __entry->op2 | ||
55 | ) | ||
56 | ); | ||
57 | |||
58 | TRACE_EVENT(iwm_tx_wifi_cmd, | ||
59 | TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_out_hdr *hdr), | ||
60 | |||
61 | TP_ARGS(iwm, hdr), | ||
62 | |||
63 | TP_STRUCT__entry( | ||
64 | IWM_ENTRY | ||
65 | __field(u8, opcode) | ||
66 | __field(u8, lmac) | ||
67 | __field(u8, resp) | ||
68 | __field(u8, eot) | ||
69 | __field(u8, ra_tid) | ||
70 | __field(u8, credit_group) | ||
71 | __field(u8, color) | ||
72 | __field(u16, seq) | ||
73 | ), | ||
74 | |||
75 | TP_fast_assign( | ||
76 | IWM_ASSIGN; | ||
77 | __entry->opcode = hdr->sw_hdr.cmd.cmd; | ||
78 | __entry->lmac = 0; | ||
79 | __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
80 | __entry->resp = GET_VAL8(hdr->sw_hdr.cmd.flags, UMAC_DEV_CMD_FLAGS_RESP_REQ); | ||
81 | __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR); | ||
82 | __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT); | ||
83 | __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID); | ||
84 | __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP); | ||
85 | if (__entry->opcode == UMAC_CMD_OPCODE_WIFI_PASS_THROUGH || | ||
86 | __entry->opcode == UMAC_CMD_OPCODE_WIFI_IF_WRAPPER) { | ||
87 | __entry->lmac = 1; | ||
88 | __entry->opcode = ((struct iwm_lmac_hdr *)(hdr + 1))->id; | ||
89 | } | ||
90 | ), | ||
91 | |||
92 | TP_printk( | ||
93 | IWM_PR_FMT " Tx %cMAC CMD: opcode 0x%x, resp %d, eot %d, " | ||
94 | "seq 0x%x, sta_color 0x%x, ra_tid 0x%x, credit_group 0x%x", | ||
95 | IWM_PR_ARG, __entry->lmac ? 'L' : 'U', __entry->opcode, | ||
96 | __entry->resp, __entry->eot, __entry->seq, __entry->color, | ||
97 | __entry->ra_tid, __entry->credit_group | ||
98 | ) | ||
99 | ); | ||
100 | |||
101 | TRACE_EVENT(iwm_tx_packets, | ||
102 | TP_PROTO(struct iwm_priv *iwm, u8 *buf, int len), | ||
103 | |||
104 | TP_ARGS(iwm, buf, len), | ||
105 | |||
106 | TP_STRUCT__entry( | ||
107 | IWM_ENTRY | ||
108 | __field(u8, eot) | ||
109 | __field(u8, ra_tid) | ||
110 | __field(u8, credit_group) | ||
111 | __field(u8, color) | ||
112 | __field(u16, seq) | ||
113 | __field(u8, npkt) | ||
114 | __field(u32, bytes) | ||
115 | ), | ||
116 | |||
117 | TP_fast_assign( | ||
118 | struct iwm_umac_wifi_out_hdr *hdr = | ||
119 | (struct iwm_umac_wifi_out_hdr *)buf; | ||
120 | |||
121 | IWM_ASSIGN; | ||
122 | __entry->eot = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_OUT_CMD_EOT); | ||
123 | __entry->ra_tid = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_RATID); | ||
124 | __entry->credit_group = GET_VAL32(hdr->hw_hdr.meta_data, UMAC_HDI_OUT_CREDIT_GRP); | ||
125 | __entry->color = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_TX_STA_COLOR); | ||
126 | __entry->seq = __le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
127 | __entry->npkt = 1; | ||
128 | __entry->bytes = len; | ||
129 | |||
130 | if (!__entry->eot) { | ||
131 | int count; | ||
132 | u8 *ptr = buf; | ||
133 | |||
134 | __entry->npkt = 0; | ||
135 | while (ptr < buf + len) { | ||
136 | count = GET_VAL32(hdr->sw_hdr.meta_data, | ||
137 | UMAC_FW_CMD_BYTE_COUNT); | ||
138 | ptr += ALIGN(sizeof(*hdr) + count, 16); | ||
139 | hdr = (struct iwm_umac_wifi_out_hdr *)ptr; | ||
140 | __entry->npkt++; | ||
141 | } | ||
142 | } | ||
143 | ), | ||
144 | |||
145 | TP_printk( | ||
146 | IWM_PR_FMT " Tx %spacket: eot %d, seq 0x%x, sta_color 0x%x, " | ||
147 | "ra_tid 0x%x, credit_group 0x%x, embeded_packets %d, %d bytes", | ||
148 | IWM_PR_ARG, !__entry->eot ? "concatenated " : "", | ||
149 | __entry->eot, __entry->seq, __entry->color, __entry->ra_tid, | ||
150 | __entry->credit_group, __entry->npkt, __entry->bytes | ||
151 | ) | ||
152 | ); | ||
153 | |||
154 | TRACE_EVENT(iwm_rx_nonwifi_cmd, | ||
155 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
156 | |||
157 | TP_ARGS(iwm, buf, len), | ||
158 | |||
159 | TP_STRUCT__entry( | ||
160 | IWM_ENTRY | ||
161 | __field(u8, opcode) | ||
162 | __field(u16, seq) | ||
163 | __field(u32, len) | ||
164 | ), | ||
165 | |||
166 | TP_fast_assign( | ||
167 | struct iwm_udma_in_hdr *hdr = buf; | ||
168 | |||
169 | IWM_ASSIGN; | ||
170 | __entry->opcode = GET_VAL32(hdr->cmd, UDMA_HDI_IN_NW_CMD_OPCODE); | ||
171 | __entry->seq = GET_VAL32(hdr->cmd, UDMA_HDI_IN_CMD_NON_WIFI_HW_SEQ_NUM); | ||
172 | __entry->len = len; | ||
173 | ), | ||
174 | |||
175 | TP_printk( | ||
176 | IWM_PR_FMT " Rx TARGET RESP: opcode 0x%x, seq 0x%x, len 0x%x", | ||
177 | IWM_PR_ARG, __entry->opcode, __entry->seq, __entry->len | ||
178 | ) | ||
179 | ); | ||
180 | |||
181 | TRACE_EVENT(iwm_rx_wifi_cmd, | ||
182 | TP_PROTO(struct iwm_priv *iwm, struct iwm_umac_wifi_in_hdr *hdr), | ||
183 | |||
184 | TP_ARGS(iwm, hdr), | ||
185 | |||
186 | TP_STRUCT__entry( | ||
187 | IWM_ENTRY | ||
188 | __field(u8, cmd) | ||
189 | __field(u8, source) | ||
190 | __field(u16, seq) | ||
191 | __field(u32, count) | ||
192 | ), | ||
193 | |||
194 | TP_fast_assign( | ||
195 | IWM_ASSIGN; | ||
196 | __entry->cmd = hdr->sw_hdr.cmd.cmd; | ||
197 | __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | ||
198 | __entry->count = GET_VAL32(hdr->sw_hdr.meta_data, UMAC_FW_CMD_BYTE_COUNT); | ||
199 | __entry->seq = le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
200 | ), | ||
201 | |||
202 | TP_printk( | ||
203 | IWM_PR_FMT " Rx %s RESP: cmd 0x%x, seq 0x%x, count 0x%x", | ||
204 | IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? "LMAC" : | ||
205 | __entry->source == UMAC_HDI_IN_SOURCE_FW ? "UMAC" : "UDMA", | ||
206 | __entry->cmd, __entry->seq, __entry->count | ||
207 | ) | ||
208 | ); | ||
209 | |||
210 | #define iwm_ticket_action_symbol \ | ||
211 | { IWM_RX_TICKET_DROP, "DROP" }, \ | ||
212 | { IWM_RX_TICKET_RELEASE, "RELEASE" }, \ | ||
213 | { IWM_RX_TICKET_SNIFFER, "SNIFFER" }, \ | ||
214 | { IWM_RX_TICKET_ENQUEUE, "ENQUEUE" } | ||
215 | |||
216 | TRACE_EVENT(iwm_rx_ticket, | ||
217 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
218 | |||
219 | TP_ARGS(iwm, buf, len), | ||
220 | |||
221 | TP_STRUCT__entry( | ||
222 | IWM_ENTRY | ||
223 | __field(u8, action) | ||
224 | __field(u8, reason) | ||
225 | __field(u16, id) | ||
226 | __field(u16, flags) | ||
227 | ), | ||
228 | |||
229 | TP_fast_assign( | ||
230 | struct iwm_rx_ticket *ticket = | ||
231 | ((struct iwm_umac_notif_rx_ticket *)buf)->tickets; | ||
232 | |||
233 | IWM_ASSIGN; | ||
234 | __entry->id = le16_to_cpu(ticket->id); | ||
235 | __entry->action = le16_to_cpu(ticket->action); | ||
236 | __entry->flags = le16_to_cpu(ticket->flags); | ||
237 | __entry->reason = (__entry->flags & IWM_RX_TICKET_DROP_REASON_MSK) >> IWM_RX_TICKET_DROP_REASON_POS; | ||
238 | ), | ||
239 | |||
240 | TP_printk( | ||
241 | IWM_PR_FMT " Rx ticket: id 0x%x, action %s, %s 0x%x%s", | ||
242 | IWM_PR_ARG, __entry->id, | ||
243 | __print_symbolic(__entry->action, iwm_ticket_action_symbol), | ||
244 | __entry->reason ? "reason" : "flags", | ||
245 | __entry->reason ? __entry->reason : __entry->flags, | ||
246 | __entry->flags & IWM_RX_TICKET_AMSDU_MSK ? ", AMSDU frame" : "" | ||
247 | ) | ||
248 | ); | ||
249 | |||
250 | TRACE_EVENT(iwm_rx_packet, | ||
251 | TP_PROTO(struct iwm_priv *iwm, void *buf, int len), | ||
252 | |||
253 | TP_ARGS(iwm, buf, len), | ||
254 | |||
255 | TP_STRUCT__entry( | ||
256 | IWM_ENTRY | ||
257 | __field(u8, source) | ||
258 | __field(u16, id) | ||
259 | __field(u32, len) | ||
260 | ), | ||
261 | |||
262 | TP_fast_assign( | ||
263 | struct iwm_umac_wifi_in_hdr *hdr = buf; | ||
264 | |||
265 | IWM_ASSIGN; | ||
266 | __entry->source = GET_VAL32(hdr->hw_hdr.cmd, UMAC_HDI_IN_CMD_SOURCE); | ||
267 | __entry->id = le16_to_cpu(hdr->sw_hdr.cmd.seq_num); | ||
268 | __entry->len = len - sizeof(*hdr); | ||
269 | ), | ||
270 | |||
271 | TP_printk( | ||
272 | IWM_PR_FMT " Rx %s packet: id 0x%x, %d bytes", | ||
273 | IWM_PR_ARG, __entry->source == UMAC_HDI_IN_SOURCE_FHRX ? | ||
274 | "LMAC" : "UMAC", __entry->id, __entry->len | ||
275 | ) | ||
276 | ); | ||
277 | #endif | ||
278 | |||
279 | #undef TRACE_INCLUDE_PATH | ||
280 | #define TRACE_INCLUDE_PATH . | ||
281 | #undef TRACE_INCLUDE_FILE | ||
282 | #define TRACE_INCLUDE_FILE trace | ||
283 | #include <trace/define_trace.h> | ||
diff --git a/drivers/net/wireless/iwmc3200wifi/tx.c b/drivers/net/wireless/iwmc3200wifi/tx.c index f6a02f123f31..3216621fc55a 100644 --- a/drivers/net/wireless/iwmc3200wifi/tx.c +++ b/drivers/net/wireless/iwmc3200wifi/tx.c | |||
@@ -302,8 +302,8 @@ void iwm_tx_credit_init_pools(struct iwm_priv *iwm, | |||
302 | 302 | ||
303 | #define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr) | 303 | #define IWM_UDMA_HDR_LEN sizeof(struct iwm_umac_wifi_out_hdr) |
304 | 304 | ||
305 | static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb, | 305 | static __le16 iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb, |
306 | int pool_id, u8 *buf) | 306 | int pool_id, u8 *buf) |
307 | { | 307 | { |
308 | struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf; | 308 | struct iwm_umac_wifi_out_hdr *hdr = (struct iwm_umac_wifi_out_hdr *)buf; |
309 | struct iwm_udma_wifi_cmd udma_cmd; | 309 | struct iwm_udma_wifi_cmd udma_cmd; |
@@ -347,6 +347,7 @@ static int iwm_tx_send_concat_packets(struct iwm_priv *iwm, | |||
347 | /* mark EOP for the last packet */ | 347 | /* mark EOP for the last packet */ |
348 | iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); | 348 | iwm_udma_wifi_hdr_set_eop(iwm, txq->concat_ptr, 1); |
349 | 349 | ||
350 | trace_iwm_tx_packets(iwm, txq->concat_buf, txq->concat_count); | ||
350 | ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); | 351 | ret = iwm_bus_send_chunk(iwm, txq->concat_buf, txq->concat_count); |
351 | 352 | ||
352 | txq->concat_count = 0; | 353 | txq->concat_count = 0; |
@@ -451,7 +452,6 @@ void iwm_tx_worker(struct work_struct *work) | |||
451 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | 452 | int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) |
452 | { | 453 | { |
453 | struct iwm_priv *iwm = ndev_to_iwm(netdev); | 454 | struct iwm_priv *iwm = ndev_to_iwm(netdev); |
454 | struct net_device *ndev = iwm_to_ndev(iwm); | ||
455 | struct wireless_dev *wdev = iwm_to_wdev(iwm); | 455 | struct wireless_dev *wdev = iwm_to_wdev(iwm); |
456 | struct iwm_tx_info *tx_info; | 456 | struct iwm_tx_info *tx_info; |
457 | struct iwm_tx_queue *txq; | 457 | struct iwm_tx_queue *txq; |
@@ -518,12 +518,12 @@ int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) | |||
518 | 518 | ||
519 | queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); | 519 | queue_work(iwm->txq[queue].wq, &iwm->txq[queue].worker); |
520 | 520 | ||
521 | ndev->stats.tx_packets++; | 521 | netdev->stats.tx_packets++; |
522 | ndev->stats.tx_bytes += skb->len; | 522 | netdev->stats.tx_bytes += skb->len; |
523 | return NETDEV_TX_OK; | 523 | return NETDEV_TX_OK; |
524 | 524 | ||
525 | drop: | 525 | drop: |
526 | ndev->stats.tx_dropped++; | 526 | netdev->stats.tx_dropped++; |
527 | dev_kfree_skb_any(skb); | 527 | dev_kfree_skb_any(skb); |
528 | return NETDEV_TX_OK; | 528 | return NETDEV_TX_OK; |
529 | } | 529 | } |
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h index 7f54a145ca65..0cbba3ecc813 100644 --- a/drivers/net/wireless/iwmc3200wifi/umac.h +++ b/drivers/net/wireless/iwmc3200wifi/umac.h | |||
@@ -362,7 +362,7 @@ struct iwm_udma_out_wifi_hdr { | |||
362 | #define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 | 362 | #define IWM_RX_TICKET_SPECIAL_SNAP_MSK 0x4 |
363 | #define IWM_RX_TICKET_AMSDU_MSK 0x8 | 363 | #define IWM_RX_TICKET_AMSDU_MSK 0x8 |
364 | #define IWM_RX_TICKET_DROP_REASON_POS 4 | 364 | #define IWM_RX_TICKET_DROP_REASON_POS 4 |
365 | #define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << RX_TICKET_FLAGS_DROP_REASON_POS) | 365 | #define IWM_RX_TICKET_DROP_REASON_MSK (0x1F << IWM_RX_TICKET_DROP_REASON_POS) |
366 | 366 | ||
367 | #define IWM_RX_DROP_NO_DROP 0x0 | 367 | #define IWM_RX_DROP_NO_DROP 0x0 |
368 | #define IWM_RX_DROP_BAD_CRC 0x1 | 368 | #define IWM_RX_DROP_BAD_CRC 0x1 |