diff options
author | David S. Miller <davem@davemloft.net> | 2019-05-31 00:39:25 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-05-31 00:39:25 +0300 |
commit | 1b0b807dd7469e36b761f5bb4ee40b61331aeee8 (patch) | |
tree | 7c43c8864d48bf08cfe8320b1a3040642381e7af | |
parent | 25e94115aee6dc8fb088a57945974d334eb72575 (diff) | |
parent | ce8843abfa674350bf0f4f1b88d8e50a59401a46 (diff) | |
download | linux-1b0b807dd7469e36b761f5bb4ee40b61331aeee8.tar.xz |
Merge branch 'r8169-fw'
Heiner Kallweit says:
====================
r8169: decouple firmware handling code from actual driver code
These two patches are a step towards eventually factoring out firmware
handling code to a separate source file.
====================
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/realtek/r8169.c | 71 |
1 files changed, 37 insertions, 34 deletions
diff --git a/drivers/net/ethernet/realtek/r8169.c b/drivers/net/ethernet/realtek/r8169.c index 1f98e450b8cb..ec9f98ad7490 100644 --- a/drivers/net/ethernet/realtek/r8169.c +++ b/drivers/net/ethernet/realtek/r8169.c @@ -626,6 +626,10 @@ struct rtl8169_stats { struct u64_stats_sync syncp; }; +struct rtl8169_private; +typedef void (*rtl_fw_write_t)(struct rtl8169_private *tp, int reg, int val); +typedef int (*rtl_fw_read_t)(struct rtl8169_private *tp, int reg); + struct rtl8169_private { void __iomem *mmio_addr; /* memory map physical address */ struct pci_dev *pci_dev; @@ -679,6 +683,10 @@ struct rtl8169_private { const char *fw_name; struct rtl_fw { + rtl_fw_write_t phy_write; + rtl_fw_read_t phy_read; + rtl_fw_write_t mac_mcu_write; + rtl_fw_read_t mac_mcu_read; const struct firmware *fw; #define RTL_VER_SIZE 32 @@ -1009,7 +1017,7 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) return value; } -static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val) +static void rtl_writephy(struct rtl8169_private *tp, int location, int val) { tp->mdio_ops.write(tp, location, val); } @@ -2314,50 +2322,45 @@ static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) const struct firmware *fw = rtl_fw->fw; struct fw_info *fw_info = (struct fw_info *)fw->data; struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; - char *version = rtl_fw->version; - bool rc = false; if (fw->size < FW_OPCODE_SIZE) - goto out; + return false; if (!fw_info->magic) { size_t i, size, start; u8 checksum = 0; if (fw->size < sizeof(*fw_info)) - goto out; + return false; for (i = 0; i < fw->size; i++) checksum += fw->data[i]; if (checksum != 0) - goto out; + return false; start = le32_to_cpu(fw_info->fw_start); if (start > fw->size) - goto out; + return false; size = le32_to_cpu(fw_info->fw_len); if (size > (fw->size - start) / FW_OPCODE_SIZE) - goto out; + return false; - memcpy(version, fw_info->version, RTL_VER_SIZE); + strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE); pa->code = (__le32 *)(fw->data + start); pa->size = size; } else { if (fw->size % FW_OPCODE_SIZE) - goto out; + return false; - strlcpy(version, tp->fw_name, RTL_VER_SIZE); + strscpy(rtl_fw->version, tp->fw_name, RTL_VER_SIZE); pa->code = (__le32 *)fw->data; pa->size = fw->size / FW_OPCODE_SIZE; } - version[RTL_VER_SIZE - 1] = 0; - rc = true; -out: - return rc; + return true; } static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, @@ -2432,17 +2435,15 @@ out: return rc; } -static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) +static void rtl_fw_write_firmware(struct rtl8169_private *tp, + struct rtl_fw *rtl_fw) { struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; - struct mdio_ops org, *ops = &tp->mdio_ops; - u32 predata, count; + rtl_fw_write_t fw_write = rtl_fw->phy_write; + rtl_fw_read_t fw_read = rtl_fw->phy_read; + int predata = 0, count = 0; size_t index; - predata = count = 0; - org.write = ops->write; - org.read = ops->read; - for (index = 0; index < pa->size; ) { u32 action = le32_to_cpu(pa->code[index]); u32 data = action & 0x0000ffff; @@ -2453,7 +2454,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) switch(action & 0xf0000000) { case PHY_READ: - predata = rtl_readphy(tp, regno); + predata = fw_read(tp, regno); count++; index++; break; @@ -2470,11 +2471,11 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) break; case PHY_MDIO_CHG: if (data == 0) { - ops->write = org.write; - ops->read = org.read; + fw_write = rtl_fw->phy_write; + fw_read = rtl_fw->phy_read; } else if (data == 1) { - ops->write = mac_mcu_write; - ops->read = mac_mcu_read; + fw_write = rtl_fw->mac_mcu_write; + fw_read = rtl_fw->mac_mcu_read; } index++; @@ -2484,7 +2485,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index++; break; case PHY_WRITE: - rtl_writephy(tp, regno, data); + fw_write(tp, regno, data); index++; break; case PHY_READCOUNT_EQ_SKIP: @@ -2501,7 +2502,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) index++; break; case PHY_WRITE_PREVIOUS: - rtl_writephy(tp, regno, predata); + fw_write(tp, regno, predata); index++; break; case PHY_SKIPN: @@ -2516,9 +2517,6 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) BUG(); } } - - ops->write = org.write; - ops->read = org.read; } static void rtl_release_firmware(struct rtl8169_private *tp) @@ -2532,9 +2530,9 @@ static void rtl_release_firmware(struct rtl8169_private *tp) static void rtl_apply_firmware(struct rtl8169_private *tp) { - /* TODO: release firmware once rtl_phy_write_fw signals failures. */ + /* TODO: release firmware if rtl_fw_write_firmware signals failure. */ if (tp->rtl_fw) - rtl_phy_write_fw(tp, tp->rtl_fw); + rtl_fw_write_firmware(tp, tp->rtl_fw); } static void rtl_apply_firmware_cond(struct rtl8169_private *tp, u8 reg, u16 val) @@ -4364,6 +4362,11 @@ static void rtl_request_firmware(struct rtl8169_private *tp) if (!rtl_fw) goto err_warn; + rtl_fw->phy_write = rtl_writephy; + rtl_fw->phy_read = rtl_readphy; + rtl_fw->mac_mcu_write = mac_mcu_write; + rtl_fw->mac_mcu_read = mac_mcu_read; + rc = request_firmware(&rtl_fw->fw, tp->fw_name, tp_to_dev(tp)); if (rc < 0) goto err_free; |