From: Paul Butler <paul.but...@windriver.com> Signed-off-by: Paul Butler <paul.but...@windriver.com> --- drivers/misc/lsi-ncr.c | 334 +++++++++++++++++++++++++++++------------------- drivers/net/rionet.c | 132 ++++++++++++------- 2 files changed, 282 insertions(+), 184 deletions(-)
diff --git a/drivers/misc/lsi-ncr.c b/drivers/misc/lsi-ncr.c index 23bcbe6..061b350 100644 --- a/drivers/misc/lsi-ncr.c +++ b/drivers/misc/lsi-ncr.c @@ -26,14 +26,18 @@ #include "lsi-ncr.h" -static void __iomem *nca_address; - #ifdef CONFIG_ARCH_AXXIA -#define NCA_PHYS_ADDRESS 0x002020100000ULL +#define NCA_PHYS_ADDRESS 0x002020100000ULL +#define APB2SER_PHY_PHYS_ADDRESS 0x002010000000ULL #else -#define NCA_PHYS_ADDRESS 0x002000520000ULL +#define NCA_PHYS_ADDRESS 0x002000520000ULL #endif +static void __iomem *nca_address; +#ifdef APB2SER_PHY_PHYS_ADDRESS +static void __iomem *apb2ser0_address; +#endif /* APB2SER_PHY_PHYS_ADDRESS */ + #define WFC_TIMEOUT (400000) #define LOCK_DOMAIN 0 @@ -212,71 +216,96 @@ ncr_read(unsigned long region, unsigned long address, int number, if (NULL == nca_address) nca_address = ioremap(NCA_PHYS_ADDRESS, 0x20000); +#ifdef APB2SER_PHY_PHYS_ADDRESS + if (NULL == apb2ser0_address) + apb2ser0_address = ioremap(APB2SER_PHY_PHYS_ADDRESS, 0x10000); +#endif /* APB2SER_PHY_PHYS_ADDRESS */ if (0 != ncr_lock(LOCK_DOMAIN)) return -1; - /* - Set up the read command. - */ - - cdr2.raw = 0; - cdr2.bits.target_node_id = NCP_NODE_ID(region); - cdr2.bits.target_id_address_upper = NCP_TARGET_ID(region); - ncr_register_write(cdr2.raw, (unsigned *) (nca_address + 0xf8)); - - cdr1.raw = 0; - cdr1.bits.target_address = (address >> 2); - ncr_register_write(cdr1.raw, (unsigned *) (nca_address + 0xf4)); - - cdr0.raw = 0; - cdr0.bits.start_done = 1; - - if (0xff == cdr2.bits.target_id_address_upper) - cdr0.bits.local_bit = 1; - - cdr0.bits.cmd_type = 4; - /* TODO: Verify number... */ - cdr0.bits.dbs = (number - 1); - ncr_register_write(cdr0.raw, (unsigned *) (nca_address + 0xf0)); - mb(); - - /* - Wait for completion. - */ - - do { - --wfc_timeout; - } while ((0x80000000UL == - ncr_register_read((unsigned *)(nca_address + 0xf0))) && - 0 < wfc_timeout); - - if (0 == wfc_timeout) { + if (NCP_NODE_ID(region) != 0x0153) { + /* + Set up the read command. + */ + + cdr2.raw = 0; + cdr2.bits.target_node_id = NCP_NODE_ID(region); + cdr2.bits.target_id_address_upper = NCP_TARGET_ID(region); + ncr_register_write(cdr2.raw, (unsigned *) (nca_address + 0xf8)); + + cdr1.raw = 0; + cdr1.bits.target_address = (address >> 2); + ncr_register_write(cdr1.raw, (unsigned *) (nca_address + 0xf4)); + + cdr0.raw = 0; + cdr0.bits.start_done = 1; + + if (0xff == cdr2.bits.target_id_address_upper) + cdr0.bits.local_bit = 1; + + cdr0.bits.cmd_type = 4; + /* TODO: Verify number... */ + cdr0.bits.dbs = (number - 1); + ncr_register_write(cdr0.raw, (unsigned *) (nca_address + 0xf0)); + mb(); + + /* + Wait for completion. + */ + + do { + --wfc_timeout; + } while ((0x80000000UL == + ncr_register_read((unsigned *)(nca_address + 0xf0))) && + 0 < wfc_timeout); + + if (0 == wfc_timeout) { + ncr_unlock(LOCK_DOMAIN); + return -1; + } + + /* + Copy data words to the buffer. + */ + + address = (unsigned long)(nca_address + 0x1000); + while (4 <= number) { + *((unsigned long *) buffer) = + ncr_register_read((unsigned *) address); + address += 4; + number -= 4; + } + + if (0 < number) { + unsigned long temp = + ncr_register_read((unsigned *) address); + memcpy((void *) buffer, &temp, number); + } + } else { +#ifdef APB2SER_PHY_PHYS_ADDRESS + void __iomem *targ_address = apb2ser0_address + + (address & (~0x3)); + /* + Copy data words to the buffer. + */ + + while (4 <= number) { + *((unsigned long *) buffer) = + *((unsigned long *) targ_address); + targ_address += 4; + number -= 4; + } +#else ncr_unlock(LOCK_DOMAIN); return -1; - } - - /* - Copy data words to the buffer. - */ - - address = (unsigned long)(nca_address + 0x1000); - while (4 <= number) { - *((unsigned long *) buffer) = - ncr_register_read((unsigned *) address); - address += 4; - number -= 4; - } - - if (0 < number) { - unsigned long temp = - ncr_register_read((unsigned *) address); - memcpy((void *) buffer, &temp, number); +#endif /* APB2SER_PHY_PHYS_ADDRESS */ } ncr_unlock(LOCK_DOMAIN); return 0; } +EXPORT_SYMBOL(ncr_read); /* ---------------------------------------------------------------------- @@ -297,92 +326,119 @@ ncr_write(unsigned long region, unsigned long address, int number, if (NULL == nca_address) nca_address = ioremap(NCA_PHYS_ADDRESS, 0x20000); +#ifdef APB2SER_PHY_PHYS_ADDRESS + if (NULL == apb2ser0_address) + apb2ser0_address = ioremap(APB2SER_PHY_PHYS_ADDRESS, 0x10000); +#endif /* APB2SER_PHY_PHYS_ADDRESS */ + if (0 != ncr_lock(LOCK_DOMAIN)) return -1; - /* - Set up the write. - */ - - cdr2.raw = 0; - cdr2.bits.target_node_id = NCP_NODE_ID(region); - cdr2.bits.target_id_address_upper = NCP_TARGET_ID(region); - ncr_register_write(cdr2.raw, (unsigned *) (nca_address + 0xf8)); - - cdr1.raw = 0; - cdr1.bits.target_address = (address >> 2); - ncr_register_write(cdr1.raw, (unsigned *) (nca_address + 0xf4)); - - /* - Copy from buffer to the data words. - */ - - data_word_base = (unsigned long)(nca_address + 0x1000); - - while (4 <= number) { - ncr_register_write(*((unsigned long *) buffer), - (unsigned *) data_word_base); - data_word_base += 4; - buffer += 4; - number -= 4; - } - - if (0 < number) { - unsigned long temp = 0; - - memcpy((void *) &temp, (void *) buffer, number); - ncr_register_write(temp, (unsigned *) data_word_base); - data_word_base += number; - buffer += number; - number = 0; - } - - cdr0.raw = 0; - cdr0.bits.start_done = 1; - - if (0xff == cdr2.bits.target_id_address_upper) - cdr0.bits.local_bit = 1; - - cdr0.bits.cmd_type = 5; - /* TODO: Verify number... */ - cdr0.bits.dbs = dbs; - ncr_register_write(cdr0.raw, (unsigned *) (nca_address + 0xf0)); - mb(); - - /* - Wait for completion. - */ - - do { - --wfc_timeout; - } while ((0x80000000UL == - ncr_register_read((unsigned *)(nca_address + 0xf0))) && - 0 < wfc_timeout); - - if (0 == wfc_timeout) { + if (NCP_NODE_ID(region) != 0x0153) { + /* + Set up the write. + */ + + cdr2.raw = 0; + cdr2.bits.target_node_id = NCP_NODE_ID(region); + cdr2.bits.target_id_address_upper = NCP_TARGET_ID(region); + ncr_register_write(cdr2.raw, (unsigned *) (nca_address + 0xf8)); + + cdr1.raw = 0; + cdr1.bits.target_address = (address >> 2); + ncr_register_write(cdr1.raw, (unsigned *) (nca_address + 0xf4)); + + /* + Copy from buffer to the data words. + */ + + data_word_base = (unsigned long)(nca_address + 0x1000); + + while (4 <= number) { + ncr_register_write(*((unsigned long *) buffer), + (unsigned *) data_word_base); + data_word_base += 4; + buffer += 4; + number -= 4; + } + + if (0 < number) { + unsigned long temp = 0; + + memcpy((void *) &temp, (void *) buffer, number); + ncr_register_write(temp, (unsigned *) data_word_base); + data_word_base += number; + buffer += number; + number = 0; + } + + cdr0.raw = 0; + cdr0.bits.start_done = 1; + + if (0xff == cdr2.bits.target_id_address_upper) + cdr0.bits.local_bit = 1; + + cdr0.bits.cmd_type = 5; + /* TODO: Verify number... */ + cdr0.bits.dbs = dbs; + ncr_register_write(cdr0.raw, (unsigned *) (nca_address + 0xf0)); + mb(); + + /* + Wait for completion. + */ + + do { + --wfc_timeout; + } while ((0x80000000UL == + ncr_register_read((unsigned *)(nca_address + 0xf0))) && + 0 < wfc_timeout); + + if (0 == wfc_timeout) { + ncr_unlock(LOCK_DOMAIN); + return -1; + } + + /* + Check status. + */ + + if (0x3 != + ((ncr_register_read((unsigned *) (nca_address + 0xf0)) & + 0x00c00000) >> 22)) { + unsigned long status; + + status = ncr_register_read((unsigned *)(nca_address + + 0xe4)); + ncr_unlock(LOCK_DOMAIN); + + return status; + } + } else { +#ifdef APB2SER_PHY_PHYS_ADDRESS + void __iomem *targ_address = apb2ser0_address + + (address & (~0x3)); + /* + Copy from buffer to the data words. + */ + + while (4 <= number) { + *((unsigned long *) targ_address) = + *((unsigned long *) buffer); + targ_address += 4; + number -= 4; + } +#else ncr_unlock(LOCK_DOMAIN); return -1; - } - - /* - Check status. - */ - - if (0x3 != - ((ncr_register_read((unsigned *) (nca_address + 0xf0)) & - 0x00c00000) >> 22)) { - unsigned long status; - - status = ncr_register_read((unsigned *)(nca_address + 0xe4)); - ncr_unlock(LOCK_DOMAIN); - - return status; +#endif /* APB2SER_PHY_PHYS_ADDRESS */ } ncr_unlock(LOCK_DOMAIN); return 0; } +EXPORT_SYMBOL(ncr_write); /* ---------------------------------------------------------------------- @@ -394,6 +450,10 @@ ncr_init(void) { nca_address = ioremap(NCA_PHYS_ADDRESS, 0x20000); +#ifdef APB2SER_PHY_PHYS_ADDRESS + apb2ser0_address = ioremap(APB2SER_PHY_PHYS_ADDRESS, 0x10000); +#endif /* APB2SER_PHY_PHYS_ADDRESS */ + return 0; } @@ -411,6 +471,12 @@ ncr_exit(void) if (NULL != nca_address) iounmap(nca_address); +#ifdef APB2SER_PHY_PHYS_ADDRESS + /* Unmap the APB2SER0 PHY. */ + if (NULL != apb2ser0_address) + iounmap(apb2ser0_address); +#endif /* APB2SER_PHY_PHYS_ADDRESS */ + return; } @@ -419,5 +485,3 @@ module_exit(ncr_exit); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Register Ring access for LSI's ACP board"); -EXPORT_SYMBOL(ncr_read); -EXPORT_SYMBOL(ncr_write); diff --git a/drivers/net/rionet.c b/drivers/net/rionet.c index 1470d3e..3409818 100644 --- a/drivers/net/rionet.c +++ b/drivers/net/rionet.c @@ -44,6 +44,7 @@ MODULE_LICENSE("GPL"); #define RIONET_DOORBELL_LEAVE 0x1001 #define RIONET_MAILBOX 0 +#define RIONET_MAILBOX_LETTER 0 #define RIONET_TX_RING_SIZE CONFIG_RIONET_TX_SIZE #define RIONET_RX_RING_SIZE CONFIG_RIONET_RX_SIZE @@ -69,7 +70,7 @@ struct rionet_peer { struct resource *res; }; -static int rionet_check = 0; +static int rionet_check; static int rionet_capable = 1; /* @@ -102,10 +103,16 @@ static int rionet_rx_clean(struct net_device *ndev) i = rnet->rx_slot; do { + int sz, slot; + u16 destid; + if (!rnet->rx_skb[i]) continue; - if (!(data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX))) + data = rio_get_inb_message(rnet->mport, RIONET_MAILBOX, + RIONET_MAILBOX_LETTER, + &sz, &slot, &destid); + if (!data) break; rnet->rx_skb[i]->data = data; @@ -149,8 +156,12 @@ static int rionet_queue_tx_msg(struct sk_buff *skb, struct net_device *ndev, struct rio_dev *rdev) { struct rionet_private *rnet = netdev_priv(ndev); + int letter = 0; + int flags = 0; + void *cookie = NULL; - rio_add_outb_message(rnet->mport, rdev, 0, skb->data, skb->len); + rio_add_outb_message(rnet->mport, rdev, rnet->mport->index, letter, + flags, skb->data, skb->len, cookie); rnet->tx_skb[rnet->tx_slot] = skb; ndev->stats.tx_packets++; @@ -178,11 +189,7 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) unsigned long flags; int add_num = 1; - local_irq_save(flags); - if (!spin_trylock(&rnet->tx_lock)) { - local_irq_restore(flags); - return NETDEV_TX_LOCKED; - } + spin_lock_irqsave(&rnet->tx_lock, flags); if (is_multicast_ether_addr(eth->h_dest)) add_num = nact; @@ -217,13 +224,19 @@ static int rionet_start_xmit(struct sk_buff *skb, struct net_device *ndev) return NETDEV_TX_OK; } -static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u16 tid, +static void rionet_dbell_event(struct rio_mport *mport, + void *dev_id, u16 sid, u16 tid, u16 info) { struct net_device *ndev = dev_id; - struct rionet_private *rnet = netdev_priv(ndev); + struct rionet_private *rnet; struct rionet_peer *peer; + if (ndev == NULL) + return; + + rnet = netdev_priv(ndev); + if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: doorbell sid %4.4x tid %4.4x info %4.4x", DRV_NAME, sid, tid, info); @@ -248,26 +261,40 @@ static void rionet_dbell_event(struct rio_mport *mport, void *dev_id, u16 sid, u } } -static void rionet_inb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot) +static void rionet_inb_msg_event(struct rio_mport *mport, + void *dev_id, int mbox, int slot) { int n; struct net_device *ndev = dev_id; - struct rionet_private *rnet = netdev_priv(ndev); + struct rionet_private *rnet; + + if (ndev == NULL) + return; + + rnet = netdev_priv(ndev); if (netif_msg_intr(rnet)) printk(KERN_INFO "%s: inbound message event, mbox %d slot %d\n", DRV_NAME, mbox, slot); spin_lock(&rnet->lock); - if ((n = rionet_rx_clean(ndev)) != rnet->rx_slot) + n = rionet_rx_clean(ndev); + if (n != rnet->rx_slot) rionet_rx_fill(ndev, n); spin_unlock(&rnet->lock); } -static void rionet_outb_msg_event(struct rio_mport *mport, void *dev_id, int mbox, int slot) +static void rionet_outb_msg_event(struct rio_mport *mport, + void *dev_id, int mbox, int slot, + void *cookie) { struct net_device *ndev = dev_id; - struct rionet_private *rnet = netdev_priv(ndev); + struct rionet_private *rnet; + + if (ndev == NULL) + return; + + rnet = netdev_priv(ndev); spin_lock(&rnet->lock); @@ -300,25 +327,29 @@ static int rionet_open(struct net_device *ndev) if (netif_msg_ifup(rnet)) printk(KERN_INFO "%s: open\n", DRV_NAME); - if ((rc = rio_request_inb_dbell(rnet->mport, - (void *)ndev, - RIONET_DOORBELL_JOIN, - RIONET_DOORBELL_LEAVE, - rionet_dbell_event)) < 0) + rc = rio_request_inb_dbell(rnet->mport, + (void *)ndev, + RIONET_DOORBELL_JOIN, + RIONET_DOORBELL_LEAVE, + rionet_dbell_event); + if (rc < 0) goto out; - if ((rc = rio_request_inb_mbox(rnet->mport, - (void *)ndev, - RIONET_MAILBOX, - RIONET_RX_RING_SIZE, - rionet_inb_msg_event)) < 0) + rc = rio_request_inb_mbox(rnet->mport, + (void *)ndev, + RIONET_MAILBOX, + RIONET_RX_RING_SIZE, + rionet_inb_msg_event); + if (rc < 0) goto out; - if ((rc = rio_request_outb_mbox(rnet->mport, - (void *)ndev, - RIONET_MAILBOX, - RIONET_TX_RING_SIZE, - rionet_outb_msg_event)) < 0) + rc = rio_request_outb_mbox(rnet->mport, + (void *)ndev, + RIONET_MAILBOX, + RIONET_TX_RING_SIZE, + 0, /* prio */ + rionet_outb_msg_event); + if (rc < 0) goto out; /* Initialize inbound message ring */ @@ -335,10 +366,10 @@ static int rionet_open(struct net_device *ndev) netif_start_queue(ndev); list_for_each_entry_safe(peer, tmp, &rionet_peers, node) { - if (!(peer->res = rio_request_outb_dbell(peer->rdev, - RIONET_DOORBELL_JOIN, - RIONET_DOORBELL_LEAVE))) - { + peer->res = rio_request_outb_dbell(peer->rdev, + RIONET_DOORBELL_JOIN, + RIONET_DOORBELL_LEAVE); + if (!peer) { printk(KERN_ERR "%s: error requesting doorbells\n", DRV_NAME); continue; @@ -348,7 +379,7 @@ static int rionet_open(struct net_device *ndev) rio_send_doorbell(peer->rdev, RIONET_DOORBELL_JOIN); } - out: +out: return rc; } @@ -388,8 +419,8 @@ static void rionet_remove(struct rio_dev *rdev) struct net_device *ndev = rio_get_drvdata(rdev); struct rionet_peer *peer, *tmp; - free_pages((unsigned long)rionet_active, get_order(sizeof(void *) * - RIO_MAX_ROUTE_ENTRIES(rdev->net->hport->sys_size))); + free_pages((unsigned long)rionet_active, rdev->hport->sys_size ? + __fls(sizeof(void *)) + 4 : 0); unregister_netdev(ndev); free_netdev(ndev); @@ -445,16 +476,15 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) int rc = 0; struct rionet_private *rnet; u16 device_id; - const size_t rionet_active_bytes = sizeof(void *) * - RIO_MAX_ROUTE_ENTRIES(mport->sys_size); rionet_active = (struct rio_dev **)__get_free_pages(GFP_KERNEL, - get_order(rionet_active_bytes)); + mport->sys_size ? __fls(sizeof(void *)) + 4 : 0); if (!rionet_active) { rc = -ENOMEM; goto out; } - memset((void *)rionet_active, 0, rionet_active_bytes); + memset((void *)rionet_active, 0, sizeof(void *) * + RIO_MAX_ROUTE_ENTRIES(mport->sys_size)); /* Set up private area */ rnet = netdev_priv(ndev); @@ -483,14 +513,14 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) if (rc != 0) goto out; - printk("%s: %s %s Version %s, MAC %pM\n", + printk(KERN_INFO "%s: %s %s Version %s, MAC %pM\n", ndev->name, DRV_NAME, DRV_DESC, DRV_VERSION, ndev->dev_addr); - out: +out: return rc; } @@ -500,7 +530,7 @@ static int rionet_setup_netdev(struct rio_mport *mport, struct net_device *ndev) static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) { int rc = -ENODEV; - u32 lsrc_ops, ldst_ops; + u32 lsrc_ops, ldst_ops, lpef; struct rionet_peer *peer; struct net_device *ndev = NULL; @@ -511,6 +541,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) /* Allocate our net_device structure */ ndev = alloc_etherdev(sizeof(struct rionet_private)); if (ndev == NULL) { + printk(KERN_INFO "%s: could not allocate ethernet device.\n", + DRV_NAME); rc = -ENOMEM; goto out; } @@ -521,9 +553,10 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) * on later probes */ if (!rionet_check) { - rio_local_read_config_32(rdev->net->hport, RIO_SRC_OPS_CAR, + rio_local_read_config_32(rdev->hport, RIO_PEF_CAR, &lpef); + rio_local_read_config_32(rdev->hport, RIO_SRC_OPS_CAR, &lsrc_ops); - rio_local_read_config_32(rdev->net->hport, RIO_DST_OPS_CAR, + rio_local_read_config_32(rdev->hport, RIO_DST_OPS_CAR, &ldst_ops); if (!is_rionet_capable(lsrc_ops, ldst_ops)) { printk(KERN_ERR @@ -534,7 +567,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) goto out; } - rc = rionet_setup_netdev(rdev->net->hport, ndev); + rc = rionet_setup_netdev(rdev->hport, ndev); rionet_check = 1; nact = 0; } @@ -544,7 +577,8 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) * add it to the peer list. */ if (dev_rionet_capable(rdev)) { - if (!(peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL))) { + peer = kmalloc(sizeof(struct rionet_peer), GFP_KERNEL); + if (!peer) { rc = -ENOMEM; goto out; } @@ -554,7 +588,7 @@ static int rionet_probe(struct rio_dev *rdev, const struct rio_device_id *id) rio_set_drvdata(rdev, ndev); - out: +out: return rc; } -- 1.7.9.5 -- _______________________________________________ linux-yocto mailing list linux-yocto@yoctoproject.org https://lists.yoctoproject.org/listinfo/linux-yocto