Skip to content
  1. Apr 04, 2019
    • Piotr Figiel's avatar
      brcmfmac: convert dev_init_lock mutex to completion · a9fd0953
      Piotr Figiel authored
      
      
      Leaving dev_init_lock mutex locked in probe causes BUG and a WARNING when
      kernel is compiled with CONFIG_PROVE_LOCKING. Convert mutex to completion
      which silences those warnings and improves code readability.
      
      Fix below errors when connecting the USB WiFi dongle:
      
      brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43143 for chip BCM43143/2
      BUG: workqueue leaked lock or atomic: kworker/0:2/0x00000000/434
           last function: hub_event
      1 lock held by kworker/0:2/434:
       #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac]
      CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Workqueue: usb_hub_wq hub_event
      [<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14)
      [<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4)
      [<809c4324>] (dump_stack) from [<8014195c>] (process_one_work+0x710/0x808)
      [<8014195c>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564)
      [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c)
      [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
      Exception stack(0xed1d9fb0 to 0xed1d9ff8)
      9fa0:                                     00000000 00000000 00000000 00000000
      9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
      
      ======================================================
      WARNING: possible circular locking dependency detected
      4.19.23-00084-g454a789-dirty #123 Not tainted
      ------------------------------------------------------
      kworker/0:2/434 is trying to acquire lock:
      e29cf799 ((wq_completion)"events"){+.+.}, at: process_one_work+0x174/0x808
      
      but task is already holding lock:
      18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac]
      
      which lock already depends on the new lock.
      
      the existing dependency chain (in reverse order) is:
      
      -> #2 (&devinfo->dev_init_lock){+.+.}:
             mutex_lock_nested+0x1c/0x24
             brcmf_usb_probe+0x78/0x550 [brcmfmac]
             usb_probe_interface+0xc0/0x1bc
             really_probe+0x228/0x2c0
             __driver_attach+0xe4/0xe8
             bus_for_each_dev+0x68/0xb4
             bus_add_driver+0x19c/0x214
             driver_register+0x78/0x110
             usb_register_driver+0x84/0x148
             process_one_work+0x228/0x808
             worker_thread+0x2c/0x564
             kthread+0x13c/0x16c
             ret_from_fork+0x14/0x20
               (null)
      
      -> #1 (brcmf_driver_work){+.+.}:
             worker_thread+0x2c/0x564
             kthread+0x13c/0x16c
             ret_from_fork+0x14/0x20
               (null)
      
      -> #0 ((wq_completion)"events"){+.+.}:
             process_one_work+0x1b8/0x808
             worker_thread+0x2c/0x564
             kthread+0x13c/0x16c
             ret_from_fork+0x14/0x20
               (null)
      
      other info that might help us debug this:
      
      Chain exists of:
        (wq_completion)"events" --> brcmf_driver_work --> &devinfo->dev_init_lock
      
       Possible unsafe locking scenario:
      
             CPU0                    CPU1
             ----                    ----
        lock(&devinfo->dev_init_lock);
                                     lock(brcmf_driver_work);
                                     lock(&devinfo->dev_init_lock);
        lock((wq_completion)"events");
      
       *** DEADLOCK ***
      
      1 lock held by kworker/0:2/434:
       #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac]
      
      stack backtrace:
      CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Workqueue: events request_firmware_work_func
      [<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14)
      [<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4)
      [<809c4324>] (dump_stack) from [<80172838>] (print_circular_bug+0x210/0x330)
      [<80172838>] (print_circular_bug) from [<80175940>] (__lock_acquire+0x160c/0x1a30)
      [<80175940>] (__lock_acquire) from [<8017671c>] (lock_acquire+0xe0/0x268)
      [<8017671c>] (lock_acquire) from [<80141404>] (process_one_work+0x1b8/0x808)
      [<80141404>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564)
      [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c)
      [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
      Exception stack(0xed1d9fb0 to 0xed1d9ff8)
      9fa0:                                     00000000 00000000 00000000 00000000
      9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      9fe0: 00000000 00000000 00000000 00000000 00000013 00000000
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      a9fd0953
    • Piotr Figiel's avatar
      brcmfmac: fix Oops when bringing up interface during USB disconnect · 24d413a3
      Piotr Figiel authored
      
      
      Fix a race which leads to an Oops with NULL pointer dereference.  The
      dereference is in brcmf_config_dongle() when cfg_to_ndev() attempts to get
      net_device structure of interface with index 0 via if2bss mapping. This
      shouldn't fail because of check for bus being ready in brcmf_netdev_open(),
      but it's not synchronised with USB disconnect and there is a race: after
      the check the bus can be marked down and the mapping for interface 0 may be
      gone.
      
      Solve this by modifying disconnect handling so that the removal of mapping
      of ifidx to brcmf_if structure happens after netdev removal (which is
      synchronous with brcmf_netdev_open() thanks to rtln being locked in
      devinet_ioctl()). This assures brcmf_netdev_open() returns before the
      mapping is removed during disconnect.
      
      Unable to handle kernel NULL pointer dereference at virtual address 00000008
      pgd = bcae2612
      [00000008] *pgd=8be73831
      Internal error: Oops: 17 [#1] PREEMPT SMP ARM
      Modules linked in: brcmfmac brcmutil nf_log_ipv4 nf_log_common xt_LOG xt_limit
      iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6
      nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis
      u_ether usb_serial_simple usbserial cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc
      usbmisc_imx ulpi 8250_exar 8250_pci 8250 8250_base libcomposite configfs
      udc_core [last unloaded: brcmutil]
      CPU: 2 PID: 24478 Comm: ifconfig Not tainted 4.19.23-00078-ga62866d-dirty #115
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      PC is at brcmf_cfg80211_up+0x94/0x29c [brcmfmac]
      LR is at brcmf_cfg80211_up+0x8c/0x29c [brcmfmac]
      pc : [<7f26a91c>]    lr : [<7f26a914>]    psr: a0070013
      sp : eca99d28  ip : 00000000  fp : ee9c6c00
      r10: 00000036  r9 : 00000000  r8 : ece4002c
      r7 : edb5b800  r6 : 00000000  r5 : 80f08448  r4 : edb5b968
      r3 : ffffffff  r2 : 00000000  r1 : 00000002  r0 : 00000000
      Flags: NzCv  IRQs on  FIQs on  Mode SVC_32  ISA ARM  Segment none
      Control: 10c5387d  Table: 7ca0c04a  DAC: 00000051
      Process ifconfig (pid: 24478, stack limit = 0xd9e85a0e)
      Stack: (0xeca99d28 to 0xeca9a000)
      9d20:                   00000000 80f873b0 0000000d 80f08448 eca99d68 50d45f32
      9d40: 7f27de94 ece40000 80f08448 80f08448 7f27de94 ece4002c 00000000 00000036
      9d60: ee9c6c00 7f27262c 00001002 50d45f32 ece40000 00000000 80f08448 80772008
      9d80: 00000001 00001043 00001002 ece40000 00000000 50d45f32 ece40000 00000001
      9da0: 80f08448 00001043 00001002 807723d0 00000000 50d45f32 80f08448 eca99e58
      9dc0: 80f87113 50d45f32 80f08448 ece40000 ece40138 00001002 80f08448 00000000
      9de0: 00000000 80772434 edbd5380 eca99e58 edbd5380 80f08448 ee9c6c0c 80805f70
      9e00: 00000000 ede08e00 00008914 ece40000 00000014 ee9c6c0c 600c0013 00001043
      9e20: 0208a8c0 ffffffff 00000000 50d45f32 eca98000 80f08448 7ee9fc38 00008914
      9e40: 80f68e40 00000051 eca98000 00000036 00000003 80808b9c 6e616c77 00000030
      9e60: 00000000 00000000 00001043 0208a8c0 ffffffff 00000000 80f08448 00000000
      9e80: 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 00000000 50d45f32
      9ea0: eca98000 80f08448 7ee9fc38 50d45f32 00008914 80f08448 7ee9fc38 80f68e40
      9ec0: ed531540 8074721c 00000800 00000001 00000000 6e616c77 00000030 00000000
      9ee0: 00000000 00001002 0208a8c0 ffffffff 00000000 50d45f32 80f08448 7ee9fc38
      9f00: ed531560 ec8fc900 80285a6c 80285138 edb910c0 00000000 ecd91008 ede08e00
      9f20: 80f08448 00000000 00000000 816d8b20 600c0013 00000001 ede09320 801763d4
      9f40: 00000000 50d45f32 00021000 edb91118 edb910c0 80f08448 01b29000 edb91118
      9f60: eca99f7c 50d45f32 00021000 ec8fc900 00000003 ec8fc900 00008914 7ee9fc38
      9f80: eca98000 00000036 00000003 80285a6c 00086364 7ee9fe1c 000000c3 00000036
      9fa0: 801011c4 80101000 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364
      9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003
      9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc 600c0010 00000003 00000000 00000000
      [<7f26a91c>] (brcmf_cfg80211_up [brcmfmac]) from [<7f27262c>] (brcmf_netdev_open+0x74/0xe8 [brcmfmac])
      [<7f27262c>] (brcmf_netdev_open [brcmfmac]) from [<80772008>] (__dev_open+0xcc/0x150)
      [<80772008>] (__dev_open) from [<807723d0>] (__dev_change_flags+0x168/0x1b4)
      [<807723d0>] (__dev_change_flags) from [<80772434>] (dev_change_flags+0x18/0x48)
      [<80772434>] (dev_change_flags) from [<80805f70>] (devinet_ioctl+0x67c/0x79c)
      [<80805f70>] (devinet_ioctl) from [<80808b9c>] (inet_ioctl+0x210/0x3d4)
      [<80808b9c>] (inet_ioctl) from [<8074721c>] (sock_ioctl+0x350/0x524)
      [<8074721c>] (sock_ioctl) from [<80285138>] (do_vfs_ioctl+0xb0/0x9b0)
      [<80285138>] (do_vfs_ioctl) from [<80285a6c>] (ksys_ioctl+0x34/0x5c)
      [<80285a6c>] (ksys_ioctl) from [<80101000>] (ret_fast_syscall+0x0/0x28)
      Exception stack(0xeca99fa8 to 0xeca99ff0)
      9fa0:                   00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364
      9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003
      9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc
      Code: e5970328 eb002021 e1a02006 e3a01002 (e5909008)
      ---[ end trace 5cbac2333f3ac5df ]---
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      24d413a3
    • Piotr Figiel's avatar
      brcmfmac: remove unused variable i from brcmf_usb_free_q · 504f0672
      Piotr Figiel authored
      
      
      Variable i is not used so remove it.
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      504f0672
    • Piotr Figiel's avatar
      brcmfmac: remove pending parameter from brcmf_usb_free_q · 2b78e5f5
      Piotr Figiel authored
      
      
      brcmf_usb_free_q is no longer called with pending=true thus this boolean
      parameter is no longer needed.
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      2b78e5f5
    • Piotr Figiel's avatar
      brcmfmac: fix race during disconnect when USB completion is in progress · db3b9e2e
      Piotr Figiel authored
      
      
      It was observed that rarely during USB disconnect happening shortly after
      connect (before full initialization completes) usb_hub_wq would wait
      forever for the dev_init_lock to be unlocked. dev_init_lock would remain
      locked though because of infinite wait during usb_kill_urb:
      
      [ 2730.656472] kworker/0:2     D    0   260      2 0x00000000
      [ 2730.660700] Workqueue: events request_firmware_work_func
      [ 2730.664807] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac)
      [ 2730.670587] [<809dd164>] (schedule) from [<8069af44>] (usb_kill_urb+0xdc/0x114)
      [ 2730.676815] [<8069af44>] (usb_kill_urb) from [<7f258b50>] (brcmf_usb_free_q+0x34/0xa8 [brcmfmac])
      [ 2730.684833] [<7f258b50>] (brcmf_usb_free_q [brcmfmac]) from [<7f2517d4>] (brcmf_detach+0xa0/0xb8 [brcmfmac])
      [ 2730.693557] [<7f2517d4>] (brcmf_detach [brcmfmac]) from [<7f251a34>] (brcmf_attach+0xac/0x3d8 [brcmfmac])
      [ 2730.702094] [<7f251a34>] (brcmf_attach [brcmfmac]) from [<7f2587ac>] (brcmf_usb_probe_phase2+0x468/0x4a0 [brcmfmac])
      [ 2730.711601] [<7f2587ac>] (brcmf_usb_probe_phase2 [brcmfmac]) from [<7f252888>] (brcmf_fw_request_done+0x194/0x220 [brcmfmac])
      [ 2730.721795] [<7f252888>] (brcmf_fw_request_done [brcmfmac]) from [<805748e4>] (request_firmware_work_func+0x4c/0x88)
      [ 2730.731125] [<805748e4>] (request_firmware_work_func) from [<80141474>] (process_one_work+0x228/0x808)
      [ 2730.739223] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564)
      [ 2730.746105] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c)
      [ 2730.752227] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
      
      [ 2733.099695] kworker/0:3     D    0  1065      2 0x00000000
      [ 2733.103926] Workqueue: usb_hub_wq hub_event
      [ 2733.106914] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac)
      [ 2733.112693] [<809dd164>] (schedule) from [<809e2a8c>] (schedule_timeout+0x214/0x3e4)
      [ 2733.119621] [<809e2a8c>] (schedule_timeout) from [<809dde2c>] (wait_for_common+0xc4/0x1c0)
      [ 2733.126810] [<809dde2c>] (wait_for_common) from [<7f258d00>] (brcmf_usb_disconnect+0x1c/0x4c [brcmfmac])
      [ 2733.135206] [<7f258d00>] (brcmf_usb_disconnect [brcmfmac]) from [<8069e0c8>] (usb_unbind_interface+0x5c/0x1e4)
      [ 2733.143943] [<8069e0c8>] (usb_unbind_interface) from [<8056d3e8>] (device_release_driver_internal+0x164/0x1fc)
      [ 2733.152769] [<8056d3e8>] (device_release_driver_internal) from [<8056c078>] (bus_remove_device+0xd0/0xfc)
      [ 2733.161138] [<8056c078>] (bus_remove_device) from [<8056977c>] (device_del+0x11c/0x310)
      [ 2733.167939] [<8056977c>] (device_del) from [<8069cba8>] (usb_disable_device+0xa0/0x1cc)
      [ 2733.174743] [<8069cba8>] (usb_disable_device) from [<8069507c>] (usb_disconnect+0x74/0x1dc)
      [ 2733.181823] [<8069507c>] (usb_disconnect) from [<80695e88>] (hub_event+0x478/0xf88)
      [ 2733.188278] [<80695e88>] (hub_event) from [<80141474>] (process_one_work+0x228/0x808)
      [ 2733.194905] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564)
      [ 2733.201724] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c)
      [ 2733.207913] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20)
      
      It was traced down to a case where usb_kill_urb would be called on an URB
      structure containing more or less random data, including large number in
      its use_count. During the debugging it appeared that in brcmf_usb_free_q()
      the traversal over URBs' lists is not synchronized with operations on those
      lists in brcmf_usb_rx_complete() leading to handling
      brcmf_usbdev_info structure (holding lists' head) as lists' element and in
      result causing above problem.
      
      Fix it by walking through all URBs during brcmf_cancel_all_urbs using the
      arrays of requests instead of linked lists.
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      db3b9e2e
    • Piotr Figiel's avatar
      brcmfmac: fix NULL pointer derefence during USB disconnect · 5cdb0ef6
      Piotr Figiel authored
      In case USB disconnect happens at the moment transmitting workqueue is in
      progress the underlying interface may be gone causing a NULL pointer
      dereference. Add synchronization of the workqueue destruction with the
      detach implementation in core so that the transmitting workqueue is stopped
      during detach before the interfaces are removed.
      
      Fix following Oops:
      
      Unable to handle kernel NULL pointer dereference at virtual address 00000008
      pgd = 9e6a802d
      [00000008] *pgd=00000000
      Internal error: Oops: 5 [#1] PREEMPT SMP ARM
      Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle
      xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4
      iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether
      usb_serial_simple usbserial cdc_acm brcmfmac brcmutil smsc95xx usbnet
      ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base
      libcomposite configfs udc_core
      CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 4.19.23-00076-g03740aa-dirty #102
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Workqueue: brcmf_fws_wq brcmf_fws_dequeue_worker [brcmfmac]
      PC is at brcmf_txfinalize+0x34/0x90 [brcmfmac]
      LR is at brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac]
      pc : [<7f0dee64>]    lr : [<7f0e4140>]    psr: 60010093
      sp : ee8abef0  ip : 00000000  fp : edf38000
      r10: ffffffed  r9 : edf38970  r8 : edf38004
      r7 : edf3e970  r6 : 00000000  r5 : ede69000  r4 : 00000000
      r3 : 00000a97  r2 : 00000000  r1 : 0000888e  r0 : ede69000
      Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment none
      Control: 10c5387d  Table: 7d03c04a  DAC: 00000051
      Process kworker/u8:0 (pid: 7, stack limit = 0x24ec3e04)
      Stack: (0xee8abef0 to 0xee8ac000)
      bee0:                                     ede69000 00000000 ed56c3e0 7f0e4140
      bf00: 00000001 00000000 edf38004
      
       edf3e99c ed56c3e0 80d03d00 edfea43a edf3e970
      bf20: ee809880 ee804200 ee971100 00000000 edf3e974 00000000 ee804200 80135a70
      bf40: 80d03d00 ee804218 ee809880 ee809894 ee804200 80d03d00 ee804218 ee8aa000
      bf60: 00000088 80135d5c 00000000 ee829f00 ee829dc0 00000000 ee809880 80135d30
      bf80: ee829f1c ee873eac 00000000 8013b1a0 ee829dc0 8013b07c 00000000 00000000
      bfa0: 00000000 00000000 00000000 801010e8 00000000 00000000 00000000 00000000
      bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000
      [<7f0dee64>] (brcmf_txfinalize [brcmfmac]) from [<7f0e4140>] (brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac])
      [<7f0e4140>] (brcmf_fws_dequeue_worker [brcmfmac]) from [<80135a70>] (process_one_work+0x138/0x3f8)
      [<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554)
      [<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154)
      [<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c)
      Exception stack(0xee8abfb0 to 0xee8abff8)
      bfa0:                                     00000000 00000000 00000000 00000000
      bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      bfe0: 00000000 00000000 00000000 00000000 00000013 00000000
      Code: e1530001 0a000007 e3560000 e1a00005 (05942008)
      ---[ end trace 079239dd31c86e90 ]---
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      5cdb0ef6
    • Piotr Figiel's avatar
      brcmfmac: fix WARNING during USB disconnect in case of unempty psq · c80d26e8
      Piotr Figiel authored
      
      
      brcmu_pkt_buf_free_skb emits WARNING when attempting to free a sk_buff
      which is part of any queue. After USB disconnect this may have happened
      when brcmf_fws_hanger_cleanup() is called as per-interface psq was never
      cleaned when removing the interface.
      Change brcmf_fws_macdesc_cleanup() in a way that it removes the
      corresponding packets from hanger table (to avoid double-free when
      brcmf_fws_hanger_cleanup() is called) and add a call to clean-up the
      interface specific packet queue.
      
      Below is a WARNING during USB disconnect with Raspberry Pi WiFi dongle
      running in AP mode. This was reproducible when the interface was
      transmitting during the disconnect and is fixed with this commit.
      
      ------------[ cut here ]------------
      WARNING: CPU: 0 PID: 1171 at drivers/net/wireless/broadcom/brcm80211/brcmutil/utils.c:49 brcmu_pkt_buf_free_skb+0x3c/0x40
      Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base libcomposite configfs udc_core
      CPU: 0 PID: 1171 Comm: kworker/0:0 Not tainted 4.19.23-00075-gde33ed8 #99
      Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
      Workqueue: usb_hub_wq hub_event
      [<8010ff84>] (unwind_backtrace) from [<8010bb64>] (show_stack+0x10/0x14)
      [<8010bb64>] (show_stack) from [<80840278>] (dump_stack+0x88/0x9c)
      [<80840278>] (dump_stack) from [<8011f5ec>] (__warn+0xfc/0x114)
      [<8011f5ec>] (__warn) from [<8011f71c>] (warn_slowpath_null+0x40/0x48)
      [<8011f71c>] (warn_slowpath_null) from [<805a476c>] (brcmu_pkt_buf_free_skb+0x3c/0x40)
      [<805a476c>] (brcmu_pkt_buf_free_skb) from [<805bb6c4>] (brcmf_fws_cleanup+0x1e4/0x22c)
      [<805bb6c4>] (brcmf_fws_cleanup) from [<805bc854>] (brcmf_fws_del_interface+0x58/0x68)
      [<805bc854>] (brcmf_fws_del_interface) from [<805b66ac>] (brcmf_remove_interface+0x40/0x150)
      [<805b66ac>] (brcmf_remove_interface) from [<805b6870>] (brcmf_detach+0x6c/0xb0)
      [<805b6870>] (brcmf_detach) from [<805bdbb8>] (brcmf_usb_disconnect+0x30/0x4c)
      [<805bdbb8>] (brcmf_usb_disconnect) from [<805e5d64>] (usb_unbind_interface+0x5c/0x1e0)
      [<805e5d64>] (usb_unbind_interface) from [<804aab10>] (device_release_driver_internal+0x154/0x1ec)
      [<804aab10>] (device_release_driver_internal) from [<804a97f4>] (bus_remove_device+0xcc/0xf8)
      [<804a97f4>] (bus_remove_device) from [<804a6fc0>] (device_del+0x118/0x308)
      [<804a6fc0>] (device_del) from [<805e488c>] (usb_disable_device+0xa0/0x1c8)
      [<805e488c>] (usb_disable_device) from [<805dcf98>] (usb_disconnect+0x70/0x1d8)
      [<805dcf98>] (usb_disconnect) from [<805ddd84>] (hub_event+0x464/0xf50)
      [<805ddd84>] (hub_event) from [<80135a70>] (process_one_work+0x138/0x3f8)
      [<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554)
      [<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154)
      [<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c)
      Exception stack(0xecf8dfb0 to 0xecf8dff8)
      dfa0:                                     00000000 00000000 00000000 00000000
      dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      dfe0: 00000000 00000000 00000000 00000000 00000013 00000000
      ---[ end trace 38d234018e9e2a90 ]---
      ------------[ cut here ]------------
      
      Signed-off-by: default avatarPiotr Figiel <p.figiel@camlintechnologies.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      c80d26e8
    • Rafał Miłecki's avatar
      brcmfmac: reset PCIe bus on a firmware crash · 4684997d
      Rafał Miłecki authored
      
      
      This includes bus reset & reloading a firmware. It should be sufficient
      for a user space to (setup and) use a wireless device again.
      
      Support for reset on USB & SDIO can be added later.
      
      Signed-off-by: default avatarRafał Miłecki <rafal@milecki.pl>
      Reviewed-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      4684997d
    • Rafał Miłecki's avatar
      brcmfmac: add a function designated for handling firmware fails · a2ec87dd
      Rafał Miłecki authored
      
      
      This improves handling PCIe firmware halts by printing a clear error
      message and replaces a similar code in the SDIO bus support.
      
      It will also allow further improvements like trying to recover from a
      firmware crash.
      
      Signed-off-by: default avatarRafał Miłecki <rafal@milecki.pl>
      Reviewed-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      a2ec87dd
    • Rafał Miłecki's avatar
      brcmfmac: support repeated brcmf_fw_alloc_request() calls · c9692820
      Rafał Miłecki authored
      
      
      During a normal brcmfmac lifetime brcmf_fw_alloc_request() is called
      once only during the probe. It's safe to assume provided array is clear.
      
      Further brcmfmac improvements may require calling it multiple times
      though. This patch allows it by fixing invalid firmware paths like:
      brcm/brcmfmac4366c-pcie.binbrcm/brcmfmac4366c-pcie.bin
      
      Signed-off-by: default avatarRafał Miłecki <rafal@milecki.pl>
      Reviewed-by: default avatarArend van Spriel <arend.vanspriel@broadcom.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      c9692820
    • Igor Mitsyanko's avatar
      qtnfmac: use scan duration param for different scan types · b63967ca
      Igor Mitsyanko authored
      
      
      Use scan duration param for both active and passive scan dwell times.
      Document what different types of dwell times are used for. Explicitly
      specify that if unset, automatic selection by device firmware
      will be used.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      b63967ca
    • Igor Mitsyanko's avatar
      qtnfmac: send EAPOL frames via control path · bc70732f
      Igor Mitsyanko authored
      
      
      Use control path to send EAPOL frames to make sure they are
      sent with higher priority with aggregation disabled.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      bc70732f
    • Sergey Matyukevich's avatar
      qtnfmac: allow changing the netns · 72b3270e
      Sergey Matyukevich authored
      
      
      Allow to change netns for wireless interfaces created by qtnfmac driver.
      
      Signed-off-by: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      72b3270e
    • Sergey Matyukevich's avatar
      qtnfmac: simplify firmware state tracking · 83b00f6e
      Sergey Matyukevich authored
      
      
      This patch streamlines firmware state tracking. In particular, state
      QTNF_FW_STATE_FW_DNLD_DONE is removed, states QTNF_FW_STATE_RESET and
      QTNF_FW_STATE_DETACHED are merged into a single state. Besides, new
      state QTNF_FW_STATE_RUNNING is introduced to distinguish between
      the following two cases:
      - firmware load succeeded, firmware init process is ongoing
      - firmware init succeeded, firmware is fully functional
      
      Signed-off-by: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      83b00f6e
    • Sergey Matyukevich's avatar
      qtnfmac: fix core attach error path in pcie backend · ae1946be
      Sergey Matyukevich authored
      
      
      Report that firmware is up and running only for successful firmware
      download. Simplify qtnf_pcie_fw_boot_done: modify error path so that
      no need to pass firmware dowload result to this function. Finally,
      do not create debugfs entries if firmware download succeeded,
      but core attach failed.
      
      Signed-off-by: default avatarSergey Matyukevich <sergey.matyukevich.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      ae1946be
    • Igor Mitsyanko's avatar
      qtnfmac: update bands information on CHANGE_INTF command · 93eeab26
      Igor Mitsyanko authored
      
      
      In some regions, different regulatory limits (like max Tx power) may be
      defined for different operating modes. As an example: in ETSI regions
      DFS master devices may use higher transmit powers compared to DFS slave
      devices. Update bands information in CHANGE_INTF command if mode of
      operation changes.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      93eeab26
    • Igor Mitsyanko's avatar
      qtnfmac: pass DFS region to firmware on region update · 438fb43b
      Igor Mitsyanko authored
      
      
      Pass DFS region as requested by regulatory core directly to firmware
      so it can initialize radar detection block accordingly.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      438fb43b
    • Igor Mitsyanko's avatar
      qtnfmac: allow each MAC to specify its own regulatory rules · c698bce0
      Igor Mitsyanko authored
      
      
      Currently driver uses the same regulatory rules to register all wiphy
      instances. This is not logically correct since each wiphy may have
      different capabilities (different supported bands, EIRP etc).
      Allow firmware to pass regulatory rules for each MAC separately.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      c698bce0
    • Igor Mitsyanko's avatar
      qtnfmac: flexible regulatory domain registration logic · 48cefdfb
      Igor Mitsyanko authored
      
      
      Use REGULATORY_CUSTOM_REG flag only if firmware advertised a custom
      regulatory domain prior to wiphy registration. Use REGULATORY_STRICT_REG
      flag only if firmware knows its regulatory domain.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      48cefdfb
    • Igor Mitsyanko's avatar
      qtnfmac: pass complete channel info in regulatory notifier · 2c31129f
      Igor Mitsyanko authored
      
      
      Currently only a portion of per-channel information is passed to
      firmware. Extend logic to pass all useful per-channel data.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      2c31129f
    • Igor Mitsyanko's avatar
      qtnfmac: include full channels info to regulatory notifier · a2fbaaf7
      Igor Mitsyanko authored
      
      
      Before regulatory notifier is invoked by a wireless core, it will
      update band information for the wiphy. Pass this information to
      firmware together with new region alpha2 code.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      a2fbaaf7
    • Igor Mitsyanko's avatar
      qtnfmac: simplify error reporting in regulatory notifier · 642f15a5
      Igor Mitsyanko authored
      
      
      Error reporting in qtnf_cfg80211_reg_notifier only requires to print
      one type of message and an error code. Firmware will report success
      for an attempt to set regulatory region to the same value,
      so no special handling is required for this case.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      642f15a5
    • Igor Mitsyanko's avatar
      qtnfmac: make regulatory notifier work on per-phy basis · d1231721
      Igor Mitsyanko authored
      
      
      Wireless core calls regulatory notifier for each wiphy and it only
      guarantees that bands info is updated for this particular wiphy prior
      to calling a notifier. Hence updating all wiphy which belong to driver
      in a single notifier callback is redundant and incorrect.
      
      Signed-off-by: default avatarIgor Mitsyanko <igor.mitsyanko.os@quantenna.com>
      Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
      d1231721
  2. Mar 30, 2019