aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-08-24 17:06:37 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-24 17:06:37 -0400
commit56fff0a01fa056502a28d67cb5a2714d64780415 (patch)
treef9f59b7da4c673d3f7cdbc5322e0e21c122fddfb
parent4a89ba04ecc6377696e4e26c1abc1cb5764decb9 (diff)
parent786eec27cbb1713caf3b33538a877a21e779d3bc (diff)
Merge branch 'fjes'
Taku Izumi says: ==================== FUJITSU Extended Socket network device driver This patchsets adds FUJITSU Extended Socket network device driver. Extended Socket network device is a shared memory based high-speed network interface between Extended Partitions of PRIMEQUEST 2000 E2 series. You can get some information about Extended Partition and Extended Socket by referring the following manual. http://globalsp.ts.fujitsu.com/dmsp/Publications/public/CA92344-0537.pdf 3.2.1 Extended Partitioning 3.2.2 Extended Socke v2.2 -> v3: - Fix up according to David's comment (No functional change) ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/Kconfig7
-rw-r--r--drivers/net/Makefile2
-rw-r--r--drivers/net/fjes/Makefile30
-rw-r--r--drivers/net/fjes/fjes.h77
-rw-r--r--drivers/net/fjes/fjes_ethtool.c137
-rw-r--r--drivers/net/fjes/fjes_hw.c1125
-rw-r--r--drivers/net/fjes/fjes_hw.h334
-rw-r--r--drivers/net/fjes/fjes_main.c1383
-rw-r--r--drivers/net/fjes/fjes_regs.h142
9 files changed, 3237 insertions, 0 deletions
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index f50373645ab4..770483b31d62 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -413,6 +413,13 @@ config VMXNET3
413 To compile this driver as a module, choose M here: the 413 To compile this driver as a module, choose M here: the
414 module will be called vmxnet3. 414 module will be called vmxnet3.
415 415
416config FUJITSU_ES
417 tristate "FUJITSU Extended Socket Network Device driver"
418 depends on ACPI
419 help
420 This driver provides support for Extended Socket network device
421 on Extended Partitioning of FUJITSU PRIMEQUEST 2000 E2 series.
422
416source "drivers/net/hyperv/Kconfig" 423source "drivers/net/hyperv/Kconfig"
417 424
418endif # NETDEVICES 425endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index ca16dd689b36..900b0c5320bb 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -68,3 +68,5 @@ obj-$(CONFIG_USB_NET_DRIVERS) += usb/
68 68
69obj-$(CONFIG_HYPERV_NET) += hyperv/ 69obj-$(CONFIG_HYPERV_NET) += hyperv/
70obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o 70obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
71
72obj-$(CONFIG_FUJITSU_ES) += fjes/
diff --git a/drivers/net/fjes/Makefile b/drivers/net/fjes/Makefile
new file mode 100644
index 000000000000..523e3d7cf7aa
--- /dev/null
+++ b/drivers/net/fjes/Makefile
@@ -0,0 +1,30 @@
1################################################################################
2#
3# FUJITSU Extended Socket Network Device driver
4# Copyright (c) 2015 FUJITSU LIMITED
5#
6# This program is free software; you can redistribute it and/or modify it
7# under the terms and conditions of the GNU General Public License,
8# version 2, as published by the Free Software Foundation.
9#
10# This program is distributed in the hope it will be useful, but WITHOUT
11# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13# more details.
14#
15# You should have received a copy of the GNU General Public License along with
16# this program; if not, see <http://www.gnu.org/licenses/>.
17#
18# The full GNU General Public License is included in this distribution in
19# the file called "COPYING".
20#
21################################################################################
22
23
24#
25# Makefile for the FUJITSU Extended Socket network device driver
26#
27
28obj-$(CONFIG_FUJITSU_ES) += fjes.o
29
30fjes-objs := fjes_main.o fjes_hw.o fjes_ethtool.o
diff --git a/drivers/net/fjes/fjes.h b/drivers/net/fjes/fjes.h
new file mode 100644
index 000000000000..a592fe21c698
--- /dev/null
+++ b/drivers/net/fjes/fjes.h
@@ -0,0 +1,77 @@
1/*
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#ifndef FJES_H_
23#define FJES_H_
24
25#include <linux/acpi.h>
26
27#include "fjes_hw.h"
28
29#define FJES_ACPI_SYMBOL "Extended Socket"
30#define FJES_MAX_QUEUES 1
31#define FJES_TX_RETRY_INTERVAL (20 * HZ)
32#define FJES_TX_RETRY_TIMEOUT (100)
33#define FJES_TX_TX_STALL_TIMEOUT (FJES_TX_RETRY_INTERVAL / 2)
34#define FJES_OPEN_ZONE_UPDATE_WAIT (300) /* msec */
35#define FJES_IRQ_WATCH_DELAY (HZ)
36
37/* board specific private data structure */
38struct fjes_adapter {
39 struct net_device *netdev;
40 struct platform_device *plat_dev;
41
42 struct napi_struct napi;
43 struct rtnl_link_stats64 stats64;
44
45 unsigned int tx_retry_count;
46 unsigned long tx_start_jiffies;
47 unsigned long rx_last_jiffies;
48 bool unset_rx_last;
49
50 struct work_struct force_close_task;
51 bool force_reset;
52 bool open_guard;
53
54 bool irq_registered;
55
56 struct workqueue_struct *txrx_wq;
57 struct workqueue_struct *control_wq;
58
59 struct work_struct tx_stall_task;
60 struct work_struct raise_intr_rxdata_task;
61
62 struct work_struct unshare_watch_task;
63 unsigned long unshare_watch_bitmask;
64
65 struct delayed_work interrupt_watch_task;
66 bool interrupt_watch_enable;
67
68 struct fjes_hw hw;
69};
70
71extern char fjes_driver_name[];
72extern char fjes_driver_version[];
73extern const u32 fjes_support_mtu[];
74
75void fjes_set_ethtool_ops(struct net_device *);
76
77#endif /* FJES_H_ */
diff --git a/drivers/net/fjes/fjes_ethtool.c b/drivers/net/fjes/fjes_ethtool.c
new file mode 100644
index 000000000000..0119dd199276
--- /dev/null
+++ b/drivers/net/fjes/fjes_ethtool.c
@@ -0,0 +1,137 @@
1/*
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/* ethtool support for fjes */
23
24#include <linux/vmalloc.h>
25#include <linux/netdevice.h>
26#include <linux/ethtool.h>
27#include <linux/platform_device.h>
28
29#include "fjes.h"
30
31struct fjes_stats {
32 char stat_string[ETH_GSTRING_LEN];
33 int sizeof_stat;
34 int stat_offset;
35};
36
37#define FJES_STAT(name, stat) { \
38 .stat_string = name, \
39 .sizeof_stat = FIELD_SIZEOF(struct fjes_adapter, stat), \
40 .stat_offset = offsetof(struct fjes_adapter, stat) \
41}
42
43static const struct fjes_stats fjes_gstrings_stats[] = {
44 FJES_STAT("rx_packets", stats64.rx_packets),
45 FJES_STAT("tx_packets", stats64.tx_packets),
46 FJES_STAT("rx_bytes", stats64.rx_bytes),
47 FJES_STAT("tx_bytes", stats64.rx_bytes),
48 FJES_STAT("rx_dropped", stats64.rx_dropped),
49 FJES_STAT("tx_dropped", stats64.tx_dropped),
50};
51
52static void fjes_get_ethtool_stats(struct net_device *netdev,
53 struct ethtool_stats *stats, u64 *data)
54{
55 struct fjes_adapter *adapter = netdev_priv(netdev);
56 char *p;
57 int i;
58
59 for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++) {
60 p = (char *)adapter + fjes_gstrings_stats[i].stat_offset;
61 data[i] = (fjes_gstrings_stats[i].sizeof_stat == sizeof(u64))
62 ? *(u64 *)p : *(u32 *)p;
63 }
64}
65
66static void fjes_get_strings(struct net_device *netdev,
67 u32 stringset, u8 *data)
68{
69 u8 *p = data;
70 int i;
71
72 switch (stringset) {
73 case ETH_SS_STATS:
74 for (i = 0; i < ARRAY_SIZE(fjes_gstrings_stats); i++) {
75 memcpy(p, fjes_gstrings_stats[i].stat_string,
76 ETH_GSTRING_LEN);
77 p += ETH_GSTRING_LEN;
78 }
79 break;
80 }
81}
82
83static int fjes_get_sset_count(struct net_device *netdev, int sset)
84{
85 switch (sset) {
86 case ETH_SS_STATS:
87 return ARRAY_SIZE(fjes_gstrings_stats);
88 default:
89 return -EOPNOTSUPP;
90 }
91}
92
93static void fjes_get_drvinfo(struct net_device *netdev,
94 struct ethtool_drvinfo *drvinfo)
95{
96 struct fjes_adapter *adapter = netdev_priv(netdev);
97 struct platform_device *plat_dev;
98
99 plat_dev = adapter->plat_dev;
100
101 strlcpy(drvinfo->driver, fjes_driver_name, sizeof(drvinfo->driver));
102 strlcpy(drvinfo->version, fjes_driver_version,
103 sizeof(drvinfo->version));
104
105 strlcpy(drvinfo->fw_version, "none", sizeof(drvinfo->fw_version));
106 snprintf(drvinfo->bus_info, sizeof(drvinfo->bus_info),
107 "platform:%s", plat_dev->name);
108 drvinfo->regdump_len = 0;
109 drvinfo->eedump_len = 0;
110}
111
112static int fjes_get_settings(struct net_device *netdev,
113 struct ethtool_cmd *ecmd)
114{
115 ecmd->supported = 0;
116 ecmd->advertising = 0;
117 ecmd->duplex = DUPLEX_FULL;
118 ecmd->autoneg = AUTONEG_DISABLE;
119 ecmd->transceiver = XCVR_DUMMY1;
120 ecmd->port = PORT_NONE;
121 ethtool_cmd_speed_set(ecmd, 20000); /* 20Gb/s */
122
123 return 0;
124}
125
126static const struct ethtool_ops fjes_ethtool_ops = {
127 .get_settings = fjes_get_settings,
128 .get_drvinfo = fjes_get_drvinfo,
129 .get_ethtool_stats = fjes_get_ethtool_stats,
130 .get_strings = fjes_get_strings,
131 .get_sset_count = fjes_get_sset_count,
132};
133
134void fjes_set_ethtool_ops(struct net_device *netdev)
135{
136 netdev->ethtool_ops = &fjes_ethtool_ops;
137}
diff --git a/drivers/net/fjes/fjes_hw.c b/drivers/net/fjes/fjes_hw.c
new file mode 100644
index 000000000000..b5f4a78da828
--- /dev/null
+++ b/drivers/net/fjes/fjes_hw.c
@@ -0,0 +1,1125 @@
1/*
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 "fjes_hw.h"
23#include "fjes.h"
24
25static void fjes_hw_update_zone_task(struct work_struct *);
26static void fjes_hw_epstop_task(struct work_struct *);
27
28/* supported MTU list */
29const u32 fjes_support_mtu[] = {
30 FJES_MTU_DEFINE(8 * 1024),
31 FJES_MTU_DEFINE(16 * 1024),
32 FJES_MTU_DEFINE(32 * 1024),
33 FJES_MTU_DEFINE(64 * 1024),
34 0
35};
36
37u32 fjes_hw_rd32(struct fjes_hw *hw, u32 reg)
38{
39 u8 *base = hw->base;
40 u32 value = 0;
41
42 value = readl(&base[reg]);
43
44 return value;
45}
46
47static u8 *fjes_hw_iomap(struct fjes_hw *hw)
48{
49 u8 *base;
50
51 if (!request_mem_region(hw->hw_res.start, hw->hw_res.size,
52 fjes_driver_name)) {
53 pr_err("request_mem_region failed\n");
54 return NULL;
55 }
56
57 base = (u8 *)ioremap_nocache(hw->hw_res.start, hw->hw_res.size);
58
59 return base;
60}
61
62static void fjes_hw_iounmap(struct fjes_hw *hw)
63{
64 iounmap(hw->base);
65 release_mem_region(hw->hw_res.start, hw->hw_res.size);
66}
67
68int fjes_hw_reset(struct fjes_hw *hw)
69{
70 union REG_DCTL dctl;
71 int timeout;
72
73 dctl.reg = 0;
74 dctl.bits.reset = 1;
75 wr32(XSCT_DCTL, dctl.reg);
76
77 timeout = FJES_DEVICE_RESET_TIMEOUT * 1000;
78 dctl.reg = rd32(XSCT_DCTL);
79 while ((dctl.bits.reset == 1) && (timeout > 0)) {
80 msleep(1000);
81 dctl.reg = rd32(XSCT_DCTL);
82 timeout -= 1000;
83 }
84
85 return timeout > 0 ? 0 : -EIO;
86}
87
88static int fjes_hw_get_max_epid(struct fjes_hw *hw)
89{
90 union REG_MAX_EP info;
91
92 info.reg = rd32(XSCT_MAX_EP);
93
94 return info.bits.maxep;
95}
96
97static int fjes_hw_get_my_epid(struct fjes_hw *hw)
98{
99 union REG_OWNER_EPID info;
100
101 info.reg = rd32(XSCT_OWNER_EPID);
102
103 return info.bits.epid;
104}
105
106static int fjes_hw_alloc_shared_status_region(struct fjes_hw *hw)
107{
108 size_t size;
109
110 size = sizeof(struct fjes_device_shared_info) +
111 (sizeof(u8) * hw->max_epid);
112 hw->hw_info.share = kzalloc(size, GFP_KERNEL);
113 if (!hw->hw_info.share)
114 return -ENOMEM;
115
116 hw->hw_info.share->epnum = hw->max_epid;
117
118 return 0;
119}
120
121static void fjes_hw_free_shared_status_region(struct fjes_hw *hw)
122{
123 kfree(hw->hw_info.share);
124 hw->hw_info.share = NULL;
125}
126
127static int fjes_hw_alloc_epbuf(struct epbuf_handler *epbh)
128{
129 void *mem;
130
131 mem = vzalloc(EP_BUFFER_SIZE);
132 if (!mem)
133 return -ENOMEM;
134
135 epbh->buffer = mem;
136 epbh->size = EP_BUFFER_SIZE;
137
138 epbh->info = (union ep_buffer_info *)mem;
139 epbh->ring = (u8 *)(mem + sizeof(union ep_buffer_info));
140
141 return 0;
142}
143
144static void fjes_hw_free_epbuf(struct epbuf_handler *epbh)
145{
146 if (epbh->buffer)
147 vfree(epbh->buffer);
148
149 epbh->buffer = NULL;
150 epbh->size = 0;
151
152 epbh->info = NULL;
153 epbh->ring = NULL;
154}
155
156void fjes_hw_setup_epbuf(struct epbuf_handler *epbh, u8 *mac_addr, u32 mtu)
157{
158 union ep_buffer_info *info = epbh->info;
159 u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX];
160 int i;
161
162 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
163 vlan_id[i] = info->v1i.vlan_id[i];
164
165 memset(info, 0, sizeof(union ep_buffer_info));
166
167 info->v1i.version = 0; /* version 0 */
168
169 for (i = 0; i < ETH_ALEN; i++)
170 info->v1i.mac_addr[i] = mac_addr[i];
171
172 info->v1i.head = 0;
173 info->v1i.tail = 1;
174
175 info->v1i.info_size = sizeof(union ep_buffer_info);
176 info->v1i.buffer_size = epbh->size - info->v1i.info_size;
177
178 info->v1i.frame_max = FJES_MTU_TO_FRAME_SIZE(mtu);
179 info->v1i.count_max =
180 EP_RING_NUM(info->v1i.buffer_size, info->v1i.frame_max);
181
182 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++)
183 info->v1i.vlan_id[i] = vlan_id[i];
184}
185
186void
187fjes_hw_init_command_registers(struct fjes_hw *hw,
188 struct fjes_device_command_param *param)
189{
190 /* Request Buffer length */
191 wr32(XSCT_REQBL, (__le32)(param->req_len));
192 /* Response Buffer Length */
193 wr32(XSCT_RESPBL, (__le32)(param->res_len));
194
195 /* Request Buffer Address */
196 wr32(XSCT_REQBAL,
197 (__le32)(param->req_start & GENMASK_ULL(31, 0)));
198 wr32(XSCT_REQBAH,
199 (__le32)((param->req_start & GENMASK_ULL(63, 32)) >> 32));
200
201 /* Response Buffer Address */
202 wr32(XSCT_RESPBAL,
203 (__le32)(param->res_start & GENMASK_ULL(31, 0)));
204 wr32(XSCT_RESPBAH,
205 (__le32)((param->res_start & GENMASK_ULL(63, 32)) >> 32));
206
207 /* Share status address */
208 wr32(XSCT_SHSTSAL,
209 (__le32)(param->share_start & GENMASK_ULL(31, 0)));
210 wr32(XSCT_SHSTSAH,
211 (__le32)((param->share_start & GENMASK_ULL(63, 32)) >> 32));
212}
213
214static int fjes_hw_setup(struct fjes_hw *hw)
215{
216 u8 mac[ETH_ALEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
217 struct fjes_device_command_param param;
218 struct ep_share_mem_info *buf_pair;
219 size_t mem_size;
220 int result;
221 int epidx;
222 void *buf;
223
224 hw->hw_info.max_epid = &hw->max_epid;
225 hw->hw_info.my_epid = &hw->my_epid;
226
227 buf = kcalloc(hw->max_epid, sizeof(struct ep_share_mem_info),
228 GFP_KERNEL);
229 if (!buf)
230 return -ENOMEM;
231
232 hw->ep_shm_info = (struct ep_share_mem_info *)buf;
233
234 mem_size = FJES_DEV_REQ_BUF_SIZE(hw->max_epid);
235 hw->hw_info.req_buf = kzalloc(mem_size, GFP_KERNEL);
236 if (!(hw->hw_info.req_buf))
237 return -ENOMEM;
238
239 hw->hw_info.req_buf_size = mem_size;
240
241 mem_size = FJES_DEV_RES_BUF_SIZE(hw->max_epid);
242 hw->hw_info.res_buf = kzalloc(mem_size, GFP_KERNEL);
243 if (!(hw->hw_info.res_buf))
244 return -ENOMEM;
245
246 hw->hw_info.res_buf_size = mem_size;
247
248 result = fjes_hw_alloc_shared_status_region(hw);
249 if (result)
250 return result;
251
252 hw->hw_info.buffer_share_bit = 0;
253 hw->hw_info.buffer_unshare_reserve_bit = 0;
254
255 for (epidx = 0; epidx < hw->max_epid; epidx++) {
256 if (epidx != hw->my_epid) {
257 buf_pair = &hw->ep_shm_info[epidx];
258
259 result = fjes_hw_alloc_epbuf(&buf_pair->tx);
260 if (result)
261 return result;
262
263 result = fjes_hw_alloc_epbuf(&buf_pair->rx);
264 if (result)
265 return result;
266
267 fjes_hw_setup_epbuf(&buf_pair->tx, mac,
268 fjes_support_mtu[0]);
269 fjes_hw_setup_epbuf(&buf_pair->rx, mac,
270 fjes_support_mtu[0]);
271 }
272 }
273
274 memset(&param, 0, sizeof(param));
275
276 param.req_len = hw->hw_info.req_buf_size;
277 param.req_start = __pa(hw->hw_info.req_buf);
278 param.res_len = hw->hw_info.res_buf_size;
279 param.res_start = __pa(hw->hw_info.res_buf);
280
281 param.share_start = __pa(hw->hw_info.share->ep_status);
282
283 fjes_hw_init_command_registers(hw, &param);
284
285 return 0;
286}
287
288static void fjes_hw_cleanup(struct fjes_hw *hw)
289{
290 int epidx;
291
292 if (!hw->ep_shm_info)
293 return;
294
295 fjes_hw_free_shared_status_region(hw);
296
297 kfree(hw->hw_info.req_buf);
298 hw->hw_info.req_buf = NULL;
299
300 kfree(hw->hw_info.res_buf);
301 hw->hw_info.res_buf = NULL;
302
303 for (epidx = 0; epidx < hw->max_epid ; epidx++) {
304 if (epidx == hw->my_epid)
305 continue;
306 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].tx);
307 fjes_hw_free_epbuf(&hw->ep_shm_info[epidx].rx);
308 }
309
310 kfree(hw->ep_shm_info);
311 hw->ep_shm_info = NULL;
312}
313
314int fjes_hw_init(struct fjes_hw *hw)
315{
316 int ret;
317
318 hw->base = fjes_hw_iomap(hw);
319 if (!hw->base)
320 return -EIO;
321
322 ret = fjes_hw_reset(hw);
323 if (ret)
324 return ret;
325
326 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
327
328 INIT_WORK(&hw->update_zone_task, fjes_hw_update_zone_task);
329 INIT_WORK(&hw->epstop_task, fjes_hw_epstop_task);
330
331 mutex_init(&hw->hw_info.lock);
332
333 hw->max_epid = fjes_hw_get_max_epid(hw);
334 hw->my_epid = fjes_hw_get_my_epid(hw);
335
336 if ((hw->max_epid == 0) || (hw->my_epid >= hw->max_epid))
337 return -ENXIO;
338
339 ret = fjes_hw_setup(hw);
340
341 return ret;
342}
343
344void fjes_hw_exit(struct fjes_hw *hw)
345{
346 int ret;
347
348 if (hw->base) {
349 ret = fjes_hw_reset(hw);
350 if (ret)
351 pr_err("%s: reset error", __func__);
352
353 fjes_hw_iounmap(hw);
354 hw->base = NULL;
355 }
356
357 fjes_hw_cleanup(hw);
358
359 cancel_work_sync(&hw->update_zone_task);
360 cancel_work_sync(&hw->epstop_task);
361}
362
363static enum fjes_dev_command_response_e
364fjes_hw_issue_request_command(struct fjes_hw *hw,
365 enum fjes_dev_command_request_type type)
366{
367 enum fjes_dev_command_response_e ret = FJES_CMD_STATUS_UNKNOWN;
368 union REG_CR cr;
369 union REG_CS cs;
370 int timeout;
371
372 cr.reg = 0;
373 cr.bits.req_start = 1;
374 cr.bits.req_code = type;
375 wr32(XSCT_CR, cr.reg);
376 cr.reg = rd32(XSCT_CR);
377
378 if (cr.bits.error == 0) {
379 timeout = FJES_COMMAND_REQ_TIMEOUT * 1000;
380 cs.reg = rd32(XSCT_CS);
381
382 while ((cs.bits.complete != 1) && timeout > 0) {
383 msleep(1000);
384 cs.reg = rd32(XSCT_CS);
385 timeout -= 1000;
386 }
387
388 if (cs.bits.complete == 1)
389 ret = FJES_CMD_STATUS_NORMAL;
390 else if (timeout <= 0)
391 ret = FJES_CMD_STATUS_TIMEOUT;
392
393 } else {
394 switch (cr.bits.err_info) {
395 case FJES_CMD_REQ_ERR_INFO_PARAM:
396 ret = FJES_CMD_STATUS_ERROR_PARAM;
397 break;
398 case FJES_CMD_REQ_ERR_INFO_STATUS:
399 ret = FJES_CMD_STATUS_ERROR_STATUS;
400 break;
401 default:
402 ret = FJES_CMD_STATUS_UNKNOWN;
403 break;
404 }
405 }
406
407 return ret;
408}
409
410int fjes_hw_request_info(struct fjes_hw *hw)
411{
412 union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
413 union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
414 enum fjes_dev_command_response_e ret;
415 int result;
416
417 memset(req_buf, 0, hw->hw_info.req_buf_size);
418 memset(res_buf, 0, hw->hw_info.res_buf_size);
419
420 req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN;
421
422 res_buf->info.length = 0;
423 res_buf->info.code = 0;
424
425 ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO);
426
427 result = 0;
428
429 if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) !=
430 res_buf->info.length) {
431 result = -ENOMSG;
432 } else if (ret == FJES_CMD_STATUS_NORMAL) {
433 switch (res_buf->info.code) {
434 case FJES_CMD_REQ_RES_CODE_NORMAL:
435 result = 0;
436 break;
437 default:
438 result = -EPERM;
439 break;
440 }
441 } else {
442 switch (ret) {
443 case FJES_CMD_STATUS_UNKNOWN:
444 result = -EPERM;
445 break;
446 case FJES_CMD_STATUS_TIMEOUT:
447 result = -EBUSY;
448 break;
449 case FJES_CMD_STATUS_ERROR_PARAM:
450 result = -EPERM;
451 break;
452 case FJES_CMD_STATUS_ERROR_STATUS:
453 result = -EPERM;
454 break;
455 default:
456 result = -EPERM;
457 break;
458 }
459 }
460
461 return result;
462}
463
464int fjes_hw_register_buff_addr(struct fjes_hw *hw, int dest_epid,
465 struct ep_share_mem_info *buf_pair)
466{
467 union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
468 union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
469 enum fjes_dev_command_response_e ret;
470 int page_count;
471 int timeout;
472 int i, idx;
473 void *addr;
474 int result;
475
476 if (test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
477 return 0;
478
479 memset(req_buf, 0, hw->hw_info.req_buf_size);
480 memset(res_buf, 0, hw->hw_info.res_buf_size);
481
482 req_buf->share_buffer.length = FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(
483 buf_pair->tx.size,
484 buf_pair->rx.size);
485 req_buf->share_buffer.epid = dest_epid;
486
487 idx = 0;
488 req_buf->share_buffer.buffer[idx++] = buf_pair->tx.size;
489 page_count = buf_pair->tx.size / EP_BUFFER_INFO_SIZE;
490 for (i = 0; i < page_count; i++) {
491 addr = ((u8 *)(buf_pair->tx.buffer)) +
492 (i * EP_BUFFER_INFO_SIZE);
493 req_buf->share_buffer.buffer[idx++] =
494 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
495 offset_in_page(addr));
496 }
497
498 req_buf->share_buffer.buffer[idx++] = buf_pair->rx.size;
499 page_count = buf_pair->rx.size / EP_BUFFER_INFO_SIZE;
500 for (i = 0; i < page_count; i++) {
501 addr = ((u8 *)(buf_pair->rx.buffer)) +
502 (i * EP_BUFFER_INFO_SIZE);
503 req_buf->share_buffer.buffer[idx++] =
504 (__le64)(page_to_phys(vmalloc_to_page(addr)) +
505 offset_in_page(addr));
506 }
507
508 res_buf->share_buffer.length = 0;
509 res_buf->share_buffer.code = 0;
510
511 ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_SHARE_BUFFER);
512
513 timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
514 while ((ret == FJES_CMD_STATUS_NORMAL) &&
515 (res_buf->share_buffer.length ==
516 FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN) &&
517 (res_buf->share_buffer.code == FJES_CMD_REQ_RES_CODE_BUSY) &&
518 (timeout > 0)) {
519 msleep(200 + hw->my_epid * 20);
520 timeout -= (200 + hw->my_epid * 20);
521
522 res_buf->share_buffer.length = 0;
523 res_buf->share_buffer.code = 0;
524
525 ret = fjes_hw_issue_request_command(
526 hw, FJES_CMD_REQ_SHARE_BUFFER);
527 }
528
529 result = 0;
530
531 if (res_buf->share_buffer.length !=
532 FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN)
533 result = -ENOMSG;
534 else if (ret == FJES_CMD_STATUS_NORMAL) {
535 switch (res_buf->share_buffer.code) {
536 case FJES_CMD_REQ_RES_CODE_NORMAL:
537 result = 0;
538 set_bit(dest_epid, &hw->hw_info.buffer_share_bit);
539 break;
540 case FJES_CMD_REQ_RES_CODE_BUSY:
541 result = -EBUSY;
542 break;
543 default:
544 result = -EPERM;
545 break;
546 }
547 } else {
548 switch (ret) {
549 case FJES_CMD_STATUS_UNKNOWN:
550 result = -EPERM;
551 break;
552 case FJES_CMD_STATUS_TIMEOUT:
553 result = -EBUSY;
554 break;
555 case FJES_CMD_STATUS_ERROR_PARAM:
556 case FJES_CMD_STATUS_ERROR_STATUS:
557 default:
558 result = -EPERM;
559 break;
560 }
561 }
562
563 return result;
564}
565
566int fjes_hw_unregister_buff_addr(struct fjes_hw *hw, int dest_epid)
567{
568 union fjes_device_command_req *req_buf = hw->hw_info.req_buf;
569 union fjes_device_command_res *res_buf = hw->hw_info.res_buf;
570 struct fjes_device_shared_info *share = hw->hw_info.share;
571 enum fjes_dev_command_response_e ret;
572 int timeout;
573 int result;
574
575 if (!hw->base)
576 return -EPERM;
577
578 if (!req_buf || !res_buf || !share)
579 return -EPERM;
580
581 if (!test_bit(dest_epid, &hw->hw_info.buffer_share_bit))
582 return 0;
583
584 memset(req_buf, 0, hw->hw_info.req_buf_size);
585 memset(res_buf, 0, hw->hw_info.res_buf_size);
586
587 req_buf->unshare_buffer.length =
588 FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN;
589 req_buf->unshare_buffer.epid = dest_epid;
590
591 res_buf->unshare_buffer.length = 0;
592 res_buf->unshare_buffer.code = 0;
593
594 ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
595
596 timeout = FJES_COMMAND_REQ_BUFF_TIMEOUT * 1000;
597 while ((ret == FJES_CMD_STATUS_NORMAL) &&
598 (res_buf->unshare_buffer.length ==
599 FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) &&
600 (res_buf->unshare_buffer.code ==
601 FJES_CMD_REQ_RES_CODE_BUSY) &&
602 (timeout > 0)) {
603 msleep(200 + hw->my_epid * 20);
604 timeout -= (200 + hw->my_epid * 20);
605
606 res_buf->unshare_buffer.length = 0;
607 res_buf->unshare_buffer.code = 0;
608
609 ret =
610 fjes_hw_issue_request_command(hw, FJES_CMD_REQ_UNSHARE_BUFFER);
611 }
612
613 result = 0;
614
615 if (res_buf->unshare_buffer.length !=
616 FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN) {
617 result = -ENOMSG;
618 } else if (ret == FJES_CMD_STATUS_NORMAL) {
619 switch (res_buf->unshare_buffer.code) {
620 case FJES_CMD_REQ_RES_CODE_NORMAL:
621 result = 0;
622 clear_bit(dest_epid, &hw->hw_info.buffer_share_bit);
623 break;
624 case FJES_CMD_REQ_RES_CODE_BUSY:
625 result = -EBUSY;
626 break;
627 default:
628 result = -EPERM;
629 break;
630 }
631 } else {
632 switch (ret) {
633 case FJES_CMD_STATUS_UNKNOWN:
634 result = -EPERM;
635 break;
636 case FJES_CMD_STATUS_TIMEOUT:
637 result = -EBUSY;
638 break;
639 case FJES_CMD_STATUS_ERROR_PARAM:
640 case FJES_CMD_STATUS_ERROR_STATUS:
641 default:
642 result = -EPERM;
643 break;
644 }
645 }
646
647 return result;
648}
649
650int fjes_hw_raise_interrupt(struct fjes_hw *hw, int dest_epid,
651 enum REG_ICTL_MASK mask)
652{
653 u32 ig = mask | dest_epid;
654
655 wr32(XSCT_IG, cpu_to_le32(ig));
656
657 return 0;
658}
659
660u32 fjes_hw_capture_interrupt_status(struct fjes_hw *hw)
661{
662 u32 cur_is;
663
664 cur_is = rd32(XSCT_IS);
665
666 return cur_is;
667}
668
669void fjes_hw_set_irqmask(struct fjes_hw *hw,
670 enum REG_ICTL_MASK intr_mask, bool mask)
671{
672 if (mask)
673 wr32(XSCT_IMS, intr_mask);
674 else
675 wr32(XSCT_IMC, intr_mask);
676}
677
678bool fjes_hw_epid_is_same_zone(struct fjes_hw *hw, int epid)
679{
680 if (epid >= hw->max_epid)
681 return false;
682
683 if ((hw->ep_shm_info[epid].es_status !=
684 FJES_ZONING_STATUS_ENABLE) ||
685 (hw->ep_shm_info[hw->my_epid].zone ==
686 FJES_ZONING_ZONE_TYPE_NONE))
687 return false;
688 else
689 return (hw->ep_shm_info[epid].zone ==
690 hw->ep_shm_info[hw->my_epid].zone);
691}
692
693int fjes_hw_epid_is_shared(struct fjes_device_shared_info *share,
694 int dest_epid)
695{
696 int value = false;
697
698 if (dest_epid < share->epnum)
699 value = share->ep_status[dest_epid];
700
701 return value;
702}
703
704static bool fjes_hw_epid_is_stop_requested(struct fjes_hw *hw, int src_epid)
705{
706 return test_bit(src_epid, &hw->txrx_stop_req_bit);
707}
708
709static bool fjes_hw_epid_is_stop_process_done(struct fjes_hw *hw, int src_epid)
710{
711 return (hw->ep_shm_info[src_epid].tx.info->v1i.rx_status &
712 FJES_RX_STOP_REQ_DONE);
713}
714
715enum ep_partner_status
716fjes_hw_get_partner_ep_status(struct fjes_hw *hw, int epid)
717{
718 enum ep_partner_status status;
719
720 if (fjes_hw_epid_is_shared(hw->hw_info.share, epid)) {
721 if (fjes_hw_epid_is_stop_requested(hw, epid)) {
722 status = EP_PARTNER_WAITING;
723 } else {
724 if (fjes_hw_epid_is_stop_process_done(hw, epid))
725 status = EP_PARTNER_COMPLETE;
726 else
727 status = EP_PARTNER_SHARED;
728 }
729 } else {
730 status = EP_PARTNER_UNSHARE;
731 }
732
733 return status;
734}
735
736void fjes_hw_raise_epstop(struct fjes_hw *hw)
737{
738 enum ep_partner_status status;
739 int epidx;
740
741 for (epidx = 0; epidx < hw->max_epid; epidx++) {
742 if (epidx == hw->my_epid)
743 continue;
744
745 status = fjes_hw_get_partner_ep_status(hw, epidx);
746 switch (status) {
747 case EP_PARTNER_SHARED:
748 fjes_hw_raise_interrupt(hw, epidx,
749 REG_ICTL_MASK_TXRX_STOP_REQ);
750 break;
751 default:
752 break;
753 }
754
755 set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
756 set_bit(epidx, &hw->txrx_stop_req_bit);
757
758 hw->ep_shm_info[epidx].tx.info->v1i.rx_status |=
759 FJES_RX_STOP_REQ_REQUEST;
760 }
761}
762
763int fjes_hw_wait_epstop(struct fjes_hw *hw)
764{
765 enum ep_partner_status status;
766 union ep_buffer_info *info;
767 int wait_time = 0;
768 int epidx;
769
770 while (hw->hw_info.buffer_unshare_reserve_bit &&
771 (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)) {
772 for (epidx = 0; epidx < hw->max_epid; epidx++) {
773 if (epidx == hw->my_epid)
774 continue;
775 status = fjes_hw_epid_is_shared(hw->hw_info.share,
776 epidx);
777 info = hw->ep_shm_info[epidx].rx.info;
778 if ((!status ||
779 (info->v1i.rx_status &
780 FJES_RX_STOP_REQ_DONE)) &&
781 test_bit(epidx,
782 &hw->hw_info.buffer_unshare_reserve_bit)) {
783 clear_bit(epidx,
784 &hw->hw_info.buffer_unshare_reserve_bit);
785 }
786 }
787
788 msleep(100);
789 wait_time += 100;
790 }
791
792 for (epidx = 0; epidx < hw->max_epid; epidx++) {
793 if (epidx == hw->my_epid)
794 continue;
795 if (test_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit))
796 clear_bit(epidx,
797 &hw->hw_info.buffer_unshare_reserve_bit);
798 }
799
800 return (wait_time < FJES_COMMAND_EPSTOP_WAIT_TIMEOUT * 1000)
801 ? 0 : -EBUSY;
802}
803
804bool fjes_hw_check_epbuf_version(struct epbuf_handler *epbh, u32 version)
805{
806 union ep_buffer_info *info = epbh->info;
807
808 return (info->common.version == version);
809}
810
811bool fjes_hw_check_mtu(struct epbuf_handler *epbh, u32 mtu)
812{
813 union ep_buffer_info *info = epbh->info;
814
815 return (info->v1i.frame_max == FJES_MTU_TO_FRAME_SIZE(mtu));
816}
817
818bool fjes_hw_check_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
819{
820 union ep_buffer_info *info = epbh->info;
821 bool ret = false;
822 int i;
823
824 if (vlan_id == 0) {
825 ret = true;
826 } else {
827 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
828 if (vlan_id == info->v1i.vlan_id[i]) {
829 ret = true;
830 break;
831 }
832 }
833 }
834 return ret;
835}
836
837bool fjes_hw_set_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
838{
839 union ep_buffer_info *info = epbh->info;
840 int i;
841
842 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
843 if (info->v1i.vlan_id[i] == 0) {
844 info->v1i.vlan_id[i] = vlan_id;
845 return true;
846 }
847 }
848 return false;
849}
850
851void fjes_hw_del_vlan_id(struct epbuf_handler *epbh, u16 vlan_id)
852{
853 union ep_buffer_info *info = epbh->info;
854 int i;
855
856 if (0 != vlan_id) {
857 for (i = 0; i < EP_BUFFER_SUPPORT_VLAN_MAX; i++) {
858 if (vlan_id == info->v1i.vlan_id[i])
859 info->v1i.vlan_id[i] = 0;
860 }
861 }
862}
863
864bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *epbh)
865{
866 union ep_buffer_info *info = epbh->info;
867
868 if (info->v1i.count_max == 0)
869 return true;
870
871 return EP_RING_EMPTY(info->v1i.head, info->v1i.tail,
872 info->v1i.count_max);
873}
874
875void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *epbh,
876 size_t *psize)
877{
878 union ep_buffer_info *info = epbh->info;
879 struct esmem_frame *ring_frame;
880 void *frame;
881
882 ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
883 (info->v1i.head,
884 info->v1i.count_max) *
885 info->v1i.frame_max]);
886
887 *psize = (size_t)ring_frame->frame_size;
888
889 frame = ring_frame->frame_data;
890
891 return frame;
892}
893
894void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *epbh)
895{
896 union ep_buffer_info *info = epbh->info;
897
898 if (fjes_hw_epbuf_rx_is_empty(epbh))
899 return;
900
901 EP_RING_INDEX_INC(epbh->info->v1i.head, info->v1i.count_max);
902}
903
904int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *epbh,
905 void *frame, size_t size)
906{
907 union ep_buffer_info *info = epbh->info;
908 struct esmem_frame *ring_frame;
909
910 if (EP_RING_FULL(info->v1i.head, info->v1i.tail, info->v1i.count_max))
911 return -ENOBUFS;
912
913 ring_frame = (struct esmem_frame *)&(epbh->ring[EP_RING_INDEX
914 (info->v1i.tail - 1,
915 info->v1i.count_max) *
916 info->v1i.frame_max]);
917
918 ring_frame->frame_size = size;
919 memcpy((void *)(ring_frame->frame_data), (void *)frame, size);
920
921 EP_RING_INDEX_INC(epbh->info->v1i.tail, info->v1i.count_max);
922
923 return 0;
924}
925
926static void fjes_hw_update_zone_task(struct work_struct *work)
927{
928 struct fjes_hw *hw = container_of(work,
929 struct fjes_hw, update_zone_task);
930
931 struct my_s {u8 es_status; u8 zone; } *info;
932 union fjes_device_command_res *res_buf;
933 enum ep_partner_status pstatus;
934
935 struct fjes_adapter *adapter;
936 struct net_device *netdev;
937
938 ulong unshare_bit = 0;
939 ulong share_bit = 0;
940 ulong irq_bit = 0;
941
942 int epidx;
943 int ret;
944
945 adapter = (struct fjes_adapter *)hw->back;
946 netdev = adapter->netdev;
947 res_buf = hw->hw_info.res_buf;
948 info = (struct my_s *)&res_buf->info.info;
949
950 mutex_lock(&hw->hw_info.lock);
951
952 ret = fjes_hw_request_info(hw);
953 switch (ret) {
954 case -ENOMSG:
955 case -EBUSY:
956 default:
957 if (!work_pending(&adapter->force_close_task)) {
958 adapter->force_reset = true;
959 schedule_work(&adapter->force_close_task);
960 }
961 break;
962
963 case 0:
964
965 for (epidx = 0; epidx < hw->max_epid; epidx++) {
966 if (epidx == hw->my_epid) {
967 hw->ep_shm_info[epidx].es_status =
968 info[epidx].es_status;
969 hw->ep_shm_info[epidx].zone =
970 info[epidx].zone;
971 continue;
972 }
973
974 pstatus = fjes_hw_get_partner_ep_status(hw, epidx);
975 switch (pstatus) {
976 case EP_PARTNER_UNSHARE:
977 default:
978 if ((info[epidx].zone !=
979 FJES_ZONING_ZONE_TYPE_NONE) &&
980 (info[epidx].es_status ==
981 FJES_ZONING_STATUS_ENABLE) &&
982 (info[epidx].zone ==
983 info[hw->my_epid].zone))
984 set_bit(epidx, &share_bit);
985 else
986 set_bit(epidx, &unshare_bit);
987 break;
988
989 case EP_PARTNER_COMPLETE:
990 case EP_PARTNER_WAITING:
991 if ((info[epidx].zone ==
992 FJES_ZONING_ZONE_TYPE_NONE) ||
993 (info[epidx].es_status !=
994 FJES_ZONING_STATUS_ENABLE) ||
995 (info[epidx].zone !=
996 info[hw->my_epid].zone)) {
997 set_bit(epidx,
998 &adapter->unshare_watch_bitmask);
999 set_bit(epidx,
1000 &hw->hw_info.buffer_unshare_reserve_bit);
1001 }
1002 break;
1003
1004 case EP_PARTNER_SHARED:
1005 if ((info[epidx].zone ==
1006 FJES_ZONING_ZONE_TYPE_NONE) ||
1007 (info[epidx].es_status !=
1008 FJES_ZONING_STATUS_ENABLE) ||
1009 (info[epidx].zone !=
1010 info[hw->my_epid].zone))
1011 set_bit(epidx, &irq_bit);
1012 break;
1013 }
1014 }
1015
1016 hw->ep_shm_info[epidx].es_status = info[epidx].es_status;
1017 hw->ep_shm_info[epidx].zone = info[epidx].zone;
1018
1019 break;
1020 }
1021
1022 mutex_unlock(&hw->hw_info.lock);
1023
1024 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1025 if (epidx == hw->my_epid)
1026 continue;
1027
1028 if (test_bit(epidx, &share_bit)) {
1029 fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
1030 netdev->dev_addr, netdev->mtu);
1031
1032 mutex_lock(&hw->hw_info.lock);
1033
1034 ret = fjes_hw_register_buff_addr(
1035 hw, epidx, &hw->ep_shm_info[epidx]);
1036
1037 switch (ret) {
1038 case 0:
1039 break;
1040 case -ENOMSG:
1041 case -EBUSY:
1042 default:
1043 if (!work_pending(&adapter->force_close_task)) {
1044 adapter->force_reset = true;
1045 schedule_work(
1046 &adapter->force_close_task);
1047 }
1048 break;
1049 }
1050 mutex_unlock(&hw->hw_info.lock);
1051 }
1052
1053 if (test_bit(epidx, &unshare_bit)) {
1054 mutex_lock(&hw->hw_info.lock);
1055
1056 ret = fjes_hw_unregister_buff_addr(hw, epidx);
1057
1058 switch (ret) {
1059 case 0:
1060 break;
1061 case -ENOMSG:
1062 case -EBUSY:
1063 default:
1064 if (!work_pending(&adapter->force_close_task)) {
1065 adapter->force_reset = true;
1066 schedule_work(
1067 &adapter->force_close_task);
1068 }
1069 break;
1070 }
1071
1072 mutex_unlock(&hw->hw_info.lock);
1073
1074 if (ret == 0)
1075 fjes_hw_setup_epbuf(
1076 &hw->ep_shm_info[epidx].tx,
1077 netdev->dev_addr, netdev->mtu);
1078 }
1079
1080 if (test_bit(epidx, &irq_bit)) {
1081 fjes_hw_raise_interrupt(hw, epidx,
1082 REG_ICTL_MASK_TXRX_STOP_REQ);
1083
1084 set_bit(epidx, &hw->txrx_stop_req_bit);
1085 hw->ep_shm_info[epidx].tx.
1086 info->v1i.rx_status |=
1087 FJES_RX_STOP_REQ_REQUEST;
1088 set_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
1089 }
1090 }
1091
1092 if (irq_bit || adapter->unshare_watch_bitmask) {
1093 if (!work_pending(&adapter->unshare_watch_task))
1094 queue_work(adapter->control_wq,
1095 &adapter->unshare_watch_task);
1096 }
1097}
1098
1099static void fjes_hw_epstop_task(struct work_struct *work)
1100{
1101 struct fjes_hw *hw = container_of(work, struct fjes_hw, epstop_task);
1102 struct fjes_adapter *adapter = (struct fjes_adapter *)hw->back;
1103
1104 ulong remain_bit;
1105 int epid_bit;
1106
1107 while ((remain_bit = hw->epstop_req_bit)) {
1108 for (epid_bit = 0; remain_bit; remain_bit >>= 1, epid_bit++) {
1109 if (remain_bit & 1) {
1110 hw->ep_shm_info[epid_bit].
1111 tx.info->v1i.rx_status |=
1112 FJES_RX_STOP_REQ_DONE;
1113
1114 clear_bit(epid_bit, &hw->epstop_req_bit);
1115 set_bit(epid_bit,
1116 &adapter->unshare_watch_bitmask);
1117
1118 if (!work_pending(&adapter->unshare_watch_task))
1119 queue_work(
1120 adapter->control_wq,
1121 &adapter->unshare_watch_task);
1122 }
1123 }
1124 }
1125}
diff --git a/drivers/net/fjes/fjes_hw.h b/drivers/net/fjes/fjes_hw.h
new file mode 100644
index 000000000000..6d57b89a0ee8
--- /dev/null
+++ b/drivers/net/fjes/fjes_hw.h
@@ -0,0 +1,334 @@
1/*
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#ifndef FJES_HW_H_
23#define FJES_HW_H_
24
25#include <linux/netdevice.h>
26#include <linux/if_vlan.h>
27#include <linux/vmalloc.h>
28
29#include "fjes_regs.h"
30
31struct fjes_hw;
32
33#define EP_BUFFER_SUPPORT_VLAN_MAX 4
34#define EP_BUFFER_INFO_SIZE 4096
35
36#define FJES_DEVICE_RESET_TIMEOUT ((17 + 1) * 3) /* sec */
37#define FJES_COMMAND_REQ_TIMEOUT (5 + 1) /* sec */
38#define FJES_COMMAND_REQ_BUFF_TIMEOUT (8 * 3) /* sec */
39#define FJES_COMMAND_EPSTOP_WAIT_TIMEOUT (1) /* sec */
40
41#define FJES_CMD_REQ_ERR_INFO_PARAM (0x0001)
42#define FJES_CMD_REQ_ERR_INFO_STATUS (0x0002)
43
44#define FJES_CMD_REQ_RES_CODE_NORMAL (0)
45#define FJES_CMD_REQ_RES_CODE_BUSY (1)
46
47#define FJES_ZONING_STATUS_DISABLE (0x00)
48#define FJES_ZONING_STATUS_ENABLE (0x01)
49#define FJES_ZONING_STATUS_INVALID (0xFF)
50
51#define FJES_ZONING_ZONE_TYPE_NONE (0xFF)
52
53#define FJES_TX_DELAY_SEND_NONE (0)
54#define FJES_TX_DELAY_SEND_PENDING (1)
55
56#define FJES_RX_STOP_REQ_NONE (0x0)
57#define FJES_RX_STOP_REQ_DONE (0x1)
58#define FJES_RX_STOP_REQ_REQUEST (0x2)
59#define FJES_RX_POLL_WORK (0x4)
60
61#define EP_BUFFER_SIZE \
62 (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \
63 / EP_BUFFER_INFO_SIZE) * EP_BUFFER_INFO_SIZE)
64
65#define EP_RING_NUM(buffer_size, frame_size) \
66 (u32)((buffer_size) / (frame_size))
67#define EP_RING_INDEX(_num, _max) (((_num) + (_max)) % (_max))
68#define EP_RING_INDEX_INC(_num, _max) \
69 ((_num) = EP_RING_INDEX((_num) + 1, (_max)))
70#define EP_RING_FULL(_head, _tail, _max) \
71 (0 == EP_RING_INDEX(((_tail) - (_head)), (_max)))
72#define EP_RING_EMPTY(_head, _tail, _max) \
73 (1 == EP_RING_INDEX(((_tail) - (_head)), (_max)))
74
75#define FJES_MTU_TO_BUFFER_SIZE(mtu) \
76 (ETH_HLEN + VLAN_HLEN + (mtu) + ETH_FCS_LEN)
77#define FJES_MTU_TO_FRAME_SIZE(mtu) \
78 (sizeof(struct esmem_frame) + FJES_MTU_TO_BUFFER_SIZE(mtu))
79#define FJES_MTU_DEFINE(size) \
80 ((size) - sizeof(struct esmem_frame) - \
81 (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN))
82
83#define FJES_DEV_COMMAND_INFO_REQ_LEN (4)
84#define FJES_DEV_COMMAND_INFO_RES_LEN(epnum) (8 + 2 * (epnum))
85#define FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(txb, rxb) \
86 (24 + (8 * ((txb) / EP_BUFFER_INFO_SIZE + (rxb) / EP_BUFFER_INFO_SIZE)))
87#define FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN (8)
88#define FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN (8)
89#define FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN (8)
90
91#define FJES_DEV_REQ_BUF_SIZE(maxep) \
92 FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(EP_BUFFER_SIZE, EP_BUFFER_SIZE)
93#define FJES_DEV_RES_BUF_SIZE(maxep) \
94 FJES_DEV_COMMAND_INFO_RES_LEN(maxep)
95
96/* Frame & MTU */
97struct esmem_frame {
98 __le32 frame_size;
99 u8 frame_data[];
100};
101
102/* EP partner status */
103enum ep_partner_status {
104 EP_PARTNER_UNSHARE,
105 EP_PARTNER_SHARED,
106 EP_PARTNER_WAITING,
107 EP_PARTNER_COMPLETE,
108 EP_PARTNER_STATUS_MAX,
109};
110
111/* shared status region */
112struct fjes_device_shared_info {
113 int epnum;
114 u8 ep_status[];
115};
116
117/* structures for command control request data*/
118union fjes_device_command_req {
119 struct {
120 __le32 length;
121 } info;
122 struct {
123 __le32 length;
124 __le32 epid;
125 __le64 buffer[];
126 } share_buffer;
127 struct {
128 __le32 length;
129 __le32 epid;
130 } unshare_buffer;
131 struct {
132 __le32 length;
133 __le32 mode;
134 __le64 buffer_len;
135 __le64 buffer[];
136 } start_trace;
137 struct {
138 __le32 length;
139 } stop_trace;
140};
141
142/* structures for command control response data */
143union fjes_device_command_res {
144 struct {
145 __le32 length;
146 __le32 code;
147 struct {
148 u8 es_status;
149 u8 zone;
150 } info[];
151 } info;
152 struct {
153 __le32 length;
154 __le32 code;
155 } share_buffer;
156 struct {
157 __le32 length;
158 __le32 code;
159 } unshare_buffer;
160 struct {
161 __le32 length;
162 __le32 code;
163 } start_trace;
164 struct {
165 __le32 length;
166 __le32 code;
167 } stop_trace;
168};
169
170/* request command type */
171enum fjes_dev_command_request_type {
172 FJES_CMD_REQ_INFO = 0x0001,
173 FJES_CMD_REQ_SHARE_BUFFER = 0x0002,
174 FJES_CMD_REQ_UNSHARE_BUFFER = 0x0004,
175};
176
177/* parameter for command control */
178struct fjes_device_command_param {
179 u32 req_len;
180 phys_addr_t req_start;
181 u32 res_len;
182 phys_addr_t res_start;
183 phys_addr_t share_start;
184};
185
186/* error code for command control */
187enum fjes_dev_command_response_e {
188 FJES_CMD_STATUS_UNKNOWN,
189 FJES_CMD_STATUS_NORMAL,
190 FJES_CMD_STATUS_TIMEOUT,
191 FJES_CMD_STATUS_ERROR_PARAM,
192 FJES_CMD_STATUS_ERROR_STATUS,
193};
194
195/* EP buffer information */
196union ep_buffer_info {
197 u8 raw[EP_BUFFER_INFO_SIZE];
198
199 struct _ep_buffer_info_common_t {
200 u32 version;
201 } common;
202
203 struct _ep_buffer_info_v1_t {
204 u32 version;
205 u32 info_size;
206
207 u32 buffer_size;
208 u16 count_max;
209
210 u16 _rsv_1;
211
212 u32 frame_max;
213 u8 mac_addr[ETH_ALEN];
214
215 u16 _rsv_2;
216 u32 _rsv_3;
217
218 u16 tx_status;
219 u16 rx_status;
220
221 u32 head;
222 u32 tail;
223
224 u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX];
225
226 } v1i;
227
228};
229
230/* buffer pair for Extended Partition */
231struct ep_share_mem_info {
232 struct epbuf_handler {
233 void *buffer;
234 size_t size;
235 union ep_buffer_info *info;
236 u8 *ring;
237 } tx, rx;
238
239 struct rtnl_link_stats64 net_stats;
240
241 u16 tx_status_work;
242
243 u8 es_status;
244 u8 zone;
245};
246
247struct es_device_trace {
248 u32 record_num;
249 u32 current_record;
250 u32 status_flag;
251 u32 _rsv;
252
253 struct {
254 u16 epid;
255 u16 dir_offset;
256 u32 data;
257 u64 tsc;
258 } record[];
259};
260
261struct fjes_hw_info {
262 struct fjes_device_shared_info *share;
263 union fjes_device_command_req *req_buf;
264 u64 req_buf_size;
265 union fjes_device_command_res *res_buf;
266 u64 res_buf_size;
267
268 int *my_epid;
269 int *max_epid;
270
271 struct es_device_trace *trace;
272 u64 trace_size;
273
274 struct mutex lock; /* buffer lock*/
275
276 unsigned long buffer_share_bit;
277 unsigned long buffer_unshare_reserve_bit;
278};
279
280struct fjes_hw {
281 void *back;
282
283 unsigned long txrx_stop_req_bit;
284 unsigned long epstop_req_bit;
285 struct work_struct update_zone_task;
286 struct work_struct epstop_task;
287
288 int my_epid;
289 int max_epid;
290
291 struct ep_share_mem_info *ep_shm_info;
292
293 struct fjes_hw_resource {
294 u64 start;
295 u64 size;
296 int irq;
297 } hw_res;
298
299 u8 *base;
300
301 struct fjes_hw_info hw_info;
302};
303
304int fjes_hw_init(struct fjes_hw *);
305void fjes_hw_exit(struct fjes_hw *);
306int fjes_hw_reset(struct fjes_hw *);
307int fjes_hw_request_info(struct fjes_hw *);
308int fjes_hw_register_buff_addr(struct fjes_hw *, int,
309 struct ep_share_mem_info *);
310int fjes_hw_unregister_buff_addr(struct fjes_hw *, int);
311void fjes_hw_init_command_registers(struct fjes_hw *,
312 struct fjes_device_command_param *);
313void fjes_hw_setup_epbuf(struct epbuf_handler *, u8 *, u32);
314int fjes_hw_raise_interrupt(struct fjes_hw *, int, enum REG_ICTL_MASK);
315void fjes_hw_set_irqmask(struct fjes_hw *, enum REG_ICTL_MASK, bool);
316u32 fjes_hw_capture_interrupt_status(struct fjes_hw *);
317void fjes_hw_raise_epstop(struct fjes_hw *);
318int fjes_hw_wait_epstop(struct fjes_hw *);
319enum ep_partner_status
320 fjes_hw_get_partner_ep_status(struct fjes_hw *, int);
321
322bool fjes_hw_epid_is_same_zone(struct fjes_hw *, int);
323int fjes_hw_epid_is_shared(struct fjes_device_shared_info *, int);
324bool fjes_hw_check_epbuf_version(struct epbuf_handler *, u32);
325bool fjes_hw_check_mtu(struct epbuf_handler *, u32);
326bool fjes_hw_check_vlan_id(struct epbuf_handler *, u16);
327bool fjes_hw_set_vlan_id(struct epbuf_handler *, u16);
328void fjes_hw_del_vlan_id(struct epbuf_handler *, u16);
329bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *);
330void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *, size_t *);
331void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *);
332int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *, void *, size_t);
333
334#endif /* FJES_HW_H_ */
diff --git a/drivers/net/fjes/fjes_main.c b/drivers/net/fjes/fjes_main.c
new file mode 100644
index 000000000000..0ddb54fe3d91
--- /dev/null
+++ b/drivers/net/fjes/fjes_main.c
@@ -0,0 +1,1383 @@
1/*
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>
26#include <linux/netdevice.h>
27#include <linux/interrupt.h>
28
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
47static 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 *);
54static netdev_tx_t fjes_xmit_frame(struct sk_buff *, struct net_device *);
55static void fjes_raise_intr_rxdata_task(struct work_struct *);
56static void fjes_tx_stall_task(struct work_struct *);
57static void fjes_force_close_task(struct work_struct *);
58static irqreturn_t fjes_intr(int, void*);
59static struct rtnl_link_stats64 *
60fjes_get_stats64(struct net_device *, struct rtnl_link_stats64 *);
61static int fjes_change_mtu(struct net_device *, int);
62static 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);
64static void fjes_tx_retry(struct net_device *);
65
66static 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
73static int fjes_sw_init(struct fjes_adapter *);
74static void fjes_netdev_setup(struct net_device *);
75static void fjes_irq_watch_task(struct work_struct *);
76static void fjes_watch_unshare_task(struct work_struct *);
77static void fjes_rx_irq(struct fjes_adapter *, int);
78static int fjes_poll(struct napi_struct *, int);
79
80static const struct acpi_device_id fjes_acpi_ids[] = {
81 {"PNP0C02", 0},
82 {"", 0},
83};
84MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids);
85
86static struct acpi_driver fjes_acpi_driver = {
87 .name = DRV_NAME,
88 .class = DRV_NAME,
89 .owner = THIS_MODULE,
90 .ids = fjes_acpi_ids,
91 .ops = {
92 .add = fjes_acpi_add,
93 .remove = fjes_acpi_remove,
94 },
95};
96
97static struct platform_driver fjes_driver = {
98 .driver = {
99 .name = DRV_NAME,
100 .owner = THIS_MODULE,
101 },
102 .probe = fjes_probe,
103 .remove = fjes_remove,
104};
105
106static struct resource fjes_resource[] = {
107 {
108 .flags = IORESOURCE_MEM,
109 .start = 0,
110 .end = 0,
111 },
112 {
113 .flags = IORESOURCE_IRQ,
114 .start = 0,
115 .end = 0,
116 },
117};
118
119static int fjes_acpi_add(struct acpi_device *device)
120{
121 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
122 char str_buf[sizeof(FJES_ACPI_SYMBOL) + 1];
123 struct platform_device *plat_dev;
124 union acpi_object *str;
125 acpi_status status;
126 int result;
127
128 status = acpi_evaluate_object(device->handle, "_STR", NULL, &buffer);
129 if (ACPI_FAILURE(status))
130 return -ENODEV;
131
132 str = buffer.pointer;
133 result = utf16s_to_utf8s((wchar_t *)str->string.pointer,
134 str->string.length, UTF16_LITTLE_ENDIAN,
135 str_buf, sizeof(str_buf) - 1);
136 str_buf[result] = 0;
137
138 if (strncmp(FJES_ACPI_SYMBOL, str_buf, strlen(FJES_ACPI_SYMBOL)) != 0) {
139 kfree(buffer.pointer);
140 return -ENODEV;
141 }
142 kfree(buffer.pointer);
143
144 status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
145 fjes_get_acpi_resource, fjes_resource);
146 if (ACPI_FAILURE(status))
147 return -ENODEV;
148
149 /* create platform_device */
150 plat_dev = platform_device_register_simple(DRV_NAME, 0, fjes_resource,
151 ARRAY_SIZE(fjes_resource));
152 device->driver_data = plat_dev;
153
154 return 0;
155}
156
157static int fjes_acpi_remove(struct acpi_device *device)
158{
159 struct platform_device *plat_dev;
160
161 plat_dev = (struct platform_device *)acpi_driver_data(device);
162 platform_device_unregister(plat_dev);
163
164 return 0;
165}
166
167static acpi_status
168fjes_get_acpi_resource(struct acpi_resource *acpi_res, void *data)
169{
170 struct acpi_resource_address32 *addr;
171 struct acpi_resource_irq *irq;
172 struct resource *res = data;
173
174 switch (acpi_res->type) {
175 case ACPI_RESOURCE_TYPE_ADDRESS32:
176 addr = &acpi_res->data.address32;
177 res[0].start = addr->address.minimum;
178 res[0].end = addr->address.minimum +
179 addr->address.address_length - 1;
180 break;
181
182 case ACPI_RESOURCE_TYPE_IRQ:
183 irq = &acpi_res->data.irq;
184 if (irq->interrupt_count != 1)
185 return AE_ERROR;
186 res[1].start = irq->interrupts[0];
187 res[1].end = irq->interrupts[0];
188 break;
189
190 default:
191 break;
192 }
193
194 return AE_OK;
195}
196
197static int fjes_request_irq(struct fjes_adapter *adapter)
198{
199 struct net_device *netdev = adapter->netdev;
200 int result = -1;
201
202 adapter->interrupt_watch_enable = true;
203 if (!delayed_work_pending(&adapter->interrupt_watch_task)) {
204 queue_delayed_work(adapter->control_wq,
205 &adapter->interrupt_watch_task,
206 FJES_IRQ_WATCH_DELAY);
207 }
208
209 if (!adapter->irq_registered) {
210 result = request_irq(adapter->hw.hw_res.irq, fjes_intr,
211 IRQF_SHARED, netdev->name, adapter);
212 if (result)
213 adapter->irq_registered = false;
214 else
215 adapter->irq_registered = true;
216 }
217
218 return result;
219}
220
221static void fjes_free_irq(struct fjes_adapter *adapter)
222{
223 struct fjes_hw *hw = &adapter->hw;
224
225 adapter->interrupt_watch_enable = false;
226 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
227
228 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, true);
229
230 if (adapter->irq_registered) {
231 free_irq(adapter->hw.hw_res.irq, adapter);
232 adapter->irq_registered = false;
233 }
234}
235
236static const struct net_device_ops fjes_netdev_ops = {
237 .ndo_open = fjes_open,
238 .ndo_stop = fjes_close,
239 .ndo_start_xmit = fjes_xmit_frame,
240 .ndo_get_stats64 = fjes_get_stats64,
241 .ndo_change_mtu = fjes_change_mtu,
242 .ndo_tx_timeout = fjes_tx_retry,
243 .ndo_vlan_rx_add_vid = fjes_vlan_rx_add_vid,
244 .ndo_vlan_rx_kill_vid = fjes_vlan_rx_kill_vid,
245};
246
247/* fjes_open - Called when a network interface is made active */
248static int fjes_open(struct net_device *netdev)
249{
250 struct fjes_adapter *adapter = netdev_priv(netdev);
251 struct fjes_hw *hw = &adapter->hw;
252 int result;
253
254 if (adapter->open_guard)
255 return -ENXIO;
256
257 result = fjes_setup_resources(adapter);
258 if (result)
259 goto err_setup_res;
260
261 hw->txrx_stop_req_bit = 0;
262 hw->epstop_req_bit = 0;
263
264 napi_enable(&adapter->napi);
265
266 fjes_hw_capture_interrupt_status(hw);
267
268 result = fjes_request_irq(adapter);
269 if (result)
270 goto err_req_irq;
271
272 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_ALL, false);
273
274 netif_tx_start_all_queues(netdev);
275 netif_carrier_on(netdev);
276
277 return 0;
278
279err_req_irq:
280 fjes_free_irq(adapter);
281 napi_disable(&adapter->napi);
282
283err_setup_res:
284 fjes_free_resources(adapter);
285 return result;
286}
287
288/* fjes_close - Disables a network interface */
289static int fjes_close(struct net_device *netdev)
290{
291 struct fjes_adapter *adapter = netdev_priv(netdev);
292 struct fjes_hw *hw = &adapter->hw;
293 int epidx;
294
295 netif_tx_stop_all_queues(netdev);
296 netif_carrier_off(netdev);
297
298 fjes_hw_raise_epstop(hw);
299
300 napi_disable(&adapter->napi);
301
302 for (epidx = 0; epidx < hw->max_epid; epidx++) {
303 if (epidx == hw->my_epid)
304 continue;
305
306 adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status &=
307 ~FJES_RX_POLL_WORK;
308 }
309
310 fjes_free_irq(adapter);
311
312 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
313 cancel_work_sync(&adapter->unshare_watch_task);
314 adapter->unshare_watch_bitmask = 0;
315 cancel_work_sync(&adapter->raise_intr_rxdata_task);
316 cancel_work_sync(&adapter->tx_stall_task);
317
318 cancel_work_sync(&hw->update_zone_task);
319 cancel_work_sync(&hw->epstop_task);
320
321 fjes_hw_wait_epstop(hw);
322
323 fjes_free_resources(adapter);
324
325 return 0;
326}
327
328static int fjes_setup_resources(struct fjes_adapter *adapter)
329{
330 struct net_device *netdev = adapter->netdev;
331 struct ep_share_mem_info *buf_pair;
332 struct fjes_hw *hw = &adapter->hw;
333 int result;
334 int epidx;
335
336 mutex_lock(&hw->hw_info.lock);
337 result = fjes_hw_request_info(hw);
338 switch (result) {
339 case 0:
340 for (epidx = 0; epidx < hw->max_epid; epidx++) {
341 hw->ep_shm_info[epidx].es_status =
342 hw->hw_info.res_buf->info.info[epidx].es_status;
343 hw->ep_shm_info[epidx].zone =
344 hw->hw_info.res_buf->info.info[epidx].zone;
345 }
346 break;
347 default:
348 case -ENOMSG:
349 case -EBUSY:
350 adapter->force_reset = true;
351
352 mutex_unlock(&hw->hw_info.lock);
353 return result;
354 }
355 mutex_unlock(&hw->hw_info.lock);
356
357 for (epidx = 0; epidx < (hw->max_epid); epidx++) {
358 if ((epidx != hw->my_epid) &&
359 (hw->ep_shm_info[epidx].es_status ==
360 FJES_ZONING_STATUS_ENABLE)) {
361 fjes_hw_raise_interrupt(hw, epidx,
362 REG_ICTL_MASK_INFO_UPDATE);
363 }
364 }
365
366 msleep(FJES_OPEN_ZONE_UPDATE_WAIT * hw->max_epid);
367
368 for (epidx = 0; epidx < (hw->max_epid); epidx++) {
369 if (epidx == hw->my_epid)
370 continue;
371
372 buf_pair = &hw->ep_shm_info[epidx];
373
374 fjes_hw_setup_epbuf(&buf_pair->tx, netdev->dev_addr,
375 netdev->mtu);
376
377 if (fjes_hw_epid_is_same_zone(hw, epidx)) {
378 mutex_lock(&hw->hw_info.lock);
379 result =
380 fjes_hw_register_buff_addr(hw, epidx, buf_pair);
381 mutex_unlock(&hw->hw_info.lock);
382
383 switch (result) {
384 case 0:
385 break;
386 case -ENOMSG:
387 case -EBUSY:
388 default:
389 adapter->force_reset = true;
390 return result;
391 }
392 }
393 }
394
395 return 0;
396}
397
398static void fjes_free_resources(struct fjes_adapter *adapter)
399{
400 struct net_device *netdev = adapter->netdev;
401 struct fjes_device_command_param param;
402 struct ep_share_mem_info *buf_pair;
403 struct fjes_hw *hw = &adapter->hw;
404 bool reset_flag = false;
405 int result;
406 int epidx;
407
408 for (epidx = 0; epidx < hw->max_epid; epidx++) {
409 if (epidx == hw->my_epid)
410 continue;
411
412 mutex_lock(&hw->hw_info.lock);
413 result = fjes_hw_unregister_buff_addr(hw, epidx);
414 mutex_unlock(&hw->hw_info.lock);
415
416 if (result)
417 reset_flag = true;
418
419 buf_pair = &hw->ep_shm_info[epidx];
420
421 fjes_hw_setup_epbuf(&buf_pair->tx,
422 netdev->dev_addr, netdev->mtu);
423
424 clear_bit(epidx, &hw->txrx_stop_req_bit);
425 }
426
427 if (reset_flag || adapter->force_reset) {
428 result = fjes_hw_reset(hw);
429
430 adapter->force_reset = false;
431
432 if (result)
433 adapter->open_guard = true;
434
435 hw->hw_info.buffer_share_bit = 0;
436
437 memset((void *)&param, 0, sizeof(param));
438
439 param.req_len = hw->hw_info.req_buf_size;
440 param.req_start = __pa(hw->hw_info.req_buf);
441 param.res_len = hw->hw_info.res_buf_size;
442 param.res_start = __pa(hw->hw_info.res_buf);
443 param.share_start = __pa(hw->hw_info.share->ep_status);
444
445 fjes_hw_init_command_registers(hw, &param);
446 }
447}
448
449static void fjes_tx_stall_task(struct work_struct *work)
450{
451 struct fjes_adapter *adapter = container_of(work,
452 struct fjes_adapter, tx_stall_task);
453 struct net_device *netdev = adapter->netdev;
454 struct fjes_hw *hw = &adapter->hw;
455 int all_queue_available, sendable;
456 enum ep_partner_status pstatus;
457 int max_epid, my_epid, epid;
458 union ep_buffer_info *info;
459 int i;
460
461 if (((long)jiffies -
462 (long)(netdev->trans_start)) > FJES_TX_TX_STALL_TIMEOUT) {
463 netif_wake_queue(netdev);
464 return;
465 }
466
467 my_epid = hw->my_epid;
468 max_epid = hw->max_epid;
469
470 for (i = 0; i < 5; i++) {
471 all_queue_available = 1;
472
473 for (epid = 0; epid < max_epid; epid++) {
474 if (my_epid == epid)
475 continue;
476
477 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
478 sendable = (pstatus == EP_PARTNER_SHARED);
479 if (!sendable)
480 continue;
481
482 info = adapter->hw.ep_shm_info[epid].tx.info;
483
484 if (EP_RING_FULL(info->v1i.head, info->v1i.tail,
485 info->v1i.count_max)) {
486 all_queue_available = 0;
487 break;
488 }
489 }
490
491 if (all_queue_available) {
492 netif_wake_queue(netdev);
493 return;
494 }
495 }
496
497 usleep_range(50, 100);
498
499 queue_work(adapter->txrx_wq, &adapter->tx_stall_task);
500}
501
502static void fjes_force_close_task(struct work_struct *work)
503{
504 struct fjes_adapter *adapter = container_of(work,
505 struct fjes_adapter, force_close_task);
506 struct net_device *netdev = adapter->netdev;
507
508 rtnl_lock();
509 dev_close(netdev);
510 rtnl_unlock();
511}
512
513static void fjes_raise_intr_rxdata_task(struct work_struct *work)
514{
515 struct fjes_adapter *adapter = container_of(work,
516 struct fjes_adapter, raise_intr_rxdata_task);
517 struct fjes_hw *hw = &adapter->hw;
518 enum ep_partner_status pstatus;
519 int max_epid, my_epid, epid;
520
521 my_epid = hw->my_epid;
522 max_epid = hw->max_epid;
523
524 for (epid = 0; epid < max_epid; epid++)
525 hw->ep_shm_info[epid].tx_status_work = 0;
526
527 for (epid = 0; epid < max_epid; epid++) {
528 if (epid == my_epid)
529 continue;
530
531 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
532 if (pstatus == EP_PARTNER_SHARED) {
533 hw->ep_shm_info[epid].tx_status_work =
534 hw->ep_shm_info[epid].tx.info->v1i.tx_status;
535
536 if (hw->ep_shm_info[epid].tx_status_work ==
537 FJES_TX_DELAY_SEND_PENDING) {
538 hw->ep_shm_info[epid].tx.info->v1i.tx_status =
539 FJES_TX_DELAY_SEND_NONE;
540 }
541 }
542 }
543
544 for (epid = 0; epid < max_epid; epid++) {
545 if (epid == my_epid)
546 continue;
547
548 pstatus = fjes_hw_get_partner_ep_status(hw, epid);
549 if ((hw->ep_shm_info[epid].tx_status_work ==
550 FJES_TX_DELAY_SEND_PENDING) &&
551 (pstatus == EP_PARTNER_SHARED) &&
552 !(hw->ep_shm_info[epid].rx.info->v1i.rx_status)) {
553 fjes_hw_raise_interrupt(hw, epid,
554 REG_ICTL_MASK_RX_DATA);
555 }
556 }
557
558 usleep_range(500, 1000);
559}
560
561static int fjes_tx_send(struct fjes_adapter *adapter, int dest,
562 void *data, size_t len)
563{
564 int retval;
565
566 retval = fjes_hw_epbuf_tx_pkt_send(&adapter->hw.ep_shm_info[dest].tx,
567 data, len);
568 if (retval)
569 return retval;
570
571 adapter->hw.ep_shm_info[dest].tx.info->v1i.tx_status =
572 FJES_TX_DELAY_SEND_PENDING;
573 if (!work_pending(&adapter->raise_intr_rxdata_task))
574 queue_work(adapter->txrx_wq,
575 &adapter->raise_intr_rxdata_task);
576
577 retval = 0;
578 return retval;
579}
580
581static netdev_tx_t
582fjes_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
583{
584 struct fjes_adapter *adapter = netdev_priv(netdev);
585 struct fjes_hw *hw = &adapter->hw;
586
587 int max_epid, my_epid, dest_epid;
588 enum ep_partner_status pstatus;
589 struct netdev_queue *cur_queue;
590 char shortpkt[VLAN_ETH_HLEN];
591 bool is_multi, vlan;
592 struct ethhdr *eth;
593 u16 queue_no = 0;
594 u16 vlan_id = 0;
595 netdev_tx_t ret;
596 char *data;
597 int len;
598
599 ret = NETDEV_TX_OK;
600 is_multi = false;
601 cur_queue = netdev_get_tx_queue(netdev, queue_no);
602
603 eth = (struct ethhdr *)skb->data;
604 my_epid = hw->my_epid;
605
606 vlan = (vlan_get_tag(skb, &vlan_id) == 0) ? true : false;
607
608 data = skb->data;
609 len = skb->len;
610
611 if (is_multicast_ether_addr(eth->h_dest)) {
612 dest_epid = 0;
613 max_epid = hw->max_epid;
614 is_multi = true;
615 } else if (is_local_ether_addr(eth->h_dest)) {
616 dest_epid = eth->h_dest[ETH_ALEN - 1];
617 max_epid = dest_epid + 1;
618
619 if ((eth->h_dest[0] == 0x02) &&
620 (0x00 == (eth->h_dest[1] | eth->h_dest[2] |
621 eth->h_dest[3] | eth->h_dest[4])) &&
622 (dest_epid < hw->max_epid)) {
623 ;
624 } else {
625 dest_epid = 0;
626 max_epid = 0;
627 ret = NETDEV_TX_OK;
628
629 adapter->stats64.tx_packets += 1;
630 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
631 adapter->stats64.tx_bytes += len;
632 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
633 }
634 } else {
635 dest_epid = 0;
636 max_epid = 0;
637 ret = NETDEV_TX_OK;
638
639 adapter->stats64.tx_packets += 1;
640 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
641 adapter->stats64.tx_bytes += len;
642 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
643 }
644
645 for (; dest_epid < max_epid; dest_epid++) {
646 if (my_epid == dest_epid)
647 continue;
648
649 pstatus = fjes_hw_get_partner_ep_status(hw, dest_epid);
650 if (pstatus != EP_PARTNER_SHARED) {
651 ret = NETDEV_TX_OK;
652 } else if (!fjes_hw_check_epbuf_version(
653 &adapter->hw.ep_shm_info[dest_epid].rx, 0)) {
654 /* version is NOT 0 */
655 adapter->stats64.tx_carrier_errors += 1;
656 hw->ep_shm_info[my_epid].net_stats
657 .tx_carrier_errors += 1;
658
659 ret = NETDEV_TX_OK;
660 } else if (!fjes_hw_check_mtu(
661 &adapter->hw.ep_shm_info[dest_epid].rx,
662 netdev->mtu)) {
663 adapter->stats64.tx_dropped += 1;
664 hw->ep_shm_info[my_epid].net_stats.tx_dropped += 1;
665 adapter->stats64.tx_errors += 1;
666 hw->ep_shm_info[my_epid].net_stats.tx_errors += 1;
667
668 ret = NETDEV_TX_OK;
669 } else if (vlan &&
670 !fjes_hw_check_vlan_id(
671 &adapter->hw.ep_shm_info[dest_epid].rx,
672 vlan_id)) {
673 ret = NETDEV_TX_OK;
674 } else {
675 if (len < VLAN_ETH_HLEN) {
676 memset(shortpkt, 0, VLAN_ETH_HLEN);
677 memcpy(shortpkt, skb->data, skb->len);
678 len = VLAN_ETH_HLEN;
679 data = shortpkt;
680 }
681
682 if (adapter->tx_retry_count == 0) {
683 adapter->tx_start_jiffies = jiffies;
684 adapter->tx_retry_count = 1;
685 } else {
686 adapter->tx_retry_count++;
687 }
688
689 if (fjes_tx_send(adapter, dest_epid, data, len)) {
690 if (is_multi) {
691 ret = NETDEV_TX_OK;
692 } else if (
693 ((long)jiffies -
694 (long)adapter->tx_start_jiffies) >=
695 FJES_TX_RETRY_TIMEOUT) {
696 adapter->stats64.tx_fifo_errors += 1;
697 hw->ep_shm_info[my_epid].net_stats
698 .tx_fifo_errors += 1;
699 adapter->stats64.tx_errors += 1;
700 hw->ep_shm_info[my_epid].net_stats
701 .tx_errors += 1;
702
703 ret = NETDEV_TX_OK;
704 } else {
705 netdev->trans_start = jiffies;
706 netif_tx_stop_queue(cur_queue);
707
708 if (!work_pending(&adapter->tx_stall_task))
709 queue_work(adapter->txrx_wq,
710 &adapter->tx_stall_task);
711
712 ret = NETDEV_TX_BUSY;
713 }
714 } else {
715 if (!is_multi) {
716 adapter->stats64.tx_packets += 1;
717 hw->ep_shm_info[my_epid].net_stats
718 .tx_packets += 1;
719 adapter->stats64.tx_bytes += len;
720 hw->ep_shm_info[my_epid].net_stats
721 .tx_bytes += len;
722 }
723
724 adapter->tx_retry_count = 0;
725 ret = NETDEV_TX_OK;
726 }
727 }
728 }
729
730 if (ret == NETDEV_TX_OK) {
731 dev_kfree_skb(skb);
732 if (is_multi) {
733 adapter->stats64.tx_packets += 1;
734 hw->ep_shm_info[my_epid].net_stats.tx_packets += 1;
735 adapter->stats64.tx_bytes += 1;
736 hw->ep_shm_info[my_epid].net_stats.tx_bytes += len;
737 }
738 }
739
740 return ret;
741}
742
743static void fjes_tx_retry(struct net_device *netdev)
744{
745 struct netdev_queue *queue = netdev_get_tx_queue(netdev, 0);
746
747 netif_tx_wake_queue(queue);
748}
749
750static struct rtnl_link_stats64 *
751fjes_get_stats64(struct net_device *netdev, struct rtnl_link_stats64 *stats)
752{
753 struct fjes_adapter *adapter = netdev_priv(netdev);
754
755 memcpy(stats, &adapter->stats64, sizeof(struct rtnl_link_stats64));
756
757 return stats;
758}
759
760static int fjes_change_mtu(struct net_device *netdev, int new_mtu)
761{
762 bool running = netif_running(netdev);
763 int ret = 0;
764 int idx;
765
766 for (idx = 0; fjes_support_mtu[idx] != 0; idx++) {
767 if (new_mtu <= fjes_support_mtu[idx]) {
768 new_mtu = fjes_support_mtu[idx];
769 if (new_mtu == netdev->mtu)
770 return 0;
771
772 if (running)
773 fjes_close(netdev);
774
775 netdev->mtu = new_mtu;
776
777 if (running)
778 ret = fjes_open(netdev);
779
780 return ret;
781 }
782 }
783
784 return -EINVAL;
785}
786
787static int fjes_vlan_rx_add_vid(struct net_device *netdev,
788 __be16 proto, u16 vid)
789{
790 struct fjes_adapter *adapter = netdev_priv(netdev);
791 bool ret = true;
792 int epid;
793
794 for (epid = 0; epid < adapter->hw.max_epid; epid++) {
795 if (epid == adapter->hw.my_epid)
796 continue;
797
798 if (!fjes_hw_check_vlan_id(
799 &adapter->hw.ep_shm_info[epid].tx, vid))
800 ret = fjes_hw_set_vlan_id(
801 &adapter->hw.ep_shm_info[epid].tx, vid);
802 }
803
804 return ret ? 0 : -ENOSPC;
805}
806
807static int fjes_vlan_rx_kill_vid(struct net_device *netdev,
808 __be16 proto, u16 vid)
809{
810 struct fjes_adapter *adapter = netdev_priv(netdev);
811 int epid;
812
813 for (epid = 0; epid < adapter->hw.max_epid; epid++) {
814 if (epid == adapter->hw.my_epid)
815 continue;
816
817 fjes_hw_del_vlan_id(&adapter->hw.ep_shm_info[epid].tx, vid);
818 }
819
820 return 0;
821}
822
823static void fjes_txrx_stop_req_irq(struct fjes_adapter *adapter,
824 int src_epid)
825{
826 struct fjes_hw *hw = &adapter->hw;
827 enum ep_partner_status status;
828
829 status = fjes_hw_get_partner_ep_status(hw, src_epid);
830 switch (status) {
831 case EP_PARTNER_UNSHARE:
832 case EP_PARTNER_COMPLETE:
833 default:
834 break;
835 case EP_PARTNER_WAITING:
836 if (src_epid < hw->my_epid) {
837 hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
838 FJES_RX_STOP_REQ_DONE;
839
840 clear_bit(src_epid, &hw->txrx_stop_req_bit);
841 set_bit(src_epid, &adapter->unshare_watch_bitmask);
842
843 if (!work_pending(&adapter->unshare_watch_task))
844 queue_work(adapter->control_wq,
845 &adapter->unshare_watch_task);
846 }
847 break;
848 case EP_PARTNER_SHARED:
849 if (hw->ep_shm_info[src_epid].rx.info->v1i.rx_status &
850 FJES_RX_STOP_REQ_REQUEST) {
851 set_bit(src_epid, &hw->epstop_req_bit);
852 if (!work_pending(&hw->epstop_task))
853 queue_work(adapter->control_wq,
854 &hw->epstop_task);
855 }
856 break;
857 }
858}
859
860static void fjes_stop_req_irq(struct fjes_adapter *adapter, int src_epid)
861{
862 struct fjes_hw *hw = &adapter->hw;
863 enum ep_partner_status status;
864
865 set_bit(src_epid, &hw->hw_info.buffer_unshare_reserve_bit);
866
867 status = fjes_hw_get_partner_ep_status(hw, src_epid);
868 switch (status) {
869 case EP_PARTNER_WAITING:
870 hw->ep_shm_info[src_epid].tx.info->v1i.rx_status |=
871 FJES_RX_STOP_REQ_DONE;
872 clear_bit(src_epid, &hw->txrx_stop_req_bit);
873 /* fall through */
874 case EP_PARTNER_UNSHARE:
875 case EP_PARTNER_COMPLETE:
876 default:
877 set_bit(src_epid, &adapter->unshare_watch_bitmask);
878 if (!work_pending(&adapter->unshare_watch_task))
879 queue_work(adapter->control_wq,
880 &adapter->unshare_watch_task);
881 break;
882 case EP_PARTNER_SHARED:
883 set_bit(src_epid, &hw->epstop_req_bit);
884
885 if (!work_pending(&hw->epstop_task))
886 queue_work(adapter->control_wq, &hw->epstop_task);
887 break;
888 }
889}
890
891static void fjes_update_zone_irq(struct fjes_adapter *adapter,
892 int src_epid)
893{
894 struct fjes_hw *hw = &adapter->hw;
895
896 if (!work_pending(&hw->update_zone_task))
897 queue_work(adapter->control_wq, &hw->update_zone_task);
898}
899
900static irqreturn_t fjes_intr(int irq, void *data)
901{
902 struct fjes_adapter *adapter = data;
903 struct fjes_hw *hw = &adapter->hw;
904 irqreturn_t ret;
905 u32 icr;
906
907 icr = fjes_hw_capture_interrupt_status(hw);
908
909 if (icr & REG_IS_MASK_IS_ASSERT) {
910 if (icr & REG_ICTL_MASK_RX_DATA)
911 fjes_rx_irq(adapter, icr & REG_IS_MASK_EPID);
912
913 if (icr & REG_ICTL_MASK_DEV_STOP_REQ)
914 fjes_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
915
916 if (icr & REG_ICTL_MASK_TXRX_STOP_REQ)
917 fjes_txrx_stop_req_irq(adapter, icr & REG_IS_MASK_EPID);
918
919 if (icr & REG_ICTL_MASK_TXRX_STOP_DONE)
920 fjes_hw_set_irqmask(hw,
921 REG_ICTL_MASK_TXRX_STOP_DONE, true);
922
923 if (icr & REG_ICTL_MASK_INFO_UPDATE)
924 fjes_update_zone_irq(adapter, icr & REG_IS_MASK_EPID);
925
926 ret = IRQ_HANDLED;
927 } else {
928 ret = IRQ_NONE;
929 }
930
931 return ret;
932}
933
934static int fjes_rxframe_search_exist(struct fjes_adapter *adapter,
935 int start_epid)
936{
937 struct fjes_hw *hw = &adapter->hw;
938 enum ep_partner_status pstatus;
939 int max_epid, cur_epid;
940 int i;
941
942 max_epid = hw->max_epid;
943 start_epid = (start_epid + 1 + max_epid) % max_epid;
944
945 for (i = 0; i < max_epid; i++) {
946 cur_epid = (start_epid + i) % max_epid;
947 if (cur_epid == hw->my_epid)
948 continue;
949
950 pstatus = fjes_hw_get_partner_ep_status(hw, cur_epid);
951 if (pstatus == EP_PARTNER_SHARED) {
952 if (!fjes_hw_epbuf_rx_is_empty(
953 &hw->ep_shm_info[cur_epid].rx))
954 return cur_epid;
955 }
956 }
957 return -1;
958}
959
960static void *fjes_rxframe_get(struct fjes_adapter *adapter, size_t *psize,
961 int *cur_epid)
962{
963 void *frame;
964
965 *cur_epid = fjes_rxframe_search_exist(adapter, *cur_epid);
966 if (*cur_epid < 0)
967 return NULL;
968
969 frame =
970 fjes_hw_epbuf_rx_curpkt_get_addr(
971 &adapter->hw.ep_shm_info[*cur_epid].rx, psize);
972
973 return frame;
974}
975
976static void fjes_rxframe_release(struct fjes_adapter *adapter, int cur_epid)
977{
978 fjes_hw_epbuf_rx_curpkt_drop(&adapter->hw.ep_shm_info[cur_epid].rx);
979}
980
981static void fjes_rx_irq(struct fjes_adapter *adapter, int src_epid)
982{
983 struct fjes_hw *hw = &adapter->hw;
984
985 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, true);
986
987 adapter->unset_rx_last = true;
988 napi_schedule(&adapter->napi);
989}
990
991static int fjes_poll(struct napi_struct *napi, int budget)
992{
993 struct fjes_adapter *adapter =
994 container_of(napi, struct fjes_adapter, napi);
995 struct net_device *netdev = napi->dev;
996 struct fjes_hw *hw = &adapter->hw;
997 struct sk_buff *skb;
998 int work_done = 0;
999 int cur_epid = 0;
1000 int epidx;
1001 size_t frame_len;
1002 void *frame;
1003
1004 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1005 if (epidx == hw->my_epid)
1006 continue;
1007
1008 adapter->hw.ep_shm_info[epidx].tx.info->v1i.rx_status |=
1009 FJES_RX_POLL_WORK;
1010 }
1011
1012 while (work_done < budget) {
1013 prefetch(&adapter->hw);
1014 frame = fjes_rxframe_get(adapter, &frame_len, &cur_epid);
1015
1016 if (frame) {
1017 skb = napi_alloc_skb(napi, frame_len);
1018 if (!skb) {
1019 adapter->stats64.rx_dropped += 1;
1020 hw->ep_shm_info[cur_epid].net_stats
1021 .rx_dropped += 1;
1022 adapter->stats64.rx_errors += 1;
1023 hw->ep_shm_info[cur_epid].net_stats
1024 .rx_errors += 1;
1025 } else {
1026 memcpy(skb_put(skb, frame_len),
1027 frame, frame_len);
1028 skb->protocol = eth_type_trans(skb, netdev);
1029 skb->ip_summed = CHECKSUM_UNNECESSARY;
1030
1031 netif_receive_skb(skb);
1032
1033 work_done++;
1034
1035 adapter->stats64.rx_packets += 1;
1036 hw->ep_shm_info[cur_epid].net_stats
1037 .rx_packets += 1;
1038 adapter->stats64.rx_bytes += frame_len;
1039 hw->ep_shm_info[cur_epid].net_stats
1040 .rx_bytes += frame_len;
1041
1042 if (is_multicast_ether_addr(
1043 ((struct ethhdr *)frame)->h_dest)) {
1044 adapter->stats64.multicast += 1;
1045 hw->ep_shm_info[cur_epid].net_stats
1046 .multicast += 1;
1047 }
1048 }
1049
1050 fjes_rxframe_release(adapter, cur_epid);
1051 adapter->unset_rx_last = true;
1052 } else {
1053 break;
1054 }
1055 }
1056
1057 if (work_done < budget) {
1058 napi_complete(napi);
1059
1060 if (adapter->unset_rx_last) {
1061 adapter->rx_last_jiffies = jiffies;
1062 adapter->unset_rx_last = false;
1063 }
1064
1065 if (((long)jiffies - (long)adapter->rx_last_jiffies) < 3) {
1066 napi_reschedule(napi);
1067 } else {
1068 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1069 if (epidx == hw->my_epid)
1070 continue;
1071 adapter->hw.ep_shm_info[epidx]
1072 .tx.info->v1i.rx_status &=
1073 ~FJES_RX_POLL_WORK;
1074 }
1075
1076 fjes_hw_set_irqmask(hw, REG_ICTL_MASK_RX_DATA, false);
1077 }
1078 }
1079
1080 return work_done;
1081}
1082
1083/* fjes_probe - Device Initialization Routine */
1084static int fjes_probe(struct platform_device *plat_dev)
1085{
1086 struct fjes_adapter *adapter;
1087 struct net_device *netdev;
1088 struct resource *res;
1089 struct fjes_hw *hw;
1090 int err;
1091
1092 err = -ENOMEM;
1093 netdev = alloc_netdev_mq(sizeof(struct fjes_adapter), "es%d",
1094 NET_NAME_UNKNOWN, fjes_netdev_setup,
1095 FJES_MAX_QUEUES);
1096
1097 if (!netdev)
1098 goto err_out;
1099
1100 SET_NETDEV_DEV(netdev, &plat_dev->dev);
1101
1102 dev_set_drvdata(&plat_dev->dev, netdev);
1103 adapter = netdev_priv(netdev);
1104 adapter->netdev = netdev;
1105 adapter->plat_dev = plat_dev;
1106 hw = &adapter->hw;
1107 hw->back = adapter;
1108
1109 /* setup the private structure */
1110 err = fjes_sw_init(adapter);
1111 if (err)
1112 goto err_free_netdev;
1113
1114 INIT_WORK(&adapter->force_close_task, fjes_force_close_task);
1115 adapter->force_reset = false;
1116 adapter->open_guard = false;
1117
1118 adapter->txrx_wq = create_workqueue(DRV_NAME "/txrx");
1119 adapter->control_wq = create_workqueue(DRV_NAME "/control");
1120
1121 INIT_WORK(&adapter->tx_stall_task, fjes_tx_stall_task);
1122 INIT_WORK(&adapter->raise_intr_rxdata_task,
1123 fjes_raise_intr_rxdata_task);
1124 INIT_WORK(&adapter->unshare_watch_task, fjes_watch_unshare_task);
1125 adapter->unshare_watch_bitmask = 0;
1126
1127 INIT_DELAYED_WORK(&adapter->interrupt_watch_task, fjes_irq_watch_task);
1128 adapter->interrupt_watch_enable = false;
1129
1130 res = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
1131 hw->hw_res.start = res->start;
1132 hw->hw_res.size = res->end - res->start + 1;
1133 hw->hw_res.irq = platform_get_irq(plat_dev, 0);
1134 err = fjes_hw_init(&adapter->hw);
1135 if (err)
1136 goto err_free_netdev;
1137
1138 /* setup MAC address (02:00:00:00:00:[epid])*/
1139 netdev->dev_addr[0] = 2;
1140 netdev->dev_addr[1] = 0;
1141 netdev->dev_addr[2] = 0;
1142 netdev->dev_addr[3] = 0;
1143 netdev->dev_addr[4] = 0;
1144 netdev->dev_addr[5] = hw->my_epid; /* EPID */
1145
1146 err = register_netdev(netdev);
1147 if (err)
1148 goto err_hw_exit;
1149
1150 netif_carrier_off(netdev);
1151
1152 return 0;
1153
1154err_hw_exit:
1155 fjes_hw_exit(&adapter->hw);
1156err_free_netdev:
1157 free_netdev(netdev);
1158err_out:
1159 return err;
1160}
1161
1162/* fjes_remove - Device Removal Routine */
1163static int fjes_remove(struct platform_device *plat_dev)
1164{
1165 struct net_device *netdev = dev_get_drvdata(&plat_dev->dev);
1166 struct fjes_adapter *adapter = netdev_priv(netdev);
1167 struct fjes_hw *hw = &adapter->hw;
1168
1169 cancel_delayed_work_sync(&adapter->interrupt_watch_task);
1170 cancel_work_sync(&adapter->unshare_watch_task);
1171 cancel_work_sync(&adapter->raise_intr_rxdata_task);
1172 cancel_work_sync(&adapter->tx_stall_task);
1173 if (adapter->control_wq)
1174 destroy_workqueue(adapter->control_wq);
1175 if (adapter->txrx_wq)
1176 destroy_workqueue(adapter->txrx_wq);
1177
1178 unregister_netdev(netdev);
1179
1180 fjes_hw_exit(hw);
1181
1182 netif_napi_del(&adapter->napi);
1183
1184 free_netdev(netdev);
1185
1186 return 0;
1187}
1188
1189static int fjes_sw_init(struct fjes_adapter *adapter)
1190{
1191 struct net_device *netdev = adapter->netdev;
1192
1193 netif_napi_add(netdev, &adapter->napi, fjes_poll, 64);
1194
1195 return 0;
1196}
1197
1198/* fjes_netdev_setup - netdevice initialization routine */
1199static void fjes_netdev_setup(struct net_device *netdev)
1200{
1201 ether_setup(netdev);
1202
1203 netdev->watchdog_timeo = FJES_TX_RETRY_INTERVAL;
1204 netdev->netdev_ops = &fjes_netdev_ops;
1205 fjes_set_ethtool_ops(netdev);
1206 netdev->mtu = fjes_support_mtu[0];
1207 netdev->flags |= IFF_BROADCAST;
1208 netdev->features |= NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_CTAG_FILTER;
1209}
1210
1211static void fjes_irq_watch_task(struct work_struct *work)
1212{
1213 struct fjes_adapter *adapter = container_of(to_delayed_work(work),
1214 struct fjes_adapter, interrupt_watch_task);
1215
1216 local_irq_disable();
1217 fjes_intr(adapter->hw.hw_res.irq, adapter);
1218 local_irq_enable();
1219
1220 if (fjes_rxframe_search_exist(adapter, 0) >= 0)
1221 napi_schedule(&adapter->napi);
1222
1223 if (adapter->interrupt_watch_enable) {
1224 if (!delayed_work_pending(&adapter->interrupt_watch_task))
1225 queue_delayed_work(adapter->control_wq,
1226 &adapter->interrupt_watch_task,
1227 FJES_IRQ_WATCH_DELAY);
1228 }
1229}
1230
1231static void fjes_watch_unshare_task(struct work_struct *work)
1232{
1233 struct fjes_adapter *adapter =
1234 container_of(work, struct fjes_adapter, unshare_watch_task);
1235
1236 struct net_device *netdev = adapter->netdev;
1237 struct fjes_hw *hw = &adapter->hw;
1238
1239 int unshare_watch, unshare_reserve;
1240 int max_epid, my_epid, epidx;
1241 int stop_req, stop_req_done;
1242 ulong unshare_watch_bitmask;
1243 int wait_time = 0;
1244 int is_shared;
1245 int ret;
1246
1247 my_epid = hw->my_epid;
1248 max_epid = hw->max_epid;
1249
1250 unshare_watch_bitmask = adapter->unshare_watch_bitmask;
1251 adapter->unshare_watch_bitmask = 0;
1252
1253 while ((unshare_watch_bitmask || hw->txrx_stop_req_bit) &&
1254 (wait_time < 3000)) {
1255 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1256 if (epidx == hw->my_epid)
1257 continue;
1258
1259 is_shared = fjes_hw_epid_is_shared(hw->hw_info.share,
1260 epidx);
1261
1262 stop_req = test_bit(epidx, &hw->txrx_stop_req_bit);
1263
1264 stop_req_done = hw->ep_shm_info[epidx].rx.info->v1i.rx_status &
1265 FJES_RX_STOP_REQ_DONE;
1266
1267 unshare_watch = test_bit(epidx, &unshare_watch_bitmask);
1268
1269 unshare_reserve = test_bit(epidx,
1270 &hw->hw_info.buffer_unshare_reserve_bit);
1271
1272 if ((!stop_req ||
1273 (is_shared && (!is_shared || !stop_req_done))) &&
1274 (is_shared || !unshare_watch || !unshare_reserve))
1275 continue;
1276
1277 mutex_lock(&hw->hw_info.lock);
1278 ret = fjes_hw_unregister_buff_addr(hw, epidx);
1279 switch (ret) {
1280 case 0:
1281 break;
1282 case -ENOMSG:
1283 case -EBUSY:
1284 default:
1285 if (!work_pending(
1286 &adapter->force_close_task)) {
1287 adapter->force_reset = true;
1288 schedule_work(
1289 &adapter->force_close_task);
1290 }
1291 break;
1292 }
1293 mutex_unlock(&hw->hw_info.lock);
1294
1295 fjes_hw_setup_epbuf(&hw->ep_shm_info[epidx].tx,
1296 netdev->dev_addr, netdev->mtu);
1297
1298 clear_bit(epidx, &hw->txrx_stop_req_bit);
1299 clear_bit(epidx, &unshare_watch_bitmask);
1300 clear_bit(epidx,
1301 &hw->hw_info.buffer_unshare_reserve_bit);
1302 }
1303
1304 msleep(100);
1305 wait_time += 100;
1306 }
1307
1308 if (hw->hw_info.buffer_unshare_reserve_bit) {
1309 for (epidx = 0; epidx < hw->max_epid; epidx++) {
1310 if (epidx == hw->my_epid)
1311 continue;
1312
1313 if (test_bit(epidx,
1314 &hw->hw_info.buffer_unshare_reserve_bit)) {
1315 mutex_lock(&hw->hw_info.lock);
1316
1317 ret = fjes_hw_unregister_buff_addr(hw, epidx);
1318 switch (ret) {
1319 case 0:
1320 break;
1321 case -ENOMSG:
1322 case -EBUSY:
1323 default:
1324 if (!work_pending(
1325 &adapter->force_close_task)) {
1326 adapter->force_reset = true;
1327 schedule_work(
1328 &adapter->force_close_task);
1329 }
1330 break;
1331 }
1332 mutex_unlock(&hw->hw_info.lock);
1333
1334 fjes_hw_setup_epbuf(
1335 &hw->ep_shm_info[epidx].tx,
1336 netdev->dev_addr, netdev->mtu);
1337
1338 clear_bit(epidx, &hw->txrx_stop_req_bit);
1339 clear_bit(epidx, &unshare_watch_bitmask);
1340 clear_bit(epidx, &hw->hw_info.buffer_unshare_reserve_bit);
1341 }
1342
1343 if (test_bit(epidx, &unshare_watch_bitmask)) {
1344 hw->ep_shm_info[epidx].tx.info->v1i.rx_status &=
1345 ~FJES_RX_STOP_REQ_DONE;
1346 }
1347 }
1348 }
1349}
1350
1351/* fjes_init_module - Driver Registration Routine */
1352static int __init fjes_init_module(void)
1353{
1354 int result;
1355
1356 pr_info("%s - version %s - %s\n",
1357 fjes_driver_string, fjes_driver_version, fjes_copyright);
1358
1359 result = platform_driver_register(&fjes_driver);
1360 if (result < 0)
1361 return result;
1362
1363 result = acpi_bus_register_driver(&fjes_acpi_driver);
1364 if (result < 0)
1365 goto fail_acpi_driver;
1366
1367 return 0;
1368
1369fail_acpi_driver:
1370 platform_driver_unregister(&fjes_driver);
1371 return result;
1372}
1373
1374module_init(fjes_init_module);
1375
1376/* fjes_exit_module - Driver Exit Cleanup Routine */
1377static void __exit fjes_exit_module(void)
1378{
1379 acpi_bus_unregister_driver(&fjes_acpi_driver);
1380 platform_driver_unregister(&fjes_driver);
1381}
1382
1383module_exit(fjes_exit_module);
diff --git a/drivers/net/fjes/fjes_regs.h b/drivers/net/fjes/fjes_regs.h
new file mode 100644
index 000000000000..029c924dc175
--- /dev/null
+++ b/drivers/net/fjes/fjes_regs.h
@@ -0,0 +1,142 @@
1/*
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#ifndef FJES_REGS_H_
23#define FJES_REGS_H_
24
25#include <linux/bitops.h>
26
27#define XSCT_DEVICE_REGISTER_SIZE 0x1000
28
29/* register offset */
30/* Information registers */
31#define XSCT_OWNER_EPID 0x0000 /* Owner EPID */
32#define XSCT_MAX_EP 0x0004 /* Maximum EP */
33
34/* Device Control registers */
35#define XSCT_DCTL 0x0010 /* Device Control */
36
37/* Command Control registers */
38#define XSCT_CR 0x0020 /* Command request */
39#define XSCT_CS 0x0024 /* Command status */
40#define XSCT_SHSTSAL 0x0028 /* Share status address Low */
41#define XSCT_SHSTSAH 0x002C /* Share status address High */
42
43#define XSCT_REQBL 0x0034 /* Request Buffer length */
44#define XSCT_REQBAL 0x0038 /* Request Buffer Address Low */
45#define XSCT_REQBAH 0x003C /* Request Buffer Address High */
46
47#define XSCT_RESPBL 0x0044 /* Response Buffer Length */
48#define XSCT_RESPBAL 0x0048 /* Response Buffer Address Low */
49#define XSCT_RESPBAH 0x004C /* Response Buffer Address High */
50
51/* Interrupt Control registers */
52#define XSCT_IS 0x0080 /* Interrupt status */
53#define XSCT_IMS 0x0084 /* Interrupt mask set */
54#define XSCT_IMC 0x0088 /* Interrupt mask clear */
55#define XSCT_IG 0x008C /* Interrupt generator */
56#define XSCT_ICTL 0x0090 /* Interrupt control */
57
58/* register structure */
59/* Information registers */
60union REG_OWNER_EPID {
61 struct {
62 __le32 epid:16;
63 __le32:16;
64 } bits;
65 __le32 reg;
66};
67
68union REG_MAX_EP {
69 struct {
70 __le32 maxep:16;
71 __le32:16;
72 } bits;
73 __le32 reg;
74};
75
76/* Device Control registers */
77union REG_DCTL {
78 struct {
79 __le32 reset:1;
80 __le32 rsv0:15;
81 __le32 rsv1:16;
82 } bits;
83 __le32 reg;
84};
85
86/* Command Control registers */
87union REG_CR {
88 struct {
89 __le32 req_code:16;
90 __le32 err_info:14;
91 __le32 error:1;
92 __le32 req_start:1;
93 } bits;
94 __le32 reg;
95};
96
97union REG_CS {
98 struct {
99 __le32 req_code:16;
100 __le32 rsv0:14;
101 __le32 busy:1;
102 __le32 complete:1;
103 } bits;
104 __le32 reg;
105};
106
107/* Interrupt Control registers */
108union REG_ICTL {
109 struct {
110 __le32 automak:1;
111 __le32 rsv0:31;
112 } bits;
113 __le32 reg;
114};
115
116enum REG_ICTL_MASK {
117 REG_ICTL_MASK_INFO_UPDATE = 1 << 20,
118 REG_ICTL_MASK_DEV_STOP_REQ = 1 << 19,
119 REG_ICTL_MASK_TXRX_STOP_REQ = 1 << 18,
120 REG_ICTL_MASK_TXRX_STOP_DONE = 1 << 17,
121 REG_ICTL_MASK_RX_DATA = 1 << 16,
122 REG_ICTL_MASK_ALL = GENMASK(20, 16),
123};
124
125enum REG_IS_MASK {
126 REG_IS_MASK_IS_ASSERT = 1 << 31,
127 REG_IS_MASK_EPID = GENMASK(15, 0),
128};
129
130struct fjes_hw;
131
132u32 fjes_hw_rd32(struct fjes_hw *hw, u32 reg);
133
134#define wr32(reg, val) \
135do { \
136 u8 *base = hw->base; \
137 writel((val), &base[(reg)]); \
138} while (0)
139
140#define rd32(reg) (fjes_hw_rd32(hw, reg))
141
142#endif /* FJES_REGS_H_ */