drivers: net: stmmac: rework core ISR to better manage PCS and PMT
[deliverable/linux.git] / drivers / net / ethernet / stmicro / stmmac / dwmac1000_core.c
CommitLineData
21d437cc
GC
1/*******************************************************************************
2 This is the driver for the GMAC on-chip Ethernet controller for ST SoCs.
3 DWC Ether MAC 10/100/1000 Universal version 3.41a has been used for
4 developing this code.
5
6 This only implements the mac core functions for this chip.
7
8 Copyright (C) 2007-2009 STMicroelectronics Ltd
9
10 This program is free software; you can redistribute it and/or modify it
11 under the terms and conditions of the GNU General Public License,
12 version 2, as published by the Free Software Foundation.
13
14 This program is distributed in the hope it will be useful, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 more details.
18
19 You should have received a copy of the GNU General Public License along with
20 this program; if not, write to the Free Software Foundation, Inc.,
21 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
22
23 The full GNU General Public License is included in this distribution in
24 the file called "COPYING".
25
26 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
27*******************************************************************************/
28
29#include <linux/crc32.h>
5a0e3ad6 30#include <linux/slab.h>
e58bb43f 31#include <linux/ethtool.h>
b7f080cf 32#include <asm/io.h>
70523e63 33#include "stmmac_pcs.h"
21d437cc
GC
34#include "dwmac1000.h"
35
7ed24bbe 36static void dwmac1000_core_init(struct mac_device_info *hw, int mtu)
21d437cc 37{
7ed24bbe 38 void __iomem *ioaddr = hw->pcsr;
21d437cc 39 u32 value = readl(ioaddr + GMAC_CONTROL);
3fe5cadb
GC
40
41 /* Configure GMAC core */
21d437cc 42 value |= GMAC_CORE_INIT;
3fe5cadb 43
2618abb7
VB
44 if (mtu > 1500)
45 value |= GMAC_CONTROL_2K;
46 if (mtu > 2000)
47 value |= GMAC_CONTROL_JE;
48
21d437cc
GC
49 writel(value, ioaddr + GMAC_CONTROL);
50
21d437cc 51 /* Mask GMAC interrupts */
3fe5cadb
GC
52 value = GMAC_INT_DEFAULT_MASK;
53
54 if (hw->pmt)
55 value &= ~GMAC_INT_DISABLE_PMT;
56 if (hw->pcs)
57 value &= ~GMAC_INT_DISABLE_PCS;
58
59 writel(value, ioaddr + GMAC_INT_MASK);
21d437cc
GC
60
61#ifdef STMMAC_VLAN_TAG_USED
62 /* Tag detection without filtering */
63 writel(0x0, ioaddr + GMAC_VLAN_TAG);
64#endif
21d437cc
GC
65}
66
7ed24bbe 67static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw)
ebbb293f 68{
7ed24bbe 69 void __iomem *ioaddr = hw->pcsr;
ebbb293f
GC
70 u32 value = readl(ioaddr + GMAC_CONTROL);
71
d2afb5bd
GC
72 if (hw->rx_csum)
73 value |= GMAC_CONTROL_IPC;
74 else
75 value &= ~GMAC_CONTROL_IPC;
76
ebbb293f
GC
77 writel(value, ioaddr + GMAC_CONTROL);
78
79 value = readl(ioaddr + GMAC_CONTROL);
80
81 return !!(value & GMAC_CONTROL_IPC);
82}
83
7ed24bbe 84static void dwmac1000_dump_regs(struct mac_device_info *hw)
21d437cc 85{
7ed24bbe 86 void __iomem *ioaddr = hw->pcsr;
21d437cc 87 int i;
1f0f6388 88 pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr);
21d437cc
GC
89
90 for (i = 0; i < 55; i++) {
91 int offset = i * 4;
92 pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i,
93 offset, readl(ioaddr + offset));
94 }
21d437cc
GC
95}
96
7ed24bbe
VB
97static void dwmac1000_set_umac_addr(struct mac_device_info *hw,
98 unsigned char *addr,
ceb69499 99 unsigned int reg_n)
21d437cc 100{
7ed24bbe 101 void __iomem *ioaddr = hw->pcsr;
21d437cc 102 stmmac_set_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
ceb69499 103 GMAC_ADDR_LOW(reg_n));
21d437cc
GC
104}
105
7ed24bbe
VB
106static void dwmac1000_get_umac_addr(struct mac_device_info *hw,
107 unsigned char *addr,
ceb69499 108 unsigned int reg_n)
21d437cc 109{
7ed24bbe 110 void __iomem *ioaddr = hw->pcsr;
21d437cc 111 stmmac_get_mac_addr(ioaddr, addr, GMAC_ADDR_HIGH(reg_n),
ceb69499 112 GMAC_ADDR_LOW(reg_n));
21d437cc
GC
113}
114
3b57de95
VB
115static void dwmac1000_set_mchash(void __iomem *ioaddr, u32 *mcfilterbits,
116 int mcbitslog2)
117{
118 int numhashregs, regs;
119
120 switch (mcbitslog2) {
121 case 6:
122 writel(mcfilterbits[0], ioaddr + GMAC_HASH_LOW);
123 writel(mcfilterbits[1], ioaddr + GMAC_HASH_HIGH);
124 return;
125 break;
126 case 7:
127 numhashregs = 4;
128 break;
129 case 8:
130 numhashregs = 8;
131 break;
132 default:
133 pr_debug("STMMAC: err in setting mulitcast filter\n");
134 return;
135 break;
136 }
137 for (regs = 0; regs < numhashregs; regs++)
138 writel(mcfilterbits[regs],
139 ioaddr + GMAC_EXTHASH_BASE + regs * 4);
140}
141
142static void dwmac1000_set_filter(struct mac_device_info *hw,
143 struct net_device *dev)
21d437cc 144{
ceb69499 145 void __iomem *ioaddr = (void __iomem *)dev->base_addr;
21d437cc 146 unsigned int value = 0;
3b57de95 147 unsigned int perfect_addr_number = hw->unicast_filter_entries;
3dab99e0 148 u32 mc_filter[8];
3b57de95 149 int mcbitslog2 = hw->mcast_bits_log2;
21d437cc 150
83d7af64
GC
151 pr_debug("%s: # mcasts %d, # unicast %d\n", __func__,
152 netdev_mc_count(dev), netdev_uc_count(dev));
21d437cc 153
aefef4c1
VB
154 memset(mc_filter, 0, sizeof(mc_filter));
155
156 if (dev->flags & IFF_PROMISC) {
21d437cc 157 value = GMAC_FRAME_FILTER_PR;
aefef4c1 158 } else if (dev->flags & IFF_ALLMULTI) {
21d437cc 159 value = GMAC_FRAME_FILTER_PM; /* pass all multi */
4cd24eaf 160 } else if (!netdev_mc_empty(dev)) {
22bedad3 161 struct netdev_hw_addr *ha;
21d437cc
GC
162
163 /* Hash filter for multicast */
164 value = GMAC_FRAME_FILTER_HMC;
165
22bedad3 166 netdev_for_each_mc_addr(ha, dev) {
3b57de95
VB
167 /* The upper n bits of the calculated CRC are used to
168 * index the contents of the hash table. The number of
169 * bits used depends on the hardware configuration
170 * selected at core configuration time.
ceb69499 171 */
3b57de95
VB
172 int bit_nr = bitrev32(~crc32_le(~0, ha->addr,
173 ETH_ALEN)) >>
174 (32 - mcbitslog2);
21d437cc
GC
175 /* The most significant bit determines the register to
176 * use (H/L) while the other 5 bits determine the bit
ceb69499
GC
177 * within the register.
178 */
21d437cc
GC
179 mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
180 }
21d437cc
GC
181 }
182
3b57de95 183 dwmac1000_set_mchash(ioaddr, mc_filter, mcbitslog2);
cffb13f4 184
ceb69499 185 /* Handle multiple unicast addresses (perfect filtering) */
cffb13f4 186 if (netdev_uc_count(dev) > perfect_addr_number)
3b57de95
VB
187 /* Switch to promiscuous mode if more than unicast
188 * addresses are requested than supported by hardware.
ceb69499 189 */
21d437cc
GC
190 value |= GMAC_FRAME_FILTER_PR;
191 else {
192 int reg = 1;
193 struct netdev_hw_addr *ha;
194
32e7bfc4 195 netdev_for_each_uc_addr(ha, dev) {
3dab99e0 196 stmmac_set_mac_addr(ioaddr, ha->addr,
7ed24bbe
VB
197 GMAC_ADDR_HIGH(reg),
198 GMAC_ADDR_LOW(reg));
32e7bfc4 199 reg++;
21d437cc
GC
200 }
201 }
202
203#ifdef FRAME_FILTER_DEBUG
204 /* Enable Receive all mode (to debug filtering_fail errors) */
205 value |= GMAC_FRAME_FILTER_RA;
206#endif
207 writel(value, ioaddr + GMAC_FRAME_FILTER);
21d437cc
GC
208}
209
7ed24bbe
VB
210
211static void dwmac1000_flow_ctrl(struct mac_device_info *hw, unsigned int duplex,
ceb69499 212 unsigned int fc, unsigned int pause_time)
21d437cc 213{
7ed24bbe 214 void __iomem *ioaddr = hw->pcsr;
545d655e
VB
215 /* Set flow such that DZPQ in Mac Register 6 is 0,
216 * and unicast pause detect is enabled.
217 */
218 unsigned int flow = GMAC_FLOW_CTRL_UP;
21d437cc 219
83d7af64 220 pr_debug("GMAC Flow-Control:\n");
21d437cc 221 if (fc & FLOW_RX) {
83d7af64 222 pr_debug("\tReceive Flow-Control ON\n");
21d437cc
GC
223 flow |= GMAC_FLOW_CTRL_RFE;
224 }
225 if (fc & FLOW_TX) {
83d7af64 226 pr_debug("\tTransmit Flow-Control ON\n");
21d437cc
GC
227 flow |= GMAC_FLOW_CTRL_TFE;
228 }
229
230 if (duplex) {
83d7af64 231 pr_debug("\tduplex mode: PAUSE %d\n", pause_time);
21d437cc
GC
232 flow |= (pause_time << GMAC_FLOW_CTRL_PT_SHIFT);
233 }
234
235 writel(flow, ioaddr + GMAC_FLOW_CTRL);
21d437cc
GC
236}
237
7ed24bbe 238static void dwmac1000_pmt(struct mac_device_info *hw, unsigned long mode)
21d437cc 239{
7ed24bbe 240 void __iomem *ioaddr = hw->pcsr;
21d437cc
GC
241 unsigned int pmt = 0;
242
74ae2fd7 243 if (mode & WAKE_MAGIC) {
83d7af64 244 pr_debug("GMAC: WOL Magic frame\n");
21d437cc 245 pmt |= power_down | magic_pkt_en;
74ae2fd7
GC
246 }
247 if (mode & WAKE_UCAST) {
83d7af64 248 pr_debug("GMAC: WOL on global unicast\n");
21d437cc
GC
249 pmt |= global_unicast;
250 }
251
252 writel(pmt, ioaddr + GMAC_PMT);
21d437cc
GC
253}
254
70523e63
GC
255/* RGMII or SMII interface */
256static void dwmac1000_rgsmii(void __iomem *ioaddr, struct stmmac_extra_stats *x)
257{
258 u32 status;
259
260 status = readl(ioaddr + GMAC_RGSMIIIS);
261 x->irq_rgmii_n++;
262
263 /* Check the link status */
264 if (status & GMAC_RGSMIIIS_LNKSTS) {
265 int speed_value;
266
267 x->pcs_link = 1;
268
269 speed_value = ((status & GMAC_RGSMIIIS_SPEED) >>
270 GMAC_RGSMIIIS_SPEED_SHIFT);
271 if (speed_value == GMAC_RGSMIIIS_SPEED_125)
272 x->pcs_speed = SPEED_1000;
273 else if (speed_value == GMAC_RGSMIIIS_SPEED_25)
274 x->pcs_speed = SPEED_100;
275 else
276 x->pcs_speed = SPEED_10;
277
278 x->pcs_duplex = (status & GMAC_RGSMIIIS_LNKMOD_MASK);
279
280 pr_info("Link is Up - %d/%s\n", (int)x->pcs_speed,
281 x->pcs_duplex ? "Full" : "Half");
282 } else {
283 x->pcs_link = 0;
284 pr_info("Link is Down\n");
285 }
286}
287
7ed24bbe 288static int dwmac1000_irq_status(struct mac_device_info *hw,
0982a0f6 289 struct stmmac_extra_stats *x)
21d437cc 290{
7ed24bbe 291 void __iomem *ioaddr = hw->pcsr;
21d437cc 292 u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
0982a0f6 293 int ret = 0;
21d437cc
GC
294
295 /* Not used events (e.g. MMC interrupts) are not handled. */
3fe5cadb 296 if ((intr_status & GMAC_INT_STATUS_MMCTIS))
0982a0f6 297 x->mmc_tx_irq_n++;
3fe5cadb 298 if (unlikely(intr_status & GMAC_INT_STATUS_MMCRIS))
0982a0f6 299 x->mmc_rx_irq_n++;
3fe5cadb 300 if (unlikely(intr_status & GMAC_INT_STATUS_MMCCSUM))
0982a0f6 301 x->mmc_rx_csum_offload_irq_n++;
3fe5cadb 302 if (unlikely(intr_status & GMAC_INT_DISABLE_PMT)) {
ceb69499 303 /* clear the PMT bits 5 and 6 by reading the PMT status reg */
21d437cc 304 readl(ioaddr + GMAC_PMT);
0982a0f6 305 x->irq_receive_pmt_irq_n++;
21d437cc 306 }
70523e63 307
3fe5cadb
GC
308 /* MAC tx/rx EEE LPI entry/exit interrupts */
309 if (intr_status & GMAC_INT_STATUS_LPIIS) {
d765955d 310 /* Clean LPI interrupt by reading the Reg 12 */
0982a0f6 311 ret = readl(ioaddr + LPI_CTRL_STATUS);
d765955d 312
83d7af64 313 if (ret & LPI_CTRL_STATUS_TLPIEN)
0982a0f6 314 x->irq_tx_path_in_lpi_mode_n++;
83d7af64 315 if (ret & LPI_CTRL_STATUS_TLPIEX)
0982a0f6 316 x->irq_tx_path_exit_lpi_mode_n++;
83d7af64 317 if (ret & LPI_CTRL_STATUS_RLPIEN)
0982a0f6 318 x->irq_rx_path_in_lpi_mode_n++;
83d7af64 319 if (ret & LPI_CTRL_STATUS_RLPIEX)
0982a0f6 320 x->irq_rx_path_exit_lpi_mode_n++;
d765955d
GC
321 }
322
70523e63
GC
323 dwmac_pcs_isr(ioaddr, GMAC_PCS_BASE, intr_status, x);
324
325 if (intr_status & PCS_RGSMIIIS_IRQ)
326 dwmac1000_rgsmii(ioaddr, x);
0982a0f6
GC
327
328 return ret;
d765955d
GC
329}
330
7ed24bbe 331static void dwmac1000_set_eee_mode(struct mac_device_info *hw)
d765955d 332{
7ed24bbe 333 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
334 u32 value;
335
336 /* Enable the link status receive on RGMII, SGMII ore SMII
337 * receive path and instruct the transmit to enter in LPI
ceb69499
GC
338 * state.
339 */
d765955d
GC
340 value = readl(ioaddr + LPI_CTRL_STATUS);
341 value |= LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA;
342 writel(value, ioaddr + LPI_CTRL_STATUS);
343}
344
7ed24bbe 345static void dwmac1000_reset_eee_mode(struct mac_device_info *hw)
d765955d 346{
7ed24bbe 347 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
348 u32 value;
349
350 value = readl(ioaddr + LPI_CTRL_STATUS);
351 value &= ~(LPI_CTRL_STATUS_LPIEN | LPI_CTRL_STATUS_LPITXA);
352 writel(value, ioaddr + LPI_CTRL_STATUS);
353}
354
7ed24bbe 355static void dwmac1000_set_eee_pls(struct mac_device_info *hw, int link)
d765955d 356{
7ed24bbe 357 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
358 u32 value;
359
360 value = readl(ioaddr + LPI_CTRL_STATUS);
361
362 if (link)
363 value |= LPI_CTRL_STATUS_PLS;
364 else
365 value &= ~LPI_CTRL_STATUS_PLS;
366
367 writel(value, ioaddr + LPI_CTRL_STATUS);
368}
369
7ed24bbe 370static void dwmac1000_set_eee_timer(struct mac_device_info *hw, int ls, int tw)
d765955d 371{
7ed24bbe 372 void __iomem *ioaddr = hw->pcsr;
d765955d
GC
373 int value = ((tw & 0xffff)) | ((ls & 0x7ff) << 16);
374
375 /* Program the timers in the LPI timer control register:
376 * LS: minimum time (ms) for which the link
377 * status from PHY should be ok before transmitting
378 * the LPI pattern.
379 * TW: minimum time (us) for which the core waits
380 * after it has stopped transmitting the LPI pattern.
381 */
382 writel(value, ioaddr + LPI_TIMER_CTRL);
21d437cc
GC
383}
384
70523e63
GC
385static void dwmac1000_ctrl_ane(void __iomem *ioaddr, bool ane, bool srgmi_ral,
386 bool loopback)
e58bb43f 387{
70523e63 388 dwmac_ctrl_ane(ioaddr, GMAC_PCS_BASE, ane, srgmi_ral, loopback);
e58bb43f
GC
389}
390
70523e63 391static void dwmac1000_rane(void __iomem *ioaddr, bool restart)
e58bb43f 392{
70523e63
GC
393 dwmac_rane(ioaddr, GMAC_PCS_BASE, restart);
394}
e58bb43f 395
70523e63
GC
396static void dwmac1000_get_adv_lp(void __iomem *ioaddr, struct rgmii_adv *adv)
397{
398 dwmac_get_adv_lp(ioaddr, GMAC_PCS_BASE, adv);
e58bb43f
GC
399}
400
2f7a791c
GC
401static void dwmac1000_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
402{
403 u32 value = readl(ioaddr + GMAC_DEBUG);
404
405 if (value & GMAC_DEBUG_TXSTSFSTS)
406 x->mtl_tx_status_fifo_full++;
407 if (value & GMAC_DEBUG_TXFSTS)
408 x->mtl_tx_fifo_not_empty++;
409 if (value & GMAC_DEBUG_TWCSTS)
410 x->mmtl_fifo_ctrl++;
411 if (value & GMAC_DEBUG_TRCSTS_MASK) {
412 u32 trcsts = (value & GMAC_DEBUG_TRCSTS_MASK)
413 >> GMAC_DEBUG_TRCSTS_SHIFT;
414 if (trcsts == GMAC_DEBUG_TRCSTS_WRITE)
415 x->mtl_tx_fifo_read_ctrl_write++;
416 else if (trcsts == GMAC_DEBUG_TRCSTS_TXW)
417 x->mtl_tx_fifo_read_ctrl_wait++;
418 else if (trcsts == GMAC_DEBUG_TRCSTS_READ)
419 x->mtl_tx_fifo_read_ctrl_read++;
420 else
421 x->mtl_tx_fifo_read_ctrl_idle++;
422 }
423 if (value & GMAC_DEBUG_TXPAUSED)
424 x->mac_tx_in_pause++;
425 if (value & GMAC_DEBUG_TFCSTS_MASK) {
426 u32 tfcsts = (value & GMAC_DEBUG_TFCSTS_MASK)
427 >> GMAC_DEBUG_TFCSTS_SHIFT;
428
429 if (tfcsts == GMAC_DEBUG_TFCSTS_XFER)
430 x->mac_tx_frame_ctrl_xfer++;
431 else if (tfcsts == GMAC_DEBUG_TFCSTS_GEN_PAUSE)
432 x->mac_tx_frame_ctrl_pause++;
433 else if (tfcsts == GMAC_DEBUG_TFCSTS_WAIT)
434 x->mac_tx_frame_ctrl_wait++;
435 else
436 x->mac_tx_frame_ctrl_idle++;
437 }
438 if (value & GMAC_DEBUG_TPESTS)
439 x->mac_gmii_tx_proto_engine++;
440 if (value & GMAC_DEBUG_RXFSTS_MASK) {
441 u32 rxfsts = (value & GMAC_DEBUG_RXFSTS_MASK)
442 >> GMAC_DEBUG_RRCSTS_SHIFT;
443
444 if (rxfsts == GMAC_DEBUG_RXFSTS_FULL)
445 x->mtl_rx_fifo_fill_level_full++;
446 else if (rxfsts == GMAC_DEBUG_RXFSTS_AT)
447 x->mtl_rx_fifo_fill_above_thresh++;
448 else if (rxfsts == GMAC_DEBUG_RXFSTS_BT)
449 x->mtl_rx_fifo_fill_below_thresh++;
450 else
451 x->mtl_rx_fifo_fill_level_empty++;
452 }
453 if (value & GMAC_DEBUG_RRCSTS_MASK) {
454 u32 rrcsts = (value & GMAC_DEBUG_RRCSTS_MASK) >>
455 GMAC_DEBUG_RRCSTS_SHIFT;
456
457 if (rrcsts == GMAC_DEBUG_RRCSTS_FLUSH)
458 x->mtl_rx_fifo_read_ctrl_flush++;
459 else if (rrcsts == GMAC_DEBUG_RRCSTS_RSTAT)
460 x->mtl_rx_fifo_read_ctrl_read_data++;
461 else if (rrcsts == GMAC_DEBUG_RRCSTS_RDATA)
462 x->mtl_rx_fifo_read_ctrl_status++;
463 else
464 x->mtl_rx_fifo_read_ctrl_idle++;
465 }
466 if (value & GMAC_DEBUG_RWCSTS)
467 x->mtl_rx_fifo_ctrl_active++;
468 if (value & GMAC_DEBUG_RFCFCSTS_MASK)
469 x->mac_rx_frame_ctrl_fifo = (value & GMAC_DEBUG_RFCFCSTS_MASK)
470 >> GMAC_DEBUG_RFCFCSTS_SHIFT;
471 if (value & GMAC_DEBUG_RPESTS)
472 x->mac_gmii_rx_proto_engine++;
473}
474
cadb7924 475static const struct stmmac_ops dwmac1000_ops = {
21d437cc 476 .core_init = dwmac1000_core_init,
38912bdb 477 .rx_ipc = dwmac1000_rx_ipc_enable,
21d437cc
GC
478 .dump_regs = dwmac1000_dump_regs,
479 .host_irq_status = dwmac1000_irq_status,
480 .set_filter = dwmac1000_set_filter,
481 .flow_ctrl = dwmac1000_flow_ctrl,
482 .pmt = dwmac1000_pmt,
483 .set_umac_addr = dwmac1000_set_umac_addr,
484 .get_umac_addr = dwmac1000_get_umac_addr,
ceb69499
GC
485 .set_eee_mode = dwmac1000_set_eee_mode,
486 .reset_eee_mode = dwmac1000_reset_eee_mode,
487 .set_eee_timer = dwmac1000_set_eee_timer,
488 .set_eee_pls = dwmac1000_set_eee_pls,
2f7a791c 489 .debug = dwmac1000_debug,
70523e63
GC
490 .pcs_ctrl_ane = dwmac1000_ctrl_ane,
491 .pcs_rane = dwmac1000_rane,
492 .pcs_get_adv_lp = dwmac1000_get_adv_lp,
21d437cc
GC
493};
494
3b57de95 495struct mac_device_info *dwmac1000_setup(void __iomem *ioaddr, int mcbins,
c623d149
AT
496 int perfect_uc_entries,
497 int *synopsys_id)
21d437cc
GC
498{
499 struct mac_device_info *mac;
f0b9d786 500 u32 hwid = readl(ioaddr + GMAC_VERSION);
21d437cc
GC
501
502 mac = kzalloc(sizeof(const struct mac_device_info), GFP_KERNEL);
1ff21906
DC
503 if (!mac)
504 return NULL;
21d437cc 505
7ed24bbe 506 mac->pcsr = ioaddr;
3b57de95
VB
507 mac->multicast_filter_bins = mcbins;
508 mac->unicast_filter_entries = perfect_uc_entries;
509 mac->mcast_bits_log2 = 0;
510
511 if (mac->multicast_filter_bins)
512 mac->mcast_bits_log2 = ilog2(mac->multicast_filter_bins);
513
21d437cc 514 mac->mac = &dwmac1000_ops;
21d437cc
GC
515 mac->dma = &dwmac1000_dma_ops;
516
21d437cc
GC
517 mac->link.port = GMAC_CONTROL_PS;
518 mac->link.duplex = GMAC_CONTROL_DM;
519 mac->link.speed = GMAC_CONTROL_FES;
520 mac->mii.addr = GMAC_MII_ADDR;
521 mac->mii.data = GMAC_MII_DATA;
c623d149
AT
522
523 /* Get and dump the chip ID */
524 *synopsys_id = stmmac_get_synopsys_id(hwid);
21d437cc
GC
525
526 return mac;
527}
This page took 0.799252 seconds and 5 git commands to generate.