]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Jul 2012 01:09:01 +0000 (18:09 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 27 Jul 2012 01:09:01 +0000 (18:09 -0700)
Pull networking updates and fixes from David Miller:

1) Reinstate the no-ref optimization for input route lookups in ipv4 to
   fix some routing cache removal perf regressions.

2) Make TCP socket pre-demux work on ipv6 side too, from Eric Dumazet.

3) Get RX hash value from correct place in be2net driver, from
   Sarveshwar Bandi.

4) Validation of FIB cached routes missing critical check, from Eric
   Dumazet.

5) EEH support in mlx4 driver, from Kleber Sacilotto de Souza.

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (23 commits)
  ipv6: Early TCP socket demux
  ipv4: Fix input route performance regression.
  pch_gbe: vlan skb len fix
  pch_gbe: add extra clean tx
  pch_gbe: fix transmit watchdog timeout
  ixgbe: fix panic while dumping packets on Tx hang with IOMMU
  be2net: Fix to parse RSS hash from Receive completions correctly.
  net/mlx4_en: Limit the RFS filter IDs to be < RPS_NO_FILTER
  hyperv: Add error handling to rndis_filter_device_add()
  hyperv: Add a check for ring_size value
  ipv4: rt_cache_valid must check expired routes
  net/pch_gpe: Cannot disable ethernet autonegation
  qeth: repair crash in qeth_l3_vlan_rx_kill_vid()
  netiucv: cleanup attribute usage
  net: wiznet add missing HAS_IOMEM dependency
  be2net: Missing byteswap in be_get_fw_log_level causes oops on PowerPC
  mlx4: Add support for EEH error recovery
  cdc-ncm: tag Ericsson WWAN devices (eg F5521gw) with FLAG_WWAN
  wanmain: comparing array with NULL
  caif: fix NULL pointer check
  ...

1  2 
drivers/net/ethernet/mellanox/mlx4/main.c

