aboutsummaryrefslogtreecommitdiff
path: root/drivers/net/ps3_gelic_net.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ps3_gelic_net.c')
-rw-r--r--drivers/net/ps3_gelic_net.c1215
1 files changed, 697 insertions, 518 deletions
diff --git a/drivers/net/ps3_gelic_net.c b/drivers/net/ps3_gelic_net.c
index 055af081e02..7eb6e7e848f 100644
--- a/drivers/net/ps3_gelic_net.c
+++ b/drivers/net/ps3_gelic_net.c
@@ -46,29 +46,25 @@
#include <asm/lv1call.h>
#include "ps3_gelic_net.h"
+#include "ps3_gelic_wireless.h"
#define DRV_NAME "Gelic Network Driver"
-#define DRV_VERSION "1.0"
+#define DRV_VERSION "2.0"
MODULE_AUTHOR("SCE Inc.");
MODULE_DESCRIPTION("Gelic Network driver");
MODULE_LICENSE("GPL");
-static inline struct device *ctodev(struct gelic_net_card *card)
-{
- return &card->dev->core;
-}
-static inline u64 bus_id(struct gelic_net_card *card)
-{
- return card->dev->bus_id;
-}
-static inline u64 dev_id(struct gelic_net_card *card)
-{
- return card->dev->dev_id;
-}
+
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card);
+static inline void gelic_card_disable_txdmac(struct gelic_card *card);
+static inline void gelic_card_reset_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr);
/* set irq_mask */
-static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
+int gelic_card_set_irq_mask(struct gelic_card *card, u64 mask)
{
int status;
@@ -76,54 +72,110 @@ static int gelic_net_set_irq_mask(struct gelic_net_card *card, u64 mask)
mask, 0);
if (status)
dev_info(ctodev(card),
- "lv1_net_set_interrupt_mask failed %d\n", status);
+ "%s failed %d\n", __func__, status);
return status;
}
-static inline void gelic_net_rx_irq_on(struct gelic_net_card *card)
+
+static inline void gelic_card_rx_irq_on(struct gelic_card *card)
{
- gelic_net_set_irq_mask(card, card->ghiintmask | GELIC_NET_RXINT);
+ card->irq_mask |= GELIC_CARD_RXINT;
+ gelic_card_set_irq_mask(card, card->irq_mask);
}
-static inline void gelic_net_rx_irq_off(struct gelic_net_card *card)
+static inline void gelic_card_rx_irq_off(struct gelic_card *card)
{
- gelic_net_set_irq_mask(card, card->ghiintmask & ~GELIC_NET_RXINT);
+ card->irq_mask &= ~GELIC_CARD_RXINT;
+ gelic_card_set_irq_mask(card, card->irq_mask);
+}
+
+static void gelic_card_get_ether_port_status(struct gelic_card *card,
+ int inform)
+{
+ u64 v2;
+ struct net_device *ether_netdev;
+
+ lv1_net_control(bus_id(card), dev_id(card),
+ GELIC_LV1_GET_ETH_PORT_STATUS,
+ GELIC_LV1_VLAN_TX_ETHERNET, 0, 0,
+ &card->ether_port_status, &v2);
+
+ if (inform) {
+ ether_netdev = card->netdev[GELIC_PORT_ETHERNET];
+ if (card->ether_port_status & GELIC_LV1_ETHER_LINK_UP)
+ netif_carrier_on(ether_netdev);
+ else
+ netif_carrier_off(ether_netdev);
+ }
+}
+
+void gelic_card_up(struct gelic_card *card)
+{
+ pr_debug("%s: called\n", __func__);
+ down(&card->updown_lock);
+ if (atomic_inc_return(&card->users) == 1) {
+ pr_debug("%s: real do\n", __func__);
+ /* enable irq */
+ gelic_card_set_irq_mask(card, card->irq_mask);
+ /* start rx */
+ gelic_card_enable_rxdmac(card);
+
+ napi_enable(&card->napi);
+ }
+ up(&card->updown_lock);
+ pr_debug("%s: done\n", __func__);
}
+
+void gelic_card_down(struct gelic_card *card)
+{
+ u64 mask;
+ pr_debug("%s: called\n", __func__);
+ down(&card->updown_lock);
+ if (atomic_dec_if_positive(&card->users) == 0) {
+ pr_debug("%s: real do\n", __func__);
+ napi_disable(&card->napi);
+ /*
+ * Disable irq. Wireless interrupts will
+ * be disabled later if any
+ */
+ mask = card->irq_mask & (GELIC_CARD_WLAN_EVENT_RECEIVED |
+ GELIC_CARD_WLAN_COMMAND_COMPLETED);
+ gelic_card_set_irq_mask(card, mask);
+ /* stop rx */
+ gelic_card_disable_rxdmac(card);
+ gelic_card_reset_chain(card, &card->rx_chain,
+ card->descr + GELIC_NET_TX_DESCRIPTORS);
+ /* stop tx */
+ gelic_card_disable_txdmac(card);
+ }
+ up(&card->updown_lock);
+ pr_debug("%s: done\n", __func__);
+}
+
/**
- * gelic_net_get_descr_status -- returns the status of a descriptor
+ * gelic_descr_get_status -- returns the status of a descriptor
* @descr: descriptor to look at
*
* returns the status as in the dmac_cmd_status field of the descriptor
*/
-static enum gelic_net_descr_status
-gelic_net_get_descr_status(struct gelic_net_descr *descr)
+static enum gelic_descr_dma_status
+gelic_descr_get_status(struct gelic_descr *descr)
{
- u32 cmd_status;
-
- cmd_status = descr->dmac_cmd_status;
- cmd_status >>= GELIC_NET_DESCR_IND_PROC_SHIFT;
- return cmd_status;
+ return be32_to_cpu(descr->dmac_cmd_status) & GELIC_DESCR_DMA_STAT_MASK;
}
/**
- * gelic_net_set_descr_status -- sets the status of a descriptor
+ * gelic_descr_set_status -- sets the status of a descriptor
* @descr: descriptor to change
* @status: status to set in the descriptor
*
* changes the status to the specified value. Doesn't change other bits
* in the status
*/
-static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
- enum gelic_net_descr_status status)
+static void gelic_descr_set_status(struct gelic_descr *descr,
+ enum gelic_descr_dma_status status)
{
- u32 cmd_status;
-
- /* read the status */
- cmd_status = descr->dmac_cmd_status;
- /* clean the upper 4 bits */
- cmd_status &= GELIC_NET_DESCR_IND_PROC_MASKO;
- /* add the status to it */
- cmd_status |= ((u32)status) << GELIC_NET_DESCR_IND_PROC_SHIFT;
- /* and write it back */
- descr->dmac_cmd_status = cmd_status;
+ descr->dmac_cmd_status = cpu_to_be32(status |
+ (be32_to_cpu(descr->dmac_cmd_status) &
+ ~GELIC_DESCR_DMA_STAT_MASK));
/*
* dma_cmd_status field is used to indicate whether the descriptor
* is valid or not.
@@ -134,24 +186,24 @@ static void gelic_net_set_descr_status(struct gelic_net_descr *descr,
}
/**
- * gelic_net_free_chain - free descriptor chain
+ * gelic_card_free_chain - free descriptor chain
* @card: card structure
* @descr_in: address of desc
*/
-static void gelic_net_free_chain(struct gelic_net_card *card,
- struct gelic_net_descr *descr_in)
+static void gelic_card_free_chain(struct gelic_card *card,
+ struct gelic_descr *descr_in)
{
- struct gelic_net_descr *descr;
+ struct gelic_descr *descr;
for (descr = descr_in; descr && descr->bus_addr; descr = descr->next) {
dma_unmap_single(ctodev(card), descr->bus_addr,
- GELIC_NET_DESCR_SIZE, DMA_BIDIRECTIONAL);
+ GELIC_DESCR_SIZE, DMA_BIDIRECTIONAL);
descr->bus_addr = 0;
}
}
/**
- * gelic_net_init_chain - links descriptor chain
+ * gelic_card_init_chain - links descriptor chain
* @card: card structure
* @chain: address of chain
* @start_descr: address of descriptor array
@@ -162,22 +214,22 @@ static void gelic_net_free_chain(struct gelic_net_card *card,
*
* returns 0 on success, <0 on failure
*/
-static int gelic_net_init_chain(struct gelic_net_card *card,
- struct gelic_net_descr_chain *chain,
- struct gelic_net_descr *start_descr, int no)
+static int gelic_card_init_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr, int no)
{
int i;
- struct gelic_net_descr *descr;
+ struct gelic_descr *descr;
descr = start_descr;
memset(descr, 0, sizeof(*descr) * no);
/* set up the hardware pointers in each descriptor */
for (i = 0; i < no; i++, descr++) {
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
descr->bus_addr =
dma_map_single(ctodev(card), descr,
- GELIC_NET_DESCR_SIZE,
+ GELIC_DESCR_SIZE,
DMA_BIDIRECTIONAL);
if (!descr->bus_addr)
@@ -193,7 +245,7 @@ static int gelic_net_init_chain(struct gelic_net_card *card,
/* chain bus addr of hw descriptor */
descr = start_descr;
for (i = 0; i < no; i++, descr++) {
- descr->next_descr_addr = descr->next->bus_addr;
+ descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
}
chain->head = start_descr;
@@ -208,13 +260,38 @@ iommu_error:
for (i--, descr--; 0 <= i; i--, descr--)
if (descr->bus_addr)
dma_unmap_single(ctodev(card), descr->bus_addr,
- GELIC_NET_DESCR_SIZE,
+ GELIC_DESCR_SIZE,
DMA_BIDIRECTIONAL);
return -ENOMEM;
}
/**
- * gelic_net_prepare_rx_descr - reinitializes a rx descriptor
+ * gelic_card_reset_chain - reset status of a descriptor chain
+ * @card: card structure
+ * @chain: address of chain
+ * @start_descr: address of descriptor array
+ *
+ * Reset the status of dma descriptors to ready state
+ * and re-initialize the hardware chain for later use
+ */
+static void gelic_card_reset_chain(struct gelic_card *card,
+ struct gelic_descr_chain *chain,
+ struct gelic_descr *start_descr)
+{
+ struct gelic_descr *descr;
+
+ for (descr = start_descr; start_descr != descr->next; descr++) {
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
+ descr->next_descr_addr = cpu_to_be32(descr->next->bus_addr);
+ }
+
+ chain->head = start_descr;
+ chain->tail = (descr - 1);
+
+ (descr - 1)->next_descr_addr = 0;
+}
+/**
+ * gelic_descr_prepare_rx - reinitializes a rx descriptor
* @card: card structure
* @descr: descriptor to re-init
*
@@ -223,29 +300,27 @@ iommu_error:
* allocates a new rx skb, iommu-maps it and attaches it to the descriptor.
* Activate the descriptor state-wise
*/
-static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static int gelic_descr_prepare_rx(struct gelic_card *card,
+ struct gelic_descr *descr)
{
int offset;
unsigned int bufsize;
- if (gelic_net_get_descr_status(descr) != GELIC_NET_DESCR_NOT_IN_USE) {
+ if (gelic_descr_get_status(descr) != GELIC_DESCR_DMA_NOT_IN_USE)
dev_info(ctodev(card), "%s: ERROR status \n", __func__);
- }
/* we need to round up the buffer size to a multiple of 128 */
bufsize = ALIGN(GELIC_NET_MAX_MTU, GELIC_NET_RXBUF_ALIGN);
/* and we need to have it 128 byte aligned, therefore we allocate a
* bit more */
- descr->skb = netdev_alloc_skb(card->netdev,
- bufsize + GELIC_NET_RXBUF_ALIGN - 1);
+ descr->skb = dev_alloc_skb(bufsize + GELIC_NET_RXBUF_ALIGN - 1);
if (!descr->skb) {
descr->buf_addr = 0; /* tell DMAC don't touch memory */
dev_info(ctodev(card),
"%s:allocate skb failed !!\n", __func__);
return -ENOMEM;
}
- descr->buf_size = bufsize;
+ descr->buf_size = cpu_to_be32(bufsize);
descr->dmac_cmd_status = 0;
descr->result_size = 0;
descr->valid_size = 0;
@@ -256,63 +331,64 @@ static int gelic_net_prepare_rx_descr(struct gelic_net_card *card,
if (offset)
skb_reserve(descr->skb, GELIC_NET_RXBUF_ALIGN - offset);
/* io-mmu-map the skb */
- descr->buf_addr = dma_map_single(ctodev(card), descr->skb->data,
- GELIC_NET_MAX_MTU,
- DMA_FROM_DEVICE);
+ descr->buf_addr = cpu_to_be32(dma_map_single(ctodev(card),
+ descr->skb->data,
+ GELIC_NET_MAX_MTU,
+ DMA_FROM_DEVICE));
if (!descr->buf_addr) {
dev_kfree_skb_any(descr->skb);
descr->skb = NULL;
dev_info(ctodev(card),
"%s:Could not iommu-map rx buffer\n", __func__);
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
return -ENOMEM;
} else {
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_CARDOWNED);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_CARDOWNED);
return 0;
}
}
/**
- * gelic_net_release_rx_chain - free all skb of rx descr
+ * gelic_card_release_rx_chain - free all skb of rx descr
* @card: card structure
*
*/
-static void gelic_net_release_rx_chain(struct gelic_net_card *card)
+static void gelic_card_release_rx_chain(struct gelic_card *card)
{
- struct gelic_net_descr *descr = card->rx_chain.head;
+ struct gelic_descr *descr = card->rx_chain.head;
do {
if (descr->skb) {
dma_unmap_single(ctodev(card),
- descr->buf_addr,
+ be32_to_cpu(descr->buf_addr),
descr->skb->len,
DMA_FROM_DEVICE);
descr->buf_addr = 0;
dev_kfree_skb_any(descr->skb);
descr->skb = NULL;
- gelic_net_set_descr_status(descr,
- GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr,
+ GELIC_DESCR_DMA_NOT_IN_USE);
}
descr = descr->next;
} while (descr != card->rx_chain.head);
}
/**
- * gelic_net_fill_rx_chain - fills descriptors/skbs in the rx chains
+ * gelic_card_fill_rx_chain - fills descriptors/skbs in the rx chains
* @card: card structure
*
* fills all descriptors in the rx chain: allocates skbs
* and iommu-maps them.
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
*/
-static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
+static int gelic_card_fill_rx_chain(struct gelic_card *card)
{
- struct gelic_net_descr *descr = card->rx_chain.head;
+ struct gelic_descr *descr = card->rx_chain.head;
int ret;
do {
if (!descr->skb) {
- ret = gelic_net_prepare_rx_descr(card, descr);
+ ret = gelic_descr_prepare_rx(card, descr);
if (ret)
goto rewind;
}
@@ -321,41 +397,41 @@ static int gelic_net_fill_rx_chain(struct gelic_net_card *card)
return 0;
rewind:
- gelic_net_release_rx_chain(card);
+ gelic_card_release_rx_chain(card);
return ret;
}
/**
- * gelic_net_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
+ * gelic_card_alloc_rx_skbs - allocates rx skbs in rx descriptor chains
* @card: card structure
*
- * returns 0 on success, <0 on failure
+ * returns 0 on success, < 0 on failure
*/
-static int gelic_net_alloc_rx_skbs(struct gelic_net_card *card)
+static int gelic_card_alloc_rx_skbs(struct gelic_card *card)
{
- struct gelic_net_descr_chain *chain;
+ struct gelic_descr_chain *chain;
int ret;
chain = &card->rx_chain;
- ret = gelic_net_fill_rx_chain(card);
- chain->head = card->rx_top->prev; /* point to the last */
+ ret = gelic_card_fill_rx_chain(card);
+ chain->tail = card->rx_top->prev; /* point to the last */
return ret;
}
/**
- * gelic_net_release_tx_descr - processes a used tx descriptor
+ * gelic_descr_release_tx - processes a used tx descriptor
* @card: card structure
* @descr: descriptor to release
*
* releases a used tx descriptor (unmapping, freeing of skb)
*/
-static void gelic_net_release_tx_descr(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static void gelic_descr_release_tx(struct gelic_card *card,
+ struct gelic_descr *descr)
{
struct sk_buff *skb = descr->skb;
- BUG_ON(!(descr->data_status & (1 << GELIC_NET_TXDESC_TAIL)));
+ BUG_ON(!(be32_to_cpu(descr->data_status) & GELIC_DESCR_TX_TAIL));
- dma_unmap_single(ctodev(card), descr->buf_addr, skb->len,
+ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr), skb->len,
DMA_TO_DEVICE);
dev_kfree_skb_any(skb);
@@ -369,59 +445,75 @@ static void gelic_net_release_tx_descr(struct gelic_net_card *card,
descr->skb = NULL;
/* set descr status */
- gelic_net_set_descr_status(descr, GELIC_NET_DESCR_NOT_IN_USE);
+ gelic_descr_set_status(descr, GELIC_DESCR_DMA_NOT_IN_USE);
+}
+
+static void gelic_card_stop_queues(struct gelic_card *card)
+{
+ netif_stop_queue(card->netdev[GELIC_PORT_ETHERNET]);
+
+ if (card->netdev[GELIC_PORT_WIRELESS])
+ netif_stop_queue(card->netdev[GELIC_PORT_WIRELESS]);
}
+static void gelic_card_wake_queues(struct gelic_card *card)
+{
+ netif_wake_queue(card->netdev[GELIC_PORT_ETHERNET]);
+ if (card->netdev[GELIC_PORT_WIRELESS])
+ netif_wake_queue(card->netdev[GELIC_PORT_WIRELESS]);
+}
/**
- * gelic_net_release_tx_chain - processes sent tx descriptors
+ * gelic_card_release_tx_chain - processes sent tx descriptors
* @card: adapter structure
* @stop: net_stop sequence
*
* releases the tx descriptors that gelic has finished with
*/
-static void gelic_net_release_tx_chain(struct gelic_net_card *card, int stop)
+static void gelic_card_release_tx_chain(struct gelic_card *card, int stop)
{
- struct gelic_net_descr_chain *tx_chain;
- enum gelic_net_descr_status status;
+ struct gelic_descr_chain *tx_chain;
+ enum gelic_descr_dma_status status;
+ struct net_device *netdev;
int release = 0;
for (tx_chain = &card->tx_chain;
tx_chain->head != tx_chain->tail && tx_chain->tail;
tx_chain->tail = tx_chain->tail->next) {
- status = gelic_net_get_descr_status(tx_chain->tail);
+ status = gelic_descr_get_status(tx_chain->tail);
+ netdev = tx_chain->tail->skb->dev;
switch (status) {
- case GELIC_NET_DESCR_RESPONSE_ERROR:
- case GELIC_NET_DESCR_PROTECTION_ERROR:
- case GELIC_NET_DESCR_FORCE_END:
+ case GELIC_DESCR_DMA_RESPONSE_ERROR:
+ case GELIC_DESCR_DMA_PROTECTION_ERROR:
+ case GELIC_DESCR_DMA_FORCE_END:
if (printk_ratelimit())
dev_info(ctodev(card),
"%s: forcing end of tx descriptor " \
"with status %x\n",
__func__, status);
- card->netdev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
break;
- case GELIC_NET_DESCR_COMPLETE:
+ case GELIC_DESCR_DMA_COMPLETE:
if (tx_chain->tail->skb) {
- card->netdev->stats.tx_packets++;
- card->netdev->stats.tx_bytes +=
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes +=
tx_chain->tail->skb->len;
}
break;
- case GELIC_NET_DESCR_CARDOWNED:
+ case GELIC_DESCR_DMA_CARDOWNED:
/* pending tx request */
default:
- /* any other value (== GELIC_NET_DESCR_NOT_IN_USE) */
+ /* any other value (== GELIC_DESCR_DMA_NOT_IN_USE) */
if (!stop)
goto out;
}
- gelic_net_release_tx_descr(card, tx_chain->tail);
+ gelic_descr_release_tx(card, tx_chain->tail);
release ++;
}
out:
if (!stop && release)
- netif_wake_queue(card->netdev);
+ gelic_card_wake_queues(card);
}
/**
@@ -432,9 +524,9 @@ out:
* netdev interface. It also sets up multicast, allmulti and promisc
* flags appropriately
*/
-static void gelic_net_set_multi(struct net_device *netdev)
+void gelic_net_set_multi(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
+ struct gelic_card *card = netdev_card(netdev);
struct dev_mc_list *mc;
unsigned int i;
uint8_t *p;
@@ -456,8 +548,8 @@ static void gelic_net_set_multi(struct net_device *netdev)
"lv1_net_add_multicast_address failed, %d\n",
status);
- if (netdev->flags & IFF_ALLMULTI
- || netdev->mc_count > GELIC_NET_MC_COUNT_MAX) { /* list max */
+ if ((netdev->flags & IFF_ALLMULTI) ||
+ (netdev->mc_count > GELIC_NET_MC_COUNT_MAX)) {
status = lv1_net_add_multicast_address(bus_id(card),
dev_id(card),
0, 1);
@@ -468,7 +560,7 @@ static void gelic_net_set_multi(struct net_device *netdev)
return;
}
- /* set multicast address */
+ /* set multicast addresses */
for (mc = netdev->mc_list; mc; mc = mc->next) {
addr = 0;
p = mc->dmi_addr;
@@ -487,31 +579,42 @@ static void gelic_net_set_multi(struct net_device *netdev)
}
/**
- * gelic_net_enable_rxdmac - enables the receive DMA controller
+ * gelic_card_enable_rxdmac - enables the receive DMA controller
* @card: card structure
*
- * gelic_net_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
+ * gelic_card_enable_rxdmac enables the DMA controller by setting RX_DMA_EN
* in the GDADMACCNTR register
*/
-static inline void gelic_net_enable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_enable_rxdmac(struct gelic_card *card)
{
int status;
+#ifdef DEBUG
+ if (gelic_descr_get_status(card->rx_chain.head) !=
+ GELIC_DESCR_DMA_CARDOWNED) {
+ printk(KERN_ERR "%s: status=%x\n", __func__,
+ be32_to_cpu(card->rx_chain.head->dmac_cmd_status));
+ printk(KERN_ERR "%s: nextphy=%x\n", __func__,
+ be32_to_cpu(card->rx_chain.head->next_descr_addr));
+ printk(KERN_ERR "%s: head=%p\n", __func__,
+ card->rx_chain.head);
+ }
+#endif
status = lv1_net_start_rx_dma(bus_id(card), dev_id(card),
- card->rx_chain.tail->bus_addr, 0);
+ card->rx_chain.head->bus_addr, 0);
if (status)
dev_info(ctodev(card),
"lv1_net_start_rx_dma failed, status=%d\n", status);
}
/**
- * gelic_net_disable_rxdmac - disables the receive DMA controller
+ * gelic_card_disable_rxdmac - disables the receive DMA controller
* @card: card structure
*
- * gelic_net_disable_rxdmac terminates processing on the DMA controller by
+ * gelic_card_disable_rxdmac terminates processing on the DMA controller by
* turing off DMA and issueing a force end
*/
-static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_rxdmac(struct gelic_card *card)
{
int status;
@@ -523,13 +626,13 @@ static inline void gelic_net_disable_rxdmac(struct gelic_net_card *card)
}
/**
- * gelic_net_disable_txdmac - disables the transmit DMA controller
+ * gelic_card_disable_txdmac - disables the transmit DMA controller
* @card: card structure
*
- * gelic_net_disable_txdmac terminates processing on the DMA controller by
+ * gelic_card_disable_txdmac terminates processing on the DMA controller by
* turing off DMA and issueing a force end
*/
-static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
+static inline void gelic_card_disable_txdmac(struct gelic_card *card)
{
int status;
@@ -546,51 +649,37 @@ static inline void gelic_net_disable_txdmac(struct gelic_net_card *card)
*
* always returns 0
*/
-static int gelic_net_stop(struct net_device *netdev)
+int gelic_net_stop(struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
-
- napi_disable(&card->napi);
- netif_stop_queue(netdev);
+ struct gelic_card *card;
- /* turn off DMA, force end */
- gelic_net_disable_rxdmac(card);
- gelic_net_disable_txdmac(card);
-
- gelic_net_set_irq_mask(card, 0);
-
- /* disconnect event port */
- free_irq(card->netdev->irq, card->netdev);
- ps3_sb_event_receive_port_destroy(card->dev, card->netdev->irq);
- card->netdev->irq = NO_IRQ;
+ pr_debug("%s: start\n", __func__);
+ netif_stop_queue(netdev);
netif_carrier_off(netdev);
- /* release chains */
- gelic_net_release_tx_chain(card, 1);
- gelic_net_release_rx_chain(card);
-
- gelic_net_free_chain(card, card->tx_top);
- gelic_net_free_chain(card, card->rx_top);
+ card = netdev_card(netdev);
+ gelic_card_down(card);
+ pr_debug("%s: done\n", __func__);
return 0;
}
/**
- * gelic_net_get_next_tx_descr - returns the next available tx descriptor
+ * gelic_card_get_next_tx_descr - returns the next available tx descriptor
* @card: device structure to get descriptor from
*
* returns the address of the next descriptor, or NULL if not available.
*/
-static struct gelic_net_descr *
-gelic_net_get_next_tx_descr(struct gelic_net_card *card)
+static struct gelic_descr *
+gelic_card_get_next_tx_descr(struct gelic_card *card)
{
if (!card->tx_chain.head)
return NULL;
/* see if the next descriptor is free */
if (card->tx_chain.tail != card->tx_chain.head->next &&
- gelic_net_get_descr_status(card->tx_chain.head) ==
- GELIC_NET_DESCR_NOT_IN_USE)
+ gelic_descr_get_status(card->tx_chain.head) ==
+ GELIC_DESCR_DMA_NOT_IN_USE)
return card->tx_chain.head;
else
return NULL;
@@ -606,32 +695,33 @@ gelic_net_get_next_tx_descr(struct gelic_net_card *card)
* depending on hardware checksum settings. This function assumes a wmb()
* has executed before.
*/
-static void gelic_net_set_txdescr_cmdstat(struct gelic_net_descr *descr,
- struct sk_buff *skb)
+static void gelic_descr_set_tx_cmdstat(struct gelic_descr *descr,
+ struct sk_buff *skb)
{
if (skb->ip_summed != CHECKSUM_PARTIAL)
- descr->dmac_cmd_status = GELIC_NET_DMAC_CMDSTAT_NOCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ descr->dmac_cmd_status =
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else {
/* is packet ip?
* if yes: tcp? udp? */
if (skb->protocol == htons(ETH_P_IP)) {
if (ip_hdr(skb)->protocol == IPPROTO_TCP)
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_TCPCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_TCP_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else if (ip_hdr(skb)->protocol == IPPROTO_UDP)
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_UDPCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_UDP_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
else /*
* the stack should checksum non-tcp and non-udp
* packets on his own: NETIF_F_IP_CSUM
*/
descr->dmac_cmd_status =
- GELIC_NET_DMAC_CMDSTAT_NOCS |
- GELIC_NET_DMAC_CMDSTAT_END_FRAME;
+ cpu_to_be32(GELIC_DESCR_DMA_CMD_NO_CHKSUM |
+ GELIC_DESCR_TX_DMA_FRAME_TAIL);
}
}
}
@@ -662,7 +752,7 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
}
/**
- * gelic_net_prepare_tx_descr_v - get dma address of skb_data
+ * gelic_descr_prepare_tx - setup a descriptor for sending packets
* @card: card structure
* @descr: descriptor structure
* @skb: packet to use
@@ -670,16 +760,19 @@ static inline struct sk_buff *gelic_put_vlan_tag(struct sk_buff *skb,
* returns 0 on success, <0 on failure.
*
*/
-static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
- struct gelic_net_descr *descr,
- struct sk_buff *skb)
+static int gelic_descr_prepare_tx(struct gelic_card *card,
+ struct gelic_descr *descr,
+ struct sk_buff *skb)
{
dma_addr_t buf;
- if (card->vlan_index != -1) {
+ if (card->vlan_required) {
struct sk_buff *skb_tmp;
+ enum gelic_port_type type;
+
+ type = netdev_port(skb->dev)->type;
skb_tmp = gelic_put_vlan_tag(skb,
- card->vlan_id[card->vlan_index]);
+ card->vlan[type].tx);
if (!skb_tmp)
return -ENOMEM;
skb = skb_tmp;
@@ -694,12 +787,12 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
return -ENOMEM;
}
- descr->buf_addr = buf;
- descr->buf_size = skb->len;
+ descr->buf_addr = cpu_to_be32(buf);
+ descr->buf_size = cpu_to_be32(skb->len);
descr->skb = skb;
descr->data_status = 0;
descr->next_descr_addr = 0; /* terminate hw descr */
- gelic_net_set_txdescr_cmdstat(descr, skb);
+ gelic_descr_set_tx_cmdstat(descr, skb);
/* bump free descriptor pointer */
card->tx_chain.head = descr->next;
@@ -707,20 +800,20 @@ static int gelic_net_prepare_tx_descr_v(struct gelic_net_card *card,
}
/**
- * gelic_net_kick_txdma - enables TX DMA processing
+ * gelic_card_kick_txdma - enables TX DMA processing
* @card: card structure
* @descr: descriptor address to enable TX processing at
*
*/
-static int gelic_net_kick_txdma(struct gelic_net_card *card,
- struct gelic_net_descr *descr)
+static int gelic_card_kick_txdma(struct gelic_card *card,
+ struct gelic_descr *descr)
{
int status = 0;
if (card->tx_dma_progress)
return 0;
- if (gelic_net_get_descr_status(descr) == GELIC_NET_DESCR_CARDOWNED) {
+ if (gelic_descr_get_status(descr) == GELIC_DESCR_DMA_CARDOWNED) {
card->tx_dma_progress = 1;
status = lv1_net_start_tx_dma(bus_id(card), dev_id(card),
descr->bus_addr, 0);
@@ -738,56 +831,56 @@ static int gelic_net_kick_txdma(struct gelic_net_card *card,
*
* returns 0 on success, <0 on failure
*/
-static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
+int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
{
- struct gelic_net_card *card = netdev_priv(netdev);
- struct gelic_net_descr *descr;
+ struct gelic_card *card = netdev_card(netdev);
+ struct gelic_descr *descr;
int result;
unsigned long flags;
- spin_lock_irqsave(&card->tx_dma_lock, flags);
+ spin_lock_irqsave(&card->tx_lock, flags);
- gelic_net_release_tx_chain(card, 0);
+ gelic_card_release_tx_chain(card, 0);
- descr = gelic_net_get_next_tx_descr(card);
+ descr = gelic_card_get_next_tx_descr(card);
if (!descr) {
/*
* no more descriptors free
*/
- netif_stop_queue(netdev);
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ gelic_card_stop_queues(card);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_BUSY;
}
- result = gelic_net_prepare_tx_descr_v(card, descr, skb);
+ result = gelic_descr_prepare_tx(card, descr, skb);
if (result) {
/*
* DMA map failed. As chanses are that failure
* would continue, just release skb and return
*/
- card->netdev->stats.tx_dropped++;
+ netdev->stats.tx_dropped++;
dev_kfree_skb_any(skb);
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_OK;
}
/*
* link this prepared descriptor to previous one
* to achieve high performance
*/
- descr->prev->next_descr_addr = descr->bus_addr;
+ descr->prev->next_descr_addr = cpu_to_be32(descr->bus_addr);
/*
* as hardware descriptor is modified in the above lines,
* ensure that the hardware sees it
*/
wmb();
- if (gelic_net_kick_txdma(card, descr)) {
+ if (gelic_card_kick_txdma(card, descr)) {
/*
* kick failed.
* release descriptors which were just prepared
*/
- card->netdev->stats.tx_dropped++;
- gelic_net_release_tx_descr(card, descr);
- gelic_net_release_tx_descr(card, descr->next);
+ netdev->stats.tx_dropped++;
+ gelic_descr_release_tx(card, descr);
+ gelic_descr_release_tx(card, descr->next);
card->tx_chain.tail = descr->next->next;
dev_info(ctodev(card), "%s: kick failure\n", __func__);
} else {
@@ -795,7 +888,7 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
netdev->trans_start = jiffies;
}
- spin_unlock_irqrestore(&card->tx_dma_lock, flags);
+ spin_unlock_irqrestore(&card->tx_lock, flags);
return NETDEV_TX_OK;
}
@@ -803,30 +896,34 @@ static int gelic_net_xmit(struct sk_buff *skb, struct net_device *netdev)
* gelic_net_pass_skb_up - takes an skb from a descriptor and passes it on
* @descr: descriptor to process
* @card: card structure
+ * @netdev: net_device structure to be passed packet
*
* iommu-unmaps the skb, fills out skb structure and passes the data to the
* stack. The descriptor state is not changed.
*/
-static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
- struct gelic_net_card *card)
+static void gelic_net_pass_skb_up(struct gelic_descr *descr,
+ struct gelic_card *card,
+ struct net_device *netdev)
+
{
- struct sk_buff *skb;
- struct net_device *netdev;
+ struct sk_buff *skb = descr->skb;
u32 data_status, data_error;
- data_status = descr->data_status;
- data_error = descr->data_error;
- netdev = card->netdev;
+ data_status = be32_to_cpu(descr->data_status);
+ data_error = be32_to_cpu(descr->data_error);
/* unmap skb buffer */
- skb = descr->skb;
- dma_unmap_single(ctodev(card), descr->buf_addr, GELIC_NET_MAX_MTU,
+ dma_unmap_single(ctodev(card), be32_to_cpu(descr->buf_addr),
+ GELIC_NET_MAX_MTU,
DMA_FROM_DEVICE);
- skb_put(skb, descr->valid_size? descr->valid_size : descr->result_size);
+ skb_put(skb, be32_to_cpu(descr->valid_size)?
+ be32_to_cpu(descr->valid_size) :
+ be32_to_cpu(descr->result_size));
if (!descr->valid_size)
dev_info(ctodev(card), "buffer full %x %x %x\n",
- descr->result_size, descr->buf_size,
- descr->dmac_cmd_status);
+ be32_to_cpu(descr->result_size),
+ be32_to_cpu(descr->buf_size),
+ be32_to_cpu(descr->dmac_cmd_status));
descr->skb = NULL;
/*
@@ -838,8 +935,8 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
/* checksum offload */
if (card->rx_csum) {
- if ((data_status & GELIC_NET_DATA_STATUS_CHK_MASK) &&
- (!(data_error & GELIC_NET_DATA_ERROR_CHK_MASK)))
+ if ((data_status & GELIC_DESCR_DATA_STATUS_CHK_MASK) &&
+ (!(data_error & GELIC_DESCR_DATA_ERROR_CHK_MASK)))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
@@ -847,15 +944,15 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
skb->ip_summed = CHECKSUM_NONE;
/* update netdevice statistics */
- card->netdev->stats.rx_packets++;
- card->netdev->stats.rx_bytes += skb->len;
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += skb->len;
/* pass skb up to stack */
netif_receive_skb(skb);
}
/**
- * gelic_net_decode_one_descr - processes an rx descriptor
+ * gelic_card_decode_one_descr - processes an rx descriptor
* @card: card structure
*
* returns 1 if a packet has been sent to the stack, otherwise 0
@@ -863,36 +960,56 @@ static void gelic_net_pass_skb_up(struct gelic_net_descr *descr,
* processes an rx descriptor by iommu-unmapping the data buffer and passing
* the packet up to the stack
*/
-static int gelic_net_decode_one_descr(struct gelic_net_card *card)
+static int gelic_card_decode_one_descr(struct gelic_card *card)
{
- enum gelic_net_descr_status status;
- struct gelic_net_descr_chain *chain = &card->rx_chain;
- struct gelic_net_descr *descr = chain->tail;
+ enum gelic_descr_dma_status status;
+ struct gelic_descr_chain *chain = &card->rx_chain;
+ struct gelic_descr *descr = chain->head;
+ struct net_device *netdev = NULL;
int dmac_chain_ended;
- status = gelic_net_get_descr_status(descr);
+ status = gelic_descr_get_status(descr);
/* is this descriptor terminated with next_descr == NULL? */
dmac_chain_ended =
- descr->dmac_cmd_status & GELIC_NET_DMAC_CMDSTAT_RXDCEIS;
+ be32_to_cpu(descr->dmac_cmd_status) &
+ GELIC_DESCR_RX_DMA_CHAIN_END;
- if (status == GELIC_NET_DESCR_CARDOWNED)
+ if (status == GELIC_DESCR_DMA_CARDOWNED)
return 0;
- if (status == GELIC_NET_DESCR_NOT_IN_USE) {
+ if (status == GELIC_DESCR_DMA_NOT_IN_USE) {
dev_dbg(ctodev(card), "dormant descr? %p\n", descr);
return 0;
}
- if ((status == GELIC_NET_DESCR_RESPONSE_ERROR) ||
- (status == GELIC_NET_DESCR_PROTECTION_ERROR) ||
- (status == GELIC_NET_DESCR_FORCE_END)) {
+ /* netdevice select */
+ if (card->vlan_required) {
+ unsigned int i;
+ u16 vid;
+ vid = *(u16 *)(descr->skb->data) & VLAN_VID_MASK;
+ for (i = 0; i < GELIC_PORT_MAX; i++) {
+ if (card->vlan[i].rx == vid) {
+ netdev = card->netdev[i];
+ break;
+ }
+ };
+ if (GELIC_PORT_MAX <= i) {
+ pr_info("%s: unknown packet vid=%x\n", __func__, vid);
+ goto refill;
+ }
+ } else
+ netdev = card->netdev[GELIC_PORT_ETHERNET];
+
+ if ((status == GELIC_DESCR_DMA_RESPONSE_ERROR) ||
+ (status == GELIC_DESCR_DMA_PROTECTION_ERROR) ||
+ (status == GELIC_DESCR_DMA_FORCE_END)) {
dev_info(ctodev(card), "dropping RX descriptor with state %x\n",
status);
- card->netdev->stats.rx_dropped++;
+ netdev->stats.rx_dropped++;
goto refill;
}
- if (status == GELIC_NET_DESCR_BUFFER_FULL) {
+ if (status == GELIC_DESCR_DMA_BUFFER_FULL) {
/*
* Buffer full would occur if and only if
* the frame length was longer than the size of this
@@ -909,14 +1026,14 @@ static int gelic_net_decode_one_descr(struct gelic_net_card *card)
* descriptoers any other than FRAME_END here should
* be treated as error.
*/
- if (status != GELIC_NET_DESCR_FRAME_END) {
+ if (status != GELIC_DESCR_DMA_FRAME_END) {
dev_dbg(ctodev(card), "RX descriptor with state %x\n",
status);
goto refill;
}
/* ok, we've got a packet in descr */
- gelic_net_pass_skb_up(descr, card);
+ gelic_net_pass_skb_up(descr, card, netdev);