]> git.kernelconcepts.de Git - karo-tx-linux.git/commitdiff
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net
authorDavid S. Miller <davem@davemloft.net>
Mon, 5 May 2014 20:30:03 +0000 (16:30 -0400)
committerDavid S. Miller <davem@davemloft.net>
Mon, 5 May 2014 20:30:03 +0000 (16:30 -0400)
Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates

This series contains updates to e1000e only.

David provides four fixes for e1000e, first is a workaround for a hardware
erratum on 82579 devices which experienced packet loss in gigabit and 100
speeds when interconnect between the PHY and MAC is exiting K1 power saving
state.  Second expands the scope of a workaround to include i217 and i218
parts as well to address over aggressive transmit behavior when connecting
at 10Mbs half-duplex.  Next is to resolve a reported link flap issue on
82579 parts which was root caused as an interoperability problem between
82579 and at least some Broadcom PHYs in the Energy Efficient Ethernet wake
mechanism.  Lastly, restricts the workaround of putting the PHY into MDIO
slow mode to access the PHY id to relevant parts since this issue has been
fixed on the newer hardware.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx4/main.c
drivers/net/ethernet/mellanox/mlx4/port.c
drivers/net/ethernet/mellanox/mlx4/resource_tracker.c
drivers/net/usb/cdc_ncm.c

index cef267e24f9c9c680613ec4ed2817c040b21c964..7cf9dadcb471bbfee9ef32761123ece4ceac131d 100644 (file)
@@ -754,10 +754,10 @@ static void mlx4_request_modules(struct mlx4_dev *dev)
                        has_eth_port = true;
        }
 
-       if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
-               request_module_nowait(IB_DRV_NAME);
        if (has_eth_port)
                request_module_nowait(EN_DRV_NAME);
+       if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE))
+               request_module_nowait(IB_DRV_NAME);
 }
 
 /*
@@ -2440,7 +2440,8 @@ slave_start:
         * No return code for this call, just warn the user in case of PCI
         * express device capabilities are under-satisfied by the bus.
         */
-       mlx4_check_pcie_caps(dev);
+       if (!mlx4_is_slave(dev))
+               mlx4_check_pcie_caps(dev);
 
        /* In master functions, the communication channel must be initialized
         * after obtaining its address from fw */
index cfcad26ed40f60b0e5b992195339d8c12c0e68d7..b5b3549b0c8d30e9878249c502af4d18e5162a25 100644 (file)
@@ -1106,6 +1106,9 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
        }
 
        if (found_ix >= 0) {
+               /* Calculate a slave_gid which is the slave number in the gid
+                * table and not a globally unique slave number.
+                */
                if (found_ix < MLX4_ROCE_PF_GIDS)
                        slave_gid = 0;
                else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) *
@@ -1118,41 +1121,43 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid,
                          ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) /
                         (vf_gids / num_vfs)) + vf_gids % num_vfs + 1;
 
+               /* Calculate the globally unique slave id */
                if (slave_gid) {
                        struct mlx4_active_ports exclusive_ports;
                        struct mlx4_active_ports actv_ports;
                        struct mlx4_slaves_pport slaves_pport_actv;
                        unsigned max_port_p_one;
-                       int num_slaves_before = 1;
+                       int num_vfs_before = 0;
+                       int candidate_slave_gid;
 
+                       /* Calculate how many VFs are on the previous port, if exists */
                        for (i = 1; i < port; i++) {
                                bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
-                               set_bit(i, exclusive_ports.ports);
+                               set_bit(i - 1, exclusive_ports.ports);
                                slaves_pport_actv =
                                        mlx4_phys_to_slaves_pport_actv(
                                                        dev, &exclusive_ports);
-                               num_slaves_before += bitmap_weight(
+                               num_vfs_before += bitmap_weight(
                                                slaves_pport_actv.slaves,
                                                dev->num_vfs + 1);
                        }
 
-                       if (slave_gid < num_slaves_before) {
-                               bitmap_zero(exclusive_ports.ports, dev->caps.num_ports);
-                               set_bit(port - 1, exclusive_ports.ports);
-                               slaves_pport_actv =
-                                       mlx4_phys_to_slaves_pport_actv(
-                                                       dev, &exclusive_ports);
-                               slave_gid += bitmap_weight(
-                                               slaves_pport_actv.slaves,
-                                               dev->num_vfs + 1) -
-                                               num_slaves_before;
-                       }
-                       actv_ports = mlx4_get_active_ports(dev, slave_gid);
+                       /* candidate_slave_gid isn't necessarily the correct slave, but
+                        * it has the same number of ports and is assigned to the same
+                        * ports as the real slave we're looking for. On dual port VF,
+                        * slave_gid = [single port VFs on port <port>] +
+                        * [offset of the current slave from the first dual port VF] +
+                        * 1 (for the PF).
+                        */
+                       candidate_slave_gid = slave_gid + num_vfs_before;
+
+                       actv_ports = mlx4_get_active_ports(dev, candidate_slave_gid);
                        max_port_p_one = find_first_bit(
                                actv_ports.ports, dev->caps.num_ports) +
                                bitmap_weight(actv_ports.ports,
                                              dev->caps.num_ports) + 1;
 
+                       /* Calculate the real slave number */
                        for (i = 1; i < max_port_p_one; i++) {
                                if (i == port)
                                        continue;
index 3b5f53ef29b292d6edcb027f6b64b9c108a3a03b..1c3fdd4a1f7df3fe84847ae7ff278d652db13463 100644 (file)
@@ -3733,6 +3733,25 @@ static int qp_detach(struct mlx4_dev *dev, struct mlx4_qp *qp,
        }
 }
 
+static int mlx4_adjust_port(struct mlx4_dev *dev, int slave,
+                           u8 *gid, enum mlx4_protocol prot)
+{
+       int real_port;
+
+       if (prot != MLX4_PROT_ETH)
+               return 0;
+
+       if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0 ||
+           dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) {
+               real_port = mlx4_slave_convert_port(dev, slave, gid[5]);
+               if (real_port < 0)
+                       return -EINVAL;
+               gid[5] = real_port;
+       }
+
+       return 0;
+}
+
 int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
                               struct mlx4_vhcr *vhcr,
                               struct mlx4_cmd_mailbox *inbox,
@@ -3768,6 +3787,10 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave,
                if (err)
                        goto ex_detach;
        } else {
+               err = mlx4_adjust_port(dev, slave, gid, prot);
+               if (err)
+                       goto ex_put;
+
                err = rem_mcg_res(dev, slave, rqp, gid, prot, type, &reg_id);
                if (err)
                        goto ex_put;
index 549dbac710ed5f576f84cedf375df8588e5a7dc5..9a2bd11943ebf391a5678c7ded07ee0bc7b50f5e 100644 (file)
@@ -785,7 +785,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign)
            skb_out->len > CDC_NCM_MIN_TX_PKT)
                memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0,
                       ctx->tx_max - skb_out->len);
-       else if ((skb_out->len % dev->maxpacket) == 0)
+       else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0)
                *skb_put(skb_out, 1) = 0;       /* force short packet */
 
        /* set final frame length */