aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/r8169.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/r8169.c')
-rw-r--r--drivers/net/r8169.c122
1 files changed, 110 insertions, 12 deletions
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index dd758cdb55c4..bb8645ab247c 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1632,36 +1632,134 @@ rtl_phy_write_fw(struct rtl8169_private *tp, const struct firmware *fw)
1632{ 1632{
1633 __le32 *phytable = (__le32 *)fw->data; 1633 __le32 *phytable = (__le32 *)fw->data;
1634 struct net_device *dev = tp->dev; 1634 struct net_device *dev = tp->dev;
1635 size_t i; 1635 size_t index, fw_size = fw->size / sizeof(*phytable);
1636 u32 predata, count;
1636 1637
1637 if (fw->size % sizeof(*phytable)) { 1638 if (fw->size % sizeof(*phytable)) {
1638 netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size); 1639 netif_err(tp, probe, dev, "odd sized firmware %zd\n", fw->size);
1639 return; 1640 return;
1640 } 1641 }
1641 1642
1642 for (i = 0; i < fw->size / sizeof(*phytable); i++) { 1643 for (index = 0; index < fw_size; index++) {
1643 u32 action = le32_to_cpu(phytable[i]); 1644 u32 action = le32_to_cpu(phytable[index]);
1645 u32 regno = (action & 0x0fff0000) >> 16;
1644 1646
1645 if (!action) 1647 switch(action & 0xf0000000) {
1648 case PHY_READ:
1649 case PHY_DATA_OR:
1650 case PHY_DATA_AND:
1651 case PHY_READ_EFUSE:
1652 case PHY_CLEAR_READCOUNT:
1653 case PHY_WRITE:
1654 case PHY_WRITE_PREVIOUS:
1655 case PHY_DELAY_MS:
1646 break; 1656 break;
1647 1657
1648 if ((action & 0xf0000000) != PHY_WRITE) { 1658 case PHY_BJMPN:
1649 netif_err(tp, probe, dev, 1659 if (regno > index) {
1650 "unknown action 0x%08x\n", action); 1660 netif_err(tp, probe, tp->dev,
1661 "Out of range of firmware\n");
1662 return;
1663 }
1664 break;
1665 case PHY_READCOUNT_EQ_SKIP:
1666 if (index + 2 >= fw_size) {
1667 netif_err(tp, probe, tp->dev,
1668 "Out of range of firmware\n");
1669 return;
1670 }
1671 break;
1672 case PHY_COMP_EQ_SKIPN:
1673 case PHY_COMP_NEQ_SKIPN:
1674 case PHY_SKIPN:
1675 if (index + 1 + regno >= fw_size) {
1676 netif_err(tp, probe, tp->dev,
1677 "Out of range of firmware\n");
1678 return;
1679 }
1680 break;
1681
1682 case PHY_READ_MAC_BYTE:
1683 case PHY_WRITE_MAC_BYTE:
1684 case PHY_WRITE_ERI_WORD:
1685 default:
1686 netif_err(tp, probe, tp->dev,
1687 "Invalid action 0x%08x\n", action);
1651 return; 1688 return;
1652 } 1689 }
1653 } 1690 }
1654 1691
1655 while (i-- != 0) { 1692 predata = 0;
1656 u32 action = le32_to_cpu(*phytable); 1693 count = 0;
1694
1695 for (index = 0; index < fw_size; ) {
1696 u32 action = le32_to_cpu(phytable[index]);
1657 u32 data = action & 0x0000ffff; 1697 u32 data = action & 0x0000ffff;
1658 u32 reg = (action & 0x0fff0000) >> 16; 1698 u32 regno = (action & 0x0fff0000) >> 16;
1699
1700 if (!action)
1701 break;
1659 1702
1660 switch(action & 0xf0000000) { 1703 switch(action & 0xf0000000) {
1704 case PHY_READ:
1705 predata = rtl_readphy(tp, regno);
1706 count++;
1707 index++;
1708 break;
1709 case PHY_DATA_OR:
1710 predata |= data;
1711 index++;
1712 break;
1713 case PHY_DATA_AND:
1714 predata &= data;
1715 index++;
1716 break;
1717 case PHY_BJMPN:
1718 index -= regno;
1719 break;
1720 case PHY_READ_EFUSE:
1721 predata = rtl8168d_efuse_read(tp->mmio_addr, regno);
1722 index++;
1723 break;
1724 case PHY_CLEAR_READCOUNT:
1725 count = 0;
1726 index++;
1727 break;
1661 case PHY_WRITE: 1728 case PHY_WRITE:
1662 rtl_writephy(tp, reg, data); 1729 rtl_writephy(tp, regno, data);
1663 phytable++; 1730 index++;
1731 break;
1732 case PHY_READCOUNT_EQ_SKIP:
1733 if (count == data)
1734 index += 2;
1735 else
1736 index += 1;
1737 break;
1738 case PHY_COMP_EQ_SKIPN:
1739 if (predata == data)
1740 index += regno;
1741 index++;
1742 break;
1743 case PHY_COMP_NEQ_SKIPN:
1744 if (predata != data)
1745 index += regno;
1746 index++;
1747 break;
1748 case PHY_WRITE_PREVIOUS:
1749 rtl_writephy(tp, regno, predata);
1750 index++;
1664 break; 1751 break;
1752 case PHY_SKIPN:
1753 index += regno + 1;
1754 break;
1755 case PHY_DELAY_MS:
1756 mdelay(data);
1757 index++;
1758 break;
1759
1760 case PHY_READ_MAC_BYTE:
1761 case PHY_WRITE_MAC_BYTE:
1762 case PHY_WRITE_ERI_WORD:
1665 default: 1763 default:
1666 BUG(); 1764 BUG();
1667 } 1765 }