kernel: bgmac: move bgmac patches already applied in mainline kernel to generic
[openwrt/openwrt.git] / target / linux / brcm47xx / patches-3.10 / 770-bgmac-phylib.patch
1 --- a/drivers/net/ethernet/broadcom/bgmac.c
2 +++ b/drivers/net/ethernet/broadcom/bgmac.c
3 @@ -1229,27 +1229,14 @@ static int bgmac_set_mac_address(struct
4 static int bgmac_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd)
5 {
6 struct bgmac *bgmac = netdev_priv(net_dev);
7 - struct mii_ioctl_data *data = if_mii(ifr);
8
9 - switch (cmd) {
10 - case SIOCGMIIPHY:
11 - data->phy_id = bgmac->phyaddr;
12 - /* fallthru */
13 - case SIOCGMIIREG:
14 - if (!netif_running(net_dev))
15 - return -EAGAIN;
16 - data->val_out = bgmac_phy_read(bgmac, data->phy_id,
17 - data->reg_num & 0x1f);
18 - return 0;
19 - case SIOCSMIIREG:
20 - if (!netif_running(net_dev))
21 - return -EAGAIN;
22 - bgmac_phy_write(bgmac, data->phy_id, data->reg_num & 0x1f,
23 - data->val_in);
24 - return 0;
25 - default:
26 - return -EOPNOTSUPP;
27 - }
28 + if (!netif_running(net_dev))
29 + return -EINVAL;
30 +
31 + if (!bgmac->phydev)
32 + return -EINVAL;
33 +
34 + return phy_mii_ioctl(bgmac->phydev, ifr, cmd);
35 }
36
37 static const struct net_device_ops bgmac_netdev_ops = {
38 @@ -1271,61 +1258,16 @@ static int bgmac_get_settings(struct net
39 {
40 struct bgmac *bgmac = netdev_priv(net_dev);
41
42 - cmd->supported = SUPPORTED_10baseT_Half |
43 - SUPPORTED_10baseT_Full |
44 - SUPPORTED_100baseT_Half |
45 - SUPPORTED_100baseT_Full |
46 - SUPPORTED_1000baseT_Half |
47 - SUPPORTED_1000baseT_Full |
48 - SUPPORTED_Autoneg;
49 -
50 - if (bgmac->autoneg) {
51 - WARN_ON(cmd->advertising);
52 - if (bgmac->full_duplex) {
53 - if (bgmac->speed & BGMAC_SPEED_10)
54 - cmd->advertising |= ADVERTISED_10baseT_Full;
55 - if (bgmac->speed & BGMAC_SPEED_100)
56 - cmd->advertising |= ADVERTISED_100baseT_Full;
57 - if (bgmac->speed & BGMAC_SPEED_1000)
58 - cmd->advertising |= ADVERTISED_1000baseT_Full;
59 - } else {
60 - if (bgmac->speed & BGMAC_SPEED_10)
61 - cmd->advertising |= ADVERTISED_10baseT_Half;
62 - if (bgmac->speed & BGMAC_SPEED_100)
63 - cmd->advertising |= ADVERTISED_100baseT_Half;
64 - if (bgmac->speed & BGMAC_SPEED_1000)
65 - cmd->advertising |= ADVERTISED_1000baseT_Half;
66 - }
67 - } else {
68 - switch (bgmac->speed) {
69 - case BGMAC_SPEED_10:
70 - ethtool_cmd_speed_set(cmd, SPEED_10);
71 - break;
72 - case BGMAC_SPEED_100:
73 - ethtool_cmd_speed_set(cmd, SPEED_100);
74 - break;
75 - case BGMAC_SPEED_1000:
76 - ethtool_cmd_speed_set(cmd, SPEED_1000);
77 - break;
78 - }
79 - }
80 -
81 - cmd->duplex = bgmac->full_duplex ? DUPLEX_FULL : DUPLEX_HALF;
82 -
83 - cmd->autoneg = bgmac->autoneg;
84 -
85 - return 0;
86 + return phy_ethtool_gset(bgmac->phydev, cmd);
87 }
88
89 -#if 0
90 static int bgmac_set_settings(struct net_device *net_dev,
91 struct ethtool_cmd *cmd)
92 {
93 struct bgmac *bgmac = netdev_priv(net_dev);
94
95 - return -1;
96 + return phy_ethtool_sset(bgmac->phydev, cmd);
97 }
98 -#endif
99
100 static void bgmac_get_drvinfo(struct net_device *net_dev,
101 struct ethtool_drvinfo *info)
102 @@ -1336,6 +1278,7 @@ static void bgmac_get_drvinfo(struct net
103
104 static const struct ethtool_ops bgmac_ethtool_ops = {
105 .get_settings = bgmac_get_settings,
106 + .set_settings = bgmac_set_settings,
107 .get_drvinfo = bgmac_get_drvinfo,
108 };
109
110 @@ -1354,10 +1297,36 @@ static int bgmac_mii_write(struct mii_bu
111 return bgmac_phy_write(bus->priv, mii_id, regnum, value);
112 }
113
114 +static void bgmac_adjust_link(struct net_device *dev)
115 +{
116 + struct bgmac *bgmac = netdev_priv(dev);
117 + struct phy_device *phydev = bgmac->phydev;
118 + bool status_changed = 0;
119 +
120 + BUG_ON(!phydev);
121 +
122 + if (bgmac->old_link != phydev->link) {
123 + status_changed = 1;
124 + bgmac->old_link = phydev->link;
125 + }
126 +
127 + /* reflect duplex change */
128 + if (phydev->link && (bgmac->old_duplex != phydev->duplex)) {
129 + status_changed = 1;
130 + bgmac->old_duplex = phydev->duplex;
131 + }
132 +
133 + if (status_changed)
134 + phy_print_status(phydev);
135 +}
136 +
137 static int bgmac_mii_register(struct bgmac *bgmac)
138 {
139 struct mii_bus *mii_bus;
140 int i, err = 0;
141 + struct phy_device *phydev = NULL;
142 + char phy_id[MII_BUS_ID_SIZE + 3];
143 + struct net_device *net_dev = bgmac->net_dev;
144
145 mii_bus = mdiobus_alloc();
146 if (!mii_bus)
147 @@ -1388,7 +1357,28 @@ static int bgmac_mii_register(struct bgm
148
149 bgmac->mii_bus = mii_bus;
150
151 - return err;
152 + /* connect to PHY */
153 + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT,
154 + mii_bus->id, bgmac->phyaddr);
155 +
156 + phydev = phy_connect(net_dev, phy_id, &bgmac_adjust_link,
157 + PHY_INTERFACE_MODE_MII);
158 +
159 + if (IS_ERR(phydev)) {
160 + netdev_err(net_dev, "could not attach PHY: %s\n", phy_id);
161 + bgmac->phyaddr = BGMAC_PHY_NOREGS;
162 + return PTR_ERR(phydev);
163 + }
164 +
165 + bgmac->phydev = phydev;
166 + bgmac->old_link = 0;
167 + bgmac->old_duplex = -1;
168 + bgmac->phyaddr = phydev->addr;
169 +
170 + netdev_info(net_dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s)\n",
171 + phydev->drv->name, dev_name(&phydev->dev));
172 +
173 + return 0;
174
175 err_free_irq:
176 kfree(mii_bus->irq);
177 --- a/drivers/net/ethernet/broadcom/bgmac.h
178 +++ b/drivers/net/ethernet/broadcom/bgmac.h
179 @@ -401,7 +401,10 @@ struct bgmac {
180 struct bcma_device *cmn; /* Reference to CMN core for BCM4706 */
181 struct net_device *net_dev;
182 struct napi_struct napi;
183 + struct phy_device *phydev;
184 struct mii_bus *mii_bus;
185 + int old_link;
186 + int old_duplex;
187
188 /* DMA */
189 struct bgmac_dma_ring tx_ring[BGMAC_MAX_TX_RINGS];