aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwmc3200wifi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwmc3200wifi')
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Kconfig9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/Makefile5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/bus.h2
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c17
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c14
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.h1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debug.h7
-rw-r--r--drivers/net/wireless/iwmc3200wifi/debugfs.c123
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c15
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.h5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c79
-rw-r--r--drivers/net/wireless/iwmc3200wifi/sdio.c19
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.c3
-rw-r--r--drivers/net/wireless/iwmc3200wifi/trace.h283
-rw-r--r--drivers/net/wireless/iwmc3200wifi/tx.c12
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h2
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
17config IWM_DEBUG 17config 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
34config 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
3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o 3iwmc3200wifi-objs += commands.o cfg80211.o eeprom.o
4 4
5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o 5iwmc3200wifi-$(CONFIG_IWM_DEBUG) += debugfs.o
6iwmc3200wifi-$(CONFIG_IWM_TRACING) += trace.o
7
8CFLAGS_trace.o := -I$(src)
9
10ccflags-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,
264int iwm_cfg80211_inform_bss(struct iwm_priv *iwm) 264int 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
729int iwm_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *netdev, 729static 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
737int iwm_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *netdev, 738static 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
745int iwm_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev) 747static 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
785int iwm_invalidate_mlme_profile(struct iwm_priv *iwm) 785int __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
799int 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);
489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags); 489int iwm_send_umac_config(struct iwm_priv *iwm, __le32 reset_flags);
490int iwm_send_mlme_profile(struct iwm_priv *iwm); 490int iwm_send_mlme_profile(struct iwm_priv *iwm);
491int __iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
491int iwm_invalidate_mlme_profile(struct iwm_priv *iwm); 492int iwm_invalidate_mlme_profile(struct iwm_priv *iwm);
492int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id); 493int iwm_send_packet(struct iwm_priv *iwm, struct sk_buff *skb, int pool_id);
493int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx); 494int 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
116int iwm_debugfs_init(struct iwm_priv *iwm); 116void iwm_debugfs_init(struct iwm_priv *iwm);
117void iwm_debugfs_exit(struct iwm_priv *iwm); 117void iwm_debugfs_exit(struct iwm_priv *iwm);
118#else 118#else
119static inline int iwm_debugfs_init(struct iwm_priv *iwm) 119static inline void iwm_debugfs_init(struct iwm_priv *iwm) {}
120{
121 return 0;
122}
123static inline void iwm_debugfs_exit(struct iwm_priv *iwm) {} 120static 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) \
50do { \ 50do { \
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
59static int iwm_debugfs_u32_read(void *data, u64 *val) 58static 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
421int iwm_debugfs_init(struct iwm_priv *iwm) 425void 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
552void iwm_debugfs_exit(struct iwm_priv *iwm) 467void 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
109static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm, 110static 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
208struct iwm_wifi_cmd *iwm_get_pending_wifi_cmd(struct iwm_priv *iwm, u16 seq_num) 209struct 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
221struct iwm_nonwifi_cmd * 222struct iwm_nonwifi_cmd *iwm_get_pending_nonwifi_cmd(struct iwm_priv *iwm,
222iwm_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
135struct iwm_wifi_cmd_buff { 136struct 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,
424static struct iwm_notif *iwm_notif_find(struct iwm_priv *iwm, u32 cmd, 427static 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(&notif->pending); 434 list_del(&notif->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)
343static struct iwm_rx_packet *iwm_rx_packet_get(struct iwm_priv *iwm, u16 id) 343static 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
369static int if_sdio_debugfs_init(struct iwm_priv *iwm, struct dentry *parent_dir) 369static 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
386static void if_sdio_debugfs_exit(struct iwm_priv *iwm) 378static 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
499static const struct sdio_device_id iwm_sdio_ids[] = { 484static 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, ...) \
9static 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
20TRACE_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
58TRACE_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
101TRACE_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
154TRACE_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
181TRACE_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
216TRACE_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
250TRACE_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
305static int iwm_tx_build_packet(struct iwm_priv *iwm, struct sk_buff *skb, 305static __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)
451int iwm_xmit_frame(struct sk_buff *skb, struct net_device *netdev) 452int 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