Skip to content

Commit

Permalink
r8169: check firmware content sooner.
Browse files Browse the repository at this point in the history
Firmware checking is only performed when the firmware is loaded
instead of each time the driver inits the phy.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
  • Loading branch information
Francois Romieu committed Jun 18, 2011
1 parent 960aee6 commit fd112f2
Showing 1 changed file with 44 additions and 19 deletions.
63 changes: 44 additions & 19 deletions drivers/net/r8169.c
Original file line number Diff line number Diff line change
Expand Up @@ -1815,18 +1815,12 @@ static bool rtl_fw_format_ok(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
return rc;
}

static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
static bool rtl_fw_data_ok(struct rtl8169_private *tp, struct net_device *dev,
struct rtl_fw_phy_action *pa)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
struct net_device *dev = tp->dev;
u32 predata, count;
bool rc = false;
size_t index;

if (!rtl_fw_format_ok(tp, rtl_fw)) {
netif_err(tp, probe, dev, "invalid firwmare\n");
return;
}

for (index = 0; index < pa->size; index++) {
u32 action = le32_to_cpu(pa->code[index]);
u32 regno = (action & 0x0fff0000) >> 16;
Expand All @@ -1844,40 +1838,65 @@ static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)

case PHY_BJMPN:
if (regno > index) {
netif_err(tp, probe, tp->dev,
netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
return;
goto out;
}
break;
case PHY_READCOUNT_EQ_SKIP:
if (index + 2 >= pa->size) {
netif_err(tp, probe, tp->dev,
netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
return;
goto out;
}
break;
case PHY_COMP_EQ_SKIPN:
case PHY_COMP_NEQ_SKIPN:
case PHY_SKIPN:
if (index + 1 + regno >= pa->size) {
netif_err(tp, probe, tp->dev,
netif_err(tp, ifup, tp->dev,
"Out of range of firmware\n");
return;
goto out;
}
break;

case PHY_READ_MAC_BYTE:
case PHY_WRITE_MAC_BYTE:
case PHY_WRITE_ERI_WORD:
default:
netif_err(tp, probe, tp->dev,
netif_err(tp, ifup, tp->dev,
"Invalid action 0x%08x\n", action);
return;
goto out;
}
}
rc = true;
out:
return rc;
}

predata = 0;
count = 0;
static int rtl_check_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct net_device *dev = tp->dev;
int rc = -EINVAL;

if (!rtl_fw_format_ok(tp, rtl_fw)) {
netif_err(tp, ifup, dev, "invalid firwmare\n");
goto out;
}

if (rtl_fw_data_ok(tp, dev, &rtl_fw->phy_action))
rc = 0;
out:
return rc;
}

static void rtl_phy_write_fw(struct rtl8169_private *tp, struct rtl_fw *rtl_fw)
{
struct rtl_fw_phy_action *pa = &rtl_fw->phy_action;
u32 predata, count;
size_t index;

predata = count = 0;

for (index = 0; index < pa->size; ) {
u32 action = le32_to_cpu(pa->code[index]);
Expand Down Expand Up @@ -3605,10 +3624,16 @@ static void rtl_request_uncached_firmware(struct rtl8169_private *tp)
if (rc < 0)
goto err_free;

rc = rtl_check_firmware(tp, rtl_fw);
if (rc < 0)
goto err_release_firmware;

tp->rtl_fw = rtl_fw;
out:
return;

err_release_firmware:
release_firmware(rtl_fw->fw);
err_free:
kfree(rtl_fw);
err_warn:
Expand Down

0 comments on commit fd112f2

Please sign in to comment.