1. 13 1月, 2019 4 次提交
    • I
      bnx2x: Fix NULL pointer dereference in bnx2x_del_all_vlans() on some hw · 6384c67c
      Ivan Mironov 提交于
      commit 38355a5f9a22bfa5bd5b1bb79805aca39fa53729 upstream.
      
      This happened when I tried to boot normal Fedora 29 system with latest
      available kernel (from fedora rawhide, plus some unrelated custom
      patches):
      
      	BUG: unable to handle kernel NULL pointer dereference at 0000000000000000
      	PGD 0 P4D 0
      	Oops: 0010 [#1] SMP PTI
      	CPU: 6 PID: 1422 Comm: libvirtd Tainted: G          I       4.20.0-0.rc7.git3.hpsa2.1.fc29.x86_64 #1
      	Hardware name: HP ProLiant BL460c G6, BIOS I24 05/21/2018
      	RIP: 0010:          (null)
      	Code: Bad RIP value.
      	RSP: 0018:ffffa47ccdc9fbe0 EFLAGS: 00010246
      	RAX: 0000000000000000 RBX: 00000000000003e8 RCX: ffffa47ccdc9fbf8
      	RDX: ffffa47ccdc9fc00 RSI: ffff97d9ee7b01f8 RDI: ffff97d9f0150b80
      	RBP: ffff97d9f0150b80 R08: 0000000000000000 R09: 0000000000000000
      	R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000003
      	R13: ffff97d9ef1e53e8 R14: 0000000000000009 R15: ffff97d9f0ac6730
      	FS:  00007f4d224ef700(0000) GS:ffff97d9fa200000(0000) knlGS:0000000000000000
      	CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      	CR2: ffffffffffffffd6 CR3: 00000011ece52006 CR4: 00000000000206e0
      	Call Trace:
      	 ? bnx2x_chip_cleanup+0x195/0x610 [bnx2x]
      	 ? bnx2x_nic_unload+0x1e2/0x8f0 [bnx2x]
      	 ? bnx2x_reload_if_running+0x24/0x40 [bnx2x]
      	 ? bnx2x_set_features+0x79/0xa0 [bnx2x]
      	 ? __netdev_update_features+0x244/0x9e0
      	 ? netlink_broadcast_filtered+0x136/0x4b0
      	 ? netdev_update_features+0x22/0x60
      	 ? dev_disable_lro+0x1c/0xe0
      	 ? devinet_sysctl_forward+0x1c6/0x211
      	 ? proc_sys_call_handler+0xab/0x100
      	 ? __vfs_write+0x36/0x1a0
      	 ? rcu_read_lock_sched_held+0x79/0x80
      	 ? rcu_sync_lockdep_assert+0x2e/0x60
      	 ? __sb_start_write+0x14c/0x1b0
      	 ? vfs_write+0x159/0x1c0
      	 ? vfs_write+0xba/0x1c0
      	 ? ksys_write+0x52/0xc0
      	 ? do_syscall_64+0x60/0x1f0
      	 ? entry_SYSCALL_64_after_hwframe+0x49/0xbe
      
      After some investigation I figured out that recently added cleanup code
      tries to call VLAN filtering de-initialization function which exist only
      for newer hardware. Corresponding function pointer is not
      set (== 0) for older hardware, namely these chips:
      
      	#define CHIP_NUM_57710			0x164e
      	#define CHIP_NUM_57711			0x164f
      	#define CHIP_NUM_57711E			0x1650
      
      And I have one of those in my test system:
      
      	Broadcom Inc. and subsidiaries NetXtreme II BCM57711E 10-Gigabit PCIe [14e4:1650]
      
      Function bnx2x_init_vlan_mac_fp_objs() from
      drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.h decides whether to
      initialize relevant pointers in bnx2x_sp_objs.vlan_obj or not.
      
      This regression was introduced after v4.20-rc7, and still exists in v4.20
      release.
      
      Fixes: 04f05230c5c13 ("bnx2x: Remove configured vlans as part of unload sequence.")
      Signed-off-by: NIvan Mironov <mironov.ivan@gmail.com>
      Signed-off-by: NIvan Mironov <mironov.ivan@gmail.com>
      Acked-by: NSudarsana Kalluru <Sudarsana.Kalluru@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Cc: Sudip Mukherjee <sudipm.mukherjee@gmail.com>
      Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
      6384c67c
    • S
      bnx2x: Send update-svid ramrod with retry/poll flags enabled · a0134540
      Sudarsana Reddy Kalluru 提交于
      [ Upstream commit 9061193c4ee065d3240fde06767c2e06ec61decc ]
      
      Driver sends update-SVID ramrod in the MFW notification path.
      If there is a pending ramrod, driver doesn't retry the command
      and storm firmware will never be updated with the SVID value.
      The patch adds changes to send update-svid ramrod in process context with
      retry/poll flags set.
      Signed-off-by: NSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
      Signed-off-by: NAriel Elior <ariel.elior@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      a0134540
    • S
      bnx2x: Remove configured vlans as part of unload sequence. · 53471f0d
      Sudarsana Reddy Kalluru 提交于
      [ Upstream commit 04f05230c5c13b1384f66f5186a68d7499e34622 ]
      
      Vlans are not getting removed when drivers are unloaded. The recent storm
      firmware versions had added safeguards against re-configuring an already
      configured vlan. As a result, PF inner reload flows (e.g., mtu change)
      might trigger an assertion.
      This change is going to remove vlans (same as we do for MACs) when doing
      a chip cleanup during unload.
      Signed-off-by: NSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
      Signed-off-by: NAriel Elior <ariel.elior@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      53471f0d
    • S
      bnx2x: Clear fip MAC when fcoe offload support is disabled · 096795d4
      Sudarsana Reddy Kalluru 提交于
      [ Upstream commit bbf666c1af916ed74795493c564df6fad462cc80 ]
      
      On some customer setups it was observed that shmem contains a non-zero fip
      MAC for 57711 which would lead to enabling of SW FCoE.
      Add a software workaround to clear the bad fip mac address if no FCoE
      connections are supported.
      Signed-off-by: NSudarsana Reddy Kalluru <Sudarsana.Kalluru@cavium.com>
      Signed-off-by: NAriel Elior <ariel.elior@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      Signed-off-by: NSasha Levin <sashal@kernel.org>
      096795d4
  2. 24 9月, 2018 1 次提交
    • E
      bnx2x: remove ndo_poll_controller · d8ea6a91
      Eric Dumazet 提交于
      As diagnosed by Song Liu, ndo_poll_controller() can
      be very dangerous on loaded hosts, since the cpu
      calling ndo_poll_controller() might steal all NAPI
      contexts (for all RX/TX queues of the NIC). This capture
      can last for unlimited amount of time, since one
      cpu is generally not able to drain all the queues under load.
      
      bnx2x uses NAPI for TX completions, so we better let core
      networking stack call the napi->poll() to avoid the capture.
      Signed-off-by: NEric Dumazet <edumazet@google.com>
      Cc: Ariel Elior <ariel.elior@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      d8ea6a91
  3. 30 6月, 2018 2 次提交
  4. 26 5月, 2018 1 次提交
    • B
      bnx2x: Report PCIe link properties with pcie_print_link_status() · cc04a1dd
      Bjorn Helgaas 提交于
      Previously the driver used pcie_get_minimum_link() to warn when the NIC
      is in a slot that can't supply as much bandwidth as the NIC could use.
      
      pcie_get_minimum_link() can be misleading because it finds the slowest link
      and the narrowest link (which may be different links) without considering
      the total bandwidth of each link.  For a path with a 16 GT/s x1 link and a
      2.5 GT/s x16 link, it returns 2.5 GT/s x1, which corresponds to 250 MB/s of
      bandwidth, not the true available bandwidth of about 1969 MB/s for a
      16 GT/s x1 link.
      
      Use pcie_print_link_status() to report PCIe link speed and possible
      limitations instead of implementing this in the driver itself.  This finds
      the slowest link in the path to the device by computing the total bandwidth
      of each link and compares that with the capabilities of the device.
      
      The dmesg change is:
      
        - %s (%c%d) PCI-E x%d %s found at mem %lx, IRQ %d, node addr %pM
        + %s (%c%d) PCI-E found at mem %lx, IRQ %d, node addr %pM
        + %u.%03u Gb/s available PCIe bandwidth (%s x%d link)
      Signed-off-by: NBjorn Helgaas <bhelgaas@google.com>
      cc04a1dd
  5. 27 3月, 2018 2 次提交
  6. 22 3月, 2018 1 次提交
  7. 01 2月, 2018 1 次提交
    • D
      bnx2x: disable GSO where gso_size is too big for hardware · 8914a595
      Daniel Axtens 提交于
      If a bnx2x card is passed a GSO packet with a gso_size larger than
      ~9700 bytes, it will cause a firmware error that will bring the card
      down:
      
      bnx2x: [bnx2x_attn_int_deasserted3:4323(enP24p1s0f0)]MC assert!
      bnx2x: [bnx2x_mc_assert:720(enP24p1s0f0)]XSTORM_ASSERT_LIST_INDEX 0x2
      bnx2x: [bnx2x_mc_assert:736(enP24p1s0f0)]XSTORM_ASSERT_INDEX 0x0 = 0x00000000 0x25e43e47 0x00463e01 0x00010052
      bnx2x: [bnx2x_mc_assert:750(enP24p1s0f0)]Chip Revision: everest3, FW Version: 7_13_1
      ... (dump of values continues) ...
      
      Detect when the mac length of a GSO packet is greater than the maximum
      packet size (9700 bytes) and disable GSO.
      Signed-off-by: NDaniel Axtens <dja@axtens.net>
      Reviewed-by: NEric Dumazet <edumazet@google.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      8914a595
  8. 28 12月, 2017 1 次提交
  9. 19 12月, 2017 1 次提交
    • M
      bnx2x: Use NETIF_F_GRO_HW. · 3c3def5f
      Michael Chan 提交于
      Advertise NETIF_F_GRO_HW and turn on TPA_MODE_GRO when NETIF_F_GRO_HW
      is set.  Disable NETIF_F_GRO_HW in bnx2x_fix_features() if the MTU
      does not support TPA_MODE_GRO or GRO is not set.  bnx2x_change_mtu() also
      needs to disable NETIF_F_GRO_HW if the MTU does not support it.
      
      Original parameter disable_tpa will continue to disable LRO and GRO_HW.
      
      Preserve the original behavior of enabling LRO by default.  User has
      to run ethtool -K to explicitly enable GRO_HW.
      
      Cc: Ariel Elior <Ariel.Elior@cavium.com>
      Cc: everest-linux-l2@cavium.com
      Signed-off-by: NMichael Chan <michael.chan@broadcom.com>
      Acked-by: NManish Chopra <manish.chopra@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      3c3def5f
  10. 22 11月, 2017 1 次提交
    • K
      treewide: setup_timer() -> timer_setup() · e99e88a9
      Kees Cook 提交于
      This converts all remaining cases of the old setup_timer() API into using
      timer_setup(), where the callback argument is the structure already
      holding the struct timer_list. These should have no behavioral changes,
      since they just change which pointer is passed into the callback with
      the same available pointers after conversion. It handles the following
      examples, in addition to some other variations.
      
      Casting from unsigned long:
      
          void my_callback(unsigned long data)
          {
              struct something *ptr = (struct something *)data;
          ...
          }
          ...
          setup_timer(&ptr->my_timer, my_callback, ptr);
      
      and forced object casts:
      
          void my_callback(struct something *ptr)
          {
          ...
          }
          ...
          setup_timer(&ptr->my_timer, my_callback, (unsigned long)ptr);
      
      become:
      
          void my_callback(struct timer_list *t)
          {
              struct something *ptr = from_timer(ptr, t, my_timer);
          ...
          }
          ...
          timer_setup(&ptr->my_timer, my_callback, 0);
      
      Direct function assignments:
      
          void my_callback(unsigned long data)
          {
              struct something *ptr = (struct something *)data;
          ...
          }
          ...
          ptr->my_timer.function = my_callback;
      
      have a temporary cast added, along with converting the args:
      
          void my_callback(struct timer_list *t)
          {
              struct something *ptr = from_timer(ptr, t, my_timer);
          ...
          }
          ...
          ptr->my_timer.function = (TIMER_FUNC_TYPE)my_callback;
      
      And finally, callbacks without a data assignment:
      
          void my_callback(unsigned long data)
          {
          ...
          }
          ...
          setup_timer(&ptr->my_timer, my_callback, 0);
      
      have their argument renamed to verify they're unused during conversion:
      
          void my_callback(struct timer_list *unused)
          {
          ...
          }
          ...
          timer_setup(&ptr->my_timer, my_callback, 0);
      
      The conversion is done with the following Coccinelle script:
      
      spatch --very-quiet --all-includes --include-headers \
      	-I ./arch/x86/include -I ./arch/x86/include/generated \
      	-I ./include -I ./arch/x86/include/uapi \
      	-I ./arch/x86/include/generated/uapi -I ./include/uapi \
      	-I ./include/generated/uapi --include ./include/linux/kconfig.h \
      	--dir . \
      	--cocci-file ~/src/data/timer_setup.cocci
      
      @fix_address_of@
      expression e;
      @@
      
       setup_timer(
      -&(e)
      +&e
       , ...)
      
      // Update any raw setup_timer() usages that have a NULL callback, but
      // would otherwise match change_timer_function_usage, since the latter
      // will update all function assignments done in the face of a NULL
      // function initialization in setup_timer().
      @change_timer_function_usage_NULL@
      expression _E;
      identifier _timer;
      type _cast_data;
      @@
      
      (
      -setup_timer(&_E->_timer, NULL, _E);
      +timer_setup(&_E->_timer, NULL, 0);
      |
      -setup_timer(&_E->_timer, NULL, (_cast_data)_E);
      +timer_setup(&_E->_timer, NULL, 0);
      |
      -setup_timer(&_E._timer, NULL, &_E);
      +timer_setup(&_E._timer, NULL, 0);
      |
      -setup_timer(&_E._timer, NULL, (_cast_data)&_E);
      +timer_setup(&_E._timer, NULL, 0);
      )
      
      @change_timer_function_usage@
      expression _E;
      identifier _timer;
      struct timer_list _stl;
      identifier _callback;
      type _cast_func, _cast_data;
      @@
      
      (
      -setup_timer(&_E->_timer, _callback, _E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, &_callback, _E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, _callback, (_cast_data)_E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, &_callback, (_cast_data)_E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, (_cast_func)_callback, _E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, (_cast_func)&_callback, _E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, (_cast_func)_callback, (_cast_data)_E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, (_cast_func)&_callback, (_cast_data)_E);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E._timer, _callback, (_cast_data)_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, _callback, (_cast_data)&_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, &_callback, (_cast_data)_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, &_callback, (_cast_data)&_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, (_cast_func)_callback, (_cast_data)&_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, (_cast_func)&_callback, (_cast_data)&_E);
      +timer_setup(&_E._timer, _callback, 0);
      |
       _E->_timer@_stl.function = _callback;
      |
       _E->_timer@_stl.function = &_callback;
      |
       _E->_timer@_stl.function = (_cast_func)_callback;
      |
       _E->_timer@_stl.function = (_cast_func)&_callback;
      |
       _E._timer@_stl.function = _callback;
      |
       _E._timer@_stl.function = &_callback;
      |
       _E._timer@_stl.function = (_cast_func)_callback;
      |
       _E._timer@_stl.function = (_cast_func)&_callback;
      )
      
      // callback(unsigned long arg)
      @change_callback_handle_cast
       depends on change_timer_function_usage@
      identifier change_timer_function_usage._callback;
      identifier change_timer_function_usage._timer;
      type _origtype;
      identifier _origarg;
      type _handletype;
      identifier _handle;
      @@
      
       void _callback(
      -_origtype _origarg
      +struct timer_list *t
       )
       {
      (
      	... when != _origarg
      	_handletype *_handle =
      -(_handletype *)_origarg;
      +from_timer(_handle, t, _timer);
      	... when != _origarg
      |
      	... when != _origarg
      	_handletype *_handle =
      -(void *)_origarg;
      +from_timer(_handle, t, _timer);
      	... when != _origarg
      |
      	... when != _origarg
      	_handletype *_handle;
      	... when != _handle
      	_handle =
      -(_handletype *)_origarg;
      +from_timer(_handle, t, _timer);
      	... when != _origarg
      |
      	... when != _origarg
      	_handletype *_handle;
      	... when != _handle
      	_handle =
      -(void *)_origarg;
      +from_timer(_handle, t, _timer);
      	... when != _origarg
      )
       }
      
      // callback(unsigned long arg) without existing variable
      @change_callback_handle_cast_no_arg
       depends on change_timer_function_usage &&
                           !change_callback_handle_cast@
      identifier change_timer_function_usage._callback;
      identifier change_timer_function_usage._timer;
      type _origtype;
      identifier _origarg;
      type _handletype;
      @@
      
       void _callback(
      -_origtype _origarg
      +struct timer_list *t
       )
       {
      +	_handletype *_origarg = from_timer(_origarg, t, _timer);
      +
      	... when != _origarg
      -	(_handletype *)_origarg
      +	_origarg
      	... when != _origarg
       }
      
      // Avoid already converted callbacks.
      @match_callback_converted
       depends on change_timer_function_usage &&
                  !change_callback_handle_cast &&
      	    !change_callback_handle_cast_no_arg@
      identifier change_timer_function_usage._callback;
      identifier t;
      @@
      
       void _callback(struct timer_list *t)
       { ... }
      
      // callback(struct something *handle)
      @change_callback_handle_arg
       depends on change_timer_function_usage &&
      	    !match_callback_converted &&
                  !change_callback_handle_cast &&
                  !change_callback_handle_cast_no_arg@
      identifier change_timer_function_usage._callback;
      identifier change_timer_function_usage._timer;
      type _handletype;
      identifier _handle;
      @@
      
       void _callback(
      -_handletype *_handle
      +struct timer_list *t
       )
       {
      +	_handletype *_handle = from_timer(_handle, t, _timer);
      	...
       }
      
      // If change_callback_handle_arg ran on an empty function, remove
      // the added handler.
      @unchange_callback_handle_arg
       depends on change_timer_function_usage &&
      	    change_callback_handle_arg@
      identifier change_timer_function_usage._callback;
      identifier change_timer_function_usage._timer;
      type _handletype;
      identifier _handle;
      identifier t;
      @@
      
       void _callback(struct timer_list *t)
       {
      -	_handletype *_handle = from_timer(_handle, t, _timer);
       }
      
      // We only want to refactor the setup_timer() data argument if we've found
      // the matching callback. This undoes changes in change_timer_function_usage.
      @unchange_timer_function_usage
       depends on change_timer_function_usage &&
                  !change_callback_handle_cast &&
                  !change_callback_handle_cast_no_arg &&
      	    !change_callback_handle_arg@
      expression change_timer_function_usage._E;
      identifier change_timer_function_usage._timer;
      identifier change_timer_function_usage._callback;
      type change_timer_function_usage._cast_data;
      @@
      
      (
      -timer_setup(&_E->_timer, _callback, 0);
      +setup_timer(&_E->_timer, _callback, (_cast_data)_E);
      |
      -timer_setup(&_E._timer, _callback, 0);
      +setup_timer(&_E._timer, _callback, (_cast_data)&_E);
      )
      
      // If we fixed a callback from a .function assignment, fix the
      // assignment cast now.
      @change_timer_function_assignment
       depends on change_timer_function_usage &&
                  (change_callback_handle_cast ||
                   change_callback_handle_cast_no_arg ||
                   change_callback_handle_arg)@
      expression change_timer_function_usage._E;
      identifier change_timer_function_usage._timer;
      identifier change_timer_function_usage._callback;
      type _cast_func;
      typedef TIMER_FUNC_TYPE;
      @@
      
      (
       _E->_timer.function =
      -_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E->_timer.function =
      -&_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E->_timer.function =
      -(_cast_func)_callback;
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E->_timer.function =
      -(_cast_func)&_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E._timer.function =
      -_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E._timer.function =
      -&_callback;
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E._timer.function =
      -(_cast_func)_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      |
       _E._timer.function =
      -(_cast_func)&_callback
      +(TIMER_FUNC_TYPE)_callback
       ;
      )
      
      // Sometimes timer functions are called directly. Replace matched args.
      @change_timer_function_calls
       depends on change_timer_function_usage &&
                  (change_callback_handle_cast ||
                   change_callback_handle_cast_no_arg ||
                   change_callback_handle_arg)@
      expression _E;
      identifier change_timer_function_usage._timer;
      identifier change_timer_function_usage._callback;
      type _cast_data;
      @@
      
       _callback(
      (
      -(_cast_data)_E
      +&_E->_timer
      |
      -(_cast_data)&_E
      +&_E._timer
      |
      -_E
      +&_E->_timer
      )
       )
      
      // If a timer has been configured without a data argument, it can be
      // converted without regard to the callback argument, since it is unused.
      @match_timer_function_unused_data@
      expression _E;
      identifier _timer;
      identifier _callback;
      @@
      
      (
      -setup_timer(&_E->_timer, _callback, 0);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, _callback, 0L);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E->_timer, _callback, 0UL);
      +timer_setup(&_E->_timer, _callback, 0);
      |
      -setup_timer(&_E._timer, _callback, 0);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, _callback, 0L);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_E._timer, _callback, 0UL);
      +timer_setup(&_E._timer, _callback, 0);
      |
      -setup_timer(&_timer, _callback, 0);
      +timer_setup(&_timer, _callback, 0);
      |
      -setup_timer(&_timer, _callback, 0L);
      +timer_setup(&_timer, _callback, 0);
      |
      -setup_timer(&_timer, _callback, 0UL);
      +timer_setup(&_timer, _callback, 0);
      |
      -setup_timer(_timer, _callback, 0);
      +timer_setup(_timer, _callback, 0);
      |
      -setup_timer(_timer, _callback, 0L);
      +timer_setup(_timer, _callback, 0);
      |
      -setup_timer(_timer, _callback, 0UL);
      +timer_setup(_timer, _callback, 0);
      )
      
      @change_callback_unused_data
       depends on match_timer_function_unused_data@
      identifier match_timer_function_unused_data._callback;
      type _origtype;
      identifier _origarg;
      @@
      
       void _callback(
      -_origtype _origarg
      +struct timer_list *unused
       )
       {
      	... when != _origarg
       }
      Signed-off-by: NKees Cook <keescook@chromium.org>
      e99e88a9
  11. 14 11月, 2017 1 次提交
    • Z
      bnx2x: fix slowpath null crash · 442866ff
      Zhu Yanjun 提交于
      When "NETDEV WATCHDOG: em4 (bnx2x): transmit queue 2 timed out" occurs,
      BNX2X_SP_RTNL_TX_TIMEOUT is set. In the function bnx2x_sp_rtnl_task,
      bnx2x_nic_unload and bnx2x_nic_load are executed to shutdown and open
      NIC. In the function bnx2x_nic_load, bnx2x_alloc_mem allocates dma
      failure. The message "bnx2x: [bnx2x_alloc_mem:8399(em4)]Can't
      allocate memory" pops out. The variable slowpath is set to NULL.
      When shutdown the NIC, the function bnx2x_nic_unload is called. In
      the function bnx2x_nic_unload, the following functions are executed.
      bnx2x_chip_cleanup
          bnx2x_set_storm_rx_mode
              bnx2x_set_q_rx_mode
                  bnx2x_set_q_rx_mode
                      bnx2x_config_rx_mode
                          bnx2x_set_rx_mode_e2
      In the function bnx2x_set_rx_mode_e2, the variable slowpath is operated.
      Then the crash occurs.
      To fix this crash, the variable slowpath is checked. And in the function
      bnx2x_sp_rtnl_task, after dma memory allocation fails, another shutdown
      and open NIC is executed.
      
      CC: Joe Jin <joe.jin@oracle.com>
      CC: Junxiao Bi <junxiao.bi@oracle.com>
      Signed-off-by: NZhu Yanjun <yanjun.zhu@oracle.com>
      Acked-by: NAriel Elior <aelior@cavium.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      442866ff
  12. 22 9月, 2017 1 次提交
  13. 25 6月, 2017 1 次提交
  14. 22 5月, 2017 1 次提交
  15. 17 5月, 2017 1 次提交
  16. 05 4月, 2017 1 次提交
  17. 08 3月, 2017 2 次提交
  18. 25 12月, 2016 1 次提交
  19. 06 12月, 2016 2 次提交
  20. 24 10月, 2016 1 次提交
  21. 18 10月, 2016 1 次提交
    • J
      ethernet/broadcom: use core min/max MTU checking · e1c6dcca
      Jarod Wilson 提交于
      tg3: min_mtu 60, max_mtu 9000/1500
      
      bnxt: min_mtu 60, max_mtu 9000
      
      bnx2x: min_mtu 46, max_mtu 9600
      - Fix up ETH_OVREHEAD -> ETH_OVERHEAD while we're in here, remove
        duplicated defines from bnx2x_link.c.
      
      bnx2: min_mtu 46, max_mtu 9000
      - Use more standard ETH_* defines while we're at it.
      
      bcm63xx_enet: min_mtu 46, max_mtu 2028
      - compute_hw_mtu was made largely pointless, and thus merged back into
        bcm_enet_change_mtu.
      
      b44: min_mtu 60, max_mtu 1500
      
      CC: netdev@vger.kernel.org
      CC: Michael Chan <michael.chan@broadcom.com>
      CC: Sony Chacko <sony.chacko@qlogic.com>
      CC: Ariel Elior <ariel.elior@qlogic.com>
      CC: Dept-HSGLinuxNICDev@qlogic.com
      CC: Siva Reddy Kallam <siva.kallam@broadcom.com>
      CC: Prashant Sreedharan <prashant@broadcom.com>
      Signed-off-by: NJarod Wilson <jarod@redhat.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      e1c6dcca
  22. 26 9月, 2016 1 次提交
  23. 07 9月, 2016 1 次提交
  24. 02 9月, 2016 1 次提交
    • G
      bnx2x: don't reset chip on cleanup if PCI function is offline · b44e108b
      Guilherme G. Piccoli 提交于
      When PCI error is detected, in some architectures (like PowerPC) a slot
      reset is performed - the driver's error handlers are in charge of "disable"
      device before the reset, and re-enable it after a successful slot reset.
      
      There are two cases though that another path is taken on the code: if the
      slot reset is not successful or if too many errors already happened in the
      specific adapter (meaning that possibly the device is experiencing a HW
      failure that slot reset is not able to solve), the core PCI error mechanism
      (called EEH in PowerPC) will remove the adapter from the system, since it
      will consider this as a permanent failure on device. In this case, a path
      is taken that leads to bnx2x_chip_cleanup() calling bnx2x_reset_hw(), which
      then tries to perform a HW reset on chip. This reset won't succeed since
      the HW is in a fault state, which can be seen by multiple messages on
      kernel log like below:
      
      	bnx2x: [bnx2x_issue_dmae_with_comp:552(eth1)]DMAE timeout!
      	bnx2x: [bnx2x_write_dmae:600(eth1)]DMAE returned failure -1
      
      After some time, the PCI error mechanism gives up on waiting the driver's
      correct removal procedure and forcibly remove the adapter from the system.
      We can see soft lockup while core PCI error mechanism is waiting for driver
      to accomplish the right removal process.
      
      This patch adds a verification to avoid a chip reset whenever the function
      is in PCI error state - since this case is only reached when we have a
      device being removed because of a permanent failure, the HW chip reset is
      not expected to work fine neither is necessary.
      
      Also, as a minor improvement in error path, we avoid the MCP information dump
      in case of non-recoverable PCI error (when adapter is about to be removed),
      since it will certainly fail.
      Reported-by: NHarsha Thyagaraja <hathyaga@in.ibm.com>
      Signed-off-by: NGuilherme G. Piccoli <gpiccoli@linux.vnet.ibm.com>
      Acked-By: NYuval Mintz <Yuval.Mintz@qlogic.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      b44e108b
  25. 25 8月, 2016 1 次提交
    • Y
      bnx2x: Don't flush multicast MACs · c7b7b483
      Yuval Mintz 提交于
      When ndo_set_rx_mode() is called for bnx2x, as part of process of
      configuring the new MAC address filters [both unicast & multicast]
      driver begins by flushing the existing configuration and then iterating
      over the network device's list of addresses and configures those instead.
      
      This has the side-effect of creating a short gap where traffic wouldn't
      be properly classified, as no filters are configured in HW.
      While for unicasts this is rather insignificant [as unicast MACs don't
      frequently change while interface is actually running],
      for multicast traffic it does pose an issue as there are multicast-based
      networks where new multicast groups would constantly be removed and
      added.
      
      This patch tries to remedy this [at least for the newer adapters] -
      Instead of flushing & reconfiguring all existing multicast filters,
      the driver would instead create the approximate hash match that would
      result from the required filters. It would then compare it against the
      currently configured approximate hash match, and only add and remove the
      delta between those.
      Signed-off-by: NYuval Mintz <Yuval.Mintz@qlogic.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      c7b7b483
  26. 18 6月, 2016 1 次提交
  27. 06 6月, 2016 1 次提交
    • M
      bnx2x: allow adding VLANs while interface is down · a02cc9d3
      Michal Schmidt 提交于
      Since implementing VLAN filtering in commit 05cc5a39
      ("bnx2x: add vlan filtering offload") bnx2x refuses to add a VLAN while
      the interface is down:
      
        # ip link add link enp3s0f0 enp3s0f0_10 type vlan id 10
        RTNETLINK answers: Bad address
      
      and in dmesg (with bnx2x.debug=0x20):
        bnx2x: [bnx2x_vlan_rx_add_vid:12941(enp3s0f0)]Ignoring VLAN
        configuration the interface is down
      
      Other drivers have no problem with this.
      Fix this peculiar behavior in the following way:
       - Accept requests to add/kill VID regardless of the device state.
         Maintain the requested list of VIDs in the bp->vlan_reg list.
       - If the device is up, try to configure the VID list into the hardware.
         If we run out of VLAN credits or encounter a failure configuring an
         entry, fall back to accepting all VLANs.
         If we successfully configure all entries from the list, turn the
         fallback off.
       - Use the same code for reconfiguring VLANs during NIC load.
      Signed-off-by: NMichal Schmidt <mschmidt@redhat.com>
      Acked-by: NYuval Mintz <Yuval.Mintz@qlogic.com>
      Signed-off-by: NDavid S. Miller <davem@davemloft.net>
      a02cc9d3
  28. 01 6月, 2016 1 次提交
  29. 21 5月, 2016 1 次提交
  30. 19 3月, 2016 1 次提交
  31. 03 3月, 2016 3 次提交