net: sxgbe: add basic framework for Samsung 10Gb ethernet driver
[deliverable/linux.git] / drivers / net / ethernet / samsung / sxgbe / sxgbe_core.c
1 /* 10G controller driver for Samsung SoCs
2 *
3 * Copyright (C) 2013 Samsung Electronics Co., Ltd.
4 * http://www.samsung.com
5 *
6 * Author: Siva Reddy Kallam <siva.kallam@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as
10 * published by the Free Software Foundation.
11 */
12
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15 #include <linux/export.h>
16 #include <linux/io.h>
17 #include <linux/netdevice.h>
18 #include <linux/phy.h>
19
20 #include "sxgbe_common.h"
21 #include "sxgbe_reg.h"
22
23 /* MAC core initialization */
24 static void sxgbe_core_init(void __iomem *ioaddr)
25 {
26 u32 regval;
27
28 /* TX configuration */
29 regval = readl(ioaddr + SXGBE_CORE_TX_CONFIG_REG);
30 /* Other configurable parameters IFP, IPG, ISR, ISM
31 * needs to be set if needed
32 */
33 regval |= SXGBE_TX_JABBER_DISABLE;
34 writel(regval, ioaddr + SXGBE_CORE_TX_CONFIG_REG);
35
36 /* RX configuration */
37 regval = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG);
38 /* Other configurable parameters CST, SPEN, USP, GPSLCE
39 * WD, LM, S2KP, HDSMS, GPSL, ELEN, ARPEN needs to be
40 * set if needed
41 */
42 regval |= SXGBE_RX_JUMBPKT_ENABLE | SXGBE_RX_ACS_ENABLE;
43 writel(regval, ioaddr + SXGBE_CORE_RX_CONFIG_REG);
44 }
45
46 /* Dump MAC registers */
47 static void sxgbe_core_dump_regs(void __iomem *ioaddr)
48 {
49 }
50
51 /* Handle extra events on specific interrupts hw dependent */
52 static int sxgbe_core_host_irq_status(void __iomem *ioaddr,
53 struct sxgbe_extra_stats *x)
54 {
55 return 0;
56 }
57
58 /* Set power management mode (e.g. magic frame) */
59 static void sxgbe_core_pmt(void __iomem *ioaddr, unsigned long mode)
60 {
61 }
62
63 /* Set/Get Unicast MAC addresses */
64 static void sxgbe_core_set_umac_addr(void __iomem *ioaddr, unsigned char *addr,
65 unsigned int reg_n)
66 {
67 u32 high_word, low_word;
68
69 high_word = (addr[5] << 8) || (addr[4]);
70 low_word = ((addr[3] << 24) || (addr[2] << 16) ||
71 (addr[1] << 8) || (addr[0]));
72 writel(high_word, ioaddr + SXGBE_CORE_ADD_HIGHOFFSET(reg_n));
73 writel(low_word, ioaddr + SXGBE_CORE_ADD_LOWOFFSET(reg_n));
74 }
75
76 static void sxgbe_core_get_umac_addr(void __iomem *ioaddr, unsigned char *addr,
77 unsigned int reg_n)
78 {
79 u32 high_word, low_word;
80
81 high_word = readl(ioaddr + SXGBE_CORE_ADD_HIGHOFFSET(reg_n));
82 low_word = readl(ioaddr + SXGBE_CORE_ADD_LOWOFFSET(reg_n));
83
84 /* extract and assign address */
85 addr[5] = (high_word & 0x0000FF00) >> 8;
86 addr[4] = (high_word & 0x000000FF);
87 addr[3] = (low_word & 0xFF000000) >> 24;
88 addr[2] = (low_word & 0x00FF0000) >> 16;
89 addr[1] = (low_word & 0x0000FF00) >> 8;
90 addr[0] = (low_word & 0x000000FF);
91 }
92
93 static void sxgbe_enable_tx(void __iomem *ioaddr, bool enable)
94 {
95 u32 tx_config;
96
97 tx_config = readl(ioaddr + SXGBE_CORE_TX_CONFIG_REG);
98 tx_config &= ~SXGBE_TX_ENABLE;
99
100 if (enable)
101 tx_config |= SXGBE_TX_ENABLE;
102 writel(tx_config, ioaddr + SXGBE_CORE_TX_CONFIG_REG);
103 }
104
105 static void sxgbe_enable_rx(void __iomem *ioaddr, bool enable)
106 {
107 u32 rx_config;
108
109 rx_config = readl(ioaddr + SXGBE_CORE_RX_CONFIG_REG);
110 rx_config &= ~SXGBE_RX_ENABLE;
111
112 if (enable)
113 rx_config |= SXGBE_RX_ENABLE;
114 writel(rx_config, ioaddr + SXGBE_CORE_RX_CONFIG_REG);
115 }
116
117 static int sxgbe_get_controller_version(void __iomem *ioaddr)
118 {
119 return readl(ioaddr + SXGBE_CORE_VERSION_REG);
120 }
121
122 /* If supported then get the optional core features */
123 static unsigned int sxgbe_get_hw_feature(void __iomem *ioaddr,
124 unsigned char feature_index)
125 {
126 return readl(ioaddr + (SXGBE_CORE_HW_FEA_REG(feature_index)));
127 }
128
129 static void sxgbe_core_set_speed(void __iomem *ioaddr, unsigned char speed)
130 {
131 u32 tx_cfg = readl(ioaddr + SXGBE_CORE_TX_CONFIG_REG);
132
133 /* clear the speed bits */
134 tx_cfg &= ~0x60000000;
135 tx_cfg |= (speed << SXGBE_SPEED_LSHIFT);
136
137 /* set the speed */
138 writel(tx_cfg, ioaddr + SXGBE_CORE_TX_CONFIG_REG);
139 }
140
141 const struct sxgbe_core_ops core_ops = {
142 .core_init = sxgbe_core_init,
143 .dump_regs = sxgbe_core_dump_regs,
144 .host_irq_status = sxgbe_core_host_irq_status,
145 .pmt = sxgbe_core_pmt,
146 .set_umac_addr = sxgbe_core_set_umac_addr,
147 .get_umac_addr = sxgbe_core_get_umac_addr,
148 .enable_rx = sxgbe_enable_rx,
149 .enable_tx = sxgbe_enable_tx,
150 .get_controller_version = sxgbe_get_controller_version,
151 .get_hw_feature = sxgbe_get_hw_feature,
152 .set_speed = sxgbe_core_set_speed,
153 };
154
155 const struct sxgbe_core_ops *sxgbe_get_core_ops(void)
156 {
157 return &core_ops;
158 }
This page took 0.035034 seconds and 5 git commands to generate.