Loading drivers/net/bfin_mac.c +77 −26 Original line number Diff line number Diff line Loading @@ -605,36 +605,87 @@ static void adjust_tx_list(void) static int bfin_mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned int data; u16 *data; current_tx_ptr->skb = skb; if (ANOMALY_05000285) { /* * Is skb->data always 16-bit aligned? * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)? * TXDWA feature is not avaible to older revision < 0.3 silicon * of BF537 * * Only if data buffer is ODD WORD alignment, we do not * need to memcpy */ if ((((unsigned int)(skb->data)) & 0x02) == 2) { u32 data_align = (u32)(skb->data) & 0x3; if (data_align == 0x2) { /* move skb->data to current_tx_ptr payload */ data = (unsigned int)(skb->data) - 2; *((unsigned short *)data) = (unsigned short)(skb->len); current_tx_ptr->desc_a.start_addr = (unsigned long)data; data = (u16 *)(skb->data) - 1; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range(data, (data + (skb->len)) + 2); blackfin_dcache_flush_range((u32)data, (u32)((u8 *)data + skb->len + 4)); } else { *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); current_tx_ptr->desc_a.start_addr = (u32)current_tx_ptr->packet; if (current_tx_ptr->status.status_word != 0) current_tx_ptr->status.status_word = 0; blackfin_dcache_flush_range( (u32)current_tx_ptr->packet, (u32)(current_tx_ptr->packet + skb->len + 2)); } } else { /* * TXDWA feature is avaible to revision < 0.3 silicon of * BF537 and always avaible to BF52x */ u32 data_align = (u32)(skb->data) & 0x3; if (data_align == 0x0) { u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl |= TXDWA; bfin_write_EMAC_SYSCTL(sysctl); /* move skb->data to current_tx_ptr payload */ data = (u16 *)(skb->data) - 2; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range( (u32)data, (u32)((u8 *)data + skb->len + 4)); } else if (data_align == 0x2) { u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl &= ~TXDWA; bfin_write_EMAC_SYSCTL(sysctl); /* move skb->data to current_tx_ptr payload */ data = (u16 *)(skb->data) - 1; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range( (u32)data, (u32)((u8 *)data + skb->len + 4)); } else { *((unsigned short *)(current_tx_ptr->packet)) = (unsigned short)(skb->len); memcpy((char *)(current_tx_ptr->packet + 2), skb->data, (skb->len)); u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl &= ~TXDWA; bfin_write_EMAC_SYSCTL(sysctl); *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); current_tx_ptr->desc_a.start_addr = (unsigned long)current_tx_ptr->packet; (u32)current_tx_ptr->packet; if (current_tx_ptr->status.status_word != 0) current_tx_ptr->status.status_word = 0; blackfin_dcache_flush_range((unsigned int)current_tx_ptr-> packet, (unsigned int)(current_tx_ptr-> packet + skb->len) + 2); blackfin_dcache_flush_range( (u32)current_tx_ptr->packet, (u32)(current_tx_ptr->packet + skb->len + 2)); } } /* enable this packet's dma */ Loading Loading
drivers/net/bfin_mac.c +77 −26 Original line number Diff line number Diff line Loading @@ -605,36 +605,87 @@ static void adjust_tx_list(void) static int bfin_mac_hard_start_xmit(struct sk_buff *skb, struct net_device *dev) { unsigned int data; u16 *data; current_tx_ptr->skb = skb; if (ANOMALY_05000285) { /* * Is skb->data always 16-bit aligned? * Do we need to memcpy((char *)(tail->packet + 2), skb->data, len)? * TXDWA feature is not avaible to older revision < 0.3 silicon * of BF537 * * Only if data buffer is ODD WORD alignment, we do not * need to memcpy */ if ((((unsigned int)(skb->data)) & 0x02) == 2) { u32 data_align = (u32)(skb->data) & 0x3; if (data_align == 0x2) { /* move skb->data to current_tx_ptr payload */ data = (unsigned int)(skb->data) - 2; *((unsigned short *)data) = (unsigned short)(skb->len); current_tx_ptr->desc_a.start_addr = (unsigned long)data; data = (u16 *)(skb->data) - 1; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range(data, (data + (skb->len)) + 2); blackfin_dcache_flush_range((u32)data, (u32)((u8 *)data + skb->len + 4)); } else { *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); current_tx_ptr->desc_a.start_addr = (u32)current_tx_ptr->packet; if (current_tx_ptr->status.status_word != 0) current_tx_ptr->status.status_word = 0; blackfin_dcache_flush_range( (u32)current_tx_ptr->packet, (u32)(current_tx_ptr->packet + skb->len + 2)); } } else { /* * TXDWA feature is avaible to revision < 0.3 silicon of * BF537 and always avaible to BF52x */ u32 data_align = (u32)(skb->data) & 0x3; if (data_align == 0x0) { u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl |= TXDWA; bfin_write_EMAC_SYSCTL(sysctl); /* move skb->data to current_tx_ptr payload */ data = (u16 *)(skb->data) - 2; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range( (u32)data, (u32)((u8 *)data + skb->len + 4)); } else if (data_align == 0x2) { u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl &= ~TXDWA; bfin_write_EMAC_SYSCTL(sysctl); /* move skb->data to current_tx_ptr payload */ data = (u16 *)(skb->data) - 1; *data = (u16)(skb->len); current_tx_ptr->desc_a.start_addr = (u32)data; /* this is important! */ blackfin_dcache_flush_range( (u32)data, (u32)((u8 *)data + skb->len + 4)); } else { *((unsigned short *)(current_tx_ptr->packet)) = (unsigned short)(skb->len); memcpy((char *)(current_tx_ptr->packet + 2), skb->data, (skb->len)); u16 sysctl = bfin_read_EMAC_SYSCTL(); sysctl &= ~TXDWA; bfin_write_EMAC_SYSCTL(sysctl); *((u16 *)(current_tx_ptr->packet)) = (u16)(skb->len); memcpy((u8 *)(current_tx_ptr->packet + 2), skb->data, skb->len); current_tx_ptr->desc_a.start_addr = (unsigned long)current_tx_ptr->packet; (u32)current_tx_ptr->packet; if (current_tx_ptr->status.status_word != 0) current_tx_ptr->status.status_word = 0; blackfin_dcache_flush_range((unsigned int)current_tx_ptr-> packet, (unsigned int)(current_tx_ptr-> packet + skb->len) + 2); blackfin_dcache_flush_range( (u32)current_tx_ptr->packet, (u32)(current_tx_ptr->packet + skb->len + 2)); } } /* enable this packet's dma */ Loading