USB网卡和以太网交换机“常连”后,增加交换机插拔网线判断机制

这个项目已经做了小半年了,客户是一个做智能电话机的。所谓的智能电话就是一台可以插网线、电话线,外观却是座机的手机。

客户的需求特别奇葩,USB网卡和一个内部的交换机直接通过PCB走线相连接。这个设计导致了系统在插入网线并且网卡link up上报后,网卡就一直处于连接状态,无法判断交换机的wan口网线是否拔出。后面经过大家的会议商讨,决定将交换机wan口led接口引出并接到我们的模块上,利用GPIO去判断LED闪烁状态来设置网卡状态。

于是乎,这个问题就首先落到了BSP这边,而后又落到了我这边,因为我这边是处理外设驱动的看😂

简单讲一下思路:DM9601作为USB网卡,driver_info(usbnet.h)中有一个.status的方法,用于轮询网卡状态。

/* for status polling */
void	(*status)(struct usbnet *, struct urb *);

// 驱动的具体实现
static void dm9601_status(struct usbnet *dev, struct urb *urb)
{
	int link;
	u8 *buf;

	/* format:
	   b0: net status
	   b1: tx status 1
	   b2: tx status 2
	   b3: rx status
	   b4: rx overflow
	   b5: rx count
	   b6: tx count
	   b7: gpr
	*/

	if (urb->actual_length < 8)
		return;

	buf = urb->transfer_buffer;

	link = !!(buf[0] & 0x40);
	if (netif_carrier_ok(dev->net) != link) {
		usbnet_link_change(dev, link, 1);
		netdev_dbg(dev->net, "Link Status is: %d\n", link);
	}
}

通过观察log发现每次插拔网线都会在轮询函数中触发log,再深入分析后发现确实是由该函数来实现网卡link up/down的设置。

于是增加修改如下:

extern struct gpio_desc * eth_switch_gpiod_get(void);
static void dm9601_status(struct usbnet *dev, struct urb *urb)
{
	int link;
	u8 *buf;
	int cnt;
	int val;
	struct gpio_desc * gpiod = NULL;

	/* format:
	   b0: net status
	   b1: tx status 1
	   b2: tx status 2
	   b3: rx status
	   b4: rx overflow
	   b5: rx count
	   b6: tx count
	   b7: gpr
	*/

	if (urb->actual_length < 8)
		return;

	buf = urb->transfer_buffer;

	link = !!(buf[0] & 0x40);
	netdev_info(dev->net, "%s link:%d\n", __func__, link);

	cnt = 0;
	gpiod = eth_switch_gpiod_get();
	if (!IS_ERR_OR_NULL(gpiod)) {
		while (link && (val = gpiod_get_value(gpiod))) {
			netdev_info(dev->net, "gpio%d:%d\n", desc_to_gpio(gpiod), val);
			if (cnt++ > 5) {
				netdev_info(dev->net, "%s link down\n", __func__);
				usbnet_link_change(dev, 0, 1);
				return;
			}
			mdelay(100);
		}
	}

	if (netif_carrier_ok(dev->net) != link) {
		usbnet_link_change(dev, link, 1);
		netdev_info(dev->net, "Link Status is: %d\n", link);
	}
}

解决思路:首先判断当前网卡状态,其次通过GPIO判断LED灯状态,为了防止误判增加重试机制。

如果本文对你有帮助,请不要吝啬你的赞!转载请务必注明来源!

PYPYN.COM 版权所有

发表评论

您的电子邮箱地址不会被公开。