aqc111: fix writing to the phy on BE
authorOliver Neukum <oneukum@suse.com>
Thu, 9 May 2019 09:08:17 +0000 (11:08 +0200)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 May 2019 16:35:40 +0000 (09:35 -0700)
When writing to the phy on BE architectures an internal data structure
was directly given, leading to it being byte swapped in the wrong
way for the CPU in 50% of all cases. A temporary buffer must be used.

Signed-off-by: Oliver Neukum <oneukum@suse.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/usb/aqc111.c

index 408df2d335e3a648d46e1f00626761c510b741d9..599d560a8450bcd2784289a32c152ca9d7e6cf36 100644 (file)
@@ -320,6 +320,7 @@ static int aqc111_get_link_ksettings(struct net_device *net,
 static void aqc111_set_phy_speed(struct usbnet *dev, u8 autoneg, u16 speed)
 {
        struct aqc111_data *aqc111_data = dev->driver_priv;
+       u32 phy_on_the_wire;
 
        aqc111_data->phy_cfg &= ~AQ_ADV_MASK;
        aqc111_data->phy_cfg |= AQ_PAUSE;
@@ -361,7 +362,8 @@ static void aqc111_set_phy_speed(struct usbnet *dev, u8 autoneg, u16 speed)
                }
        }
 
-       aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0, &aqc111_data->phy_cfg);
+       phy_on_the_wire = aqc111_data->phy_cfg;
+       aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0, &phy_on_the_wire);
 }
 
 static int aqc111_set_link_ksettings(struct net_device *net,
@@ -755,6 +757,7 @@ static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
 {
        struct aqc111_data *aqc111_data = dev->driver_priv;
        u16 reg16;
+       u32 phy_on_the_wire;
 
        /* Force bz */
        reg16 = SFR_PHYPWR_RSTCTL_BZ;
@@ -768,8 +771,9 @@ static void aqc111_unbind(struct usbnet *dev, struct usb_interface *intf)
        aqc111_data->phy_cfg &= ~AQ_ADV_MASK;
        aqc111_data->phy_cfg |= AQ_LOW_POWER;
        aqc111_data->phy_cfg &= ~AQ_PHY_POWER_EN;
+       phy_on_the_wire = aqc111_data->phy_cfg;
        aqc111_write32_cmd_nopm(dev, AQ_PHY_OPS, 0, 0,
-                               &aqc111_data->phy_cfg);
+                               &phy_on_the_wire);
 
        kfree(aqc111_data);
 }
@@ -992,6 +996,7 @@ static int aqc111_reset(struct usbnet *dev)
 {
        struct aqc111_data *aqc111_data = dev->driver_priv;
        u8 reg8 = 0;
+       u32 phy_on_the_wire;
 
        dev->rx_urb_size = URB_SIZE;
 
@@ -1004,8 +1009,9 @@ static int aqc111_reset(struct usbnet *dev)
 
        /* Power up ethernet PHY */
        aqc111_data->phy_cfg = AQ_PHY_POWER_EN;
+       phy_on_the_wire = aqc111_data->phy_cfg;
        aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
-                          &aqc111_data->phy_cfg);
+                          &phy_on_the_wire);
 
        /* Set the MAC address */
        aqc111_write_cmd(dev, AQ_ACCESS_MAC, SFR_NODE_ID, ETH_ALEN,
@@ -1036,6 +1042,7 @@ static int aqc111_stop(struct usbnet *dev)
 {
        struct aqc111_data *aqc111_data = dev->driver_priv;
        u16 reg16 = 0;
+       u32 phy_on_the_wire;
 
        aqc111_read16_cmd(dev, AQ_ACCESS_MAC, SFR_MEDIUM_STATUS_MODE,
                          2, &reg16);
@@ -1047,8 +1054,9 @@ static int aqc111_stop(struct usbnet *dev)
 
        /* Put PHY to low power*/
        aqc111_data->phy_cfg |= AQ_LOW_POWER;
+       phy_on_the_wire = aqc111_data->phy_cfg;
        aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
-                          &aqc111_data->phy_cfg);
+                          &phy_on_the_wire);
 
        netif_carrier_off(dev->net);
 
@@ -1324,6 +1332,7 @@ static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
        u16 temp_rx_ctrl = 0x00;
        u16 reg16;
        u8 reg8;
+       u32 phy_on_the_wire;
 
        usbnet_suspend(intf, message);
 
@@ -1395,12 +1404,14 @@ static int aqc111_suspend(struct usb_interface *intf, pm_message_t message)
 
                aqc111_write_cmd(dev, AQ_WOL_CFG, 0, 0,
                                 WOL_CFG_SIZE, &wol_cfg);
+               phy_on_the_wire = aqc111_data->phy_cfg;
                aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
-                                  &aqc111_data->phy_cfg);
+                                  &phy_on_the_wire);
        } else {
                aqc111_data->phy_cfg |= AQ_LOW_POWER;
+               phy_on_the_wire = aqc111_data->phy_cfg;
                aqc111_write32_cmd(dev, AQ_PHY_OPS, 0, 0,
-                                  &aqc111_data->phy_cfg);
+                                  &phy_on_the_wire);
 
                /* Disable RX path */
                aqc111_read16_cmd_nopm(dev, AQ_ACCESS_MAC,