Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fjes: ES information acquisition routine

This patch adds ES information acquisition routine.
ES information can be retrieved issuing information
request command. ES information includes which
receiver is same zone.

Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Taku Izumi and committed by
David S. Miller
3bb025d4 2fcbca68

+148
+101
drivers/net/fjes/fjes_hw.c
··· 351 351 fjes_hw_cleanup(hw); 352 352 } 353 353 354 + static enum fjes_dev_command_response_e 355 + fjes_hw_issue_request_command(struct fjes_hw *hw, 356 + enum fjes_dev_command_request_type type) 357 + { 358 + enum fjes_dev_command_response_e ret = FJES_CMD_STATUS_UNKNOWN; 359 + union REG_CR cr; 360 + union REG_CS cs; 361 + int timeout; 362 + 363 + cr.reg = 0; 364 + cr.bits.req_start = 1; 365 + cr.bits.req_code = type; 366 + wr32(XSCT_CR, cr.reg); 367 + cr.reg = rd32(XSCT_CR); 368 + 369 + if (cr.bits.error == 0) { 370 + timeout = FJES_COMMAND_REQ_TIMEOUT * 1000; 371 + cs.reg = rd32(XSCT_CS); 372 + 373 + while ((cs.bits.complete != 1) && timeout > 0) { 374 + msleep(1000); 375 + cs.reg = rd32(XSCT_CS); 376 + timeout -= 1000; 377 + } 378 + 379 + if (cs.bits.complete == 1) 380 + ret = FJES_CMD_STATUS_NORMAL; 381 + else if (timeout <= 0) 382 + ret = FJES_CMD_STATUS_TIMEOUT; 383 + 384 + } else { 385 + switch (cr.bits.err_info) { 386 + case FJES_CMD_REQ_ERR_INFO_PARAM: 387 + ret = FJES_CMD_STATUS_ERROR_PARAM; 388 + break; 389 + case FJES_CMD_REQ_ERR_INFO_STATUS: 390 + ret = FJES_CMD_STATUS_ERROR_STATUS; 391 + break; 392 + default: 393 + ret = FJES_CMD_STATUS_UNKNOWN; 394 + break; 395 + } 396 + } 397 + 398 + return ret; 399 + } 400 + 401 + int fjes_hw_request_info(struct fjes_hw *hw) 402 + { 403 + union fjes_device_command_req *req_buf = hw->hw_info.req_buf; 404 + union fjes_device_command_res *res_buf = hw->hw_info.res_buf; 405 + enum fjes_dev_command_response_e ret; 406 + int result; 407 + 408 + memset(req_buf, 0, hw->hw_info.req_buf_size); 409 + memset(res_buf, 0, hw->hw_info.res_buf_size); 410 + 411 + req_buf->info.length = FJES_DEV_COMMAND_INFO_REQ_LEN; 412 + 413 + res_buf->info.length = 0; 414 + res_buf->info.code = 0; 415 + 416 + ret = fjes_hw_issue_request_command(hw, FJES_CMD_REQ_INFO); 417 + 418 + result = 0; 419 + 420 + if (FJES_DEV_COMMAND_INFO_RES_LEN((*hw->hw_info.max_epid)) != 421 + res_buf->info.length) { 422 + result = -ENOMSG; 423 + } else if (ret == FJES_CMD_STATUS_NORMAL) { 424 + switch (res_buf->info.code) { 425 + case FJES_CMD_REQ_RES_CODE_NORMAL: 426 + result = 0; 427 + break; 428 + default: 429 + result = -EPERM; 430 + break; 431 + } 432 + } else { 433 + switch (ret) { 434 + case FJES_CMD_STATUS_UNKNOWN: 435 + result = -EPERM; 436 + break; 437 + case FJES_CMD_STATUS_TIMEOUT: 438 + result = -EBUSY; 439 + break; 440 + case FJES_CMD_STATUS_ERROR_PARAM: 441 + result = -EPERM; 442 + break; 443 + case FJES_CMD_STATUS_ERROR_STATUS: 444 + result = -EPERM; 445 + break; 446 + default: 447 + result = -EPERM; 448 + break; 449 + } 450 + } 451 + 452 + return result; 453 + } 454 + 354 455 void fjes_hw_set_irqmask(struct fjes_hw *hw, 355 456 enum REG_ICTL_MASK intr_mask, bool mask) 356 457 {
+24
drivers/net/fjes/fjes_hw.h
··· 34 34 #define EP_BUFFER_INFO_SIZE 4096 35 35 36 36 #define FJES_DEVICE_RESET_TIMEOUT ((17 + 1) * 3) /* sec */ 37 + #define FJES_COMMAND_REQ_TIMEOUT (5 + 1) /* sec */ 38 + 39 + #define FJES_CMD_REQ_ERR_INFO_PARAM (0x0001) 40 + #define FJES_CMD_REQ_ERR_INFO_STATUS (0x0002) 41 + 42 + #define FJES_CMD_REQ_RES_CODE_NORMAL (0) 37 43 38 44 #define EP_BUFFER_SIZE \ 39 45 (((sizeof(union ep_buffer_info) + (128 * (64 * 1024))) \ ··· 56 50 ((size) - sizeof(struct esmem_frame) - \ 57 51 (ETH_HLEN + VLAN_HLEN + ETH_FCS_LEN)) 58 52 53 + #define FJES_DEV_COMMAND_INFO_REQ_LEN (4) 59 54 #define FJES_DEV_COMMAND_INFO_RES_LEN(epnum) (8 + 2 * (epnum)) 60 55 #define FJES_DEV_COMMAND_SHARE_BUFFER_REQ_LEN(txb, rxb) \ 61 56 (24 + (8 * ((txb) / EP_BUFFER_INFO_SIZE + (rxb) / EP_BUFFER_INFO_SIZE))) ··· 131 124 } stop_trace; 132 125 }; 133 126 127 + /* request command type */ 128 + enum fjes_dev_command_request_type { 129 + FJES_CMD_REQ_INFO = 0x0001, 130 + FJES_CMD_REQ_SHARE_BUFFER = 0x0002, 131 + FJES_CMD_REQ_UNSHARE_BUFFER = 0x0004, 132 + }; 133 + 134 134 /* parameter for command control */ 135 135 struct fjes_device_command_param { 136 136 u32 req_len; ··· 145 131 u32 res_len; 146 132 phys_addr_t res_start; 147 133 phys_addr_t share_start; 134 + }; 135 + 136 + /* error code for command control */ 137 + enum fjes_dev_command_response_e { 138 + FJES_CMD_STATUS_UNKNOWN, 139 + FJES_CMD_STATUS_NORMAL, 140 + FJES_CMD_STATUS_TIMEOUT, 141 + FJES_CMD_STATUS_ERROR_PARAM, 142 + FJES_CMD_STATUS_ERROR_STATUS, 148 143 }; 149 144 150 145 /* EP buffer information */ ··· 266 243 int fjes_hw_init(struct fjes_hw *); 267 244 void fjes_hw_exit(struct fjes_hw *); 268 245 int fjes_hw_reset(struct fjes_hw *); 246 + int fjes_hw_request_info(struct fjes_hw *); 269 247 270 248 void fjes_hw_init_command_registers(struct fjes_hw *, 271 249 struct fjes_device_command_param *);
+23
drivers/net/fjes/fjes_regs.h
··· 35 35 #define XSCT_DCTL 0x0010 /* Device Control */ 36 36 37 37 /* Command Control registers */ 38 + #define XSCT_CR 0x0020 /* Command request */ 39 + #define XSCT_CS 0x0024 /* Command status */ 38 40 #define XSCT_SHSTSAL 0x0028 /* Share status address Low */ 39 41 #define XSCT_SHSTSAH 0x002C /* Share status address High */ 40 42 ··· 76 74 __le32 reset:1; 77 75 __le32 rsv0:15; 78 76 __le32 rsv1:16; 77 + } bits; 78 + __le32 reg; 79 + }; 80 + 81 + /* Command Control registers */ 82 + union REG_CR { 83 + struct { 84 + __le32 req_code:16; 85 + __le32 err_info:14; 86 + __le32 error:1; 87 + __le32 req_start:1; 88 + } bits; 89 + __le32 reg; 90 + }; 91 + 92 + union REG_CS { 93 + struct { 94 + __le32 req_code:16; 95 + __le32 rsv0:14; 96 + __le32 busy:1; 97 + __le32 complete:1; 79 98 } bits; 80 99 __le32 reg; 81 100 };