diff options
author | Taku Izumi <izumi.taku@jp.fujitsu.com> | 2015-08-21 04:29:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-08-24 17:06:34 -0400 |
commit | 2fcbca687702163ae3a37ec4eac5905d6f119296 (patch) | |
tree | dff775d4786b9f8fe33787471ff62173d0012d2b | |
parent | a18aaec21ec8f4d2a4e09ad590437777a1ebf691 (diff) |
fjes: platform_driver's .probe and .remove routine
This patch implements platform_driver's .probe and .remove
routine, and also adds board specific private data structure.
This driver registers net_device at platform_driver's .probe
routine and unregisters net_device at its .remove routine.
Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/fjes/fjes.h | 25 | ||||
-rw-r--r-- | drivers/net/fjes/fjes_main.c | 94 |
2 files changed, 119 insertions, 0 deletions
diff --git a/drivers/net/fjes/fjes.h b/drivers/net/fjes/fjes.h index 15ded9642101..54bc189a997c 100644 --- a/drivers/net/fjes/fjes.h +++ b/drivers/net/fjes/fjes.h | |||
@@ -24,7 +24,32 @@ | |||
24 | 24 | ||
25 | #include <linux/acpi.h> | 25 | #include <linux/acpi.h> |
26 | 26 | ||
27 | #include "fjes_hw.h" | ||
28 | |||
27 | #define FJES_ACPI_SYMBOL "Extended Socket" | 29 | #define FJES_ACPI_SYMBOL "Extended Socket" |
30 | #define FJES_MAX_QUEUES 1 | ||
31 | #define FJES_TX_RETRY_INTERVAL (20 * HZ) | ||
32 | |||
33 | /* board specific private data structure */ | ||
34 | struct fjes_adapter { | ||
35 | struct net_device *netdev; | ||
36 | struct platform_device *plat_dev; | ||
37 | |||
38 | struct napi_struct napi; | ||
39 | struct rtnl_link_stats64 stats64; | ||
40 | |||
41 | unsigned int tx_retry_count; | ||
42 | unsigned long tx_start_jiffies; | ||
43 | unsigned long rx_last_jiffies; | ||
44 | bool unset_rx_last; | ||
45 | |||
46 | bool force_reset; | ||
47 | bool open_guard; | ||
48 | |||
49 | bool irq_registered; | ||
50 | |||
51 | struct fjes_hw hw; | ||
52 | }; | ||
28 | 53 | ||
29 | extern char fjes_driver_name[]; | 54 | extern char fjes_driver_name[]; |
30 | extern char fjes_driver_version[]; | 55 | extern char fjes_driver_version[]; |
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c index 95176667131e..45a8b9c52ae5 100644 --- a/drivers/net/fjes/fjes_main.c +++ b/drivers/net/fjes/fjes_main.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/types.h> | 23 | #include <linux/types.h> |
24 | #include <linux/nls.h> | 24 | #include <linux/nls.h> |
25 | #include <linux/platform_device.h> | 25 | #include <linux/platform_device.h> |
26 | #include <linux/netdevice.h> | ||
26 | 27 | ||
27 | #include "fjes.h" | 28 | #include "fjes.h" |
28 | 29 | ||
@@ -49,6 +50,9 @@ static acpi_status fjes_get_acpi_resource(struct acpi_resource *, void*); | |||
49 | static int fjes_probe(struct platform_device *); | 50 | static int fjes_probe(struct platform_device *); |
50 | static int fjes_remove(struct platform_device *); | 51 | static int fjes_remove(struct platform_device *); |
51 | 52 | ||
53 | static int fjes_sw_init(struct fjes_adapter *); | ||
54 | static void fjes_netdev_setup(struct net_device *); | ||
55 | |||
52 | static const struct acpi_device_id fjes_acpi_ids[] = { | 56 | static const struct acpi_device_id fjes_acpi_ids[] = { |
53 | {"PNP0C02", 0}, | 57 | {"PNP0C02", 0}, |
54 | {"", 0}, | 58 | {"", 0}, |
@@ -166,18 +170,108 @@ fjes_get_acpi_resource(struct acpi_resource *acpi_res, void *data) | |||
166 | return AE_OK; | 170 | return AE_OK; |
167 | } | 171 | } |
168 | 172 | ||
173 | static const struct net_device_ops fjes_netdev_ops = { | ||
174 | }; | ||
175 | |||
169 | /* fjes_probe - Device Initialization Routine */ | 176 | /* fjes_probe - Device Initialization Routine */ |
170 | static int fjes_probe(struct platform_device *plat_dev) | 177 | static int fjes_probe(struct platform_device *plat_dev) |
171 | { | 178 | { |
179 | struct fjes_adapter *adapter; | ||
180 | struct net_device *netdev; | ||
181 | struct resource *res; | ||
182 | struct fjes_hw *hw; | ||
183 | int err; | ||
184 | |||
185 | err = -ENOMEM; | ||
186 | netdev = alloc_netdev_mq(sizeof(struct fjes_adapter), "es%d", | ||
187 | NET_NAME_UNKNOWN, fjes_netdev_setup, | ||
188 | FJES_MAX_QUEUES); | ||
189 | |||
190 | if (!netdev) | ||
191 | goto err_out; | ||
192 | |||
193 | SET_NETDEV_DEV(netdev, &plat_dev->dev); | ||
194 | |||
195 | dev_set_drvdata(&plat_dev->dev, netdev); | ||
196 | adapter = netdev_priv(netdev); | ||
197 | adapter->netdev = netdev; | ||
198 | adapter->plat_dev = plat_dev; | ||
199 | hw = &adapter->hw; | ||
200 | hw->back = adapter; | ||
201 | |||
202 | /* setup the private structure */ | ||
203 | err = fjes_sw_init(adapter); | ||
204 | if (err) | ||
205 | goto err_free_netdev; | ||
206 | |||
207 | adapter->force_reset = false; | ||
208 | adapter->open_guard = false; | ||
209 | |||
210 | res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0); | ||
211 | hw->hw_res.start = res->start; | ||
212 | hw->hw_res.size = res->end - res->start + 1; | ||
213 | hw->hw_res.irq = platform_get_irq(plat_dev, 0); | ||
214 | err = fjes_hw_init(&adapter->hw); | ||
215 | if (err) | ||
216 | goto err_free_netdev; | ||
217 | |||
218 | /* setup MAC address (02:00:00:00:00:[epid])*/ | ||
219 | netdev->dev_addr[0] = 2; | ||
220 | netdev->dev_addr[1] = 0; | ||
221 | netdev->dev_addr[2] = 0; | ||
222 | netdev->dev_addr[3] = 0; | ||
223 | netdev->dev_addr[4] = 0; | ||
224 | netdev->dev_addr[5] = hw->my_epid; /* EPID */ | ||
225 | |||
226 | err = register_netdev(netdev); | ||
227 | if (err) | ||
228 | goto err_hw_exit; | ||
229 | |||
230 | netif_carrier_off(netdev); | ||
231 | |||
172 | return 0; | 232 | return 0; |
233 | |||
234 | err_hw_exit: | ||
235 | fjes_hw_exit(&adapter->hw); | ||
236 | err_free_netdev: | ||
237 | free_netdev(netdev); | ||
238 | err_out: | ||
239 | return err; | ||
173 | } | 240 | } |
174 | 241 | ||
175 | /* fjes_remove - Device Removal Routine */ | 242 | /* fjes_remove - Device Removal Routine */ |
176 | static int fjes_remove(struct platform_device *plat_dev) | 243 | static int fjes_remove(struct platform_device *plat_dev) |
177 | { | 244 | { |
245 | struct net_device *netdev = dev_get_drvdata(&plat_dev->dev); | ||
246 | struct fjes_adapter *adapter = netdev_priv(netdev); | ||
247 | struct fjes_hw *hw = &adapter->hw; | ||
248 | |||
249 | unregister_netdev(netdev); | ||
250 | |||
251 | fjes_hw_exit(hw); | ||
252 | |||
253 | free_netdev(netdev); | ||
254 | |||
178 | return 0; | 255 | return 0; |
179 | } | 256 | } |
180 | 257 | ||
258 | static int fjes_sw_init(struct fjes_adapter *adapter) | ||
259 | { | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | /* fjes_netdev_setup - netdevice initialization routine */ | ||
264 | static void fjes_netdev_setup(struct net_device *netdev) | ||
265 | { | ||
266 | ether_setup(netdev); | ||
267 | |||
268 | netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL; | ||
269 | netdev->netdev_ops = &fjes_netdev_ops; | ||
270 | netdev->mtu = fjes_support_mtu[0]; | ||
271 | netdev->flags |= IFF_BROADCAST; | ||
272 | netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER; | ||
273 | } | ||
274 | |||
181 | /* fjes_init_module - Driver Registration Routine */ | 275 | /* fjes_init_module - Driver Registration Routine */ |
182 | static int __init fjes_init_module(void) | 276 | static int __init fjes_init_module(void) |
183 | { | 277 | { |