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

Commit 3f1f39c4 authored by David S. Miller's avatar David S. Miller
Browse files
parents dfe9a837 7481806d
Loading
Loading
Loading
Loading
+55 −45
Original line number Diff line number Diff line
@@ -292,8 +292,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,

	d_fnstart(3, dev, "(i2400m %p ss %p [%u])\n", i2400m, ss, i2400m_state);

	if (unlikely(i2400m->ready == 0))	/* act if up */
		goto out;
	if (i2400m->state != i2400m_state) {
		i2400m->state = i2400m_state;
		wake_up_all(&i2400m->state_wq);
@@ -341,7 +339,6 @@ void i2400m_report_tlv_system_state(struct i2400m *i2400m,
		i2400m->bus_reset(i2400m, I2400M_RT_WARM);
		break;
	};
out:
	d_fnend(3, dev, "(i2400m %p ss %p [%u]) = void\n",
		i2400m, ss, i2400m_state);
}
@@ -372,8 +369,6 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,

	d_fnstart(3, dev, "(i2400m %p ms %p [%u])\n", i2400m, ms, status);

	if (unlikely(i2400m->ready == 0))	/* act if up */
		goto out;
	switch (status) {
	case I2400M_MEDIA_STATUS_LINK_UP:
		netif_carrier_on(net_dev);
@@ -393,50 +388,32 @@ void i2400m_report_tlv_media_status(struct i2400m *i2400m,
		dev_err(dev, "HW BUG? unknown media status %u\n",
			status);
	};
out:
	d_fnend(3, dev, "(i2400m %p ms %p [%u]) = void\n",
		i2400m, ms, status);
}


/*
 * Parse a 'state report' and extract carrier on/off information
 * Process a TLV from a 'state report'
 *
 * @i2400m: device descriptor
 * @l3l4_hdr: pointer to message; it has been already validated for
 * @tlv: pointer to the TLV header; it has been already validated for
 *     consistent size.
 * @size: size of the message (header + payload). The header length
 *        declaration is assumed to be congruent with @size (as in
 *        sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
 *
 * Extract from the report state the system state TLV and infer from
 * there if we have a carrier or not. Update our local state and tell
 * netdev.
 * @tag: for error messages
 *
 * When setting the carrier, it's fine to set OFF twice (for example),
 * as netif_carrier_off() will not generate two OFF events (just on
 * the transitions).
 * Act on the TLVs from a 'state report'.
 */
static
void i2400m_report_state_hook(struct i2400m *i2400m,
			      const struct i2400m_l3l4_hdr *l3l4_hdr,
			      size_t size, const char *tag)
void i2400m_report_state_parse_tlv(struct i2400m *i2400m,
				   const struct i2400m_tlv_hdr *tlv,
				   const char *tag)
{
	struct device *dev = i2400m_dev(i2400m);
	const struct i2400m_tlv_hdr *tlv;
	const struct i2400m_tlv_media_status *ms;
	const struct i2400m_tlv_system_state *ss;
	const struct i2400m_tlv_rf_switches_status *rfss;
	const struct i2400m_tlv_media_status *ms;
	size_t tlv_size = le16_to_cpu(l3l4_hdr->length);

	d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
		  i2400m, l3l4_hdr, size, tag);
	tlv = NULL;

	while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
					     tlv_size, tlv))) {
		if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE,
					  sizeof(*ss))) {
	if (0 == i2400m_tlv_match(tlv, I2400M_TLV_SYSTEM_STATE, sizeof(*ss))) {
		ss = container_of(tlv, typeof(*ss), hdr);
		d_printf(2, dev, "%s: system state TLV "
			 "found (0x%04x), state 0x%08x\n",
@@ -444,8 +421,7 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
			 le32_to_cpu(ss->state));
		i2400m_report_tlv_system_state(i2400m, ss);
	}
		if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS,
					  sizeof(*rfss))) {
	if (0 == i2400m_tlv_match(tlv, I2400M_TLV_RF_STATUS, sizeof(*rfss))) {
		rfss = container_of(tlv, typeof(*rfss), hdr);
		d_printf(2, dev, "%s: RF status TLV "
			 "found (0x%04x), sw 0x%02x hw 0x%02x\n",
@@ -454,14 +430,43 @@ void i2400m_report_state_hook(struct i2400m *i2400m,
			 le32_to_cpu(rfss->hw_rf_switch));
		i2400m_report_tlv_rf_switches_status(i2400m, rfss);
	}
		if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS,
					  sizeof(*ms))) {
	if (0 == i2400m_tlv_match(tlv, I2400M_TLV_MEDIA_STATUS, sizeof(*ms))) {
		ms = container_of(tlv, typeof(*ms), hdr);
		d_printf(2, dev, "%s: Media Status TLV: %u\n",
			 tag, le32_to_cpu(ms->media_status));
		i2400m_report_tlv_media_status(i2400m, ms);
	}
}


/*
 * Parse a 'state report' and extract information
 *
 * @i2400m: device descriptor
 * @l3l4_hdr: pointer to message; it has been already validated for
 *            consistent size.
 * @size: size of the message (header + payload). The header length
 *        declaration is assumed to be congruent with @size (as in
 *        sizeof(*l3l4_hdr) + l3l4_hdr->length == size)
 *
 * Walk over the TLVs in a report state and act on them.
 */
