27 #include "../switchtec_priv.h"
31 #include <linux/switchtec_ioctl.h>
40 #include <sys/ioctl.h>
42 #include <sys/sysmacros.h>
43 #include <arpa/inet.h>
45 #include <sys/types.h>
46 #include <sys/socket.h>
53 #define ETH_SERVER_PORT 54545
55 #define ETH_CHAN_TYPE_COMMAND 0x1
56 #define ETH_CHAN_TYPE_EVENT 0x2
58 #define ETH_PROT_SIGNATURE 0x6d6c7373
59 #define ETH_PROT_VERSION 0x1
61 #define ETH_PACKET_TYPE_OPEN 0xB1
62 #define ETH_PACKET_TYPE_CMD 0xB2
64 #define ETH_FUNC_TYPE_OPEN_REQUEST 0x1
65 #define ETH_FUNC_TYPE_OPEN_ACCEPT 0x2
66 #define ETH_FUNC_TYPE_OPEN_REJECT 0x3
67 #define ETH_FUNC_TYPE_OPEN_CLOSE 0x4
69 #define ETH_FUNC_TYPE_MRPC_CMD 0x1
70 #define ETH_FUNC_TYPE_MOE_CMD 0x2
71 #define ETH_FUNC_TYPE_MRPC_RESP 0x3
72 #define ETH_FUNC_TYPE_EVENT 0x4
73 #define ETH_FUNC_TYPE_MOE_RESP 0x5
75 #define ETH_INST_ID_0 0x0
76 #define ETH_INST_ID_1 0x1
78 #define ETH_GAS_READ_CMD_ID 0x1001
79 #define ETH_GAS_WRITE_CMD_ID 0x1002
81 #define ETH_MAX_READ 512
84 struct switchtec_dev dev;
89 #define to_switchtec_eth(d) \
90 ((struct switchtec_eth *) \
91 ((char *)d - offsetof(struct switchtec_eth, dev)))
97 uint8_t function_type;
100 uint8_t service_inst;
104 uint8_t service_type;
107 uint16_t payload_bytes;
109 uint16_t mrpc_output_bytes;
110 uint16_t return_code;
117 uint8_t body[MRPC_MAX_DATA_LEN + 4];
120 static int send_eth_command(
int cmd_fd,
int func_type, uint8_t *data,
121 uint32_t data_len, uint32_t mrpc_output_len)
126 packet_len = offsetof(
struct eth_packet, body) + data_len;
127 command_p = malloc(packet_len);
129 command_p->hdr.signature = htonl(ETH_PROT_SIGNATURE);
130 command_p->hdr.version_id = ETH_PROT_VERSION;
131 command_p->hdr.function_type = func_type;
132 command_p->hdr.packet_type = ETH_PACKET_TYPE_CMD;
133 command_p->hdr.payload_bytes = htons(data_len);
134 command_p->hdr.mrpc_output_bytes = htons(mrpc_output_len);
136 memcpy(command_p->body, data, data_len);
138 if (send(cmd_fd, command_p, packet_len, 0) < 0) {
147 static int recv_eth_response(
int cmd_fd, uint32_t *result,
148 uint8_t *output, uint32_t *output_len)
154 uint16_t packet_type;
158 if (recv(cmd_fd, &recvd_p.hdr, len, 0) < 0)
161 func_type = recvd_p.hdr.function_type;
162 packet_type = recvd_p.hdr.packet_type;
164 if ((func_type == ETH_FUNC_TYPE_OPEN_CLOSE)
165 && (packet_type == ETH_PACKET_TYPE_OPEN))
168 len = ntohs(recvd_p.hdr.payload_bytes);
174 if (recv(cmd_fd, p, len, 0) < 0)
177 if (packet_type == ETH_PACKET_TYPE_CMD) {
178 *result = le32toh(*(uint32_t *)p);
179 p +=
sizeof(uint32_t);
180 len -=
sizeof(uint32_t);
182 memcpy(output, p, len);
190 static int switchtec_submit_cmd_eth(
struct switchtec_dev *dev, uint32_t cmd,
191 const void *payload,
size_t payload_len,
198 struct eth_mrpc_body{
201 } __attribute__(( packed )) *mrpc_body;
203 body_len = offsetof(
struct eth_mrpc_body, data) + payload_len;
204 mrpc_body = malloc(body_len);
205 memset(mrpc_body, 0, body_len);
207 mrpc_body->command_id = htole32(cmd);
208 memcpy(mrpc_body->data, payload, payload_len);
210 ret = send_eth_command(edev->cmd_fd, ETH_FUNC_TYPE_MRPC_CMD,
211 (uint8_t *)mrpc_body, body_len, resp_len);
217 static int switchtec_read_resp_eth(
struct switchtec_dev *dev,
void *resp,
223 uint8_t buf[resp_len];
224 uint32_t received_len;
226 ret = recv_eth_response(edev->cmd_fd, &result, buf, &received_len);
230 if (received_len != resp_len) {
241 memcpy(resp, buf, resp_len);
246 static int eth_cmd(
struct switchtec_dev *dev, uint32_t cmd,
247 const void *payload,
size_t payload_len,
248 void *resp,
size_t resp_len)
252 ret = switchtec_submit_cmd_eth(dev, cmd, payload,
253 payload_len, resp_len);
258 return switchtec_read_resp_eth(dev, resp, resp_len);
262 #define __force __attribute__((force))
267 static int eth_gas_write_exec(
int fd, uint32_t offset,
268 const void *data, uint16_t bytes)
274 struct eth_gas_write_body{
280 } __attribute__(( packed )) *gas_write_body;
282 body_len = offsetof(
struct eth_gas_write_body, data) + bytes;
283 gas_write_body = malloc(body_len);
284 memset(gas_write_body, 0, body_len);
286 gas_write_body->command_id = htole32(ETH_GAS_WRITE_CMD_ID);
287 gas_write_body->offset = htole32(offset);
288 gas_write_body->bytes = htole16(bytes);
290 memcpy(gas_write_body->data, data, bytes);
292 ret = send_eth_command(fd, ETH_FUNC_TYPE_MOE_CMD,
293 (uint8_t *)gas_write_body, body_len, 0);
295 free(gas_write_body);
300 ret = recv_eth_response(fd, &result, NULL, NULL);
305 static int eth_gas_read_exec(
struct switchtec_dev *dev, uint32_t offset,
306 uint8_t *data,
size_t bytes)
314 struct eth_gas_write_body{
319 } __attribute__(( packed )) gas_read_body;
321 gas_read_body.command_id = htole32(ETH_GAS_READ_CMD_ID);
322 gas_read_body.offset = htole32(offset);
323 gas_read_body.bytes = htole16(bytes);
325 body_len =
sizeof(gas_read_body);
327 ret = send_eth_command(edev->cmd_fd, ETH_FUNC_TYPE_MOE_CMD,
328 (uint8_t *)&gas_read_body, body_len, 0);
333 ret = recv_eth_response(edev->cmd_fd, &result, data, &data_len);
338 static void eth_gas_read(
struct switchtec_dev *dev,
void *dest,
339 const void __gas *src,
size_t n)
344 gas_addr = (uint32_t)(src - (
void __gas *)dev->gas_map);
345 ret = eth_gas_read_exec(dev, gas_addr, dest, n);
350 static void eth_gas_write(
struct switchtec_dev *dev,
void __gas *dest,
351 const void *src,
size_t n)
357 gas_addr = (uint32_t)(dest - (
void __gas *)dev->gas_map);
358 ret = eth_gas_write_exec(edev->cmd_fd, gas_addr, src, n);
363 static void eth_gas_write8(
struct switchtec_dev *dev, uint8_t val,
366 eth_gas_write(dev, addr, &val,
sizeof(uint8_t));
369 static void eth_gas_write16(
struct switchtec_dev *dev, uint16_t val,
370 uint16_t __gas *addr)
373 eth_gas_write(dev, addr, &val,
sizeof(uint16_t));
376 static void eth_gas_write32(
struct switchtec_dev *dev, uint32_t val,
377 uint32_t __gas *addr)
380 eth_gas_write(dev, addr, &val,
sizeof(uint32_t));
383 static void eth_gas_write64(
struct switchtec_dev *dev, uint64_t val,
384 uint64_t __gas *addr)
387 eth_gas_write(dev, addr, &val,
sizeof(uint64_t));
390 static void eth_memcpy_from_gas(
struct switchtec_dev *dev,
void *dest,
391 const void __gas *src,
size_t n)
393 eth_gas_read(dev, dest, src, n);
396 static void eth_memcpy_to_gas(
struct switchtec_dev *dev,
void __gas *dest,
397 const void *src,
size_t n)
399 eth_gas_write(dev, dest, src, n);
402 static ssize_t eth_write_from_gas(
struct switchtec_dev *dev,
int fd,
403 const void __gas *src,
size_t n)
406 uint8_t buf[ETH_MAX_READ];
410 cnt = n > ETH_MAX_READ ? ETH_MAX_READ : n;
411 eth_memcpy_from_gas(dev, buf, src, cnt);
412 ret +=write(fd, buf, cnt);
421 static uint8_t eth_gas_read8(
struct switchtec_dev *dev, uint8_t __gas *addr)
425 eth_gas_read(dev, &val, addr,
sizeof(val));
429 static uint16_t eth_gas_read16(
struct switchtec_dev *dev, uint16_t __gas *addr)
433 eth_gas_read(dev, &val, addr,
sizeof(val));
437 static uint32_t eth_gas_read32(
struct switchtec_dev *dev, uint32_t __gas *addr)
441 eth_gas_read(dev, &val, addr,
sizeof(val));
445 static uint64_t eth_gas_read64(
struct switchtec_dev *dev, uint64_t __gas *addr)
449 eth_gas_read(dev, &val, addr,
sizeof(val));
453 static void eth_close(
struct switchtec_dev *dev)
458 munmap((
void __force *)dev->gas_map, dev->gas_map_size);
464 static int map_gas(
struct switchtec_dev *dev)
467 dev->gas_map_size = 4 << 20;
478 addr = mmap(NULL, dev->gas_map_size, PROT_NONE,
479 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
480 if (addr == MAP_FAILED)
483 dev->gas_map = (
gasptr_t __force)addr;
488 static gasptr_t eth_gas_map(
struct switchtec_dev *dev,
int writeable,
492 *map_size = dev->gas_map_size;
497 static int eth_event_wait(
struct switchtec_dev *dev,
int timeout_ms)
506 if (timeout_ms != -1)
507 setsockopt(edev->evt_fd, SOL_SOCKET, SO_RCVTIMEO,
508 (
char *)&timeout_ms,
sizeof(
int));
510 ret = recv(edev->evt_fd, &recvd_p.hdr, len, 0);
514 if ((recvd_p.hdr.packet_type == ETH_PACKET_TYPE_CMD)
515 && (recvd_p.hdr.function_type == ETH_FUNC_TYPE_EVENT))
521 static const struct switchtec_ops eth_ops = {
523 .gas_map = eth_gas_map,
525 .get_device_id = gasop_get_device_id,
526 .get_fw_version = gasop_get_fw_version,
527 .pff_to_port = gasop_pff_to_port,
528 .port_to_pff = gasop_port_to_pff,
529 .flash_part = gasop_flash_part,
530 .event_summary = gasop_event_summary,
531 .event_ctl = gasop_event_ctl,
532 .event_wait = eth_event_wait,
534 .gas_read8 = eth_gas_read8,
535 .gas_read16 = eth_gas_read16,
536 .gas_read32 = eth_gas_read32,
537 .gas_read64 = eth_gas_read64,
538 .gas_write8 = eth_gas_write8,
539 .gas_write16 = eth_gas_write16,
540 .gas_write32 = eth_gas_write32,
541 .gas_write32_no_retry = eth_gas_write32,
542 .gas_write64 = eth_gas_write64,
543 .memcpy_to_gas = eth_memcpy_to_gas,
544 .memcpy_from_gas = eth_memcpy_from_gas,
545 .write_from_gas = eth_write_from_gas,
548 static int open_eth_chan(
const char *server_ip,
int server_port,
549 int chan_type,
int moe_inst_id)
554 struct sockaddr_in server;
558 fd = socket(AF_INET, SOCK_STREAM, 0);
563 server.sin_addr.s_addr = inet_addr(server_ip);
564 server.sin_family = AF_INET;
565 server.sin_port = htons(server_port);
567 if (connect(fd, (
struct sockaddr *)&server ,
sizeof(server)) < 0) {
576 open_p->hdr.signature = htonl(ETH_PROT_SIGNATURE);
577 open_p->hdr.version_id = ETH_PROT_VERSION;
578 open_p->hdr.function_type = ETH_FUNC_TYPE_OPEN_REQUEST;
579 open_p->hdr.packet_type = ETH_PACKET_TYPE_OPEN;
580 open_p->hdr.service_inst = moe_inst_id;
581 open_p->hdr.service_type = chan_type;
583 if (send(fd, open_p, len, 0) < 0) {
589 if (recv(fd, open_p, len, 0) < 0) {
594 if (!((open_p->hdr.function_type == ETH_FUNC_TYPE_OPEN_ACCEPT)
595 && (open_p->hdr.return_code == 0)))
607 edev = malloc(
sizeof(*edev));
611 edev->cmd_fd = open_eth_chan(ip, ETH_SERVER_PORT,
612 ETH_CHAN_TYPE_COMMAND, inst);
613 if (edev->cmd_fd < 0)
614 goto err_close_cmd_free;
616 edev->evt_fd = open_eth_chan(ip, ETH_SERVER_PORT,
617 ETH_CHAN_TYPE_EVENT, inst);
618 if (edev->evt_fd < 0)
621 if (map_gas(&edev->dev))
624 edev->dev.ops = ð_ops;
626 gasop_set_partition_info(&edev->dev);