9 #define pr_fmt(fmt) KBUILD_MODNAME ":" fmt
12 #include <linux/sched.h>
13 #include <linux/list.h>
14 #include <linux/netdevice.h>
15 #include <linux/if_arp.h>
23 #define TX_BUF_SZ 0x2000
24 #define RX_BUF_SZ 0x2000
26 #define CAIF_NEEDED_HEADROOM 32
28 #define CAIF_FLOW_ON 1
29 #define CAIF_FLOW_OFF 0
31 #define LOW_WATERMARK 3
32 #define HIGH_WATERMARK 4
35 #define SHM_MAX_FRMS_PER_BUF 10
41 #define SHM_CAIF_DESC_SIZE ((SHM_MAX_FRMS_PER_BUF + 1) * \
42 sizeof(struct shm_pck_desc))
48 #define SHM_CAIF_FRM_OFS (SHM_CAIF_DESC_SIZE + (SHM_CAIF_DESC_SIZE % 32))
54 #define SHM_FRM_PAD_LEN 4
56 #define CAIF_MAX_MTU 4096
58 #define SHM_SET_FULL(x) (((x+1) & 0x0F) << 0)
59 #define SHM_GET_FULL(x) (((x >> 0) & 0x0F) - 1)
61 #define SHM_SET_EMPTY(x) (((x+1) & 0x0F) << 4)
62 #define SHM_GET_EMPTY(x) (((x >> 4) & 0x0F) - 1)
64 #define SHM_FULL_MASK (0x0F << 0)
65 #define SHM_EMPTY_MASK (0x0F << 4)
118 static int shm_netdev_open(
struct net_device *shm_netdev)
120 netif_wake_queue(shm_netdev);
124 static int shm_netdev_close(
struct net_device *shm_netdev)
126 netif_stop_queue(shm_netdev);
135 u32 avail_emptybuff = 0;
136 unsigned long flags = 0;
150 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
153 pr_warn(
"No empty Rx buffers to fill: "
154 "mbx_msg:%x\n", mbx_msg);
170 "phyif_shm_mbx_msg_cb: RX full out of sync:"
171 " idx:%d, msg:%x SHM_GET_FULL(mbx_msg):%x\n",
174 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
180 list_del_init(&pbuf->
list);
183 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
201 pr_warn(
"No TX to empty: msg:%x\n", mbx_msg);
203 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
217 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
221 "out of sync:idx:%d, msg:%x\n", idx, mbx_msg);
226 list_del_init(&pbuf->
list);
242 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
243 pshm_drv->
cfdev.flowctrl
253 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
266 unsigned long flags = 0;
281 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
288 list_del_init(&pbuf->
list);
289 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
299 unsigned int frm_buf_ofs;
300 unsigned int frm_pck_ofs;
301 unsigned int frm_pck_len;
335 if ((frm_pck_ofs + pck_desc->
frm_len) > pbuf->
len)
339 skb = netdev_alloc_skb(pshm_drv->
pshm_dev->pshm_netdev,
343 pr_info(
"OOM: Try next frame in descriptor\n");
351 skb_reset_mac_header(skb);
358 pshm_drv->
pshm_dev->pshm_netdev->stats.
360 pshm_drv->
pshm_dev->pshm_netdev->stats.
363 ++pshm_drv->
pshm_dev->pshm_netdev->stats.
372 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
382 static void shm_tx_work_func(
struct work_struct *tx_work)
385 unsigned int frmlen, avail_emptybuff, append = 0;
386 unsigned long flags = 0;
409 list_del_init(&pbuf->
list);
418 skb = skb_peek(&pshm_drv->
sk_qhead);
427 pshm_drv->tx_empty_available) {
430 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
431 pshm_drv->
cfdev.flowctrl
450 skb = skb_peek(&pshm_drv->
sk_qhead);
464 frmlen += SHM_FRM_PAD_LEN -
475 list_del_init(&pbuf->
list);
487 pshm_drv->
pshm_dev->pshm_netdev->stats.tx_packets++;
488 pshm_drv->
pshm_dev->pshm_netdev->stats.tx_bytes +=
505 pbuf->
frm_ofs += frmlen + (frmlen % 32);
514 spin_unlock_irqrestore(&pshm_drv->
lock, flags);
518 (pshm_drv->
pshm_dev->shm_id, mbox_msg);
526 pshm_drv = netdev_priv(shm_netdev);
538 .ndo_open = shm_netdev_open,
539 .ndo_stop = shm_netdev_close,
540 .ndo_start_xmit = shm_netdev_tx,
543 static void shm_netdev_setup(
struct net_device *pshm_netdev)
554 pshm_drv = netdev_priv(pshm_netdev);
568 "cfshm%d", shm_netdev_setup);
583 pr_warn(
"Could not config. SHM Mailbox,"
584 " Bailing out.....\n");
589 skb_queue_head_init(&pshm_drv->
sk_qhead);
591 pr_info(
"SHM DEVICE[%d] PROBED BY DRIVER, NEW SHM DRIVER"
592 " INSTANCE AT pshm_drv =0x%p\n",
593 pshm_drv->
pshm_dev->shm_id, pshm_drv);
598 pr_warn(
"ERROR, Amount of available"
599 " Phys. SHM cannot accommodate current SHM "
600 "driver configuration, Bailing out ...\n");
635 if (tx_buf ==
NULL) {
637 " allocate dynamic mem. for tx_buf,"
638 " Bailing out ...\n");
664 if (rx_buf ==
NULL) {
666 " allocate dynamic mem.for rx_buf,"
667 " Bailing out ...\n");
686 pr_warn(
"ERROR[%d], SHM could not, "
687 "register with NW FRMWK Bailing out ...\n", result);
697 pshm_drv = netdev_priv(pshm_netdev);