Blame view
drivers/net/sb1250-mac.c
65.2 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
f90fdc3cc [PATCH] sb1250-ma... |
2 |
* Copyright (C) 2001,2002,2003,2004 Broadcom Corporation |
f5279ffdc sb1250-mac: Drive... |
3 |
* Copyright (c) 2006, 2007 Maciej W. Rozycki |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 |
* * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
74b0247fb [PATCH] sb1250-ma... |
14 |
* |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 18 19 20 21 |
* You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * This driver is designed for the Broadcom SiByte SOC built-in * Ethernet controllers. Written by Mitch Lichtenberg at Broadcom Corp. |
f5279ffdc sb1250-mac: Drive... |
22 23 24 |
* * Updated to the driver model and the PHY abstraction layer * by Maciej W. Rozycki. |
1da177e4c Linux-2.6.12-rc2 |
25 |
*/ |
f5279ffdc sb1250-mac: Drive... |
26 27 |
#include <linux/bug.h> |
1da177e4c Linux-2.6.12-rc2 |
28 29 30 31 32 33 34 35 36 37 38 39 |
#include <linux/module.h> #include <linux/kernel.h> #include <linux/string.h> #include <linux/timer.h> #include <linux/errno.h> #include <linux/ioport.h> #include <linux/slab.h> #include <linux/interrupt.h> #include <linux/netdevice.h> #include <linux/etherdevice.h> #include <linux/skbuff.h> #include <linux/init.h> |
1da177e4c Linux-2.6.12-rc2 |
40 |
#include <linux/bitops.h> |
f5279ffdc sb1250-mac: Drive... |
41 42 43 44 45 |
#include <linux/err.h> #include <linux/ethtool.h> #include <linux/mii.h> #include <linux/phy.h> #include <linux/platform_device.h> |
1da177e4c Linux-2.6.12-rc2 |
46 |
#include <asm/cache.h> |
f5279ffdc sb1250-mac: Drive... |
47 48 |
#include <asm/io.h> #include <asm/processor.h> /* Processor type for cache alignment. */ |
1da177e4c Linux-2.6.12-rc2 |
49 |
|
1da177e4c Linux-2.6.12-rc2 |
50 51 52 |
/* Operational parameters that usually are not changed. */ #define CONFIG_SBMAC_COALESCE |
1da177e4c Linux-2.6.12-rc2 |
53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
/* Time in jiffies before concluding the transmitter is hung. */ #define TX_TIMEOUT (2*HZ) MODULE_AUTHOR("Mitch Lichtenberg (Broadcom Corp.)"); MODULE_DESCRIPTION("Broadcom SiByte SOC GB Ethernet driver"); /* A few user-configurable values which may be modified when a driver module is loaded. */ /* 1 normal messages, 0 quiet .. 7 verbose. */ static int debug = 1; module_param(debug, int, S_IRUGO); MODULE_PARM_DESC(debug, "Debug messages"); |
1da177e4c Linux-2.6.12-rc2 |
67 |
#ifdef CONFIG_SBMAC_COALESCE |
693aa9470 add NAPI support ... |
68 69 70 |
static int int_pktcnt_tx = 255; module_param(int_pktcnt_tx, int, S_IRUGO); MODULE_PARM_DESC(int_pktcnt_tx, "TX packet count"); |
1da177e4c Linux-2.6.12-rc2 |
71 |
|
693aa9470 add NAPI support ... |
72 73 74 75 76 77 78 79 80 81 82 |
static int int_timeout_tx = 255; module_param(int_timeout_tx, int, S_IRUGO); MODULE_PARM_DESC(int_timeout_tx, "TX timeout value"); static int int_pktcnt_rx = 64; module_param(int_pktcnt_rx, int, S_IRUGO); MODULE_PARM_DESC(int_pktcnt_rx, "RX packet count"); static int int_timeout_rx = 64; module_param(int_timeout_rx, int, S_IRUGO); MODULE_PARM_DESC(int_timeout_rx, "RX timeout value"); |
1da177e4c Linux-2.6.12-rc2 |
83 |
#endif |
f5279ffdc sb1250-mac: Drive... |
84 |
#include <asm/sibyte/board.h> |
1da177e4c Linux-2.6.12-rc2 |
85 |
#include <asm/sibyte/sb1250.h> |
f90fdc3cc [PATCH] sb1250-ma... |
86 87 88 |
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) #include <asm/sibyte/bcm1480_regs.h> #include <asm/sibyte/bcm1480_int.h> |
693aa9470 add NAPI support ... |
89 |
#define R_MAC_DMA_OODPKTLOST_RX R_MAC_DMA_OODPKTLOST |
f90fdc3cc [PATCH] sb1250-ma... |
90 |
#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) |
1da177e4c Linux-2.6.12-rc2 |
91 |
#include <asm/sibyte/sb1250_regs.h> |
1da177e4c Linux-2.6.12-rc2 |
92 |
#include <asm/sibyte/sb1250_int.h> |
f90fdc3cc [PATCH] sb1250-ma... |
93 94 95 |
#else #error invalid SiByte MAC configuation #endif |
1da177e4c Linux-2.6.12-rc2 |
96 |
#include <asm/sibyte/sb1250_scd.h> |
f90fdc3cc [PATCH] sb1250-ma... |
97 98 |
#include <asm/sibyte/sb1250_mac.h> #include <asm/sibyte/sb1250_dma.h> |
1da177e4c Linux-2.6.12-rc2 |
99 |
|
f90fdc3cc [PATCH] sb1250-ma... |
100 101 102 103 104 105 106 |
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) #define UNIT_INT(n) (K_BCM1480_INT_MAC_0 + ((n) * 2)) #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) #define UNIT_INT(n) (K_INT_MAC_0 + (n)) #else #error invalid SiByte MAC configuation #endif |
1da177e4c Linux-2.6.12-rc2 |
107 |
|
f5279ffdc sb1250-mac: Drive... |
108 109 110 111 112 |
#ifdef K_INT_PHY #define SBMAC_PHY_INT K_INT_PHY #else #define SBMAC_PHY_INT PHY_POLL #endif |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 |
/********************************************************************** * Simple types ********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
116 117 118 119 120 121 |
enum sbmac_speed { sbmac_speed_none = 0, sbmac_speed_10 = SPEED_10, sbmac_speed_100 = SPEED_100, sbmac_speed_1000 = SPEED_1000, }; |
1da177e4c Linux-2.6.12-rc2 |
122 |
|
f5279ffdc sb1250-mac: Drive... |
123 124 125 126 127 |
enum sbmac_duplex { sbmac_duplex_none = -1, sbmac_duplex_half = DUPLEX_HALF, sbmac_duplex_full = DUPLEX_FULL, }; |
1da177e4c Linux-2.6.12-rc2 |
128 |
|
f5279ffdc sb1250-mac: Drive... |
129 130 131 132 133 134 135 |
enum sbmac_fc { sbmac_fc_none, sbmac_fc_disabled, sbmac_fc_frame, sbmac_fc_collision, sbmac_fc_carrier, }; |
1da177e4c Linux-2.6.12-rc2 |
136 |
|
f5279ffdc sb1250-mac: Drive... |
137 138 139 140 141 142 |
enum sbmac_state { sbmac_state_uninit, sbmac_state_off, sbmac_state_on, sbmac_state_broken, }; |
1da177e4c Linux-2.6.12-rc2 |
143 144 145 146 147 148 149 150 151 152 153 154 |
/********************************************************************** * Macros ********************************************************************* */ #define SBDMA_NEXTBUF(d,f) ((((d)->f+1) == (d)->sbdma_dscrtable_end) ? \ (d)->sbdma_dscrtable : (d)->f+1) #define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES) |
693aa9470 add NAPI support ... |
155 156 |
#define SBMAC_MAX_TXDESCR 256 #define SBMAC_MAX_RXDESCR 256 |
1da177e4c Linux-2.6.12-rc2 |
157 |
|
789585e96 sb1250: use netde... |
158 |
#define ETHER_ADDR_LEN 6 |
74b0247fb [PATCH] sb1250-ma... |
159 160 |
#define ENET_PACKET_SIZE 1518 /*#define ENET_PACKET_SIZE 9216 */ |
1da177e4c Linux-2.6.12-rc2 |
161 162 163 164 |
/********************************************************************** * DMA Descriptor structure ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
165 |
struct sbdmadscr { |
1da177e4c Linux-2.6.12-rc2 |
166 167 |
uint64_t dscr_a; uint64_t dscr_b; |
73d739698 sb1250-mac.c: De-... |
168 |
}; |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 |
/********************************************************************** * DMA Controller structure ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
173 |
struct sbmacdma { |
74b0247fb [PATCH] sb1250-ma... |
174 175 |
/* |
1da177e4c Linux-2.6.12-rc2 |
176 177 178 |
* This stuff is used to identify the channel and the registers * associated with it. */ |
73d739698 sb1250-mac.c: De-... |
179 180 181 182 183 184 |
struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */ int sbdma_channel; /* channel number */ int sbdma_txdir; /* direction (1=transmit) */ int sbdma_maxdescr; /* total # of descriptors in ring */ |
1da177e4c Linux-2.6.12-rc2 |
185 |
#ifdef CONFIG_SBMAC_COALESCE |
73d739698 sb1250-mac.c: De-... |
186 187 188 189 190 |
int sbdma_int_pktcnt; /* # descriptors rx/tx before interrupt */ int sbdma_int_timeout; /* # usec rx/tx interrupt */ |
1da177e4c Linux-2.6.12-rc2 |
191 |
#endif |
73d739698 sb1250-mac.c: De-... |
192 193 194 195 196 197 198 199 200 |
void __iomem *sbdma_config0; /* DMA config register 0 */ void __iomem *sbdma_config1; /* DMA config register 1 */ void __iomem *sbdma_dscrbase; /* descriptor base address */ void __iomem *sbdma_dscrcnt; /* descriptor count register */ void __iomem *sbdma_curdscr; /* current descriptor address */ void __iomem *sbdma_oodpktlost; /* pkt drop (rx only) */ |
74b0247fb [PATCH] sb1250-ma... |
201 |
|
1da177e4c Linux-2.6.12-rc2 |
202 203 204 |
/* * This stuff is for maintenance of the ring */ |
73d739698 sb1250-mac.c: De-... |
205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
void *sbdma_dscrtable_unaligned; struct sbdmadscr *sbdma_dscrtable; /* base of descriptor table */ struct sbdmadscr *sbdma_dscrtable_end; /* end of descriptor table */ struct sk_buff **sbdma_ctxtable; /* context table, one per descr */ dma_addr_t sbdma_dscrtable_phys; /* and also the phys addr */ struct sbdmadscr *sbdma_addptr; /* next dscr for sw to add */ struct sbdmadscr *sbdma_remptr; /* next dscr for sw to remove */ }; |
1da177e4c Linux-2.6.12-rc2 |
219 220 221 222 223 224 225 |
/********************************************************************** * Ethernet softc structure ********************************************************************* */ struct sbmac_softc { |
74b0247fb [PATCH] sb1250-ma... |
226 |
|
1da177e4c Linux-2.6.12-rc2 |
227 228 229 |
/* * Linux-specific things */ |
73d739698 sb1250-mac.c: De-... |
230 231 |
struct net_device *sbm_dev; /* pointer to linux device */ struct napi_struct napi; |
f5279ffdc sb1250-mac: Drive... |
232 |
struct phy_device *phy_dev; /* the associated PHY device */ |
298cf9beb phylib: move to d... |
233 |
struct mii_bus *mii_bus; /* the MII bus */ |
f5279ffdc sb1250-mac: Drive... |
234 |
int phy_irq[PHY_MAX_ADDR]; |
73d739698 sb1250-mac.c: De-... |
235 |
spinlock_t sbm_lock; /* spin lock */ |
73d739698 sb1250-mac.c: De-... |
236 |
int sbm_devflags; /* current device flags */ |
74b0247fb [PATCH] sb1250-ma... |
237 |
|
1da177e4c Linux-2.6.12-rc2 |
238 239 240 |
/* * Controller-specific things */ |
73d739698 sb1250-mac.c: De-... |
241 242 |
void __iomem *sbm_base; /* MAC's base address */ enum sbmac_state sbm_state; /* current state */ |
74b0247fb [PATCH] sb1250-ma... |
243 |
|
73d739698 sb1250-mac.c: De-... |
244 245 246 247 248 249 250 251 |
void __iomem *sbm_macenable; /* MAC Enable Register */ void __iomem *sbm_maccfg; /* MAC Config Register */ void __iomem *sbm_fifocfg; /* FIFO Config Register */ void __iomem *sbm_framecfg; /* Frame Config Register */ void __iomem *sbm_rxfilter; /* Receive Filter Register */ void __iomem *sbm_isr; /* Interrupt Status Register */ void __iomem *sbm_imr; /* Interrupt Mask Register */ void __iomem *sbm_mdio; /* MDIO Register */ |
74b0247fb [PATCH] sb1250-ma... |
252 |
|
73d739698 sb1250-mac.c: De-... |
253 254 255 |
enum sbmac_speed sbm_speed; /* current speed */ enum sbmac_duplex sbm_duplex; /* current duplex */ enum sbmac_fc sbm_fc; /* cur. flow control setting */ |
f5279ffdc sb1250-mac: Drive... |
256 257 |
int sbm_pause; /* current pause setting */ int sbm_link; /* current link state */ |
74b0247fb [PATCH] sb1250-ma... |
258 |
|
73d739698 sb1250-mac.c: De-... |
259 |
unsigned char sbm_hwaddr[ETHER_ADDR_LEN]; |
74b0247fb [PATCH] sb1250-ma... |
260 |
|
73d739698 sb1250-mac.c: De-... |
261 262 263 264 |
struct sbmacdma sbm_txdma; /* only channel 0 for now */ struct sbmacdma sbm_rxdma; int rx_hw_checksum; int sbe_idx; |
1da177e4c Linux-2.6.12-rc2 |
265 266 267 268 269 270 271 272 273 274 |
}; /********************************************************************** * Externs ********************************************************************* */ /********************************************************************** * Prototypes ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
275 276 277 |
static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, int txrx, int maxdescr); static void sbdma_channel_start(struct sbmacdma *d, int rxtx); |
789585e96 sb1250: use netde... |
278 279 |
static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, struct sk_buff *m); |
73d739698 sb1250-mac.c: De-... |
280 281 |
static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *m); static void sbdma_emptyring(struct sbmacdma *d); |
789585e96 sb1250: use netde... |
282 |
static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d); |
73d739698 sb1250-mac.c: De-... |
283 284 285 286 |
static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, int work_to_do, int poll); static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, int poll); |
1da177e4c Linux-2.6.12-rc2 |
287 288 289 |
static int sbmac_initctx(struct sbmac_softc *s); static void sbmac_channel_start(struct sbmac_softc *s); static void sbmac_channel_stop(struct sbmac_softc *s); |
73d739698 sb1250-mac.c: De-... |
290 291 292 |
static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *, enum sbmac_state); static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff); |
1da177e4c Linux-2.6.12-rc2 |
293 |
static uint64_t sbmac_addr2reg(unsigned char *ptr); |
73d739698 sb1250-mac.c: De-... |
294 |
static irqreturn_t sbmac_intr(int irq, void *dev_instance); |
1da177e4c Linux-2.6.12-rc2 |
295 296 |
static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev); static void sbmac_setmulti(struct sbmac_softc *sc); |
f5279ffdc sb1250-mac: Drive... |
297 |
static int sbmac_init(struct platform_device *pldev, long long base); |
73d739698 sb1250-mac.c: De-... |
298 299 300 |
static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed); static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex, enum sbmac_fc fc); |
1da177e4c Linux-2.6.12-rc2 |
301 302 |
static int sbmac_open(struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
303 |
static void sbmac_tx_timeout (struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
304 305 306 |
static void sbmac_set_rx_mode(struct net_device *dev); static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); static int sbmac_close(struct net_device *dev); |
bea3348ee [NET]: Make NAPI ... |
307 |
static int sbmac_poll(struct napi_struct *napi, int budget); |
693aa9470 add NAPI support ... |
308 |
|
f5279ffdc sb1250-mac: Drive... |
309 |
static void sbmac_mii_poll(struct net_device *dev); |
59b818270 [PATCH] sb1250-ma... |
310 |
static int sbmac_mii_probe(struct net_device *dev); |
1da177e4c Linux-2.6.12-rc2 |
311 |
|
f5279ffdc sb1250-mac: Drive... |
312 313 |
static void sbmac_mii_sync(void __iomem *sbm_mdio); static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data, |
73d739698 sb1250-mac.c: De-... |
314 |
int bitcnt); |
f5279ffdc sb1250-mac: Drive... |
315 316 317 |
static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx); static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, u16 val); |
1da177e4c Linux-2.6.12-rc2 |
318 319 320 321 322 |
/********************************************************************** * Globals ********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
323 |
static char sbmac_string[] = "sb1250-mac"; |
f5279ffdc sb1250-mac: Drive... |
324 325 |
static char sbmac_mdio_string[] = "sb1250-mac-mdio"; |
1da177e4c Linux-2.6.12-rc2 |
326 327 328 329 330 331 332 333 334 335 |
/********************************************************************** * MDIO constants ********************************************************************* */ #define MII_COMMAND_START 0x01 #define MII_COMMAND_READ 0x02 #define MII_COMMAND_WRITE 0x01 #define MII_COMMAND_ACK 0x02 |
1da177e4c Linux-2.6.12-rc2 |
336 337 338 339 340 341 |
#define M_MAC_MDIO_DIR_OUTPUT 0 /* for clarity */ #define ENABLE 1 #define DISABLE 0 /********************************************************************** |
f5279ffdc sb1250-mac: Drive... |
342 |
* SBMAC_MII_SYNC(sbm_mdio) |
74b0247fb [PATCH] sb1250-ma... |
343 |
* |
1da177e4c Linux-2.6.12-rc2 |
344 345 |
* Synchronize with the MII - send a pattern of bits to the MII * that will guarantee that it is ready to accept a command. |
74b0247fb [PATCH] sb1250-ma... |
346 347 |
* * Input parameters: |
f5279ffdc sb1250-mac: Drive... |
348 |
* sbm_mdio - address of the MAC's MDIO register |
74b0247fb [PATCH] sb1250-ma... |
349 |
* |
1da177e4c Linux-2.6.12-rc2 |
350 351 352 |
* Return value: * nothing ********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
353 |
static void sbmac_mii_sync(void __iomem *sbm_mdio) |
1da177e4c Linux-2.6.12-rc2 |
354 355 356 357 |
{ int cnt; uint64_t bits; int mac_mdio_genc; |
f5279ffdc sb1250-mac: Drive... |
358 |
mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC; |
74b0247fb [PATCH] sb1250-ma... |
359 |
|
1da177e4c Linux-2.6.12-rc2 |
360 |
bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT; |
74b0247fb [PATCH] sb1250-ma... |
361 |
|
f5279ffdc sb1250-mac: Drive... |
362 |
__raw_writeq(bits | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
363 |
|
1da177e4c Linux-2.6.12-rc2 |
364 |
for (cnt = 0; cnt < 32; cnt++) { |
f5279ffdc sb1250-mac: Drive... |
365 366 |
__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, sbm_mdio); __raw_writeq(bits | mac_mdio_genc, sbm_mdio); |
1da177e4c Linux-2.6.12-rc2 |
367 368 369 370 |
} } /********************************************************************** |
f5279ffdc sb1250-mac: Drive... |
371 |
* SBMAC_MII_SENDDATA(sbm_mdio, data, bitcnt) |
74b0247fb [PATCH] sb1250-ma... |
372 |
* |
1da177e4c Linux-2.6.12-rc2 |
373 374 |
* Send some bits to the MII. The bits to be sent are right- * justified in the 'data' parameter. |
74b0247fb [PATCH] sb1250-ma... |
375 376 |
* * Input parameters: |
f5279ffdc sb1250-mac: Drive... |
377 378 379 |
* sbm_mdio - address of the MAC's MDIO register * data - data to send * bitcnt - number of bits to send |
1da177e4c Linux-2.6.12-rc2 |
380 |
********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
381 382 |
static void sbmac_mii_senddata(void __iomem *sbm_mdio, unsigned int data, int bitcnt) |
1da177e4c Linux-2.6.12-rc2 |
383 384 385 386 387 |
{ int i; uint64_t bits; unsigned int curmask; int mac_mdio_genc; |
f5279ffdc sb1250-mac: Drive... |
388 |
mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC; |
74b0247fb [PATCH] sb1250-ma... |
389 |
|
1da177e4c Linux-2.6.12-rc2 |
390 |
bits = M_MAC_MDIO_DIR_OUTPUT; |
f5279ffdc sb1250-mac: Drive... |
391 |
__raw_writeq(bits | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
392 |
|
1da177e4c Linux-2.6.12-rc2 |
393 |
curmask = 1 << (bitcnt - 1); |
74b0247fb [PATCH] sb1250-ma... |
394 |
|
1da177e4c Linux-2.6.12-rc2 |
395 396 397 398 |
for (i = 0; i < bitcnt; i++) { if (data & curmask) bits |= M_MAC_MDIO_OUT; else bits &= ~M_MAC_MDIO_OUT; |
f5279ffdc sb1250-mac: Drive... |
399 400 401 |
__raw_writeq(bits | mac_mdio_genc, sbm_mdio); __raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, sbm_mdio); __raw_writeq(bits | mac_mdio_genc, sbm_mdio); |
1da177e4c Linux-2.6.12-rc2 |
402 403 404 405 406 407 408 |
curmask >>= 1; } } /********************************************************************** |
f5279ffdc sb1250-mac: Drive... |
409 |
* SBMAC_MII_READ(bus, phyaddr, regidx) |
1da177e4c Linux-2.6.12-rc2 |
410 |
* Read a PHY register. |
74b0247fb [PATCH] sb1250-ma... |
411 412 |
* * Input parameters: |
f5279ffdc sb1250-mac: Drive... |
413 |
* bus - MDIO bus handle |
1da177e4c Linux-2.6.12-rc2 |
414 |
* phyaddr - PHY's address |
f5279ffdc sb1250-mac: Drive... |
415 |
* regnum - index of register to read |
74b0247fb [PATCH] sb1250-ma... |
416 |
* |
1da177e4c Linux-2.6.12-rc2 |
417 |
* Return value: |
f5279ffdc sb1250-mac: Drive... |
418 |
* value read, or 0xffff if an error occurred. |
1da177e4c Linux-2.6.12-rc2 |
419 |
********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
420 |
static int sbmac_mii_read(struct mii_bus *bus, int phyaddr, int regidx) |
1da177e4c Linux-2.6.12-rc2 |
421 |
{ |
f5279ffdc sb1250-mac: Drive... |
422 423 |
struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; void __iomem *sbm_mdio = sc->sbm_mdio; |
1da177e4c Linux-2.6.12-rc2 |
424 425 426 427 428 429 430 431 432 |
int idx; int error; int regval; int mac_mdio_genc; /* * Synchronize ourselves so that the PHY knows the next * thing coming down is a command */ |
f5279ffdc sb1250-mac: Drive... |
433 |
sbmac_mii_sync(sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
434 |
|
1da177e4c Linux-2.6.12-rc2 |
435 436 437 438 439 440 441 |
/* * Send the data to the PHY. The sequence is * a "start" command (2 bits) * a "read" command (2 bits) * the PHY addr (5 bits) * the register index (5 bits) */ |
f5279ffdc sb1250-mac: Drive... |
442 443 444 445 |
sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, 2); sbmac_mii_senddata(sbm_mdio, MII_COMMAND_READ, 2); sbmac_mii_senddata(sbm_mdio, phyaddr, 5); sbmac_mii_senddata(sbm_mdio, regidx, 5); |
74b0247fb [PATCH] sb1250-ma... |
446 |
|
f5279ffdc sb1250-mac: Drive... |
447 |
mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC; |
74b0247fb [PATCH] sb1250-ma... |
448 449 |
/* |
1da177e4c Linux-2.6.12-rc2 |
450 451 |
* Switch the port around without a clock transition. */ |
f5279ffdc sb1250-mac: Drive... |
452 |
__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
453 |
|
1da177e4c Linux-2.6.12-rc2 |
454 455 456 |
/* * Send out a clock pulse to signal we want the status */ |
f5279ffdc sb1250-mac: Drive... |
457 458 459 |
__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, sbm_mdio); __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
460 461 |
/* |
1da177e4c Linux-2.6.12-rc2 |
462 463 |
* If an error occurred, the PHY will signal '1' back */ |
f5279ffdc sb1250-mac: Drive... |
464 |
error = __raw_readq(sbm_mdio) & M_MAC_MDIO_IN; |
74b0247fb [PATCH] sb1250-ma... |
465 466 |
/* |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 |
* Issue an 'idle' clock pulse, but keep the direction * the same. */ |
f5279ffdc sb1250-mac: Drive... |
470 471 472 |
__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, sbm_mdio); __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
473 |
|
1da177e4c Linux-2.6.12-rc2 |
474 |
regval = 0; |
74b0247fb [PATCH] sb1250-ma... |
475 |
|
1da177e4c Linux-2.6.12-rc2 |
476 477 |
for (idx = 0; idx < 16; idx++) { regval <<= 1; |
74b0247fb [PATCH] sb1250-ma... |
478 |
|
1da177e4c Linux-2.6.12-rc2 |
479 |
if (error == 0) { |
f5279ffdc sb1250-mac: Drive... |
480 |
if (__raw_readq(sbm_mdio) & M_MAC_MDIO_IN) |
1da177e4c Linux-2.6.12-rc2 |
481 482 |
regval |= 1; } |
74b0247fb [PATCH] sb1250-ma... |
483 |
|
f5279ffdc sb1250-mac: Drive... |
484 485 486 |
__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, sbm_mdio); __raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, sbm_mdio); |
1da177e4c Linux-2.6.12-rc2 |
487 |
} |
74b0247fb [PATCH] sb1250-ma... |
488 |
|
1da177e4c Linux-2.6.12-rc2 |
489 |
/* Switch back to output */ |
f5279ffdc sb1250-mac: Drive... |
490 |
__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
491 |
|
1da177e4c Linux-2.6.12-rc2 |
492 493 |
if (error == 0) return regval; |
f5279ffdc sb1250-mac: Drive... |
494 |
return 0xffff; |
1da177e4c Linux-2.6.12-rc2 |
495 496 497 498 |
} /********************************************************************** |
f5279ffdc sb1250-mac: Drive... |
499 |
* SBMAC_MII_WRITE(bus, phyaddr, regidx, regval) |
74b0247fb [PATCH] sb1250-ma... |
500 |
* |
1da177e4c Linux-2.6.12-rc2 |
501 |
* Write a value to a PHY register. |
74b0247fb [PATCH] sb1250-ma... |
502 503 |
* * Input parameters: |
f5279ffdc sb1250-mac: Drive... |
504 |
* bus - MDIO bus handle |
1da177e4c Linux-2.6.12-rc2 |
505 |
* phyaddr - PHY to use |
f5279ffdc sb1250-mac: Drive... |
506 507 |
* regidx - register within the PHY * regval - data to write to register |
74b0247fb [PATCH] sb1250-ma... |
508 |
* |
1da177e4c Linux-2.6.12-rc2 |
509 |
* Return value: |
f5279ffdc sb1250-mac: Drive... |
510 |
* 0 for success |
1da177e4c Linux-2.6.12-rc2 |
511 |
********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
512 513 |
static int sbmac_mii_write(struct mii_bus *bus, int phyaddr, int regidx, u16 regval) |
1da177e4c Linux-2.6.12-rc2 |
514 |
{ |
f5279ffdc sb1250-mac: Drive... |
515 516 |
struct sbmac_softc *sc = (struct sbmac_softc *)bus->priv; void __iomem *sbm_mdio = sc->sbm_mdio; |
1da177e4c Linux-2.6.12-rc2 |
517 |
int mac_mdio_genc; |
f5279ffdc sb1250-mac: Drive... |
518 |
sbmac_mii_sync(sbm_mdio); |
74b0247fb [PATCH] sb1250-ma... |
519 |
|
f5279ffdc sb1250-mac: Drive... |
520 521 522 523 524 525 |
sbmac_mii_senddata(sbm_mdio, MII_COMMAND_START, 2); sbmac_mii_senddata(sbm_mdio, MII_COMMAND_WRITE, 2); sbmac_mii_senddata(sbm_mdio, phyaddr, 5); sbmac_mii_senddata(sbm_mdio, regidx, 5); sbmac_mii_senddata(sbm_mdio, MII_COMMAND_ACK, 2); sbmac_mii_senddata(sbm_mdio, regval, 16); |
1da177e4c Linux-2.6.12-rc2 |
526 |
|
f5279ffdc sb1250-mac: Drive... |
527 |
mac_mdio_genc = __raw_readq(sbm_mdio) & M_MAC_GENC; |
1da177e4c Linux-2.6.12-rc2 |
528 |
|
f5279ffdc sb1250-mac: Drive... |
529 530 531 |
__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, sbm_mdio); return 0; |
1da177e4c Linux-2.6.12-rc2 |
532 533 534 535 536 537 |
} /********************************************************************** * SBDMA_INITCTX(d,s,chan,txrx,maxdescr) |
74b0247fb [PATCH] sb1250-ma... |
538 |
* |
1da177e4c Linux-2.6.12-rc2 |
539 540 |
* Initialize a DMA channel context. Since there are potentially * eight DMA channels per MAC, it's nice to do this in a standard |
74b0247fb [PATCH] sb1250-ma... |
541 542 543 |
* way. * * Input parameters: |
73d739698 sb1250-mac.c: De-... |
544 545 |
* d - struct sbmacdma (DMA channel context) * s - struct sbmac_softc (pointer to a MAC) |
1da177e4c Linux-2.6.12-rc2 |
546 547 548 |
* chan - channel number (0..1 right now) * txrx - Identifies DMA_TX or DMA_RX for channel direction * maxdescr - number of descriptors |
74b0247fb [PATCH] sb1250-ma... |
549 |
* |
1da177e4c Linux-2.6.12-rc2 |
550 551 552 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
553 554 |
static void sbdma_initctx(struct sbmacdma *d, struct sbmac_softc *s, int chan, int txrx, int maxdescr) |
1da177e4c Linux-2.6.12-rc2 |
555 |
{ |
693aa9470 add NAPI support ... |
556 557 558 |
#ifdef CONFIG_SBMAC_COALESCE int int_pktcnt, int_timeout; #endif |
74b0247fb [PATCH] sb1250-ma... |
559 560 |
/* * Save away interesting stuff in the structure |
1da177e4c Linux-2.6.12-rc2 |
561 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
562 |
|
1da177e4c Linux-2.6.12-rc2 |
563 564 565 |
d->sbdma_eth = s; d->sbdma_channel = chan; d->sbdma_txdir = txrx; |
74b0247fb [PATCH] sb1250-ma... |
566 |
|
1da177e4c Linux-2.6.12-rc2 |
567 568 569 570 |
#if 0 /* RMON clearing */ s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING; #endif |
f5279ffdc sb1250-mac: Drive... |
571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 |
__raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BYTES); __raw_writeq(0, s->sbm_base + R_MAC_RMON_COLLISIONS); __raw_writeq(0, s->sbm_base + R_MAC_RMON_LATE_COL); __raw_writeq(0, s->sbm_base + R_MAC_RMON_EX_COL); __raw_writeq(0, s->sbm_base + R_MAC_RMON_FCS_ERROR); __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_ABORT); __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_BAD); __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_GOOD); __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_RUNT); __raw_writeq(0, s->sbm_base + R_MAC_RMON_TX_OVERSIZE); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BYTES); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_MCAST); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BCAST); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_BAD); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_GOOD); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_RUNT); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_OVERSIZE); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_FCS_ERROR); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_LENGTH_ERROR); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_CODE_ERROR); __raw_writeq(0, s->sbm_base + R_MAC_RMON_RX_ALIGN_ERROR); |
1da177e4c Linux-2.6.12-rc2 |
592 |
|
74b0247fb [PATCH] sb1250-ma... |
593 594 |
/* * initialize register pointers |
1da177e4c Linux-2.6.12-rc2 |
595 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
596 597 |
d->sbdma_config0 = |
1da177e4c Linux-2.6.12-rc2 |
598 |
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG0); |
74b0247fb [PATCH] sb1250-ma... |
599 |
d->sbdma_config1 = |
1da177e4c Linux-2.6.12-rc2 |
600 |
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CONFIG1); |
74b0247fb [PATCH] sb1250-ma... |
601 |
d->sbdma_dscrbase = |
1da177e4c Linux-2.6.12-rc2 |
602 |
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_BASE); |
74b0247fb [PATCH] sb1250-ma... |
603 |
d->sbdma_dscrcnt = |
1da177e4c Linux-2.6.12-rc2 |
604 |
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_DSCR_CNT); |
74b0247fb [PATCH] sb1250-ma... |
605 |
d->sbdma_curdscr = |
1da177e4c Linux-2.6.12-rc2 |
606 |
s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_CUR_DSCRADDR); |
693aa9470 add NAPI support ... |
607 608 609 610 611 |
if (d->sbdma_txdir) d->sbdma_oodpktlost = NULL; else d->sbdma_oodpktlost = s->sbm_base + R_MAC_DMA_REGISTER(txrx,chan,R_MAC_DMA_OODPKTLOST_RX); |
74b0247fb [PATCH] sb1250-ma... |
612 |
|
1da177e4c Linux-2.6.12-rc2 |
613 614 615 |
/* * Allocate memory for the ring */ |
74b0247fb [PATCH] sb1250-ma... |
616 |
|
1da177e4c Linux-2.6.12-rc2 |
617 |
d->sbdma_maxdescr = maxdescr; |
74b0247fb [PATCH] sb1250-ma... |
618 |
|
73d739698 sb1250-mac.c: De-... |
619 620 621 |
d->sbdma_dscrtable_unaligned = kcalloc(d->sbdma_maxdescr + 1, sizeof(*d->sbdma_dscrtable), GFP_KERNEL); |
04115def6 [PATCH] sb1250-ma... |
622 623 624 625 626 |
/* * The descriptor table must be aligned to at least 16 bytes or the * MAC will corrupt it. */ |
73d739698 sb1250-mac.c: De-... |
627 628 629 |
d->sbdma_dscrtable = (struct sbdmadscr *) ALIGN((unsigned long)d->sbdma_dscrtable_unaligned, sizeof(*d->sbdma_dscrtable)); |
74b0247fb [PATCH] sb1250-ma... |
630 |
|
1da177e4c Linux-2.6.12-rc2 |
631 |
d->sbdma_dscrtable_end = d->sbdma_dscrtable + d->sbdma_maxdescr; |
74b0247fb [PATCH] sb1250-ma... |
632 |
|
1da177e4c Linux-2.6.12-rc2 |
633 |
d->sbdma_dscrtable_phys = virt_to_phys(d->sbdma_dscrtable); |
74b0247fb [PATCH] sb1250-ma... |
634 |
|
1da177e4c Linux-2.6.12-rc2 |
635 636 637 |
/* * And context table */ |
74b0247fb [PATCH] sb1250-ma... |
638 |
|
c477f3348 drivers/net/sb125... |
639 |
d->sbdma_ctxtable = kcalloc(d->sbdma_maxdescr, |
73d739698 sb1250-mac.c: De-... |
640 |
sizeof(*d->sbdma_ctxtable), GFP_KERNEL); |
74b0247fb [PATCH] sb1250-ma... |
641 |
|
1da177e4c Linux-2.6.12-rc2 |
642 643 644 645 |
#ifdef CONFIG_SBMAC_COALESCE /* * Setup Rx/Tx DMA coalescing defaults */ |
693aa9470 add NAPI support ... |
646 |
int_pktcnt = (txrx == DMA_TX) ? int_pktcnt_tx : int_pktcnt_rx; |
1da177e4c Linux-2.6.12-rc2 |
647 648 649 650 651 |
if ( int_pktcnt ) { d->sbdma_int_pktcnt = int_pktcnt; } else { d->sbdma_int_pktcnt = 1; } |
74b0247fb [PATCH] sb1250-ma... |
652 |
|
693aa9470 add NAPI support ... |
653 |
int_timeout = (txrx == DMA_TX) ? int_timeout_tx : int_timeout_rx; |
1da177e4c Linux-2.6.12-rc2 |
654 655 656 657 658 659 660 661 662 663 664 |
if ( int_timeout ) { d->sbdma_int_timeout = int_timeout; } else { d->sbdma_int_timeout = 0; } #endif } /********************************************************************** * SBDMA_CHANNEL_START(d) |
74b0247fb [PATCH] sb1250-ma... |
665 |
* |
1da177e4c Linux-2.6.12-rc2 |
666 |
* Initialize the hardware registers for a DMA channel. |
74b0247fb [PATCH] sb1250-ma... |
667 668 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
669 670 |
* d - DMA channel to init (context must be previously init'd * rxtx - DMA_RX or DMA_TX depending on what type of channel |
74b0247fb [PATCH] sb1250-ma... |
671 |
* |
1da177e4c Linux-2.6.12-rc2 |
672 673 674 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
675 |
static void sbdma_channel_start(struct sbmacdma *d, int rxtx) |
1da177e4c Linux-2.6.12-rc2 |
676 677 678 679 |
{ /* * Turn on the DMA channel */ |
74b0247fb [PATCH] sb1250-ma... |
680 |
|
1da177e4c Linux-2.6.12-rc2 |
681 |
#ifdef CONFIG_SBMAC_COALESCE |
2039973af [PATCH] sb1250-ma... |
682 683 684 |
__raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) | 0, d->sbdma_config1); __raw_writeq(M_DMA_EOP_INT_EN | |
1da177e4c Linux-2.6.12-rc2 |
685 686 |
V_DMA_RINGSZ(d->sbdma_maxdescr) | V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) | |
2039973af [PATCH] sb1250-ma... |
687 |
0, d->sbdma_config0); |
1da177e4c Linux-2.6.12-rc2 |
688 |
#else |
2039973af [PATCH] sb1250-ma... |
689 690 691 |
__raw_writeq(0, d->sbdma_config1); __raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) | 0, d->sbdma_config0); |
1da177e4c Linux-2.6.12-rc2 |
692 |
#endif |
2039973af [PATCH] sb1250-ma... |
693 |
__raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase); |
1da177e4c Linux-2.6.12-rc2 |
694 695 696 697 698 699 700 701 702 703 704 |
/* * Initialize ring pointers */ d->sbdma_addptr = d->sbdma_dscrtable; d->sbdma_remptr = d->sbdma_dscrtable; } /********************************************************************** * SBDMA_CHANNEL_STOP(d) |
74b0247fb [PATCH] sb1250-ma... |
705 |
* |
1da177e4c Linux-2.6.12-rc2 |
706 |
* Initialize the hardware registers for a DMA channel. |
74b0247fb [PATCH] sb1250-ma... |
707 708 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
709 |
* d - DMA channel to init (context must be previously init'd |
74b0247fb [PATCH] sb1250-ma... |
710 |
* |
1da177e4c Linux-2.6.12-rc2 |
711 712 713 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
714 |
static void sbdma_channel_stop(struct sbmacdma *d) |
1da177e4c Linux-2.6.12-rc2 |
715 716 717 718 |
{ /* * Turn off the DMA channel */ |
74b0247fb [PATCH] sb1250-ma... |
719 |
|
2039973af [PATCH] sb1250-ma... |
720 |
__raw_writeq(0, d->sbdma_config1); |
74b0247fb [PATCH] sb1250-ma... |
721 |
|
2039973af [PATCH] sb1250-ma... |
722 |
__raw_writeq(0, d->sbdma_dscrbase); |
74b0247fb [PATCH] sb1250-ma... |
723 |
|
2039973af [PATCH] sb1250-ma... |
724 |
__raw_writeq(0, d->sbdma_config0); |
74b0247fb [PATCH] sb1250-ma... |
725 |
|
1da177e4c Linux-2.6.12-rc2 |
726 727 728 |
/* * Zero ring pointers */ |
74b0247fb [PATCH] sb1250-ma... |
729 |
|
2039973af [PATCH] sb1250-ma... |
730 731 |
d->sbdma_addptr = NULL; d->sbdma_remptr = NULL; |
1da177e4c Linux-2.6.12-rc2 |
732 |
} |
789585e96 sb1250: use netde... |
733 734 |
static inline void sbdma_align_skb(struct sk_buff *skb, unsigned int power2, unsigned int offset) |
1da177e4c Linux-2.6.12-rc2 |
735 |
{ |
789585e96 sb1250: use netde... |
736 737 |
unsigned char *addr = skb->data; unsigned char *newaddr = PTR_ALIGN(addr, power2); |
74b0247fb [PATCH] sb1250-ma... |
738 |
|
789585e96 sb1250: use netde... |
739 |
skb_reserve(skb, newaddr - addr + offset); |
1da177e4c Linux-2.6.12-rc2 |
740 741 742 743 744 |
} /********************************************************************** * SBDMA_ADD_RCVBUFFER(d,sb) |
74b0247fb [PATCH] sb1250-ma... |
745 |
* |
1da177e4c Linux-2.6.12-rc2 |
746 747 |
* Add a buffer to the specified DMA channel. For receive channels, * this queues a buffer for inbound packets. |
74b0247fb [PATCH] sb1250-ma... |
748 749 |
* * Input parameters: |
789585e96 sb1250: use netde... |
750 751 |
* sc - softc structure * d - DMA channel descriptor |
1da177e4c Linux-2.6.12-rc2 |
752 |
* sb - sk_buff to add, or NULL if we should allocate one |
74b0247fb [PATCH] sb1250-ma... |
753 |
* |
1da177e4c Linux-2.6.12-rc2 |
754 755 756 757 |
* Return value: * 0 if buffer could not be added (ring is full) * 1 if buffer added successfully ********************************************************************* */ |
789585e96 sb1250: use netde... |
758 759 |
static int sbdma_add_rcvbuffer(struct sbmac_softc *sc, struct sbmacdma *d, struct sk_buff *sb) |
1da177e4c Linux-2.6.12-rc2 |
760 |
{ |
789585e96 sb1250: use netde... |
761 |
struct net_device *dev = sc->sbm_dev; |
73d739698 sb1250-mac.c: De-... |
762 763 |
struct sbdmadscr *dsc; struct sbdmadscr *nextdsc; |
1da177e4c Linux-2.6.12-rc2 |
764 765 |
struct sk_buff *sb_new = NULL; int pktsize = ENET_PACKET_SIZE; |
74b0247fb [PATCH] sb1250-ma... |
766 |
|
1da177e4c Linux-2.6.12-rc2 |
767 |
/* get pointer to our current place in the ring */ |
74b0247fb [PATCH] sb1250-ma... |
768 |
|
1da177e4c Linux-2.6.12-rc2 |
769 770 |
dsc = d->sbdma_addptr; nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr); |
74b0247fb [PATCH] sb1250-ma... |
771 |
|
1da177e4c Linux-2.6.12-rc2 |
772 773 774 775 776 |
/* * figure out if the ring is full - if the next descriptor * is the same as the one that we're going to remove from * the ring, the ring is full */ |
74b0247fb [PATCH] sb1250-ma... |
777 |
|
1da177e4c Linux-2.6.12-rc2 |
778 779 780 |
if (nextdsc == d->sbdma_remptr) { return -ENOSPC; } |
74b0247fb [PATCH] sb1250-ma... |
781 782 |
/* * Allocate a sk_buff if we don't already have one. |
1da177e4c Linux-2.6.12-rc2 |
783 784 785 786 787 788 789 790 |
* If we do have an sk_buff, reset it so that it's empty. * * Note: sk_buffs don't seem to be guaranteed to have any sort * of alignment when they are allocated. Therefore, allocate enough * extra space to make sure that: * * 1. the data does not start in the middle of a cache line. * 2. The data does not end in the middle of a cache line |
74b0247fb [PATCH] sb1250-ma... |
791 |
* 3. The buffer can be aligned such that the IP addresses are |
1da177e4c Linux-2.6.12-rc2 |
792 793 794 795 796 797 798 |
* naturally aligned. * * Remember, the SOCs MAC writes whole cache lines at a time, * without reading the old contents first. So, if the sk_buff's * data portion starts in the middle of a cache line, the SOC * DMA will trash the beginning (and ending) portions. */ |
74b0247fb [PATCH] sb1250-ma... |
799 |
|
1da177e4c Linux-2.6.12-rc2 |
800 |
if (sb == NULL) { |
789585e96 sb1250: use netde... |
801 802 803 |
sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE + SMP_CACHE_BYTES * 2 + NET_IP_ALIGN); |
1da177e4c Linux-2.6.12-rc2 |
804 |
if (sb_new == NULL) { |
f5279ffdc sb1250-mac: Drive... |
805 806 |
pr_info("%s: sk_buff allocation failed ", |
1da177e4c Linux-2.6.12-rc2 |
807 808 809 |
d->sbdma_eth->sbm_dev->name); return -ENOBUFS; } |
789585e96 sb1250: use netde... |
810 |
sbdma_align_skb(sb_new, SMP_CACHE_BYTES, NET_IP_ALIGN); |
1da177e4c Linux-2.6.12-rc2 |
811 812 813 |
} else { sb_new = sb; |
74b0247fb [PATCH] sb1250-ma... |
814 |
/* |
1da177e4c Linux-2.6.12-rc2 |
815 816 817 818 |
* nothing special to reinit buffer, it's already aligned * and sb->data already points to a good place. */ } |
74b0247fb [PATCH] sb1250-ma... |
819 |
|
1da177e4c Linux-2.6.12-rc2 |
820 |
/* |
74b0247fb [PATCH] sb1250-ma... |
821 |
* fill in the descriptor |
1da177e4c Linux-2.6.12-rc2 |
822 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
823 |
|
1da177e4c Linux-2.6.12-rc2 |
824 825 826 827 |
#ifdef CONFIG_SBMAC_COALESCE /* * Do not interrupt per DMA transfer. */ |
689be4394 [NET]: Remove gra... |
828 |
dsc->dscr_a = virt_to_phys(sb_new->data) | |
789585e96 sb1250: use netde... |
829 |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | 0; |
1da177e4c Linux-2.6.12-rc2 |
830 |
#else |
689be4394 [NET]: Remove gra... |
831 |
dsc->dscr_a = virt_to_phys(sb_new->data) | |
789585e96 sb1250: use netde... |
832 |
V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize + NET_IP_ALIGN)) | |
1da177e4c Linux-2.6.12-rc2 |
833 834 835 836 837 |
M_DMA_DSCRA_INTERRUPT; #endif /* receiving: no options */ dsc->dscr_b = 0; |
74b0247fb [PATCH] sb1250-ma... |
838 |
|
1da177e4c Linux-2.6.12-rc2 |
839 |
/* |
74b0247fb [PATCH] sb1250-ma... |
840 |
* fill in the context |
1da177e4c Linux-2.6.12-rc2 |
841 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
842 |
|
1da177e4c Linux-2.6.12-rc2 |
843 |
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb_new; |
74b0247fb [PATCH] sb1250-ma... |
844 845 846 |
/* * point at next packet |
1da177e4c Linux-2.6.12-rc2 |
847 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
848 |
|
1da177e4c Linux-2.6.12-rc2 |
849 |
d->sbdma_addptr = nextdsc; |
74b0247fb [PATCH] sb1250-ma... |
850 851 |
/* |
1da177e4c Linux-2.6.12-rc2 |
852 853 |
* Give the buffer to the DMA engine. */ |
74b0247fb [PATCH] sb1250-ma... |
854 |
|
2039973af [PATCH] sb1250-ma... |
855 |
__raw_writeq(1, d->sbdma_dscrcnt); |
74b0247fb [PATCH] sb1250-ma... |
856 |
|
1da177e4c Linux-2.6.12-rc2 |
857 858 859 860 861 |
return 0; /* we did it */ } /********************************************************************** * SBDMA_ADD_TXBUFFER(d,sb) |
74b0247fb [PATCH] sb1250-ma... |
862 |
* |
1da177e4c Linux-2.6.12-rc2 |
863 864 |
* Add a transmit buffer to the specified DMA channel, causing a * transmit to start. |
74b0247fb [PATCH] sb1250-ma... |
865 866 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
867 868 |
* d - DMA channel descriptor * sb - sk_buff to add |
74b0247fb [PATCH] sb1250-ma... |
869 |
* |
1da177e4c Linux-2.6.12-rc2 |
870 871 872 873 |
* Return value: * 0 transmit queued successfully * otherwise error code ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
874 |
static int sbdma_add_txbuffer(struct sbmacdma *d, struct sk_buff *sb) |
1da177e4c Linux-2.6.12-rc2 |
875 |
{ |
73d739698 sb1250-mac.c: De-... |
876 877 |
struct sbdmadscr *dsc; struct sbdmadscr *nextdsc; |
1da177e4c Linux-2.6.12-rc2 |
878 879 880 |
uint64_t phys; uint64_t ncb; int length; |
74b0247fb [PATCH] sb1250-ma... |
881 |
|
1da177e4c Linux-2.6.12-rc2 |
882 |
/* get pointer to our current place in the ring */ |
74b0247fb [PATCH] sb1250-ma... |
883 |
|
1da177e4c Linux-2.6.12-rc2 |
884 885 |
dsc = d->sbdma_addptr; nextdsc = SBDMA_NEXTBUF(d,sbdma_addptr); |
74b0247fb [PATCH] sb1250-ma... |
886 |
|
1da177e4c Linux-2.6.12-rc2 |
887 888 889 890 891 |
/* * figure out if the ring is full - if the next descriptor * is the same as the one that we're going to remove from * the ring, the ring is full */ |
74b0247fb [PATCH] sb1250-ma... |
892 |
|
1da177e4c Linux-2.6.12-rc2 |
893 894 895 |
if (nextdsc == d->sbdma_remptr) { return -ENOSPC; } |
74b0247fb [PATCH] sb1250-ma... |
896 |
|
1da177e4c Linux-2.6.12-rc2 |
897 898 899 900 901 |
/* * Under Linux, it's not necessary to copy/coalesce buffers * like it is on NetBSD. We think they're all contiguous, * but that may not be true for GBE. */ |
74b0247fb [PATCH] sb1250-ma... |
902 |
|
1da177e4c Linux-2.6.12-rc2 |
903 |
length = sb->len; |
74b0247fb [PATCH] sb1250-ma... |
904 |
|
1da177e4c Linux-2.6.12-rc2 |
905 906 907 908 909 910 |
/* * fill in the descriptor. Note that the number of cache * blocks in the descriptor is the number of blocks * *spanned*, so we need to add in the offset (if any) * while doing the calculation. */ |
74b0247fb [PATCH] sb1250-ma... |
911 |
|
1da177e4c Linux-2.6.12-rc2 |
912 913 |
phys = virt_to_phys(sb->data); ncb = NUMCACHEBLKS(length+(phys & (SMP_CACHE_BYTES - 1))); |
74b0247fb [PATCH] sb1250-ma... |
914 |
dsc->dscr_a = phys | |
1da177e4c Linux-2.6.12-rc2 |
915 916 917 918 919 |
V_DMA_DSCRA_A_SIZE(ncb) | #ifndef CONFIG_SBMAC_COALESCE M_DMA_DSCRA_INTERRUPT | #endif M_DMA_ETHTX_SOP; |
74b0247fb [PATCH] sb1250-ma... |
920 |
|
1da177e4c Linux-2.6.12-rc2 |
921 922 923 924 |
/* transmitting: set outbound options and length */ dsc->dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) | V_DMA_DSCRB_PKT_SIZE(length); |
74b0247fb [PATCH] sb1250-ma... |
925 |
|
1da177e4c Linux-2.6.12-rc2 |
926 |
/* |
74b0247fb [PATCH] sb1250-ma... |
927 |
* fill in the context |
1da177e4c Linux-2.6.12-rc2 |
928 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
929 |
|
1da177e4c Linux-2.6.12-rc2 |
930 |
d->sbdma_ctxtable[dsc-d->sbdma_dscrtable] = sb; |
74b0247fb [PATCH] sb1250-ma... |
931 932 933 |
/* * point at next packet |
1da177e4c Linux-2.6.12-rc2 |
934 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
935 |
|
1da177e4c Linux-2.6.12-rc2 |
936 |
d->sbdma_addptr = nextdsc; |
74b0247fb [PATCH] sb1250-ma... |
937 938 |
/* |
1da177e4c Linux-2.6.12-rc2 |
939 940 |
* Give the buffer to the DMA engine. */ |
74b0247fb [PATCH] sb1250-ma... |
941 |
|
2039973af [PATCH] sb1250-ma... |
942 |
__raw_writeq(1, d->sbdma_dscrcnt); |
74b0247fb [PATCH] sb1250-ma... |
943 |
|
1da177e4c Linux-2.6.12-rc2 |
944 945 946 947 948 949 950 951 |
return 0; /* we did it */ } /********************************************************************** * SBDMA_EMPTYRING(d) |
74b0247fb [PATCH] sb1250-ma... |
952 |
* |
1da177e4c Linux-2.6.12-rc2 |
953 |
* Free all allocated sk_buffs on the specified DMA channel; |
74b0247fb [PATCH] sb1250-ma... |
954 955 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
956 |
* d - DMA channel |
74b0247fb [PATCH] sb1250-ma... |
957 |
* |
1da177e4c Linux-2.6.12-rc2 |
958 959 960 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
961 |
static void sbdma_emptyring(struct sbmacdma *d) |
1da177e4c Linux-2.6.12-rc2 |
962 963 964 |
{ int idx; struct sk_buff *sb; |
74b0247fb [PATCH] sb1250-ma... |
965 |
|
1da177e4c Linux-2.6.12-rc2 |
966 967 968 969 970 971 972 973 974 975 976 977 |
for (idx = 0; idx < d->sbdma_maxdescr; idx++) { sb = d->sbdma_ctxtable[idx]; if (sb) { dev_kfree_skb(sb); d->sbdma_ctxtable[idx] = NULL; } } } /********************************************************************** * SBDMA_FILLRING(d) |
74b0247fb [PATCH] sb1250-ma... |
978 |
* |
1da177e4c Linux-2.6.12-rc2 |
979 980 |
* Fill the specified DMA channel (must be receive channel) * with sk_buffs |
74b0247fb [PATCH] sb1250-ma... |
981 982 |
* * Input parameters: |
789585e96 sb1250: use netde... |
983 984 |
* sc - softc structure * d - DMA channel |
74b0247fb [PATCH] sb1250-ma... |
985 |
* |
1da177e4c Linux-2.6.12-rc2 |
986 987 988 |
* Return value: * nothing ********************************************************************* */ |
789585e96 sb1250: use netde... |
989 |
static void sbdma_fillring(struct sbmac_softc *sc, struct sbmacdma *d) |
1da177e4c Linux-2.6.12-rc2 |
990 991 |
{ int idx; |
74b0247fb [PATCH] sb1250-ma... |
992 |
|
789585e96 sb1250: use netde... |
993 994 |
for (idx = 0; idx < SBMAC_MAX_RXDESCR - 1; idx++) { if (sbdma_add_rcvbuffer(sc, d, NULL) != 0) |
1da177e4c Linux-2.6.12-rc2 |
995 996 997 |
break; } } |
d68300182 Netpoll support f... |
998 999 1000 1001 1002 1003 1004 |
#ifdef CONFIG_NET_POLL_CONTROLLER static void sbmac_netpoll(struct net_device *netdev) { struct sbmac_softc *sc = netdev_priv(netdev); int irq = sc->sbm_dev->irq; __raw_writeq(0, sc->sbm_imr); |
0da2f0f16 potential compile... |
1005 |
sbmac_intr(irq, netdev); |
d68300182 Netpoll support f... |
1006 1007 1008 1009 1010 1011 |
#ifdef CONFIG_SBMAC_COALESCE __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), sc->sbm_imr); #else |
7d2e3cb70 [netdrvr] Trim tr... |
1012 |
__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | |
d68300182 Netpoll support f... |
1013 1014 1015 1016 |
(M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); #endif } #endif |
1da177e4c Linux-2.6.12-rc2 |
1017 1018 |
/********************************************************************** |
693aa9470 add NAPI support ... |
1019 |
* SBDMA_RX_PROCESS(sc,d,work_to_do,poll) |
74b0247fb [PATCH] sb1250-ma... |
1020 1021 |
* * Process "completed" receive buffers on the specified DMA channel. |
1da177e4c Linux-2.6.12-rc2 |
1022 |
* |
74b0247fb [PATCH] sb1250-ma... |
1023 |
* Input parameters: |
693aa9470 add NAPI support ... |
1024 1025 1026 1027 1028 |
* sc - softc structure * d - DMA channel context * work_to_do - no. of packets to process before enabling interrupt * again (for NAPI) * poll - 1: using polling (for NAPI) |
74b0247fb [PATCH] sb1250-ma... |
1029 |
* |
1da177e4c Linux-2.6.12-rc2 |
1030 1031 1032 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
1033 1034 |
static int sbdma_rx_process(struct sbmac_softc *sc, struct sbmacdma *d, int work_to_do, int poll) |
1da177e4c Linux-2.6.12-rc2 |
1035 |
{ |
09f75cd7b [NET] drivers/net... |
1036 |
struct net_device *dev = sc->sbm_dev; |
1da177e4c Linux-2.6.12-rc2 |
1037 1038 |
int curidx; int hwidx; |
73d739698 sb1250-mac.c: De-... |
1039 |
struct sbdmadscr *dsc; |
1da177e4c Linux-2.6.12-rc2 |
1040 1041 |
struct sk_buff *sb; int len; |
693aa9470 add NAPI support ... |
1042 1043 |
int work_done = 0; int dropped = 0; |
74b0247fb [PATCH] sb1250-ma... |
1044 |
|
693aa9470 add NAPI support ... |
1045 1046 1047 1048 |
prefetch(d); again: /* Check if the HW dropped any frames */ |
09f75cd7b [NET] drivers/net... |
1049 |
dev->stats.rx_fifo_errors |
693aa9470 add NAPI support ... |
1050 1051 1052 1053 |
+= __raw_readq(sc->sbm_rxdma.sbdma_oodpktlost) & 0xffff; __raw_writeq(0, sc->sbm_rxdma.sbdma_oodpktlost); while (work_to_do-- > 0) { |
74b0247fb [PATCH] sb1250-ma... |
1054 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1055 1056 1057 |
* figure out where we are (as an index) and where * the hardware is (also as an index) * |
74b0247fb [PATCH] sb1250-ma... |
1058 |
* This could be done faster if (for example) the |
1da177e4c Linux-2.6.12-rc2 |
1059 1060 1061 1062 1063 |
* descriptor table was page-aligned and contiguous in * both virtual and physical memory -- you could then * just compare the low-order bits of the virtual address * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) */ |
74b0247fb [PATCH] sb1250-ma... |
1064 |
|
693aa9470 add NAPI support ... |
1065 1066 1067 1068 1069 |
dsc = d->sbdma_remptr; curidx = dsc - d->sbdma_dscrtable; prefetch(dsc); prefetch(&d->sbdma_ctxtable[curidx]); |
73d739698 sb1250-mac.c: De-... |
1070 1071 1072 |
hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - d->sbdma_dscrtable_phys) / sizeof(*d->sbdma_dscrtable); |
74b0247fb [PATCH] sb1250-ma... |
1073 |
|
1da177e4c Linux-2.6.12-rc2 |
1074 1075 1076 1077 1078 |
/* * If they're the same, that means we've processed all * of the descriptors up to (but not including) the one that * the hardware is working on right now. */ |
74b0247fb [PATCH] sb1250-ma... |
1079 |
|
1da177e4c Linux-2.6.12-rc2 |
1080 |
if (curidx == hwidx) |
693aa9470 add NAPI support ... |
1081 |
goto done; |
74b0247fb [PATCH] sb1250-ma... |
1082 |
|
1da177e4c Linux-2.6.12-rc2 |
1083 1084 1085 |
/* * Otherwise, get the packet's sk_buff ptr back */ |
74b0247fb [PATCH] sb1250-ma... |
1086 |
|
1da177e4c Linux-2.6.12-rc2 |
1087 1088 |
sb = d->sbdma_ctxtable[curidx]; d->sbdma_ctxtable[curidx] = NULL; |
74b0247fb [PATCH] sb1250-ma... |
1089 |
|
1da177e4c Linux-2.6.12-rc2 |
1090 |
len = (int)G_DMA_DSCRB_PKT_SIZE(dsc->dscr_b) - 4; |
74b0247fb [PATCH] sb1250-ma... |
1091 |
|
1da177e4c Linux-2.6.12-rc2 |
1092 1093 1094 1095 1096 |
/* * Check packet status. If good, process it. * If not, silently drop it and put it back on the * receive ring. */ |
74b0247fb [PATCH] sb1250-ma... |
1097 |
|
693aa9470 add NAPI support ... |
1098 |
if (likely (!(dsc->dscr_a & M_DMA_ETHRX_BAD))) { |
74b0247fb [PATCH] sb1250-ma... |
1099 |
|
1da177e4c Linux-2.6.12-rc2 |
1100 1101 1102 1103 1104 |
/* * Add a new buffer to replace the old one. If we fail * to allocate a buffer, we're going to drop this * packet and put it right back on the receive ring. */ |
74b0247fb [PATCH] sb1250-ma... |
1105 |
|
789585e96 sb1250: use netde... |
1106 1107 |
if (unlikely(sbdma_add_rcvbuffer(sc, d, NULL) == -ENOBUFS)) { |
09f75cd7b [NET] drivers/net... |
1108 |
dev->stats.rx_dropped++; |
789585e96 sb1250: use netde... |
1109 1110 |
/* Re-add old buffer */ sbdma_add_rcvbuffer(sc, d, sb); |
693aa9470 add NAPI support ... |
1111 1112 1113 1114 1115 |
/* No point in continuing at the moment */ printk(KERN_ERR "dropped packet (1) "); d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); goto done; |
1da177e4c Linux-2.6.12-rc2 |
1116 1117 1118 1119 1120 |
} else { /* * Set length into the packet */ skb_put(sb,len); |
74b0247fb [PATCH] sb1250-ma... |
1121 |
|
1da177e4c Linux-2.6.12-rc2 |
1122 1123 1124 1125 1126 |
/* * Buffer has been replaced on the * receive ring. Pass the buffer to * the kernel */ |
1da177e4c Linux-2.6.12-rc2 |
1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 |
sb->protocol = eth_type_trans(sb,d->sbdma_eth->sbm_dev); /* Check hw IPv4/TCP checksum if supported */ if (sc->rx_hw_checksum == ENABLE) { if (!((dsc->dscr_a) & M_DMA_ETHRX_BADIP4CS) && !((dsc->dscr_a) & M_DMA_ETHRX_BADTCPCS)) { sb->ip_summed = CHECKSUM_UNNECESSARY; /* don't need to set sb->csum */ } else { sb->ip_summed = CHECKSUM_NONE; } } |
693aa9470 add NAPI support ... |
1138 1139 1140 1141 1142 1143 1144 1145 |
prefetch(sb->data); prefetch((const void *)(((char *)sb->data)+32)); if (poll) dropped = netif_receive_skb(sb); else dropped = netif_rx(sb); if (dropped == NET_RX_DROP) { |
09f75cd7b [NET] drivers/net... |
1146 |
dev->stats.rx_dropped++; |
693aa9470 add NAPI support ... |
1147 1148 1149 1150 |
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); goto done; } else { |
09f75cd7b [NET] drivers/net... |
1151 1152 |
dev->stats.rx_bytes += len; dev->stats.rx_packets++; |
693aa9470 add NAPI support ... |
1153 |
} |
1da177e4c Linux-2.6.12-rc2 |
1154 1155 1156 1157 1158 1159 |
} } else { /* * Packet was mangled somehow. Just drop it and * put it back on the receive ring. */ |
09f75cd7b [NET] drivers/net... |
1160 |
dev->stats.rx_errors++; |
789585e96 sb1250: use netde... |
1161 |
sbdma_add_rcvbuffer(sc, d, sb); |
1da177e4c Linux-2.6.12-rc2 |
1162 |
} |
74b0247fb [PATCH] sb1250-ma... |
1163 1164 1165 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1166 1167 |
* .. and advance to the next buffer. */ |
74b0247fb [PATCH] sb1250-ma... |
1168 |
|
1da177e4c Linux-2.6.12-rc2 |
1169 |
d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
693aa9470 add NAPI support ... |
1170 1171 1172 1173 1174 |
work_done++; } if (!poll) { work_to_do = 32; goto again; /* collect fifo drop statistics again */ |
1da177e4c Linux-2.6.12-rc2 |
1175 |
} |
693aa9470 add NAPI support ... |
1176 1177 |
done: return work_done; |
1da177e4c Linux-2.6.12-rc2 |
1178 |
} |
1da177e4c Linux-2.6.12-rc2 |
1179 1180 |
/********************************************************************** * SBDMA_TX_PROCESS(sc,d) |
74b0247fb [PATCH] sb1250-ma... |
1181 1182 |
* * Process "completed" transmit buffers on the specified DMA channel. |
1da177e4c Linux-2.6.12-rc2 |
1183 1184 |
* This is normally called within the interrupt service routine. * Note that this isn't really ideal for priority channels, since |
74b0247fb [PATCH] sb1250-ma... |
1185 1186 |
* it processes all of the packets on a given channel before * returning. |
1da177e4c Linux-2.6.12-rc2 |
1187 |
* |
74b0247fb [PATCH] sb1250-ma... |
1188 |
* Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1189 |
* sc - softc structure |
693aa9470 add NAPI support ... |
1190 1191 |
* d - DMA channel context * poll - 1: using polling (for NAPI) |
74b0247fb [PATCH] sb1250-ma... |
1192 |
* |
1da177e4c Linux-2.6.12-rc2 |
1193 1194 1195 |
* Return value: * nothing ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
1196 1197 |
static void sbdma_tx_process(struct sbmac_softc *sc, struct sbmacdma *d, int poll) |
1da177e4c Linux-2.6.12-rc2 |
1198 |
{ |
09f75cd7b [NET] drivers/net... |
1199 |
struct net_device *dev = sc->sbm_dev; |
1da177e4c Linux-2.6.12-rc2 |
1200 1201 |
int curidx; int hwidx; |
73d739698 sb1250-mac.c: De-... |
1202 |
struct sbdmadscr *dsc; |
1da177e4c Linux-2.6.12-rc2 |
1203 1204 |
struct sk_buff *sb; unsigned long flags; |
693aa9470 add NAPI support ... |
1205 |
int packets_handled = 0; |
1da177e4c Linux-2.6.12-rc2 |
1206 1207 |
spin_lock_irqsave(&(sc->sbm_lock), flags); |
74b0247fb [PATCH] sb1250-ma... |
1208 |
|
693aa9470 add NAPI support ... |
1209 1210 |
if (d->sbdma_remptr == d->sbdma_addptr) goto end_unlock; |
73d739698 sb1250-mac.c: De-... |
1211 1212 |
hwidx = ((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - d->sbdma_dscrtable_phys) / sizeof(*d->sbdma_dscrtable); |
693aa9470 add NAPI support ... |
1213 |
|
1da177e4c Linux-2.6.12-rc2 |
1214 |
for (;;) { |
74b0247fb [PATCH] sb1250-ma... |
1215 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1216 1217 1218 |
* figure out where we are (as an index) and where * the hardware is (also as an index) * |
74b0247fb [PATCH] sb1250-ma... |
1219 |
* This could be done faster if (for example) the |
1da177e4c Linux-2.6.12-rc2 |
1220 1221 1222 1223 1224 |
* descriptor table was page-aligned and contiguous in * both virtual and physical memory -- you could then * just compare the low-order bits of the virtual address * (sbdma_remptr) and the physical address (sbdma_curdscr CSR) */ |
74b0247fb [PATCH] sb1250-ma... |
1225 |
|
1da177e4c Linux-2.6.12-rc2 |
1226 |
curidx = d->sbdma_remptr - d->sbdma_dscrtable; |
1da177e4c Linux-2.6.12-rc2 |
1227 1228 1229 1230 1231 1232 |
/* * If they're the same, that means we've processed all * of the descriptors up to (but not including) the one that * the hardware is working on right now. */ |
74b0247fb [PATCH] sb1250-ma... |
1233 |
|
1da177e4c Linux-2.6.12-rc2 |
1234 1235 |
if (curidx == hwidx) break; |
74b0247fb [PATCH] sb1250-ma... |
1236 |
|
1da177e4c Linux-2.6.12-rc2 |
1237 1238 1239 |
/* * Otherwise, get the packet's sk_buff ptr back */ |
74b0247fb [PATCH] sb1250-ma... |
1240 |
|
1da177e4c Linux-2.6.12-rc2 |
1241 1242 1243 |
dsc = &(d->sbdma_dscrtable[curidx]); sb = d->sbdma_ctxtable[curidx]; d->sbdma_ctxtable[curidx] = NULL; |
74b0247fb [PATCH] sb1250-ma... |
1244 |
|
1da177e4c Linux-2.6.12-rc2 |
1245 1246 1247 |
/* * Stats */ |
74b0247fb [PATCH] sb1250-ma... |
1248 |
|
09f75cd7b [NET] drivers/net... |
1249 1250 |
dev->stats.tx_bytes += sb->len; dev->stats.tx_packets++; |
74b0247fb [PATCH] sb1250-ma... |
1251 |
|
1da177e4c Linux-2.6.12-rc2 |
1252 1253 1254 |
/* * for transmits, we just free buffers. */ |
74b0247fb [PATCH] sb1250-ma... |
1255 |
|
1da177e4c Linux-2.6.12-rc2 |
1256 |
dev_kfree_skb_irq(sb); |
74b0247fb [PATCH] sb1250-ma... |
1257 1258 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1259 1260 1261 1262 |
* .. and advance to the next buffer. */ d->sbdma_remptr = SBDMA_NEXTBUF(d,sbdma_remptr); |
74b0247fb [PATCH] sb1250-ma... |
1263 |
|
693aa9470 add NAPI support ... |
1264 |
packets_handled++; |
1da177e4c Linux-2.6.12-rc2 |
1265 |
} |
74b0247fb [PATCH] sb1250-ma... |
1266 |
|
1da177e4c Linux-2.6.12-rc2 |
1267 1268 1269 1270 1271 |
/* * Decide if we should wake up the protocol or not. * Other drivers seem to do this when we reach a low * watermark on the transmit queue. */ |
74b0247fb [PATCH] sb1250-ma... |
1272 |
|
693aa9470 add NAPI support ... |
1273 1274 |
if (packets_handled) netif_wake_queue(d->sbdma_eth->sbm_dev); |
74b0247fb [PATCH] sb1250-ma... |
1275 |
|
693aa9470 add NAPI support ... |
1276 |
end_unlock: |
1da177e4c Linux-2.6.12-rc2 |
1277 |
spin_unlock_irqrestore(&(sc->sbm_lock), flags); |
74b0247fb [PATCH] sb1250-ma... |
1278 |
|
1da177e4c Linux-2.6.12-rc2 |
1279 1280 1281 1282 1283 1284 |
} /********************************************************************** * SBMAC_INITCTX(s) |
74b0247fb [PATCH] sb1250-ma... |
1285 |
* |
1da177e4c Linux-2.6.12-rc2 |
1286 1287 1288 1289 |
* Initialize an Ethernet context structure - this is called * once per MAC on the 1250. Memory is allocated here, so don't * call it again from inside the ioctl routines that bring the * interface up/down |
74b0247fb [PATCH] sb1250-ma... |
1290 1291 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1292 |
* s - sbmac context structure |
74b0247fb [PATCH] sb1250-ma... |
1293 |
* |
1da177e4c Linux-2.6.12-rc2 |
1294 1295 1296 1297 1298 1299 |
* Return value: * 0 ********************************************************************* */ static int sbmac_initctx(struct sbmac_softc *s) { |
74b0247fb [PATCH] sb1250-ma... |
1300 1301 1302 |
/* * figure out the addresses of some ports |
1da177e4c Linux-2.6.12-rc2 |
1303 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1304 |
|
1da177e4c Linux-2.6.12-rc2 |
1305 1306 1307 1308 1309 1310 1311 1312 |
s->sbm_macenable = s->sbm_base + R_MAC_ENABLE; s->sbm_maccfg = s->sbm_base + R_MAC_CFG; s->sbm_fifocfg = s->sbm_base + R_MAC_THRSH_CFG; s->sbm_framecfg = s->sbm_base + R_MAC_FRAMECFG; s->sbm_rxfilter = s->sbm_base + R_MAC_ADFILTER_CFG; s->sbm_isr = s->sbm_base + R_MAC_STATUS; s->sbm_imr = s->sbm_base + R_MAC_INT_MASK; s->sbm_mdio = s->sbm_base + R_MAC_MDIO; |
1da177e4c Linux-2.6.12-rc2 |
1313 1314 1315 1316 |
/* * Initialize the DMA channels. Right now, only one per MAC is used * Note: Only do this _once_, as it allocates memory from the kernel! */ |
74b0247fb [PATCH] sb1250-ma... |
1317 |
|
1da177e4c Linux-2.6.12-rc2 |
1318 1319 |
sbdma_initctx(&(s->sbm_txdma),s,0,DMA_TX,SBMAC_MAX_TXDESCR); sbdma_initctx(&(s->sbm_rxdma),s,0,DMA_RX,SBMAC_MAX_RXDESCR); |
74b0247fb [PATCH] sb1250-ma... |
1320 |
|
1da177e4c Linux-2.6.12-rc2 |
1321 1322 1323 |
/* * initial state is OFF */ |
74b0247fb [PATCH] sb1250-ma... |
1324 |
|
1da177e4c Linux-2.6.12-rc2 |
1325 |
s->sbm_state = sbmac_state_off; |
74b0247fb [PATCH] sb1250-ma... |
1326 |
|
1da177e4c Linux-2.6.12-rc2 |
1327 1328 |
return 0; } |
73d739698 sb1250-mac.c: De-... |
1329 |
static void sbdma_uninitctx(struct sbmacdma *d) |
1da177e4c Linux-2.6.12-rc2 |
1330 |
{ |
693aa9470 add NAPI support ... |
1331 1332 1333 |
if (d->sbdma_dscrtable_unaligned) { kfree(d->sbdma_dscrtable_unaligned); d->sbdma_dscrtable_unaligned = d->sbdma_dscrtable = NULL; |
1da177e4c Linux-2.6.12-rc2 |
1334 |
} |
74b0247fb [PATCH] sb1250-ma... |
1335 |
|
1da177e4c Linux-2.6.12-rc2 |
1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 |
if (d->sbdma_ctxtable) { kfree(d->sbdma_ctxtable); d->sbdma_ctxtable = NULL; } } static void sbmac_uninitctx(struct sbmac_softc *sc) { sbdma_uninitctx(&(sc->sbm_txdma)); sbdma_uninitctx(&(sc->sbm_rxdma)); } /********************************************************************** * SBMAC_CHANNEL_START(s) |
74b0247fb [PATCH] sb1250-ma... |
1352 |
* |
1da177e4c Linux-2.6.12-rc2 |
1353 |
* Start packet processing on this MAC. |
74b0247fb [PATCH] sb1250-ma... |
1354 1355 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1356 |
* s - sbmac structure |
74b0247fb [PATCH] sb1250-ma... |
1357 |
* |
1da177e4c Linux-2.6.12-rc2 |
1358 1359 1360 1361 1362 1363 1364 |
* Return value: * nothing ********************************************************************* */ static void sbmac_channel_start(struct sbmac_softc *s) { uint64_t reg; |
73d739698 sb1250-mac.c: De-... |
1365 |
void __iomem *port; |
1da177e4c Linux-2.6.12-rc2 |
1366 1367 |
uint64_t cfg,fifo,framecfg; int idx, th_value; |
74b0247fb [PATCH] sb1250-ma... |
1368 |
|
1da177e4c Linux-2.6.12-rc2 |
1369 1370 1371 1372 1373 1374 |
/* * Don't do this if running */ if (s->sbm_state == sbmac_state_on) return; |
74b0247fb [PATCH] sb1250-ma... |
1375 |
|
1da177e4c Linux-2.6.12-rc2 |
1376 1377 1378 |
/* * Bring the controller out of reset, but leave it off. */ |
74b0247fb [PATCH] sb1250-ma... |
1379 |
|
2039973af [PATCH] sb1250-ma... |
1380 |
__raw_writeq(0, s->sbm_macenable); |
74b0247fb [PATCH] sb1250-ma... |
1381 |
|
1da177e4c Linux-2.6.12-rc2 |
1382 1383 1384 |
/* * Ignore all received packets */ |
74b0247fb [PATCH] sb1250-ma... |
1385 |
|
2039973af [PATCH] sb1250-ma... |
1386 |
__raw_writeq(0, s->sbm_rxfilter); |
74b0247fb [PATCH] sb1250-ma... |
1387 1388 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1389 1390 |
* Calculate values for various control registers. */ |
74b0247fb [PATCH] sb1250-ma... |
1391 |
|
1da177e4c Linux-2.6.12-rc2 |
1392 |
cfg = M_MAC_RETRY_EN | |
74b0247fb [PATCH] sb1250-ma... |
1393 |
M_MAC_TX_HOLD_SOP_EN | |
1da177e4c Linux-2.6.12-rc2 |
1394 1395 1396 1397 1398 |
V_MAC_TX_PAUSE_CNT_16K | M_MAC_AP_STAT_EN | M_MAC_FAST_SYNC | M_MAC_SS_EN | 0; |
74b0247fb [PATCH] sb1250-ma... |
1399 1400 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1401 1402 1403 1404 |
* Be sure that RD_THRSH+WR_THRSH <= 32 for pass1 pars * and make sure that RD_THRSH + WR_THRSH <=128 for pass2 and above * Use a larger RD_THRSH for gigabit */ |
f90fdc3cc [PATCH] sb1250-ma... |
1405 |
if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) |
1da177e4c Linux-2.6.12-rc2 |
1406 |
th_value = 28; |
f90fdc3cc [PATCH] sb1250-ma... |
1407 1408 |
else th_value = 64; |
1da177e4c Linux-2.6.12-rc2 |
1409 1410 1411 1412 1413 1414 1415 |
fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ ((s->sbm_speed == sbmac_speed_1000) ? V_MAC_TX_RD_THRSH(th_value) : V_MAC_TX_RD_THRSH(4)) | V_MAC_TX_RL_THRSH(4) | V_MAC_RX_PL_THRSH(4) | V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ |
1da177e4c Linux-2.6.12-rc2 |
1416 1417 1418 1419 1420 1421 1422 1423 |
V_MAC_RX_RL_THRSH(8) | 0; framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | V_MAC_MAX_FRAMESZ_DEFAULT | V_MAC_BACKOFF_SEL(1); /* |
74b0247fb [PATCH] sb1250-ma... |
1424 |
* Clear out the hash address map |
1da177e4c Linux-2.6.12-rc2 |
1425 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1426 |
|
1da177e4c Linux-2.6.12-rc2 |
1427 1428 |
port = s->sbm_base + R_MAC_HASH_BASE; for (idx = 0; idx < MAC_HASH_COUNT; idx++) { |
2039973af [PATCH] sb1250-ma... |
1429 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
1430 1431 |
port += sizeof(uint64_t); } |
74b0247fb [PATCH] sb1250-ma... |
1432 |
|
1da177e4c Linux-2.6.12-rc2 |
1433 1434 1435 |
/* * Clear out the exact-match table */ |
74b0247fb [PATCH] sb1250-ma... |
1436 |
|
1da177e4c Linux-2.6.12-rc2 |
1437 1438 |
port = s->sbm_base + R_MAC_ADDR_BASE; for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { |
2039973af [PATCH] sb1250-ma... |
1439 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
1440 1441 |
port += sizeof(uint64_t); } |
74b0247fb [PATCH] sb1250-ma... |
1442 |
|
1da177e4c Linux-2.6.12-rc2 |
1443 1444 1445 |
/* * Clear out the DMA Channel mapping table registers */ |
74b0247fb [PATCH] sb1250-ma... |
1446 |
|
1da177e4c Linux-2.6.12-rc2 |
1447 1448 |
port = s->sbm_base + R_MAC_CHUP0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { |
2039973af [PATCH] sb1250-ma... |
1449 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
1450 1451 1452 1453 1454 1455 |
port += sizeof(uint64_t); } port = s->sbm_base + R_MAC_CHLO0_BASE; for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { |
2039973af [PATCH] sb1250-ma... |
1456 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
1457 1458 |
port += sizeof(uint64_t); } |
74b0247fb [PATCH] sb1250-ma... |
1459 |
|
1da177e4c Linux-2.6.12-rc2 |
1460 1461 1462 1463 |
/* * Program the hardware address. It goes into the hardware-address * register as well as the first filter register. */ |
74b0247fb [PATCH] sb1250-ma... |
1464 |
|
1da177e4c Linux-2.6.12-rc2 |
1465 |
reg = sbmac_addr2reg(s->sbm_hwaddr); |
74b0247fb [PATCH] sb1250-ma... |
1466 |
|
1da177e4c Linux-2.6.12-rc2 |
1467 |
port = s->sbm_base + R_MAC_ADDR_BASE; |
2039973af [PATCH] sb1250-ma... |
1468 |
__raw_writeq(reg, port); |
1da177e4c Linux-2.6.12-rc2 |
1469 1470 1471 1472 1473 1474 1475 1476 |
port = s->sbm_base + R_MAC_ETHERNET_ADDR; #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS /* * Pass1 SOCs do not receive packets addressed to the * destination address in the R_MAC_ETHERNET_ADDR register. * Set the value to zero. */ |
2039973af [PATCH] sb1250-ma... |
1477 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
1478 |
#else |
2039973af [PATCH] sb1250-ma... |
1479 |
__raw_writeq(reg, port); |
1da177e4c Linux-2.6.12-rc2 |
1480 |
#endif |
74b0247fb [PATCH] sb1250-ma... |
1481 |
|
1da177e4c Linux-2.6.12-rc2 |
1482 1483 1484 1485 |
/* * Set the receive filter for no packets, and write values * to the various config registers */ |
74b0247fb [PATCH] sb1250-ma... |
1486 |
|
2039973af [PATCH] sb1250-ma... |
1487 1488 1489 1490 1491 |
__raw_writeq(0, s->sbm_rxfilter); __raw_writeq(0, s->sbm_imr); __raw_writeq(framecfg, s->sbm_framecfg); __raw_writeq(fifo, s->sbm_fifocfg); __raw_writeq(cfg, s->sbm_maccfg); |
74b0247fb [PATCH] sb1250-ma... |
1492 |
|
1da177e4c Linux-2.6.12-rc2 |
1493 1494 1495 |
/* * Initialize DMA channels (rings should be ok now) */ |
74b0247fb [PATCH] sb1250-ma... |
1496 |
|
1da177e4c Linux-2.6.12-rc2 |
1497 1498 |
sbdma_channel_start(&(s->sbm_rxdma), DMA_RX); sbdma_channel_start(&(s->sbm_txdma), DMA_TX); |
74b0247fb [PATCH] sb1250-ma... |
1499 |
|
1da177e4c Linux-2.6.12-rc2 |
1500 1501 1502 1503 1504 1505 |
/* * Configure the speed, duplex, and flow control */ sbmac_set_speed(s,s->sbm_speed); sbmac_set_duplex(s,s->sbm_duplex,s->sbm_fc); |
74b0247fb [PATCH] sb1250-ma... |
1506 |
|
1da177e4c Linux-2.6.12-rc2 |
1507 1508 1509 |
/* * Fill the receive ring */ |
74b0247fb [PATCH] sb1250-ma... |
1510 |
|
789585e96 sb1250: use netde... |
1511 |
sbdma_fillring(s, &(s->sbm_rxdma)); |
74b0247fb [PATCH] sb1250-ma... |
1512 1513 |
/* |
1da177e4c Linux-2.6.12-rc2 |
1514 |
* Turn on the rest of the bits in the enable register |
74b0247fb [PATCH] sb1250-ma... |
1515 |
*/ |
f90fdc3cc [PATCH] sb1250-ma... |
1516 1517 1518 1519 |
#if defined(CONFIG_SIBYTE_BCM1x55) || defined(CONFIG_SIBYTE_BCM1x80) __raw_writeq(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0, s->sbm_macenable); #elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) |
2039973af [PATCH] sb1250-ma... |
1520 |
__raw_writeq(M_MAC_RXDMA_EN0 | |
1da177e4c Linux-2.6.12-rc2 |
1521 1522 |
M_MAC_TXDMA_EN0 | M_MAC_RX_ENABLE | |
2039973af [PATCH] sb1250-ma... |
1523 |
M_MAC_TX_ENABLE, s->sbm_macenable); |
f90fdc3cc [PATCH] sb1250-ma... |
1524 1525 1526 |
#else #error invalid SiByte MAC configuation #endif |
1da177e4c Linux-2.6.12-rc2 |
1527 1528 |
#ifdef CONFIG_SBMAC_COALESCE |
2039973af [PATCH] sb1250-ma... |
1529 1530 |
__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr); |
1da177e4c Linux-2.6.12-rc2 |
1531 |
#else |
2039973af [PATCH] sb1250-ma... |
1532 1533 |
__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr); |
1da177e4c Linux-2.6.12-rc2 |
1534 |
#endif |
74b0247fb [PATCH] sb1250-ma... |
1535 1536 1537 |
/* * Enable receiving unicasts and broadcasts |
1da177e4c Linux-2.6.12-rc2 |
1538 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1539 |
|
2039973af [PATCH] sb1250-ma... |
1540 |
__raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter); |
74b0247fb [PATCH] sb1250-ma... |
1541 |
|
1da177e4c Linux-2.6.12-rc2 |
1542 |
/* |
74b0247fb [PATCH] sb1250-ma... |
1543 |
* we're running now. |
1da177e4c Linux-2.6.12-rc2 |
1544 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1545 |
|
1da177e4c Linux-2.6.12-rc2 |
1546 |
s->sbm_state = sbmac_state_on; |
74b0247fb [PATCH] sb1250-ma... |
1547 1548 1549 |
/* * Program multicast addresses |
1da177e4c Linux-2.6.12-rc2 |
1550 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1551 |
|
1da177e4c Linux-2.6.12-rc2 |
1552 |
sbmac_setmulti(s); |
74b0247fb [PATCH] sb1250-ma... |
1553 1554 1555 |
/* * If channel was in promiscuous mode before, turn that on |
1da177e4c Linux-2.6.12-rc2 |
1556 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1557 |
|
1da177e4c Linux-2.6.12-rc2 |
1558 1559 1560 |
if (s->sbm_devflags & IFF_PROMISC) { sbmac_promiscuous_mode(s,1); } |
74b0247fb [PATCH] sb1250-ma... |
1561 |
|
1da177e4c Linux-2.6.12-rc2 |
1562 1563 1564 1565 1566 |
} /********************************************************************** * SBMAC_CHANNEL_STOP(s) |
74b0247fb [PATCH] sb1250-ma... |
1567 |
* |
1da177e4c Linux-2.6.12-rc2 |
1568 |
* Stop packet processing on this MAC. |
74b0247fb [PATCH] sb1250-ma... |
1569 1570 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1571 |
* s - sbmac structure |
74b0247fb [PATCH] sb1250-ma... |
1572 |
* |
1da177e4c Linux-2.6.12-rc2 |
1573 1574 1575 1576 1577 1578 1579 |
* Return value: * nothing ********************************************************************* */ static void sbmac_channel_stop(struct sbmac_softc *s) { /* don't do this if already stopped */ |
74b0247fb [PATCH] sb1250-ma... |
1580 |
|
1da177e4c Linux-2.6.12-rc2 |
1581 1582 |
if (s->sbm_state == sbmac_state_off) return; |
74b0247fb [PATCH] sb1250-ma... |
1583 |
|
1da177e4c Linux-2.6.12-rc2 |
1584 |
/* don't accept any packets, disable all interrupts */ |
74b0247fb [PATCH] sb1250-ma... |
1585 |
|
2039973af [PATCH] sb1250-ma... |
1586 1587 |
__raw_writeq(0, s->sbm_rxfilter); __raw_writeq(0, s->sbm_imr); |
74b0247fb [PATCH] sb1250-ma... |
1588 |
|
1da177e4c Linux-2.6.12-rc2 |
1589 |
/* Turn off ticker */ |
74b0247fb [PATCH] sb1250-ma... |
1590 |
|
1da177e4c Linux-2.6.12-rc2 |
1591 |
/* XXX */ |
74b0247fb [PATCH] sb1250-ma... |
1592 |
|
1da177e4c Linux-2.6.12-rc2 |
1593 |
/* turn off receiver and transmitter */ |
74b0247fb [PATCH] sb1250-ma... |
1594 |
|
2039973af [PATCH] sb1250-ma... |
1595 |
__raw_writeq(0, s->sbm_macenable); |
74b0247fb [PATCH] sb1250-ma... |
1596 |
|
1da177e4c Linux-2.6.12-rc2 |
1597 |
/* We're stopped now. */ |
74b0247fb [PATCH] sb1250-ma... |
1598 |
|
1da177e4c Linux-2.6.12-rc2 |
1599 |
s->sbm_state = sbmac_state_off; |
74b0247fb [PATCH] sb1250-ma... |
1600 |
|
1da177e4c Linux-2.6.12-rc2 |
1601 1602 1603 |
/* * Stop DMA channels (rings should be ok now) */ |
74b0247fb [PATCH] sb1250-ma... |
1604 |
|
1da177e4c Linux-2.6.12-rc2 |
1605 1606 |
sbdma_channel_stop(&(s->sbm_rxdma)); sbdma_channel_stop(&(s->sbm_txdma)); |
74b0247fb [PATCH] sb1250-ma... |
1607 |
|
1da177e4c Linux-2.6.12-rc2 |
1608 |
/* Empty the receive and transmit rings */ |
74b0247fb [PATCH] sb1250-ma... |
1609 |
|
1da177e4c Linux-2.6.12-rc2 |
1610 1611 |
sbdma_emptyring(&(s->sbm_rxdma)); sbdma_emptyring(&(s->sbm_txdma)); |
74b0247fb [PATCH] sb1250-ma... |
1612 |
|
1da177e4c Linux-2.6.12-rc2 |
1613 1614 1615 1616 |
} /********************************************************************** * SBMAC_SET_CHANNEL_STATE(state) |
74b0247fb [PATCH] sb1250-ma... |
1617 |
* |
1da177e4c Linux-2.6.12-rc2 |
1618 |
* Set the channel's state ON or OFF |
74b0247fb [PATCH] sb1250-ma... |
1619 1620 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1621 |
* state - new state |
74b0247fb [PATCH] sb1250-ma... |
1622 |
* |
1da177e4c Linux-2.6.12-rc2 |
1623 1624 1625 |
* Return value: * old state ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
1626 1627 |
static enum sbmac_state sbmac_set_channel_state(struct sbmac_softc *sc, enum sbmac_state state) |
1da177e4c Linux-2.6.12-rc2 |
1628 |
{ |
73d739698 sb1250-mac.c: De-... |
1629 |
enum sbmac_state oldstate = sc->sbm_state; |
74b0247fb [PATCH] sb1250-ma... |
1630 |
|
1da177e4c Linux-2.6.12-rc2 |
1631 1632 1633 |
/* * If same as previous state, return */ |
74b0247fb [PATCH] sb1250-ma... |
1634 |
|
1da177e4c Linux-2.6.12-rc2 |
1635 1636 1637 |
if (state == oldstate) { return oldstate; } |
74b0247fb [PATCH] sb1250-ma... |
1638 |
|
1da177e4c Linux-2.6.12-rc2 |
1639 |
/* |
74b0247fb [PATCH] sb1250-ma... |
1640 |
* If new state is ON, turn channel on |
1da177e4c Linux-2.6.12-rc2 |
1641 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1642 |
|
1da177e4c Linux-2.6.12-rc2 |
1643 1644 1645 1646 1647 1648 |
if (state == sbmac_state_on) { sbmac_channel_start(sc); } else { sbmac_channel_stop(sc); } |
74b0247fb [PATCH] sb1250-ma... |
1649 |
|
1da177e4c Linux-2.6.12-rc2 |
1650 1651 1652 |
/* * Return previous state */ |
74b0247fb [PATCH] sb1250-ma... |
1653 |
|
1da177e4c Linux-2.6.12-rc2 |
1654 1655 1656 1657 1658 1659 |
return oldstate; } /********************************************************************** * SBMAC_PROMISCUOUS_MODE(sc,onoff) |
74b0247fb [PATCH] sb1250-ma... |
1660 |
* |
1da177e4c Linux-2.6.12-rc2 |
1661 |
* Turn on or off promiscuous mode |
74b0247fb [PATCH] sb1250-ma... |
1662 1663 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1664 1665 |
* sc - softc * onoff - 1 to turn on, 0 to turn off |
74b0247fb [PATCH] sb1250-ma... |
1666 |
* |
1da177e4c Linux-2.6.12-rc2 |
1667 1668 1669 1670 1671 1672 1673 |
* Return value: * nothing ********************************************************************* */ static void sbmac_promiscuous_mode(struct sbmac_softc *sc,int onoff) { uint64_t reg; |
74b0247fb [PATCH] sb1250-ma... |
1674 |
|
1da177e4c Linux-2.6.12-rc2 |
1675 1676 |
if (sc->sbm_state != sbmac_state_on) return; |
74b0247fb [PATCH] sb1250-ma... |
1677 |
|
1da177e4c Linux-2.6.12-rc2 |
1678 |
if (onoff) { |
2039973af [PATCH] sb1250-ma... |
1679 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
1680 |
reg |= M_MAC_ALLPKT_EN; |
2039973af [PATCH] sb1250-ma... |
1681 |
__raw_writeq(reg, sc->sbm_rxfilter); |
74b0247fb [PATCH] sb1250-ma... |
1682 |
} |
1da177e4c Linux-2.6.12-rc2 |
1683 |
else { |
2039973af [PATCH] sb1250-ma... |
1684 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
1685 |
reg &= ~M_MAC_ALLPKT_EN; |
2039973af [PATCH] sb1250-ma... |
1686 |
__raw_writeq(reg, sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
1687 1688 1689 1690 1691 |
} } /********************************************************************** * SBMAC_SETIPHDR_OFFSET(sc,onoff) |
74b0247fb [PATCH] sb1250-ma... |
1692 |
* |
1da177e4c Linux-2.6.12-rc2 |
1693 |
* Set the iphdr offset as 15 assuming ethernet encapsulation |
74b0247fb [PATCH] sb1250-ma... |
1694 1695 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1696 |
* sc - softc |
74b0247fb [PATCH] sb1250-ma... |
1697 |
* |
1da177e4c Linux-2.6.12-rc2 |
1698 1699 1700 1701 1702 1703 1704 |
* Return value: * nothing ********************************************************************* */ static void sbmac_set_iphdr_offset(struct sbmac_softc *sc) { uint64_t reg; |
74b0247fb [PATCH] sb1250-ma... |
1705 |
|
1da177e4c Linux-2.6.12-rc2 |
1706 |
/* Hard code the off set to 15 for now */ |
2039973af [PATCH] sb1250-ma... |
1707 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
1708 |
reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15); |
2039973af [PATCH] sb1250-ma... |
1709 |
__raw_writeq(reg, sc->sbm_rxfilter); |
74b0247fb [PATCH] sb1250-ma... |
1710 |
|
f90fdc3cc [PATCH] sb1250-ma... |
1711 1712 1713 |
/* BCM1250 pass1 didn't have hardware checksum. Everything later does. */ if (soc_type == K_SYS_SOC_TYPE_BCM1250 && periph_rev < 2) { |
1da177e4c Linux-2.6.12-rc2 |
1714 |
sc->rx_hw_checksum = DISABLE; |
f90fdc3cc [PATCH] sb1250-ma... |
1715 1716 |
} else { sc->rx_hw_checksum = ENABLE; |
1da177e4c Linux-2.6.12-rc2 |
1717 1718 1719 1720 1721 1722 |
} } /********************************************************************** * SBMAC_ADDR2REG(ptr) |
74b0247fb [PATCH] sb1250-ma... |
1723 |
* |
1da177e4c Linux-2.6.12-rc2 |
1724 1725 |
* Convert six bytes into the 64-bit register value that * we typically write into the SBMAC's address/mcast registers |
74b0247fb [PATCH] sb1250-ma... |
1726 1727 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1728 |
* ptr - pointer to 6 bytes |
74b0247fb [PATCH] sb1250-ma... |
1729 |
* |
1da177e4c Linux-2.6.12-rc2 |
1730 1731 1732 1733 1734 1735 1736 |
* Return value: * register value ********************************************************************* */ static uint64_t sbmac_addr2reg(unsigned char *ptr) { uint64_t reg = 0; |
74b0247fb [PATCH] sb1250-ma... |
1737 |
|
1da177e4c Linux-2.6.12-rc2 |
1738 |
ptr += 6; |
74b0247fb [PATCH] sb1250-ma... |
1739 1740 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1741 |
reg <<= 8; |
74b0247fb [PATCH] sb1250-ma... |
1742 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1743 |
reg <<= 8; |
74b0247fb [PATCH] sb1250-ma... |
1744 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1745 |
reg <<= 8; |
74b0247fb [PATCH] sb1250-ma... |
1746 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1747 |
reg <<= 8; |
74b0247fb [PATCH] sb1250-ma... |
1748 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1749 |
reg <<= 8; |
74b0247fb [PATCH] sb1250-ma... |
1750 |
reg |= (uint64_t) *(--ptr); |
1da177e4c Linux-2.6.12-rc2 |
1751 1752 1753 1754 1755 1756 |
return reg; } /********************************************************************** * SBMAC_SET_SPEED(s,speed) |
74b0247fb [PATCH] sb1250-ma... |
1757 |
* |
1da177e4c Linux-2.6.12-rc2 |
1758 1759 |
* Configure LAN speed for the specified MAC. * Warning: must be called when MAC is off! |
74b0247fb [PATCH] sb1250-ma... |
1760 1761 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1762 |
* s - sbmac structure |
73d739698 sb1250-mac.c: De-... |
1763 |
* speed - speed to set MAC to (see enum sbmac_speed) |
74b0247fb [PATCH] sb1250-ma... |
1764 |
* |
1da177e4c Linux-2.6.12-rc2 |
1765 1766 1767 1768 |
* Return value: * 1 if successful * 0 indicates invalid parameters ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
1769 |
static int sbmac_set_speed(struct sbmac_softc *s, enum sbmac_speed speed) |
1da177e4c Linux-2.6.12-rc2 |
1770 1771 1772 1773 1774 1775 1776 |
{ uint64_t cfg; uint64_t framecfg; /* * Save new current values */ |
74b0247fb [PATCH] sb1250-ma... |
1777 |
|
1da177e4c Linux-2.6.12-rc2 |
1778 |
s->sbm_speed = speed; |
74b0247fb [PATCH] sb1250-ma... |
1779 |
|
1da177e4c Linux-2.6.12-rc2 |
1780 1781 1782 1783 |
if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ /* |
74b0247fb [PATCH] sb1250-ma... |
1784 |
* Read current register values |
1da177e4c Linux-2.6.12-rc2 |
1785 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1786 |
|
2039973af [PATCH] sb1250-ma... |
1787 1788 |
cfg = __raw_readq(s->sbm_maccfg); framecfg = __raw_readq(s->sbm_framecfg); |
74b0247fb [PATCH] sb1250-ma... |
1789 |
|
1da177e4c Linux-2.6.12-rc2 |
1790 1791 1792 |
/* * Mask out the stuff we want to change */ |
74b0247fb [PATCH] sb1250-ma... |
1793 |
|
1da177e4c Linux-2.6.12-rc2 |
1794 1795 1796 |
cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL); framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH | M_MAC_SLOT_SIZE); |
74b0247fb [PATCH] sb1250-ma... |
1797 |
|
1da177e4c Linux-2.6.12-rc2 |
1798 1799 1800 |
/* * Now add in the new bits */ |
74b0247fb [PATCH] sb1250-ma... |
1801 |
|
1da177e4c Linux-2.6.12-rc2 |
1802 1803 1804 1805 1806 1807 1808 1809 |
switch (speed) { case sbmac_speed_10: framecfg |= V_MAC_IFG_RX_10 | V_MAC_IFG_TX_10 | K_MAC_IFG_THRSH_10 | V_MAC_SLOT_SIZE_10; cfg |= V_MAC_SPEED_SEL_10MBPS; break; |
74b0247fb [PATCH] sb1250-ma... |
1810 |
|
1da177e4c Linux-2.6.12-rc2 |
1811 1812 1813 1814 1815 1816 1817 |
case sbmac_speed_100: framecfg |= V_MAC_IFG_RX_100 | V_MAC_IFG_TX_100 | V_MAC_IFG_THRSH_100 | V_MAC_SLOT_SIZE_100; cfg |= V_MAC_SPEED_SEL_100MBPS ; break; |
74b0247fb [PATCH] sb1250-ma... |
1818 |
|
1da177e4c Linux-2.6.12-rc2 |
1819 1820 1821 1822 1823 1824 1825 |
case sbmac_speed_1000: framecfg |= V_MAC_IFG_RX_1000 | V_MAC_IFG_TX_1000 | V_MAC_IFG_THRSH_1000 | V_MAC_SLOT_SIZE_1000; cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN; break; |
74b0247fb [PATCH] sb1250-ma... |
1826 |
|
1da177e4c Linux-2.6.12-rc2 |
1827 1828 1829 |
default: return 0; } |
74b0247fb [PATCH] sb1250-ma... |
1830 |
|
1da177e4c Linux-2.6.12-rc2 |
1831 |
/* |
74b0247fb [PATCH] sb1250-ma... |
1832 |
* Send the bits back to the hardware |
1da177e4c Linux-2.6.12-rc2 |
1833 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1834 |
|
2039973af [PATCH] sb1250-ma... |
1835 1836 |
__raw_writeq(framecfg, s->sbm_framecfg); __raw_writeq(cfg, s->sbm_maccfg); |
74b0247fb [PATCH] sb1250-ma... |
1837 |
|
1da177e4c Linux-2.6.12-rc2 |
1838 1839 1840 1841 1842 |
return 1; } /********************************************************************** * SBMAC_SET_DUPLEX(s,duplex,fc) |
74b0247fb [PATCH] sb1250-ma... |
1843 |
* |
1da177e4c Linux-2.6.12-rc2 |
1844 1845 |
* Set Ethernet duplex and flow control options for this MAC * Warning: must be called when MAC is off! |
74b0247fb [PATCH] sb1250-ma... |
1846 1847 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1848 |
* s - sbmac structure |
73d739698 sb1250-mac.c: De-... |
1849 1850 |
* duplex - duplex setting (see enum sbmac_duplex) * fc - flow control setting (see enum sbmac_fc) |
74b0247fb [PATCH] sb1250-ma... |
1851 |
* |
1da177e4c Linux-2.6.12-rc2 |
1852 1853 1854 1855 |
* Return value: * 1 if ok * 0 if an invalid parameter combination was specified ********************************************************************* */ |
73d739698 sb1250-mac.c: De-... |
1856 1857 |
static int sbmac_set_duplex(struct sbmac_softc *s, enum sbmac_duplex duplex, enum sbmac_fc fc) |
1da177e4c Linux-2.6.12-rc2 |
1858 1859 |
{ uint64_t cfg; |
74b0247fb [PATCH] sb1250-ma... |
1860 |
|
1da177e4c Linux-2.6.12-rc2 |
1861 1862 1863 |
/* * Save new current values */ |
74b0247fb [PATCH] sb1250-ma... |
1864 |
|
1da177e4c Linux-2.6.12-rc2 |
1865 1866 |
s->sbm_duplex = duplex; s->sbm_fc = fc; |
74b0247fb [PATCH] sb1250-ma... |
1867 |
|
1da177e4c Linux-2.6.12-rc2 |
1868 1869 |
if (s->sbm_state == sbmac_state_on) return 0; /* save for next restart */ |
74b0247fb [PATCH] sb1250-ma... |
1870 |
|
1da177e4c Linux-2.6.12-rc2 |
1871 |
/* |
74b0247fb [PATCH] sb1250-ma... |
1872 |
* Read current register values |
1da177e4c Linux-2.6.12-rc2 |
1873 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1874 |
|
2039973af [PATCH] sb1250-ma... |
1875 |
cfg = __raw_readq(s->sbm_maccfg); |
74b0247fb [PATCH] sb1250-ma... |
1876 |
|
1da177e4c Linux-2.6.12-rc2 |
1877 1878 1879 |
/* * Mask off the stuff we're about to change */ |
74b0247fb [PATCH] sb1250-ma... |
1880 |
|
1da177e4c Linux-2.6.12-rc2 |
1881 |
cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN); |
74b0247fb [PATCH] sb1250-ma... |
1882 |
|
1da177e4c Linux-2.6.12-rc2 |
1883 1884 1885 1886 1887 1888 |
switch (duplex) { case sbmac_duplex_half: switch (fc) { case sbmac_fc_disabled: cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED; break; |
74b0247fb [PATCH] sb1250-ma... |
1889 |
|
1da177e4c Linux-2.6.12-rc2 |
1890 1891 1892 |
case sbmac_fc_collision: cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED; break; |
74b0247fb [PATCH] sb1250-ma... |
1893 |
|
1da177e4c Linux-2.6.12-rc2 |
1894 1895 1896 |
case sbmac_fc_carrier: cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR; break; |
74b0247fb [PATCH] sb1250-ma... |
1897 |
|
1da177e4c Linux-2.6.12-rc2 |
1898 1899 1900 1901 1902 |
case sbmac_fc_frame: /* not valid in half duplex */ default: /* invalid selection */ return 0; } break; |
74b0247fb [PATCH] sb1250-ma... |
1903 |
|
1da177e4c Linux-2.6.12-rc2 |
1904 1905 1906 1907 1908 |
case sbmac_duplex_full: switch (fc) { case sbmac_fc_disabled: cfg |= V_MAC_FC_CMD_DISABLED; break; |
74b0247fb [PATCH] sb1250-ma... |
1909 |
|
1da177e4c Linux-2.6.12-rc2 |
1910 1911 1912 |
case sbmac_fc_frame: cfg |= V_MAC_FC_CMD_ENABLED; break; |
74b0247fb [PATCH] sb1250-ma... |
1913 |
|
1da177e4c Linux-2.6.12-rc2 |
1914 1915 |
case sbmac_fc_collision: /* not valid in full duplex */ case sbmac_fc_carrier: /* not valid in full duplex */ |
1da177e4c Linux-2.6.12-rc2 |
1916 1917 1918 1919 |
default: return 0; } break; |
f5279ffdc sb1250-mac: Drive... |
1920 1921 |
default: return 0; |
1da177e4c Linux-2.6.12-rc2 |
1922 |
} |
74b0247fb [PATCH] sb1250-ma... |
1923 |
|
1da177e4c Linux-2.6.12-rc2 |
1924 |
/* |
74b0247fb [PATCH] sb1250-ma... |
1925 |
* Send the bits back to the hardware |
1da177e4c Linux-2.6.12-rc2 |
1926 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
1927 |
|
2039973af [PATCH] sb1250-ma... |
1928 |
__raw_writeq(cfg, s->sbm_maccfg); |
74b0247fb [PATCH] sb1250-ma... |
1929 |
|
1da177e4c Linux-2.6.12-rc2 |
1930 1931 1932 1933 1934 1935 1936 1937 |
return 1; } /********************************************************************** * SBMAC_INTR() |
74b0247fb [PATCH] sb1250-ma... |
1938 |
* |
1da177e4c Linux-2.6.12-rc2 |
1939 |
* Interrupt handler for MAC interrupts |
74b0247fb [PATCH] sb1250-ma... |
1940 1941 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
1942 |
* MAC structure |
74b0247fb [PATCH] sb1250-ma... |
1943 |
* |
1da177e4c Linux-2.6.12-rc2 |
1944 1945 1946 |
* Return value: * nothing ********************************************************************* */ |
7d12e780e IRQ: Maintain reg... |
1947 |
static irqreturn_t sbmac_intr(int irq,void *dev_instance) |
1da177e4c Linux-2.6.12-rc2 |
1948 1949 1950 1951 1952 |
{ struct net_device *dev = (struct net_device *) dev_instance; struct sbmac_softc *sc = netdev_priv(dev); uint64_t isr; int handled = 0; |
693aa9470 add NAPI support ... |
1953 1954 1955 1956 |
/* * Read the ISR (this clears the bits in the real * register, except for counter addr) */ |
74b0247fb [PATCH] sb1250-ma... |
1957 |
|
693aa9470 add NAPI support ... |
1958 |
isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR; |
1da177e4c Linux-2.6.12-rc2 |
1959 |
|
693aa9470 add NAPI support ... |
1960 1961 1962 |
if (isr == 0) return IRQ_RETVAL(0); handled = 1; |
74b0247fb [PATCH] sb1250-ma... |
1963 |
|
693aa9470 add NAPI support ... |
1964 1965 1966 |
/* * Transmits on channel 0 */ |
74b0247fb [PATCH] sb1250-ma... |
1967 |
|
bea3348ee [NET]: Make NAPI ... |
1968 |
if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) |
693aa9470 add NAPI support ... |
1969 |
sbdma_tx_process(sc,&(sc->sbm_txdma), 0); |
74b0247fb [PATCH] sb1250-ma... |
1970 |
|
693aa9470 add NAPI support ... |
1971 |
if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) { |
288379f05 net: Remove redun... |
1972 |
if (napi_schedule_prep(&sc->napi)) { |
693aa9470 add NAPI support ... |
1973 |
__raw_writeq(0, sc->sbm_imr); |
288379f05 net: Remove redun... |
1974 |
__napi_schedule(&sc->napi); |
693aa9470 add NAPI support ... |
1975 1976 1977 1978 1979 1980 |
/* Depend on the exit from poll to reenable intr */ } else { /* may leave some packets behind */ sbdma_rx_process(sc,&(sc->sbm_rxdma), SBMAC_MAX_RXDESCR * 2, 0); |
1da177e4c Linux-2.6.12-rc2 |
1981 1982 1983 1984 |
} } return IRQ_RETVAL(handled); } |
1da177e4c Linux-2.6.12-rc2 |
1985 1986 |
/********************************************************************** * SBMAC_START_TX(skb,dev) |
74b0247fb [PATCH] sb1250-ma... |
1987 1988 |
* * Start output on the specified interface. Basically, we |
1da177e4c Linux-2.6.12-rc2 |
1989 1990 |
* queue as many buffers as we can until the ring fills up, or * we run off the end of the queue, whichever comes first. |
74b0247fb [PATCH] sb1250-ma... |
1991 1992 1993 1994 |
* * Input parameters: * * |
1da177e4c Linux-2.6.12-rc2 |
1995 1996 1997 1998 1999 2000 |
* Return value: * nothing ********************************************************************* */ static int sbmac_start_tx(struct sk_buff *skb, struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); |
be61ea529 [netdrvr] convert... |
2001 |
unsigned long flags; |
74b0247fb [PATCH] sb1250-ma... |
2002 |
|
1da177e4c Linux-2.6.12-rc2 |
2003 |
/* lock eth irq */ |
be61ea529 [netdrvr] convert... |
2004 |
spin_lock_irqsave(&sc->sbm_lock, flags); |
74b0247fb [PATCH] sb1250-ma... |
2005 |
|
1da177e4c Linux-2.6.12-rc2 |
2006 |
/* |
74b0247fb [PATCH] sb1250-ma... |
2007 |
* Put the buffer on the transmit ring. If we |
1da177e4c Linux-2.6.12-rc2 |
2008 2009 |
* don't have room, stop the queue. */ |
74b0247fb [PATCH] sb1250-ma... |
2010 |
|
1da177e4c Linux-2.6.12-rc2 |
2011 2012 2013 |
if (sbdma_add_txbuffer(&(sc->sbm_txdma),skb)) { /* XXX save skb that we could not send */ netif_stop_queue(dev); |
be61ea529 [netdrvr] convert... |
2014 |
spin_unlock_irqrestore(&sc->sbm_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
2015 |
|
5b5481402 net: use symbolic... |
2016 |
return NETDEV_TX_BUSY; |
1da177e4c Linux-2.6.12-rc2 |
2017 |
} |
74b0247fb [PATCH] sb1250-ma... |
2018 |
|
be61ea529 [netdrvr] convert... |
2019 |
spin_unlock_irqrestore(&sc->sbm_lock, flags); |
74b0247fb [PATCH] sb1250-ma... |
2020 |
|
6ed106549 net: use NETDEV_T... |
2021 |
return NETDEV_TX_OK; |
1da177e4c Linux-2.6.12-rc2 |
2022 2023 2024 2025 |
} /********************************************************************** * SBMAC_SETMULTI(sc) |
74b0247fb [PATCH] sb1250-ma... |
2026 |
* |
1da177e4c Linux-2.6.12-rc2 |
2027 2028 2029 |
* Reprogram the multicast table into the hardware, given * the list of multicasts associated with the interface * structure. |
74b0247fb [PATCH] sb1250-ma... |
2030 2031 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
2032 |
* sc - softc |
74b0247fb [PATCH] sb1250-ma... |
2033 |
* |
1da177e4c Linux-2.6.12-rc2 |
2034 2035 2036 2037 2038 2039 2040 |
* Return value: * nothing ********************************************************************* */ static void sbmac_setmulti(struct sbmac_softc *sc) { uint64_t reg; |
73d739698 sb1250-mac.c: De-... |
2041 |
void __iomem *port; |
1da177e4c Linux-2.6.12-rc2 |
2042 |
int idx; |
22bedad3c net: convert mult... |
2043 |
struct netdev_hw_addr *ha; |
1da177e4c Linux-2.6.12-rc2 |
2044 |
struct net_device *dev = sc->sbm_dev; |
74b0247fb [PATCH] sb1250-ma... |
2045 2046 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2047 2048 |
* Clear out entire multicast table. We do this by nuking * the entire hash table and all the direct matches except |
74b0247fb [PATCH] sb1250-ma... |
2049 |
* the first one, which is used for our station address |
1da177e4c Linux-2.6.12-rc2 |
2050 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
2051 |
|
1da177e4c Linux-2.6.12-rc2 |
2052 2053 |
for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t)); |
2039973af [PATCH] sb1250-ma... |
2054 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
2055 |
} |
74b0247fb [PATCH] sb1250-ma... |
2056 |
|
1da177e4c Linux-2.6.12-rc2 |
2057 2058 |
for (idx = 0; idx < MAC_HASH_COUNT; idx++) { port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t)); |
2039973af [PATCH] sb1250-ma... |
2059 |
__raw_writeq(0, port); |
1da177e4c Linux-2.6.12-rc2 |
2060 |
} |
74b0247fb [PATCH] sb1250-ma... |
2061 |
|
1da177e4c Linux-2.6.12-rc2 |
2062 2063 2064 |
/* * Clear the filter to say we don't want any multicasts. */ |
74b0247fb [PATCH] sb1250-ma... |
2065 |
|
2039973af [PATCH] sb1250-ma... |
2066 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
2067 |
reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN); |
2039973af [PATCH] sb1250-ma... |
2068 |
__raw_writeq(reg, sc->sbm_rxfilter); |
74b0247fb [PATCH] sb1250-ma... |
2069 |
|
1da177e4c Linux-2.6.12-rc2 |
2070 |
if (dev->flags & IFF_ALLMULTI) { |
74b0247fb [PATCH] sb1250-ma... |
2071 2072 2073 |
/* * Enable ALL multicasts. Do this by inverting the * multicast enable bit. |
1da177e4c Linux-2.6.12-rc2 |
2074 |
*/ |
2039973af [PATCH] sb1250-ma... |
2075 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
2076 |
reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN); |
2039973af [PATCH] sb1250-ma... |
2077 |
__raw_writeq(reg, sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
2078 2079 |
return; } |
1da177e4c Linux-2.6.12-rc2 |
2080 |
|
74b0247fb [PATCH] sb1250-ma... |
2081 2082 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2083 2084 2085 2086 |
* Progam new multicast entries. For now, only use the * perfect filter. In the future we'll need to use the * hash filter if the perfect filter overflows */ |
74b0247fb [PATCH] sb1250-ma... |
2087 |
|
1da177e4c Linux-2.6.12-rc2 |
2088 2089 |
/* XXX only using perfect filter for now, need to use hash * XXX if the table overflows */ |
74b0247fb [PATCH] sb1250-ma... |
2090 |
|
1da177e4c Linux-2.6.12-rc2 |
2091 |
idx = 1; /* skip station address */ |
22bedad3c net: convert mult... |
2092 |
netdev_for_each_mc_addr(ha, dev) { |
5508590c1 net: convert mult... |
2093 2094 |
if (idx == MAC_ADDR_COUNT) break; |
22bedad3c net: convert mult... |
2095 |
reg = sbmac_addr2reg(ha->addr); |
1da177e4c Linux-2.6.12-rc2 |
2096 |
port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t)); |
2039973af [PATCH] sb1250-ma... |
2097 |
__raw_writeq(reg, port); |
1da177e4c Linux-2.6.12-rc2 |
2098 |
idx++; |
1da177e4c Linux-2.6.12-rc2 |
2099 |
} |
74b0247fb [PATCH] sb1250-ma... |
2100 2101 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2102 |
* Enable the "accept multicast bits" if we programmed at least one |
74b0247fb [PATCH] sb1250-ma... |
2103 |
* multicast. |
1da177e4c Linux-2.6.12-rc2 |
2104 |
*/ |
74b0247fb [PATCH] sb1250-ma... |
2105 |
|
1da177e4c Linux-2.6.12-rc2 |
2106 |
if (idx > 1) { |
2039973af [PATCH] sb1250-ma... |
2107 |
reg = __raw_readq(sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
2108 |
reg |= M_MAC_MCAST_EN; |
2039973af [PATCH] sb1250-ma... |
2109 |
__raw_writeq(reg, sc->sbm_rxfilter); |
1da177e4c Linux-2.6.12-rc2 |
2110 2111 |
} } |
1da177e4c Linux-2.6.12-rc2 |
2112 2113 2114 2115 2116 |
static int sb1250_change_mtu(struct net_device *_dev, int new_mtu) { if (new_mtu > ENET_PACKET_SIZE) return -EINVAL; _dev->mtu = new_mtu; |
f5279ffdc sb1250-mac: Drive... |
2117 2118 |
pr_info("changing the mtu to %d ", new_mtu); |
1da177e4c Linux-2.6.12-rc2 |
2119 2120 |
return 0; } |
b4cf3421a sb1250-mac: conve... |
2121 2122 2123 2124 2125 2126 2127 2128 2129 2130 2131 2132 2133 2134 |
static const struct net_device_ops sbmac_netdev_ops = { .ndo_open = sbmac_open, .ndo_stop = sbmac_close, .ndo_start_xmit = sbmac_start_tx, .ndo_set_multicast_list = sbmac_set_rx_mode, .ndo_tx_timeout = sbmac_tx_timeout, .ndo_do_ioctl = sbmac_mii_ioctl, .ndo_change_mtu = sb1250_change_mtu, .ndo_validate_addr = eth_validate_addr, .ndo_set_mac_address = eth_mac_addr, #ifdef CONFIG_NET_POLL_CONTROLLER .ndo_poll_controller = sbmac_netpoll, #endif }; |
1da177e4c Linux-2.6.12-rc2 |
2135 2136 |
/********************************************************************** * SBMAC_INIT(dev) |
74b0247fb [PATCH] sb1250-ma... |
2137 |
* |
1da177e4c Linux-2.6.12-rc2 |
2138 |
* Attach routine - init hardware and hook ourselves into linux |
74b0247fb [PATCH] sb1250-ma... |
2139 2140 |
* * Input parameters: |
1da177e4c Linux-2.6.12-rc2 |
2141 |
* dev - net_device structure |
74b0247fb [PATCH] sb1250-ma... |
2142 |
* |
1da177e4c Linux-2.6.12-rc2 |
2143 2144 2145 |
* Return value: * status ********************************************************************* */ |
f5279ffdc sb1250-mac: Drive... |
2146 |
static int sbmac_init(struct platform_device *pldev, long long base) |
1da177e4c Linux-2.6.12-rc2 |
2147 |
{ |
c7ae011dc net: remove drive... |
2148 |
struct net_device *dev = dev_get_drvdata(&pldev->dev); |
f5279ffdc sb1250-mac: Drive... |
2149 2150 |
int idx = pldev->id; struct sbmac_softc *sc = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
2151 2152 2153 2154 |
unsigned char *eaddr; uint64_t ea_reg; int i; int err; |
74b0247fb [PATCH] sb1250-ma... |
2155 |
|
1da177e4c Linux-2.6.12-rc2 |
2156 2157 |
sc->sbm_dev = dev; sc->sbe_idx = idx; |
74b0247fb [PATCH] sb1250-ma... |
2158 |
|
1da177e4c Linux-2.6.12-rc2 |
2159 |
eaddr = sc->sbm_hwaddr; |
74b0247fb [PATCH] sb1250-ma... |
2160 2161 |
/* |
877d03105 trivial: Fix miss... |
2162 |
* Read the ethernet address. The firmware left this programmed |
1da177e4c Linux-2.6.12-rc2 |
2163 2164 |
* for us in the ethernet address register for each mac. */ |
74b0247fb [PATCH] sb1250-ma... |
2165 |
|
2039973af [PATCH] sb1250-ma... |
2166 2167 |
ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR); __raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR); |
1da177e4c Linux-2.6.12-rc2 |
2168 2169 2170 2171 |
for (i = 0; i < 6; i++) { eaddr[i] = (uint8_t) (ea_reg & 0xFF); ea_reg >>= 8; } |
74b0247fb [PATCH] sb1250-ma... |
2172 |
|
1da177e4c Linux-2.6.12-rc2 |
2173 2174 2175 |
for (i = 0; i < 6; i++) { dev->dev_addr[i] = eaddr[i]; } |
74b0247fb [PATCH] sb1250-ma... |
2176 |
|
74b0247fb [PATCH] sb1250-ma... |
2177 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2178 2179 2180 |
* Initialize context (get pointers to registers and stuff), then * allocate the memory for the descriptor tables. */ |
74b0247fb [PATCH] sb1250-ma... |
2181 |
|
1da177e4c Linux-2.6.12-rc2 |
2182 |
sbmac_initctx(sc); |
74b0247fb [PATCH] sb1250-ma... |
2183 |
|
1da177e4c Linux-2.6.12-rc2 |
2184 2185 2186 |
/* * Set up Linux device callins */ |
74b0247fb [PATCH] sb1250-ma... |
2187 |
|
1da177e4c Linux-2.6.12-rc2 |
2188 |
spin_lock_init(&(sc->sbm_lock)); |
74b0247fb [PATCH] sb1250-ma... |
2189 |
|
b4cf3421a sb1250-mac: conve... |
2190 2191 |
dev->netdev_ops = &sbmac_netdev_ops; dev->watchdog_timeo = TX_TIMEOUT; |
bea3348ee [NET]: Make NAPI ... |
2192 2193 |
netif_napi_add(dev, &sc->napi, sbmac_poll, 16); |
1da177e4c Linux-2.6.12-rc2 |
2194 |
|
f5279ffdc sb1250-mac: Drive... |
2195 |
dev->irq = UNIT_INT(idx); |
1da177e4c Linux-2.6.12-rc2 |
2196 2197 |
/* This is needed for PASS2 for Rx H/W checksum feature */ sbmac_set_iphdr_offset(sc); |
298cf9beb phylib: move to d... |
2198 2199 |
sc->mii_bus = mdiobus_alloc(); if (sc->mii_bus == NULL) { |
03f80cc3f net/sb1250: regis... |
2200 2201 |
err = -ENOMEM; goto uninit_ctx; |
298cf9beb phylib: move to d... |
2202 |
} |
03f80cc3f net/sb1250: regis... |
2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 |
sc->mii_bus->name = sbmac_mdio_string; snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx); sc->mii_bus->priv = sc; sc->mii_bus->read = sbmac_mii_read; sc->mii_bus->write = sbmac_mii_write; sc->mii_bus->irq = sc->phy_irq; for (i = 0; i < PHY_MAX_ADDR; ++i) sc->mii_bus->irq[i] = SBMAC_PHY_INT; sc->mii_bus->parent = &pldev->dev; /* * Probe PHY address */ err = mdiobus_register(sc->mii_bus); if (err) { printk(KERN_ERR "%s: unable to register MDIO bus ", dev->name); goto free_mdio; } dev_set_drvdata(&pldev->dev, sc->mii_bus); |
1da177e4c Linux-2.6.12-rc2 |
2224 |
err = register_netdev(dev); |
f5279ffdc sb1250-mac: Drive... |
2225 2226 2227 2228 |
if (err) { printk(KERN_ERR "%s.%d: unable to register netdev ", sbmac_string, idx); |
03f80cc3f net/sb1250: regis... |
2229 |
goto unreg_mdio; |
1da177e4c Linux-2.6.12-rc2 |
2230 |
} |
f5279ffdc sb1250-mac: Drive... |
2231 2232 2233 2234 2235 2236 |
pr_info("%s.%d: registered as %s ", sbmac_string, idx, dev->name); if (sc->rx_hw_checksum == ENABLE) pr_info("%s: enabling TCP rcv checksum ", dev->name); |
1da177e4c Linux-2.6.12-rc2 |
2237 2238 2239 2240 2241 |
/* * Display Ethernet address (this is called during the config * process so we need to finish off the config message that * was being displayed) */ |
e174961ca net: convert prin... |
2242 2243 2244 |
pr_info("%s: SiByte Ethernet at 0x%08Lx, address: %pM ", dev->name, base, eaddr); |
1da177e4c Linux-2.6.12-rc2 |
2245 |
|
f5279ffdc sb1250-mac: Drive... |
2246 |
return 0; |
03f80cc3f net/sb1250: regis... |
2247 2248 2249 2250 2251 2252 2253 2254 |
unreg_mdio: mdiobus_unregister(sc->mii_bus); dev_set_drvdata(&pldev->dev, NULL); free_mdio: mdiobus_free(sc->mii_bus); uninit_ctx: sbmac_uninitctx(sc); return err; |
1da177e4c Linux-2.6.12-rc2 |
2255 2256 2257 2258 2259 2260 |
} static int sbmac_open(struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); |
f5279ffdc sb1250-mac: Drive... |
2261 |
int err; |
74b0247fb [PATCH] sb1250-ma... |
2262 |
|
f5279ffdc sb1250-mac: Drive... |
2263 2264 2265 |
if (debug > 1) pr_debug("%s: sbmac_open() irq %d. ", dev->name, dev->irq); |
74b0247fb [PATCH] sb1250-ma... |
2266 2267 |
/* |
1da177e4c Linux-2.6.12-rc2 |
2268 2269 2270 2271 |
* map/route interrupt (clear status first, in case something * weird is pending; we haven't initialized the mac registers * yet) */ |
2039973af [PATCH] sb1250-ma... |
2272 |
__raw_readq(sc->sbm_isr); |
a0607fd3a drivers/net: requ... |
2273 |
err = request_irq(dev->irq, sbmac_intr, IRQF_SHARED, dev->name, dev); |
f5279ffdc sb1250-mac: Drive... |
2274 2275 2276 2277 2278 2279 |
if (err) { printk(KERN_ERR "%s: unable to get IRQ %d ", dev->name, dev->irq); goto out_err; } |
1da177e4c Linux-2.6.12-rc2 |
2280 |
|
f5279ffdc sb1250-mac: Drive... |
2281 2282 2283 2284 2285 |
sc->sbm_speed = sbmac_speed_none; sc->sbm_duplex = sbmac_duplex_none; sc->sbm_fc = sbmac_fc_none; sc->sbm_pause = -1; sc->sbm_link = 0; |
bea3348ee [NET]: Make NAPI ... |
2286 |
|
59b818270 [PATCH] sb1250-ma... |
2287 |
/* |
f5279ffdc sb1250-mac: Drive... |
2288 |
* Attach to the PHY |
1da177e4c Linux-2.6.12-rc2 |
2289 |
*/ |
f5279ffdc sb1250-mac: Drive... |
2290 2291 2292 |
err = sbmac_mii_probe(dev); if (err) goto out_unregister; |
74b0247fb [PATCH] sb1250-ma... |
2293 |
|
1da177e4c Linux-2.6.12-rc2 |
2294 2295 2296 2297 2298 |
/* * Turn on the channel */ sbmac_set_channel_state(sc,sbmac_state_on); |
74b0247fb [PATCH] sb1250-ma... |
2299 |
|
1da177e4c Linux-2.6.12-rc2 |
2300 |
netif_start_queue(dev); |
74b0247fb [PATCH] sb1250-ma... |
2301 |
|
1da177e4c Linux-2.6.12-rc2 |
2302 |
sbmac_set_rx_mode(dev); |
74b0247fb [PATCH] sb1250-ma... |
2303 |
|
f5279ffdc sb1250-mac: Drive... |
2304 2305 2306 |
phy_start(sc->phy_dev); napi_enable(&sc->napi); |
74b0247fb [PATCH] sb1250-ma... |
2307 |
|
1da177e4c Linux-2.6.12-rc2 |
2308 |
return 0; |
f5279ffdc sb1250-mac: Drive... |
2309 2310 |
out_unregister: |
f5279ffdc sb1250-mac: Drive... |
2311 |
free_irq(dev->irq, dev); |
f5279ffdc sb1250-mac: Drive... |
2312 2313 |
out_err: return err; |
1da177e4c Linux-2.6.12-rc2 |
2314 |
} |
59b818270 [PATCH] sb1250-ma... |
2315 2316 |
static int sbmac_mii_probe(struct net_device *dev) { |
f5279ffdc sb1250-mac: Drive... |
2317 2318 |
struct sbmac_softc *sc = netdev_priv(dev); struct phy_device *phy_dev; |
59b818270 [PATCH] sb1250-ma... |
2319 |
int i; |
1da177e4c Linux-2.6.12-rc2 |
2320 |
|
f5279ffdc sb1250-mac: Drive... |
2321 |
for (i = 0; i < PHY_MAX_ADDR; i++) { |
298cf9beb phylib: move to d... |
2322 |
phy_dev = sc->mii_bus->phy_map[i]; |
f5279ffdc sb1250-mac: Drive... |
2323 2324 |
if (phy_dev) break; |
1da177e4c Linux-2.6.12-rc2 |
2325 |
} |
f5279ffdc sb1250-mac: Drive... |
2326 2327 2328 2329 |
if (!phy_dev) { printk(KERN_ERR "%s: no PHY found ", dev->name); return -ENXIO; |
1da177e4c Linux-2.6.12-rc2 |
2330 |
} |
db1d7bf70 net: struct devic... |
2331 |
phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &sbmac_mii_poll, 0, |
f5279ffdc sb1250-mac: Drive... |
2332 2333 2334 2335 2336 |
PHY_INTERFACE_MODE_GMII); if (IS_ERR(phy_dev)) { printk(KERN_ERR "%s: could not attach to PHY ", dev->name); return PTR_ERR(phy_dev); |
1da177e4c Linux-2.6.12-rc2 |
2337 |
} |
f5279ffdc sb1250-mac: Drive... |
2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 2352 2353 |
/* Remove any features not supported by the controller */ phy_dev->supported &= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | SUPPORTED_Autoneg | SUPPORTED_MII | SUPPORTED_Pause | SUPPORTED_Asym_Pause; phy_dev->advertising = phy_dev->supported; pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d) ", dev->name, phy_dev->drv->name, |
db1d7bf70 net: struct devic... |
2354 |
dev_name(&phy_dev->dev), phy_dev->irq); |
f5279ffdc sb1250-mac: Drive... |
2355 2356 |
sc->phy_dev = phy_dev; |
1da177e4c Linux-2.6.12-rc2 |
2357 |
|
f5279ffdc sb1250-mac: Drive... |
2358 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
2359 |
} |
f5279ffdc sb1250-mac: Drive... |
2360 |
static void sbmac_mii_poll(struct net_device *dev) |
1da177e4c Linux-2.6.12-rc2 |
2361 |
{ |
1da177e4c Linux-2.6.12-rc2 |
2362 |
struct sbmac_softc *sc = netdev_priv(dev); |
f5279ffdc sb1250-mac: Drive... |
2363 2364 2365 2366 2367 2368 2369 2370 2371 2372 2373 2374 2375 2376 2377 2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 |
struct phy_device *phy_dev = sc->phy_dev; unsigned long flags; enum sbmac_fc fc; int link_chg, speed_chg, duplex_chg, pause_chg, fc_chg; link_chg = (sc->sbm_link != phy_dev->link); speed_chg = (sc->sbm_speed != phy_dev->speed); duplex_chg = (sc->sbm_duplex != phy_dev->duplex); pause_chg = (sc->sbm_pause != phy_dev->pause); if (!link_chg && !speed_chg && !duplex_chg && !pause_chg) return; /* Hmmm... */ if (!phy_dev->link) { if (link_chg) { sc->sbm_link = phy_dev->link; sc->sbm_speed = sbmac_speed_none; sc->sbm_duplex = sbmac_duplex_none; sc->sbm_fc = sbmac_fc_disabled; sc->sbm_pause = -1; pr_info("%s: link unavailable ", dev->name); } return; } |
1da177e4c Linux-2.6.12-rc2 |
2388 |
|
f5279ffdc sb1250-mac: Drive... |
2389 2390 2391 2392 2393 2394 2395 2396 |
if (phy_dev->duplex == DUPLEX_FULL) { if (phy_dev->pause) fc = sbmac_fc_frame; else fc = sbmac_fc_disabled; } else fc = sbmac_fc_collision; fc_chg = (sc->sbm_fc != fc); |
74b0247fb [PATCH] sb1250-ma... |
2397 |
|
f5279ffdc sb1250-mac: Drive... |
2398 2399 2400 |
pr_info("%s: link available: %dbase-%cD ", dev->name, phy_dev->speed, phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H'); |
74b0247fb [PATCH] sb1250-ma... |
2401 |
|
f5279ffdc sb1250-mac: Drive... |
2402 |
spin_lock_irqsave(&sc->sbm_lock, flags); |
74b0247fb [PATCH] sb1250-ma... |
2403 |
|
f5279ffdc sb1250-mac: Drive... |
2404 2405 2406 2407 2408 |
sc->sbm_speed = phy_dev->speed; sc->sbm_duplex = phy_dev->duplex; sc->sbm_fc = fc; sc->sbm_pause = phy_dev->pause; sc->sbm_link = phy_dev->link; |
1da177e4c Linux-2.6.12-rc2 |
2409 |
|
f5279ffdc sb1250-mac: Drive... |
2410 2411 2412 2413 2414 2415 2416 2417 2418 2419 2420 |
if ((speed_chg || duplex_chg || fc_chg) && sc->sbm_state != sbmac_state_off) { /* * something changed, restart the channel */ if (debug > 1) pr_debug("%s: restarting channel " "because PHY state changed ", dev->name); sbmac_channel_stop(sc); sbmac_channel_start(sc); |
1da177e4c Linux-2.6.12-rc2 |
2421 |
} |
74b0247fb [PATCH] sb1250-ma... |
2422 |
|
f5279ffdc sb1250-mac: Drive... |
2423 |
spin_unlock_irqrestore(&sc->sbm_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
2424 2425 2426 2427 2428 2429 |
} static void sbmac_tx_timeout (struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); |
be61ea529 [netdrvr] convert... |
2430 |
unsigned long flags; |
74b0247fb [PATCH] sb1250-ma... |
2431 |
|
be61ea529 [netdrvr] convert... |
2432 |
spin_lock_irqsave(&sc->sbm_lock, flags); |
74b0247fb [PATCH] sb1250-ma... |
2433 |
|
1ae5dc342 net: trans_start ... |
2434 |
dev->trans_start = jiffies; /* prevent tx timeout */ |
09f75cd7b [NET] drivers/net... |
2435 |
dev->stats.tx_errors++; |
74b0247fb [PATCH] sb1250-ma... |
2436 |
|
be61ea529 [netdrvr] convert... |
2437 |
spin_unlock_irqrestore(&sc->sbm_lock, flags); |
1da177e4c Linux-2.6.12-rc2 |
2438 2439 2440 2441 |
printk (KERN_WARNING "%s: Transmit timed out ",dev->name); } |
1da177e4c Linux-2.6.12-rc2 |
2442 2443 2444 |
static void sbmac_set_rx_mode(struct net_device *dev) { unsigned long flags; |
1da177e4c Linux-2.6.12-rc2 |
2445 2446 2447 2448 2449 2450 2451 |
struct sbmac_softc *sc = netdev_priv(dev); spin_lock_irqsave(&sc->sbm_lock, flags); if ((dev->flags ^ sc->sbm_devflags) & IFF_PROMISC) { /* * Promiscuous changed. */ |
74b0247fb [PATCH] sb1250-ma... |
2452 2453 |
if (dev->flags & IFF_PROMISC) { |
1da177e4c Linux-2.6.12-rc2 |
2454 2455 2456 |
sbmac_promiscuous_mode(sc,1); } else { |
1da177e4c Linux-2.6.12-rc2 |
2457 2458 2459 2460 |
sbmac_promiscuous_mode(sc,0); } } spin_unlock_irqrestore(&sc->sbm_lock, flags); |
74b0247fb [PATCH] sb1250-ma... |
2461 |
|
1da177e4c Linux-2.6.12-rc2 |
2462 2463 2464 |
/* * Program the multicasts. Do this every time. */ |
74b0247fb [PATCH] sb1250-ma... |
2465 |
|
1da177e4c Linux-2.6.12-rc2 |
2466 |
sbmac_setmulti(sc); |
74b0247fb [PATCH] sb1250-ma... |
2467 |
|
1da177e4c Linux-2.6.12-rc2 |
2468 2469 2470 2471 2472 |
} static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) { struct sbmac_softc *sc = netdev_priv(dev); |
74b0247fb [PATCH] sb1250-ma... |
2473 |
|
f5279ffdc sb1250-mac: Drive... |
2474 2475 |
if (!netif_running(dev) || !sc->phy_dev) return -EINVAL; |
74b0247fb [PATCH] sb1250-ma... |
2476 |
|
f5279ffdc sb1250-mac: Drive... |
2477 |
return phy_mii_ioctl(sc->phy_dev, if_mii(rq), cmd); |
1da177e4c Linux-2.6.12-rc2 |
2478 2479 2480 2481 2482 |
} static int sbmac_close(struct net_device *dev) { struct sbmac_softc *sc = netdev_priv(dev); |
1da177e4c Linux-2.6.12-rc2 |
2483 |
|
bea3348ee [NET]: Make NAPI ... |
2484 |
napi_disable(&sc->napi); |
f5279ffdc sb1250-mac: Drive... |
2485 |
phy_stop(sc->phy_dev); |
1da177e4c Linux-2.6.12-rc2 |
2486 |
|
f5279ffdc sb1250-mac: Drive... |
2487 |
sbmac_set_channel_state(sc, sbmac_state_off); |
1da177e4c Linux-2.6.12-rc2 |
2488 2489 |
netif_stop_queue(dev); |
f5279ffdc sb1250-mac: Drive... |
2490 2491 2492 |
if (debug > 1) pr_debug("%s: Shutting down ethercard ", dev->name); |
1da177e4c Linux-2.6.12-rc2 |
2493 |
|
f5279ffdc sb1250-mac: Drive... |
2494 2495 |
phy_disconnect(sc->phy_dev); sc->phy_dev = NULL; |
f5279ffdc sb1250-mac: Drive... |
2496 |
free_irq(dev->irq, dev); |
1da177e4c Linux-2.6.12-rc2 |
2497 2498 2499 |
sbdma_emptyring(&(sc->sbm_txdma)); sbdma_emptyring(&(sc->sbm_rxdma)); |
74b0247fb [PATCH] sb1250-ma... |
2500 |
|
1da177e4c Linux-2.6.12-rc2 |
2501 2502 |
return 0; } |
bea3348ee [NET]: Make NAPI ... |
2503 |
static int sbmac_poll(struct napi_struct *napi, int budget) |
693aa9470 add NAPI support ... |
2504 |
{ |
bea3348ee [NET]: Make NAPI ... |
2505 |
struct sbmac_softc *sc = container_of(napi, struct sbmac_softc, napi); |
693aa9470 add NAPI support ... |
2506 |
int work_done; |
1da177e4c Linux-2.6.12-rc2 |
2507 |
|
bea3348ee [NET]: Make NAPI ... |
2508 |
work_done = sbdma_rx_process(sc, &(sc->sbm_rxdma), budget, 1); |
693aa9470 add NAPI support ... |
2509 |
sbdma_tx_process(sc, &(sc->sbm_txdma), 1); |
bea3348ee [NET]: Make NAPI ... |
2510 |
if (work_done < budget) { |
288379f05 net: Remove redun... |
2511 |
napi_complete(napi); |
693aa9470 add NAPI support ... |
2512 2513 2514 2515 2516 2517 2518 2519 2520 2521 |
#ifdef CONFIG_SBMAC_COALESCE __raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) | ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), sc->sbm_imr); #else __raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), sc->sbm_imr); #endif } |
bea3348ee [NET]: Make NAPI ... |
2522 |
return work_done; |
693aa9470 add NAPI support ... |
2523 |
} |
1da177e4c Linux-2.6.12-rc2 |
2524 |
|
f5279ffdc sb1250-mac: Drive... |
2525 |
|
ffe8553f8 net: move sb1250-... |
2526 |
static int __devinit sbmac_probe(struct platform_device *pldev) |
f5279ffdc sb1250-mac: Drive... |
2527 2528 2529 2530 2531 2532 2533 2534 2535 2536 2537 2538 2539 2540 |
{ struct net_device *dev; struct sbmac_softc *sc; void __iomem *sbm_base; struct resource *res; u64 sbmac_orig_hwaddr; int err; res = platform_get_resource(pldev, IORESOURCE_MEM, 0); BUG_ON(!res); sbm_base = ioremap_nocache(res->start, res->end - res->start + 1); if (!sbm_base) { printk(KERN_ERR "%s: unable to map device registers ", |
db1d7bf70 net: struct devic... |
2541 |
dev_name(&pldev->dev)); |
f5279ffdc sb1250-mac: Drive... |
2542 2543 2544 2545 2546 2547 2548 2549 2550 2551 |
err = -ENOMEM; goto out_out; } /* * The R_MAC_ETHERNET_ADDR register will be set to some nonzero * value for us by the firmware if we're going to use this MAC. * If we find a zero, skip this MAC. */ sbmac_orig_hwaddr = __raw_readq(sbm_base + R_MAC_ETHERNET_ADDR); |
db1d7bf70 net: struct devic... |
2552 2553 |
pr_debug("%s: %sconfiguring MAC at 0x%08Lx ", dev_name(&pldev->dev), |
f5279ffdc sb1250-mac: Drive... |
2554 2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 |
sbmac_orig_hwaddr ? "" : "not ", (long long)res->start); if (sbmac_orig_hwaddr == 0) { err = 0; goto out_unmap; } /* * Okay, cool. Initialize this MAC. */ dev = alloc_etherdev(sizeof(struct sbmac_softc)); if (!dev) { printk(KERN_ERR "%s: unable to allocate etherdev ", |
db1d7bf70 net: struct devic... |
2567 |
dev_name(&pldev->dev)); |
f5279ffdc sb1250-mac: Drive... |
2568 2569 2570 |
err = -ENOMEM; goto out_unmap; } |
c7ae011dc net: remove drive... |
2571 |
dev_set_drvdata(&pldev->dev, dev); |
f5279ffdc sb1250-mac: Drive... |
2572 2573 2574 2575 2576 2577 2578 2579 2580 2581 2582 2583 2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594 2595 |
SET_NETDEV_DEV(dev, &pldev->dev); sc = netdev_priv(dev); sc->sbm_base = sbm_base; err = sbmac_init(pldev, res->start); if (err) goto out_kfree; return 0; out_kfree: free_netdev(dev); __raw_writeq(sbmac_orig_hwaddr, sbm_base + R_MAC_ETHERNET_ADDR); out_unmap: iounmap(sbm_base); out_out: return err; } static int __exit sbmac_remove(struct platform_device *pldev) { |
c7ae011dc net: remove drive... |
2596 |
struct net_device *dev = dev_get_drvdata(&pldev->dev); |
f5279ffdc sb1250-mac: Drive... |
2597 2598 2599 2600 |
struct sbmac_softc *sc = netdev_priv(dev); unregister_netdev(dev); sbmac_uninitctx(sc); |
03f80cc3f net/sb1250: regis... |
2601 |
mdiobus_unregister(sc->mii_bus); |
298cf9beb phylib: move to d... |
2602 |
mdiobus_free(sc->mii_bus); |
f5279ffdc sb1250-mac: Drive... |
2603 2604 2605 2606 2607 |
iounmap(sc->sbm_base); free_netdev(dev); return 0; } |
f5279ffdc sb1250-mac: Drive... |
2608 2609 2610 2611 2612 |
static struct platform_driver sbmac_driver = { .probe = sbmac_probe, .remove = __exit_p(sbmac_remove), .driver = { .name = sbmac_string, |
33b665eee NET: SB1250: Init... |
2613 |
.owner = THIS_MODULE, |
f5279ffdc sb1250-mac: Drive... |
2614 2615 |
}, }; |
1da177e4c Linux-2.6.12-rc2 |
2616 |
|
f5279ffdc sb1250-mac: Drive... |
2617 2618 |
static int __init sbmac_init_module(void) { |
8cd9b1320 net/sb1250: setup... |
2619 |
return platform_driver_register(&sbmac_driver); |
f5279ffdc sb1250-mac: Drive... |
2620 |
} |
1da177e4c Linux-2.6.12-rc2 |
2621 |
|
f5279ffdc sb1250-mac: Drive... |
2622 |
static void __exit sbmac_cleanup_module(void) |
1da177e4c Linux-2.6.12-rc2 |
2623 |
{ |
f5279ffdc sb1250-mac: Drive... |
2624 |
platform_driver_unregister(&sbmac_driver); |
1da177e4c Linux-2.6.12-rc2 |
2625 2626 2627 2628 |
} module_init(sbmac_init_module); module_exit(sbmac_cleanup_module); |