Velocity Userspace
platform.c
Go to the documentation of this file.
1 /*
2  * Microsemi Switchtec(tm) PCIe Management Library
3  * Copyright (c) 2017, Microsemi Corporation
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included
13  * in all copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21  * OTHER DEALINGS IN THE SOFTWARE.
22  *
23  */
24 
30 #include "../switchtec_priv.h"
31 #include "switchtec/switchtec.h"
32 #include "switchtec/gas.h"
33 #include "switchtec/gas_mrpc.h"
34 #include "switchtec/errors.h"
35 
36 #include <string.h>
37 #include <errno.h>
38 
45 struct switchtec_dev *switchtec_open_by_path(const char *path);
46 
56 struct switchtec_dev *switchtec_open_by_index(int index);
57 
67 struct switchtec_dev *switchtec_open_by_pci_addr(int domain, int bus,
68  int device, int func);
69 
77 struct switchtec_dev *switchtec_open_i2c(const char *path, int i2c_addr);
78 
85 struct switchtec_dev *switchtec_open_uart(int fd);
86 
94 struct switchtec_dev *switchtec_open_eth(const char *ip, const int inst);
95 
101 void switchtec_close(struct switchtec_dev *dev)
102 {
103  if (!dev)
104  return;
105 
106  dev->ops->close(dev);
107 }
108 
116 int switchtec_list(struct switchtec_device_info **devlist);
117 
125 int switchtec_get_fw_version(struct switchtec_dev *dev, char *buf,
126  size_t buflen)
127 {
128  struct switchtec_fw_part_summary *sum;
129  struct switchtec_fw_image_info *running_img;
130 
131  sum = switchtec_fw_part_summary(dev);
132  if (!sum)
133  return -1;
134 
135  if ((sum->img.active != NULL) && (sum->img.active->running)) {
136  running_img = sum->img.active;
137  } else if ((sum->img.inactive != NULL) && (sum->img.inactive->running)) {
138  running_img = sum->img.inactive;
139  } else {
141  errno = EIO;
142  return -1;
143  }
144 
145  strncpy(buf, running_img->version, buflen);
146  buf[buflen - 1] = '\0';
147 
149 
150  return 0;
151 }
152 
164 int switchtec_cmd(struct switchtec_dev *dev, uint32_t cmd,
165  const void *payload, size_t payload_len, void *resp,
166  size_t resp_len)
167 {
168  int ret;
169 
170  cmd &= SWITCHTEC_CMD_MASK;
171  cmd |= dev->pax_id << SWITCHTEC_PAX_ID_SHIFT;
172 
173  ret = dev->ops->cmd(dev, cmd, payload, payload_len, resp, resp_len);
174  if (ret > 0) {
175  mrpc_error_cmd = cmd & SWITCHTEC_CMD_MASK;
176  errno |= SWITCHTEC_ERRNO_MRPC_FLAG_BIT;
177  }
178 
179  return ret;
180 }
181 
194 int switchtec_get_devices(struct switchtec_dev *dev,
195  struct switchtec_status *status,
196  int ports)
197 {
198  if (!dev->ops->get_devices)
199  return 0;
200 
201  return dev->ops->get_devices(dev, status, ports);
202 }
203 
213 int switchtec_pff_to_port(struct switchtec_dev *dev, int pff,
214  int *partition, int *port)
215 {
216  return dev->ops->pff_to_port(dev, pff, partition, port);
217 }
218 
228 int switchtec_port_to_pff(struct switchtec_dev *dev, int partition,
229  int port, int *pff)
230 {
231  return dev->ops->port_to_pff(dev, partition, port, pff);
232 }
233 
255 gasptr_t switchtec_gas_map(struct switchtec_dev *dev, int writeable,
256  size_t *map_size)
257 {
258  return dev->ops->gas_map(dev, writeable, map_size);
259 }
260 
267 void switchtec_gas_unmap(struct switchtec_dev *dev, gasptr_t map)
268 {
269  if (!dev->ops->gas_unmap)
270  return;
271 
272  dev->ops->gas_unmap(dev, map);
273 }
274 
283 int switchtec_flash_part(struct switchtec_dev *dev,
284  struct switchtec_fw_image_info *info,
285  enum switchtec_fw_image_part_id_gen3 part)
286 {
287  return dev->ops->flash_part(dev, info, part);
288 }
289 
297 int switchtec_event_summary(struct switchtec_dev *dev,
298  struct switchtec_event_summary *sum)
299 {
300  return dev->ops->event_summary(dev, sum);
301 }
302 
313 int switchtec_event_ctl(struct switchtec_dev *dev,
314  enum switchtec_event_id e,
315  int index, int flags,
316  uint32_t data[5])
317 {
318  return dev->ops->event_ctl(dev, e, index, flags, data);
319 }
320 
329 int switchtec_event_wait(struct switchtec_dev *dev, int timeout_ms)
330 {
331  if (!dev->ops->event_wait) {
332  errno = ENOTSUP;
333  return -errno;
334  }
335 
336  return dev->ops->event_wait(dev, timeout_ms);
337 }
338 
346 int gas_read8(struct switchtec_dev *dev, uint8_t __gas *addr, uint8_t *val)
347 {
348  if (dev->pax_id != dev->local_pax_id)
349  return gas_mrpc_read8(dev, addr, val);
350  else
351  *val = __gas_read8(dev, addr);
352 
353  return 0;
354 }
355 
363 int gas_read16(struct switchtec_dev *dev, uint16_t __gas *addr, uint16_t *val)
364 {
365  if (dev->pax_id != dev->local_pax_id)
366  return gas_mrpc_read16(dev, addr, val);
367  else
368  *val = __gas_read16(dev, addr);
369 
370  return 0;
371 }
372 
380 int gas_read32(struct switchtec_dev *dev, uint32_t __gas *addr, uint32_t *val)
381 {
382  if (dev->pax_id != dev->local_pax_id)
383  return gas_mrpc_read32(dev, addr, val);
384  else
385  *val = __gas_read32(dev, addr);
386 
387  return 0;
388 }
389 
397 int gas_read64(struct switchtec_dev *dev, uint64_t __gas *addr, uint64_t *val)
398 {
399  if (dev->pax_id != dev->local_pax_id)
400  return gas_mrpc_read64(dev, addr, val);
401  else
402  *val = __gas_read64(dev, addr);
403 
404  return 0;
405 }
406 
413 void gas_write8(struct switchtec_dev *dev, uint8_t val, uint8_t __gas *addr)
414 {
415  if (dev->pax_id != dev->local_pax_id)
416  gas_mrpc_write8(dev, val, addr);
417  else
418  __gas_write8(dev, val, addr);
419 }
420 
427 void gas_write16(struct switchtec_dev *dev, uint16_t val, uint16_t __gas *addr)
428 {
429  if (dev->pax_id != dev->local_pax_id)
430  gas_mrpc_write16(dev, val, addr);
431  else
432  __gas_write16(dev, val, addr);
433 }
434 
441 void gas_write32(struct switchtec_dev *dev, uint32_t val, uint32_t __gas *addr)
442 {
443  if (dev->pax_id != dev->local_pax_id)
444  gas_mrpc_write32(dev, val, addr);
445  else
446  __gas_write32(dev, val, addr);
447 }
448 
455 void gas_write64(struct switchtec_dev *dev, uint64_t val, uint64_t __gas *addr)
456 {
457  if (dev->pax_id != dev->local_pax_id)
458  gas_mrpc_write64(dev, val, addr);
459  else
460  __gas_write64(dev, val, addr);
461 }
462 
470 void memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest,
471  const void *src, size_t n)
472 {
473  if (dev->pax_id != dev->local_pax_id)
474  gas_mrpc_memcpy_to_gas(dev, dest, src, n);
475  else
476  __memcpy_to_gas(dev, dest, src, n);
477 }
478 
487 int memcpy_from_gas(struct switchtec_dev *dev, void *dest,
488  const void __gas *src, size_t n)
489 {
490  if (dev->pax_id != dev->local_pax_id)
491  return gas_mrpc_memcpy_from_gas(dev, dest, src, n);
492  else
493  __memcpy_from_gas(dev, dest, src, n);
494 
495  return 0;
496 }
497 
505 ssize_t write_from_gas(struct switchtec_dev *dev, int fd,
506  const void __gas *src, size_t n)
507 {
508  if (dev->pax_id != dev->local_pax_id)
509  return gas_mrpc_write_from_gas(dev, fd, src, n);
510  else
511  return __write_from_gas(dev, fd, src, n);
512 }
switchtec_get_fw_version
int switchtec_get_fw_version(struct switchtec_dev *dev, char *buf, size_t buflen)
Get the firmware version as a user readable string.
Definition: platform.c:125
switchtec_gas_map
gasptr_t switchtec_gas_map(struct switchtec_dev *dev, int writeable, size_t *map_size)
Map the GAS and return a pointer to access the gas.
Definition: platform.c:255
gas_mrpc_memcpy_from_gas
int gas_mrpc_memcpy_from_gas(struct switchtec_dev *dev, void *dest, const void __gas *src, size_t n)
Copy data from the GAS using MRPC commands.
Definition: gas_mrpc.c:94
switchtec_status
Port status structure.
Definition: switchtec.h:184
switchtec_get_devices
int switchtec_get_devices(struct switchtec_dev *dev, struct switchtec_status *status, int ports)
Populate an already retrieved switchtec_status structure list with information about the devices plug...
Definition: platform.c:194
switchtec_open_eth
struct switchtec_dev * switchtec_open_eth(const char *ip, const int inst)
Open a switchtec device over ethernet.
Definition: linux-eth.c:603
gas_read32
int gas_read32(struct switchtec_dev *dev, uint32_t __gas *addr, uint32_t *val)
Read a uint32_t from the GAS.
Definition: platform.c:380
gas_write32
void gas_write32(struct switchtec_dev *dev, uint32_t val, uint32_t __gas *addr)
Write a uint32_t to the GAS.
Definition: platform.c:441
switchtec.h
Main Switchtec header.
gas_read64
int gas_read64(struct switchtec_dev *dev, uint64_t __gas *addr, uint64_t *val)
Read a uint64_t from the GAS.
Definition: platform.c:397
memcpy_to_gas
void memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest, const void *src, size_t n)
Copy data to the GAS.
Definition: platform.c:470
gas_write8
void gas_write8(struct switchtec_dev *dev, uint8_t val, uint8_t __gas *addr)
Write a uint8_t to the GAS.
Definition: platform.c:413
switchtec_open_i2c
struct switchtec_dev * switchtec_open_i2c(const char *path, int i2c_addr)
Open a switchtec device behind an I2C device.
Definition: linux-i2c.c:647
switchtec_port_to_pff
int switchtec_port_to_pff(struct switchtec_dev *dev, int partition, int port, int *pff)
Convert a partition and port number to a port function index.
Definition: platform.c:228
switchtec_event_summary
int switchtec_event_summary(struct switchtec_dev *dev, struct switchtec_event_summary *sum)
Retrieve a summary of all the events that have occurred in the switch.
Definition: platform.c:297
switchtec_open_by_pci_addr
struct switchtec_dev * switchtec_open_by_pci_addr(int domain, int bus, int device, int func)
Open a switchtec device by PCI address (BDF)
Definition: linux.c:1050
switchtec_pff_to_port
int switchtec_pff_to_port(struct switchtec_dev *dev, int pff, int *partition, int *port)
Convert a port function index to a partition and port number.
Definition: platform.c:213
switchtec_close
void switchtec_close(struct switchtec_dev *dev)
Close a Switchtec device handle.
Definition: platform.c:101
gas.h
GAS Accessor functions.
switchtec_fw_image_info
Information about a firmware image or partition.
Definition: switchtec.h:285
switchtec_event_id
switchtec_event_id
Enumeration of all possible events.
Definition: switchtec.h:337
gas_write64
void gas_write64(struct switchtec_dev *dev, uint64_t val, uint64_t __gas *addr)
Write a uint64_t to the GAS.
Definition: platform.c:455
switchtec_list
int switchtec_list(struct switchtec_device_info **devlist)
List all the switchtec devices in the system.
Definition: linux.c:213
gas_write16
void gas_write16(struct switchtec_dev *dev, uint16_t val, uint16_t __gas *addr)
Write a uint16_t to the GAS.
Definition: platform.c:427
switchtec_fw_image_info::version
char version[32]
Firmware/Config version.
Definition: switchtec.h:289
memcpy_from_gas
int memcpy_from_gas(struct switchtec_dev *dev, void *dest, const void __gas *src, size_t n)
Copy data from the GAS.
Definition: platform.c:487
switchtec_open_by_index
struct switchtec_dev * switchtec_open_by_index(int index)
Open a switchtec device by index.
Definition: linux.c:1035
switchtec_open_uart
struct switchtec_dev * switchtec_open_uart(int fd)
Open a switchtec device behind a uart device.
Definition: linux-uart.c:497
switchtec_flash_part
int switchtec_flash_part(struct switchtec_dev *dev, struct switchtec_fw_image_info *info, enum switchtec_fw_image_part_id_gen3 part)
Retrieve information about a flash partition.
Definition: platform.c:283
gas_read16
int gas_read16(struct switchtec_dev *dev, uint16_t __gas *addr, uint16_t *val)
Read a uint16_t from the GAS.
Definition: platform.c:363
switchtec_gas_unmap
void switchtec_gas_unmap(struct switchtec_dev *dev, gasptr_t map)
Unmap the GAS region mapped with.
Definition: platform.c:267
switchtec_event_summary
Event summary bitmaps.
Definition: switchtec.h:322
switchtec_fw_part_summary
struct switchtec_fw_part_summary * switchtec_fw_part_summary(struct switchtec_dev *dev)
Return firmware summary information structure for the flash partitfons in the device.
Definition: fw.c:1243
switchtec_fw_part_summary_free
void switchtec_fw_part_summary_free(struct switchtec_fw_part_summary *summary)
Free a firmware part summary data structure.
Definition: fw.c:1328
gas_mrpc_write_from_gas
ssize_t gas_mrpc_write_from_gas(struct switchtec_dev *dev, int fd, const void __gas *src, size_t n)
Call write() with data from the GAS using an MRPC command.
Definition: gas_mrpc.c:131
gasptr_t
__gas struct switchtec_gas * gasptr_t
Shortform for a pointer to the GAS register space.
Definition: switchtec.h:83
gas_mrpc_memcpy_to_gas
void gas_mrpc_memcpy_to_gas(struct switchtec_dev *dev, void __gas *dest, const void *src, size_t n)
Copy data to the GAS using MRPC commands.
Definition: gas_mrpc.c:59
switchtec_event_wait
int switchtec_event_wait(struct switchtec_dev *dev, int timeout_ms)
Wait for any event to occur (typically just an interrupt)
Definition: platform.c:329
write_from_gas
ssize_t write_from_gas(struct switchtec_dev *dev, int fd, const void __gas *src, size_t n)
Call write() with data from the GAS.
Definition: platform.c:505
switchtec_open_by_path
struct switchtec_dev * switchtec_open_by_path(const char *path)
Open a switchtec device by path.
Definition: linux.c:999
switchtec_device_info
Represents a Switchtec device in the switchtec_list() function.
Definition: switchtec.h:155
switchtec_fw_part_summary
Definition: switchtec.h:308
mrpc_error_cmd
int mrpc_error_cmd
The MRPC command ID when errno is set.
Definition: switchtec.c:603
switchtec_cmd
int switchtec_cmd(struct switchtec_dev *dev, uint32_t cmd, const void *payload, size_t payload_len, void *resp, size_t resp_len)
Execute an MRPC command.
Definition: platform.c:164
switchtec_event_ctl
int switchtec_event_ctl(struct switchtec_dev *dev, enum switchtec_event_id e, int index, int flags, uint32_t data[5])
Enable, disable and clear events or retrieve event data.
Definition: platform.c:313
gas_read8
int gas_read8(struct switchtec_dev *dev, uint8_t __gas *addr, uint8_t *val)
Read a uint8_t from the GAS.
Definition: platform.c:346