index e8f8ebb4ae65d653befa53f87f3fd319fb3b96ad,e717091734d016fdb4e3d5c612a497d12e887457..48d0e90194cb19d2a322990425b478f9e178b623
@@@ -218,10 -218,6 +218,10 @@@ static int mlx4_dev_cap(struct mlx4_de
        for (i = 1; i <= dev->caps.num_ports; ++i) {
                dev->caps.vl_cap[i]         = dev_cap->max_vl[i];
                dev->caps.ib_mtu_cap[i]     = dev_cap->ib_mtu[i];
 +              dev->phys_caps.gid_phys_table_len[i]  = dev_cap->max_gids[i];
 +              dev->phys_caps.pkey_phys_table_len[i] = dev_cap->max_pkeys[i];
 +              /* set gid and pkey table operating lengths by default
 +               * to non-sriov values */
                dev->caps.gid_table_len[i]  = dev_cap->max_gids[i];
                dev->caps.pkey_table_len[i] = dev_cap->max_pkeys[i];
                dev->caps.port_width_cap[i] = dev_cap->max_port_width[i];
                        /* if only ETH is supported - assign ETH */
                        if (dev->caps.supported_type[i] == MLX4_PORT_TYPE_ETH)
                                dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
 -                      /* if only IB is supported,
 -                       * assign IB only if SRIOV is off*/
 +                      /* if only IB is supported, assign IB */
                        else if (dev->caps.supported_type[i] ==
 -                               MLX4_PORT_TYPE_IB) {
 -                              if (dev->flags & MLX4_FLAG_SRIOV)
 -                                      dev->caps.port_type[i] =
 -                                              MLX4_PORT_TYPE_NONE;
 -                              else
 -                                      dev->caps.port_type[i] =
 -                                              MLX4_PORT_TYPE_IB;
 -                      /* if IB and ETH are supported,
 -                       * first of all check if SRIOV is on */
 -                      } else if (dev->flags & MLX4_FLAG_SRIOV)
 -                              dev->caps.port_type[i] = MLX4_PORT_TYPE_ETH;
 +                               MLX4_PORT_TYPE_IB)
 +                              dev->caps.port_type[i] = MLX4_PORT_TYPE_IB;
                        else {
 -                              /* In non-SRIOV mode, we set the port type
 -                               * according to user selection of port type,
 -                               * if usere selected none, take the FW hint */
 -                              if (port_type_array[i-1] == MLX4_PORT_TYPE_NONE)
 +                              /* if IB and ETH are supported, we set the port
 +                               * type according to user selection of port type;
 +                               * if user selected none, take the FW hint */
 +                              if (port_type_array[i - 1] == MLX4_PORT_TYPE_NONE)
                                        dev->caps.port_type[i] = dev->caps.suggested_type[i] ?
                                                MLX4_PORT_TYPE_ETH : MLX4_PORT_TYPE_IB;
                                else
 -                                      dev->caps.port_type[i] = port_type_array[i-1];
 +                                      dev->caps.port_type[i] = port_type_array[i - 1];
                        }
                }
                /*
@@@ -409,23 -415,6 +409,23 @@@ static int mlx4_how_many_lives_vf(struc
        return ret;
  }
  
 +int mlx4_get_parav_qkey(struct mlx4_dev *dev, u32 qpn, u32 *qkey)
 +{
 +      u32 qk = MLX4_RESERVED_QKEY_BASE;
 +      if (qpn >= dev->caps.base_tunnel_sqpn + 8 * MLX4_MFUNC_MAX ||
 +          qpn < dev->caps.sqp_start)
 +              return -EINVAL;
 +
 +      if (qpn >= dev->caps.base_tunnel_sqpn)
 +              /* tunnel qp */
 +              qk += qpn - dev->caps.base_tunnel_sqpn;
 +      else
 +              qk += qpn - dev->caps.sqp_start;
 +      *qkey = qk;
 +      return 0;
 +}
 +EXPORT_SYMBOL(mlx4_get_parav_qkey);
 +
  int mlx4_is_slave_active(struct mlx4_dev *dev, int slave)
  {
        struct mlx4_priv *priv = mlx4_priv(dev);
@@@ -526,13 -515,8 +526,13 @@@ static int mlx4_slave_cap(struct mlx4_d
                return -ENODEV;
        }
  
 -      for (i = 1; i <= dev->caps.num_ports; ++i)
 +      for (i = 1; i <= dev->caps.num_ports; ++i) {
                dev->caps.port_mask[i] = dev->caps.port_type[i];
 +              if (mlx4_get_slave_pkey_gid_tbl_len(dev, i,
 +                                                  &dev->caps.gid_table_len[i],
 +                                                  &dev->caps.pkey_table_len[i]))
 +                      return -ENODEV;
 +      }
  
        if (dev->caps.uar_page_size * (dev->caps.num_uars -
                                       dev->caps.reserved_uars) >
@@@ -569,7 -553,7 +569,7 @@@ int mlx4_change_port_types(struct mlx4_
                for (port = 1; port <= dev->caps.num_ports; port++) {
                        mlx4_CLOSE_PORT(dev, port);
                        dev->caps.port_type[port] = port_types[port - 1];
 -                      err = mlx4_SET_PORT(dev, port);
 +                      err = mlx4_SET_PORT(dev, port, -1);
                        if (err) {
                                mlx4_err(dev, "Failed to set port %d, "
                                              "aborting\n", port);
@@@ -755,7 -739,7 +755,7 @@@ static ssize_t set_port_ib_mtu(struct d
        mlx4_unregister_device(mdev);
        for (port = 1; port <= mdev->caps.num_ports; port++) {
                mlx4_CLOSE_PORT(mdev, port);
 -              err = mlx4_SET_PORT(mdev, port);
 +              err = mlx4_SET_PORT(mdev, port, -1);
                if (err) {
                        mlx4_err(mdev, "Failed to set port %d, "
                                      "aborting\n", port);
        return -EIO;
  }
  
 +static void mlx4_parav_master_pf_caps(struct mlx4_dev *dev)
 +{
 +      int i;
 +
 +      for (i = 1; i <= dev->caps.num_ports; i++) {
 +              dev->caps.gid_table_len[i] = 1;
 +              dev->caps.pkey_table_len[i] =
 +                      dev->phys_caps.pkey_phys_table_len[i] - 1;
 +      }
 +}
 +
  static int mlx4_init_hca(struct mlx4_dev *dev)
  {
        struct mlx4_priv          *priv = mlx4_priv(dev);
                        goto err_stop_fw;
                }
  
 +              if (mlx4_is_master(dev))
 +                      mlx4_parav_master_pf_caps(dev);
 +
                priv->fs_hash_mode = MLX4_FS_L2_HASH;
  
                switch (priv->fs_hash_mode) {
@@@ -1552,24 -1522,12 +1552,24 @@@ static int mlx4_setup_hca(struct mlx4_d
                                          "with caps = 0\n", port, err);
                        dev->caps.ib_port_def_cap[port] = ib_port_default_caps;
  
 +                      /* initialize per-slave default ib port capabilities */
 +                      if (mlx4_is_master(dev)) {
 +                              int i;
 +                              for (i = 0; i < dev->num_slaves; i++) {
 +                                      if (i == mlx4_master_func_num(dev))
 +                                              continue;
 +                                      priv->mfunc.master.slave_state[i].ib_cap_mask[port] =
 +                                                      ib_port_default_caps;
 +                              }
 +                      }
 +
                        if (mlx4_is_mfunc(dev))
                                dev->caps.port_ib_mtu[port] = IB_MTU_2048;
                        else
                                dev->caps.port_ib_mtu[port] = IB_MTU_4096;
  
 -                      err = mlx4_SET_PORT(dev, port);
 +                      err = mlx4_SET_PORT(dev, port, mlx4_is_master(dev) ?
 +                                          dev->caps.pkey_table_len[port] : -1);
                        if (err) {
                                mlx4_err(dev, "Failed to set port %d, aborting\n",
                                        port);
@@@ -1817,6 -1775,9 +1817,9 @@@ static int mlx4_get_ownership(struct ml
        void __iomem *owner;
        u32 ret;
  
+       if (pci_channel_offline(dev->pdev))
+               return -EIO;
        owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE,
                        MLX4_OWNER_SIZE);
        if (!owner) {
@@@ -1833,6 -1794,9 +1836,9 @@@ static void mlx4_free_ownership(struct 
  {
        void __iomem *owner;
  
+       if (pci_channel_offline(dev->pdev))
+               return;
        owner = ioremap(pci_resource_start(dev->pdev, 0) + MLX4_OWNER_BASE,
                        MLX4_OWNER_SIZE);
        if (!owner) {
@@@ -2279,11 -2243,33 +2285,33 @@@ static DEFINE_PCI_DEVICE_TABLE(mlx4_pci
  
  MODULE_DEVICE_TABLE(pci, mlx4_pci_table);
  
+ static pci_ers_result_t mlx4_pci_err_detected(struct pci_dev *pdev,
+                                             pci_channel_state_t state)
+ {
+       mlx4_remove_one(pdev);
+       return state == pci_channel_io_perm_failure ?
+               PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_NEED_RESET;
+ }
+ static pci_ers_result_t mlx4_pci_slot_reset(struct pci_dev *pdev)
+ {
+       int ret = __mlx4_init_one(pdev, NULL);
+       return ret ? PCI_ERS_RESULT_DISCONNECT : PCI_ERS_RESULT_RECOVERED;
+ }
+ static struct pci_error_handlers mlx4_err_handler = {
+       .error_detected = mlx4_pci_err_detected,
+       .slot_reset     = mlx4_pci_slot_reset,
+ };
  static struct pci_driver mlx4_driver = {
        .name           = DRV_NAME,
        .id_table       = mlx4_pci_table,
        .probe          = mlx4_init_one,
-       .remove         = __devexit_p(mlx4_remove_one)
+       .remove         = __devexit_p(mlx4_remove_one),
+       .err_handler    = &mlx4_err_handler,
  };
  
  static int __init mlx4_verify_params(void)