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

Commit 5b06db16 authored by Clemens Ladisch's avatar Clemens Ladisch Committed by Stefan Richter
Browse files

firewire: make PHY packet header format consistent



Change the header of PHY packets to be sent to include a pseudo
transaction code.  This makes the header consistent with that of
received PHY packets, and allows at_context_queue_packet() and
log_ar_at_event() to see the packet type directly instead of having
to deduce it from the header length or even from the header contents.

Signed-off-by: default avatarClemens Ladisch <clemens@ladisch.de>
Signed-off-by: default avatarStefan Richter <stefanr@s5r6.in-berlin.de>
parent 8327b37b
Loading
Loading
Loading
Loading
+4 −3
Original line number Diff line number Diff line
@@ -1501,9 +1501,10 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg)
	e->client		= client;
	e->p.speed		= SCODE_100;
	e->p.generation		= a->generation;
	e->p.header[0]		= a->data[0];
	e->p.header[1]		= a->data[1];
	e->p.header_length	= 8;
	e->p.header[0]		= TCODE_LINK_INTERNAL << 4;
	e->p.header[1]		= a->data[0];
	e->p.header[2]		= a->data[1];
	e->p.header_length	= 12;
	e->p.callback		= outbound_phy_packet_callback;
	e->phy_packet.closure	= a->closure;
	e->phy_packet.type	= FW_CDEV_EVENT_PHY_PACKET_SENT;
+4 −3
Original line number Diff line number Diff line
@@ -423,7 +423,8 @@ static void transmit_phy_packet_callback(struct fw_packet *packet,
}

static struct fw_packet phy_config_packet = {
	.header_length	= 8,
	.header_length	= 12,
	.header[0]	= TCODE_LINK_INTERNAL << 4,
	.payload_length	= 0,
	.speed		= SCODE_100,
	.callback	= transmit_phy_packet_callback,
@@ -451,8 +452,8 @@ void fw_send_phy_config(struct fw_card *card,

	mutex_lock(&phy_config_mutex);

	phy_config_packet.header[0] = data;
	phy_config_packet.header[1] = ~data;
	phy_config_packet.header[1] = data;
	phy_config_packet.header[2] = ~data;
	phy_config_packet.generation = generation;
	INIT_COMPLETION(phy_config_done);

+3 −1
Original line number Diff line number Diff line
@@ -215,9 +215,11 @@ static inline bool is_next_generation(int new_generation, int old_generation)

/* -transaction */

#define TCODE_LINK_INTERNAL		0xe

#define TCODE_IS_READ_REQUEST(tcode)	(((tcode) & ~1) == 4)
#define TCODE_IS_BLOCK_PACKET(tcode)	(((tcode) &  1) != 0)
#define TCODE_IS_LINK_INTERNAL(tcode)	((tcode) == 0xe)
#define TCODE_IS_LINK_INTERNAL(tcode)	((tcode) == TCODE_LINK_INTERNAL)
#define TCODE_IS_REQUEST(tcode)		(((tcode) &  2) == 0)
#define TCODE_IS_RESPONSE(tcode)	(((tcode) &  2) != 0)
#define TCODE_HAS_REQUEST_DATA(tcode)	(((tcode) & 12) != 4)
+22 −22
Original line number Diff line number Diff line
@@ -418,10 +418,6 @@ static const char *tcodes[] = {
	[0xc] = "-reserved-",		[0xd] = "-reserved-",
	[0xe] = "link internal",	[0xf] = "-reserved-",
};
static const char *phys[] = {
	[0x0] = "phy config packet",	[0x1] = "link-on packet",
	[0x2] = "self-id packet",	[0x3] = "-reserved-",
};

static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
{
@@ -440,12 +436,6 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
		return;
	}

	if (header[0] == ~header[1]) {
		fw_notify("A%c %s, %s, %08x\n",
		    dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]);
		return;
	}

	switch (tcode) {
	case 0x0: case 0x6: case 0x8:
		snprintf(specific, sizeof(specific), " = %08x",
@@ -460,9 +450,13 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt)
	}

	switch (tcode) {
	case 0xe: case 0xa:
	case 0xa:
		fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]);
		break;
	case 0xe:
		fw_notify("A%c %s, PHY %08x %08x\n",
			  dir, evts[evt], header[1], header[2]);
		break;
	case 0x0: case 0x1: case 0x4: case 0x5: case 0x9:
		fw_notify("A%c spd %x tl %02x, "
		    "%04x -> %04x, %s, "
@@ -1250,21 +1244,27 @@ static int at_context_queue_packet(struct context *ctx,
	/*
	 * The DMA format for asyncronous link packets is different
	 * from the IEEE1394 layout, so shift the fields around
	 * accordingly.  If header_length is 8, it's a PHY packet, to
	 * which we need to prepend an extra quadlet.
	 * accordingly.
	 */

	tcode = (packet->header[0] >> 4) & 0x0f;
	header = (__le32 *) &d[1];
	switch (packet->header_length) {
	case 16:
	case 12:
	switch (tcode) {
	case TCODE_WRITE_QUADLET_REQUEST:
	case TCODE_WRITE_BLOCK_REQUEST:
	case TCODE_WRITE_RESPONSE:
	case TCODE_READ_QUADLET_REQUEST:
	case TCODE_READ_BLOCK_REQUEST:
	case TCODE_READ_QUADLET_RESPONSE:
	case TCODE_READ_BLOCK_RESPONSE:
	case TCODE_LOCK_REQUEST:
	case TCODE_LOCK_RESPONSE:
		header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
					(packet->speed << 16));
		header[1] = cpu_to_le32((packet->header[1] & 0xffff) |
					(packet->header[0] & 0xffff0000));
		header[2] = cpu_to_le32(packet->header[2]);

		tcode = (packet->header[0] >> 4) & 0x0f;
		if (TCODE_IS_BLOCK_PACKET(tcode))
			header[3] = cpu_to_le32(packet->header[3]);
		else
@@ -1273,18 +1273,18 @@ static int at_context_queue_packet(struct context *ctx,
		d[0].req_count = cpu_to_le16(packet->header_length);
		break;

	case 8:
	case TCODE_LINK_INTERNAL:
		header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) |
					(packet->speed << 16));
		header[1] = cpu_to_le32(packet->header[0]);
		header[2] = cpu_to_le32(packet->header[1]);
		header[1] = cpu_to_le32(packet->header[1]);
		header[2] = cpu_to_le32(packet->header[2]);
		d[0].req_count = cpu_to_le16(12);

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

	case 4:
	case TCODE_STREAM_DATA:
		header[0] = cpu_to_le32((packet->header[0] & 0xffff) |
					(packet->speed << 16));
		header[1] = cpu_to_le32(packet->header[0] & 0xffff0000);