1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * FUJITSU Extended Socket Network Device driver 4*4882a593Smuzhiyun * Copyright (c) 2015 FUJITSU LIMITED 5*4882a593Smuzhiyun */ 6*4882a593Smuzhiyun 7*4882a593Smuzhiyun #ifndef FJES_HW_H_ 8*4882a593Smuzhiyun #define FJES_HW_H_ 9*4882a593Smuzhiyun 10*4882a593Smuzhiyun #include <linux/netdevice.h> 11*4882a593Smuzhiyun #include <linux/if_vlan.h> 12*4882a593Smuzhiyun #include <linux/vmalloc.h> 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun #include "fjes_regs.h" 15*4882a593Smuzhiyun 16*4882a593Smuzhiyun struct fjes_hw; 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define EP_BUFFER_SUPPORT_VLAN_MAX 4 19*4882a593Smuzhiyun #define EP_BUFFER_INFO_SIZE 4096 20*4882a593Smuzhiyun 21*4882a593Smuzhiyun #define FJES_DEBUG_PAGE_SIZE 4096 22*4882a593Smuzhiyun #define FJES_DEBUG_BUFFER_SIZE (16 * FJES_DEBUG_PAGE_SIZE) 23*4882a593Smuzhiyun 24*4882a593Smuzhiyun #define FJES_DEVICE_RESET_TIMEOUT ((17 + 1) * 3 * 8) /* sec */ 25*4882a593Smuzhiyun #define FJES_COMMAND_REQ_TIMEOUT ((5 + 1) * 3 * 8) /* sec */ 26*4882a593Smuzhiyun #define FJES_COMMAND_REQ_BUFF_TIMEOUT (60 * 3) /* sec */ 27*4882a593Smuzhiyun #define FJES_COMMAND_EPSTOP_WAIT_TIMEOUT (1) /* sec */ 28*4882a593Smuzhiyun 29*4882a593Smuzhiyun #define FJES_CMD_REQ_ERR_INFO_PARAM (0x0001) 30*4882a593Smuzhiyun #define FJES_CMD_REQ_ERR_INFO_STATUS (0x0002) 31*4882a593Smuzhiyun 32*4882a593Smuzhiyun #define FJES_CMD_REQ_RES_CODE_NORMAL (0) 33*4882a593Smuzhiyun #define FJES_CMD_REQ_RES_CODE_BUSY (1) 34*4882a593Smuzhiyun 35*4882a593Smuzhiyun #define FJES_ZONING_STATUS_DISABLE (0x00) 36*4882a593Smuzhiyun #define FJES_ZONING_STATUS_ENABLE (0x01) 37*4882a593Smuzhiyun #define FJES_ZONING_STATUS_INVALID (0xFF) 38*4882a593Smuzhiyun 39*4882a593Smuzhiyun #define FJES_ZONING_ZONE_TYPE_NONE (0xFF) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun #define FJES_TX_DELAY_SEND_NONE (0) 42*4882a593Smuzhiyun #define FJES_TX_DELAY_SEND_PENDING (1) 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun #define FJES_RX_STOP_REQ_NONE (0x0) 45*4882a593Smuzhiyun #define FJES_RX_STOP_REQ_DONE (0x1) 46*4882a593Smuzhiyun #define FJES_RX_STOP_REQ_REQUEST (0x2) 47*4882a593Smuzhiyun #define FJES_RX_POLL_WORK (0x4) 48*4882a593Smuzhiyun #define FJES_RX_MTU_CHANGING_DONE (0x8) 49*4882a593Smuzhiyun 50*4882a593Smuzhiyun #define EP_BUFFER_SIZE \ 51*4882a593Smuzhiyun (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ 52*4882a593Smuzhiyun / EP_BUFFER_INFO_SIZE) * EP_BUFFER_INFO_SIZE) 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun #define EP_RING_NUM(buffer_size, frame_size) \ 55*4882a593Smuzhiyun (u32)((buffer_size) / (frame_size)) 56*4882a593Smuzhiyun #define EP_RING_INDEX(_num, _max) (((_num) + (_max)) % (_max)) 57*4882a593Smuzhiyun #define EP_RING_INDEX_INC(_num, _max) \ 58*4882a593Smuzhiyun ((_num) = EP_RING_INDEX((_num) + 1, (_max))) 59*4882a593Smuzhiyun #define EP_RING_FULL(_head, _tail, _max) \ 60*4882a593Smuzhiyun (0 == EP_RING_INDEX(((_tail) - (_head)), (_max))) 61*4882a593Smuzhiyun #define EP_RING_EMPTY(_head, _tail, _max) \ 62*4882a593Smuzhiyun (1 == EP_RING_INDEX(((_tail) - (_head)), (_max))) 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define FJES_MTU_TO_BUFFER_SIZE(mtu) \ 65*4882a593Smuzhiyun (ETH_HLEN + VLAN_HLEN + (mtu) + ETH_FCS_LEN) 66*4882a593Smuzhiyun #define FJES_MTU_TO_FRAME_SIZE(mtu) \ 67*4882a593Smuzhiyun (sizeof(struct esmem_frame) + FJES_MTU_TO_BUFFER_SIZE(mtu)) 68*4882a593Smuzhiyun #define FJES_MTU_DEFINE(size) \ 69*4882a593Smuzhiyun ((size) - sizeof(struct esmem_frame) - \ 70*4882a593Smuzhiyun (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)) 71*4882a593Smuzhiyun 72*4882a593Smuzhiyun #define FJES_DEV_COMMAND_INFO_REQ_LEN (4) 73*4882a593Smuzhiyun #define FJES_DEV_COMMAND_INFO_RES_LEN(epnum) (8 + 2 * (epnum)) 74*4882a593Smuzhiyun #define FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(txb, rxb) \ 75*4882a593Smuzhiyun (24 + (8 * ((txb) / EP_BUFFER_INFO_SIZE + (rxb) / EP_BUFFER_INFO_SIZE))) 76*4882a593Smuzhiyun #define FJES_DEV_COMMAND_SHARE_BUFFER_RES_LEN (8) 77*4882a593Smuzhiyun #define FJES_DEV_COMMAND_UNSHARE_BUFFER_REQ_LEN (8) 78*4882a593Smuzhiyun #define FJES_DEV_COMMAND_UNSHARE_BUFFER_RES_LEN (8) 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun #define FJES_DEV_REQ_BUF_SIZE(maxep) \ 81*4882a593Smuzhiyun FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(EP_BUFFER_SIZE, EP_BUFFER_SIZE) 82*4882a593Smuzhiyun #define FJES_DEV_RES_BUF_SIZE(maxep) \ 83*4882a593Smuzhiyun FJES_DEV_COMMAND_INFO_RES_LEN(maxep) 84*4882a593Smuzhiyun 85*4882a593Smuzhiyun #define FJES_DEV_COMMAND_START_DBG_REQ_LEN(byte) \ 86*4882a593Smuzhiyun (16 + (8 * (byte) / FJES_DEBUG_PAGE_SIZE)) 87*4882a593Smuzhiyun #define FJES_DEV_COMMAND_START_DBG_RES_LEN (8) 88*4882a593Smuzhiyun #define FJES_DEV_COMMAND_STOP_DBG_REQ_LEN (4) 89*4882a593Smuzhiyun #define FJES_DEV_COMMAND_STOP_DBG_RES_LEN (8) 90*4882a593Smuzhiyun 91*4882a593Smuzhiyun /* Frame & MTU */ 92*4882a593Smuzhiyun struct esmem_frame { 93*4882a593Smuzhiyun __le32 frame_size; 94*4882a593Smuzhiyun u8 frame_data[]; 95*4882a593Smuzhiyun }; 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun /* EP partner status */ 98*4882a593Smuzhiyun enum ep_partner_status { 99*4882a593Smuzhiyun EP_PARTNER_UNSHARE, 100*4882a593Smuzhiyun EP_PARTNER_SHARED, 101*4882a593Smuzhiyun EP_PARTNER_WAITING, 102*4882a593Smuzhiyun EP_PARTNER_COMPLETE, 103*4882a593Smuzhiyun EP_PARTNER_STATUS_MAX, 104*4882a593Smuzhiyun }; 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun /* shared status region */ 107*4882a593Smuzhiyun struct fjes_device_shared_info { 108*4882a593Smuzhiyun int epnum; 109*4882a593Smuzhiyun u8 ep_status[]; 110*4882a593Smuzhiyun }; 111*4882a593Smuzhiyun 112*4882a593Smuzhiyun /* structures for command control request data*/ 113*4882a593Smuzhiyun union fjes_device_command_req { 114*4882a593Smuzhiyun struct { 115*4882a593Smuzhiyun __le32 length; 116*4882a593Smuzhiyun } info; 117*4882a593Smuzhiyun struct { 118*4882a593Smuzhiyun __le32 length; 119*4882a593Smuzhiyun __le32 epid; 120*4882a593Smuzhiyun __le64 buffer[]; 121*4882a593Smuzhiyun } share_buffer; 122*4882a593Smuzhiyun struct { 123*4882a593Smuzhiyun __le32 length; 124*4882a593Smuzhiyun __le32 epid; 125*4882a593Smuzhiyun } unshare_buffer; 126*4882a593Smuzhiyun struct { 127*4882a593Smuzhiyun __le32 length; 128*4882a593Smuzhiyun __le32 mode; 129*4882a593Smuzhiyun __le64 buffer_len; 130*4882a593Smuzhiyun __le64 buffer[]; 131*4882a593Smuzhiyun } start_trace; 132*4882a593Smuzhiyun struct { 133*4882a593Smuzhiyun __le32 length; 134*4882a593Smuzhiyun } stop_trace; 135*4882a593Smuzhiyun }; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun /* structures for command control response data */ 138*4882a593Smuzhiyun union fjes_device_command_res { 139*4882a593Smuzhiyun struct { 140*4882a593Smuzhiyun __le32 length; 141*4882a593Smuzhiyun __le32 code; 142*4882a593Smuzhiyun struct { 143*4882a593Smuzhiyun u8 es_status; 144*4882a593Smuzhiyun u8 zone; 145*4882a593Smuzhiyun } info[]; 146*4882a593Smuzhiyun } info; 147*4882a593Smuzhiyun struct { 148*4882a593Smuzhiyun __le32 length; 149*4882a593Smuzhiyun __le32 code; 150*4882a593Smuzhiyun } share_buffer; 151*4882a593Smuzhiyun struct { 152*4882a593Smuzhiyun __le32 length; 153*4882a593Smuzhiyun __le32 code; 154*4882a593Smuzhiyun } unshare_buffer; 155*4882a593Smuzhiyun struct { 156*4882a593Smuzhiyun __le32 length; 157*4882a593Smuzhiyun __le32 code; 158*4882a593Smuzhiyun } start_trace; 159*4882a593Smuzhiyun struct { 160*4882a593Smuzhiyun __le32 length; 161*4882a593Smuzhiyun __le32 code; 162*4882a593Smuzhiyun } stop_trace; 163*4882a593Smuzhiyun }; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /* request command type */ 166*4882a593Smuzhiyun enum fjes_dev_command_request_type { 167*4882a593Smuzhiyun FJES_CMD_REQ_INFO = 0x0001, 168*4882a593Smuzhiyun FJES_CMD_REQ_SHARE_BUFFER = 0x0002, 169*4882a593Smuzhiyun FJES_CMD_REQ_UNSHARE_BUFFER = 0x0004, 170*4882a593Smuzhiyun FJES_CMD_REQ_START_DEBUG = 0x0100, 171*4882a593Smuzhiyun FJES_CMD_REQ_STOP_DEBUG = 0x0200, 172*4882a593Smuzhiyun }; 173*4882a593Smuzhiyun 174*4882a593Smuzhiyun /* parameter for command control */ 175*4882a593Smuzhiyun struct fjes_device_command_param { 176*4882a593Smuzhiyun u32 req_len; 177*4882a593Smuzhiyun phys_addr_t req_start; 178*4882a593Smuzhiyun u32 res_len; 179*4882a593Smuzhiyun phys_addr_t res_start; 180*4882a593Smuzhiyun phys_addr_t share_start; 181*4882a593Smuzhiyun }; 182*4882a593Smuzhiyun 183*4882a593Smuzhiyun /* error code for command control */ 184*4882a593Smuzhiyun enum fjes_dev_command_response_e { 185*4882a593Smuzhiyun FJES_CMD_STATUS_UNKNOWN, 186*4882a593Smuzhiyun FJES_CMD_STATUS_NORMAL, 187*4882a593Smuzhiyun FJES_CMD_STATUS_TIMEOUT, 188*4882a593Smuzhiyun FJES_CMD_STATUS_ERROR_PARAM, 189*4882a593Smuzhiyun FJES_CMD_STATUS_ERROR_STATUS, 190*4882a593Smuzhiyun }; 191*4882a593Smuzhiyun 192*4882a593Smuzhiyun /* EP buffer information */ 193*4882a593Smuzhiyun union ep_buffer_info { 194*4882a593Smuzhiyun u8 raw[EP_BUFFER_INFO_SIZE]; 195*4882a593Smuzhiyun 196*4882a593Smuzhiyun struct _ep_buffer_info_common_t { 197*4882a593Smuzhiyun u32 version; 198*4882a593Smuzhiyun } common; 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun struct _ep_buffer_info_v1_t { 201*4882a593Smuzhiyun u32 version; 202*4882a593Smuzhiyun u32 info_size; 203*4882a593Smuzhiyun 204*4882a593Smuzhiyun u32 buffer_size; 205*4882a593Smuzhiyun u16 count_max; 206*4882a593Smuzhiyun 207*4882a593Smuzhiyun u16 _rsv_1; 208*4882a593Smuzhiyun 209*4882a593Smuzhiyun u32 frame_max; 210*4882a593Smuzhiyun u8 mac_addr[ETH_ALEN]; 211*4882a593Smuzhiyun 212*4882a593Smuzhiyun u16 _rsv_2; 213*4882a593Smuzhiyun u32 _rsv_3; 214*4882a593Smuzhiyun 215*4882a593Smuzhiyun u16 tx_status; 216*4882a593Smuzhiyun u16 rx_status; 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun u32 head; 219*4882a593Smuzhiyun u32 tail; 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun u16 vlan_id[EP_BUFFER_SUPPORT_VLAN_MAX]; 222*4882a593Smuzhiyun 223*4882a593Smuzhiyun } v1i; 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun }; 226*4882a593Smuzhiyun 227*4882a593Smuzhiyun /* statistics of EP */ 228*4882a593Smuzhiyun struct fjes_drv_ep_stats { 229*4882a593Smuzhiyun u64 com_regist_buf_exec; 230*4882a593Smuzhiyun u64 com_unregist_buf_exec; 231*4882a593Smuzhiyun u64 send_intr_rx; 232*4882a593Smuzhiyun u64 send_intr_unshare; 233*4882a593Smuzhiyun u64 send_intr_zoneupdate; 234*4882a593Smuzhiyun u64 recv_intr_rx; 235*4882a593Smuzhiyun u64 recv_intr_unshare; 236*4882a593Smuzhiyun u64 recv_intr_stop; 237*4882a593Smuzhiyun u64 recv_intr_zoneupdate; 238*4882a593Smuzhiyun u64 tx_buffer_full; 239*4882a593Smuzhiyun u64 tx_dropped_not_shared; 240*4882a593Smuzhiyun u64 tx_dropped_ver_mismatch; 241*4882a593Smuzhiyun u64 tx_dropped_buf_size_mismatch; 242*4882a593Smuzhiyun u64 tx_dropped_vlanid_mismatch; 243*4882a593Smuzhiyun }; 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun /* buffer pair for Extended Partition */ 246*4882a593Smuzhiyun struct ep_share_mem_info { 247*4882a593Smuzhiyun struct epbuf_handler { 248*4882a593Smuzhiyun void *buffer; 249*4882a593Smuzhiyun size_t size; 250*4882a593Smuzhiyun union ep_buffer_info *info; 251*4882a593Smuzhiyun u8 *ring; 252*4882a593Smuzhiyun } tx, rx; 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun struct rtnl_link_stats64 net_stats; 255*4882a593Smuzhiyun struct fjes_drv_ep_stats ep_stats; 256*4882a593Smuzhiyun 257*4882a593Smuzhiyun u16 tx_status_work; 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun u8 es_status; 260*4882a593Smuzhiyun u8 zone; 261*4882a593Smuzhiyun }; 262*4882a593Smuzhiyun 263*4882a593Smuzhiyun struct es_device_trace { 264*4882a593Smuzhiyun u32 record_num; 265*4882a593Smuzhiyun u32 current_record; 266*4882a593Smuzhiyun u32 status_flag; 267*4882a593Smuzhiyun u32 _rsv; 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun struct { 270*4882a593Smuzhiyun u16 epid; 271*4882a593Smuzhiyun u16 dir_offset; 272*4882a593Smuzhiyun u32 data; 273*4882a593Smuzhiyun u64 tsc; 274*4882a593Smuzhiyun } record[]; 275*4882a593Smuzhiyun }; 276*4882a593Smuzhiyun 277*4882a593Smuzhiyun struct fjes_hw_info { 278*4882a593Smuzhiyun struct fjes_device_shared_info *share; 279*4882a593Smuzhiyun union fjes_device_command_req *req_buf; 280*4882a593Smuzhiyun u64 req_buf_size; 281*4882a593Smuzhiyun union fjes_device_command_res *res_buf; 282*4882a593Smuzhiyun u64 res_buf_size; 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun int *my_epid; 285*4882a593Smuzhiyun int *max_epid; 286*4882a593Smuzhiyun 287*4882a593Smuzhiyun struct es_device_trace *trace; 288*4882a593Smuzhiyun u64 trace_size; 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun struct mutex lock; /* buffer lock*/ 291*4882a593Smuzhiyun 292*4882a593Smuzhiyun unsigned long buffer_share_bit; 293*4882a593Smuzhiyun unsigned long buffer_unshare_reserve_bit; 294*4882a593Smuzhiyun }; 295*4882a593Smuzhiyun 296*4882a593Smuzhiyun struct fjes_hw { 297*4882a593Smuzhiyun void *back; 298*4882a593Smuzhiyun 299*4882a593Smuzhiyun unsigned long txrx_stop_req_bit; 300*4882a593Smuzhiyun unsigned long epstop_req_bit; 301*4882a593Smuzhiyun struct work_struct update_zone_task; 302*4882a593Smuzhiyun struct work_struct epstop_task; 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun int my_epid; 305*4882a593Smuzhiyun int max_epid; 306*4882a593Smuzhiyun 307*4882a593Smuzhiyun struct ep_share_mem_info *ep_shm_info; 308*4882a593Smuzhiyun 309*4882a593Smuzhiyun struct fjes_hw_resource { 310*4882a593Smuzhiyun u64 start; 311*4882a593Smuzhiyun u64 size; 312*4882a593Smuzhiyun int irq; 313*4882a593Smuzhiyun } hw_res; 314*4882a593Smuzhiyun 315*4882a593Smuzhiyun u8 *base; 316*4882a593Smuzhiyun 317*4882a593Smuzhiyun struct fjes_hw_info hw_info; 318*4882a593Smuzhiyun 319*4882a593Smuzhiyun spinlock_t rx_status_lock; /* spinlock for rx_status */ 320*4882a593Smuzhiyun 321*4882a593Smuzhiyun u32 debug_mode; 322*4882a593Smuzhiyun }; 323*4882a593Smuzhiyun 324*4882a593Smuzhiyun int fjes_hw_init(struct fjes_hw *); 325*4882a593Smuzhiyun void fjes_hw_exit(struct fjes_hw *); 326*4882a593Smuzhiyun int fjes_hw_reset(struct fjes_hw *); 327*4882a593Smuzhiyun int fjes_hw_request_info(struct fjes_hw *); 328*4882a593Smuzhiyun int fjes_hw_register_buff_addr(struct fjes_hw *, int, 329*4882a593Smuzhiyun struct ep_share_mem_info *); 330*4882a593Smuzhiyun int fjes_hw_unregister_buff_addr(struct fjes_hw *, int); 331*4882a593Smuzhiyun void fjes_hw_init_command_registers(struct fjes_hw *, 332*4882a593Smuzhiyun struct fjes_device_command_param *); 333*4882a593Smuzhiyun void fjes_hw_setup_epbuf(struct epbuf_handler *, u8 *, u32); 334*4882a593Smuzhiyun int fjes_hw_raise_interrupt(struct fjes_hw *, int, enum REG_ICTL_MASK); 335*4882a593Smuzhiyun void fjes_hw_set_irqmask(struct fjes_hw *, enum REG_ICTL_MASK, bool); 336*4882a593Smuzhiyun u32 fjes_hw_capture_interrupt_status(struct fjes_hw *); 337*4882a593Smuzhiyun void fjes_hw_raise_epstop(struct fjes_hw *); 338*4882a593Smuzhiyun int fjes_hw_wait_epstop(struct fjes_hw *); 339*4882a593Smuzhiyun enum ep_partner_status 340*4882a593Smuzhiyun fjes_hw_get_partner_ep_status(struct fjes_hw *, int); 341*4882a593Smuzhiyun 342*4882a593Smuzhiyun bool fjes_hw_epid_is_same_zone(struct fjes_hw *, int); 343*4882a593Smuzhiyun int fjes_hw_epid_is_shared(struct fjes_device_shared_info *, int); 344*4882a593Smuzhiyun bool fjes_hw_check_epbuf_version(struct epbuf_handler *, u32); 345*4882a593Smuzhiyun bool fjes_hw_check_mtu(struct epbuf_handler *, u32); 346*4882a593Smuzhiyun bool fjes_hw_check_vlan_id(struct epbuf_handler *, u16); 347*4882a593Smuzhiyun bool fjes_hw_set_vlan_id(struct epbuf_handler *, u16); 348*4882a593Smuzhiyun void fjes_hw_del_vlan_id(struct epbuf_handler *, u16); 349*4882a593Smuzhiyun bool fjes_hw_epbuf_rx_is_empty(struct epbuf_handler *); 350*4882a593Smuzhiyun void *fjes_hw_epbuf_rx_curpkt_get_addr(struct epbuf_handler *, size_t *); 351*4882a593Smuzhiyun void fjes_hw_epbuf_rx_curpkt_drop(struct epbuf_handler *); 352*4882a593Smuzhiyun int fjes_hw_epbuf_tx_pkt_send(struct epbuf_handler *, void *, size_t); 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun int fjes_hw_start_debug(struct fjes_hw *); 355*4882a593Smuzhiyun int fjes_hw_stop_debug(struct fjes_hw *); 356*4882a593Smuzhiyun #endif /* FJES_HW_H_ */ 357