static
void i2400m_report_state_hook(struct i2400m *i2400m,
			      const struct i2400m_l3l4_hdr *l3l4_hdr,
			      size_t size, const char *tag)
{
	struct device *dev = i2400m_dev(i2400m);
	const struct i2400m_tlv_hdr *tlv;
	size_t tlv_size = le16_to_cpu(l3l4_hdr->length);

	d_fnstart(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s)\n",
		  i2400m, l3l4_hdr, size, tag);
	tlv = NULL;

	while ((tlv = i2400m_tlv_buffer_walk(i2400m, &l3l4_hdr->pl,
					     tlv_size, tlv)))
		i2400m_report_state_parse_tlv(i2400m, tlv, tag);
	d_fnend(4, dev, "(i2400m %p, l3l4_hdr %p, size %zu, %s) = void\n",
		i2400m, l3l4_hdr, size, tag);
}
@@ -721,6 +726,8 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
		ack_timeout = HZ;
	};

	if (unlikely(i2400m->trace_msg_from_user))
		wimax_msg(&i2400m->wimax_dev, "echo", buf, buf_len, GFP_KERNEL);
	/* The RX path in rx.c will put any response for this message
	 * in i2400m->ack_skb and wake us up. If we cancel the wait,
	 * we need to change the value of i2400m->ack_skb to something
@@ -755,6 +762,9 @@ struct sk_buff *i2400m_msg_to_dev(struct i2400m *i2400m,
	ack_l3l4_hdr = wimax_msg_data_len(ack_skb, &ack_len);

	/* Check the ack and deliver it if it is ok */
	if (unlikely(i2400m->trace_msg_from_user))
		wimax_msg(&i2400m->wimax_dev, "echo",
			  ack_l3l4_hdr, ack_len, GFP_KERNEL);
	result = i2400m_msg_size_check(i2400m, ack_l3l4_hdr, ack_len);
	if (result < 0) {
		dev_err(dev, "HW BUG? reply to message 0x%04x: %d\n",
+2 −3
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@
 *   unregister_netdev()
 */
#include "i2400m.h"
#include <linux/etherdevice.h>
#include <linux/wimax/i2400m.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -234,9 +235,6 @@ int i2400m_op_msg_from_user(struct wimax_dev *wimax_dev,
	result = PTR_ERR(ack_skb);
	if (IS_ERR(ack_skb))
		goto error_msg_to_dev;
	if (unlikely(i2400m->trace_msg_from_user))
		wimax_msg(&i2400m->wimax_dev, "trace",
			  msg_buf, msg_len, GFP_KERNEL);
	result = wimax_msg_send(&i2400m->wimax_dev, ack_skb);
error_msg_to_dev:
	d_fnend(4, dev, "(wimax_dev %p [i2400m %p] msg_buf %p msg_len %zu "
@@ -650,6 +648,7 @@ int i2400m_setup(struct i2400m *i2400m, enum i2400m_bri bm_flags)
	result = i2400m_read_mac_addr(i2400m);
	if (result < 0)
		goto error_read_mac_addr;
	random_ether_addr(i2400m->src_mac_addr);

	result = register_netdev(net_dev);	/* Okey dokey, bring it up */
	if (result < 0) {
+5 −0
Original line number Diff line number Diff line
@@ -323,6 +323,10 @@ struct i2400m_roq;
 *     delivered. Then the driver can release them to the host. See
 *     drivers/net/i2400m/rx.c for details.
 *
 * @src_mac_addr: MAC address used to make ethernet packets be coming
 *     from. This is generated at i2400m_setup() time and used during
 *     the life cycle of the instance. See i2400m_fake_eth_header().
 *
 * @init_mutex: Mutex used for serializing the device bringup
 *     sequence; this way if the device reboots in the middle, we
 *     don't try to do a bringup again while we are tearing down the
@@ -421,6 +425,7 @@ struct i2400m {
	unsigned rx_pl_num, rx_pl_max, rx_pl_min,
		rx_num, rx_size_acc, rx_size_min, rx_size_max;
	struct i2400m_roq *rx_roq;	/* not under rx_lock! */
	u8 src_mac_addr[ETH_HLEN];

	struct mutex msg_mutex;		/* serialize command execution */
	struct completion msg_completion;
+3 −1
Original line number Diff line number Diff line
@@ -404,10 +404,12 @@ static
void i2400m_rx_fake_eth_header(struct net_device *net_dev,
			       void *_eth_hdr, __be16 protocol)
{
	struct i2400m *i2400m = net_dev_to_i2400m(net_dev);
	struct ethhdr *eth_hdr = _eth_hdr;

	memcpy(eth_hdr->h_dest, net_dev->dev_addr, sizeof(eth_hdr->h_dest));
	memset(eth_hdr->h_source, 0, sizeof(eth_hdr->h_dest));
	memcpy(eth_hdr->h_source, i2400m->src_mac_addr,
	       sizeof(eth_hdr->h_source));
	eth_hdr->h_proto = protocol;
}

+5 −1
Original line number Diff line number Diff line
@@ -177,6 +177,7 @@ void i2400m_report_hook_work(struct work_struct *ws)
	struct i2400m_work *iw =
		container_of(ws, struct i2400m_work, ws);
	struct i2400m_report_hook_args *args = (void *) iw->pl;
	if (iw->i2400m->ready)
		i2400m_report_hook(iw->i2400m, args->l3l4_hdr, args->size);
	kfree_skb(args->skb_rx);
	i2400m_put(iw->i2400m);
@@ -309,6 +310,9 @@ void i2400m_rx_ctl(struct i2400m *i2400m, struct sk_buff *skb_rx,
		skb_get(skb_rx);
		i2400m_queue_work(i2400m, i2400m_report_hook_work,
				  GFP_KERNEL, &args, sizeof(args));
		if (unlikely(i2400m->trace_msg_from_user))
			wimax_msg(&i2400m->wimax_dev, "echo",
				  l3l4_hdr, size, GFP_KERNEL);
		result = wimax_msg(&i2400m->wimax_dev, NULL, l3l4_hdr, size,
				   GFP_KERNEL);
		if (result < 0)
Loading