brintos

brintos / linux-shallow public Read only

0
0
Text · 17.5 KiB · 89dc4c4 Raw
773 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/* Copyright (C) 2021 in-tech smart charging GmbH3 *4 * driver is based on micrel/ks8851_spi.c5 */6 7#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt8 9#include <linux/interrupt.h>10#include <linux/module.h>11#include <linux/kernel.h>12#include <linux/netdevice.h>13#include <linux/etherdevice.h>14#include <linux/ethtool.h>15#include <linux/cache.h>16#include <linux/debugfs.h>17#include <linux/seq_file.h>18 19#include <linux/spi/spi.h>20#include <linux/of_net.h>21 22#define MSG_DEFAULT	(NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK | \23			 NETIF_MSG_TIMER)24 25#define DRV_NAME	"mse102x"26 27#define DET_CMD		0x000128#define DET_SOF		0x000229#define DET_DFT		0x55AA30 31#define CMD_SHIFT	1232#define CMD_RTS		(0x1 << CMD_SHIFT)33#define CMD_CTR		(0x2 << CMD_SHIFT)34 35#define CMD_MASK	GENMASK(15, CMD_SHIFT)36#define LEN_MASK	GENMASK(CMD_SHIFT - 1, 0)37 38#define DET_CMD_LEN	439#define DET_SOF_LEN	240#define DET_DFT_LEN	241 42#define MIN_FREQ_HZ	600000043#define MAX_FREQ_HZ	714285744 45struct mse102x_stats {46	u64 xfer_err;47	u64 invalid_cmd;48	u64 invalid_ctr;49	u64 invalid_dft;50	u64 invalid_len;51	u64 invalid_rts;52	u64 invalid_sof;53	u64 tx_timeout;54};55 56static const char mse102x_gstrings_stats[][ETH_GSTRING_LEN] = {57	"SPI transfer errors",58	"Invalid command",59	"Invalid CTR",60	"Invalid DFT",61	"Invalid frame length",62	"Invalid RTS",63	"Invalid SOF",64	"TX timeout",65};66 67struct mse102x_net {68	struct net_device	*ndev;69 70	u8			rxd[8];71	u8			txd[8];72 73	u32			msg_enable ____cacheline_aligned;74 75	struct sk_buff_head	txq;76	struct mse102x_stats	stats;77};78 79struct mse102x_net_spi {80	struct mse102x_net	mse102x;81	struct mutex		lock;		/* Protect SPI frame transfer */82	struct work_struct	tx_work;83	struct spi_device	*spidev;84	struct spi_message	spi_msg;85	struct spi_transfer	spi_xfer;86 87#ifdef CONFIG_DEBUG_FS88	struct dentry		*device_root;89#endif90};91 92#define to_mse102x_spi(mse) container_of((mse), struct mse102x_net_spi, mse102x)93 94#ifdef CONFIG_DEBUG_FS95 96static int mse102x_info_show(struct seq_file *s, void *what)97{98	struct mse102x_net_spi *mses = s->private;99 100	seq_printf(s, "TX ring size        : %u\n",101		   skb_queue_len(&mses->mse102x.txq));102 103	seq_printf(s, "IRQ                 : %d\n",104		   mses->spidev->irq);105 106	seq_printf(s, "SPI effective speed : %lu\n",107		   (unsigned long)mses->spi_xfer.effective_speed_hz);108	seq_printf(s, "SPI mode            : %x\n",109		   mses->spidev->mode);110 111	return 0;112}113DEFINE_SHOW_ATTRIBUTE(mse102x_info);114 115static void mse102x_init_device_debugfs(struct mse102x_net_spi *mses)116{117	mses->device_root = debugfs_create_dir(dev_name(&mses->mse102x.ndev->dev),118					       NULL);119 120	debugfs_create_file("info", S_IFREG | 0444, mses->device_root, mses,121			    &mse102x_info_fops);122}123 124static void mse102x_remove_device_debugfs(struct mse102x_net_spi *mses)125{126	debugfs_remove_recursive(mses->device_root);127}128 129#else /* CONFIG_DEBUG_FS */130 131static void mse102x_init_device_debugfs(struct mse102x_net_spi *mses)132{133}134 135static void mse102x_remove_device_debugfs(struct mse102x_net_spi *mses)136{137}138 139#endif140 141/* SPI register read/write calls.142 *143 * All these calls issue SPI transactions to access the chip's registers. They144 * all require that the necessary lock is held to prevent accesses when the145 * chip is busy transferring packet data.146 */147 148static void mse102x_tx_cmd_spi(struct mse102x_net *mse, u16 cmd)149{150	struct mse102x_net_spi *mses = to_mse102x_spi(mse);151	struct spi_transfer *xfer = &mses->spi_xfer;152	struct spi_message *msg = &mses->spi_msg;153	__be16 txb[2];154	int ret;155 156	txb[0] = cpu_to_be16(DET_CMD);157	txb[1] = cpu_to_be16(cmd);158 159	xfer->tx_buf = txb;160	xfer->rx_buf = NULL;161	xfer->len = DET_CMD_LEN;162 163	ret = spi_sync(mses->spidev, msg);164	if (ret < 0) {165		netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",166			   __func__, ret);167		mse->stats.xfer_err++;168	}169}170 171static int mse102x_rx_cmd_spi(struct mse102x_net *mse, u8 *rxb)172{173	struct mse102x_net_spi *mses = to_mse102x_spi(mse);174	struct spi_transfer *xfer = &mses->spi_xfer;175	struct spi_message *msg = &mses->spi_msg;176	__be16 *txb = (__be16 *)mse->txd;177	__be16 *cmd = (__be16 *)mse->rxd;178	u8 *trx = mse->rxd;179	int ret;180 181	txb[0] = 0;182	txb[1] = 0;183 184	xfer->tx_buf = txb;185	xfer->rx_buf = trx;186	xfer->len = DET_CMD_LEN;187 188	ret = spi_sync(mses->spidev, msg);189	if (ret < 0) {190		netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",191			   __func__, ret);192		mse->stats.xfer_err++;193	} else if (*cmd != cpu_to_be16(DET_CMD)) {194		net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",195				    __func__, *cmd);196		mse->stats.invalid_cmd++;197		ret = -EIO;198	} else {199		memcpy(rxb, trx + 2, 2);200	}201 202	return ret;203}204 205static inline void mse102x_push_header(struct sk_buff *skb)206{207	__be16 *header = skb_push(skb, DET_SOF_LEN);208 209	*header = cpu_to_be16(DET_SOF);210}211 212static inline void mse102x_put_footer(struct sk_buff *skb)213{214	__be16 *footer = skb_put(skb, DET_DFT_LEN);215 216	*footer = cpu_to_be16(DET_DFT);217}218 219static int mse102x_tx_frame_spi(struct mse102x_net *mse, struct sk_buff *txp,220				unsigned int pad)221{222	struct mse102x_net_spi *mses = to_mse102x_spi(mse);223	struct spi_transfer *xfer = &mses->spi_xfer;224	struct spi_message *msg = &mses->spi_msg;225	struct sk_buff *tskb = NULL;226	int ret;227 228	netif_dbg(mse, tx_queued, mse->ndev, "%s: skb %p, %d@%p\n",229		  __func__, txp, txp->len, txp->data);230 231	if ((skb_headroom(txp) < DET_SOF_LEN) ||232	    (skb_tailroom(txp) < DET_DFT_LEN + pad)) {233		tskb = skb_copy_expand(txp, DET_SOF_LEN, DET_DFT_LEN + pad,234				       GFP_KERNEL);235		if (!tskb)236			return -ENOMEM;237 238		txp = tskb;239	}240 241	mse102x_push_header(txp);242 243	if (pad)244		skb_put_zero(txp, pad);245 246	mse102x_put_footer(txp);247 248	xfer->tx_buf = txp->data;249	xfer->rx_buf = NULL;250	xfer->len = txp->len;251 252	ret = spi_sync(mses->spidev, msg);253	if (ret < 0) {254		netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",255			   __func__, ret);256		mse->stats.xfer_err++;257	}258 259	dev_kfree_skb(tskb);260 261	return ret;262}263 264static int mse102x_rx_frame_spi(struct mse102x_net *mse, u8 *buff,265				unsigned int frame_len)266{267	struct mse102x_net_spi *mses = to_mse102x_spi(mse);268	struct spi_transfer *xfer = &mses->spi_xfer;269	struct spi_message *msg = &mses->spi_msg;270	__be16 *sof = (__be16 *)buff;271	__be16 *dft = (__be16 *)(buff + DET_SOF_LEN + frame_len);272	int ret;273 274	xfer->rx_buf = buff;275	xfer->tx_buf = NULL;276	xfer->len = DET_SOF_LEN + frame_len + DET_DFT_LEN;277 278	ret = spi_sync(mses->spidev, msg);279	if (ret < 0) {280		netdev_err(mse->ndev, "%s: spi_sync() failed: %d\n",281			   __func__, ret);282		mse->stats.xfer_err++;283	} else if (*sof != cpu_to_be16(DET_SOF)) {284		netdev_dbg(mse->ndev, "%s: SPI start of frame is invalid (0x%04x)\n",285			   __func__, *sof);286		mse->stats.invalid_sof++;287		ret = -EIO;288	} else if (*dft != cpu_to_be16(DET_DFT)) {289		netdev_dbg(mse->ndev, "%s: SPI frame tail is invalid (0x%04x)\n",290			   __func__, *dft);291		mse->stats.invalid_dft++;292		ret = -EIO;293	}294 295	return ret;296}297 298static void mse102x_dump_packet(const char *msg, int len, const char *data)299{300	printk(KERN_DEBUG ": %s - packet len:%d\n", msg, len);301	print_hex_dump(KERN_DEBUG, "pk data: ", DUMP_PREFIX_OFFSET, 16, 1,302		       data, len, true);303}304 305static void mse102x_rx_pkt_spi(struct mse102x_net *mse)306{307	struct sk_buff *skb;308	unsigned int rxalign;309	unsigned int rxlen;310	__be16 rx = 0;311	u16 cmd_resp;312	u8 *rxpkt;313	int ret;314 315	mse102x_tx_cmd_spi(mse, CMD_CTR);316	ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx);317	cmd_resp = be16_to_cpu(rx);318 319	if (ret || ((cmd_resp & CMD_MASK) != CMD_RTS)) {320		usleep_range(50, 100);321 322		mse102x_tx_cmd_spi(mse, CMD_CTR);323		ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx);324		if (ret)325			return;326 327		cmd_resp = be16_to_cpu(rx);328		if ((cmd_resp & CMD_MASK) != CMD_RTS) {329			net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",330					    __func__, cmd_resp);331			mse->stats.invalid_rts++;332			return;333		}334 335		net_dbg_ratelimited("%s: Unexpected response to first CMD\n",336				    __func__);337	}338 339	rxlen = cmd_resp & LEN_MASK;340	if (!rxlen) {341		net_dbg_ratelimited("%s: No frame length defined\n", __func__);342		mse->stats.invalid_len++;343		return;344	}345 346	rxalign = ALIGN(rxlen + DET_SOF_LEN + DET_DFT_LEN, 4);347	skb = netdev_alloc_skb_ip_align(mse->ndev, rxalign);348	if (!skb)349		return;350 351	/* 2 bytes Start of frame (before ethernet header)352	 * 2 bytes Data frame tail (after ethernet frame)353	 * They are copied, but ignored.354	 */355	rxpkt = skb_put(skb, rxlen) - DET_SOF_LEN;356	if (mse102x_rx_frame_spi(mse, rxpkt, rxlen)) {357		mse->ndev->stats.rx_errors++;358		dev_kfree_skb(skb);359		return;360	}361 362	if (netif_msg_pktdata(mse))363		mse102x_dump_packet(__func__, skb->len, skb->data);364 365	skb->protocol = eth_type_trans(skb, mse->ndev);366	netif_rx(skb);367 368	mse->ndev->stats.rx_packets++;369	mse->ndev->stats.rx_bytes += rxlen;370}371 372static int mse102x_tx_pkt_spi(struct mse102x_net *mse, struct sk_buff *txb,373			      unsigned long work_timeout)374{375	unsigned int pad = 0;376	__be16 rx = 0;377	u16 cmd_resp;378	int ret;379	bool first = true;380 381	if (txb->len < ETH_ZLEN)382		pad = ETH_ZLEN - txb->len;383 384	while (1) {385		mse102x_tx_cmd_spi(mse, CMD_RTS | (txb->len + pad));386		ret = mse102x_rx_cmd_spi(mse, (u8 *)&rx);387		cmd_resp = be16_to_cpu(rx);388 389		if (!ret) {390			/* ready to send frame ? */391			if (cmd_resp == CMD_CTR)392				break;393 394			net_dbg_ratelimited("%s: Unexpected response (0x%04x)\n",395					    __func__, cmd_resp);396			mse->stats.invalid_ctr++;397		}398 399		/* It's not predictable how long / many retries it takes to400		 * send at least one packet, so TX timeouts are possible.401		 * That's the reason why the netdev watchdog is not used here.402		 */403		if (time_after(jiffies, work_timeout))404			return -ETIMEDOUT;405 406		if (first) {407			/* throttle at first issue */408			netif_stop_queue(mse->ndev);409			/* fast retry */410			usleep_range(50, 100);411			first = false;412		} else {413			msleep(20);414		}415	}416 417	ret = mse102x_tx_frame_spi(mse, txb, pad);418	if (ret)419		net_dbg_ratelimited("%s: Failed to send (%d), drop frame\n",420				    __func__, ret);421 422	return ret;423}424 425#define TX_QUEUE_MAX 10426 427static void mse102x_tx_work(struct work_struct *work)428{429	/* Make sure timeout is sufficient to transfer TX_QUEUE_MAX frames */430	unsigned long work_timeout = jiffies + msecs_to_jiffies(1000);431	struct mse102x_net_spi *mses;432	struct mse102x_net *mse;433	struct sk_buff *txb;434	int ret = 0;435 436	mses = container_of(work, struct mse102x_net_spi, tx_work);437	mse = &mses->mse102x;438 439	while ((txb = skb_dequeue(&mse->txq))) {440		unsigned int len = max_t(unsigned int, txb->len, ETH_ZLEN);441 442		mutex_lock(&mses->lock);443		ret = mse102x_tx_pkt_spi(mse, txb, work_timeout);444		mutex_unlock(&mses->lock);445		if (ret) {446			mse->ndev->stats.tx_dropped++;447		} else {448			mse->ndev->stats.tx_bytes += len;449			mse->ndev->stats.tx_packets++;450		}451 452		dev_kfree_skb(txb);453	}454 455	if (ret == -ETIMEDOUT) {456		if (netif_msg_timer(mse))457			netdev_err_once(mse->ndev, "tx work timeout\n");458 459		mse->stats.tx_timeout++;460	}461 462	netif_wake_queue(mse->ndev);463}464 465static netdev_tx_t mse102x_start_xmit_spi(struct sk_buff *skb,466					  struct net_device *ndev)467{468	struct mse102x_net *mse = netdev_priv(ndev);469	struct mse102x_net_spi *mses = to_mse102x_spi(mse);470 471	netif_dbg(mse, tx_queued, ndev,472		  "%s: skb %p, %d@%p\n", __func__, skb, skb->len, skb->data);473 474	skb_queue_tail(&mse->txq, skb);475 476	if (skb_queue_len(&mse->txq) >= TX_QUEUE_MAX)477		netif_stop_queue(ndev);478 479	schedule_work(&mses->tx_work);480 481	return NETDEV_TX_OK;482}483 484static void mse102x_init_mac(struct mse102x_net *mse, struct device_node *np)485{486	struct net_device *ndev = mse->ndev;487	int ret = of_get_ethdev_address(np, ndev);488 489	if (ret) {490		eth_hw_addr_random(ndev);491		dev_warn(ndev->dev.parent, "Using random MAC address: %pM\n",492			 ndev->dev_addr);493	}494}495 496/* Assumption: this is called for every incoming packet */497static irqreturn_t mse102x_irq(int irq, void *_mse)498{499	struct mse102x_net *mse = _mse;500	struct mse102x_net_spi *mses = to_mse102x_spi(mse);501 502	mutex_lock(&mses->lock);503	mse102x_rx_pkt_spi(mse);504	mutex_unlock(&mses->lock);505 506	return IRQ_HANDLED;507}508 509static int mse102x_net_open(struct net_device *ndev)510{511	struct mse102x_net *mse = netdev_priv(ndev);512	int ret;513 514	ret = request_threaded_irq(ndev->irq, NULL, mse102x_irq, IRQF_ONESHOT,515				   ndev->name, mse);516	if (ret < 0) {517		netdev_err(ndev, "Failed to get irq: %d\n", ret);518		return ret;519	}520 521	netif_dbg(mse, ifup, ndev, "opening\n");522 523	netif_start_queue(ndev);524 525	netif_carrier_on(ndev);526 527	netif_dbg(mse, ifup, ndev, "network device up\n");528 529	return 0;530}531 532static int mse102x_net_stop(struct net_device *ndev)533{534	struct mse102x_net *mse = netdev_priv(ndev);535	struct mse102x_net_spi *mses = to_mse102x_spi(mse);536 537	netif_info(mse, ifdown, ndev, "shutting down\n");538 539	netif_carrier_off(mse->ndev);540 541	/* stop any outstanding work */542	flush_work(&mses->tx_work);543 544	netif_stop_queue(ndev);545 546	skb_queue_purge(&mse->txq);547 548	free_irq(ndev->irq, mse);549 550	return 0;551}552 553static const struct net_device_ops mse102x_netdev_ops = {554	.ndo_open		= mse102x_net_open,555	.ndo_stop		= mse102x_net_stop,556	.ndo_start_xmit		= mse102x_start_xmit_spi,557	.ndo_set_mac_address	= eth_mac_addr,558	.ndo_validate_addr	= eth_validate_addr,559};560 561/* ethtool support */562 563static void mse102x_get_drvinfo(struct net_device *ndev,564				struct ethtool_drvinfo *di)565{566	strscpy(di->driver, DRV_NAME, sizeof(di->driver));567	strscpy(di->bus_info, dev_name(ndev->dev.parent), sizeof(di->bus_info));568}569 570static u32 mse102x_get_msglevel(struct net_device *ndev)571{572	struct mse102x_net *mse = netdev_priv(ndev);573 574	return mse->msg_enable;575}576 577static void mse102x_set_msglevel(struct net_device *ndev, u32 to)578{579	struct mse102x_net *mse = netdev_priv(ndev);580 581	mse->msg_enable = to;582}583 584static void mse102x_get_ethtool_stats(struct net_device *ndev,585				      struct ethtool_stats *estats, u64 *data)586{587	struct mse102x_net *mse = netdev_priv(ndev);588	struct mse102x_stats *st = &mse->stats;589 590	memcpy(data, st, ARRAY_SIZE(mse102x_gstrings_stats) * sizeof(u64));591}592 593static void mse102x_get_strings(struct net_device *ndev, u32 stringset, u8 *buf)594{595	switch (stringset) {596	case ETH_SS_STATS:597		memcpy(buf, &mse102x_gstrings_stats,598		       sizeof(mse102x_gstrings_stats));599		break;600	default:601		WARN_ON(1);602		break;603	}604}605 606static int mse102x_get_sset_count(struct net_device *ndev, int sset)607{608	switch (sset) {609	case ETH_SS_STATS:610		return ARRAY_SIZE(mse102x_gstrings_stats);611	default:612		return -EINVAL;613	}614}615 616static const struct ethtool_ops mse102x_ethtool_ops = {617	.get_drvinfo		= mse102x_get_drvinfo,618	.get_link		= ethtool_op_get_link,619	.get_msglevel		= mse102x_get_msglevel,620	.set_msglevel		= mse102x_set_msglevel,621	.get_ethtool_stats	= mse102x_get_ethtool_stats,622	.get_strings		= mse102x_get_strings,623	.get_sset_count		= mse102x_get_sset_count,624};625 626/* driver bus management functions */627 628static int mse102x_suspend(struct device *dev)629{630	struct mse102x_net *mse = dev_get_drvdata(dev);631	struct net_device *ndev = mse->ndev;632 633	if (netif_running(ndev)) {634		netif_device_detach(ndev);635		mse102x_net_stop(ndev);636	}637 638	return 0;639}640 641static int mse102x_resume(struct device *dev)642{643	struct mse102x_net *mse = dev_get_drvdata(dev);644	struct net_device *ndev = mse->ndev;645 646	if (netif_running(ndev)) {647		mse102x_net_open(ndev);648		netif_device_attach(ndev);649	}650 651	return 0;652}653 654static DEFINE_SIMPLE_DEV_PM_OPS(mse102x_pm_ops, mse102x_suspend, mse102x_resume);655 656static int mse102x_probe_spi(struct spi_device *spi)657{658	struct device *dev = &spi->dev;659	struct mse102x_net_spi *mses;660	struct net_device *ndev;661	struct mse102x_net *mse;662	int ret;663 664	spi->bits_per_word = 8;665	spi->mode |= SPI_MODE_3;666	/* enforce minimum speed to ensure device functionality */667	spi->controller->min_speed_hz = MIN_FREQ_HZ;668 669	if (!spi->max_speed_hz)670		spi->max_speed_hz = MAX_FREQ_HZ;671 672	if (spi->max_speed_hz < MIN_FREQ_HZ ||673	    spi->max_speed_hz > MAX_FREQ_HZ) {674		dev_err(&spi->dev, "SPI max frequency out of range (min: %u, max: %u)\n",675			MIN_FREQ_HZ, MAX_FREQ_HZ);676		return -EINVAL;677	}678 679	ret = spi_setup(spi);680	if (ret < 0) {681		dev_err(&spi->dev, "Unable to setup SPI device: %d\n", ret);682		return ret;683	}684 685	ndev = devm_alloc_etherdev(dev, sizeof(struct mse102x_net_spi));686	if (!ndev)687		return -ENOMEM;688 689	ndev->needed_tailroom += ALIGN(DET_DFT_LEN, 4);690	ndev->needed_headroom += ALIGN(DET_SOF_LEN, 4);691	ndev->priv_flags &= ~IFF_TX_SKB_SHARING;692	ndev->tx_queue_len = 100;693 694	mse = netdev_priv(ndev);695	mses = to_mse102x_spi(mse);696 697	mses->spidev = spi;698	mutex_init(&mses->lock);699	INIT_WORK(&mses->tx_work, mse102x_tx_work);700 701	/* initialise pre-made spi transfer messages */702	spi_message_init(&mses->spi_msg);703	spi_message_add_tail(&mses->spi_xfer, &mses->spi_msg);704 705	ndev->irq = spi->irq;706	mse->ndev = ndev;707 708	/* set the default message enable */709	mse->msg_enable = netif_msg_init(-1, MSG_DEFAULT);710 711	skb_queue_head_init(&mse->txq);712 713	SET_NETDEV_DEV(ndev, dev);714 715	dev_set_drvdata(dev, mse);716 717	netif_carrier_off(mse->ndev);718	ndev->netdev_ops = &mse102x_netdev_ops;719	ndev->ethtool_ops = &mse102x_ethtool_ops;720 721	mse102x_init_mac(mse, dev->of_node);722 723	ret = register_netdev(ndev);724	if (ret) {725		dev_err(dev, "failed to register network device: %d\n", ret);726		return ret;727	}728 729	mse102x_init_device_debugfs(mses);730 731	return 0;732}733 734static void mse102x_remove_spi(struct spi_device *spi)735{736	struct mse102x_net *mse = dev_get_drvdata(&spi->dev);737	struct mse102x_net_spi *mses = to_mse102x_spi(mse);738 739	mse102x_remove_device_debugfs(mses);740	unregister_netdev(mse->ndev);741}742 743static const struct of_device_id mse102x_match_table[] = {744	{ .compatible = "vertexcom,mse1021" },745	{ .compatible = "vertexcom,mse1022" },746	{ }747};748MODULE_DEVICE_TABLE(of, mse102x_match_table);749 750static const struct spi_device_id mse102x_ids[] = {751	{ "mse1021" },752	{ "mse1022" },753	{ }754};755MODULE_DEVICE_TABLE(spi, mse102x_ids);756 757static struct spi_driver mse102x_driver = {758	.driver = {759		.name = DRV_NAME,760		.of_match_table = mse102x_match_table,761		.pm = pm_sleep_ptr(&mse102x_pm_ops),762	},763	.probe = mse102x_probe_spi,764	.remove = mse102x_remove_spi,765	.id_table = mse102x_ids,766};767module_spi_driver(mse102x_driver);768 769MODULE_DESCRIPTION("MSE102x Network driver");770MODULE_AUTHOR("Stefan Wahren <stefan.wahren@chargebyte.com>");771MODULE_LICENSE("GPL");772MODULE_ALIAS("spi:" DRV_NAME);773