Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc550216 authored by Stefan Richter's avatar Stefan Richter
Browse files

firewire: cdev: add PHY pinging



This extends the FW_CDEV_IOC_SEND_PHY_PACKET ioctl() for /dev/fw* to be
useful for ping time measurements.  One application for it would be gap
count optimization in userspace that is based on ping times rather than
hop count.  (The latter is implemented in firewire-core itself but is
not applicable to beta PHYs that act as repeater.)

Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent bf54e146
Loading
Loading
Loading
Loading
+6 −3
Original line number Diff line number Diff line
@@ -1423,9 +1423,10 @@ static void outbound_phy_packet_callback(struct fw_packet *packet,
	/* stale generation; cancelled; on certain controllers: no ack */
	default:		e->phy_packet.rcode = status;		break;
	}
	e->phy_packet.data[0] = packet->timestamp;

	queue_event(e->client, &e->event,
		    &e->phy_packet, sizeof(e->phy_packet), NULL, 0);
	queue_event(e->client, &e->event, &e->phy_packet,
		    sizeof(e->phy_packet) + e->phy_packet.length, NULL, 0);
	client_put(e->client);
}

@@ -1439,7 +1440,7 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
	if (!client->device->is_local)
		return -ENOSYS;

	e = kzalloc(sizeof(*e), GFP_KERNEL);
	e = kzalloc(sizeof(*e) + 4, GFP_KERNEL);
	if (e == NULL)
		return -ENOMEM;

@@ -1453,6 +1454,8 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
	e->p.callback		= outbound_phy_packet_callback;
	e->phy_packet.closure	= a->closure;
	e->phy_packet.type	= FW_CDEV_EVENT_PHY_PACKET_SENT;
	if (is_ping_packet(a->data))
			e->phy_packet.length = 4;

	card->driver->send_request(card, &e->p);

+5 −0
Original line number Diff line number Diff line
@@ -234,4 +234,9 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header,
void fw_send_phy_config(struct fw_card *card,
			int node_id, int generation, int gap_count);

static inline bool is_ping_packet(u32 *data)
{
	return (data[0] & 0xc0ffffff) == 0 && ~data[0] == data[1];
}

#endif /* _FIREWIRE_CORE_H */
+3 −0
Original line number Diff line number Diff line
@@ -1068,6 +1068,9 @@ static int at_context_queue_packet(struct context *ctx,
		header[1] = cpu_to_le32(packet->header[0]);
		header[2] = cpu_to_le32(packet->header[1]);
		d[0].req_count = cpu_to_le16(12);

		if (is_ping_packet(packet->header))
			d[0].control |= cpu_to_le16(DESCRIPTOR_PING);
		break;

	case 4:
+4 −1
Original line number Diff line number Diff line
@@ -294,7 +294,10 @@ struct fw_cdev_event_iso_resource {
 * @length:	Data length in bytes
 * @data:	Incoming data
 *
 * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty.
 * If @type is %FW_CDEV_EVENT_PHY_PACKET_SENT, @length is 0 and @data empty,
 * except in case of a ping packet:  Then, @length is 4, and @data[0] is the
 * ping time in 49.152MHz clocks if @rcode is %RCODE_COMPLETE.
 *
 * If @type is %FW_CDEV_EVENT_PHY_PACKET_RECEIVED, @length is 8 and @data
 * consists of the two PHY packet quadlets, in host byte order.
 */