2 * FUJITSU Extended Socket Network Device driver
3 * Copyright (c) 2015 FUJITSU LIMITED
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.
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
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/>.
17 * The full GNU General Public License is included in this distribution in
18 * the file called "COPYING".
25 /* supported MTU list */
26 const u32 fjes_support_mtu
[] = {
27 FJES_MTU_DEFINE(8 * 1024),
28 FJES_MTU_DEFINE(16 * 1024),
29 FJES_MTU_DEFINE(32 * 1024),
30 FJES_MTU_DEFINE(64 * 1024),
34 u32
fjes_hw_rd32(struct fjes_hw
*hw
, u32 reg
)
39 value
= readl(&base
[reg
]);
44 static u8
*fjes_hw_iomap(struct fjes_hw
*hw
)
48 if (!request_mem_region(hw
->hw_res
.start
, hw
->hw_res
.size
,
50 pr_err("request_mem_region failed\n");
54 base
= (u8
*)ioremap_nocache(hw
->hw_res
.start
, hw
->hw_res
.size
);
59 int fjes_hw_reset(struct fjes_hw
*hw
)
66 wr32(XSCT_DCTL
, dctl
.reg
);
68 timeout
= FJES_DEVICE_RESET_TIMEOUT
* 1000;
69 dctl
.reg
= rd32(XSCT_DCTL
);
70 while ((dctl
.bits
.reset
== 1) && (timeout
> 0)) {
72 dctl
.reg
= rd32(XSCT_DCTL
);
76 return timeout
> 0 ? 0 : -EIO
;
79 static int fjes_hw_get_max_epid(struct fjes_hw
*hw
)
81 union REG_MAX_EP info
;
83 info
.reg
= rd32(XSCT_MAX_EP
);
85 return info
.bits
.maxep
;
88 static int fjes_hw_get_my_epid(struct fjes_hw
*hw
)
90 union REG_OWNER_EPID info
;
92 info
.reg
= rd32(XSCT_OWNER_EPID
);
94 return info
.bits
.epid
;
97 static int fjes_hw_alloc_shared_status_region(struct fjes_hw
*hw
)
101 size
= sizeof(struct fjes_device_shared_info
) +
102 (sizeof(u8
) * hw
->max_epid
);
103 hw
->hw_info
.share
= kzalloc(size
, GFP_KERNEL
);
104 if (!hw
->hw_info
.share
)
107 hw
->hw_info
.share
->epnum
= hw
->max_epid
;
112 static int fjes_hw_alloc_epbuf(struct epbuf_handler
*epbh
)
116 mem
= vzalloc(EP_BUFFER_SIZE
);
121 epbh
->size
= EP_BUFFER_SIZE
;
123 epbh
->info
= (union ep_buffer_info
*)mem
;
124 epbh
->ring
= (u8
*)(mem
+ sizeof(union ep_buffer_info
));
129 void fjes_hw_setup_epbuf(struct epbuf_handler
*epbh
, u8
*mac_addr
, u32 mtu
)
131 union ep_buffer_info
*info
= epbh
->info
;
132 u16 vlan_id
[EP_BUFFER_SUPPORT_VLAN_MAX
];
135 for (i
= 0; i
< EP_BUFFER_SUPPORT_VLAN_MAX
; i
++)
136 vlan_id
[i
] = info
->v1i
.vlan_id
[i
];
138 memset(info
, 0, sizeof(union ep_buffer_info
));
140 info
->v1i
.version
= 0; /* version 0 */
142 for (i
= 0; i
< ETH_ALEN
; i
++)
143 info
->v1i
.mac_addr
[i
] = mac_addr
[i
];
148 info
->v1i
.info_size
= sizeof(union ep_buffer_info
);
149 info
->v1i
.buffer_size
= epbh
->size
- info
->v1i
.info_size
;
151 info
->v1i
.frame_max
= FJES_MTU_TO_FRAME_SIZE(mtu
);
152 info
->v1i
.count_max
=
153 EP_RING_NUM(info
->v1i
.buffer_size
, info
->v1i
.frame_max
);
155 for (i
= 0; i
< EP_BUFFER_SUPPORT_VLAN_MAX
; i
++)
156 info
->v1i
.vlan_id
[i
] = vlan_id
[i
];
160 fjes_hw_init_command_registers(struct fjes_hw
*hw
,
161 struct fjes_device_command_param
*param
)
163 /* Request Buffer length */
164 wr32(XSCT_REQBL
, (__le32
)(param
->req_len
));
165 /* Response Buffer Length */
166 wr32(XSCT_RESPBL
, (__le32
)(param
->res_len
));
168 /* Request Buffer Address */
170 (__le32
)(param
->req_start
& GENMASK_ULL(31, 0)));
172 (__le32
)((param
->req_start
& GENMASK_ULL(63, 32)) >> 32));
174 /* Response Buffer Address */
176 (__le32
)(param
->res_start
& GENMASK_ULL(31, 0)));
178 (__le32
)((param
->res_start
& GENMASK_ULL(63, 32)) >> 32));
180 /* Share status address */
182 (__le32
)(param
->share_start
& GENMASK_ULL(31, 0)));
184 (__le32
)((param
->share_start
& GENMASK_ULL(63, 32)) >> 32));
187 static int fjes_hw_setup(struct fjes_hw
*hw
)
189 u8 mac
[ETH_ALEN
] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
190 struct fjes_device_command_param param
;
191 struct ep_share_mem_info
*buf_pair
;
197 hw
->hw_info
.max_epid
= &hw
->max_epid
;
198 hw
->hw_info
.my_epid
= &hw
->my_epid
;
200 buf
= kcalloc(hw
->max_epid
, sizeof(struct ep_share_mem_info
),
205 hw
->ep_shm_info
= (struct ep_share_mem_info
*)buf
;
207 mem_size
= FJES_DEV_REQ_BUF_SIZE(hw
->max_epid
);
208 hw
->hw_info
.req_buf
= kzalloc(mem_size
, GFP_KERNEL
);
209 if (!(hw
->hw_info
.req_buf
))
212 hw
->hw_info
.req_buf_size
= mem_size
;
214 mem_size
= FJES_DEV_RES_BUF_SIZE(hw
->max_epid
);
215 hw
->hw_info
.res_buf
= kzalloc(mem_size
, GFP_KERNEL
);
216 if (!(hw
->hw_info
.res_buf
))
219 hw
->hw_info
.res_buf_size
= mem_size
;
221 result
= fjes_hw_alloc_shared_status_region(hw
);
225 hw
->hw_info
.buffer_share_bit
= 0;
226 hw
->hw_info
.buffer_unshare_reserve_bit
= 0;
228 for (epidx
= 0; epidx
< hw
->max_epid
; epidx
++) {
229 if (epidx
!= hw
->my_epid
) {
230 buf_pair
= &hw
->ep_shm_info
[epidx
];
232 result
= fjes_hw_alloc_epbuf(&buf_pair
->tx
);
236 result
= fjes_hw_alloc_epbuf(&buf_pair
->rx
);
240 fjes_hw_setup_epbuf(&buf_pair
->tx
, mac
,
241 fjes_support_mtu
[0]);
242 fjes_hw_setup_epbuf(&buf_pair
->rx
, mac
,
243 fjes_support_mtu
[0]);
247 memset(¶m
, 0, sizeof(param
));
249 param
.req_len
= hw
->hw_info
.req_buf_size
;
250 param
.req_start
= __pa(hw
->hw_info
.req_buf
);
251 param
.res_len
= hw
->hw_info
.res_buf_size
;
252 param
.res_start
= __pa(hw
->hw_info
.res_buf
);
254 param
.share_start
= __pa(hw
->hw_info
.share
->ep_status
);
256 fjes_hw_init_command_registers(hw
, ¶m
);
261 int fjes_hw_init(struct fjes_hw
*hw
)
265 hw
->base
= fjes_hw_iomap(hw
);
269 ret
= fjes_hw_reset(hw
);
273 fjes_hw_set_irqmask(hw
, REG_ICTL_MASK_ALL
, true);
275 mutex_init(&hw
->hw_info
.lock
);
277 hw
->max_epid
= fjes_hw_get_max_epid(hw
);
278 hw
->my_epid
= fjes_hw_get_my_epid(hw
);
280 if ((hw
->max_epid
== 0) || (hw
->my_epid
>= hw
->max_epid
))
283 ret
= fjes_hw_setup(hw
);
288 void fjes_hw_set_irqmask(struct fjes_hw
*hw
,
289 enum REG_ICTL_MASK intr_mask
, bool mask
)
292 wr32(XSCT_IMS
, intr_mask
);
294 wr32(XSCT_IMC
, intr_mask
);