I suspect that you're confusing compile-time and run-time. Macros run at compile time, producing code to be executed at run-time. Generally speaking it's hard to keep these straight and it makes writing macros difficult.
In any event, when I put this into ielm, I get:
ELISP> (defmacro times_two (var)
(* 2 var))
times_two
ELISP> (times_two '(+ 1 2))
*** Eval error *** Wrong type argument: number-or-marker-p, (quote (+ 1 2))
ELISP>
At least part of the problem then is the '(+ 1 2), but then when I remove the quote the following is no better:
ELISP> (times_two (+ 1 2))
*** Eval error *** Wrong type argument: number-or-marker-p, (+ 1 2)
ELISP>
It seems that elisp is looking for a number or a marker in the place where we are putting '(+ 1 2) and (+ 1 2). Let's try using a number:
ELISP> (times_two 3)
6
That works.
Interestingly, the macro expansion of this gives:
ELISP> (macroexpand '(times_two 3))
6
Which is probably not really what we want.
When we write macros we want to return expressions to be evaluated at run time. So rather than returning a number we can try this:
ELISP> (defmacro times_two (var)
`(* 2 ,var))
The backtick (quasiquote) is a way of creating a list, but also allowing interpolation with the use of a comma. Defining times_two in this way gives:
ELISP> (times_two (+ 1 2))
6
And the expansion of:
ELISP> (macroexpand '(times_two (+ 1 2)))
(* 2
(+ 1 2))
Which is exactly how you imagined it.