Commit 1b0b807d authored by David S. Miller's avatar David S. Miller

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: default avatarDavid S. Miller <davem@davemloft.net>
parents 25e94115 ce8843ab
...@@ -626,6 +626,10 @@ struct rtl8169_stats { ...@@ -626,6 +626,10 @@ struct rtl8169_stats {
struct u64_stats_sync syncp; 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 { struct rtl8169_private {
void __iomem *mmio_addr; /* memory map physical address */ void __iomem *mmio_addr; /* memory map physical address */
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
...@@ -679,6 +683,10 @@ struct rtl8169_private { ...@@ -679,6 +683,10 @@ struct rtl8169_private {
const char *fw_name; const char *fw_name;
struct rtl_fw { 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; const struct firmware *fw;
#define RTL_VER_SIZE 32 #define RTL_VER_SIZE 32
...@@ -1009,7 +1017,7 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg) ...@@ -1009,7 +1017,7 @@ static int r8168dp_2_mdio_read(struct rtl8169_private *tp, int reg)
return value; 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); 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) ...@@ -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; const struct firmware *fw = rtl_fw->fw;
struct fw_info *fw_info = (struct fw_info *)fw->data; struct fw_info *fw_info = (struct fw_info *)fw->data;
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
char *version = rtl_fw->version;
bool rc = false;
if (fw->size < FW_OPCODE_SIZE) if (fw->size < FW_OPCODE_SIZE)
goto out; return false;
if (!fw_info->magic) { if (!fw_info->magic) {
size_t i, size, start; size_t i, size, start;
u8 checksum = 0; u8 checksum = 0;
if (fw->size < sizeof(*fw_info)) if (fw->size < sizeof(*fw_info))
goto out; return false;
for (i = 0; i < fw->size; i++) for (i = 0; i < fw->size; i++)
checksum += fw->data[i]; checksum += fw->data[i];
if (checksum != 0) if (checksum != 0)
goto out; return false;
start = le32_to_cpu(fw_info->fw_start); start = le32_to_cpu(fw_info->fw_start);
if (start > fw->size) if (start > fw->size)
goto out; return false;
size = le32_to_cpu(fw_info->fw_len); size = le32_to_cpu(fw_info->fw_len);
if (size > (fw->size - start) / FW_OPCODE_SIZE) 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->code = (__le32 *)(fw->data + start);
pa->size = size; pa->size = size;
} else { } else {
if (fw->size % FW_OPCODE_SIZE) 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->code = (__le32 *)fw->data;
pa->size = fw->size / FW_OPCODE_SIZE; pa->size = fw->size / FW_OPCODE_SIZE;
} }
version[RTL_VER_SIZE - 1] = 0;
rc = true; return true;
out:
return rc;
} }
static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev, static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev,
...@@ -2432,17 +2435,15 @@ static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2432,17 +2435,15 @@ static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
return rc; 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 rtl_fw_phy_action *pa = &rtl_fw->phy_action;
struct mdio_ops org, *ops = &tp->mdio_ops; rtl_fw_write_t fw_write = rtl_fw->phy_write;
u32 predata, count; rtl_fw_read_t fw_read = rtl_fw->phy_read;
int predata = 0, count = 0;
size_t index; size_t index;
predata = count = 0;
org.write = ops->write;
org.read = ops->read;
for (index = 0; index < pa->size; ) { for (index = 0; index < pa->size; ) {
u32 action = le32_to_cpu(pa->code[index]); u32 action = le32_to_cpu(pa->code[index]);
u32 data = action & 0x0000ffff; u32 data = action & 0x0000ffff;
...@@ -2453,7 +2454,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2453,7 +2454,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
switch(action & 0xf0000000) { switch(action & 0xf0000000) {
case PHY_READ: case PHY_READ:
predata = rtl_readphy(tp, regno); predata = fw_read(tp, regno);
count++; count++;
index++; index++;
break; break;
...@@ -2470,11 +2471,11 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2470,11 +2471,11 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
break; break;
case PHY_MDIO_CHG: case PHY_MDIO_CHG:
if (data == 0) { if (data == 0) {
ops->write = org.write; fw_write = rtl_fw->phy_write;
ops->read = org.read; fw_read = rtl_fw->phy_read;
} else if (data == 1) { } else if (data == 1) {
ops->write = mac_mcu_write; fw_write = rtl_fw->mac_mcu_write;
ops->read = mac_mcu_read; fw_read = rtl_fw->mac_mcu_read;
} }
index++; index++;
...@@ -2484,7 +2485,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2484,7 +2485,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
index++; index++;
break; break;
case PHY_WRITE: case PHY_WRITE:
rtl_writephy(tp, regno, data); fw_write(tp, regno, data);
index++; index++;
break; break;
case PHY_READCOUNT_EQ_SKIP: case PHY_READCOUNT_EQ_SKIP:
...@@ -2501,7 +2502,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2501,7 +2502,7 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
index++; index++;
break; break;
case PHY_WRITE_PREVIOUS: case PHY_WRITE_PREVIOUS:
rtl_writephy(tp, regno, predata); fw_write(tp, regno, predata);
index++; index++;
break; break;
case PHY_SKIPN: case PHY_SKIPN:
...@@ -2516,9 +2517,6 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) ...@@ -2516,9 +2517,6 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
BUG(); BUG();
} }
} }
ops->write = org.write;
ops->read = org.read;
} }
static void rtl_release_firmware(struct rtl8169_private *tp) static void rtl_release_firmware(struct rtl8169_private *tp)
...@@ -2532,9 +2530,9 @@ 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) 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) 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) 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) ...@@ -4364,6 +4362,11 @@ static void rtl_request_firmware(struct rtl8169_private *tp)
if (!rtl_fw) if (!rtl_fw)
goto err_warn; 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)); rc = request_firmware(&rtl_fw->fw, tp->fw_name, tp_to_dev(tp));
if (rc < 0) if (rc < 0)
goto err_free; goto err_free;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment