net: aquantia: Fix actual speed capabilities reporting
authorIgor Russkikh <igor.russkikh@aquantia.com>
Thu, 14 Dec 2017 09:34:40 +0000 (12:34 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 15 Dec 2017 17:46:41 +0000 (12:46 -0500)
Different hardware device Ids correspond to different maximum speed
available. Extra checks were added for devices D108 and D109 to
remove unsupported speeds from these device capabilities list.

Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/aquantia/atlantic/aq_hw.h
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/aq_pci_func.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_a0.c
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c

index 0207927dc8a6ab4ac76c46fb17669b7e50e7ae1e..4ebd53b3c7da74b8b6a46e743b009fe190677351 100644 (file)
@@ -85,7 +85,9 @@ struct aq_hw_ops {
        void (*destroy)(struct aq_hw_s *self);
 
        int (*get_hw_caps)(struct aq_hw_s *self,
-                          struct aq_hw_caps_s *aq_hw_caps);
+                          struct aq_hw_caps_s *aq_hw_caps,
+                          unsigned short device,
+                          unsigned short subsystem_device);
 
        int (*hw_ring_tx_xmit)(struct aq_hw_s *self, struct aq_ring_s *aq_ring,
                               unsigned int frags);
index 78dfb2ab78cefa0586168a0d043348c3488f0f20..a360ccc298b9e935abcc9b0510da91f7ffb80c19 100644 (file)
@@ -222,7 +222,7 @@ static struct net_device *aq_nic_ndev_alloc(void)
 
 struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
                                   const struct ethtool_ops *et_ops,
-                                  struct device *dev,
+                                  struct pci_dev *pdev,
                                   struct aq_pci_func_s *aq_pci_func,
                                   unsigned int port,
                                   const struct aq_hw_ops *aq_hw_ops)
@@ -242,7 +242,7 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
        ndev->netdev_ops = ndev_ops;
        ndev->ethtool_ops = et_ops;
 
-       SET_NETDEV_DEV(ndev, dev);
+       SET_NETDEV_DEV(ndev, &pdev->dev);
 
        ndev->if_port = port;
        self->ndev = ndev;
@@ -254,7 +254,8 @@ struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
 
        self->aq_hw = self->aq_hw_ops.create(aq_pci_func, self->port,
                                                &self->aq_hw_ops);
-       err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps);
+       err = self->aq_hw_ops.get_hw_caps(self->aq_hw, &self->aq_hw_caps,
+                                         pdev->device, pdev->subsystem_device);
        if (err < 0)
                goto err_exit;
 
index 4309983acdd6f7502fa05869f79336fd459dc2fe..3c9f8db03d5f2a576c83064b18e930d5af6b7e1c 100644 (file)
@@ -71,7 +71,7 @@ struct aq_nic_cfg_s {
 
 struct aq_nic_s *aq_nic_alloc_cold(const struct net_device_ops *ndev_ops,
                                   const struct ethtool_ops *et_ops,
-                                  struct device *dev,
+                                  struct pci_dev *pdev,
                                   struct aq_pci_func_s *aq_pci_func,
                                   unsigned int port,
                                   const struct aq_hw_ops *aq_hw_ops);
index cadaa646c89f4b741382b4beee72c6ec3e3bfc18..58c29d04b186e634686ca667bc5afe9bd86e63a3 100644 (file)
@@ -51,7 +51,8 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops,
        pci_set_drvdata(pdev, self);
        self->pdev = pdev;
 
-       err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps);
+       err = aq_hw_ops->get_hw_caps(NULL, &self->aq_hw_caps, pdev->device,
+                                    pdev->subsystem_device);
        if (err < 0)
                goto err_exit;
 
@@ -59,7 +60,7 @@ struct aq_pci_func_s *aq_pci_func_alloc(struct aq_hw_ops *aq_hw_ops,
 
        for (port = 0; port < self->ports; ++port) {
                struct aq_nic_s *aq_nic = aq_nic_alloc_cold(ndev_ops, eth_ops,
-                                                           &pdev->dev, self,
+                                                           pdev, self,
                                                            port, aq_hw_ops);
 
                if (!aq_nic) {
index 07b3c49a16a4266b4fb312bb79198f9ba0c60f04..b0abd187cead95a34da01d2b07f54e5bf30726cb 100644 (file)
 #include "hw_atl_a0_internal.h"
 
 static int hw_atl_a0_get_hw_caps(struct aq_hw_s *self,
-                                struct aq_hw_caps_s *aq_hw_caps)
+                                struct aq_hw_caps_s *aq_hw_caps,
+                                unsigned short device,
+                                unsigned short subsystem_device)
 {
        memcpy(aq_hw_caps, &hw_atl_a0_hw_caps_, sizeof(*aq_hw_caps));
+
+       if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001)
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G;
+
+       if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) {
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_10G;
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_A0_RATE_5G;
+       }
+
        return 0;
 }
 
index ec68c20efcbdb6079b9dba4b8200ad8f1f450233..e4e3b8e2d67e124c4abe31840f496a745e729885 100644 (file)
 #include "hw_atl_b0_internal.h"
 
 static int hw_atl_b0_get_hw_caps(struct aq_hw_s *self,
-                                struct aq_hw_caps_s *aq_hw_caps)
+                                struct aq_hw_caps_s *aq_hw_caps,
+                                unsigned short device,
+                                unsigned short subsystem_device)
 {
        memcpy(aq_hw_caps, &hw_atl_b0_hw_caps_, sizeof(*aq_hw_caps));
+
+       if (device == HW_ATL_DEVICE_ID_D108 && subsystem_device == 0x0001)
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G;
+
+       if (device == HW_ATL_DEVICE_ID_D109 && subsystem_device == 0x0001) {
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_10G;
+               aq_hw_caps->link_speed_msk &= ~HW_ATL_B0_RATE_5G;
+       }
+
        return 0;
 }