blob: caecfb39ecf99bb1ec51c199a841eaa8ef233f33 [file] [log] [blame]
Taku Izumi658d4392015-08-21 17:29:17 +09001/*
2 * FUJITSU Extended Socket Network Device driver
3 * Copyright (c) 2015 FUJITSU LIMITED
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, see <http://www.gnu.org/licenses/>.
16 *
17 * The full GNU General Public License is included in this distribution in
18 * the file called "COPYING".
19 *
20 */
21
22#include <linux/module.h>
23#include <linux/types.h>
24#include <linux/nls.h>
25#include <linux/platform_device.h>
Taku Izumi2fcbca62015-08-21 17:29:20 +090026#include <linux/netdevice.h>
Taku Izumie5d486d2015-08-21 17:29:23 +090027#include <linux/interrupt.h>
Taku Izumi658d4392015-08-21 17:29:17 +090028
29#include "fjes.h"
30
31#define MAJ 1
32#define MIN 0
33#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN)
34#define DRV_NAME "fjes"
35char fjes_driver_name[] = DRV_NAME;
36char fjes_driver_version[] = DRV_VERSION;
37static const char fjes_driver_string[] =
38 "FUJITSU Extended Socket Network Device Driver";
39static const char fjes_copyright[] =
40 "Copyright (c) 2015 FUJITSU LIMITED";
41
42MODULE_AUTHOR("Taku Izumi <izumi.taku@jp.fujitsu.com>");
43MODULE_DESCRIPTION("FUJITSU Extended Socket Network Device Driver");
44MODULE_LICENSE("GPL");
45MODULE_VERSION(DRV_VERSION);
46
Taku Izumie5d486d2015-08-21 17:29:23 +090047static int fjes_request_irq(struct fjes_adapter *);
48static void fjes_free_irq(struct fjes_adapter *);
49
50static int fjes_open(struct net_device *);
51static int fjes_close(struct net_device *);
52static int fjes_setup_resources(struct fjes_adapter *);
53static void fjes_free_resources(struct fjes_adapter *);
Taku Izumi9acf51c2015-08-21 17:29:24 +090054static netdev_tx_t fjes_xmit_frame(struct sk_buff *, struct net_device *);
Taku Izumib772b9d2015-08-21 17:29:25 +090055static void fjes_raise_intr_rxdata_task(struct work_struct *);
Taku Izumiac63b942015-08-21 17:29:26 +090056static void fjes_tx_stall_task(struct work_struct *);
Taku Izumiff5b4212015-08-21 17:29:33 +090057static void fjes_force_close_task(struct work_struct *);
Taku Izumie5d486d2015-08-21 17:29:23 +090058static irqreturn_t fjes_intr(int, void*);
Taku Izumi879bc9a2015-08-21 17:29:28 +090059static struct rtnl_link_stats64 *
60fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *);
Taku Izumib9e23a62015-08-21 17:29:29 +090061static int fjes_change_mtu(struct net_device *, int);
Taku Izumi3e3fedd2015-08-21 17:29:31 +090062static int fjes_vlan_rx_add_vid(struct net_device *, __be16 proto, u16);
63static int fjes_vlan_rx_kill_vid(struct net_device *, __be16 proto, u16);
Taku Izumi4393e762015-08-21 17:29:30 +090064static void fjes_tx_retry(struct net_device *);
Taku Izumie5d486d2015-08-21 17:29:23 +090065
Taku Izumi658d4392015-08-21 17:29:17 +090066static int fjes_acpi_add(struct acpi_device *);
67static int fjes_acpi_remove(struct acpi_device *);
68static acpi_status fjes_get_acpi_resource(struct acpi_resource *, void*);
69
70static int fjes_probe(struct platform_device *);
71static int fjes_remove(struct platform_device *);
72
Taku Izumi2fcbca62015-08-21 17:29:20 +090073static int fjes_sw_init(struct fjes_adapter *);
74static void fjes_netdev_setup(struct net_device *);
Taku Izumi8edb62a2015-08-21 17:29:32 +090075static void fjes_irq_watch_task(struct work_struct *);
Taku Izumi26585932015-08-21 17:29:27 +090076static void fjes_rx_irq(struct fjes_adapter *, int);
77static int fjes_poll(struct napi_struct *, int);
78
Taku Izumi658d4392015-08-21 17:29:17 +090079static const struct acpi_device_id fjes_acpi_ids[] = {
80 {"PNP0C02", 0},
81 {"", 0},
82};
83MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids);
84
85static struct acpi_driver fjes_acpi_driver = {
86 .name = DRV_NAME,
87 .class = DRV_NAME,
88 .owner = THIS_MODULE,
89 .ids = fjes_acpi_ids,
90 .ops = {
91 .add = fjes_acpi_add,
92 .remove = fjes_acpi_remove,
93 },
94};
95
96static struct platform_driver fjes_driver = {
97 .driver = {
98 .name = DRV_NAME,
99 .owner = THIS_MODULE,
100 },
101 .probe = fjes_probe,
102 .remove = fjes_remove,
103};
104
105static struct resource fjes_resource[] = {
106 {
107 .flags = IORESOURCE_MEM,
108 .start = 0,
109 .end = 0,
110 },
111 {
112 .flags = IORESOURCE_IRQ,
113 .start = 0,
114 .end = 0,
115 },
116};
117
118static int fjes_acpi_add(struct acpi_device *device)
119{
120 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
121 char str_buf[sizeof(FJES_ACPI_SYMBOL) + 1];
122 struct platform_device *plat_dev;
123 union acpi_object *str;
124 acpi_status status;
125 int result;
126
127 status = acpi_evaluate_object(device->handle, "_STR", NULL, &buffer);
128 if (ACPI_FAILURE(status))
129 return -ENODEV;
130
131 str = buffer.pointer;
132 result = utf16s_to_utf8s((wchar_t *)str->string.pointer,
133 str->string.length, UTF16_LITTLE_ENDIAN,
134 str_buf, sizeof(str_buf) - 1);
135 str_buf[result] = 0;
136
137 if (strncmp(FJES_ACPI_SYMBOL, str_buf, strlen(FJES_ACPI_SYMBOL)) != 0) {
138 kfree(buffer.pointer);
139 return -ENODEV;
140 }
141 kfree(buffer.pointer);
142
143 status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
144 fjes_get_acpi_resource, fjes_resource);
145 if (ACPI_FAILURE(status))
146 return -ENODEV;
147
148 /* create platform_device */
149 plat_dev = platform_device_register_simple(DRV_NAME, 0, fjes_resource,
150 ARRAY_SIZE(fjes_resource));
151 device->driver_data = plat_dev;
152
153 return 0;
154}
155
156static int fjes_acpi_remove(struct acpi_device *device)
157{
158 struct platform_device *plat_dev;
159
160 plat_dev = (struct platform_device *)acpi_driver_data(device);
161 platform_device_unregister(plat_dev);
162
163 return 0;
164}
165
166static acpi_status
167fjes_get_acpi_resource(struct acpi_resource *acpi_res, void *data)
168{
169 struct acpi_resource_address32 *addr;
170 struct acpi_resource_irq *irq;
171 struct resource *res = data;
172
173 switch (acpi_res->type) {
174 case ACPI_RESOURCE_TYPE_ADDRESS32:
175 addr = &acpi_res->data.address32;
176 res[0].start = addr->address.minimum;
177 res[0].end = addr->address.minimum +
178 addr->address.address_length - 1;
179 break;
180
181 case ACPI_RESOURCE_TYPE_IRQ:
182 irq = &acpi_res->data.irq;
183 if (irq->interrupt_count != 1)
184 return AE_ERROR;
185 res[1].start = irq->interrupts[0];
186 res[1].end = irq->interrupts[0];
187 break;
188
189 default:
190 break;
191 }
192
193 return AE_OK;
194}
195
Taku Izumie5d486d2015-08-21 17:29:23 +0900196static int fjes_request_irq(struct fjes_adapter *adapter)
197{
198 struct net_device *netdev = adapter->netdev;
199 int result = -1;
200
Taku Izumi8edb62a2015-08-21 17:29:32 +0900201 adapter->interrupt_watch_enable = true;
202 if (!delayed_work_pending(&adapter->interrupt_watch_task)) {
203 queue_delayed_work(adapter->control_wq,
204 &adapter->interrupt_watch_task,
205 FJES_IRQ_WATCH_DELAY);
206 }
207
Taku Izumie5d486d2015-08-21 17:29:23 +0900208 if (!adapter->irq_registered) {
209 result = request_irq(adapter->hw.hw_res.irq, fjes_intr,
210 IRQF_SHARED, netdev->name, adapter);
211 if (result)
212 adapter->irq_registered = false;
213 else
214 adapter->irq_registered = true;
215 }
216
217 return result;
218}
219
220static void fjes_free_irq(struct fjes_adapter *adapter)
221{
222 struct fjes_hw *hw = &adapter->hw;
223
Taku Izumi8edb62a2015-08-21 17:29:32 +0900224 adapter->interrupt_watch_enable = false;
225 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
226
Taku Izumie5d486d2015-08-21 17:29:23 +0900227 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
228
229 if (adapter->irq_registered) {
230 free_irq(adapter->hw.hw_res.irq, adapter);
231 adapter->irq_registered = false;
232 }
233}
234
Taku Izumi2fcbca62015-08-21 17:29:20 +0900235static const struct net_device_ops fjes_netdev_ops = {
Taku Izumie5d486d2015-08-21 17:29:23 +0900236 .ndo_open = fjes_open,
237 .ndo_stop = fjes_close,
Taku Izumi9acf51c2015-08-21 17:29:24 +0900238 .ndo_start_xmit = fjes_xmit_frame,
Taku Izumi879bc9a2015-08-21 17:29:28 +0900239 .ndo_get_stats64 = fjes_get_stats64,
Taku Izumib9e23a62015-08-21 17:29:29 +0900240 .ndo_change_mtu = fjes_change_mtu,
Taku Izumi4393e762015-08-21 17:29:30 +0900241 .ndo_tx_timeout = fjes_tx_retry,
Taku Izumi3e3fedd2015-08-21 17:29:31 +0900242 .ndo_vlan_rx_add_vid = fjes_vlan_rx_add_vid,
243 .ndo_vlan_rx_kill_vid = fjes_vlan_rx_kill_vid,
Taku Izumi2fcbca62015-08-21 17:29:20 +0900244};
245
Taku Izumie5d486d2015-08-21 17:29:23 +0900246/* fjes_open - Called when a network interface is made active */
247static int fjes_open(struct net_device *netdev)
248{
249 struct fjes_adapter *adapter = netdev_priv(netdev);
250 struct fjes_hw *hw = &adapter->hw;
251 int result;
252
253 if (adapter->open_guard)
254 return -ENXIO;
255
256 result = fjes_setup_resources(adapter);
257 if (result)
258 goto err_setup_res;
259
260 hw->txrx_stop_req_bit = 0;
261 hw->epstop_req_bit = 0;
262
Taku Izumi26585932015-08-21 17:29:27 +0900263 napi_enable(&adapter->napi);
264
Taku Izumie5d486d2015-08-21 17:29:23 +0900265 fjes_hw_capture_interrupt_status(hw);
266
267 result = fjes_request_irq(adapter);
268 if (result)
269 goto err_req_irq;
270
271 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, false);
272
273 netif_tx_start_all_queues(netdev);
274 netif_carrier_on(netdev);
275
276 return 0;
277
278err_req_irq:
279 fjes_free_irq(adapter);
Taku Izumi26585932015-08-21 17:29:27 +0900280 napi_disable(&adapter->napi);
Taku Izumie5d486d2015-08-21 17:29:23 +0900281
282err_setup_res:
283 fjes_free_resources(adapter);
284 return result;
285}
286
287/* fjes_close - Disables a network interface */
288static int fjes_close(struct net_device *netdev)
289{
290 struct fjes_adapter *adapter = netdev_priv(netdev);
291 struct fjes_hw *hw = &adapter->hw;
292 int epidx;
293
294 netif_tx_stop_all_queues(netdev);
295 netif_carrier_off(netdev);
296
297 fjes_hw_raise_epstop(hw);
298
Taku Izumi26585932015-08-21 17:29:27 +0900299 napi_disable(&adapter->napi);
300
Taku Izumie5d486d2015-08-21 17:29:23 +0900301 for (epidx = 0; epidx < hw->max_epid; epidx++) {
302 if (epidx == hw->my_epid)
303 continue;
304
305 adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status &=
306 ~FJES_RX_POLL_WORK;
307 }
308
309 fjes_free_irq(adapter);
310
Taku Izumi8edb62a2015-08-21 17:29:32 +0900311 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
Taku Izumib772b9d2015-08-21 17:29:25 +0900312 cancel_work_sync(&adapter->raise_intr_rxdata_task);
Taku Izumiac63b942015-08-21 17:29:26 +0900313 cancel_work_sync(&adapter->tx_stall_task);
Taku Izumib772b9d2015-08-21 17:29:25 +0900314
Taku Izumie5d486d2015-08-21 17:29:23 +0900315 fjes_hw_wait_epstop(hw);
316
317 fjes_free_resources(adapter);
318
319 return 0;
320}
321
322static int fjes_setup_resources(struct fjes_adapter *adapter)
323{
324 struct net_device *netdev = adapter->netdev;
325 struct ep_share_mem_info *buf_pair;
326 struct fjes_hw *hw = &adapter->hw;
327 int result;
328 int epidx;
329
330 mutex_lock(&hw->hw_info.lock);
331 result = fjes_hw_request_info(hw);
332 switch (result) {
333 case 0:
334 for (epidx = 0; epidx < hw->max_epid; epidx++) {
335 hw->ep_shm_info[epidx].es_status =
336 hw->hw_info.res_buf->info.info[epidx].es_status;
337 hw->ep_shm_info[epidx].zone =
338 hw->hw_info.res_buf->info.info[epidx].zone;
339 }
340 break;
341 default:
342 case -ENOMSG:
343 case -EBUSY:
344 adapter->force_reset = true;
345
346 mutex_unlock(&hw->hw_info.lock);
347 return result;
348 }
349 mutex_unlock(&hw->hw_info.lock);
350
351 for (epidx = 0; epidx < (hw->max_epid); epidx++) {
352 if ((epidx != hw->my_epid) &&
353 (hw->ep_shm_info[epidx].es_status ==
354 FJES_ZONING_STATUS_ENABLE)) {
355 fjes_hw_raise_interrupt(hw, epidx,
356 REG_ICTL_MASK_INFO_UPDATE);
357 }
358 }
359
360 msleep(FJES_OPEN_ZONE_UPDATE_WAIT * hw->max_epid);
361
362 for (epidx = 0; epidx < (hw->max_epid); epidx++) {
363 if (epidx == hw->my_epid)
364 continue;
365
366 buf_pair = &hw->ep_shm_info[epidx];
367
368 fjes_hw_setup_epbuf(&buf_pair->tx, netdev->dev_addr,
369 netdev->mtu);
370
371 if (fjes_hw_epid_is_same_zone(hw, epidx)) {
372 mutex_lock(&hw->hw_info.lock);
373 result =
374 fjes_hw_register_buff_addr(hw, epidx, buf_pair);
375 mutex_unlock(&hw->hw_info.lock);
376
377 switch (result) {
378 case 0:
379 break;
380 case -ENOMSG:
381 case -EBUSY:
382 default:
383 adapter->force_reset = true;
384 return result;
385 }
386 }
387 }
388
389 return 0;
390}
391
392static void fjes_free_resources(struct fjes_adapter *adapter)
393{
394 struct net_device *netdev = adapter->netdev;
395 struct fjes_device_command_param param;
396 struct ep_share_mem_info *buf_pair;
397 struct fjes_hw *hw = &adapter->hw;
398 bool reset_flag = false;
399 int result;
400 int epidx;
401
402 for (epidx = 0; epidx < hw->max_epid; epidx++) {
403 if (epidx == hw->my_epid)
404 continue;
405
406 mutex_lock(&hw->hw_info.lock);
407 result = fjes_hw_unregister_buff_addr(hw, epidx);
408 mutex_unlock(&hw->hw_info.lock);
409
410 if (result)
411 reset_flag = true;
412
413 buf_pair = &hw->ep_shm_info[epidx];
414
415 fjes_hw_setup_epbuf(&buf_pair->tx,
416 netdev->dev_addr, netdev->mtu);
417
418 clear_bit(epidx, &hw->txrx_stop_req_bit);
419 }
420
421 if (reset_flag || adapter->force_reset) {
422 result = fjes_hw_reset(hw);
423
424 adapter->force_reset = false;
425
426 if (result)
427 adapter->open_guard = true;
428
429 hw->hw_info.buffer_share_bit = 0;
430
431 memset((void *)&param, 0, sizeof(param));
432
433 param.req_len = hw->hw_info.req_buf_size;
434 param.req_start = __pa(hw->hw_info.req_buf);
435 param.res_len = hw->hw_info.res_buf_size;
436 param.res_start = __pa(hw->hw_info.res_buf);
437 param.share_start = __pa(hw->hw_info.share->ep_status);
438
439 fjes_hw_init_command_registers(hw, &param);
440 }
441}
442
Taku Izumiac63b942015-08-21 17:29:26 +0900443static void fjes_tx_stall_task(struct work_struct *work)
444{
445 struct fjes_adapter *adapter = container_of(work,
446 struct fjes_adapter, tx_stall_task);
447 struct net_device *netdev = adapter->netdev;
448 struct fjes_hw *hw = &adapter->hw;
449 int all_queue_available, sendable;
450 enum ep_partner_status pstatus;
451 int max_epid, my_epid, epid;
452 union ep_buffer_info *info;
453 int i;
454
455 if (((long)jiffies -
456 (long)(netdev->trans_start)) > FJES_TX_TX_STALL_TIMEOUT) {
457 netif_wake_queue(netdev);
458 return;
459 }
460
461 my_epid = hw->my_epid;
462 max_epid = hw->max_epid;
463
464 for (i = 0; i < 5; i++) {
465 all_queue_available = 1;
466
467 for (epid = 0; epid < max_epid; epid++) {
468 if (my_epid == epid)
469 continue;
470
471 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
472 sendable = (pstatus == EP_PARTNER_SHARED);
473 if (!sendable)
474 continue;
475
476 info = adapter->hw.ep_shm_info[epid].tx.info;
477
478 if (EP_RING_FULL(info->v1i.head, info->v1i.tail,
479 info->v1i.count_max)) {
480 all_queue_available = 0;
481 break;
482 }
483 }
484
485 if (all_queue_available) {
486 netif_wake_queue(netdev);
487 return;
488 }
489 }
490
491 usleep_range(50, 100);
492
493 queue_work(adapter->txrx_wq, &adapter->tx_stall_task);
494}
495
Taku Izumiff5b4212015-08-21 17:29:33 +0900496static void fjes_force_close_task(struct work_struct *work)
497{
498 struct fjes_adapter *adapter = container_of(work,
499 struct fjes_adapter, force_close_task);
500 struct net_device *netdev = adapter->netdev;
501
502 rtnl_lock();
503 dev_close(netdev);
504 rtnl_unlock();
505}
506
Taku Izumib772b9d2015-08-21 17:29:25 +0900507static void fjes_raise_intr_rxdata_task(struct work_struct *work)
508{
509 struct fjes_adapter *adapter = container_of(work,
510 struct fjes_adapter, raise_intr_rxdata_task);
511 struct fjes_hw *hw = &adapter->hw;
512 enum ep_partner_status pstatus;
513 int max_epid, my_epid, epid;
514
515 my_epid = hw->my_epid;
516 max_epid = hw->max_epid;
517
518 for (epid = 0; epid < max_epid; epid++)
519 hw->ep_shm_info[epid].tx_status_work = 0;
520
521 for (epid = 0; epid < max_epid; epid++) {
522 if (epid == my_epid)
523 continue;
524
525 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
526 if (pstatus == EP_PARTNER_SHARED) {
527 hw->ep_shm_info[epid].tx_status_work =
528 hw->ep_shm_info[epid].tx.info->v1i.tx_status;
529
530 if (hw->ep_shm_info[epid].tx_status_work ==
531 FJES_TX_DELAY_SEND_PENDING) {
532 hw->ep_shm_info[epid].tx.info->v1i.tx_status =
533 FJES_TX_DELAY_SEND_NONE;
534 }
535 }
536 }
537
538 for (epid = 0; epid < max_epid; epid++) {
539 if (epid == my_epid)
540 continue;
541
542 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
543 if ((hw->ep_shm_info[epid].tx_status_work ==
544 FJES_TX_DELAY_SEND_PENDING) &&
545 (pstatus == EP_PARTNER_SHARED) &&
546 !(hw->ep_shm_info[epid].rx.info->v1i.rx_status)) {
547 fjes_hw_raise_interrupt(hw, epid,
548 REG_ICTL_MASK_RX_DATA);
549 }
550 }
551
552 usleep_range(500, 1000);
553}
554
Taku Izumi9acf51c2015-08-21 17:29:24 +0900555static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
556 void *data, size_t len)
557{
558 int retval;
559
560 retval = fjes_hw_epbuf_tx_pkt_send(&adapter->hw.ep_shm_info[dest].tx,
561 data, len);
562 if (retval)
563 return retval;
564
565 adapter->hw.ep_shm_info[dest].tx.info->v1i.tx_status =
566 FJES_TX_DELAY_SEND_PENDING;
Taku Izumib772b9d2015-08-21 17:29:25 +0900567 if (!work_pending(&adapter->raise_intr_rxdata_task))
568 queue_work(adapter->txrx_wq,
569 &adapter->raise_intr_rxdata_task);
Taku Izumi9acf51c2015-08-21 17:29:24 +0900570
571 retval = 0;
572 return retval;
573}
574
575static netdev_tx_t
576fjes_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
577{
578 struct fjes_adapter *adapter = netdev_priv(netdev);
579 struct fjes_hw *hw = &adapter->hw;
580
581 int max_epid, my_epid, dest_epid;
582 enum ep_partner_status pstatus;
583 struct netdev_queue *cur_queue;
584 char shortpkt[VLAN_ETH_HLEN];
585 bool is_multi, vlan;
586 struct ethhdr *eth;
587 u16 queue_no = 0;
588 u16 vlan_id = 0;
589 netdev_tx_t ret;
590 char *data;
591 int len;
592
593 ret = NETDEV_TX_OK;
594 is_multi = false;
595 cur_queue = netdev_get_tx_queue(netdev, queue_no);
596
597 eth = (struct ethhdr *)skb->data;
598 my_epid = hw->my_epid;
599
600 vlan = (vlan_get_tag(skb, &vlan_id) == 0) ? true : false;
601
602 data = skb->data;
603 len = skb->len;
604
605 if (is_multicast_ether_addr(eth->h_dest)) {
606 dest_epid = 0;
607 max_epid = hw->max_epid;
608 is_multi = true;
609 } else if (is_local_ether_addr(eth->h_dest)) {
610 dest_epid = eth->h_dest[ETH_ALEN - 1];
611 max_epid = dest_epid + 1;
612
613 if ((eth->h_dest[0] == 0x02) &&
614 (0x00 == (eth->h_dest[1] | eth->h_dest[2] |
615 eth->h_dest[3] | eth->h_dest[4])) &&
616 (dest_epid < hw->max_epid)) {
617 ;
618 } else {
619 dest_epid = 0;
620 max_epid = 0;
621 ret = NETDEV_TX_OK;
622
623 adapter->stats64.tx_packets += 1;
624 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
625 adapter->stats64.tx_bytes += len;
626 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
627 }
628 } else {
629 dest_epid = 0;
630 max_epid = 0;
631 ret = NETDEV_TX_OK;
632
633 adapter->stats64.tx_packets += 1;
634 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
635 adapter->stats64.tx_bytes += len;
636 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
637 }
638
639 for (; dest_epid < max_epid; dest_epid++) {
640 if (my_epid == dest_epid)
641 continue;
642
643 pstatus = fjes_hw_get_partner_ep_status(hw, dest_epid);
644 if (pstatus != EP_PARTNER_SHARED) {
645 ret = NETDEV_TX_OK;
646 } else if (!fjes_hw_check_epbuf_version(
647 &adapter->hw.ep_shm_info[dest_epid].rx, 0)) {
648 /* version is NOT 0 */
649 adapter->stats64.tx_carrier_errors += 1;
650 hw->ep_shm_info[my_epid].net_stats
651 .tx_carrier_errors += 1;
652
653 ret = NETDEV_TX_OK;
654 } else if (!fjes_hw_check_mtu(
655 &adapter->hw.ep_shm_info[dest_epid].rx,
656 netdev->mtu)) {
657 adapter->stats64.tx_dropped += 1;
658 hw->ep_shm_info[my_epid].net_stats.tx_dropped += 1;
659 adapter->stats64.tx_errors += 1;
660 hw->ep_shm_info[my_epid].net_stats.tx_errors += 1;
661
662 ret = NETDEV_TX_OK;
663 } else if (vlan &&
664 !fjes_hw_check_vlan_id(
665 &adapter->hw.ep_shm_info[dest_epid].rx,
666 vlan_id)) {
667 ret = NETDEV_TX_OK;
668 } else {
669 if (len < VLAN_ETH_HLEN) {
670 memset(shortpkt, 0, VLAN_ETH_HLEN);
671 memcpy(shortpkt, skb->data, skb->len);
672 len = VLAN_ETH_HLEN;
673 data = shortpkt;
674 }
675
676 if (adapter->tx_retry_count == 0) {
677 adapter->tx_start_jiffies = jiffies;
678 adapter->tx_retry_count = 1;
679 } else {
680 adapter->tx_retry_count++;
681 }
682
683 if (fjes_tx_send(adapter, dest_epid, data, len)) {
684 if (is_multi) {
685 ret = NETDEV_TX_OK;
686 } else if (
687 ((long)jiffies -
688 (long)adapter->tx_start_jiffies) >=
689 FJES_TX_RETRY_TIMEOUT) {
690 adapter->stats64.tx_fifo_errors += 1;
691 hw->ep_shm_info[my_epid].net_stats
692 .tx_fifo_errors += 1;
693 adapter->stats64.tx_errors += 1;
694 hw->ep_shm_info[my_epid].net_stats
695 .tx_errors += 1;
696
697 ret = NETDEV_TX_OK;
698 } else {
699 netdev->trans_start = jiffies;
700 netif_tx_stop_queue(cur_queue);
701
Taku Izumiac63b942015-08-21 17:29:26 +0900702 if (!work_pending(&adapter->tx_stall_task))
703 queue_work(adapter->txrx_wq,
704 &adapter->tx_stall_task);
705
Taku Izumi9acf51c2015-08-21 17:29:24 +0900706 ret = NETDEV_TX_BUSY;
707 }
708 } else {
709 if (!is_multi) {
710 adapter->stats64.tx_packets += 1;
711 hw->ep_shm_info[my_epid].net_stats
712 .tx_packets += 1;
713 adapter->stats64.tx_bytes += len;
714 hw->ep_shm_info[my_epid].net_stats
715 .tx_bytes += len;
716 }
717
718 adapter->tx_retry_count = 0;
719 ret = NETDEV_TX_OK;
720 }
721 }
722 }
723
724 if (ret == NETDEV_TX_OK) {
725 dev_kfree_skb(skb);
726 if (is_multi) {
727 adapter->stats64.tx_packets += 1;
728 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
729 adapter->stats64.tx_bytes += 1;
730 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
731 }
732 }
733
734 return ret;
735}
736
Taku Izumi4393e762015-08-21 17:29:30 +0900737static void fjes_tx_retry(struct net_device *netdev)
738{
739 struct netdev_queue *queue = netdev_get_tx_queue(netdev, 0);
740
741 netif_tx_wake_queue(queue);
742}
743
Taku Izumi879bc9a2015-08-21 17:29:28 +0900744static struct rtnl_link_stats64 *
745fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
746{
747 struct fjes_adapter *adapter = netdev_priv(netdev);
748
749 memcpy(stats, &adapter->stats64, sizeof(struct rtnl_link_stats64));
750
751 return stats;
752}
753
Taku Izumib9e23a62015-08-21 17:29:29 +0900754static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
755{
756 bool running = netif_running(netdev);
757 int ret = 0;
758 int idx;
759
760 for (idx = 0; fjes_support_mtu[idx] != 0; idx++) {
761 if (new_mtu <= fjes_support_mtu[idx]) {
762 new_mtu = fjes_support_mtu[idx];
763 if (new_mtu == netdev->mtu)
764 return 0;
765
766 if (running)
767 fjes_close(netdev);
768
769 netdev->mtu = new_mtu;
770
771 if (running)
772 ret = fjes_open(netdev);
773
774 return ret;
775 }
776 }
777
778 return -EINVAL;
779}
780
Taku Izumi3e3fedd2015-08-21 17:29:31 +0900781static int fjes_vlan_rx_add_vid(struct net_device *netdev,
782 __be16 proto, u16 vid)
783{
784 struct fjes_adapter *adapter = netdev_priv(netdev);
785 bool ret = true;
786 int epid;
787
788 for (epid = 0; epid < adapter->hw.max_epid; epid++) {
789 if (epid == adapter->hw.my_epid)
790 continue;
791
792 if (!fjes_hw_check_vlan_id(
793 &adapter->hw.ep_shm_info[epid].tx, vid))
794 ret = fjes_hw_set_vlan_id(
795 &adapter->hw.ep_shm_info[epid].tx, vid);
796 }
797
798 return ret ? 0 : -ENOSPC;
799}
800
801static int fjes_vlan_rx_kill_vid(struct net_device *netdev,
802 __be16 proto, u16 vid)
803{
804 struct fjes_adapter *adapter = netdev_priv(netdev);
805 int epid;
806
807 for (epid = 0; epid < adapter->hw.max_epid; epid++) {
808 if (epid == adapter->hw.my_epid)
809 continue;
810
811 fjes_hw_del_vlan_id(&adapter->hw.ep_shm_info[epid].tx, vid);
812 }
813
814 return 0;
815}
816
Taku Izumie5d486d2015-08-21 17:29:23 +0900817static irqreturn_t fjes_intr(int irq, void *data)
818{
819 struct fjes_adapter *adapter = data;
820 struct fjes_hw *hw = &adapter->hw;
821 irqreturn_t ret;
822 u32 icr;
823
824 icr = fjes_hw_capture_interrupt_status(hw);
825
Taku Izumi26585932015-08-21 17:29:27 +0900826 if (icr & REG_IS_MASK_IS_ASSERT) {
827 if (icr & REG_ICTL_MASK_RX_DATA)
828 fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID);
829
Taku Izumie5d486d2015-08-21 17:29:23 +0900830 ret = IRQ_HANDLED;
Taku Izumi26585932015-08-21 17:29:27 +0900831 } else {
Taku Izumie5d486d2015-08-21 17:29:23 +0900832 ret = IRQ_NONE;
Taku Izumi26585932015-08-21 17:29:27 +0900833 }
Taku Izumie5d486d2015-08-21 17:29:23 +0900834
835 return ret;
836}
837
Taku Izumi26585932015-08-21 17:29:27 +0900838static int fjes_rxframe_search_exist(struct fjes_adapter *adapter,
839 int start_epid)
840{
841 struct fjes_hw *hw = &adapter->hw;
842 enum ep_partner_status pstatus;
843 int max_epid, cur_epid;
844 int i;
845
846 max_epid = hw->max_epid;
847 start_epid = (start_epid + 1 + max_epid) % max_epid;
848
849 for (i = 0; i < max_epid; i++) {
850 cur_epid = (start_epid + i) % max_epid;
851 if (cur_epid == hw->my_epid)
852 continue;
853
854 pstatus = fjes_hw_get_partner_ep_status(hw, cur_epid);
855 if (pstatus == EP_PARTNER_SHARED) {
856 if (!fjes_hw_epbuf_rx_is_empty(
857 &hw->ep_shm_info[cur_epid].rx))
858 return cur_epid;
859 }
860 }
861 return -1;
862}
863
864static void *fjes_rxframe_get(struct fjes_adapter *adapter, size_t *psize,
865 int *cur_epid)
866{
867 void *frame;
868
869 *cur_epid = fjes_rxframe_search_exist(adapter, *cur_epid);
870 if (*cur_epid < 0)
871 return NULL;
872
873 frame =
874 fjes_hw_epbuf_rx_curpkt_get_addr(
875 &adapter->hw.ep_shm_info[*cur_epid].rx, psize);
876
877 return frame;
878}
879
880static void fjes_rxframe_release(struct fjes_adapter *adapter, int cur_epid)
881{
882 fjes_hw_epbuf_rx_curpkt_drop(&adapter->hw.ep_shm_info[cur_epid].rx);
883}
884
885static void fjes_rx_irq(struct fjes_adapter *adapter, int src_epid)
886{
887 struct fjes_hw *hw = &adapter->hw;
888
889 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, true);
890
891 adapter->unset_rx_last = true;
892 napi_schedule(&adapter->napi);
893}
894
895static int fjes_poll(struct napi_struct *napi, int budget)
896{
897 struct fjes_adapter *adapter =
898 container_of(napi, struct fjes_adapter, napi);
899 struct net_device *netdev = napi->dev;
900 struct fjes_hw *hw = &adapter->hw;
901 struct sk_buff *skb;
902 int work_done = 0;
903 int cur_epid = 0;
904 int epidx;
905 size_t frame_len;
906 void *frame;
907
908 for (epidx = 0; epidx < hw->max_epid; epidx++) {
909 if (epidx == hw->my_epid)
910 continue;
911
912 adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status |=
913 FJES_RX_POLL_WORK;
914 }
915
916 while (work_done < budget) {
917 prefetch(&adapter->hw);
918 frame = fjes_rxframe_get(adapter, &frame_len, &cur_epid);
919
920 if (frame) {
921 skb = napi_alloc_skb(napi, frame_len);
922 if (!skb) {
923 adapter->stats64.rx_dropped += 1;
924 hw->ep_shm_info[cur_epid].net_stats
925 .rx_dropped += 1;
926 adapter->stats64.rx_errors += 1;
927 hw->ep_shm_info[cur_epid].net_stats
928 .rx_errors += 1;
929 } else {
930 memcpy(skb_put(skb, frame_len),
931 frame, frame_len);
932 skb->protocol = eth_type_trans(skb, netdev);
933 skb->ip_summed = CHECKSUM_UNNECESSARY;
934
935 netif_receive_skb(skb);
936
937 work_done++;
938
939 adapter->stats64.rx_packets += 1;
940 hw->ep_shm_info[cur_epid].net_stats
941 .rx_packets += 1;
942 adapter->stats64.rx_bytes += frame_len;
943 hw->ep_shm_info[cur_epid].net_stats
944 .rx_bytes += frame_len;
945
946 if (is_multicast_ether_addr(
947 ((struct ethhdr *)frame)->h_dest)) {
948 adapter->stats64.multicast += 1;
949 hw->ep_shm_info[cur_epid].net_stats
950 .multicast += 1;
951 }
952 }
953
954 fjes_rxframe_release(adapter, cur_epid);
955 adapter->unset_rx_last = true;
956 } else {
957 break;
958 }
959 }
960
961 if (work_done < budget) {
962 napi_complete(napi);
963
964 if (adapter->unset_rx_last) {
965 adapter->rx_last_jiffies = jiffies;
966 adapter->unset_rx_last = false;
967 }
968
969 if (((long)jiffies - (long)adapter->rx_last_jiffies) < 3) {
970 napi_reschedule(napi);
971 } else {
972 for (epidx = 0; epidx < hw->max_epid; epidx++) {
973 if (epidx == hw->my_epid)
974 continue;
975 adapter->hw.ep_shm_info[epidx]
976 .tx.info->v1i.rx_status &=
977 ~FJES_RX_POLL_WORK;
978 }
979
980 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, false);
981 }
982 }
983
984 return work_done;
985}
986
Taku Izumi658d4392015-08-21 17:29:17 +0900987/* fjes_probe - Device Initialization Routine */
988static int fjes_probe(struct platform_device *plat_dev)
989{
Taku Izumi2fcbca62015-08-21 17:29:20 +0900990 struct fjes_adapter *adapter;
991 struct net_device *netdev;
992 struct resource *res;
993 struct fjes_hw *hw;
994 int err;
995
996 err = -ENOMEM;
997 netdev = alloc_netdev_mq(sizeof(struct fjes_adapter), "es%d",
998 NET_NAME_UNKNOWN, fjes_netdev_setup,
999 FJES_MAX_QUEUES);
1000
1001 if (!netdev)
1002 goto err_out;
1003
1004 SET_NETDEV_DEV(netdev, &plat_dev->dev);
1005
1006 dev_set_drvdata(&plat_dev->dev, netdev);
1007 adapter = netdev_priv(netdev);
1008 adapter->netdev = netdev;
1009 adapter->plat_dev = plat_dev;
1010 hw = &adapter->hw;
1011 hw->back = adapter;
1012
1013 /* setup the private structure */
1014 err = fjes_sw_init(adapter);
1015 if (err)
1016 goto err_free_netdev;
1017
Taku Izumiff5b4212015-08-21 17:29:33 +09001018 INIT_WORK(&adapter->force_close_task, fjes_force_close_task);
Taku Izumi2fcbca62015-08-21 17:29:20 +09001019 adapter->force_reset = false;
1020 adapter->open_guard = false;
1021
Taku Izumib772b9d2015-08-21 17:29:25 +09001022 adapter->txrx_wq = create_workqueue(DRV_NAME "/txrx");
Taku Izumi8edb62a2015-08-21 17:29:32 +09001023 adapter->control_wq = create_workqueue(DRV_NAME "/control");
Taku Izumib772b9d2015-08-21 17:29:25 +09001024
Taku Izumiac63b942015-08-21 17:29:26 +09001025 INIT_WORK(&adapter->tx_stall_task, fjes_tx_stall_task);
Taku Izumib772b9d2015-08-21 17:29:25 +09001026 INIT_WORK(&adapter->raise_intr_rxdata_task,
1027 fjes_raise_intr_rxdata_task);
1028
Taku Izumi8edb62a2015-08-21 17:29:32 +09001029 INIT_DELAYED_WORK(&adapter->interrupt_watch_task, fjes_irq_watch_task);
1030 adapter->interrupt_watch_enable = false;
1031
Taku Izumi2fcbca62015-08-21 17:29:20 +09001032 res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
1033 hw->hw_res.start = res->start;
1034 hw->hw_res.size = res->end - res->start + 1;
1035 hw->hw_res.irq = platform_get_irq(plat_dev, 0);
1036 err = fjes_hw_init(&adapter->hw);
1037 if (err)
1038 goto err_free_netdev;
1039
1040 /* setup MAC address (02:00:00:00:00:[epid])*/
1041 netdev->dev_addr[0] = 2;
1042 netdev->dev_addr[1] = 0;
1043 netdev->dev_addr[2] = 0;
1044 netdev->dev_addr[3] = 0;
1045 netdev->dev_addr[4] = 0;
1046 netdev->dev_addr[5] = hw->my_epid; /* EPID */
1047
1048 err = register_netdev(netdev);
1049 if (err)
1050 goto err_hw_exit;
1051
1052 netif_carrier_off(netdev);
1053
Taku Izumi658d4392015-08-21 17:29:17 +09001054 return 0;
Taku Izumi2fcbca62015-08-21 17:29:20 +09001055
1056err_hw_exit:
1057 fjes_hw_exit(&adapter->hw);
1058err_free_netdev:
1059 free_netdev(netdev);
1060err_out:
1061 return err;
Taku Izumi658d4392015-08-21 17:29:17 +09001062}
1063
1064/* fjes_remove - Device Removal Routine */
1065static int fjes_remove(struct platform_device *plat_dev)
1066{
Taku Izumi2fcbca62015-08-21 17:29:20 +09001067 struct net_device *netdev = dev_get_drvdata(&plat_dev->dev);
1068 struct fjes_adapter *adapter = netdev_priv(netdev);
1069 struct fjes_hw *hw = &adapter->hw;
1070
Taku Izumi8edb62a2015-08-21 17:29:32 +09001071 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
Taku Izumib772b9d2015-08-21 17:29:25 +09001072 cancel_work_sync(&adapter->raise_intr_rxdata_task);
Taku Izumiac63b942015-08-21 17:29:26 +09001073 cancel_work_sync(&adapter->tx_stall_task);
Taku Izumi8edb62a2015-08-21 17:29:32 +09001074 if (adapter->control_wq)
1075 destroy_workqueue(adapter->control_wq);
Taku Izumib772b9d2015-08-21 17:29:25 +09001076 if (adapter->txrx_wq)
1077 destroy_workqueue(adapter->txrx_wq);
1078
Taku Izumi2fcbca62015-08-21 17:29:20 +09001079 unregister_netdev(netdev);
1080
1081 fjes_hw_exit(hw);
1082
Taku Izumi26585932015-08-21 17:29:27 +09001083 netif_napi_del(&adapter->napi);
1084
Taku Izumi2fcbca62015-08-21 17:29:20 +09001085 free_netdev(netdev);
1086
Taku Izumi658d4392015-08-21 17:29:17 +09001087 return 0;
1088}
1089
Taku Izumi2fcbca62015-08-21 17:29:20 +09001090static int fjes_sw_init(struct fjes_adapter *adapter)
1091{
Taku Izumi26585932015-08-21 17:29:27 +09001092 struct net_device *netdev = adapter->netdev;
1093
1094 netif_napi_add(netdev, &adapter->napi, fjes_poll, 64);
1095
Taku Izumi2fcbca62015-08-21 17:29:20 +09001096 return 0;
1097}
1098
1099/* fjes_netdev_setup - netdevice initialization routine */
1100static void fjes_netdev_setup(struct net_device *netdev)
1101{
1102 ether_setup(netdev);
1103
1104 netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL;
1105 netdev->netdev_ops = &fjes_netdev_ops;
1106 netdev->mtu = fjes_support_mtu[0];
1107 netdev->flags |= IFF_BROADCAST;
1108 netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER;
1109}
1110
Taku Izumi8edb62a2015-08-21 17:29:32 +09001111static void fjes_irq_watch_task(struct work_struct *work)
1112{
1113 struct fjes_adapter *adapter = container_of(to_delayed_work(work),
1114 struct fjes_adapter, interrupt_watch_task);
1115
1116 local_irq_disable();
1117 fjes_intr(adapter->hw.hw_res.irq, adapter);
1118 local_irq_enable();
1119
1120 if (fjes_rxframe_search_exist(adapter, 0) >= 0)
1121 napi_schedule(&adapter->napi);
1122
1123 if (adapter->interrupt_watch_enable) {
1124 if (!delayed_work_pending(&adapter->interrupt_watch_task))
1125 queue_delayed_work(adapter->control_wq,
1126 &adapter->interrupt_watch_task,
1127 FJES_IRQ_WATCH_DELAY);
1128 }
1129}
1130
Taku Izumi658d4392015-08-21 17:29:17 +09001131/* fjes_init_module - Driver Registration Routine */
1132static int __init fjes_init_module(void)
1133{
1134 int result;
1135
1136 pr_info("%s - version %s - %s\n",
1137 fjes_driver_string, fjes_driver_version, fjes_copyright);
1138
1139 result = platform_driver_register(&fjes_driver);
1140 if (result < 0)
1141 return result;
1142
1143 result = acpi_bus_register_driver(&fjes_acpi_driver);
1144 if (result < 0)
1145 goto fail_acpi_driver;
1146
1147 return 0;
1148
1149fail_acpi_driver:
1150 platform_driver_unregister(&fjes_driver);
1151 return result;
1152}
1153
1154module_init(fjes_init_module);
1155
1156/* fjes_exit_module - Driver Exit Cleanup Routine */
1157static void __exit fjes_exit_module(void)
1158{
1159 acpi_bus_unregister_driver(&fjes_acpi_driver);
1160 platform_driver_unregister(&fjes_driver);
1161}
1162
1163module_exit(fjes_exit_module);